Hi everyone, As rounding seems a current topic, I'm throwing in a patch that is sitting in my tree for a while now:
We used to round coords to the shifted values in a subdiv by just using the ">>" shift operator. This works. But it's not the mathematical way of rounding, and the later is better IMHO. Let me explain this with an example: Let's assume the center-Lat of a subdiv is exactly at 0. Let's assume the shift-value is 4. So we divide by 16, or truncate to it, however you like to think about it. So if we have a point at lat=31, it will have the shifted value of (31-0) >> 4 = _1_. This will be displayed at 0 + (_1_ << 4) = 16. While _2_ would give us 0 + (_2_ << 4) = 32. 32 is much closer to the real value. Another more intuitive way of looking at the whole thing is with classic rounding: Just assume, that the current shift value is choosen so that we round exactly to "degrees" (some special sort of degrees). So, 3.9 will currently be rounded to just 3, not 4. The solution is add half the rounding distance and truncate: truncate(3.9 + 0.5) = 4. PENDING ISSUES: I am not sure, that I have catched all cases in mkgmap. Any feedback on this is highly welcome. Of course, general testing and feedback is also welcome! Elrond p.s.: This is also related to the overview map issue I was talking about a while back and wanting to post patches for. This one can be counted as the next one.
Index: uk/me/parabola/imgfmt/app/trergn/MapObject.java =================================================================== --- uk/me/parabola/imgfmt/app/trergn/MapObject.java (revision 1129) +++ uk/me/parabola/imgfmt/app/trergn/MapObject.java (working copy) @@ -91,10 +91,8 @@ */ public void setLatitude(int lat) { Subdivision div = getSubdiv(); - int shift = div.getShift(); - int centerLat = div.getLatitude() >> shift; - int diff = ((lat>>shift) - centerLat); + int diff = div.roundLatToLocalShifted(lat); setDeltaLat(diff); } @@ -107,15 +105,13 @@ */ public void setLongitude(int lon) { Subdivision div = getSubdiv(); - int shift = div.getShift(); - int centerLon = div.getLongitude() >> shift; - int diff = ((lon>> shift) - centerLon); + int diff = div.roundLonToLocalShifted(lon); setDeltaLong(diff); } - // directly setting shouldn't be done + // directly setting shouldn't be done private void setDeltaLat(int deltaLat) { this.deltaLat = deltaLat; } Index: uk/me/parabola/imgfmt/app/trergn/LinePreparer.java =================================================================== --- uk/me/parabola/imgfmt/app/trergn/LinePreparer.java (revision 1129) +++ uk/me/parabola/imgfmt/app/trergn/LinePreparer.java (working copy) @@ -169,9 +169,10 @@ * the lat and long values. */ private void calcDeltas() { + Subdivision subdiv = polyline.getSubdiv(); if(log.isDebugEnabled()) log.debug("label offset", polyline.getLabel().getOffset()); - int shift = polyline.getSubdiv().getShift(); + int shift = subdiv.getShift(); List<Coord> points = polyline.getPoints(); // Space to hold the deltas @@ -196,8 +197,8 @@ for (int i = 0; i < points.size(); i++) { Coord co = points.get(i); - int lat = co.getLatitude() >> shift; - int lon = co.getLongitude() >> shift; + int lat = subdiv.roundLatToLocalShifted(co.getLatitude()); + int lon = subdiv.roundLonToLocalShifted(co.getLongitude()); if (log.isDebugEnabled()) log.debug("shifted pos", lat, lon); if (first) { Index: uk/me/parabola/imgfmt/app/trergn/Subdivision.java =================================================================== --- uk/me/parabola/imgfmt/app/trergn/Subdivision.java (revision 1129) +++ uk/me/parabola/imgfmt/app/trergn/Subdivision.java (working copy) @@ -414,4 +414,24 @@ rgnFile.setPolygonPtr(); } + + /** + * Convert an absolute Lat to a local, shifted value + */ + public int roundLatToLocalShifted(int absval) { + int shift = getShift(); + int val = absval - getLatitude(); + val = val + ((1 << shift) / 2); + return (val >> shift); + } + + /** + * Convert an absolute Lon to a local, shifted value + */ + public int roundLonToLocalShifted(int absval) { + int shift = getShift(); + int val = absval - getLongitude(); + val = val + ((1 << shift) / 2); + return (val >> shift); + } }
_______________________________________________ mkgmap-dev mailing list mkgmap-dev@lists.mkgmap.org.uk http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev