Changeset 19336 in josm
- Timestamp:
- 2025-02-25T17:29:20+01:00 (7 hours ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/MultipolygonBuilder.java
r19101 r19336 155 155 */ 156 156 public static Pair<List<JoinedPolygon>, List<JoinedPolygon>> joinWays(Relation multipolygon) { 157 return joinWays(null, multipolygon); 158 } 159 160 /** 161 * Joins the given {@code multipolygon} to a pair of outer and inner multipolygon rings. 162 * 163 * @param multipolygon the multipolygon to join. 164 * @return a pair of outer and inner multipolygon rings. 165 * @throws JoinedPolygonCreationException if the creation fails. 166 * @since xxx 167 */ 168 public static Pair<List<JoinedPolygon>, List<JoinedPolygon>> joinWays( 169 Map<IRelation<?>, Pair<List<JoinedPolygon>, List<JoinedPolygon>>> cache, Relation multipolygon) { 170 if (cache != null) { 171 return cache.computeIfAbsent(multipolygon, MultipolygonBuilder::joinWaysActual); 172 } 173 return joinWaysActual(multipolygon); 174 } 175 176 /** 177 * Perform the actual join ways calculation 178 * 179 * @param multipolygon the multipolygon to join. 180 * @return a pair of outer and inner multipolygon rings. 181 * @throws JoinedPolygonCreationException if the creation fails. 182 */ 183 private static Pair<List<JoinedPolygon>, List<JoinedPolygon>> joinWaysActual(IRelation<?> multipolygon) { 157 184 CheckParameterUtil.ensureThat(multipolygon.isMultipolygon(), "multipolygon.isMultipolygon"); 158 final Map<String, Set<Way>> members = multipolygon.getMembers().stream() 159 .filter(RelationMember::isWay) 160 .collect(Collectors.groupingBy(RelationMember::getRole, Collectors.mapping(RelationMember::getWay, Collectors.toSet()))); 185 CheckParameterUtil.ensureThat(multipolygon instanceof Relation, 186 "This method currently only supports Relation objects due to potential breakage"); 187 final Map<String, Set<Way>> members = ((Relation) multipolygon).getMembers().stream() 188 .filter(IRelationMember::isWay) 189 .collect(Collectors.groupingBy(IRelationMember::getRole, Collectors.mapping(RelationMember::getWay, Collectors.toSet()))); 161 190 final List<JoinedPolygon> outerRings = joinWays(members.getOrDefault("outer", Collections.emptySet())); 162 191 final List<JoinedPolygon> innerRings = joinWays(members.getOrDefault("inner", Collections.emptySet())); -
trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
r18801 r19336 25 25 26 26 import org.openstreetmap.josm.data.osm.IPrimitive; 27 import org.openstreetmap.josm.data.osm.IRelation; 28 import org.openstreetmap.josm.data.osm.MultipolygonBuilder.JoinedPolygon; 27 29 import org.openstreetmap.josm.data.osm.OsmPrimitive; 28 30 import org.openstreetmap.josm.data.preferences.BooleanProperty; … … 50 52 import org.openstreetmap.josm.tools.Logging; 51 53 import org.openstreetmap.josm.tools.MultiMap; 54 import org.openstreetmap.josm.tools.Pair; 52 55 import org.openstreetmap.josm.tools.Stopwatch; 53 56 import org.openstreetmap.josm.tools.Utils; … … 61 64 private final Map<MapCSSRule, MapCSSTagCheckerAndRule> ruleToCheckMap = new HashMap<>(); 62 65 private static final Map<IPrimitive, Area> mpAreaCache = new HashMap<>(); 66 private static final Map<IRelation<?>, Pair<List<JoinedPolygon>, List<JoinedPolygon>>> mpJoinedAreaCache = new HashMap<>(); 63 67 private static final Set<IPrimitive> toMatchForSurrounding = new HashSet<>(); 64 68 static final boolean ALL_TESTS = true; … … 164 168 final Environment env = new Environment(p, new MultiCascade(), Environment.DEFAULT_LAYER, null); 165 169 env.mpAreaCache = mpAreaCache; 170 env.mpJoinedAreaCache = mpJoinedAreaCache; 166 171 env.toMatchForSurrounding = toMatchForSurrounding; 167 172 … … 222 227 final Environment env = new Environment(p, new MultiCascade(), Environment.DEFAULT_LAYER, null); 223 228 env.mpAreaCache = mpAreaCache; 229 env.mpJoinedAreaCache = mpJoinedAreaCache; 224 230 env.toMatchForSurrounding = toMatchForSurrounding; 225 231 for (Set<MapCSSTagCheckerRule> schecks : checksCol) { … … 377 383 mpAreaCache.clear(); 378 384 ruleToCheckMap.clear(); 385 mpJoinedAreaCache.clear(); 379 386 toMatchForSurrounding.clear(); 380 387 super.endTest(); … … 397 404 398 405 mpAreaCache.clear(); 406 mpJoinedAreaCache.clear(); 399 407 toMatchForSurrounding.clear(); 400 408 -
trunk/src/org/openstreetmap/josm/gui/mappaint/Environment.java
r18918 r19336 9 9 10 10 import org.openstreetmap.josm.data.osm.IPrimitive; 11 import org.openstreetmap.josm.data.osm.IRelation; 12 import org.openstreetmap.josm.data.osm.MultipolygonBuilder; 11 13 import org.openstreetmap.josm.data.osm.Relation; 12 14 import org.openstreetmap.josm.data.osm.Way; … … 16 18 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector.LinkSelector; 17 19 import org.openstreetmap.josm.tools.CheckParameterUtil; 20 import org.openstreetmap.josm.tools.Pair; 18 21 19 22 /** … … 91 94 */ 92 95 public Map<IPrimitive, Area> mpAreaCache; 96 /** 97 * Cache for multipolygon areas as calculated by {@link MultipolygonBuilder#joinWays(Relation)}, can be {@code null} 98 */ 99 public Map<IRelation<?>, Pair<List<MultipolygonBuilder.JoinedPolygon>, List<MultipolygonBuilder.JoinedPolygon>>> mpJoinedAreaCache; 93 100 94 101 /** … … 163 170 this.crossingWaysMap = other.crossingWaysMap; 164 171 this.mpAreaCache = other.mpAreaCache; 172 this.mpJoinedAreaCache = other.mpJoinedAreaCache; 165 173 this.toMatchForSurrounding = other.toMatchForSurrounding; 166 174 this.selector = selector; -
trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
r19050 r19336 491 491 if (r instanceof Relation && r.isMultipolygon() && r.getBBox().bounds(e.osm.getBBox()) 492 492 && left.matches(new Environment(r).withParent(e.osm)) 493 && !Geometry.filterInsideMultipolygon(Collections.singletonList(e.osm), (Relation) r).isEmpty()) { 493 && !Geometry.filterInsideMultipolygon(Collections.singletonList(e.osm), (Relation) r, e.mpJoinedAreaCache).isEmpty()) { 494 494 addToChildren(e, r); 495 495 } -
trunk/src/org/openstreetmap/josm/tools/Geometry.java
r19272 r19336 18 18 import java.util.LinkedHashSet; 19 19 import java.util.List; 20 import java.util.Map; 20 21 import java.util.Set; 21 22 import java.util.TreeSet; … … 33 34 import org.openstreetmap.josm.data.osm.INode; 34 35 import org.openstreetmap.josm.data.osm.IPrimitive; 36 import org.openstreetmap.josm.data.osm.IRelation; 35 37 import org.openstreetmap.josm.data.osm.IWay; 36 38 import org.openstreetmap.josm.data.osm.MultipolygonBuilder; … … 1192 1194 polygonArea = getArea(polygon.getNodes()); 1193 1195 } 1194 Multipolygon mp = new Multipolygon((Relation) p); 1196 Multipolygon mp = p.getDataSet() != null ? MultipolygonCache.getInstance().get((Relation) p) : new Multipolygon((Relation) p); 1195 1197 boolean inside = true; 1196 1198 // a (valid) multipolygon is inside the polygon if all outer rings are inside … … 1221 1223 */ 1222 1224 public static List<IPrimitive> filterInsideMultipolygon(Collection<IPrimitive> primitives, Relation multiPolygon) { 1225 return filterInsideMultipolygon(primitives, multiPolygon, null); 1226 } 1227 1228 /** 1229 * Find all primitives in the given collection which are inside the given multipolygon. Members of the multipolygon are 1230 * ignored. Unclosed ways and multipolygon relations with unclosed outer rings are ignored. 1231 * @param primitives the primitives 1232 * @param multiPolygon the multipolygon relation 1233 * @param cache The cache to avoid calculating joined inner/outer ways multiple times (see {@link MultipolygonBuilder#joinWays(Relation)}) 1234 * @return a new list containing the found primitives, empty if multipolygon is invalid or nothing was found. 1235 * @since xxx 1236 */ 1237 public static List<IPrimitive> filterInsideMultipolygon(Collection<IPrimitive> primitives, Relation multiPolygon, 1238 Map<IRelation<?>, Pair<List<JoinedPolygon>, List<JoinedPolygon>>> cache) { 1223 1239 List<IPrimitive> res = new ArrayList<>(); 1224 1240 if (primitives.isEmpty()) … … 1227 1243 final Pair<List<JoinedPolygon>, List<JoinedPolygon>> outerInner; 1228 1244 try { 1229 outerInner = MultipolygonBuilder.joinWays(multiPolygon); 1245 outerInner = MultipolygonBuilder.joinWays(cache, multiPolygon); 1230 1246 } catch (MultipolygonBuilder.JoinedPolygonCreationException ex) { 1231 1247 Logging.trace(ex); -
trunk/test/unit/org/openstreetmap/josm/tools/GeometryTest.java
r19272 r19336 368 368 mp2.put("type", "multipolygon"); 369 369 assertFalse(Geometry.isPolygonInsideMultiPolygon(w1.getNodes(), mp2, null)); 370 assertFalse(Geometry.filterInsideMultipolygon(Collections.singletonList(w1), mp2).contains(w1)); 370 assertFalse(Geometry.filterInsideMultipolygon(Collections.singletonList(w1), mp2, null).contains(w1)); 371 371 372 372 node4.setCoor(new LatLon(1.006, 0.99)); 373 373 // now w1 is inside 374 374 assertTrue(Geometry.isPolygonInsideMultiPolygon(w1.getNodes(), mp2, null)); 375 assertTrue(Geometry.filterInsideMultipolygon(Collections.singletonList(w1), mp2).contains(w1)); 376 assertTrue(Geometry.filterInsideMultipolygon(Collections.singletonList(mp1), mp2).contains(mp1)); 377 assertTrue(Geometry.filterInsideMultipolygon(Arrays.asList(w1, mp1), mp2).contains(w1)); 378 assertTrue(Geometry.filterInsideMultipolygon(Arrays.asList(w1, mp1), mp2).contains(mp1)); 375 assertTrue(Geometry.filterInsideMultipolygon(Collections.singletonList(w1), mp2, null).contains(w1)); 376 assertTrue(Geometry.filterInsideMultipolygon(Collections.singletonList(mp1), mp2, null).contains(mp1)); 377 assertTrue(Geometry.filterInsideMultipolygon(Arrays.asList(w1, mp1), mp2, null).contains(w1)); 378 assertTrue(Geometry.filterInsideMultipolygon(Arrays.asList(w1, mp1), mp2, null).contains(mp1)); 379 379 } 380 380
Note:
See TracChangeset
for help on using the changeset viewer.