- Timestamp:
- 2011-12-03T00:14:54+01:00 (13 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPaintSettings.java
- Property svn:mime-type deleted
-
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapPainter.java
- Property svn:mime-type deleted
r4623 r4627 19 19 import java.awt.geom.AffineTransform; 20 20 import java.awt.geom.GeneralPath; 21 import java.awt.geom.Path2D; 22 import java.awt.geom.Point2D; 21 23 import java.awt.geom.Rectangle2D; 22 24 import java.awt.image.BufferedImage; … … 29 31 30 32 import org.openstreetmap.josm.Main; 33 import org.openstreetmap.josm.data.coor.EastNorth; 31 34 import org.openstreetmap.josm.data.osm.Node; 32 35 import org.openstreetmap.josm.data.osm.OsmPrimitive; … … 41 44 import org.openstreetmap.josm.gui.NavigatableComponent; 42 45 import org.openstreetmap.josm.gui.mappaint.BoxTextElemStyle; 43 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle;44 import org.openstreetmap.josm.gui.mappaint.TextElement;45 46 import org.openstreetmap.josm.gui.mappaint.BoxTextElemStyle.HorizontalTextAlignment; 46 47 import org.openstreetmap.josm.gui.mappaint.BoxTextElemStyle.VerticalTextAlignment; 48 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle; 47 49 import org.openstreetmap.josm.gui.mappaint.NodeElemStyle.Symbol; 50 import org.openstreetmap.josm.gui.mappaint.TextElement; 48 51 import org.openstreetmap.josm.tools.ImageProvider; 49 52 import org.openstreetmap.josm.tools.Pair; … … 783 786 } 784 787 785 private Polygon getPolygon(Way w) { 786 Polygon polygon = new Polygon(); 787 788 for (Node n : w.getNodes()) { 789 Point p = nc.getPoint(n); 790 polygon.addPoint(p.x,p.y); 791 } 792 return polygon; 788 private Path2D.Double getPath(Way w) { 789 Path2D.Double path = new Path2D.Double(); 790 boolean initial = true; 791 for (Node n : w.getNodes()) 792 { 793 Point2D p = n.getEastNorth(); 794 if (initial) { 795 path.moveTo(p.getX(), p.getY()); 796 initial = false; 797 } else { 798 path.lineTo(p.getX(), p.getY()); 799 } 800 } 801 return path; 793 802 } 794 803 795 804 public void drawArea(Way w, Color color, BufferedImage fillImage, float fillImageAlpha, TextElement text) { 796 Polygon polygon = getPolygon(w); 797 drawArea(w, polygon, color, fillImage, fillImageAlpha, text); 798 } 799 800 protected void drawArea(OsmPrimitive osm, Polygon polygon, Color color, BufferedImage fillImage, float fillImageAlpha, TextElement text) { 801 805 drawArea(w, getPath(w), color, fillImage, fillImageAlpha, text); 806 } 807 808 protected void drawArea(OsmPrimitive osm, Path2D.Double path, Color color, BufferedImage fillImage, float fillImageAlpha, TextElement text) { 809 810 Shape area = path.createTransformedShape(nc.getAffineTransform()); 811 802 812 if (!isOutlineOnly) { 803 813 if (fillImage == null) { 804 814 g.setColor(color); 805 g.fill Polygon(polygon);815 g.fill(area); 806 816 } else { 807 817 TexturePaint texture = new TexturePaint(fillImage, 808 new Rectangle(polygon.xpoints[0], polygon.ypoints[0], fillImage.getWidth(), fillImage.getHeight())); 818 // new Rectangle(polygon.xpoints[0], polygon.ypoints[0], fillImage.getWidth(), fillImage.getHeight())); 819 new Rectangle(0, 0, fillImage.getWidth(), fillImage.getHeight())); 809 820 g.setPaint(texture); 810 821 if (fillImageAlpha != 1f) { 811 822 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, fillImageAlpha)); 812 823 } 813 g.fill( polygon);824 g.fill(area); 814 825 g.setPaintMode(); 815 826 } … … 824 835 if (name == null) return; 825 836 826 Rectangle pb = polygon.getBounds();837 Rectangle pb = area.getBounds(); 827 838 FontMetrics fontMetrics = g.getFontMetrics(orderFont); // if slow, use cache 828 839 Rectangle2D nb = fontMetrics.getStringBounds(name, g); // if slow, approximate by strlen()*maxcharbounds(font) … … 847 858 848 859 if ((pb.width >= nb.getWidth() && pb.height >= nb.getHeight()) && // quick check 849 polygon.contains(centeredNBounds) // slow but nice860 area.contains(centeredNBounds) // slow but nice 850 861 ) { 851 862 g.setColor(text.color); … … 862 873 public void drawArea(Relation r, Color color, BufferedImage fillImage, float fillImageAlpha, TextElement text) { 863 874 Multipolygon multipolygon = MultipolygonCache.getInstance().get(nc, r); 864 if (!r.isDisabled() && !multipolygon.getOuterWays().isEmpty()) {875 if (!r.isDisabled() && !multipolygon.getOuterWays().isEmpty()) { 865 876 for (PolyData pd : multipolygon.getCombinedPolygons()) { 866 P olygonp = pd.get();867 if (!isPolygonVisible(p)) {877 Path2D.Double p = pd.get(); 878 if (!isAreaVisible(p)) { 868 879 continue; 869 880 } … … 875 886 } 876 887 877 private boolean isPolygonVisible(Polygon polygon) { 878 Rectangle bounds = polygon.getBounds(); 879 if (bounds.width == 0 && bounds.height == 0) return false; 880 if (bounds.x > nc.getWidth()) return false; 881 if (bounds.y > nc.getHeight()) return false; 882 if (bounds.x + bounds.width < 0) return false; 883 if (bounds.y + bounds.height < 0) return false; 888 private boolean isAreaVisible(Path2D.Double area) { 889 Rectangle2D bounds = area.getBounds2D(); 890 if (bounds.isEmpty()) return false; 891 Point2D p = nc.getPoint2D(new EastNorth(bounds.getX(), bounds.getY())); 892 if (p.getX() > nc.getWidth()) return false; 893 if (p.getY() < 0) return false; 894 p = nc.getPoint2D(new EastNorth(bounds.getX() + bounds.getWidth(), bounds.getY() + bounds.getHeight())); 895 if (p.getX() < 0) return false; 896 if (p.getY() > nc.getHeight()) return false; 884 897 return true; 885 898 } -
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/PaintColors.java
- Property svn:mime-type deleted
-
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 } -
trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/MultipolygonCache.java
r4626 r4627 26 26 import org.openstreetmap.josm.gui.MapView.LayerChangeListener; 27 27 import org.openstreetmap.josm.gui.NavigatableComponent; 28 import org.openstreetmap.josm.gui.NavigatableComponent.ZoomChangeListener;29 28 import org.openstreetmap.josm.gui.layer.Layer; 30 29 import org.openstreetmap.josm.gui.layer.OsmDataLayer; … … 34 33 * 35 34 */ 36 public class MultipolygonCache implements DataSetListener, LayerChangeListener, ZoomChangeListener,ProjectionChangeListener {35 public class MultipolygonCache implements DataSetListener, LayerChangeListener, ProjectionChangeListener { 37 36 38 37 private static final MultipolygonCache instance = new MultipolygonCache(); … … 41 40 42 41 private MultipolygonCache() { 43 this.cache = new HashMap<NavigatableComponent, Map<DataSet, Map<Relation, Multipolygon>>>();42 this.cache = new HashMap<NavigatableComponent, Map<DataSet, Map<Relation, Multipolygon>>>(); 44 43 Main.addProjectionChangeListener(this); 45 44 } … … 66 65 multipolygon = map2.get(r); 67 66 if (multipolygon == null || forceRefresh) { 68 map2.put(r, multipolygon = new Multipolygon( nc,r));67 map2.put(r, multipolygon = new Multipolygon(r)); 69 68 } 70 69 } … … 209 208 210 209 @Override 211 public void zoomChanged(/*NavigatableComponent source*/) {212 // TODO Change zoomChanged() method to add a "NavigatableComponent source" argument ? (this method is however used at least by one plugin)213 //clear(source);214 clear();215 }216 217 @Override218 210 public void projectionChanged(Projection oldValue, Projection newValue) { 219 211 clear(); -
trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java
r4623 r4627 21 21 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.JoinedWay; 22 22 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection; 23 import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache; 23 24 import org.openstreetmap.josm.data.validation.Severity; 24 25 import org.openstreetmap.josm.data.validation.Test; … … 134 135 checkMembersAndRoles(r); 135 136 136 Multipolygon polygon = new Multipolygon(Main.map.mapView, r);137 Multipolygon polygon = MultipolygonCache.getInstance().get(Main.map.mapView, r); 137 138 138 139 boolean hasOuterWay = false; -
trunk/src/org/openstreetmap/josm/gui/MapView.java
r4623 r4627 239 239 }); 240 240 241 // Add Multipolygon cache to layer and zoomlisteners241 // Add Multipolygon cache to layer listeners 242 242 addLayerChangeListener(MultipolygonCache.getInstance()); 243 addZoomChangeListener(MultipolygonCache.getInstance());244 243 } 245 244 -
trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java
r4126 r4627 7 7 import java.awt.Point; 8 8 import java.awt.Rectangle; 9 import java.awt.geom.AffineTransform; 9 10 import java.awt.geom.Point2D; 10 11 import java.util.ArrayList; … … 61 62 public static final IntegerProperty PROP_SNAP_DISTANCE = new IntegerProperty("mappaint.node.snap-distance", 10); 62 63 64 public static final String PROPNAME_CENTER = "center"; 65 public static final String PROPNAME_SCALE = "scale"; 66 63 67 /** 64 68 * the zoom listeners … … 229 233 } 230 234 235 public AffineTransform getAffineTransform() { 236 return new AffineTransform( 237 1.0/scale, 0.0, 0.0, -1.0/scale, getWidth()/2.0 - center.east()/scale, getHeight()/2.0 + center.north()/scale); 238 } 239 231 240 /** 232 241 * Return the point on the screen where this Coordinate would be. … … 335 344 EastNorth oldCenter = center; 336 345 center = newCenter; 337 firePropertyChange( "center", oldCenter, newCenter);346 firePropertyChange(PROPNAME_CENTER, oldCenter, newCenter); 338 347 } 339 348 if (scale != newScale) { 340 349 double oldScale = scale; 341 350 scale = newScale; 342 firePropertyChange( "scale", oldScale, newScale);351 firePropertyChange(PROPNAME_SCALE, oldScale, newScale); 343 352 } 344 353 -
trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java
r4310 r4627 50 50 import org.openstreetmap.josm.gui.MapView; 51 51 import org.openstreetmap.josm.gui.MapView.LayerChangeListener; 52 import org.openstreetmap.josm.gui.NavigatableComponent; 52 53 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 53 54 import org.openstreetmap.josm.gui.dialogs.LayerListDialog; … … 790 791 791 792 public void propertyChange(PropertyChangeEvent evt) { 792 if ( "center".equals(evt.getPropertyName()) || "scale".equals(evt.getPropertyName())) {793 if (NavigatableComponent.PROPNAME_CENTER.equals(evt.getPropertyName()) || NavigatableComponent.PROPNAME_SCALE.equals(evt.getPropertyName())) { 793 794 updateOffscreenBuffer = true; 794 795 }
Note:
See TracChangeset
for help on using the changeset viewer.