- Timestamp:
- 2019-05-02T06:55:14+02:00 (6 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/gpx/GpxDistance.java
r14802 r15035 32 32 public static double getLowestDistance(OsmPrimitive p, GpxData gpxData) { 33 33 return gpxData.getTrackPoints() 34 .mapToDouble(tp -> getDistance(p, tp))34 .mapToDouble(tp -> Geometry.getDistance(p, new Node(tp.getCoor()))) 35 35 .filter(x -> x >= 0) 36 36 .min().orElse(Double.MAX_VALUE); … … 42 42 * @param waypoint WayPoint to get the distance from 43 43 * @return The shortest distance between p and waypoint 44 * @deprecated Use {@code Geometry.getDistance(p, new Node(waypoint.getCoor()))} 45 * instead 44 46 */ 47 @Deprecated 45 48 public static double getDistance(OsmPrimitive p, WayPoint waypoint) { 46 if (p instanceof Node) { 47 return getDistanceNode((Node) p, waypoint); 48 } else if (p instanceof Way) { 49 return getDistanceWay((Way) p, waypoint); 50 } else if (p instanceof Relation) { 51 return getDistanceRelation((Relation) p, waypoint); 52 } 53 return Double.MAX_VALUE; 49 return Geometry.getDistance(p, new Node(waypoint.getCoor())); 54 50 } 55 51 … … 59 55 * @param waypoint WayPoint to get the distance to 60 56 * @return The distance between the relation and the waypoint 57 * @deprecated Use {@code Geometry.getDistance(relation, new Node(waypoint.getCoor()))} 58 * instead 61 59 */ 60 @Deprecated 62 61 public static double getDistanceRelation(Relation relation, WayPoint waypoint) { 63 62 double shortestDistance = Double.MAX_VALUE; … … 86 85 * @param waypoint WayPoint to get the distance to 87 86 * @return The distance between the way and the waypoint 87 * @deprecated Use {@code Geometry.getDistanceWayNode(way, new Node(waypoint.getCoor()))} instead 88 88 */ 89 @Deprecated 89 90 public static double getDistanceWay(Way way, WayPoint waypoint) { 90 double shortestDistance = Double.MAX_VALUE; 91 if (way == null || waypoint == null) return shortestDistance; 92 LatLon llwaypoint = waypoint.getCoor(); 93 EastNorth enwaypoint = new EastNorth(llwaypoint.getY(), llwaypoint.getX()); 94 for (int i = 0; i < way.getNodesCount() - 1; i++) { 95 double distance = Double.MAX_VALUE; 96 LatLon llfirst = way.getNode(i).getCoor(); 97 LatLon llsecond = way.getNode(i + 1).getCoor(); 98 EastNorth first = new EastNorth(llfirst.getY(), llfirst.getX()); 99 EastNorth second = new EastNorth(llsecond.getY(), llsecond.getX()); 100 if (first.isValid() && second.isValid()) { 101 EastNorth closestPoint = Geometry.closestPointToSegment(first, second, enwaypoint); 102 distance = llwaypoint.greatCircleDistance(new LatLon(closestPoint.getX(), closestPoint.getY())); 103 } else if (first.isValid() && !second.isValid()) { 104 distance = getDistanceEastNorth(first, waypoint); 105 } else if (!first.isValid() && second.isValid()) { 106 distance = getDistanceEastNorth(second, waypoint); 107 } else if (!first.isValid() && !second.isValid()) { 108 distance = Double.MAX_VALUE; 109 } 110 if (distance < shortestDistance) shortestDistance = distance; 111 112 } 113 return shortestDistance; 91 if (way == null || waypoint == null) return Double.MAX_VALUE; 92 return Geometry.getDistanceWayNode(way, new Node(waypoint.getCoor())); 114 93 } 115 94 … … 119 98 * @param waypoint WayPoint to get the distance to 120 99 * @return The distance between the two points 100 * @deprecated Use {@code Geometry.getDistance(node, new Node(waypoint.getCoor()))} 101 * instead 121 102 */ 103 @Deprecated 122 104 public static double getDistanceNode(Node node, WayPoint waypoint) { 123 if (node == null ) return Double.MAX_VALUE;124 return getDistanceLatLon(node.getCoor(), waypoint);105 if (node == null || waypoint == null) return Double.MAX_VALUE; 106 return Geometry.getDistance(node, new Node(waypoint.getCoor())); 125 107 } 126 108 … … 130 112 * @param waypoint WayPoint to get the distance to 131 113 * @return The distance between the two points 114 * @deprecated Use {@code Geometry.getDistance(new Node(en), new Node(waypoint.getCoor()))} instead 132 115 */ 116 @Deprecated 133 117 public static double getDistanceEastNorth(EastNorth en, WayPoint waypoint) { 134 if (en == null || !en.isValid()) return Double.MAX_VALUE;135 return getDistanceLatLon(new LatLon(en.getY(), en.getX()), waypoint);118 if (en == null || waypoint == null) return Double.MAX_VALUE; 119 return Geometry.getDistance(new Node(en), new Node(waypoint.getCoor())); 136 120 } 137 121 … … 141 125 * @param waypoint WayPoint to get the distance to 142 126 * @return The distance between the two points 127 * @deprecated Use {@code Geometry.getDistance(new Node(latlon), new Node(waypoint.getCoor()))} instead 143 128 */ 129 @Deprecated 144 130 public static double getDistanceLatLon(LatLon latlon, WayPoint waypoint) { 145 131 if (latlon == null || waypoint == null || waypoint.getCoor() == null) return Double.MAX_VALUE; 146 return waypoint.getCoor().greatCircleDistance(latlon);132 return Geometry.getDistance(new Node(latlon), new Node(waypoint.getCoor())); 147 133 } 148 134 } -
trunk/src/org/openstreetmap/josm/tools/Geometry.java
r15021 r15035 10 10 import java.math.MathContext; 11 11 import java.util.ArrayList; 12 import java.util.Collection; 12 13 import java.util.Collections; 13 14 import java.util.Comparator; 15 import java.util.Iterator; 14 16 import java.util.LinkedHashSet; 15 17 import java.util.List; 16 18 import java.util.Set; 19 import java.util.TreeSet; 17 20 import java.util.function.Predicate; 18 21 import java.util.stream.Collectors; … … 31 34 import org.openstreetmap.josm.data.osm.Node; 32 35 import org.openstreetmap.josm.data.osm.NodePositionComparator; 36 import org.openstreetmap.josm.data.osm.OsmPrimitive; 33 37 import org.openstreetmap.josm.data.osm.Relation; 34 38 import org.openstreetmap.josm.data.osm.Way; 39 import org.openstreetmap.josm.data.osm.WaySegment; 35 40 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon; 36 41 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache; … … 1103 1108 return new AreaAndPerimeter(Math.abs(area) / 2, perimeter); 1104 1109 } 1110 1111 /** 1112 * Get the closest primitive to {@code osm} from the collection of 1113 * OsmPrimitive {@code primitives} 1114 * 1115 * The {@code primitives} should be fully downloaded to ensure accuracy. 1116 * 1117 * Note: The complexity of this method is O(n*m), where n is the number of 1118 * children {@code osm} has plus 1, m is the number of children the 1119 * collection of primitives have plus the number of primitives in the 1120 * collection. 1121 * 1122 * @param <T> The return type of the primitive 1123 * @param osm The primitive to get the distances from 1124 * @param primitives The collection of primitives to get the distance to 1125 * @return The closest {@link OsmPrimitive}. This is not determinative. 1126 * To get all primitives that share the same distance, use 1127 * {@link Geometry#getClosestPrimitives}. 1128 * @since 15035 1129 */ 1130 public static <T extends OsmPrimitive> T getClosestPrimitive(OsmPrimitive osm, Collection<T> primitives) { 1131 Collection<T> collection = getClosestPrimitives(osm, primitives); 1132 return collection.iterator().next(); 1133 } 1134 1135 /** 1136 * Get the closest primitives to {@code osm} from the collection of 1137 * OsmPrimitive {@code primitives} 1138 * 1139 * The {@code primitives} should be fully downloaded to ensure accuracy. 1140 * 1141 * Note: The complexity of this method is O(n*m), where n is the number of 1142 * children {@code osm} has plus 1, m is the number of children the 1143 * collection of primitives have plus the number of primitives in the 1144 * collection. 1145 * 1146 * @param <T> The return type of the primitive 1147 * @param osm The primitive to get the distances from 1148 * @param primitives The collection of primitives to get the distance to 1149 * @return The closest {@link OsmPrimitive}s. May be empty. 1150 * @since 15035 1151 */ 1152 public static <T extends OsmPrimitive> Collection<T> getClosestPrimitives(OsmPrimitive osm, Collection<T> primitives) { 1153 double lowestDistance = Double.MAX_VALUE; 1154 TreeSet<T> closest = new TreeSet<>(); 1155 for (T primitive : primitives) { 1156 double distance = getDistance(osm, primitive); 1157 if (Double.isNaN(distance)) continue; 1158 if (distance < lowestDistance) { 1159 closest.clear(); 1160 lowestDistance = distance; 1161 closest.add(primitive); 1162 } else if (distance == lowestDistance) { 1163 closest.add(primitive); 1164 } 1165 } 1166 return closest; 1167 } 1168 1169 /** 1170 * Get the furthest primitive to {@code osm} from the collection of 1171 * OsmPrimitive {@code primitives} 1172 * 1173 * The {@code primitives} should be fully downloaded to ensure accuracy. 1174 * 1175 * It does NOT give the furthest primitive based off of the furthest 1176 * part of that primitive 1177 * 1178 * Note: The complexity of this method is O(n*m), where n is the number of 1179 * children {@code osm} has plus 1, m is the number of children the 1180 * collection of primitives have plus the number of primitives in the 1181 * collection. 1182 * 1183 * @param <T> The return type of the primitive 1184 * @param osm The primitive to get the distances from 1185 * @param primitives The collection of primitives to get the distance to 1186 * @return The furthest {@link OsmPrimitive}. This is not determinative. 1187 * To get all primitives that share the same distance, use 1188 * {@link Geometry#getFurthestPrimitives} 1189 * @since 15035 1190 */ 1191 public static <T extends OsmPrimitive> T getFurthestPrimitive(OsmPrimitive osm, Collection<T> primitives) { 1192 return getFurthestPrimitives(osm, primitives).iterator().next(); 1193 } 1194 1195 /** 1196 * Get the furthest primitives to {@code osm} from the collection of 1197 * OsmPrimitive {@code primitives} 1198 * 1199 * The {@code primitives} should be fully downloaded to ensure accuracy. 1200 * 1201 * It does NOT give the furthest primitive based off of the furthest 1202 * part of that primitive 1203 * 1204 * Note: The complexity of this method is O(n*m), where n is the number of 1205 * children {@code osm} has plus 1, m is the number of children the 1206 * collection of primitives have plus the number of primitives in the 1207 * collection. 1208 * 1209 * @param <T> The return type of the primitive 1210 * @param osm The primitive to get the distances from 1211 * @param primitives The collection of primitives to get the distance to 1212 * @return The furthest {@link OsmPrimitive}s. It may return an empty collection. 1213 * @since 15035 1214 */ 1215 public static <T extends OsmPrimitive> Collection<T> getFurthestPrimitives(OsmPrimitive osm, Collection<T> primitives) { 1216 double furthestDistance = Double.NEGATIVE_INFINITY; 1217 TreeSet<T> furthest = new TreeSet<>(); 1218 for (T primitive : primitives) { 1219 double distance = getDistance(osm, primitive); 1220 if (Double.isNaN(distance)) continue; 1221 if (distance > furthestDistance) { 1222 furthest.clear(); 1223 furthestDistance = distance; 1224 furthest.add(primitive); 1225 } else if (distance == furthestDistance) { 1226 furthest.add(primitive); 1227 } 1228 } 1229 return furthest; 1230 } 1231 1232 /** 1233 * Get the distance between different {@link OsmPrimitive}s 1234 * @param one The primitive to get the distance from 1235 * @param two The primitive to get the distance to 1236 * @return The distance between the primitives in meters 1237 * (or the unit of the current projection, see {@link Projection}). 1238 * May return {@link Double#NaN} if one of the primitives is incomplete. 1239 * 1240 * Note: The complexity is O(n*m), where (n,m) are the number of child 1241 * objects the {@link OsmPrimitive}s have. 1242 * @since 15035 1243 */ 1244 public static double getDistance(OsmPrimitive one, OsmPrimitive two) { 1245 double rValue = Double.MAX_VALUE; 1246 if (one == null || two == null || one.isIncomplete() 1247 || two.isIncomplete()) return Double.NaN; 1248 if (one instanceof Node && two instanceof Node) { 1249 rValue = ((Node) one).getCoor().greatCircleDistance(((Node) two).getCoor()); 1250 } else if (one instanceof Node && two instanceof Way) { 1251 rValue = getDistanceWayNode((Way) two, (Node) one); 1252 } else if (one instanceof Way && two instanceof Node) { 1253 rValue = getDistanceWayNode((Way) one, (Node) two); 1254 } else if (one instanceof Way && two instanceof Way) { 1255 rValue = getDistanceWayWay((Way) one, (Way) two); 1256 } else if (one instanceof Relation && !(two instanceof Relation)) { 1257 for (OsmPrimitive osmPrimitive: ((Relation) one).getMemberPrimitives()) { 1258 double currentDistance = getDistance(osmPrimitive, two); 1259 if (currentDistance < rValue) rValue = currentDistance; 1260 } 1261 } else if (!(one instanceof Relation) && two instanceof Relation) { 1262 rValue = getDistance(two, one); 1263 } else if (one instanceof Relation && two instanceof Relation) { 1264 for (OsmPrimitive osmPrimitive1 : ((Relation) one).getMemberPrimitives()) { 1265 for (OsmPrimitive osmPrimitive2 : ((Relation) two).getMemberPrimitives()) { 1266 double currentDistance = getDistance(osmPrimitive1, osmPrimitive2); 1267 if (currentDistance < rValue) rValue = currentDistance; 1268 } 1269 } 1270 } 1271 return rValue != Double.MAX_VALUE ? rValue : Double.NaN; 1272 } 1273 1274 /** 1275 * Get the distance between a way and a node 1276 * @param way The way to get the distance from 1277 * @param node The node to get the distance to 1278 * @return The distance between the {@code way} and the {@code node} in 1279 * meters (or the unit of the current projection, see {@link Projection}). 1280 * May return {@link Double#NaN} if the primitives are incomplete. 1281 * @since 15035 1282 */ 1283 public static double getDistanceWayNode(Way way, Node node) { 1284 if (way == null || node == null || way.getNodesCount() < 2 || !node.isLatLonKnown()) 1285 return Double.NaN; 1286 1287 double smallest = Double.MAX_VALUE; 1288 EastNorth en0 = node.getEastNorth(); 1289 // go through the nodes as if they were paired 1290 Iterator<Node> iter = way.getNodes().iterator(); 1291 EastNorth en1 = iter.next().getEastNorth(); 1292 while (iter.hasNext()) { 1293 EastNorth en2 = iter.next().getEastNorth(); 1294 double distance = getSegmentNodeDistSq(en1, en2, en0); 1295 if (distance < smallest) 1296 smallest = distance; 1297 en1 = en2; 1298 } 1299 return smallest != Double.MAX_VALUE ? Math.sqrt(smallest) : Double.NaN; 1300 } 1301 1302 /** 1303 * Get the closest {@link WaySegment} from a way to a primitive. 1304 * @param way The {@link Way} to get the distance from and the {@link WaySegment} 1305 * @param primitive The {@link OsmPrimitive} to get the distance to 1306 * @return The {@link WaySegment} that is closest to {@code primitive} from {@code way}. 1307 * If there are multiple {@link WaySegment}s with the same distance, the last 1308 * {@link WaySegment} with the same distance will be returned. 1309 * May return {@code null} if the way has fewer than two nodes or one 1310 * of the primitives is incomplete. 1311 * @since 15035 1312 */ 1313 public static WaySegment getClosestWaySegment(Way way, OsmPrimitive primitive) { 1314 if (way == null || primitive == null || way.isIncomplete() 1315 || primitive.isIncomplete()) return null; 1316 double lowestDistance = Double.MAX_VALUE; 1317 Pair<Node, Node> closestNodes = null; 1318 for (Pair<Node, Node> nodes : way.getNodePairs(false)) { 1319 Way tWay = new Way(); 1320 tWay.addNode(nodes.a); 1321 tWay.addNode(nodes.b); 1322 double distance = getDistance(tWay, primitive); 1323 if (distance < lowestDistance) { 1324 lowestDistance = distance; 1325 closestNodes = nodes; 1326 } 1327 } 1328 if (closestNodes == null) return null; 1329 return lowestDistance != Double.MAX_VALUE ? WaySegment.forNodePair(way, closestNodes.a, closestNodes.b) : null; 1330 } 1331 1332 /** 1333 * Get the distance between different ways. Iterates over the nodes of the ways, complexity is O(n*m) 1334 * (n,m giving the number of nodes) 1335 * @param w1 The first {@link Way} 1336 * @param w2 The second {@link Way} 1337 * @return The shortest distance between the ways in meters 1338 * (or the unit of the current projection, see {@link Projection}). 1339 * May return {@link Double#NaN}. 1340 * @since 15035 1341 */ 1342 public static double getDistanceWayWay(Way w1, Way w2) { 1343 if (w1 == null || w2 == null || w1.getNodesCount() < 2 || w2.getNodesCount() < 2) 1344 return Double.NaN; 1345 double rValue = Double.MAX_VALUE; 1346 Iterator<Node> iter1 = w1.getNodes().iterator(); 1347 Node w1N1 = iter1.next(); 1348 while (iter1.hasNext()) { 1349 Node w1N2 = iter1.next(); 1350 Iterator<Node> iter2 = w2.getNodes().iterator(); 1351 Node w2N1 = iter2.next(); 1352 while (iter2.hasNext()) { 1353 Node w2N2 = iter2.next(); 1354 double distance = getDistanceSegmentSegment(w1N1, w1N2, w2N1, w2N2); 1355 if (distance < rValue) 1356 rValue = distance; 1357 w2N1 = w2N2; 1358 } 1359 w1N1 = w1N2; 1360 } 1361 return rValue != Double.MAX_VALUE ? rValue : Double.NaN; 1362 } 1363 1364 /** 1365 * Get the distance between different {@link WaySegment}s 1366 * @param ws1 A {@link WaySegment} 1367 * @param ws2 A {@link WaySegment} 1368 * @return The distance between the two {@link WaySegment}s in meters 1369 * (or the unit of the current projection, see {@link Projection}). 1370 * May return {@link Double#NaN}. 1371 * @since 15035 1372 */ 1373 public static double getDistanceSegmentSegment(WaySegment ws1, WaySegment ws2) { 1374 return getDistanceSegmentSegment(ws1.getFirstNode(), ws1.getSecondNode(), ws2.getFirstNode(), ws2.getSecondNode()); 1375 } 1376 1377 /** 1378 * Get the distance between different {@link WaySegment}s 1379 * @param ws1Node1 The first node of the first WaySegment 1380 * @param ws1Node2 The second node of the second WaySegment 1381 * @param ws2Node1 The first node of the second WaySegment 1382 * @param ws2Node2 The second node of the second WaySegment 1383 * @return The distance between the two {@link WaySegment}s in meters 1384 * (or the unit of the current projection, see {@link Projection}). 1385 * May return {@link Double#NaN}. 1386 * @since 15035 1387 */ 1388 public static double getDistanceSegmentSegment(Node ws1Node1, Node ws1Node2, Node ws2Node1, Node ws2Node2) { 1389 EastNorth enWs1Node1 = ws1Node1.getEastNorth(); 1390 EastNorth enWs1Node2 = ws1Node2.getEastNorth(); 1391 EastNorth enWs2Node1 = ws2Node1.getEastNorth(); 1392 EastNorth enWs2Node2 = ws2Node2.getEastNorth(); 1393 if (enWs1Node1 == null || enWs1Node2 == null || enWs2Node1 == null || enWs2Node2 == null) 1394 return Double.NaN; 1395 if (getSegmentSegmentIntersection(enWs1Node1, enWs1Node2, enWs2Node1, enWs2Node2) != null) 1396 return 0; 1397 1398 double dist1sq = getSegmentNodeDistSq(enWs1Node1, enWs1Node2, enWs2Node1); 1399 double dist2sq = getSegmentNodeDistSq(enWs1Node1, enWs1Node2, enWs2Node2); 1400 double dist3sq = getSegmentNodeDistSq(enWs2Node1, enWs2Node2, enWs1Node1); 1401 double dist4sq = getSegmentNodeDistSq(enWs2Node1, enWs2Node2, enWs1Node2); 1402 double smallest = Math.min(Math.min(dist1sq, dist2sq), Math.min(dist3sq, dist4sq)); 1403 return smallest != Double.MAX_VALUE ? Math.sqrt(smallest) : Double.NaN; 1404 } 1405 1406 /** 1407 * Calculate closest distance between a line segment s1-s2 and a point p 1408 * @param s1 start of segment 1409 * @param s2 end of segment 1410 * @param p the point 1411 * @return the square of the euclidean distance from p to the closest point on the segment 1412 */ 1413 private static double getSegmentNodeDistSq(EastNorth s1, EastNorth s2, EastNorth p) { 1414 EastNorth c1 = closestPointTo(s1, s2, p, true); 1415 return c1.distanceSq(p); 1416 } 1105 1417 } -
trunk/test/unit/org/openstreetmap/josm/tools/GeometryTest.java
r15034 r15035 10 10 import java.nio.file.Files; 11 11 import java.nio.file.Paths; 12 import java.util.ArrayList; 12 13 import java.util.Arrays; 13 14 import java.util.List; … … 21 22 import org.openstreetmap.josm.data.osm.DataSet; 22 23 import org.openstreetmap.josm.data.osm.Node; 24 import org.openstreetmap.josm.data.osm.OsmPrimitive; 23 25 import org.openstreetmap.josm.data.osm.Relation; 24 26 import org.openstreetmap.josm.data.osm.RelationMember; … … 261 263 assertTrue(Geometry.isPolygonInsideMultiPolygon(w1.getNodes(), mp, null)); 262 264 } 265 266 /** 267 * Test of {@link Geometry#getDistance} method. 268 */ 269 @Test 270 public void testGetDistance() { 271 Node node1 = new Node(new LatLon(0, 0)); 272 Node node2 = new Node(new LatLon(0.1, 1)); 273 Node node3 = new Node(new LatLon(1.1, 0.1)); 274 Node node4 = new Node(new LatLon(1, 1.1)); 275 Way way1 = TestUtils.newWay("", node1, node2); 276 Way way2 = TestUtils.newWay("", node3, node4); 277 Relation testRelation1 = new Relation(); 278 Relation testRelation2 = new Relation(); 279 testRelation1.addMember(new RelationMember("", way1)); 280 testRelation1.addMember(new RelationMember("", way2)); 281 testRelation2.addMember(new RelationMember("", node1)); 282 testRelation2.addMember(new RelationMember("", node2)); 283 testRelation2.addMember(new RelationMember("", node3)); 284 testRelation2.addMember(new RelationMember("", node4)); 285 286 double distance = Geometry.getDistance(null, node3); 287 assertEquals(Double.NaN, distance, 0.1); 288 289 distance = Geometry.getDistance(way1, null); 290 assertEquals(Double.NaN, distance, 0.1); 291 292 distance = Geometry.getDistance(null, null); 293 assertEquals(Double.NaN, distance, 0.1); 294 295 distance = Geometry.getDistance(node1, node2); 296 assertEquals(111874.6474307704, distance, 0.1); 297 298 distance = Geometry.getDistance(way1, node3); 299 assertEquals(120743.55085962385, distance, 0.1); 300 301 distance = Geometry.getDistance(node3, way1); 302 assertEquals(120743.55085962385, distance, 0.1); 303 304 distance = Geometry.getDistance(way1, way2); 305 assertEquals(100803.63714283936, distance, 0.1); 306 307 distance = Geometry.getDistance(testRelation1, new Node(new LatLon(0, 0.5))); 308 assertEquals(5538.354450686605, distance, 0.1); 309 310 distance = Geometry.getDistance(new Node(new LatLon(0, 0.5)), testRelation1); 311 assertEquals(5538.354450686605, distance, 0.1); 312 313 distance = Geometry.getDistance(testRelation1, testRelation2); 314 assertEquals(0.0, distance, 0.1); 315 } 316 317 /** 318 * Test of {@link Geometry#getClosestPrimitive} method 319 */ 320 @Test 321 public void testGetClosestPrimitive() { 322 Node node1 = new Node(new LatLon(0, 0)); 323 Node node2 = new Node(new LatLon(0.1, 1)); 324 Node node3 = new Node(new LatLon(1.1, 0.1)); 325 Node node4 = new Node(new LatLon(1, 1.1)); 326 Way way1 = TestUtils.newWay("", node1, node2); 327 Way way2 = TestUtils.newWay("", node3, node4); 328 329 List<OsmPrimitive> primitives = new ArrayList<>(); 330 primitives.add(way1); 331 primitives.add(way2); 332 OsmPrimitive closest = Geometry.getClosestPrimitive(node1, primitives); 333 assertEquals(way1, closest); 334 } 335 336 /** 337 * Test of {@link Geometry#getFurthestPrimitive} method 338 */ 339 @Test 340 public void testGetFurthestPrimitive() { 341 Node node1 = new Node(new LatLon(0, 0)); 342 Node node2 = new Node(new LatLon(0, 1.1)); 343 Node node3 = new Node(new LatLon(1, 0.1)); 344 Node node4 = new Node(new LatLon(1.1, 1)); 345 Way way1 = TestUtils.newWay("", node1, node2); 346 Way way2 = TestUtils.newWay("", node3, node4); 347 Way way3 = TestUtils.newWay("", node2, node4); 348 Way way4 = TestUtils.newWay("", node1, node3); 349 350 List<OsmPrimitive> primitives = new ArrayList<>(); 351 primitives.add(way1); 352 OsmPrimitive furthest = Geometry.getFurthestPrimitive(new Node(new LatLon(0, 0.75)), primitives); 353 assertEquals(way1, furthest); 354 primitives.add(way2); 355 primitives.add(way3); 356 primitives.add(way4); 357 furthest = Geometry.getFurthestPrimitive(new Node(new LatLon(0, 0.5)), primitives); 358 assertEquals(way2, furthest); 359 furthest = Geometry.getFurthestPrimitive(new Node(new LatLon(.25, 0.5)), primitives); 360 assertEquals(way2, furthest); 361 } 362 363 /** 364 * Test of {@link Geometry#getClosestWaySegment} method 365 */ 366 @Test 367 public void testGetClosestWaySegment() { 368 Node node1 = new Node(new LatLon(0, 0)); 369 Node node2 = new Node(new LatLon(0, 1)); 370 Node node3 = new Node(new LatLon(0.3, 0.5)); 371 Node node4 = new Node(new LatLon(0.1, 0)); 372 Way way1 = TestUtils.newWay("", node1, node2, node3, node4); 373 374 Way closestSegment = Geometry.getClosestWaySegment(way1, new Node(new LatLon(0, 0.5))).toWay(); 375 Assert.assertTrue(closestSegment.containsNode(node1)); 376 Assert.assertTrue(closestSegment.containsNode(node2)); 377 } 378 379 /** 380 * Test of {@link Geometry#getDistanceSegmentSegment} method 381 */ 382 @Test 383 public void testGetDistanceSegmentSegment() { 384 Node node1 = new Node(new LatLon(2.0, 2.0)); 385 Node node2 = new Node(new LatLon(2.0, 3.0)); 386 Node node3 = new Node(new LatLon(2.3, 2.5)); 387 Node node4 = new Node(new LatLon(2.1, 2.0)); 388 389 // connected segments 390 assertEquals(0.0, Geometry.getDistanceSegmentSegment(node1, node2, node3, node1), 0.000001); 391 392 // distance between node 1 and node4 is the shortest 393 double expected = node1.getEastNorth().distance(node4.getEastNorth()); 394 assertEquals(expected, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.000001); 395 396 // crossing segments 397 node4.setCoor(new LatLon(1.9998192774806864, 2.0004056993230455)); 398 assertEquals(0, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.000001); 399 400 // usual case 401 node4.setCoor(new LatLon(2.0002098170882276, 2.0000778643530537)); 402 assertEquals(23.4, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 1.0); 403 404 // similar segments, reversed direction 405 node3.setCoor(node2.getCoor()); 406 node4.setCoor(node1.getCoor()); 407 assertEquals(0.0, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.000001); 408 409 // overlapping segments 410 node3.setCoor(new LatLon(2.0, 2.2)); 411 node4.setCoor(new LatLon(2.0, 2.3)); 412 assertEquals(0.0, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.000001); 413 414 // parallel segments, n1 and n3 at same longitude 415 node3.setCoor(new LatLon(2.1, 2.0)); 416 node4.setCoor(new LatLon(2.1, 2.3)); 417 expected = node1.getEastNorth().distance(node3.getEastNorth()); 418 assertEquals(expected, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.000001); 419 420 // parallel segments 421 node3.setCoor(new LatLon(2.1, 2.1)); 422 assertEquals(expected, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.000001); 423 424 // almost parallel segments 425 node3.setCoor(new LatLon(2.09999999, 2.1)); 426 assertEquals(expected, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.01); 427 assertTrue(expected > Geometry.getDistanceSegmentSegment(node1, node2, node3, node4)); 428 } 429 263 430 }
Note:
See TracChangeset
for help on using the changeset viewer.