[josm-dev] When to move a node?
Petr Nejedly
Petr.Nejedly at Sun.COM
Tue Nov 18 21:13:57 GMT 2008
Harald Kucharek napsal(a):
> When Frederik added my orthogonalization action to JOSM, he remarked:
> --
> There's one thing I do not like yet, and that is that multiple changes
> are generated if you call the function repeatedly (it doesn't recognize
> that the shape is already rectangular, makes minuscle adjustments). I
> tried to build in a treshold under which there would be no change
> recorded but it didn't work out well.
> --
> It seems, this hold for all similar actions, like "Align nodes in
> circle" etc.
>
> Frederik used from LatLon this method:
>
> public boolean equalsEpsilon(LatLon other) {
> final double p = 1/Projection.MAX_SERVER_PRECISION;
> return Math.abs(lat()-other.lat()) <= p &&
> Math.abs(lon()-other.lon()) <= p;
> }
>
> where
> /**
> * Minimum difference in location to not be represented as the same position.
> */
> MAX_SERVER_PRECISION = 1e12;
>
> Almost all operations will make this method return false, just due to
> numeric inaccuracies, I guess. Also, this is a very non-intuitive test.
No wonder, the used epsilon, on a +-180 degree scale leads to comparing
49 out of 53 bits of double mantissa. 4 bits of error will easily accumulate
over few operations. The epsilon also transforms to something like 100nm
(yes, 100 nanometers) on the earth surface.
>
> I made a quick change by using
> public double greatCircleDistance(LatLon other)
> also from LatLon, only really moving nodes when the distance computed by
> above method is less than 2 meters (the method computes the distance in
> meters).
2 meters is way too much, you certainly want to fix smaller errors.
2m is like 21 out of 53 bits, so we have 28bit scale in between to pick from.
I don't expect the numerical errors much bigger than those 4 bits (unless the
algorithm is flawed on the error propagation front, I haven't analyzed that much).
If we add 10 bits (epsilon of 1e-9) to have a plenty of headroom, we're still
at around 0.1mm accuracy.
So, you can either keep using equalsEpsilon and update epsilon to 1e-9
(enough accuracy IMHO, but needs wider acceptance, as this has much deeper impact,
like comparing nodes on merge), or change the limit to getCircleDistance
to 0.0001m. The former is faster code....
> This way, it is very clear when a node really moves and when not. I had
> no time for long tests, but it seemed to me that the computed distance
> is either smaller than expected or the scale of the map, as nodes I
> expected to move weren't moved. I've to check this next weekend.
> Sure, greatCircleDistance() is computationally much more expensive than
> equalsEpsilon(), but we usually don't move millions of nodes.
>
> That was my idea. Now, any other ideas or thoughts about the problem?
>
> Regards,
>
> Harald
>
>
>
> _______________________________________________
> josm-dev mailing list
> josm-dev at openstreetmap.org
> http://lists.openstreetmap.org/listinfo/josm-dev
--
Petr "Nenik" Nejedly, NetBeans/Sun Microsystems, http://www.netbeans.org
355/113 -- Not the famous irrational number PI, but an incredible simulation!
More information about the josm-dev
mailing list