Fix poi out of its boundaries
This commit is contained in:
parent
1f3e889ec8
commit
0c158551f1
3 changed files with 79 additions and 3 deletions
|
@ -7,6 +7,7 @@ import java.util.Comparator;
|
|||
import java.util.List;
|
||||
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.util.MapAlgorithms;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
public class OsmMapUtils {
|
||||
|
@ -27,7 +28,7 @@ public class OsmMapUtils {
|
|||
if (e instanceof Node) {
|
||||
return ((Node) e).getLatLon();
|
||||
} else if (e instanceof Way) {
|
||||
return getWeightCenterForNodes(((Way) e).getNodes());
|
||||
return getWeightCenterForWay(((Way) e));
|
||||
} else if (e instanceof Relation) {
|
||||
List<LatLon> list = new ArrayList<LatLon>();
|
||||
for (Entity fe : ((Relation) e).getMembers(null)) {
|
||||
|
@ -58,7 +59,7 @@ public class OsmMapUtils {
|
|||
return new LatLon(latitude / nodes.size(), longitude / nodes.size());
|
||||
}
|
||||
|
||||
public static LatLon getWeightCenterForNodes(Collection<Node> nodes) {
|
||||
public static LatLon getWeightCenterForNodes(Collection<Node> nodes ) {
|
||||
if (nodes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -77,6 +78,36 @@ public class OsmMapUtils {
|
|||
}
|
||||
return new LatLon(latitude / count, longitude / count);
|
||||
}
|
||||
|
||||
public static LatLon getWeightCenterForWay(Way w) {
|
||||
Collection<Node> nodes = w.getNodes();
|
||||
boolean area = w.getFirstNodeId() == w.getLastNodeId();
|
||||
if (nodes.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
LatLon ll = area ? getMathWeightCenterForNodes(nodes) : getWeightCenterForNodes(nodes);
|
||||
if(ll == null) {
|
||||
return null;
|
||||
}
|
||||
double flat = ll.getLatitude();
|
||||
double flon = ll.getLongitude();
|
||||
if(!area || !MapAlgorithms.containsPoint(nodes, ll.getLatitude(), ll.getLongitude())) {
|
||||
double minDistance = Double.MAX_VALUE;
|
||||
for (Node n : nodes) {
|
||||
if (n != null) {
|
||||
double d = MapUtils.getDistance(n.getLatitude(), n.getLongitude(), ll.getLatitude(), ll.getLongitude());
|
||||
if(d < minDistance) {
|
||||
flon = n.getLongitude();
|
||||
flat = n.getLatitude();
|
||||
minDistance = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new LatLon(flat, flon);
|
||||
}
|
||||
|
||||
|
||||
public static LatLon getMathWeightCenterForNodes(Collection<Node> nodes) {
|
||||
if (nodes.isEmpty()) {
|
||||
|
|
|
@ -178,7 +178,7 @@ public class Way extends Entity {
|
|||
if(nodes == null){
|
||||
return null;
|
||||
}
|
||||
return OsmMapUtils.getWeightCenterForNodes(nodes);
|
||||
return OsmMapUtils.getWeightCenterForWay(this);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
package net.osmand.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import gnu.trove.list.TLongList;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.osm.edit.Node;
|
||||
import net.osmand.osm.edit.OsmMapUtils;
|
||||
|
||||
public class MapAlgorithms {
|
||||
|
||||
|
@ -285,4 +290,44 @@ public class MapAlgorithms {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean containsPoint(Collection<Node> polyNodes, double latitude, double longitude){
|
||||
return countIntersections(polyNodes, latitude, longitude) % 2 == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* count the intersections when going from lat, lon to outside the ring
|
||||
* @param polyNodes2
|
||||
*/
|
||||
private static int countIntersections(Collection<Node> polyNodes, double latitude, double longitude) {
|
||||
int intersections = 0;
|
||||
if (polyNodes.size() == 0) return 0;
|
||||
Node prev = null;
|
||||
Node first = null;
|
||||
Node last = null;
|
||||
for(Node n : polyNodes) {
|
||||
if(prev == null) {
|
||||
prev = n;
|
||||
first = prev;
|
||||
continue;
|
||||
}
|
||||
if(n == null) {
|
||||
continue;
|
||||
}
|
||||
last = n;
|
||||
if (OsmMapUtils.ray_intersect_lon(prev,
|
||||
n, latitude, longitude) != -360.0d) {
|
||||
intersections++;
|
||||
}
|
||||
prev = n;
|
||||
}
|
||||
// special handling, also count first and last, might not be closed, but
|
||||
// we want this!
|
||||
if (OsmMapUtils.ray_intersect_lon(first,
|
||||
last, latitude, longitude) != -360.0d) {
|
||||
intersections++;
|
||||
}
|
||||
return intersections;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue