Ignore:
Timestamp:
2011-12-03T03:08:44+01:00 (13 years ago)
Author:
Don-vip
Message:

see #6987 - optim: moving a node belonging to a MP only resets concerned PolyData objects

Location:
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java

    r4628 r4629  
    1919import org.openstreetmap.josm.data.osm.RelationMember;
    2020import org.openstreetmap.josm.data.osm.Way;
     21import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
    2122import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection;
    2223
     
    176177        private Rectangle2D bounds;
    177178        private final Collection<Way> ways;
     179        private final List<Node> nodes;
     180        private final List<PolyData> inners;
    178181
    179182        public PolyData(JoinedWay joinedWay, Collection<Way> refWays) {
     
    183186        public PolyData(List<Node> nodes, boolean selected, Collection<Way> refWays) {
    184187            this.ways = Collections.unmodifiableCollection(refWays);
     188            this.nodes = Collections.unmodifiableList(nodes);
    185189            this.selected = selected;
    186             boolean initial = true;
     190            this.inners = new ArrayList<Multipolygon.PolyData>();
    187191            this.poly = new Path2D.Double();
    188192            this.poly.setWindingRule(Path2D.WIND_EVEN_ODD);
     193            buildPoly();
     194        }
     195       
     196        private void buildPoly() {
     197            boolean initial = true;
    189198            for (Node n : nodes)
    190199            {
     
    198207            }
    199208            poly.closePath();
     209            for (PolyData inner : inners) {
     210                appendInner(inner.poly);
     211            }
    200212        }
    201213
     
    203215            this.selected = copy.selected;
    204216            this.poly = (Double) copy.poly.clone();
    205             this.ways = new ArrayList<Way>(copy.ways);
     217            this.ways = Collections.unmodifiableCollection(copy.ways);
     218            this.nodes = Collections.unmodifiableList(copy.nodes);
     219            this.inners = new ArrayList<Multipolygon.PolyData>(copy.inners);
    206220        }
    207221       
     
    225239        }
    226240
    227         public void addInner(Path2D.Double inner) {
     241        public void addInner(PolyData inner) {
     242            inners.add(inner);
     243            appendInner(inner.poly);
     244        }
     245       
     246        private void appendInner(Path2D.Double inner) {
    228247            poly.append(inner.getPathIterator(null), false);
    229248        }
     
    242261        public Collection<Way> getWays() {
    243262            return ways;
     263        }
     264       
     265        private void resetPoly() {
     266            poly.reset();
     267            buildPoly();
     268            bounds = null;
     269        }
     270       
     271        public void nodeMoved(NodeMovedEvent event) {
     272            final Node n = event.getNode();
     273            boolean innerChanged = false;
     274            for (PolyData inner : inners) {
     275                if (inner.nodes.contains(n)) {
     276                    inner.resetPoly();
     277                    innerChanged = true;
     278                }
     279            }
     280            if (nodes.contains(n) || innerChanged) {
     281                resetPoly();
     282            }
    244283        }
    245284    }
     
    441480            PolyData combinedOuter = new PolyData(outerPolygons.get(0));
    442481            for (PolyData inner: innerPolygons) {
    443                 combinedOuter.addInner(inner.poly);
     482                combinedOuter.addInner(inner);
    444483            }
    445484            combinedPolygons.add(combinedOuter);
     
    454493                    o = outerPolygons.get(0);
    455494                }
    456                 o.addInner(pdInner.poly);
     495                o.addInner(pdInner);
    457496            }
    458497        }
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/MultipolygonCache.java

    r4628 r4629  
    120120    }
    121121   
    122     private static final void removeMultipolygonFrom(Relation mp, Collection<Map<Relation, Multipolygon>> maps) {
    123         for (Map<Relation, Multipolygon> map : maps) {
    124             map.remove(mp);
    125         }
    126     }
    127 
    128     private final void removeMultipolygonsReferringTo(AbstractDatasetChangedEvent event) {
    129         removeMultipolygonsReferringTo(event.getPrimitives(), event.getDataset());
    130     }
    131 
    132     private final void removeMultipolygonsReferringTo(Collection<? extends OsmPrimitive> primitives, DataSet ds) {
    133         removeMultipolygonsReferringTo(primitives, ds, null);
    134     }
    135    
    136     private final Collection<Map<Relation, Multipolygon>> removeMultipolygonsReferringTo(
    137             Collection<? extends OsmPrimitive> primitives, DataSet ds, Collection<Map<Relation, Multipolygon>> initialMaps) {
     122    private final void updateMultipolygonsReferringTo(final AbstractDatasetChangedEvent event) {
     123        updateMultipolygonsReferringTo(event, event.getPrimitives(), event.getDataset());
     124    }
     125
     126    private final void updateMultipolygonsReferringTo(
     127            final AbstractDatasetChangedEvent event, final Collection<? extends OsmPrimitive> primitives, final DataSet ds) {
     128        updateMultipolygonsReferringTo(event, primitives, ds, null);
     129    }
     130   
     131    private final Collection<Map<Relation, Multipolygon>> updateMultipolygonsReferringTo(
     132            final AbstractDatasetChangedEvent event, final Collection<? extends OsmPrimitive> primitives,
     133            final DataSet ds, final Collection<Map<Relation, Multipolygon>> initialMaps) {
    138134        Collection<Map<Relation, Multipolygon>> maps = initialMaps;
    139135        if (primitives != null) {
     
    143139                        maps = getMapsFor(ds);
    144140                    }
    145                     removeMultipolygonFrom((Relation) p, maps);
     141                    processEvent(event, (Relation) p, maps);
    146142                   
    147143                } else if (p instanceof Way && p.getDataSet() != null) {
     
    151147                                maps = getMapsFor(ds);
    152148                            }
    153                             removeMultipolygonFrom((Relation) ref, maps);
     149                            processEvent(event, (Relation) ref, maps);
    154150                        }
    155151                    }
    156152                } else if (p instanceof Node && p.getDataSet() != null) {
    157                     maps = removeMultipolygonsReferringTo(p.getReferrers(), ds, maps);
     153                    maps = updateMultipolygonsReferringTo(event, p.getReferrers(), ds, maps);
    158154                }
    159155            }
    160156        }
    161157        return maps;
     158    }
     159   
     160    private final void processEvent(final AbstractDatasetChangedEvent event, final Relation r, final Collection<Map<Relation, Multipolygon>> maps) {
     161        if (event instanceof NodeMovedEvent) {
     162            for (Map<Relation, Multipolygon> map : maps) {
     163                Multipolygon m = map.get(r);
     164                for (PolyData pd : m.getCombinedPolygons()) {
     165                    pd.nodeMoved((NodeMovedEvent) event);
     166                }
     167            }
     168        } else {
     169            // Default (non-optimal) action: remove multipolygon from cache
     170            for (Map<Relation, Multipolygon> map : maps) {
     171                map.remove(r);
     172            }
     173        }
    162174    }
    163175
     
    169181    @Override
    170182    public void primitivesRemoved(PrimitivesRemovedEvent event) {
    171         removeMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
     183        updateMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
    172184    }
    173185
     
    179191    @Override
    180192    public void nodeMoved(NodeMovedEvent event) {
    181         removeMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
     193        updateMultipolygonsReferringTo(event);
    182194    }
    183195
    184196    @Override
    185197    public void wayNodesChanged(WayNodesChangedEvent event) {
    186         removeMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
     198        updateMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
    187199    }
    188200
    189201    @Override
    190202    public void relationMembersChanged(RelationMembersChangedEvent event) {
    191         removeMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
     203        updateMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
    192204    }
    193205
    194206    @Override
    195207    public void otherDatasetChange(AbstractDatasetChangedEvent event) {
    196         removeMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
     208        updateMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
    197209    }
    198210
    199211    @Override
    200212    public void dataChanged(DataChangedEvent event) {
    201         removeMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
     213        updateMultipolygonsReferringTo(event);// FIXME: See if it is possible to update only concerned PolyData
    202214    }
    203215
Note: See TracChangeset for help on using the changeset viewer.