Ignore:
Timestamp:
2014-10-19T01:27:04+02:00 (10 years ago)
Author:
donvip
Message:

[josm_plugins] fix java 7 warnings / global usage of try-with-resource

File:
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/reltoolbox/src/relcontext/actions/TheRing.java

    r30737 r30738  
    3636
    3737    public TheRing( Way source ) {
    38         this.source = source;
    39         segments = new ArrayList<>(1);
    40         segments.add(new RingSegment(source));
     38    this.source = source;
     39    segments = new ArrayList<>(1);
     40    segments.add(new RingSegment(source));
    4141    }
    4242   
    4343    public static boolean areAllOfThoseRings( Collection<Way> ways ) {
    44         List<Way> rings = new ArrayList<>();
    45         for( Way way : ways ) {
    46             if( way.isClosed() )
    47                 rings.add(way);
    48             else
    49                 return false;
    50         }
    51         if( rings.isEmpty() || ways.size() == 1 )
    52             return false;
    53 
    54         // check for non-containment of rings
    55         for( int i = 0; i < rings.size() - 1; i++ ) {
    56             for( int j = i + 1; j < rings.size(); j++ ) {
    57                 PolygonIntersection intersection = Geometry.polygonIntersection(rings.get(i).getNodes(), rings.get(j).getNodes());
    58                 if( intersection == PolygonIntersection.FIRST_INSIDE_SECOND || intersection == PolygonIntersection.SECOND_INSIDE_FIRST )
    59                     return false;
    60             }
    61         }
    62 
    63         return true;
     44    List<Way> rings = new ArrayList<>();
     45    for( Way way : ways ) {
     46        if( way.isClosed() )
     47        rings.add(way);
     48        else
     49        return false;
     50    }
     51    if( rings.isEmpty() || ways.size() == 1 )
     52        return false;
     53
     54    // check for non-containment of rings
     55    for( int i = 0; i < rings.size() - 1; i++ ) {
     56        for( int j = i + 1; j < rings.size(); j++ ) {
     57        PolygonIntersection intersection = Geometry.polygonIntersection(rings.get(i).getNodes(), rings.get(j).getNodes());
     58        if( intersection == PolygonIntersection.FIRST_INSIDE_SECOND || intersection == PolygonIntersection.SECOND_INSIDE_FIRST )
     59            return false;
     60        }
     61    }
     62
     63    return true;
    6464    }
    6565
     
    6969     */
    7070    public static List<Relation> makeManySimpleMultipolygons( Collection<Way> selection, List<Command> commands ) {
    71         log("---------------------------------------");
    72         List<TheRing> rings = new ArrayList<>(selection.size());
    73         for( Way w : selection )
    74             rings.add(new TheRing(w));
    75         for( int i = 0; i < rings.size() - 1; i++ )
    76             for( int j = i + 1; j < rings.size(); j++ )
    77                 rings.get(i).collide(rings.get(j));
    78         redistributeSegments(rings);
    79         List<Relation> relations = new ArrayList<>();
    80         Map<Relation, Relation> relationCache = new HashMap<>();
    81         for( TheRing r : rings ) {
    82             commands.addAll(r.getCommands(relationCache));
    83             relations.add(r.getRelation());
    84         }
    85         updateCommandsWithRelations(commands, relationCache);
    86         return relations;
     71    log("---------------------------------------");
     72    List<TheRing> rings = new ArrayList<>(selection.size());
     73    for( Way w : selection )
     74        rings.add(new TheRing(w));
     75    for( int i = 0; i < rings.size() - 1; i++ )
     76        for( int j = i + 1; j < rings.size(); j++ )
     77        rings.get(i).collide(rings.get(j));
     78    redistributeSegments(rings);
     79    List<Relation> relations = new ArrayList<>();
     80    Map<Relation, Relation> relationCache = new HashMap<>();
     81    for( TheRing r : rings ) {
     82        commands.addAll(r.getCommands(relationCache));
     83        relations.add(r.getRelation());
     84    }
     85    updateCommandsWithRelations(commands, relationCache);
     86    return relations;
    8787    }
    8888
    8989    public void collide( TheRing other ) {
    90         boolean collideNoted = false;
    91         for( int i = 0; i < segments.size(); i++ ) {
    92             RingSegment segment1 = segments.get(i);
    93             if( !segment1.isReference() ) {
    94                 for( int j = 0; j < other.segments.size(); j++ ) {
    95                     RingSegment segment2 = other.segments.get(j);
    96                     if( !segment2.isReference() ) {
    97                         log("Comparing " + segment1 + " and " + segment2);
    98                         Node[] split = getSplitNodes(segment1.getNodes(), segment2.getNodes(), segment1.isRing(), segment2.isRing());
    99                         if( split != null ) {
    100                             if( !collideNoted ) {
    101                                 log("Rings for ways " + source.getUniqueId() + " and " + other.source.getUniqueId() + " collide.");
    102                                 collideNoted = true;
    103                             }
    104                             RingSegment segment = splitRingAt(i, split[0], split[1]);
    105                             RingSegment otherSegment = other.splitRingAt(j, split[2], split[3]);
    106                             if( !areSegmentsEqual(segment, otherSegment) )
    107                                 throw new IllegalArgumentException("Error: algorithm gave incorrect segments: " + segment + " and " + otherSegment);
    108                             segment.makeReference(otherSegment);
    109                         }
    110                     }
    111                     if( segment1.isReference() )
    112                         break;
    113                 }
    114             }
    115         }
     90    boolean collideNoted = false;
     91    for( int i = 0; i < segments.size(); i++ ) {
     92        RingSegment segment1 = segments.get(i);
     93        if( !segment1.isReference() ) {
     94        for( int j = 0; j < other.segments.size(); j++ ) {
     95            RingSegment segment2 = other.segments.get(j);
     96            if( !segment2.isReference() ) {
     97            log("Comparing " + segment1 + " and " + segment2);
     98            Node[] split = getSplitNodes(segment1.getNodes(), segment2.getNodes(), segment1.isRing(), segment2.isRing());
     99            if( split != null ) {
     100                if( !collideNoted ) {
     101                log("Rings for ways " + source.getUniqueId() + " and " + other.source.getUniqueId() + " collide.");
     102                collideNoted = true;
     103                }
     104                RingSegment segment = splitRingAt(i, split[0], split[1]);
     105                RingSegment otherSegment = other.splitRingAt(j, split[2], split[3]);
     106                if( !areSegmentsEqual(segment, otherSegment) )
     107                throw new IllegalArgumentException("Error: algorithm gave incorrect segments: " + segment + " and " + otherSegment);
     108                segment.makeReference(otherSegment);
     109            }
     110            }
     111            if( segment1.isReference() )
     112            break;
     113        }
     114        }
     115    }
    116116    }
    117117   
     
    120120     */
    121121    public static Node[] getSplitNodes( List<Node> nodes1, List<Node> nodes2, boolean isRing1, boolean isRing2 ) {
    122         int pos = 0;
    123         while( pos < nodes1.size() && !nodes2.contains(nodes1.get(pos)) )
    124             pos++;
    125         boolean collideFound = pos == nodes1.size();
    126         if( pos == 0 && isRing1 ) {
    127             // rewind a bit
    128             pos = nodes1.size() - 1;
    129             while( pos > 0 && nodes2.contains(nodes1.get(pos)) )
    130                 pos--;
    131             if( pos == 0 && nodes1.size() == nodes2.size() ) {
    132                 JOptionPane.showMessageDialog(Main.parent, "Two rings are equal, and this must not be.", "Multipolygon from rings", JOptionPane.ERROR_MESSAGE);
    133                 return null;
    134             }
    135             pos = pos == nodes1.size() - 1 ? 0 : pos + 1;
    136         }
    137         int firstPos = isRing1 ? pos : nodes1.size();
    138         while( !collideFound ) {
    139             log("pos=" + pos);
    140             int start1 = pos;
    141             int start2 = nodes2.indexOf(nodes1.get(start1));
    142             int last1 = incrementBy(start1, 1, nodes1.size(), isRing1);
    143             int last2 = start2;
    144             int increment2 = 0;
    145             if( last1 >= 0 ) {
    146                 last2 = incrementBy(start2, -1, nodes2.size(), isRing2);
    147                 if( last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) )
    148                     increment2 = -1;
    149                 else {
    150                     last2 = incrementBy(start2, 1, nodes2.size(), isRing2);
    151                     if( last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) )
    152                         increment2 = 1;
    153                 }
    154             }
    155             log("last1=" + last1 + " last2=" + last2 + " increment2=" + increment2);
    156             if( increment2 != 0 ) {
    157                 // find the first nodes
    158                 boolean reachedEnd = false;
    159                 while( !reachedEnd ) {
    160                     int newLast1 = incrementBy(last1, 1, nodes1.size(), isRing1);
    161                     int newLast2 = incrementBy(last2, increment2, nodes2.size(), isRing2);
    162                     if( newLast1 < 0 || newLast2 < 0 || !nodes1.get(newLast1).equals(nodes2.get(newLast2)) )
    163                         reachedEnd = true;
    164                     else {
    165                         last1 = newLast1;
    166                         last2 = newLast2;
    167                     }
    168                 }
    169                 log("last1=" + last1 + " last2=" + last2);
    170                 if( increment2 < 0 ) {
    171                     int tmp = start2;
    172                     start2 = last2;
    173                     last2 = tmp;
    174                 }
    175                 return new Node[] {nodes1.get(start1), nodes1.get(last1), nodes2.get(start2), nodes2.get(last2)};
    176             } else {
    177                 pos = last1;
    178                 while( pos != firstPos && pos >= 0 && !nodes2.contains(nodes1.get(pos)) )
    179                     pos = incrementBy(pos, 1, nodes1.size(), isRing1);
    180                 if( pos < 0 || pos == firstPos || !nodes2.contains(nodes1.get(pos)) )
    181                     collideFound = true;
    182             }
    183         }
    184         return null;
     122    int pos = 0;
     123    while( pos < nodes1.size() && !nodes2.contains(nodes1.get(pos)) )
     124        pos++;
     125    boolean collideFound = pos == nodes1.size();
     126    if( pos == 0 && isRing1 ) {
     127        // rewind a bit
     128        pos = nodes1.size() - 1;
     129        while( pos > 0 && nodes2.contains(nodes1.get(pos)) )
     130        pos--;
     131        if( pos == 0 && nodes1.size() == nodes2.size() ) {
     132        JOptionPane.showMessageDialog(Main.parent, "Two rings are equal, and this must not be.", "Multipolygon from rings", JOptionPane.ERROR_MESSAGE);
     133        return null;
     134        }
     135        pos = pos == nodes1.size() - 1 ? 0 : pos + 1;
     136    }
     137    int firstPos = isRing1 ? pos : nodes1.size();
     138    while( !collideFound ) {
     139        log("pos=" + pos);
     140        int start1 = pos;
     141        int start2 = nodes2.indexOf(nodes1.get(start1));
     142        int last1 = incrementBy(start1, 1, nodes1.size(), isRing1);
     143        int last2 = start2;
     144        int increment2 = 0;
     145        if( last1 >= 0 ) {
     146        last2 = incrementBy(start2, -1, nodes2.size(), isRing2);
     147        if( last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) )
     148            increment2 = -1;
     149        else {
     150            last2 = incrementBy(start2, 1, nodes2.size(), isRing2);
     151            if( last2 >= 0 && nodes1.get(last1).equals(nodes2.get(last2)) )
     152            increment2 = 1;
     153        }
     154        }
     155        log("last1=" + last1 + " last2=" + last2 + " increment2=" + increment2);
     156        if( increment2 != 0 ) {
     157        // find the first nodes
     158        boolean reachedEnd = false;
     159        while( !reachedEnd ) {
     160            int newLast1 = incrementBy(last1, 1, nodes1.size(), isRing1);
     161            int newLast2 = incrementBy(last2, increment2, nodes2.size(), isRing2);
     162            if( newLast1 < 0 || newLast2 < 0 || !nodes1.get(newLast1).equals(nodes2.get(newLast2)) )
     163            reachedEnd = true;
     164            else {
     165            last1 = newLast1;
     166            last2 = newLast2;
     167            }
     168        }
     169        log("last1=" + last1 + " last2=" + last2);
     170        if( increment2 < 0 ) {
     171            int tmp = start2;
     172            start2 = last2;
     173            last2 = tmp;
     174        }
     175        return new Node[] {nodes1.get(start1), nodes1.get(last1), nodes2.get(start2), nodes2.get(last2)};
     176        } else {
     177        pos = last1;
     178        while( pos != firstPos && pos >= 0 && !nodes2.contains(nodes1.get(pos)) )
     179            pos = incrementBy(pos, 1, nodes1.size(), isRing1);
     180        if( pos < 0 || pos == firstPos || !nodes2.contains(nodes1.get(pos)) )
     181            collideFound = true;
     182        }
     183    }
     184    return null;
    185185    }
    186186   
    187187    private static int incrementBy( int value, int increment, int limit1, boolean isRing ) {
    188         int result = value + increment;
    189         if( result < 0 )
    190             return isRing ? result + limit1 : -1;
    191         else if( result >= limit1 )
    192             return isRing ? result - limit1 : -1;
    193         else
    194             return result;
     188    int result = value + increment;
     189    if( result < 0 )
     190        return isRing ? result + limit1 : -1;
     191    else if( result >= limit1 )
     192        return isRing ? result - limit1 : -1;
     193    else
     194        return result;
    195195    }
    196196   
    197197    private boolean areSegmentsEqual( RingSegment seg1, RingSegment seg2 ) {
    198         List<Node> nodes1 = seg1.getNodes();
    199         List<Node> nodes2 = seg2.getNodes();
    200         int size = nodes1.size();
    201         if( size != nodes2.size() )
    202             return false;
    203         boolean reverse = size > 1 && !nodes1.get(0).equals(nodes2.get(0));
    204         for( int i = 0; i < size; i++ )
    205             if( !nodes1.get(i).equals(nodes2.get(reverse ? size-1-i : i)) )
    206                 return false;
    207         return true;
     198    List<Node> nodes1 = seg1.getNodes();
     199    List<Node> nodes2 = seg2.getNodes();
     200    int size = nodes1.size();
     201    if( size != nodes2.size() )
     202        return false;
     203    boolean reverse = size > 1 && !nodes1.get(0).equals(nodes2.get(0));
     204    for( int i = 0; i < size; i++ )
     205        if( !nodes1.get(i).equals(nodes2.get(reverse ? size-1-i : i)) )
     206        return false;
     207    return true;
    208208    }
    209209
     
    213213     */
    214214    private RingSegment splitRingAt( int segmentIndex, Node n1, Node n2 ) {
    215         if( n1.equals(n2) )
    216             throw new IllegalArgumentException("Both nodes are equal, id=" + n1.getUniqueId());
    217         RingSegment segment = segments.get(segmentIndex);
    218         boolean isRing = segment.isRing();
    219         log("Split segment " + segment + " at nodes " + n1.getUniqueId() + " and " + n2.getUniqueId());
    220         boolean reversed = segment.getNodes().indexOf(n2) < segment.getNodes().indexOf(n1);
    221         if( reversed && !isRing ) {
    222             // order nodes
    223             Node tmp = n1;
    224             n1 = n2;
    225             n2 = tmp;
    226         }
    227         RingSegment secondPart = isRing ? segment.split(n1, n2) : segment.split(n1);
    228         // if secondPart == null, then n1 == firstNode
    229         RingSegment thirdPart = isRing ? null : secondPart == null ? segment.split(n2) : secondPart.split(n2);
    230         // if secondPart == null, then thirdPart is between n1 and n2
    231         // otherwise, thirdPart is between n2 and lastNode
    232         // if thirdPart == null, then n2 == lastNode
    233         int pos = segmentIndex + 1;
    234         if( secondPart != null )
    235             segments.add(pos++, secondPart);
    236         if( thirdPart != null )
    237             segments.add(pos++, thirdPart);
    238         return isRing || secondPart == null ? segment : secondPart;
     215    if( n1.equals(n2) )
     216        throw new IllegalArgumentException("Both nodes are equal, id=" + n1.getUniqueId());
     217    RingSegment segment = segments.get(segmentIndex);
     218    boolean isRing = segment.isRing();
     219    log("Split segment " + segment + " at nodes " + n1.getUniqueId() + " and " + n2.getUniqueId());
     220    boolean reversed = segment.getNodes().indexOf(n2) < segment.getNodes().indexOf(n1);
     221    if( reversed && !isRing ) {
     222        // order nodes
     223        Node tmp = n1;
     224        n1 = n2;
     225        n2 = tmp;
     226    }
     227    RingSegment secondPart = isRing ? segment.split(n1, n2) : segment.split(n1);
     228    // if secondPart == null, then n1 == firstNode
     229    RingSegment thirdPart = isRing ? null : secondPart == null ? segment.split(n2) : secondPart.split(n2);
     230    // if secondPart == null, then thirdPart is between n1 and n2
     231    // otherwise, thirdPart is between n2 and lastNode
     232    // if thirdPart == null, then n2 == lastNode
     233    int pos = segmentIndex + 1;
     234    if( secondPart != null )
     235        segments.add(pos++, secondPart);
     236    if( thirdPart != null )
     237        segments.add(pos++, thirdPart);
     238    return isRing || secondPart == null ? segment : secondPart;
    239239    }
    240240
     
    246246     */
    247247    public static void redistributeSegments( List<TheRing> rings ) {
    248         // build segments map
    249         Map<RingSegment, TheRing> segmentMap = new HashMap<>();
    250         for( TheRing ring : rings )
    251             for( RingSegment seg : ring.segments )
    252                 if( !seg.isReference() )
    253                     segmentMap.put(seg, ring);
    254 
    255         // rearrange references
    256         for( int i = 0; i < rings.size(); i++ ) {
    257             TheRing ring = rings.get(i);
    258             if( ring.countNonReferenceSegments() == 0 ) {
    259                 // need to find one non-reference segment
    260                 for( RingSegment seg : ring.segments ) {
    261                     TheRing otherRing = segmentMap.get(seg.references);
    262                     if( otherRing.countNonReferenceSegments() > 1 ) {
    263                         // we could check for >0, but it is prone to deadlocking
    264                         seg.swapReference();
    265                     }
    266                 }
    267             }
    268         }
    269 
    270         // initializing source way for each ring
    271         for( TheRing ring : rings )
    272             ring.putSourceWayFirst();
     248    // build segments map
     249    Map<RingSegment, TheRing> segmentMap = new HashMap<>();
     250    for( TheRing ring : rings )
     251        for( RingSegment seg : ring.segments )
     252        if( !seg.isReference() )
     253            segmentMap.put(seg, ring);
     254
     255    // rearrange references
     256    for( int i = 0; i < rings.size(); i++ ) {
     257        TheRing ring = rings.get(i);
     258        if( ring.countNonReferenceSegments() == 0 ) {
     259        // need to find one non-reference segment
     260        for( RingSegment seg : ring.segments ) {
     261            TheRing otherRing = segmentMap.get(seg.references);
     262            if( otherRing.countNonReferenceSegments() > 1 ) {
     263            // we could check for >0, but it is prone to deadlocking
     264            seg.swapReference();
     265            }
     266        }
     267        }
     268    }
     269
     270    // initializing source way for each ring
     271    for( TheRing ring : rings )
     272        ring.putSourceWayFirst();
    273273    }
    274274
    275275    private int countNonReferenceSegments() {
    276         int count = 0;
    277         for( RingSegment seg : segments )
    278             if( !seg.isReference() )
    279                 count++;
    280         return count;
     276    int count = 0;
     277    for( RingSegment seg : segments )
     278        if( !seg.isReference() )
     279        count++;
     280    return count;
    281281    }
    282282
    283283    public void putSourceWayFirst() {
    284         for( RingSegment seg : segments ) {
    285             if( !seg.isReference() ) {
    286                 seg.overrideWay(source);
    287                 return;
    288             }
    289         }
     284    for( RingSegment seg : segments ) {
     285        if( !seg.isReference() ) {
     286        seg.overrideWay(source);
     287        return;
     288        }
     289    }
    290290    }
    291291   
    292292    public List<Command> getCommands() {
    293         return getCommands(true, null);
     293    return getCommands(true, null);
    294294    }
    295295   
    296296    public List<Command> getCommands( Map<Relation, Relation> relationChangeMap ) {
    297         return getCommands(true, relationChangeMap);
     297    return getCommands(true, relationChangeMap);
    298298    }
    299299   
     
    303303     */
    304304    public List<Command> getCommands( boolean createMultipolygon, Map<Relation, Relation> relationChangeMap ) {
    305         Way sourceCopy = new Way(source);
    306         if( createMultipolygon ) {
    307             Collection<String> linearTags = Main.pref.getCollection(PREF_MULTIPOLY + "lineartags", CreateMultipolygonAction.DEFAULT_LINEAR_TAGS);
    308             relation = new Relation();
    309             relation.put("type", "multipolygon");
    310             for( String key : sourceCopy.keySet() ) {
     305    Way sourceCopy = new Way(source);
     306    if( createMultipolygon ) {
     307        Collection<String> linearTags = Main.pref.getCollection(PREF_MULTIPOLY + "lineartags", CreateMultipolygonAction.DEFAULT_LINEAR_TAGS);
     308        relation = new Relation();
     309        relation.put("type", "multipolygon");
     310        for( String key : sourceCopy.keySet() ) {
    311311                if( linearTags.contains(key) ) continue;
    312312                if( key.equals("natural") && sourceCopy.get("natural").equals("coastline") ) continue;
    313313                relation.put(key, sourceCopy.get(key));
    314314                sourceCopy.remove(key);
    315             }
    316         }
    317 
    318         // build a map of referencing relations
    319         Map<Relation, Integer> referencingRelations = new HashMap<>();
    320         List<Command> relationCommands = new ArrayList<>();
    321         for( OsmPrimitive p : source.getReferrers() ) {
    322             if( p instanceof Relation ) {
    323                 Relation rel = null;
    324                 if( relationChangeMap != null ) {
    325                     if( relationChangeMap.containsKey((Relation)p) )
    326                         rel = relationChangeMap.get((Relation)p);
    327                     else {
    328                         rel = new Relation((Relation)p);
    329                         relationChangeMap.put((Relation)p, rel);
    330                     }
    331                 } else {                   
    332                     rel = new Relation((Relation)p);
    333                     relationCommands.add(new ChangeCommand((Relation)p, rel));
    334                 }
    335                 for( int i = 0; i < rel.getMembersCount(); i++ )
    336                     if( rel.getMember(i).getMember().equals(source) )
    337                         referencingRelations.put(rel, Integer.valueOf(i));
    338             }
    339         }
    340         // todo: когда два кольца менÑ�ÑŽÑ‚ одно и то же отношение, в Ñ�пиÑ�ок команд добавлÑ�етÑ�Ñ�
    341         // изменение базового отношениÑ� на новое, а не предыдущего
    342         // поÑ�тому Ñ�охранÑ�етÑ�Ñ� только первое изменение
    343 
    344         List<Command> commands = new ArrayList<>();
    345         boolean foundOwnWay = false;
    346         for( RingSegment seg : segments ) {
    347             boolean needAdding = !seg.isWayConstructed();
    348             Way w = seg.constructWay(seg.isReference() ? null : sourceCopy);
    349             if( needAdding )
    350                 commands.add(new AddCommand(w));
    351             if( w.equals(source) ) {
    352                 if( createMultipolygon || !seg.getWayNodes().equals(source.getNodes()) ) {
    353                     sourceCopy.setNodes(seg.getWayNodes());
    354                     commands.add(new ChangeCommand(source, sourceCopy));
    355                 }
    356                 foundOwnWay = true;
    357             } else {
    358                 for( Relation rel : referencingRelations.keySet() ) {
    359                     int relIndex = referencingRelations.get(rel);
    360                     rel.addMember(new RelationMember(rel.getMember(relIndex).getRole(), w));
    361                 }
    362             }
    363             if( createMultipolygon )
    364                 relation.addMember(new RelationMember("outer", w));
    365         }
    366         if( !foundOwnWay )
    367             commands.add(new DeleteCommand(source));
    368         commands.addAll(relationCommands);
    369         if( createMultipolygon )
    370             commands.add(new AddCommand(relation));
    371         return commands;
     315        }
     316    }
     317
     318    // build a map of referencing relations
     319    Map<Relation, Integer> referencingRelations = new HashMap<>();
     320    List<Command> relationCommands = new ArrayList<>();
     321    for( OsmPrimitive p : source.getReferrers() ) {
     322        if( p instanceof Relation ) {
     323        Relation rel = null;
     324        if( relationChangeMap != null ) {
     325            if( relationChangeMap.containsKey((Relation)p) )
     326            rel = relationChangeMap.get((Relation)p);
     327            else {
     328            rel = new Relation((Relation)p);
     329            relationChangeMap.put((Relation)p, rel);
     330            }
     331        } else {           
     332            rel = new Relation((Relation)p);
     333            relationCommands.add(new ChangeCommand((Relation)p, rel));
     334        }
     335        for( int i = 0; i < rel.getMembersCount(); i++ )
     336            if( rel.getMember(i).getMember().equals(source) )
     337            referencingRelations.put(rel, Integer.valueOf(i));
     338        }
     339    }
     340    // todo: когда два кольца менÑ�ÑŽÑ‚ одно и то же отношение, в Ñ�пиÑ�ок команд добавлÑ�етÑ�Ñ�
     341    // изменение базового отношениÑ� на новое, а не предыдущего
     342    // поÑ�тому Ñ�охранÑ�етÑ�Ñ� только первое изменение
     343
     344    List<Command> commands = new ArrayList<>();
     345    boolean foundOwnWay = false;
     346    for( RingSegment seg : segments ) {
     347        boolean needAdding = !seg.isWayConstructed();
     348        Way w = seg.constructWay(seg.isReference() ? null : sourceCopy);
     349        if( needAdding )
     350        commands.add(new AddCommand(w));
     351        if( w.equals(source) ) {
     352        if( createMultipolygon || !seg.getWayNodes().equals(source.getNodes()) ) {
     353            sourceCopy.setNodes(seg.getWayNodes());
     354            commands.add(new ChangeCommand(source, sourceCopy));
     355        }
     356        foundOwnWay = true;
     357        } else {
     358        for( Relation rel : referencingRelations.keySet() ) {
     359            int relIndex = referencingRelations.get(rel);
     360            rel.addMember(new RelationMember(rel.getMember(relIndex).getRole(), w));
     361        }
     362        }
     363        if( createMultipolygon )
     364        relation.addMember(new RelationMember("outer", w));
     365    }
     366    if( !foundOwnWay )
     367        commands.add(new DeleteCommand(source));
     368    commands.addAll(relationCommands);
     369    if( createMultipolygon )
     370        commands.add(new AddCommand(relation));
     371    return commands;
    372372    }
    373373   
    374374    public static void updateCommandsWithRelations( List<Command> commands, Map<Relation, Relation> relationCache ) {
    375         for( Relation src : relationCache.keySet() )
    376             commands.add(new ChangeCommand(src, relationCache.get(src)));
     375    for( Relation src : relationCache.keySet() )
     376        commands.add(new ChangeCommand(src, relationCache.get(src)));
    377377    }
    378378
     
    381381     */
    382382    public Relation getRelation() {
    383         return relation;
     383    return relation;
    384384    }
    385385
    386386    @Override
    387387    public String toString() {
    388         StringBuilder sb = new StringBuilder("TheRing@");
    389         sb.append(this.hashCode()).append('[').append("wayId: ").append(source == null ? "null" : source.getUniqueId()).append("; segments: ");
    390         if( segments.isEmpty() )
    391             sb.append("empty");
    392         else {
    393             sb.append(segments.get(0));
    394             for( int i = 1; i < segments.size(); i++ )
    395                 sb.append(", ").append(segments.get(i));
    396         }
    397         return sb.append(']').toString();
     388    StringBuilder sb = new StringBuilder("TheRing@");
     389    sb.append(this.hashCode()).append('[').append("wayId: ").append(source == null ? "null" : source.getUniqueId()).append("; segments: ");
     390    if( segments.isEmpty() )
     391        sb.append("empty");
     392    else {
     393        sb.append(segments.get(0));
     394        for( int i = 1; i < segments.size(); i++ )
     395        sb.append(", ").append(segments.get(i));
     396    }
     397    return sb.append(']').toString();
    398398    }
    399399
     
    402402     */
    403403    /*private static void closePolygon( List<Node> base, List<Node> append ) {
    404         if( append.get(0).equals(base.get(0)) && append.get(append.size() - 1).equals(base.get(base.size() - 1)) ) {
    405             List<Node> ap2 = new ArrayList<Node>(append);
    406             Collections.reverse(ap2);
    407             append = ap2;
    408         }
    409         base.remove(base.size() - 1);
    410         base.addAll(append);
     404    if( append.get(0).equals(base.get(0)) && append.get(append.size() - 1).equals(base.get(base.size() - 1)) ) {
     405        List<Node> ap2 = new ArrayList<Node>(append);
     406        Collections.reverse(ap2);
     407        append = ap2;
     408    }
     409    base.remove(base.size() - 1);
     410    base.addAll(append);
    411411    }*/
    412412
     
    415415     */
    416416    /*private static boolean segmentInsidePolygon( Node n1, Node n2, List<Node> polygon ) {
    417         EastNorth en1 = n1.getEastNorth();
    418         EastNorth en2 = n2.getEastNorth();
    419         Node testNode = new Node(new EastNorth((en1.east() + en2.east()) / 2.0, (en1.north() + en2.north()) / 2.0));
    420         return Geometry.nodeInsidePolygon(testNode, polygon);
     417    EastNorth en1 = n1.getEastNorth();
     418    EastNorth en2 = n2.getEastNorth();
     419    Node testNode = new Node(new EastNorth((en1.east() + en2.east()) / 2.0, (en1.north() + en2.north()) / 2.0));
     420    return Geometry.nodeInsidePolygon(testNode, polygon);
    421421    }*/
    422422   
    423423    private static void log( String s ) {
    424 //      System.out.println(s);
     424//    System.out.println(s);
    425425    }
    426426   
    427427    private static class RingSegment {
    428         private List<Node> nodes;
    429         private RingSegment references;
    430         private Way resultingWay = null;
    431         private boolean wasTemplateApplied = false;
    432         private boolean isRing;
    433 
    434         /*private RingSegment() {
    435         }*/
    436 
    437         public RingSegment( Way w ) {
    438             this(w.getNodes());
    439         }
    440 
    441         public RingSegment( List<Node> nodes ) {
    442             this.nodes = nodes;
    443             isRing = nodes.size() > 1 && nodes.get(0).equals(nodes.get(nodes.size() - 1));
    444             if( isRing )
    445                 nodes.remove(nodes.size() - 1);
    446             references = null;
    447         }
    448 
    449         /*public RingSegment( RingSegment ref ) {
    450             this.nodes = null;
    451             this.references = ref;
    452         }*/
    453 
    454         /**
    455         * Splits this segment at node n. Retains nodes 0..n and moves
    456         * nodes n..N to a separate segment that is returned.
    457         * @param n node at which to split.
    458         * @return new segment, {@code null} if splitting is unnecessary.
    459         */
    460         public RingSegment split( Node n ) {
    461             if( nodes == null )
    462                 throw new IllegalArgumentException("Cannot split segment: it is a reference");
    463             int pos = nodes.indexOf(n);
    464             if( pos <= 0 || pos >= nodes.size() - 1 )
    465                 return null;
    466             List<Node> newNodes = new ArrayList<>(nodes.subList(pos, nodes.size()));
    467             nodes.subList(pos + 1, nodes.size()).clear();
    468             return new RingSegment(newNodes);
    469         }
    470 
    471         /**
    472         * Split this segment as a way at two nodes. If one of them is null or at the end,
    473         * split as an arc. Note: order of nodes is important.
    474         * @return A new segment from n2 to n1.
    475         */
    476         public RingSegment split( Node n1, Node n2 ) {
    477             if( nodes == null )
    478                 throw new IllegalArgumentException("Cannot split segment: it is a reference");
    479             if( !isRing ) {
    480                 if( n1 == null || nodes.get(0).equals(n1) || nodes.get(nodes.size() - 1).equals(n1) )
    481                     return split(n2);
    482                 if( n2 == null || nodes.get(0).equals(n2) || nodes.get(nodes.size() - 1).equals(n2) )
    483                     return split(n1);
    484                 throw new IllegalArgumentException("Split for two nodes is called for not-ring: " + this);
    485             }
    486             int pos1 = nodes.indexOf(n1);
    487             int pos2 = nodes.indexOf(n2);
    488             if( pos1 == pos2 )
    489                 return null;
    490 
    491             List<Node> newNodes = new ArrayList<>();
    492             if( pos2 > pos1 ) {
    493                 newNodes.addAll(nodes.subList(pos2, nodes.size()));
    494                 newNodes.addAll(nodes.subList(0, pos1 + 1));
    495                 if( pos2 + 1 < nodes.size() )
    496                     nodes.subList(pos2 + 1, nodes.size()).clear();
    497                 if( pos1 > 0 )
    498                     nodes.subList(0, pos1).clear();
    499             } else {
    500                 newNodes.addAll(nodes.subList(pos2, pos1 + 1));
    501                 nodes.addAll(new ArrayList<>(nodes.subList(0, pos2 + 1)));
    502                 nodes.subList(0, pos1).clear();
    503             }
    504             isRing = false;
    505             return new RingSegment(newNodes);
    506         }
    507 
    508         public List<Node> getNodes() {
    509             return nodes == null ? references.nodes : nodes;
    510         }
    511 
    512         public List<Node> getWayNodes() {
    513             if( nodes == null )
    514                 throw new IllegalArgumentException("Won't give you wayNodes: it is a reference");
    515             List<Node> wayNodes = new ArrayList<>(nodes);
    516             if( isRing )
    517                 wayNodes.add(wayNodes.get(0));
    518             return wayNodes;
    519         }
    520 
    521         public boolean isReference() {
    522             return nodes == null;
    523         }
    524 
    525         public boolean isRing() {
    526             return isRing;
    527         }
    528 
    529         public void makeReference( RingSegment segment ) {
    530             log(this + " was made a reference to " + segment);
    531             this.nodes = null;
    532             this.references = segment;
    533         }
    534 
    535         public void swapReference() {
    536             this.nodes = references.nodes;
    537             references.nodes = null;
    538             references.references = this;
    539             this.references = null;
    540         }
    541 
    542         public boolean isWayConstructed() {
    543             return isReference() ? references.isWayConstructed() : resultingWay != null;
    544         }
    545 
    546         public Way constructWay( Way template ) {
    547             if( isReference() )
    548                 return references.constructWay(template);
    549             if( resultingWay == null ) {
    550                 resultingWay = new Way();
    551                 resultingWay.setNodes(getWayNodes());
    552             }
    553             if( template != null && !wasTemplateApplied ) {
    554                 resultingWay.setKeys(template.getKeys());
    555                 wasTemplateApplied = true;
    556             }
    557             return resultingWay;
    558         }
    559 
    560         public void overrideWay( Way source ) {
    561             if( isReference() )
    562                 references.overrideWay(source);
    563             else {
    564                 resultingWay = source;
    565                 wasTemplateApplied = true;
    566             }
    567         }
    568 
    569         /**
    570         * Compares two segments with respect to referencing.
    571         * @return true if ways are equals, or one references another.
    572         */
    573         /*public boolean isReferencingEqual( RingSegment other ) {
    574             return this.equals(other) || (other.isReference() && other.references == this) || (isReference() && references == other);
    575         }*/
    576 
    577         @Override
    578         public String toString() {
    579             StringBuilder sb = new StringBuilder("RingSegment@");
    580             sb.append(this.hashCode()).append('[');
    581             if( isReference() )
    582                 sb.append("references ").append(references.hashCode());
    583             else if( nodes.isEmpty() )
    584                 sb.append("empty");
    585             else {
    586                 if( isRing )
    587                     sb.append("ring:");
    588                 sb.append(nodes.get(0).getUniqueId());
    589                 for( int i = 1; i < nodes.size(); i++ )
    590                     sb.append(',').append(nodes.get(i).getUniqueId());
    591             }
    592             return sb.append(']').toString();
    593         }
     428    private List<Node> nodes;
     429    private RingSegment references;
     430    private Way resultingWay = null;
     431    private boolean wasTemplateApplied = false;
     432    private boolean isRing;
     433
     434    /*private RingSegment() {
     435    }*/
     436
     437    public RingSegment( Way w ) {
     438        this(w.getNodes());
     439    }
     440
     441    public RingSegment( List<Node> nodes ) {
     442        this.nodes = nodes;
     443        isRing = nodes.size() > 1 && nodes.get(0).equals(nodes.get(nodes.size() - 1));
     444        if( isRing )
     445        nodes.remove(nodes.size() - 1);
     446        references = null;
     447    }
     448
     449    /*public RingSegment( RingSegment ref ) {
     450        this.nodes = null;
     451        this.references = ref;
     452    }*/
     453
     454    /**
     455    * Splits this segment at node n. Retains nodes 0..n and moves
     456    * nodes n..N to a separate segment that is returned.
     457    * @param n node at which to split.
     458    * @return new segment, {@code null} if splitting is unnecessary.
     459    */
     460    public RingSegment split( Node n ) {
     461        if( nodes == null )
     462        throw new IllegalArgumentException("Cannot split segment: it is a reference");
     463        int pos = nodes.indexOf(n);
     464        if( pos <= 0 || pos >= nodes.size() - 1 )
     465        return null;
     466        List<Node> newNodes = new ArrayList<>(nodes.subList(pos, nodes.size()));
     467        nodes.subList(pos + 1, nodes.size()).clear();
     468        return new RingSegment(newNodes);
     469    }
     470
     471    /**
     472    * Split this segment as a way at two nodes. If one of them is null or at the end,
     473    * split as an arc. Note: order of nodes is important.
     474    * @return A new segment from n2 to n1.
     475    */
     476    public RingSegment split( Node n1, Node n2 ) {
     477        if( nodes == null )
     478        throw new IllegalArgumentException("Cannot split segment: it is a reference");
     479        if( !isRing ) {
     480        if( n1 == null || nodes.get(0).equals(n1) || nodes.get(nodes.size() - 1).equals(n1) )
     481            return split(n2);
     482        if( n2 == null || nodes.get(0).equals(n2) || nodes.get(nodes.size() - 1).equals(n2) )
     483            return split(n1);
     484        throw new IllegalArgumentException("Split for two nodes is called for not-ring: " + this);
     485        }
     486        int pos1 = nodes.indexOf(n1);
     487        int pos2 = nodes.indexOf(n2);
     488        if( pos1 == pos2 )
     489        return null;
     490
     491        List<Node> newNodes = new ArrayList<>();
     492        if( pos2 > pos1 ) {
     493        newNodes.addAll(nodes.subList(pos2, nodes.size()));
     494        newNodes.addAll(nodes.subList(0, pos1 + 1));
     495        if( pos2 + 1 < nodes.size() )
     496            nodes.subList(pos2 + 1, nodes.size()).clear();
     497        if( pos1 > 0 )
     498            nodes.subList(0, pos1).clear();
     499        } else {
     500        newNodes.addAll(nodes.subList(pos2, pos1 + 1));
     501        nodes.addAll(new ArrayList<>(nodes.subList(0, pos2 + 1)));
     502        nodes.subList(0, pos1).clear();
     503        }
     504        isRing = false;
     505        return new RingSegment(newNodes);
     506    }
     507
     508    public List<Node> getNodes() {
     509        return nodes == null ? references.nodes : nodes;
     510    }
     511
     512    public List<Node> getWayNodes() {
     513        if( nodes == null )
     514        throw new IllegalArgumentException("Won't give you wayNodes: it is a reference");
     515        List<Node> wayNodes = new ArrayList<>(nodes);
     516        if( isRing )
     517        wayNodes.add(wayNodes.get(0));
     518        return wayNodes;
     519    }
     520
     521    public boolean isReference() {
     522        return nodes == null;
     523    }
     524
     525    public boolean isRing() {
     526        return isRing;
     527    }
     528
     529    public void makeReference( RingSegment segment ) {
     530        log(this + " was made a reference to " + segment);
     531        this.nodes = null;
     532        this.references = segment;
     533    }
     534
     535    public void swapReference() {
     536        this.nodes = references.nodes;
     537        references.nodes = null;
     538        references.references = this;
     539        this.references = null;
     540    }
     541
     542    public boolean isWayConstructed() {
     543        return isReference() ? references.isWayConstructed() : resultingWay != null;
     544    }
     545
     546    public Way constructWay( Way template ) {
     547        if( isReference() )
     548        return references.constructWay(template);
     549        if( resultingWay == null ) {
     550        resultingWay = new Way();
     551        resultingWay.setNodes(getWayNodes());
     552        }
     553        if( template != null && !wasTemplateApplied ) {
     554        resultingWay.setKeys(template.getKeys());
     555        wasTemplateApplied = true;
     556        }
     557        return resultingWay;
     558    }
     559
     560    public void overrideWay( Way source ) {
     561        if( isReference() )
     562        references.overrideWay(source);
     563        else {
     564        resultingWay = source;
     565        wasTemplateApplied = true;
     566        }
     567    }
     568
     569    /**
     570    * Compares two segments with respect to referencing.
     571    * @return true if ways are equals, or one references another.
     572    */
     573    /*public boolean isReferencingEqual( RingSegment other ) {
     574        return this.equals(other) || (other.isReference() && other.references == this) || (isReference() && references == other);
     575    }*/
     576
     577    @Override
     578    public String toString() {
     579        StringBuilder sb = new StringBuilder("RingSegment@");
     580        sb.append(this.hashCode()).append('[');
     581        if( isReference() )
     582        sb.append("references ").append(references.hashCode());
     583        else if( nodes.isEmpty() )
     584        sb.append("empty");
     585        else {
     586        if( isRing )
     587            sb.append("ring:");
     588        sb.append(nodes.get(0).getUniqueId());
     589        for( int i = 1; i < nodes.size(); i++ )
     590            sb.append(',').append(nodes.get(i).getUniqueId());
     591        }
     592        return sb.append(']').toString();
     593    }
    594594    }
    595595}
Note: See TracChangeset for help on using the changeset viewer.