Ticket #24046: 24046.patch

File 24046.patch, 5.7 KB (added by taylor.smock, 12 months ago)

Extend MultipolygonCache to cache JoinedPolygon calculations

  • src/org/openstreetmap/josm/data/osm/visitor/paint/relations/MultipolygonCache.java

    Subject: [PATCH] 24046
    ---
    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/MultipolygonCache.java b/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/MultipolygonCache.java
    a b  
    33
    44import java.util.ArrayList;
    55import java.util.Collection;
     6import java.util.Collections;
     7import java.util.HashMap;
    68import java.util.Iterator;
    79import java.util.List;
    810import java.util.Map;
     
    1012
    1113import org.openstreetmap.josm.data.osm.DataSelectionListener;
    1214import org.openstreetmap.josm.data.osm.DataSet;
     15import org.openstreetmap.josm.data.osm.MultipolygonBuilder;
     16import org.openstreetmap.josm.data.osm.MultipolygonBuilder.JoinedPolygon;
     17import org.openstreetmap.josm.data.osm.MultipolygonBuilder.JoinedPolygonCreationException;
    1318import org.openstreetmap.josm.data.osm.Node;
    1419import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1520import org.openstreetmap.josm.data.osm.Relation;
     
    3439import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
    3540import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
    3641import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     42import org.openstreetmap.josm.tools.Pair;
    3743
    3844/**
    3945 * A memory cache for {@link Multipolygon} objects.
     
    4450    private static final MultipolygonCache INSTANCE = new MultipolygonCache();
    4551
    4652    private final Map<DataSet, Map<Relation, Multipolygon>> cache = new ConcurrentHashMap<>(); // see ticket 11833
     53    private final Map<DataSet, Map<Relation, Pair<List<JoinedPolygon>, List<JoinedPolygon>>>> wayCache = new HashMap<>();
    4754
    4855    private final Collection<PolyData> selectedPolyData = new ArrayList<>();
    4956
     
    102109        return multipolygon;
    103110    }
    104111
     112    /**
     113     * Get joined ways for a relation
     114     * @param r The relation to get the joined ways for
     115     * @return The joined ways, see {@link MultipolygonBuilder#joinWays(Relation)} for details.
     116     * @throws JoinedPolygonCreationException if the creation fails
     117     * @since xxx
     118     */
     119    public Pair<List<JoinedPolygon>, List<JoinedPolygon>> getWays(Relation r) throws JoinedPolygonCreationException {
     120        return getWays(r, false);
     121    }
     122
     123    /**
     124     * Get joined ways for a relation
     125     * @param r The relation to get the joined ways for
     126     * @param forceRefresh {@code true} if a cached calculation should not be used
     127     * @return The joined ways, see {@link MultipolygonBuilder#joinWays(Relation)} for details.
     128     * @throws JoinedPolygonCreationException if the creation fails
     129     * @since xxx
     130     */
     131    public Pair<List<JoinedPolygon>, List<JoinedPolygon>> getWays(Relation r, boolean forceRefresh) throws JoinedPolygonCreationException {
     132        if (r == null) {
     133            return new Pair<>(Collections.emptyList(), Collections.emptyList());
     134        } else if (r.getDataSet() == null) {
     135            return MultipolygonBuilder.joinWays(r);
     136        }
     137        Map<Relation, Pair<List<JoinedPolygon>, List<JoinedPolygon>>> tMap = wayCache.computeIfAbsent(r.getDataSet(), d -> new HashMap<>());
     138        if (forceRefresh || !tMap.containsKey(r)) {
     139            Pair<List<JoinedPolygon>, List<JoinedPolygon>> outerInner = MultipolygonBuilder.joinWays(r);
     140            tMap.put(r, outerInner);
     141            return outerInner;
     142        }
     143        return tMap.get(r);
     144    }
     145
    105146    /**
    106147     * Clears the cache for the given dataset.
    107148     * @param ds the data set
     
    111152        if (map2 != null) {
    112153            map2.clear();
    113154        }
     155        Map<Relation, Pair<List<JoinedPolygon>, List<JoinedPolygon>>> map3 = wayCache.remove(ds);
     156        if (map3 != null) {
     157            map3.clear();
     158        }
    114159    }
    115160
    116161    /**
     
    118163     */
    119164    public void clear() {
    120165        cache.clear();
     166        wayCache.clear();
    121167    }
    122168
    123169    private Collection<Map<Relation, Multipolygon>> getMapsFor(DataSet ds) {
  • src/org/openstreetmap/josm/tools/Geometry.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/tools/Geometry.java b/src/org/openstreetmap/josm/tools/Geometry.java
    a b  
    11911191                if (polygonArea == null) {
    11921192                    polygonArea = getArea(polygon.getNodes());
    11931193                }
    1194                 Multipolygon mp = new Multipolygon((Relation) p);
     1194                Multipolygon mp = p.getDataSet() != null ? MultipolygonCache.getInstance().get((Relation) p) : new Multipolygon((Relation) p);
    11951195                boolean inside = true;
    11961196                // a (valid) multipolygon is inside the polygon if all outer rings are inside
    11971197                for (PolyData outer : mp.getOuterPolygons()) {
     
    12261226
    12271227        final Pair<List<JoinedPolygon>, List<JoinedPolygon>> outerInner;
    12281228        try {
    1229             outerInner = MultipolygonBuilder.joinWays(multiPolygon);
     1229            outerInner = MultipolygonCache.getInstance().getWays(multiPolygon);
    12301230        } catch (MultipolygonBuilder.JoinedPolygonCreationException ex) {
    12311231            Logging.trace(ex);
    12321232            Logging.debug("Invalid multipolygon " + multiPolygon);