Index: src/uk/me/parabola/mkgmap/reader/osm/HousenumberHooks.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/HousenumberHooks.java	(revision 4919)
+++ src/uk/me/parabola/mkgmap/reader/osm/HousenumberHooks.java	(working copy)
@@ -21,6 +21,7 @@
 import java.util.stream.Collectors;
 
 import uk.me.parabola.log.Logger;
+import uk.me.parabola.mkgmap.osmstyle.housenumber.HousenumberGenerator;
 import uk.me.parabola.util.EnhancedProperties;
 
 /**
@@ -34,7 +35,6 @@
 	private ElementSaver saver;
 	private final List<Node> nodes = new ArrayList<>();
 	
-	private static final short TK_ADDR_HOUSENUMBER = TagDict.getInstance().xlate("addr:housenumber");
 	private static final short TK_ADDR_INTERPOLATION = TagDict.getInstance().xlate("addr:interpolation");
 	
 	public static final short TKM_PART_OF_INTERPOLATION = TagDict.getInstance().xlate("mkgmap:part-of-interpolation");
@@ -55,7 +55,7 @@
 	@Override
 	public void onNodeAddedToWay(Way way, long id) {
 		Node currentNodeInWay = saver.getNode(id);
-		if (currentNodeInWay != null && currentNodeInWay.getTag(TK_ADDR_HOUSENUMBER) != null) { 
+		if (currentNodeInWay != null && HousenumberGenerator.getHousenumber(currentNodeInWay) != null) { 
 			// this node might be part of a way that has the addr:interpolation tag
 			nodes.add(currentNodeInWay);
 		}
Index: src/uk/me/parabola/mkgmap/reader/osm/POIGeneratorHook.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/POIGeneratorHook.java	(revision 4919)
+++ src/uk/me/parabola/mkgmap/reader/osm/POIGeneratorHook.java	(working copy)
@@ -16,6 +16,7 @@
 import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
@@ -25,9 +26,13 @@
 
 import uk.me.parabola.imgfmt.app.Coord;
 import uk.me.parabola.log.Logger;
+import uk.me.parabola.mkgmap.CommandArgs;
 import uk.me.parabola.mkgmap.osmstyle.NameFinder;
 import uk.me.parabola.mkgmap.osmstyle.function.AreaSizeFunction;
+import uk.me.parabola.mkgmap.osmstyle.housenumber.HousenumberGenerator;
 import uk.me.parabola.util.EnhancedProperties;
+import uk.me.parabola.util.IsInUtil;
+import uk.me.parabola.util.QuadTree;
 
 /**
  * Adds a POI for each area and multipolygon with the same tags in case the add-pois-to-areas option
@@ -79,6 +84,9 @@
 	private boolean poisToLinesEnd = false; 
 	private boolean poisToLinesMid = false; 
 	private boolean poisToLinesOther = false; 
+	private boolean addHnrMissing;
+	private QuadTree qtNumberNodes;
+	private final Set<String> hnrBuildings = new HashSet<>(); 	
 	private NameFinder nameFinder;
 	private AreaSizeFunction areaSizeFunction = new AreaSizeFunction();
 
@@ -89,6 +97,8 @@
 	public static final short TKM_LINE2POI = TagDict.getInstance().xlate("mkgmap:line2poi");
 	public static final short TKM_LINE2POI_TYPE = TagDict.getInstance().xlate("mkgmap:line2poitype");
 	public static final short TKM_WAY_LENGTH = TagDict.getInstance().xlate("mkgmap:way-length");
+	public static final short TK_BUILDING = TagDict.getInstance().xlate("building");
+	public static final short TKM_HNR_MISSING = TagDict.getInstance().xlate("mkgmap:hnr-missing");
 	
 	@Override
 	public boolean init(ElementSaver saver, EnhancedProperties props, Style style) {
@@ -128,6 +138,17 @@
 			
 		}
 		
+		final String hnrOption = "add-hnr-missing";
+		addHnrMissing = props.containsKey(hnrOption);
+		if (addHnrMissing) {
+			String houseTypes = props.getProperty(hnrOption);
+			if (houseTypes.isEmpty())
+				houseTypes = "apartments,bungalow,detached,farm,house,residential,semidetached_house,terrace";
+			hnrBuildings.clear();
+			hnrBuildings.addAll(CommandArgs.stringToList(houseTypes, hnrOption));
+			poisToAreas = true;
+		}
+		
 		if (!(poisToAreas || poisToLines)) {
 			log.info("Disable Areas2POIHook because add-pois-to-areas and add-pois-to-lines option is not set.");
 			return false;
@@ -146,6 +167,10 @@
 		} else {
 			usedTagsPOI = Collections.emptySet();
 		}
+		if (addHnrMissing) {
+			usedTagsPOI.add("building");
+			usedTagsPOI.add("addr:housenumber");
+		}
 		return true;
 	}
 	
@@ -224,9 +249,18 @@
 				}
 			}
 		}
+		if (addHnrMissing) {
+			for (Node n : saver.getNodes().values()) {
+				if (isBuildingWithoutHousenumberTag(n))
+					n.addTag(TKM_HNR_MISSING, "true");
+			}
+			fillNumberQuadTree();
+
+		}
 		addPOIsForWays();
 		addPOIsForMPs();
 		coordToNodeMap.clear();
+		qtNumberNodes = null;
 		log.info(getClass().getSimpleName(), "finished");
 	}
 	
@@ -238,7 +272,7 @@
 				return order;
 			}
 		}
-		// no poi tag match
+		// no POI tag match
 		return -1;
 	}
 	
@@ -283,10 +317,8 @@
 					addPOItoPolygon(w, labelCoords);
 					ways2POI++;
 				}
-			} else {
-				if (poisToLines) {
-					lines2POI += addPOItoLine(w);
-				}
+			} else if (poisToLines) {
+				lines2POI += addPOItoLine(w);
 			}
 		}
 		
@@ -300,8 +332,12 @@
 		if (!poisToAreas) {
 			return;
 		}
-		
-		// get the coord where the poi is placed
+
+		if (addHnrMissing && isBuildingWithoutHousenumberTag(polygon) && !hasNumberInside(polygon)) {
+			polygon.addTag(TKM_HNR_MISSING, "true");
+		}
+		 		
+		// get the coord where the POI is placed
 		Coord poiCoord = null;
 		// do we have some labeling coords?
 		if (!labelCoords.isEmpty()) {
@@ -491,5 +527,31 @@
 		log.info(mps2POI,"POIs from multipolygons created");
 	}
 
+	private void fillNumberQuadTree() {
+		long t0 = System.currentTimeMillis();
+		qtNumberNodes = new QuadTree(saver.getBoundingBox());
+		for (Node n : saver.getNodes().values()) {
+			if (HousenumberGenerator.getHousenumber(n) != null) {
+				qtNumberNodes.add(n.getLocation());
+			}
+		}
+		long dt = System.currentTimeMillis() - t0;
+		log.info("add-hnr-missing: Calculation of quad-tree with", qtNumberNodes.getSize(), " points took", dt, "ms");
+	}
 
+	private boolean hasNumberInside(Way way) {
+		List<Coord> candidates = qtNumberNodes.get(way.getPoints());
+		for (Coord c : candidates) {
+			int res = IsInUtil.isPointInShape(c, way.getPoints());
+			if (res == IsInUtil.IN || res == IsInUtil.ON) {
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	private boolean isBuildingWithoutHousenumberTag(Element e) {
+		String building = e.getTag(TK_BUILDING);
+		return building != null && hnrBuildings.contains(building) && HousenumberGenerator.getHousenumber(e) == null;
+	}
 }
