Index: src/uk/me/parabola/imgfmt/Utils.java
===================================================================
--- src/uk/me/parabola/imgfmt/Utils.java	(revision 4193)
+++ src/uk/me/parabola/imgfmt/Utils.java	(working copy)
@@ -183,6 +183,15 @@
 		return toDegrees(mapunits) * (Math.PI / 180);
 	}
 
+	/**
+	 * Convert high precision int value to map units with double precision 
+	 * @param highPrecMapUnits the high precision as return from e.g. Coord.getHighPrecLat()
+	 * @return map units as double value that preserves the precision  
+	 */
+	public static double hpToDouble(int highPrecMapUnits) {
+		return (double) highPrecMapUnits / (1 << Coord.DELTA_SHIFT);	
+	}
+	
 	public static void closeFile(Closeable f) {
 		if (f != null) {
 			try {
Index: src/uk/me/parabola/mkgmap/reader/osm/LocationHook.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/LocationHook.java	(revision 4195)
+++ src/uk/me/parabola/mkgmap/reader/osm/LocationHook.java	(working copy)
@@ -179,32 +179,50 @@
 		else if (elem instanceof Way){
 			Way way = (Way) elem;
 			// try the mid point of the way first
-			int middle = way.getPoints().size() / 2;
-			Coord midPoint;
-			if (way.getPoints().size() == 2) {
-				midPoint = way.getPoints().get(0).makeBetweenPoint(way.getPoints().get(1), 0.5);
+			int n = way.getPoints().size();
+			int middle = n / 2;
+			Coord testPoint;
+			if (n == 2) {
+				testPoint = way.getPoints().get(0).makeBetweenPoint(way.getPoints().get(1), 0.5);
 			} else {
-				midPoint = way.getPoints().get(middle);
+				testPoint = way.getPoints().get(middle);
 			}
-			tags = search(midPoint);
+			tags = search(testPoint);
 			if (tags == null){
+				// still not found, try rest excluding first and last
+				
+				for (int off = 1; off < middle; off++){
+					tags = search(way.getPoints().get(off));
+					if (tags != null) 
+						break;
+					int pos = n - 1 - off;
+					if (pos > middle) {
+						tags = search(way.getPoints().get(pos));
+						if (tags != null) 
+							break;
+					}
+					
+				}
+			}
+			if (tags == null){
+				// try position close to 1st point next
+				testPoint = getClosePoint(way.getPoints().get(0), way.getPoints().get(1));
+				tags = search(testPoint);
+			}
+			if (tags == null){
+				// try position close to last point next
+				testPoint = getClosePoint(way.getPoints().get(n-1), way.getPoints().get(n-2));
+				tags = search(testPoint);
+			}
+			// seems that only first or last point is in the bounding box
+			if (tags == null){
 				// try 1st point next
 				tags = search(way.getPoints().get(0));
 			}
 			if (tags == null){
 				// try last point next
-				tags = search(way.getPoints().get(way.getPoints().size()-1));
+				tags = search(way.getPoints().get(n-1));
 			}
-			if (tags == null){
-				// still not found, try rest
-				for (int i = 1; i < way.getPoints().size()-1; i++){
-					if (i == middle)
-						continue;
-					tags = search(way.getPoints().get(i));
-					if (tags != null) 
-						break;
-				}
-			}
 			if (tags == null)
 				++cntwayNotFnd;
 		}
@@ -225,6 +243,27 @@
 	}
 	
 	/**
+	 * Try to calculate a coord next position on line p1->p2
+	 * @param p1 1st point
+	 * @param p2 2nd point
+	 * @return new point or p1
+	 */
+	private static Coord getClosePoint (Coord p1, Coord p2) {
+		double dist = p1.distance(p2);
+		if (dist > .2) {
+			double fraction = 0.1/dist; // 10cm; 
+			while (fraction < 0.5) {
+				Coord p = p1.makeBetweenPoint(p2, fraction);
+				if (!p.highPrecEquals(p1)) {
+					// The boundary data is used with low precision! 
+					return p;
+				}
+				fraction *= 2;
+			}
+		}
+		return p1;
+	}
+	/**
 	 * perform search in grid and maintain statistic counter
 	 * @param co a point that is to be searched
 	 * @return location relevant tags or null
Index: src/uk/me/parabola/mkgmap/reader/osm/ResidentialHook.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/ResidentialHook.java	(revision 4193)
+++ src/uk/me/parabola/mkgmap/reader/osm/ResidentialHook.java	(working copy)
@@ -97,7 +97,9 @@
 			}
 		}
 		
-		return new BoundaryQuadTree(saver.getBoundingBox(), residentials, null);
+		BoundaryQuadTree bqt = new BoundaryQuadTree(saver.getBoundingBox(), residentials, null);
+		bqt.setSearchDist(1 << Coord.DELTA_SHIFT);
+		return bqt;
 	}
 
 	/**
@@ -114,10 +116,11 @@
 		} else if (elem instanceof Way){
 			Way way = (Way) elem;
 			// try the mid point of the way first
-			int middle = way.getPoints().size() / 2;
-			Coord loc = way.hasIdenticalEndPoints() ? way.getCofG() : way.getPoints().get(middle);
-			if (! "residential".equals(way.getTag(landuseTagKey)))
+			if (! "residential".equals(way.getTag(landuseTagKey))) {
+				int middle = way.getPoints().size() / 2;
+				Coord loc = way.hasIdenticalEndPoints() ? way.getCofG() : way.getPoints().get(middle);
 				residentialTags = residentialBoundaries.get(loc);
+			}
 		}
 
 		if (residentialTags != null) {
Index: src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryGrid.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryGrid.java	(revision 4193)
+++ src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryGrid.java	(working copy)
@@ -16,6 +16,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
 
+import uk.me.parabola.imgfmt.Utils;
 import uk.me.parabola.imgfmt.app.Coord;
 import uk.me.parabola.log.Logger;
 import uk.me.parabola.mkgmap.reader.osm.Tags;
@@ -75,8 +76,14 @@
 	public Tags get(Coord co) {
 		if (!searchBbox.contains(co))
 			return null;
-		int gridLat = (co.getLatitude() - minLat) / BoundaryUtil.RASTER;
-		int gridLon = (co.getLongitude() - minLon) / BoundaryUtil.RASTER;
+		
+		// BoundaryQuadTree uses high precision values, make sure that we select the proper tree
+		// when point is close to the grid raster.
+		int lon = (int) Math.floor(Utils.hpToDouble(co.getHighPrecLon()));
+		int lat = (int) Math.floor(Utils.hpToDouble(co.getHighPrecLat()));
+		
+		int gridLat = (lat - minLat) / BoundaryUtil.RASTER;
+		int gridLon = (lon - minLon) / BoundaryUtil.RASTER;
 		if (grid[gridLat][gridLon] == null){
 			if (emptyMessagePrinted[gridLat][gridLon] == false){
 				emptyMessagePrinted[gridLat][gridLon] = true;
Index: src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryQuadTree.java
===================================================================
--- src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryQuadTree.java	(revision 4193)
+++ src/uk/me/parabola/mkgmap/reader/osm/boundary/BoundaryQuadTree.java	(working copy)
@@ -35,6 +35,7 @@
 import java.util.Map.Entry;
 import java.util.regex.Pattern;
 
+import uk.me.parabola.imgfmt.Utils;
 import uk.me.parabola.imgfmt.app.Coord;
 import uk.me.parabola.log.Logger;
 import uk.me.parabola.mkgmap.reader.osm.Tags;
@@ -72,8 +73,17 @@
 	private final Node root;
 	// the bounding box of the quadtree
 	private final Rectangle bbox;
-	private final String bbox_key; 
+	private final String bbox_key;
+	private int searchDist = 1;
 	
+	/** set search distance for the get method.
+	 *  
+	 * @param searchDist distance in high precision map units (see Coord) 
+	 */
+	public void setSearchDist(int searchDist) {
+		this.searchDist = searchDist;
+	}
+
 	// tags that can be returned in the get method
 	public final static String[] mkgmapTagsArray =  {
 		"mkgmap:admin_level1",
@@ -164,21 +174,23 @@
 	 */
 	public Tags get(Coord co){
 		Tags res = root.get(co/*, "_"*/);
-		if (res == null && bbox.contains(co.getLongitude(),co.getLatitude())){
+		if (res == null && searchDist > 0 && bbox.contains(co.getLongitude(),co.getLatitude())){
+			// this is likely when called from the ResidentialHook
 			// we did not find the point, probably it lies on a boundary and
 			// the clauses regarding insideness of areas make it "invisible"
-			// try again a few other nearby points 
-			Coord neighbour1 = new Coord(co.getLatitude()-1, co.getLongitude());
-			Coord neighbour2 = new Coord(co.getLatitude()  , co.getLongitude()-1);
-			Coord neighbour3 = new Coord(co.getLatitude()+1, co.getLongitude());
-			Coord neighbour4 = new Coord(co.getLatitude()  , co.getLongitude()+1);
-			res = root.get(neighbour1/*, "_"*/);
-			if (res == null)
-				res = root.get(neighbour2/*, "_"*/);
-			if (res == null)
-				res = root.get(neighbour3/*, "_"*/);
-			if (res == null)
-				res = root.get(neighbour4/*, "_"*/);
+			// try again a few other nearby points
+			int hpLat = co.getHighPrecLat();
+			int hpLon = co.getHighPrecLon();
+			res = root.get(Coord.makeHighPrecCoord(hpLat - searchDist, hpLon)/* , "_" */);
+			if (res != null)
+				return res;
+			res = root.get(Coord.makeHighPrecCoord(hpLat, hpLon - searchDist)/* , "_" */);
+			if (res != null)
+				return res;
+			res = root.get(Coord.makeHighPrecCoord(hpLat + searchDist, hpLon)/* , "_" */);
+			if (res != null)
+				return res;
+			res = root.get(Coord.makeHighPrecCoord(hpLat, hpLon + searchDist)/* , "_" */);
 		}
 		return res;
 	}
@@ -474,7 +486,7 @@
 				int lon = co.getLongitude();
 				int lat = co.getLatitude();
 				for (NodeElem nodeElem: nodes){
-					if (nodeElem.tagMask > 0){	
+					if (nodeElem.tagMask != 0){	
 						if (nodeElem.getArea().contains(lon,lat)){
 							String res = new String (nodeElem.boundaryId);
 							if (nodeElem.locationDataSrc != null)
@@ -506,10 +518,10 @@
 			if (isLeaf){
 				if (nodes == null || nodes.size() == 0)
 					return null;
-				int lon = co.getLongitude();
-				int lat = co.getLatitude();
+				double lon = Utils.hpToDouble(co.getHighPrecLon());
+				double lat = Utils.hpToDouble(co.getHighPrecLat());
 				for (NodeElem nodeElem: nodes){
-					if (nodeElem.tagMask > 0){	
+					if (nodeElem.tagMask != 0){	
 						if (nodeElem.getArea().contains(lon,lat)){
 							return nodeElem.locTags;
 						}
Index: src/uk/me/parabola/util/Java2DConverter.java
===================================================================
--- src/uk/me/parabola/util/Java2DConverter.java	(revision 4193)
+++ src/uk/me/parabola/util/Java2DConverter.java	(working copy)
@@ -98,8 +98,8 @@
 			Coord co = polygonPoints.get(i);
 			int latHp = co.getHighPrecLat();
 			int lonHp = co.getHighPrecLon();
-			double x = (double)lonHp / (1<<Coord.DELTA_SHIFT); 
-			double y = (double)latHp / (1<<Coord.DELTA_SHIFT); 
+			double x = Utils.hpToDouble(lonHp); 
+			double y = Utils.hpToDouble(latHp); 
 			if (i == 0)
 				path.moveTo(x, y);
 			else {
