Fix poi out of its boundaries

This commit is contained in:
Victor Shcherb 2015-07-07 21:28:17 +03:00
parent 1f3e889ec8
commit 0c158551f1
3 changed files with 79 additions and 3 deletions

View file

@ -7,6 +7,7 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.util.MapAlgorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
public class OsmMapUtils { public class OsmMapUtils {
@ -27,7 +28,7 @@ public class OsmMapUtils {
if (e instanceof Node) { if (e instanceof Node) {
return ((Node) e).getLatLon(); return ((Node) e).getLatLon();
} else if (e instanceof Way) { } else if (e instanceof Way) {
return getWeightCenterForNodes(((Way) e).getNodes()); return getWeightCenterForWay(((Way) e));
} else if (e instanceof Relation) { } else if (e instanceof Relation) {
List<LatLon> list = new ArrayList<LatLon>(); List<LatLon> list = new ArrayList<LatLon>();
for (Entity fe : ((Relation) e).getMembers(null)) { for (Entity fe : ((Relation) e).getMembers(null)) {
@ -58,7 +59,7 @@ public class OsmMapUtils {
return new LatLon(latitude / nodes.size(), longitude / nodes.size()); 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()) { if (nodes.isEmpty()) {
return null; return null;
} }
@ -77,6 +78,36 @@ public class OsmMapUtils {
} }
return new LatLon(latitude / count, longitude / count); 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) { public static LatLon getMathWeightCenterForNodes(Collection<Node> nodes) {
if (nodes.isEmpty()) { if (nodes.isEmpty()) {

View file

@ -178,7 +178,7 @@ public class Way extends Entity {
if(nodes == null){ if(nodes == null){
return null; return null;
} }
return OsmMapUtils.getWeightCenterForNodes(nodes); return OsmMapUtils.getWeightCenterForWay(this);
} }

View file

@ -1,7 +1,12 @@
package net.osmand.util; package net.osmand.util;
import java.util.Collection;
import java.util.List;
import gnu.trove.list.TLongList; import gnu.trove.list.TLongList;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.osm.edit.Node;
import net.osmand.osm.edit.OsmMapUtils;
public class MapAlgorithms { public class MapAlgorithms {
@ -285,4 +290,44 @@ public class MapAlgorithms {
} }
return true; 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;
}
} }