Ticket #17616: 17616_v10.2.patch
File 17616_v10.2.patch, 28.6 KB (added by , 6 years ago) |
---|
-
src/org/openstreetmap/josm/data/gpx/GpxDistance.java
31 31 */ 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); 37 37 } … … 41 41 * @param p OsmPrimitive to get the distance to the WayPoint 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 56 52 /** … … 58 54 * @param relation Relation to get the distance from 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; 64 63 List<Node> nodes = new ArrayList<>(relation.getMemberPrimitives(Node.class)); … … 85 84 * @param way Way to get the distance from 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 116 95 /** … … 118 97 * @param node Node to get the distance from 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 127 109 /** … … 129 111 * @param en The EastNorth to get the distance to 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 138 122 /** … … 140 124 * @param latlon LatLon to get the distance from 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 } -
src/org/openstreetmap/josm/tools/Geometry.java
9 9 import java.math.BigDecimal; 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; 14 15 import java.util.LinkedHashSet; 15 16 import java.util.List; 16 17 import java.util.Set; 18 import java.util.TreeSet; 17 19 import java.util.function.Predicate; 18 20 import java.util.stream.Collectors; 19 21 … … 30 32 import org.openstreetmap.josm.data.osm.MultipolygonBuilder.JoinedPolygon; 31 33 import org.openstreetmap.josm.data.osm.Node; 32 34 import org.openstreetmap.josm.data.osm.NodePositionComparator; 35 import org.openstreetmap.josm.data.osm.OsmPrimitive; 33 36 import org.openstreetmap.josm.data.osm.Relation; 34 37 import org.openstreetmap.josm.data.osm.Way; 38 import org.openstreetmap.josm.data.osm.WaySegment; 35 39 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon; 36 40 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache; 37 41 import org.openstreetmap.josm.data.projection.Projection; … … 1102 1106 } 1103 1107 return new AreaAndPerimeter(Math.abs(area) / 2, perimeter); 1104 1108 } 1109 1110 /** 1111 * Get the closest primitive to {@code osm} from the collection of 1112 * OsmPrimitive {@code primitives} 1113 * 1114 * The {@code primitives} should be fully downloaded to ensure accuracy. 1115 * 1116 * @param <T> The return type of the primitive 1117 * @param osm The primitive to get the distances from 1118 * @param primitives The collection of primitives to get the distance to 1119 * @return The closest {@link OsmPrimitive}. This is not determinative. 1120 * To get all primitives that share the same distance, use 1121 * {@link Geometry#getClosestPrimitives}. 1122 * @since xxx 1123 */ 1124 public static <T extends OsmPrimitive> T getClosestPrimitive(OsmPrimitive osm, Collection<T> primitives) { 1125 Collection<T> collection = getClosestPrimitives(osm, primitives); 1126 return collection.iterator().next(); 1127 } 1128 1129 /** 1130 * Get the closest primitives to {@code osm} from the collection of 1131 * OsmPrimitive {@code primitives} 1132 * 1133 * The {@code primitives} should be fully downloaded to ensure accuracy. 1134 * 1135 * @param <T> The return type of the primitive 1136 * @param osm The primitive to get the distances from 1137 * @param primitives The collection of primitives to get the distance to 1138 * @return The closest {@link OsmPrimitive}s. May be empty. 1139 * @since xxx 1140 */ 1141 public static <T extends OsmPrimitive> Collection<T> getClosestPrimitives(OsmPrimitive osm, Collection<T> primitives) { 1142 double lowestDistance = Double.MAX_VALUE; 1143 TreeSet<T> closest = new TreeSet<>(); 1144 for (T primitive : primitives) { 1145 double distance = getDistance(osm, primitive); 1146 if (Double.isNaN(distance)) continue; 1147 if (distance < lowestDistance) { 1148 closest.clear(); 1149 lowestDistance = distance; 1150 closest.add(primitive); 1151 } else if (distance == lowestDistance) { 1152 closest.add(primitive); 1153 } 1154 } 1155 return closest; 1156 } 1157 1158 /** 1159 * Get the furthest primitive to {@code osm} from the collection of 1160 * OsmPrimitive {@code primitives} 1161 * 1162 * The {@code primitives} should be fully downloaded to ensure accuracy. 1163 * 1164 * It does NOT give the furthest primitive based off of the furthest 1165 * part of that primitive 1166 * @param <T> The return type of the primitive 1167 * @param osm The primitive to get the distances from 1168 * @param primitives The collection of primitives to get the distance to 1169 * @return The furthest {@link OsmPrimitive}. This is not determinative. 1170 * To get all primitives that share the same distance, use 1171 * {@link Geometry#getFurthestPrimitives} 1172 * @since xxx 1173 */ 1174 public static <T extends OsmPrimitive> T getFurthestPrimitive(OsmPrimitive osm, Collection<T> primitives) { 1175 return getFurthestPrimitives(osm, primitives).iterator().next(); 1176 } 1177 1178 /** 1179 * Get the furthest primitives to {@code osm} from the collection of 1180 * OsmPrimitive {@code primitives} 1181 * 1182 * The {@code primitives} should be fully downloaded to ensure accuracy. 1183 * 1184 * It does NOT give the furthest primitive based off of the furthest 1185 * part of that primitive 1186 * @param <T> The return type of the primitive 1187 * @param osm The primitive to get the distances from 1188 * @param primitives The collection of primitives to get the distance to 1189 * @return The furthest {@link OsmPrimitive}s. It may return an empty collection. 1190 * @since xxx 1191 */ 1192 public static <T extends OsmPrimitive> Collection<T> getFurthestPrimitives(OsmPrimitive osm, Collection<T> primitives) { 1193 double furthestDistance = Double.NEGATIVE_INFINITY; 1194 TreeSet<T> furthest = new TreeSet<>(); 1195 for (T primitive : primitives) { 1196 double distance = getDistance(osm, primitive); 1197 if (Double.isNaN(distance)) continue; 1198 if (distance > furthestDistance) { 1199 furthest.clear(); 1200 furthestDistance = distance; 1201 furthest.add(primitive); 1202 } else if (distance == furthestDistance) { 1203 furthest.add(primitive); 1204 } 1205 } 1206 return furthest; 1207 } 1208 1209 /** 1210 * Get the distance between different {@link OsmPrimitive}s 1211 * @param one The primitive to get the distance from 1212 * @param two The primitive to get the distance to 1213 * @return The distance between the primitives in meters 1214 * (or the unit of the current projection, see {@link Projection}). 1215 * May return {@link Double#NaN} if one of the primitives is incomplete. 1216 * @since xxx 1217 */ 1218 public static double getDistance(OsmPrimitive one, OsmPrimitive two) { 1219 double rValue = Double.MAX_VALUE; 1220 if (one == null || two == null || one.isIncomplete() 1221 || two.isIncomplete()) return Double.NaN; 1222 if (one instanceof Node && two instanceof Node) { 1223 rValue = ((Node) one).getCoor().greatCircleDistance(((Node) two).getCoor()); 1224 } else if (one instanceof Node && two instanceof Way) { 1225 rValue = getDistanceWayNode((Way) two, (Node) one); 1226 } else if (one instanceof Way && two instanceof Node) { 1227 rValue = getDistanceWayNode((Way) one, (Node) two); 1228 } else if (one instanceof Way && two instanceof Way) { 1229 rValue = getDistanceWayWay((Way) one, (Way) two); 1230 } else if (one instanceof Relation && !(two instanceof Relation)) { 1231 for (OsmPrimitive osmPrimitive: ((Relation) one).getMemberPrimitives()) { 1232 double currentDistance = getDistance(osmPrimitive, two); 1233 if (currentDistance < rValue) rValue = currentDistance; 1234 } 1235 } else if (!(one instanceof Relation) && two instanceof Relation) { 1236 for (OsmPrimitive osmPrimitive : ((Relation) two).getMemberPrimitives()) { 1237 double currentDistance = getDistance(osmPrimitive, one); 1238 if (currentDistance < rValue) rValue = currentDistance; 1239 } 1240 } else if (one instanceof Relation && two instanceof Relation) { 1241 for (OsmPrimitive osmPrimitive1 : ((Relation) one).getMemberPrimitives()) { 1242 for (OsmPrimitive osmPrimitive2 : ((Relation) two).getMemberPrimitives()) { 1243 double currentDistance = getDistance(osmPrimitive1, osmPrimitive2); 1244 if (currentDistance < rValue) rValue = currentDistance; 1245 } 1246 } 1247 } 1248 return rValue; 1249 } 1250 1251 /** 1252 * Get the distance between a way and a node 1253 * @param way The way to get the distance from 1254 * @param node The node to get the distance to 1255 * @return The distance between the {@code way} and the {@code node} in 1256 * meters (or the unit of the current projection, see {@link Projection}). 1257 * May return {@link Double#NaN} if the primitives are incomplete. 1258 * @since xxx 1259 */ 1260 public static double getDistanceWayNode(Way way, Node node) { 1261 if (way == null || node == null || way.isIncomplete() 1262 || node.isIncomplete()) return Double.NaN; 1263 return getDistanceWayNode(way.getNodePairs(false), node); 1264 } 1265 1266 /** 1267 * Get the distance between a list of paired nodes making up a way and a node 1268 * @param listNodes The paired list of nodes of a way 1269 * @param node The node to get the distance to 1270 * @return The distance between the way described by {@code listNodes} and the {@code node} 1271 */ 1272 private static double getDistanceWayNode(List<Pair<Node, Node>> listNodes, Node node) { 1273 Double rValue = Double.MAX_VALUE; 1274 for (Pair<Node, Node> nodes : listNodes) { 1275 double distance = getDistanceNodeWay(node, nodes.a, nodes.b); 1276 if (distance < rValue) rValue = distance; 1277 } 1278 return rValue; 1279 } 1280 1281 /** 1282 * Get the distance between a node and a set of nodes describing a way 1283 * (pairs of nodes, so {@code [Node a, Node b, Node b, Node c]}, etc.) 1284 * @param node The node to get the distance to 1285 * @param nodes The pairs of nodes that describe the way 1286 * @return The shortest distance between the way and the node 1287 * May return {@code Double.NaN} if the number of {@code nodes} are not 1288 * even (divisible by 2). It does not check to ensure that the node pairs 1289 * make up a way, so you could have {@code [Node a, Node b, Node d, Node e]} 1290 * for the {@code nodes}. 1291 */ 1292 private static double getDistanceNodeWay(Node node, Node... nodes) { 1293 if (nodes.length % 2 != 0 || nodes.length == 0) return Double.NaN; 1294 double rValue = Double.MAX_VALUE; 1295 // go through the nodes as if they were paired 1296 for (int i = 0; i < nodes.length / 2; i++) { 1297 EastNorth point = Geometry.closestPointToSegment( 1298 nodes[2*i].getEastNorth(), nodes[2*i + 1].getEastNorth(), 1299 node.getEastNorth()); 1300 double distance = point.distance(node.getEastNorth()); 1301 if (distance < rValue) rValue = distance; 1302 } 1303 return rValue; 1304 } 1305 1306 /** 1307 * Get the closest {@link WaySegment} from a way to a primitive. 1308 * @param way The {@link Way} to get the distance from and the {@link WaySegment} 1309 * @param primitive The {@link OsmPrimitive} to get the distance to 1310 * @return The {@link WaySegment} that is closest to {@code primitive} from {@code way}. 1311 * If there are multiple {@link WaySegment}s with the same distance, the last 1312 * {@link WaySegment} with the same distance will be returned. 1313 * May return {@code null} if the way has fewer than two nodes or one 1314 * of the primitives is incomplete. 1315 * @since xxx 1316 */ 1317 public static WaySegment getClosestWaySegment(Way way, OsmPrimitive primitive) { 1318 if (way == null || primitive == null || way.isIncomplete() 1319 || primitive.isIncomplete()) return null; 1320 double lowestDistance = Double.MAX_VALUE; 1321 Pair<Node, Node> closestNodes = null; 1322 for (Pair<Node, Node> nodes : way.getNodePairs(false)) { 1323 Way tWay = new Way(); 1324 tWay.addNode(nodes.a); 1325 tWay.addNode(nodes.b); 1326 double distance = getDistance(tWay, primitive); 1327 if (distance < lowestDistance) { 1328 lowestDistance = distance; 1329 closestNodes = nodes; 1330 } 1331 } 1332 if (closestNodes == null) return null; 1333 return WaySegment.forNodePair(way, closestNodes.a, closestNodes.b); 1334 } 1335 1336 /** 1337 * Get the distance between different ways 1338 * @param one The way to get the distance from 1339 * @param two The {@link Way} to get the distance to 1340 * @return The shortest distance between the ways in meters 1341 * (or the unit of the current projection, see {@link Projection}). 1342 * May return {@link Double#NaN}. 1343 * @since xxx 1344 */ 1345 public static double getDistanceWayWay(Way one, Way two) { 1346 if (one == null || two == null || one.isIncomplete() 1347 || two.isIncomplete()) return Double.NaN; 1348 1349 double rValue = Double.MAX_VALUE; 1350 for (Pair<Node, Node> oneNodes : one.getNodePairs(false)) { 1351 for (Pair<Node, Node> twoNodes : two.getNodePairs(false)) { 1352 double distance = getDistanceSegmentSegment(oneNodes.a, oneNodes.b, twoNodes.a, twoNodes.b); 1353 if (distance < rValue) rValue = distance; 1354 } 1355 } 1356 return rValue; 1357 } 1358 1359 /** 1360 * Get the distance between different {@link WaySegment}s 1361 * @param one A {@link WaySegment} to get the distance from 1362 * @param two A {@link WaySegment} to get the distance to 1363 * @return The distance between the two {@link WaySegment}s in meters 1364 * (or the unit of the current projection, see {@link Projection}). 1365 * May return {@link Double#NaN}. 1366 * @since xxx 1367 */ 1368 public static double getDistanceSegmentSegment(WaySegment one, WaySegment two) { 1369 return getDistanceSegmentSegment(one.getFirstNode(), one.getSecondNode(), two.getFirstNode(), two.getSecondNode()); 1370 } 1371 1372 /** 1373 * Get the distance between different {@link WaySegment}s 1374 * @param way1Node1 The first node of the first WaySegment 1375 * @param way1Node2 The second node of the second WaySegment 1376 * @param way2Node1 The first node of the second WaySegment 1377 * @param way2Node2 The second node of the second WaySegment 1378 * @return The distance between the two {@link WaySegment}s in meters 1379 * (or the unit of the current projection, see {@link Projection}). 1380 * May return {@link Double#NaN}. 1381 * @since xxx 1382 */ 1383 public static double getDistanceSegmentSegment(Node way1Node1, Node way1Node2, Node way2Node1, Node way2Node2) { 1384 if (way1Node1.isIncomplete() || way1Node2.isIncomplete() 1385 || way2Node1.isIncomplete() || way2Node2.isIncomplete() 1386 || !way1Node1.isLatLonKnown() || !way1Node2.isLatLonKnown() 1387 || !way2Node1.isLatLonKnown() || !way2Node2.isLatLonKnown()) 1388 return Double.NaN; 1389 EastNorth intersection = getSegmentSegmentIntersection(way1Node1.getEastNorth(), way1Node2.getEastNorth(), 1390 way2Node1.getEastNorth(), way2Node2.getEastNorth()); 1391 if (intersection != null) return 0.0; 1392 1393 double distanceW1N1W2 = getDistanceNodeWay(way1Node1, way2Node1, way2Node2); 1394 double distanceW1N2W2 = getDistanceNodeWay(way1Node2, way2Node1, way2Node2); 1395 double distanceW2N1W1 = getDistanceNodeWay(way2Node1, way1Node1, way1Node2); 1396 double distanceW2N2W1 = getDistanceNodeWay(way2Node2, way1Node1, way1Node2); 1397 return Math.min(Math.min(distanceW1N1W2, distanceW1N2W2), 1398 Math.min(distanceW2N1W1, distanceW2N2W1)); 1399 } 1105 1400 } -
test/unit/org/openstreetmap/josm/tools/GeometryTest.java
7 7 import static org.junit.Assert.assertTrue; 8 8 9 9 import java.io.FileInputStream; 10 import java.util.ArrayList; 10 11 import java.util.Arrays; 11 12 import java.util.List; 12 13 … … 18 19 import org.openstreetmap.josm.data.coor.LatLon; 19 20 import org.openstreetmap.josm.data.osm.DataSet; 20 21 import org.openstreetmap.josm.data.osm.Node; 22 import org.openstreetmap.josm.data.osm.OsmPrimitive; 21 23 import org.openstreetmap.josm.data.osm.Relation; 22 24 import org.openstreetmap.josm.data.osm.RelationMember; 23 25 import org.openstreetmap.josm.data.osm.Way; … … 258 260 // now w1 is inside 259 261 assertTrue(Geometry.isPolygonInsideMultiPolygon(w1.getNodes(), mp, null)); 260 262 } 263 264 /** 265 * Test of {@link Geometry#getDistance} method. 266 */ 267 @Test 268 public void testGetDistance() { 269 Node node1 = new Node(new LatLon(0, 0)); 270 Node node2 = new Node(new LatLon(0.1, 1)); 271 Node node3 = new Node(new LatLon(1.1, 0.1)); 272 Node node4 = new Node(new LatLon(1, 1.1)); 273 Way way1 = TestUtils.newWay("", node1, node2); 274 Way way2 = TestUtils.newWay("", node3, node4); 275 Relation testRelation1 = new Relation(); 276 Relation testRelation2 = new Relation(); 277 testRelation1.addMember(new RelationMember("", way1)); 278 testRelation1.addMember(new RelationMember("", way2)); 279 testRelation2.addMember(new RelationMember("", node1)); 280 testRelation2.addMember(new RelationMember("", node2)); 281 testRelation2.addMember(new RelationMember("", node3)); 282 testRelation2.addMember(new RelationMember("", node4)); 283 284 double distance = Geometry.getDistance(null, node3); 285 assertEquals(Double.NaN, distance, 0.1); 286 287 distance = Geometry.getDistance(way1, null); 288 assertEquals(Double.NaN, distance, 0.1); 289 290 distance = Geometry.getDistance(null, null); 291 assertEquals(Double.NaN, distance, 0.1); 292 293 distance = Geometry.getDistance(node1, node2); 294 assertEquals(111874.6474307704, distance, 0.1); 295 296 distance = Geometry.getDistance(way1, node3); 297 assertEquals(120743.55085962385, distance, 0.1); 298 299 distance = Geometry.getDistance(node3, way1); 300 assertEquals(120743.55085962385, distance, 0.1); 301 302 distance = Geometry.getDistance(way1, way2); 303 assertEquals(100803.63714283936, distance, 0.1); 304 305 distance = Geometry.getDistance(testRelation1, new Node(new LatLon(0, 0.5))); 306 assertEquals(5538.354450686605, distance, 0.1); 307 308 distance = Geometry.getDistance(new Node(new LatLon(0, 0.5)), testRelation1); 309 assertEquals(5538.354450686605, distance, 0.1); 310 311 distance = Geometry.getDistance(testRelation1, testRelation2); 312 assertEquals(0.0, distance, 0.1); 313 } 314 315 /** 316 * Test of {@link Geometry#getClosestPrimitive} method 317 */ 318 @Test 319 public void testGetClosestPrimitive() { 320 Node node1 = new Node(new LatLon(0, 0)); 321 Node node2 = new Node(new LatLon(0.1, 1)); 322 Node node3 = new Node(new LatLon(1.1, 0.1)); 323 Node node4 = new Node(new LatLon(1, 1.1)); 324 Way way1 = TestUtils.newWay("", node1, node2); 325 Way way2 = TestUtils.newWay("", node3, node4); 326 327 List<OsmPrimitive> primitives = new ArrayList<>(); 328 primitives.add(way1); 329 primitives.add(way2); 330 OsmPrimitive closest = Geometry.getClosestPrimitive(node1, primitives); 331 assertEquals(way1, closest); 332 } 333 334 /** 335 * Test of {@link Geometry#getFurthestPrimitive} method 336 */ 337 @Test 338 public void testGetFurthestPrimitive() { 339 Node node1 = new Node(new LatLon(0, 0)); 340 Node node2 = new Node(new LatLon(0, 1.1)); 341 Node node3 = new Node(new LatLon(1, 0.1)); 342 Node node4 = new Node(new LatLon(1.1, 1)); 343 Way way1 = TestUtils.newWay("", node1, node2); 344 Way way2 = TestUtils.newWay("", node3, node4); 345 Way way3 = TestUtils.newWay("", node2, node4); 346 Way way4 = TestUtils.newWay("", node1, node3); 347 348 List<OsmPrimitive> primitives = new ArrayList<>(); 349 primitives.add(way1); 350 OsmPrimitive furthest = Geometry.getFurthestPrimitive(new Node(new LatLon(0, 0.75)), primitives); 351 assertEquals(way1, furthest); 352 primitives.add(way2); 353 primitives.add(way3); 354 primitives.add(way4); 355 furthest = Geometry.getFurthestPrimitive(new Node(new LatLon(0, 0.5)), primitives); 356 assertEquals(way2, furthest); 357 furthest = Geometry.getFurthestPrimitive(new Node(new LatLon(.25, 0.5)), primitives); 358 assertEquals(way2, furthest); 359 } 360 361 /** 362 * Test of {@link Geometry#getClosestWaySegment} method 363 */ 364 @Test 365 public void testGetClosestWaySegment() { 366 Node node1 = new Node(new LatLon(0, 0)); 367 Node node2 = new Node(new LatLon(0, 1)); 368 Node node3 = new Node(new LatLon(0.3, 0.5)); 369 Node node4 = new Node(new LatLon(0.1, 0)); 370 Way way1 = TestUtils.newWay("", node1, node2, node3, node4); 371 372 Way closestSegment = Geometry.getClosestWaySegment(way1, new Node(new LatLon(0, 0.5))).toWay(); 373 Assert.assertTrue(closestSegment.containsNode(node1)); 374 Assert.assertTrue(closestSegment.containsNode(node2)); 375 } 376 377 /** 378 * Test of {@link Geometry#getDistanceSegmentSegment} method 379 */ 380 @Test 381 public void testGetDistanceSegmentSegment() { 382 Node node1 = new Node(new LatLon(2.0, 2.0)); 383 Node node2 = new Node(new LatLon(2.0, 3.0)); 384 Node node3 = new Node(new LatLon(2.3, 2.5)); 385 Node node4 = new Node(new LatLon(2.1, 2.0)); 386 387 // connected segments 388 assertEquals(0.0, Geometry.getDistanceSegmentSegment(node1, node2, node3, node1), 0.000001); 389 390 // distance between node 1 and node4 is the shortest 391 double expected = node1.getEastNorth().distance(node4.getEastNorth()); 392 assertEquals(expected, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.000001); 393 394 // crossing segments 395 node4.setCoor(new LatLon(1.9998192774806864, 2.0004056993230455)); 396 assertEquals(0.0, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.000001); 397 // usual case 398 node4.setCoor(new LatLon(2.0002098170882276, 2.0000778643530537)); 399 assertEquals(23.4, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 1.0); 400 401 // similar segments, reversed direction 402 node3.setCoor(node2.getCoor()); 403 node4.setCoor(node1.getCoor()); 404 assertEquals(0.0, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.000001); 405 406 // overlapping segments 407 node3.setCoor(new LatLon(2.0, 2.2)); 408 node4.setCoor(new LatLon(2.0, 2.3)); 409 assertEquals(0.0, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.000001); 410 411 // parallel segments, n1 and n3 at same longitude 412 node3.setCoor(new LatLon(2.1, 2.0)); 413 node4.setCoor(new LatLon(2.1, 2.3)); 414 expected = node1.getEastNorth().distance(node3.getEastNorth()); 415 assertEquals(expected, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.000001); 416 417 // parallel segments 418 node3.setCoor(new LatLon(2.1, 2.1)); 419 assertEquals(expected, Geometry.getDistanceSegmentSegment(node1, node2, node3, node4), 0.000001); 420 } 261 421 }