Changeset 4627 in josm for trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java
- Timestamp:
- 2011-12-03T00:14:54+01:00 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java
- Property svn:mime-type deleted
r4623 r4627 2 2 package org.openstreetmap.josm.data.osm.visitor.paint.relations; 3 3 4 import java.awt.Point; 5 import java.awt.Polygon; 6 import java.awt.Rectangle; 4 import java.awt.geom.Path2D; 5 import java.awt.geom.Path2D.Double; 6 import java.awt.geom.PathIterator; 7 import java.awt.geom.Point2D; 8 import java.awt.geom.Rectangle2D; 7 9 import java.util.ArrayList; 8 10 import java.util.Collection; … … 17 19 import org.openstreetmap.josm.data.osm.Way; 18 20 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection; 19 import org.openstreetmap.josm.gui.NavigatableComponent;20 21 21 22 public class Multipolygon { … … 170 171 public enum Intersection {INSIDE, OUTSIDE, CROSSING} 171 172 172 public Polygon poly = new Polygon();173 public final Path2D.Double poly; 173 174 public final boolean selected; 174 private Point lastP; 175 private Rectangle bounds; 176 177 public PolyData(NavigatableComponent nc, JoinedWay joinedWay) { 178 this(nc, joinedWay.getNodes(), joinedWay.isSelected()); 179 } 180 181 public PolyData(NavigatableComponent nc, List<Node> nodes, boolean selected) { 175 private Rectangle2D bounds; 176 177 public PolyData(JoinedWay joinedWay) { 178 this(joinedWay.getNodes(), joinedWay.isSelected()); 179 } 180 181 public PolyData(List<Node> nodes, boolean selected) { 182 182 this.selected = selected; 183 Point p = null; 183 boolean initial = true; 184 this.poly = new Path2D.Double(); 185 this.poly.setWindingRule(Path2D.WIND_EVEN_ODD); 184 186 for (Node n : nodes) 185 187 { 186 p = nc.getPoint(n); 187 poly.addPoint(p.x,p.y); 188 } 189 if (!nodes.get(0).equals(nodes.get(nodes.size() - 1))) { 190 p = nc.getPoint(nodes.get(0)); 191 poly.addPoint(p.x, p.y); 192 } 193 lastP = p; 188 Point2D p = n.getEastNorth(); 189 if (initial) { 190 poly.moveTo(p.getX(), p.getY()); 191 initial = false; 192 } else { 193 poly.lineTo(p.getX(), p.getY()); 194 } 195 } 196 poly.closePath(); 194 197 } 195 198 196 199 public PolyData(PolyData copy) { 197 poly = new Polygon(copy.poly.xpoints, copy.poly.ypoints, copy.poly.npoints);198 200 this.selected = copy.selected; 199 lastP = copy.lastP; 200 } 201 202 public Intersection contains(Polygon p) { 203 int contains = p.npoints; 204 for(int i = 0; i < p.npoints; ++i) 205 { 206 if(poly.contains(p.xpoints[i],p.ypoints[i])) { 207 --contains; 208 } 209 } 210 if(contains == 0) return Intersection.INSIDE; 211 if(contains == p.npoints) return Intersection.OUTSIDE; 201 this.poly = (Double) copy.poly.clone(); 202 } 203 204 public Intersection contains(Path2D.Double p) { 205 int contains = 0; 206 int total = 0; 207 double[] coords = new double[6]; 208 for (PathIterator it = p.getPathIterator(null); !it.isDone(); it.next()) { 209 switch (it.currentSegment(coords)) { 210 case PathIterator.SEG_MOVETO: 211 case PathIterator.SEG_LINETO: 212 if (poly.contains(coords[0], coords[1])) { 213 contains++; 214 } 215 total++; 216 } 217 } 218 if (contains == total) return Intersection.INSIDE; 219 if (contains == 0) return Intersection.OUTSIDE; 212 220 return Intersection.CROSSING; 213 221 } 214 222 215 public void addInner(Polygon p) { 216 for(int i = 0; i < p.npoints; ++i) { 217 poly.addPoint(p.xpoints[i],p.ypoints[i]); 218 } 219 poly.addPoint(lastP.x, lastP.y); 220 } 221 222 public Polygon get() { 223 public void addInner(Path2D.Double inner) { 224 poly.append(inner.getPathIterator(null), false); 225 } 226 227 public Path2D.Double get() { 223 228 return poly; 224 229 } 225 230 226 public Rectangle getBounds() {231 public Rectangle2D getBounds() { 227 232 if (bounds == null) { 228 bounds = poly.getBounds ();233 bounds = poly.getBounds2D(); 229 234 } 230 235 return bounds; 231 }232 233 @Override234 public String toString() {235 return "Points: " + poly.npoints + " Selected: " + selected;236 236 } 237 237 } … … 243 243 private final List<PolyData> combinedPolygons = new ArrayList<PolyData>(); 244 244 245 public Multipolygon( NavigatableComponent nc,Relation r) {246 load(r , nc);247 } 248 249 private void load(Relation r , NavigatableComponent nc) {245 public Multipolygon(Relation r) { 246 load(r); 247 } 248 249 private void load(Relation r) { 250 250 MultipolygonRoleMatcher matcher = getMultipolygonRoleMatcher(); 251 251 … … 253 253 for (RelationMember m : r.getMembers()) { 254 254 if (m.getMember().isDrawable()) { 255 if (m.isWay()) {255 if (m.isWay()) { 256 256 Way w = m.getWay(); 257 257 258 if (w.getNodesCount() < 2) {258 if (w.getNodesCount() < 2) { 259 259 continue; 260 260 } 261 261 262 if (matcher.isInnerRole(m.getRole())) {262 if (matcher.isInnerRole(m.getRole())) { 263 263 innerWays.add(w); 264 } else if (matcher.isOuterRole(m.getRole())) {264 } else if (matcher.isOuterRole(m.getRole())) { 265 265 outerWays.add(w); 266 266 } else if (!m.hasRole()) { … … 271 271 } 272 272 273 createPolygons( nc,innerWays, innerPolygons);274 createPolygons( nc,outerWays, outerPolygons);273 createPolygons(innerWays, innerPolygons); 274 createPolygons(outerWays, outerPolygons); 275 275 if (!outerPolygons.isEmpty()) { 276 276 addInnerToOuters(); … … 278 278 } 279 279 280 private void createPolygons( NavigatableComponent nc,List<Way> ways, List<PolyData> result) {280 private void createPolygons(List<Way> ways, List<PolyData> result) { 281 281 List<Way> waysToJoin = new ArrayList<Way>(); 282 282 for (Way way: ways) { 283 283 if (way.isClosed()) { 284 result.add(new PolyData( nc,way.getNodes(), way.isSelected()));284 result.add(new PolyData(way.getNodes(), way.isSelected())); 285 285 } else { 286 286 waysToJoin.add(way); … … 289 289 290 290 for (JoinedWay jw: joinWays(waysToJoin)) { 291 result.add(new PolyData( nc,jw));291 result.add(new PolyData(jw)); 292 292 } 293 293 } … … 390 390 391 391 public PolyData findOuterPolygon(PolyData inner, List<PolyData> outerPolygons) { 392 393 // First try to test only bbox, use precise testing only if we don't get unique result 394 Rectangle2D innerBox = inner.getBounds(); 395 PolyData insidePolygon = null; 396 PolyData intersectingPolygon = null; 397 int insideCount = 0; 398 int intersectingCount = 0; 399 400 for (PolyData outer: outerPolygons) { 401 if (outer.getBounds().contains(innerBox)) { 402 insidePolygon = outer; 403 insideCount++; 404 } else if (outer.getBounds().intersects(innerBox)) { 405 intersectingPolygon = outer; 406 intersectingCount++; 407 } 408 } 409 410 if (insideCount == 1) 411 return insidePolygon; 412 else if (intersectingCount == 1) 413 return intersectingPolygon; 414 392 415 PolyData result = null; 393 394 {// First try to test only bbox, use precise testing only if we don't get unique result395 Rectangle innerBox = inner.getBounds();396 PolyData insidePolygon = null;397 PolyData intersectingPolygon = null;398 int insideCount = 0;399 int intersectingCount = 0;400 401 for (PolyData outer: outerPolygons) {402 if (outer.getBounds().contains(innerBox)) {403 insidePolygon = outer;404 insideCount++;405 } else if (outer.getBounds().intersects(innerBox)) {406 intersectingPolygon = outer;407 intersectingCount++;408 }409 }410 411 if (insideCount == 1)412 return insidePolygon;413 else if (intersectingCount == 1)414 return intersectingPolygon;415 }416 417 416 for (PolyData combined : outerPolygons) { 418 417 Intersection c = combined.contains(inner.poly); 419 if (c != Intersection.OUTSIDE)418 if (c != Intersection.OUTSIDE) 420 419 { 421 if (result == null || result.contains(combined.poly) != Intersection.INSIDE) {420 if (result == null || result.contains(combined.poly) != Intersection.INSIDE) { 422 421 result = combined; 423 422 } … … 444 443 for (PolyData pdInner: innerPolygons) { 445 444 PolyData o = findOuterPolygon(pdInner, combinedPolygons); 446 if (o == null) {445 if (o == null) { 447 446 o = outerPolygons.get(0); 448 447 }
Note:
See TracChangeset
for help on using the changeset viewer.