Index: src/uk/me/parabola/mkgmap/reader/osm/HousenumberHooks.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/HousenumberHooks.java	(revision 4921)
+++ 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 4921)
+++ 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;
@@ -23,11 +24,16 @@
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import uk.me.parabola.imgfmt.app.Area;
 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 +85,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 +98,9 @@
 	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");
+	public static final short TK_NOHOUSENUMBER = TagDict.getInstance().xlate("nohousenumber");
 	
 	@Override
 	public boolean init(ElementSaver saver, EnhancedProperties props, Style style) {
@@ -128,6 +140,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;
@@ -205,7 +228,14 @@
 	
 	@Override
 	public Set<String> getUsedTags() {
-		return poiPlacementTags.stream().map(Map.Entry::getKey).collect(Collectors.toSet());
+		Set<String>usedTags = new HashSet<>(); 
+		poiPlacementTags.stream().map(Map.Entry::getKey).forEach(usedTags::add);
+		if (addHnrMissing) {
+			usedTags.add("building");
+			usedTags.add("addr:housenumber");
+			usedTags.add("nohousenumber");
+		}
+		return usedTags;
 	}
 	
 	@Override
@@ -224,9 +254,18 @@
 				}
 			}
 		}
+		if (addHnrMissing) {
+			for (Node n : saver.getNodes().values()) {
+				if (needsHousenumber(n))
+					n.addTag(TKM_HNR_MISSING, "true");
+			}
+			fillNumberQuadTree();
+
+		}
 		addPOIsForWays();
 		addPOIsForMPs();
 		coordToNodeMap.clear();
+		qtNumberNodes = null;
 		log.info(getClass().getSimpleName(), "finished");
 	}
 	
@@ -238,7 +277,7 @@
 				return order;
 			}
 		}
-		// no poi tag match
+		// no POI tag match
 		return -1;
 	}
 	
@@ -283,10 +322,8 @@
 					addPOItoPolygon(w, labelCoords);
 					ways2POI++;
 				}
-			} else {
-				if (poisToLines) {
-					lines2POI += addPOItoLine(w);
-				}
+			} else if (poisToLines) {
+				lines2POI += addPOItoLine(w);
 			}
 		}
 		
@@ -300,8 +337,12 @@
 		if (!poisToAreas) {
 			return;
 		}
-		
-		// get the coord where the poi is placed
+
+		if (addHnrMissing && needsHousenumber(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 +532,34 @@
 		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(Area.getBBox(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 needsHousenumber(Element e) {
+		if (e.tagIsLikeYes(TK_NOHOUSENUMBER))
+			return false;
+		String building = e.getTag(TK_BUILDING);
+		return building != null && hnrBuildings.contains(building) && HousenumberGenerator.getHousenumber(e) == null;
+	}
 }
