001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.mappaint.styleelement; 003 004import java.awt.Color; 005import java.util.Objects; 006 007import org.openstreetmap.josm.Main; 008import org.openstreetmap.josm.data.osm.OsmPrimitive; 009import org.openstreetmap.josm.data.osm.Relation; 010import org.openstreetmap.josm.data.osm.Way; 011import org.openstreetmap.josm.data.osm.visitor.paint.MapPaintSettings; 012import org.openstreetmap.josm.data.osm.visitor.paint.PaintColors; 013import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer; 014import org.openstreetmap.josm.gui.mappaint.Cascade; 015import org.openstreetmap.josm.gui.mappaint.Environment; 016import org.openstreetmap.josm.gui.mappaint.Keyword; 017import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference; 018import org.openstreetmap.josm.tools.CheckParameterUtil; 019import org.openstreetmap.josm.tools.Utils; 020 021public class AreaElement extends StyleElement { 022 023 /** 024 * If fillImage == null, color is the fill-color, otherwise 025 * an arbitrary color value sampled from the fillImage 026 */ 027 public Color color; 028 public MapImage fillImage; 029 public TextLabel text; 030 public Float extent; 031 public Float extentThreshold; 032 033 protected AreaElement(Cascade c, Color color, MapImage fillImage, Float extent, Float extentThreshold, TextLabel text) { 034 super(c, 1f); 035 CheckParameterUtil.ensureParameterNotNull(color); 036 this.color = color; 037 this.fillImage = fillImage; 038 this.extent = extent; 039 this.extentThreshold = extentThreshold; 040 this.text = text; 041 } 042 043 public static AreaElement create(final Environment env) { 044 final Cascade c = env.mc.getCascade(env.layer); 045 MapImage fillImage = null; 046 Color color; 047 048 IconReference iconRef = c.get(FILL_IMAGE, null, IconReference.class); 049 if (iconRef != null) { 050 fillImage = new MapImage(iconRef.iconName, iconRef.source, false); 051 052 color = new Color(fillImage.getImage(false).getRGB( 053 fillImage.getWidth() / 2, fillImage.getHeight() / 2) 054 ); 055 056 fillImage.alpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.fill-image-alpha", 255)))); 057 Integer pAlpha = Utils.color_float2int(c.get(FILL_OPACITY, null, float.class)); 058 if (pAlpha != null) { 059 fillImage.alpha = pAlpha; 060 } 061 } else { 062 color = c.get(FILL_COLOR, null, Color.class); 063 if (color != null) { 064 int alpha = color.getAlpha(); 065 if (alpha == 255) { 066 // Assume alpha value has not been specified by the user if 067 // is set to fully opaque. Use default value in this case. 068 // It is not an ideal solution, but a little tricky to get this 069 // right, especially as named map colors can be changed in 070 // the preference GUI and written to the preferences file. 071 alpha = Math.min(255, Math.max(0, Integer.valueOf(Main.pref.getInteger("mappaint.fillalpha", 50)))); 072 } 073 Integer pAlpha = Utils.color_float2int(c.get(FILL_OPACITY, null, float.class)); 074 if (pAlpha != null) { 075 alpha = pAlpha; 076 } 077 color = new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha); 078 } 079 } 080 081 TextLabel text = null; 082 Keyword textPos = c.get(TEXT_POSITION, null, Keyword.class); 083 if (textPos == null || "center".equals(textPos.val)) { 084 text = TextLabel.create(env, PaintColors.AREA_TEXT.get(), true); 085 } 086 087 Float extent = c.get(FILL_EXTENT, null, float.class); 088 Float extentThreshold = c.get(FILL_EXTENT_THRESHOLD, null, float.class); 089 090 if (color != null) 091 return new AreaElement(c, color, fillImage, extent, extentThreshold, text); 092 else 093 return null; 094 } 095 096 @Override 097 public void paintPrimitive(OsmPrimitive osm, MapPaintSettings paintSettings, StyledMapRenderer painter, 098 boolean selected, boolean outermember, boolean member) { 099 Color myColor = color; 100 if (osm instanceof Way) { 101 if (color != null) { 102 if (selected) { 103 myColor = paintSettings.getSelectedColor(color.getAlpha()); 104 } else if (outermember) { 105 myColor = paintSettings.getRelationSelectedColor(color.getAlpha()); 106 } 107 } 108 painter.drawArea((Way) osm, myColor, fillImage, extent, extentThreshold, painter.isInactiveMode() || osm.isDisabled(), text); 109 } else if (osm instanceof Relation) { 110 if (color != null && (selected || outermember)) { 111 myColor = paintSettings.getRelationSelectedColor(color.getAlpha()); 112 } 113 painter.drawArea((Relation) osm, myColor, fillImage, extent, extentThreshold, painter.isInactiveMode() || osm.isDisabled(), text); 114 } 115 } 116 117 @Override 118 public boolean equals(Object obj) { 119 if (this == obj) return true; 120 if (obj == null || getClass() != obj.getClass()) return false; 121 if (!super.equals(obj)) return false; 122 AreaElement that = (AreaElement) obj; 123 return Objects.equals(color, that.color) && 124 Objects.equals(fillImage, that.fillImage) && 125 Objects.equals(text, that.text) && 126 Objects.equals(extent, that.extent) && 127 Objects.equals(extentThreshold, that.extentThreshold); 128 } 129 130 @Override 131 public int hashCode() { 132 return Objects.hash(super.hashCode(), color, fillImage, text, extent, extentThreshold); 133 } 134 135 @Override 136 public String toString() { 137 return "AreaElemStyle{" + super.toString() + "color=" + Utils.toString(color) + 138 " fillImage=[" + fillImage + "]}"; 139 } 140}