Changeset 32398 in osm for applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/TheRing.java
- Timestamp:
- 2016-06-25T11:56:57+02:00 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/TheRing.java
r32395 r32398 1 1 // License: GPL. For details, see LICENSE file. 2 2 package relcontext.actions; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 3 5 4 6 import java.util.ArrayList; … … 45 47 List<Way> rings = new ArrayList<>(); 46 48 for (Way way : ways) { 47 if (way.isClosed() ) {49 if (way.isClosed()) { 48 50 rings.add(way); 49 51 } else 50 52 return false; 51 53 } 52 if (rings.isEmpty() || ways.size() == 1 )54 if (rings.isEmpty() || ways.size() == 1) 53 55 return false; 54 56 … … 57 59 for (int j = i + 1; j < rings.size(); j++) { 58 60 PolygonIntersection intersection = Geometry.polygonIntersection(rings.get(i).getNodes(), rings.get(j).getNodes()); 59 if (intersection == PolygonIntersection.FIRST_INSIDE_SECOND || intersection == PolygonIntersection.SECOND_INSIDE_FIRST )61 if (intersection == PolygonIntersection.FIRST_INSIDE_SECOND || intersection == PolygonIntersection.SECOND_INSIDE_FIRST) 60 62 return false; 61 63 } … … 72 74 log("---------------------------------------"); 73 75 List<TheRing> rings = new ArrayList<>(selection.size()); 74 for (Way w : selection ) {76 for (Way w : selection) { 75 77 rings.add(new TheRing(w)); 76 78 } 77 for (int i = 0; i < rings.size() - 1; i++ ) {78 for (int j = i + 1; j < rings.size(); j++ ) {79 for (int i = 0; i < rings.size() - 1; i++) { 80 for (int j = i + 1; j < rings.size(); j++) { 79 81 rings.get(i).collide(rings.get(j)); 80 82 } … … 108 110 RingSegment segment = splitRingAt(i, split[0], split[1]); 109 111 RingSegment otherSegment = other.splitRingAt(j, split[2], split[3]); 110 if (!areSegmentsEqual(segment, otherSegment) ) 111 throw new IllegalArgumentException("Error: algorithm gave incorrect segments: " + segment + " and " + otherSegment); 112 if (!areSegmentsEqual(segment, otherSegment)) 113 throw new IllegalArgumentException( 114 "Error: algorithm gave incorrect segments: " + segment + " and " + otherSegment); 112 115 segment.makeReference(otherSegment); 113 116 } 114 117 } 115 if (segment1.isReference() ) {118 if (segment1.isReference()) { 116 119 break; 117 120 } … … 126 129 public static Node[] getSplitNodes(List<Node> nodes1, List<Node> nodes2, boolean isRing1, boolean isRing2) { 127 130 int pos = 0; 128 while(pos < nodes1.size() && !nodes2.contains(nodes1.get(pos)) ) {131 while (pos < nodes1.size() && !nodes2.contains(nodes1.get(pos))) { 129 132 pos++; 130 133 } … … 133 136 // rewind a bit 134 137 pos = nodes1.size() - 1; 135 while(pos > 0 && nodes2.contains(nodes1.get(pos)) ) {138 while (pos > 0 && nodes2.contains(nodes1.get(pos))) { 136 139 pos--; 137 140 } 138 141 if (pos == 0 && nodes1.size() == nodes2.size()) { 139 JOptionPane.showMessageDialog(Main.parent, "Two rings are equal, and this must not be.", "Multipolygon from rings", JOptionPane.ERROR_MESSAGE); 142 JOptionPane.showMessageDialog(Main.parent, 143 tr("Two rings are equal, and this must not be."), tr("Multipolygon from rings"), JOptionPane.ERROR_MESSAGE); 140 144 return null; 141 145 } … … 143 147 } 144 148 int firstPos = isRing1 ? pos : nodes1.size(); 145 while(!collideFound) { 149 while (!collideFound) { 146 150 log("pos=" + pos); 147 151 int start1 = pos; … … 152 156 if (last1 >= 0) { 153 157 last2 = incrementBy(start2, -1, nodes2.size(), isRing2); 154 if (last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) ) {158 if (last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2))) { 155 159 increment2 = -1; 156 160 } else { 157 161 last2 = incrementBy(start2, 1, nodes2.size(), isRing2); 158 if (last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) ) {162 if (last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2))) { 159 163 increment2 = 1; 160 164 } … … 165 169 // find the first nodes 166 170 boolean reachedEnd = false; 167 while(!reachedEnd) { 171 while (!reachedEnd) { 168 172 int newLast1 = incrementBy(last1, 1, nodes1.size(), isRing1); 169 173 int newLast2 = incrementBy(last2, increment2, nodes2.size(), isRing2); 170 if (newLast1 < 0 || newLast2 < 0 || !nodes1.get(newLast1).equals(nodes2.get(newLast2)) ) {174 if (newLast1 < 0 || newLast2 < 0 || !nodes1.get(newLast1).equals(nodes2.get(newLast2))) { 171 175 reachedEnd = true; 172 176 } else { … … 184 188 } else { 185 189 pos = last1; 186 while(pos != firstPos && pos >= 0 && !nodes2.contains(nodes1.get(pos)) ) {190 while (pos != firstPos && pos >= 0 && !nodes2.contains(nodes1.get(pos))) { 187 191 pos = incrementBy(pos, 1, nodes1.size(), isRing1); 188 192 } 189 if (pos < 0 || pos == firstPos || !nodes2.contains(nodes1.get(pos)) ) {193 if (pos < 0 || pos == firstPos || !nodes2.contains(nodes1.get(pos))) { 190 194 collideFound = true; 191 195 } … … 197 201 private static int incrementBy(int value, int increment, int limit1, boolean isRing) { 198 202 int result = value + increment; 199 if (result < 0 )203 if (result < 0) 200 204 return isRing ? result + limit1 : -1; 201 else if (result >= limit1 )205 else if (result >= limit1) 202 206 return isRing ? result - limit1 : -1; 203 207 else … … 209 213 List<Node> nodes2 = seg2.getNodes(); 210 214 int size = nodes1.size(); 211 if (size != nodes2.size() )215 if (size != nodes2.size()) 212 216 return false; 213 217 boolean reverse = size > 1 && !nodes1.get(0).equals(nodes2.get(0)); 214 for (int i = 0; i < size; i++ )215 if (!nodes1.get(i).equals(nodes2.get(reverse ? size-1-i : i)) )218 for (int i = 0; i < size; i++) { 219 if (!nodes1.get(i).equals(nodes2.get(reverse ? size-1-i : i))) 216 220 return false; 221 } 217 222 return true; 218 223 } … … 223 228 */ 224 229 private RingSegment splitRingAt(int segmentIndex, Node n1, Node n2) { 225 if (n1.equals(n2) )230 if (n1.equals(n2)) 226 231 throw new IllegalArgumentException("Both nodes are equal, id=" + n1.getUniqueId()); 227 232 RingSegment segment = segments.get(segmentIndex); … … 242 247 // if thirdPart == null, then n2 == lastNode 243 248 int pos = segmentIndex + 1; 244 if (secondPart != null ) {249 if (secondPart != null) { 245 250 segments.add(pos++, secondPart); 246 251 } 247 if (thirdPart != null ) {252 if (thirdPart != null) { 248 253 segments.add(pos++, thirdPart); 249 254 } … … 260 265 // build segments map 261 266 Map<RingSegment, TheRing> segmentMap = new HashMap<>(); 262 for (TheRing ring : rings ) {263 for (RingSegment seg : ring.segments )264 if (!seg.isReference() ) {267 for (TheRing ring : rings) { 268 for (RingSegment seg : ring.segments) { 269 if (!seg.isReference()) { 265 270 segmentMap.put(seg, ring); 266 271 } 272 } 267 273 } 268 274 … … 283 289 284 290 // initializing source way for each ring 285 for (TheRing ring : rings ) {291 for (TheRing ring : rings) { 286 292 ring.putSourceWayFirst(); 287 293 } … … 290 296 private int countNonReferenceSegments() { 291 297 int count = 0; 292 for (RingSegment seg : segments )293 if (!seg.isReference() ) {298 for (RingSegment seg : segments) { 299 if (!seg.isReference()) { 294 300 count++; 295 301 } 302 } 296 303 return count; 297 304 } … … 325 332 relation.put("type", "multipolygon"); 326 333 for (String key : sourceCopy.keySet()) { 327 if (linearTags.contains(key) ) {334 if (linearTags.contains(key)) { 328 335 continue; 329 336 } 330 if (key.equals("natural") && sourceCopy.get("natural").equals("coastline") ) {337 if (key.equals("natural") && sourceCopy.get("natural").equals("coastline")) { 331 338 continue; 332 339 } … … 343 350 Relation rel = null; 344 351 if (relationChangeMap != null) { 345 if (relationChangeMap.containsKey(p) ) {352 if (relationChangeMap.containsKey(p)) { 346 353 rel = relationChangeMap.get(p); 347 354 } else { 348 rel = new Relation((Relation)p); 349 relationChangeMap.put((Relation)p, rel); 355 rel = new Relation((Relation) p); 356 relationChangeMap.put((Relation) p, rel); 350 357 } 351 358 } else { 352 rel = new Relation((Relation)p); 359 rel = new Relation((Relation) p); 353 360 relationCommands.add(new ChangeCommand(p, rel)); 354 361 } 355 for (int i = 0; i < rel.getMembersCount(); i++ )356 if (rel.getMember(i).getMember().equals(source) ) {362 for (int i = 0; i < rel.getMembersCount(); i++) { 363 if (rel.getMember(i).getMember().equals(source)) { 357 364 referencingRelations.put(rel, Integer.valueOf(i)); 358 365 } 359 } 360 } 361 // todo: когда два кольца менÑ�ÑŽÑ‚ одно и то же отношение, в Ñ�пиÑ�ок команд добавлÑ�етÑ�Ñ� 362 // изменение базового отношениÑ� на новое, а не предыдущего 363 // поÑ�тому Ñ�охранÑ�етÑ�Ñ� только первое изменение 366 } 367 } 368 } 364 369 365 370 List<Command> commands = new ArrayList<>(); … … 368 373 boolean needAdding = !seg.isWayConstructed(); 369 374 Way w = seg.constructWay(seg.isReference() ? null : sourceCopy); 370 if (needAdding ) {375 if (needAdding) { 371 376 commands.add(new AddCommand(w)); 372 377 } … … 383 388 } 384 389 } 385 if (createMultipolygon ) {390 if (createMultipolygon) { 386 391 relation.addMember(new RelationMember("outer", w)); 387 392 } 388 393 } 389 if (!foundOwnWay ) {394 if (!foundOwnWay) { 390 395 commands.add(new DeleteCommand(source)); 391 396 } 392 397 commands.addAll(relationCommands); 393 if (createMultipolygon ) {398 if (createMultipolygon) { 394 399 commands.add(new AddCommand(relation)); 395 400 } … … 398 403 399 404 public static void updateCommandsWithRelations(List<Command> commands, Map<Relation, Relation> relationCache) { 400 for (Relation src : relationCache.keySet() ) {405 for (Relation src : relationCache.keySet()) { 401 406 commands.add(new ChangeCommand(src, relationCache.get(src))); 402 407 } … … 414 419 StringBuilder sb = new StringBuilder("TheRing@"); 415 420 sb.append(this.hashCode()).append('[').append("wayId: ").append(source == null ? "null" : source.getUniqueId()).append("; segments: "); 416 if (segments.isEmpty() ) {421 if (segments.isEmpty()) { 417 422 sb.append("empty"); 418 423 } else { 419 424 sb.append(segments.get(0)); 420 for (int i = 1; i < segments.size(); i++ ) {425 for (int i = 1; i < segments.size(); i++) { 421 426 sb.append(", ").append(segments.get(i)); 422 427 } … … 425 430 } 426 431 427 /**428 * Appends "append" to "base" so the closed polygon forms.429 */430 /*private static void closePolygon(List<Node> base, List<Node> append) {431 if (append.get(0).equals(base.get(0)) && append.get(append.size() - 1).equals(base.get(base.size() - 1))) {432 List<Node> ap2 = new ArrayList<Node>(append);433 Collections.reverse(ap2);434 append = ap2;435 }436 base.remove(base.size() - 1);437 base.addAll(append);438 }*/439 440 /**441 * Checks if a middle point between two nodes is inside a polygon. Useful to check if the way is inside.442 */443 /*private static boolean segmentInsidePolygon(Node n1, Node n2, List<Node> polygon) {444 EastNorth en1 = n1.getEastNorth();445 EastNorth en2 = n2.getEastNorth();446 Node testNode = new Node(new EastNorth((en1.east() + en2.east()) / 2.0, (en1.north() + en2.north()) / 2.0));447 return Geometry.nodeInsidePolygon(testNode, polygon);448 }*/449 450 432 private static void log(String s) { 451 // System.out.println(s);433 Main.debug(s); 452 434 } 453 435 … … 459 441 private boolean isRing; 460 442 461 /*private RingSegment() { 462 }*/ 463 464 public RingSegment(Way w) { 443 RingSegment(Way w) { 465 444 this(w.getNodes()); 466 445 } 467 446 468 publicRingSegment(List<Node> nodes) {447 RingSegment(List<Node> nodes) { 469 448 this.nodes = nodes; 470 449 isRing = nodes.size() > 1 && nodes.get(0).equals(nodes.get(nodes.size() - 1)); 471 if (isRing ) {450 if (isRing) { 472 451 nodes.remove(nodes.size() - 1); 473 452 } 474 453 references = null; 475 454 } 476 477 /*public RingSegment(RingSegment ref) {478 this.nodes = null;479 this.references = ref;480 }*/481 455 482 456 /** … … 487 461 */ 488 462 public RingSegment split(Node n) { 489 if (nodes == null )463 if (nodes == null) 490 464 throw new IllegalArgumentException("Cannot split segment: it is a reference"); 491 465 int pos = nodes.indexOf(n); 492 if (pos <= 0 || pos >= nodes.size() - 1 )466 if (pos <= 0 || pos >= nodes.size() - 1) 493 467 return null; 494 468 List<Node> newNodes = new ArrayList<>(nodes.subList(pos, nodes.size())); … … 503 477 */ 504 478 public RingSegment split(Node n1, Node n2) { 505 if (nodes == null )479 if (nodes == null) 506 480 throw new IllegalArgumentException("Cannot split segment: it is a reference"); 507 481 if (!isRing) { 508 if (n1 == null || nodes.get(0).equals(n1) || nodes.get(nodes.size() - 1).equals(n1) )482 if (n1 == null || nodes.get(0).equals(n1) || nodes.get(nodes.size() - 1).equals(n1)) 509 483 return split(n2); 510 if (n2 == null || nodes.get(0).equals(n2) || nodes.get(nodes.size() - 1).equals(n2) )484 if (n2 == null || nodes.get(0).equals(n2) || nodes.get(nodes.size() - 1).equals(n2)) 511 485 return split(n1); 512 486 throw new IllegalArgumentException("Split for two nodes is called for not-ring: " + this); … … 514 488 int pos1 = nodes.indexOf(n1); 515 489 int pos2 = nodes.indexOf(n2); 516 if (pos1 == pos2 )490 if (pos1 == pos2) 517 491 return null; 518 492 … … 521 495 newNodes.addAll(nodes.subList(pos2, nodes.size())); 522 496 newNodes.addAll(nodes.subList(0, pos1 + 1)); 523 if (pos2 + 1 < nodes.size() ) {497 if (pos2 + 1 < nodes.size()) { 524 498 nodes.subList(pos2 + 1, nodes.size()).clear(); 525 499 } 526 if (pos1 > 0 ) {500 if (pos1 > 0) { 527 501 nodes.subList(0, pos1).clear(); 528 502 } … … 541 515 542 516 public List<Node> getWayNodes() { 543 if (nodes == null )517 if (nodes == null) 544 518 throw new IllegalArgumentException("Won't give you wayNodes: it is a reference"); 545 519 List<Node> wayNodes = new ArrayList<>(nodes); 546 if (isRing ) {520 if (isRing) { 547 521 wayNodes.add(wayNodes.get(0)); 548 522 } … … 576 550 577 551 public Way constructWay(Way template) { 578 if (isReference() )552 if (isReference()) 579 553 return references.constructWay(template); 580 554 if (resultingWay == null) { … … 590 564 591 565 public void overrideWay(Way source) { 592 if (isReference() ) {566 if (isReference()) { 593 567 references.overrideWay(source); 594 568 } else { … … 598 572 } 599 573 600 /**601 * Compares two segments with respect to referencing.602 * @return true if ways are equals, or one references another.603 */604 /*public boolean isReferencingEqual(RingSegment other) {605 return this.equals(other) || (other.isReference() && other.references == this) || (isReference() && references == other);606 }*/607 608 574 @Override 609 575 public String toString() { 610 576 StringBuilder sb = new StringBuilder("RingSegment@"); 611 577 sb.append(this.hashCode()).append('['); 612 if (isReference() ) {578 if (isReference()) { 613 579 sb.append("references ").append(references.hashCode()); 614 } else if (nodes.isEmpty() ) {580 } else if (nodes.isEmpty()) { 615 581 sb.append("empty"); 616 582 } else { 617 if (isRing ) {583 if (isRing) { 618 584 sb.append("ring:"); 619 585 } 620 586 sb.append(nodes.get(0).getUniqueId()); 621 for (int i = 1; i < nodes.size(); i++ ) {587 for (int i = 1; i < nodes.size(); i++) { 622 588 sb.append(',').append(nodes.get(i).getUniqueId()); 623 589 }
Note:
See TracChangeset
for help on using the changeset viewer.
