Changeset 11730 in josm


Ignore:
Timestamp:
2017-03-13T20:11:23+01:00 (6 months ago)
Author:
michael2402
Message:

Add a new style element for area icon styles. Use the same placement algorithm we use for texts. Fixes #10176

Location:
trunk/src/org/openstreetmap/josm
Files:
1 added
3 edited

Legend:

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

    r11722 r11730  
    3939import java.util.concurrent.RecursiveTask;
    4040import java.util.function.BiConsumer;
     41import java.util.function.Consumer;
    4142import java.util.function.Supplier;
    4243import java.util.stream.Collectors;
     
    740741
    741742    /**
    742      * Draw the icon for a given area. The icon is drawn around the lat/lon center of the area.
    743      * @param primitive The node
    744      * @param img The icon to draw at the node position
     743     * Draw the icon for a given area. Normally, the icon is drawn around the center of the area.
     744     * @param osm The primitive to draw the icon for
     745     * @param img The icon to draw
    745746     * @param disabled {@code} true to render disabled version, {@code false} for the standard version
    746747     * @param selected {@code} true to render it as selected, {@code false} otherwise
    747748     * @param member {@code} true to render it as a relation member, {@code false} otherwise
    748749     * @param theta the angle of rotation in radians
     750     * @param iconPosition Where to place the icon.
    749751     * @since 11670
    750752     */
    751     public void drawAreaIcon(OsmPrimitive primitive, MapImage img, boolean disabled, boolean selected, boolean member, double theta) {
    752         BBox bbox = null;
    753         if (primitive instanceof Way) {
    754             bbox = primitive.getBBox();
    755         } else if (primitive instanceof Relation) {
    756             Multipolygon multipolygon = MultipolygonCache.getInstance().get(nc, (Relation) primitive);
    757             if (multipolygon != null) {
    758                 BBox collect = new BBox();
    759                 multipolygon.getOuterPolygons().forEach(p -> p.getNodes().forEach(n -> collect.add(n.getCoor())));
    760                 bbox = collect;
    761             }
    762         }
    763 
    764         if (bbox != null && bbox.isValid()) {
    765             MapViewPoint p = mapState.getPointFor(bbox.getCenter());
     753    public void drawAreaIcon(OsmPrimitive osm, MapImage img, boolean disabled, boolean selected, boolean member, double theta, PositionForAreaStrategy iconPosition) {
     754        Rectangle2D.Double iconRect = new Rectangle2D.Double(-img.getWidth() / 2.0, -img.getHeight() / 2.0, img.getWidth(), img.getHeight());
     755
     756        forEachPolygon(osm, path -> {
     757            Shape area = path.createTransformedShape(mapState.getAffineTransform());
     758            Rectangle2D placement = iconPosition.findLabelPlacement(area, iconRect);
     759            if (placement == null) {
     760                return;
     761            }
     762            MapViewPoint p = mapState.getForView(placement.getCenterX(), placement.getCenterY());
    766763            drawIcon(p, img, disabled, selected, member, theta, (g, r) -> {
    767764                if (useStrokes) {
     
    774771                g.draw(r);
    775772            });
    776         }
     773        });
    777774    }
    778775
     
    11221119            }
    11231120        } else {
    1124             if (osm instanceof Way) {
    1125                 drawAreaText(osm, text, getPath((Way) osm));
    1126             } else if (osm instanceof Relation) {
    1127                 Multipolygon multipolygon = MultipolygonCache.getInstance().get(nc, (Relation) osm);
    1128                 if (!multipolygon.getOuterWays().isEmpty()) {
    1129                     for (PolyData pd : multipolygon.getCombinedPolygons()) {
    1130                         drawAreaText(osm, text, pd.get());
    1131                     }
     1121            forEachPolygon(osm, path -> drawAreaText(osm, text, path));
     1122        }
     1123    }
     1124
     1125    /**
     1126     * Calls a consumer for each path of the area shape-
     1127     * @param osm A way or a multipolygon
     1128     * @param consumer The consumer to call.
     1129     */
     1130    private void forEachPolygon(OsmPrimitive osm, Consumer<Path2D.Double> consumer) {
     1131        if (osm instanceof Way) {
     1132            consumer.accept(getPath((Way) osm));
     1133        } else if (osm instanceof Relation) {
     1134            Multipolygon multipolygon = MultipolygonCache.getInstance().get(nc, (Relation) osm);
     1135            if (!multipolygon.getOuterWays().isEmpty()) {
     1136                for (PolyData pd : multipolygon.getCombinedPolygons()) {
     1137                    consumer.accept(pd.get());
    11321138                }
    11331139            }
  • trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java

    r11722 r11730  
    2424import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
    2525import org.openstreetmap.josm.gui.mappaint.styleelement.AreaElement;
     26import org.openstreetmap.josm.gui.mappaint.styleelement.AreaIconElement;
    2627import org.openstreetmap.josm.gui.mappaint.styleelement.BoxTextElement;
    2728import org.openstreetmap.josm.gui.mappaint.styleelement.LineElement;
     
    373374                addIfNotNull(sl, LineElement.createRightCasing(env));
    374375                addIfNotNull(sl, LineElement.createCasing(env));
     376                addIfNotNull(sl, AreaIconElement.create(env));
    375377                addIfNotNull(sl, TextElement.create(env));
    376378                if (areaStyle != null) {
     
    393395                    addIfNotNull(sl, LineElement.createLine(env));
    394396                    addIfNotNull(sl, LineElement.createCasing(env));
     397                    addIfNotNull(sl, AreaIconElement.create(env));
    395398                    addIfNotNull(sl, TextElement.create(env));
    396399                    if (areaStyle != null) {
  • trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/AreaElement.java

    r11728 r11730  
    1515import org.openstreetmap.josm.gui.mappaint.Environment;
    1616import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference;
    17 import org.openstreetmap.josm.gui.util.RotationAngle;
    1817import org.openstreetmap.josm.tools.CheckParameterUtil;
    1918import org.openstreetmap.josm.tools.Utils;
     
    4443    /**
    4544     * The text that should be written on this area.
     45     * @deprecated Use {@link TextElement} instead.
    4646     */
    47     public TextLabel text;
     47    @Deprecated
     48    public TextLabel text = null;
    4849
    4950    /**
     
    6364    public Float extentThreshold;
    6465
    65     /**
    66      * The icon that is displayed on the center of the area.
    67      */
    68     private final MapImage iconImage;
    69 
    70     /**
    71      * The rotation of the {@link #iconImageAngle}
    72      */
    73     private final RotationAngle iconImageAngle;
    74 
    75     protected AreaElement(Cascade c, Color color, MapImage fillImage, Float extent,
    76             Float extentThreshold, TextLabel text, MapImage iconImage, RotationAngle iconImageAngle) {
     66    protected AreaElement(Cascade c, Color color, MapImage fillImage, Float extent, Float extentThreshold) {
    7767        super(c, 1f);
    7868        CheckParameterUtil.ensureParameterNotNull(color);
     
    8171        this.extent = extent;
    8272        this.extentThreshold = extentThreshold;
    83         this.text = text;
    84         this.iconImage = iconImage;
    85         this.iconImageAngle = iconImageAngle;
    8673    }
    8774
     
    118105        }
    119106
    120         TextLabel text = null; // <- text is handled by TextElement
    121         MapImage iconImage = NodeElement.createIcon(env);
    122         RotationAngle rotationAngle = NodeElement.createRotationAngle(env);
    123 
    124         if (iconImage != null) {
    125             // fake a transparent color.
    126             color = new Color(0, 0, 0, 0);
    127         }
    128 
    129107        if (color != null) {
    130108            Float extent = c.get(FILL_EXTENT, null, float.class);
    131109            Float extentThreshold = c.get(FILL_EXTENT_THRESHOLD, null, float.class);
    132110
    133             return new AreaElement(c, color, fillImage, extent, extentThreshold, text, iconImage, rotationAngle);
     111            return new AreaElement(c, color, fillImage, extent, extentThreshold);
    134112        } else {
    135113            return null;
     
    156134            painter.drawArea((Relation) osm, myColor, fillImage, extent, extentThreshold, painter.isInactiveMode() || osm.isDisabled(), text);
    157135        }
    158 
    159         if (iconImage != null && painter.isShowIcons()) {
    160             painter.drawAreaIcon(osm, iconImage, painter.isInactiveMode() || osm.isDisabled(), selected, member,
    161                     iconImageAngle == null ? 0.0 : iconImageAngle.getRotationAngle(osm));
    162         }
    163136    }
    164137
     
    171144        return Objects.equals(color, that.color) &&
    172145                Objects.equals(fillImage, that.fillImage) &&
    173                 Objects.equals(text, that.text) &&
    174146                Objects.equals(extent, that.extent) &&
    175                 Objects.equals(extentThreshold, that.extentThreshold) &&
    176                 Objects.equals(iconImage, that.iconImage) &&
    177                 Objects.equals(iconImageAngle, that.iconImageAngle);
     147                Objects.equals(extentThreshold, that.extentThreshold);
    178148    }
    179149
    180150    @Override
    181151    public int hashCode() {
    182         return Objects.hash(super.hashCode(), color, fillImage, text, extent, extentThreshold, iconImage, iconImageAngle);
     152        return Objects.hash(super.hashCode(), color, fillImage, extent, extentThreshold);
    183153    }
    184154
     
    186156    public String toString() {
    187157        return "AreaElemStyle{" + super.toString() + "color=" + Utils.toString(color) +
    188                 " fillImage=[" + fillImage + "] iconImage=[" + iconImage + "] iconImageAngle=[" + iconImageAngle + "]}";
     158                " fillImage=[" + fillImage + "] extent=[" + extent + "] extentThreshold=[" + extentThreshold + "]}";
    189159    }
    190160}
Note: See TracChangeset for help on using the changeset viewer.