/* * Copyright (C) 2014 Alec Dhuse * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package co.foldingmap.map.themes; import co.foldingmap.Logger; import co.foldingmap.ResourceHelper; import co.foldingmap.map.Visibility; import co.foldingmap.map.vector.LineString; import co.foldingmap.map.vector.MapPoint; import co.foldingmap.map.vector.Polygon; import co.foldingmap.map.vector.VectorObject; import co.foldingmap.xml.XmlOutput; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.util.ArrayList; import java.util.HashMap; import javax.swing.ImageIcon; /** * Class used for storing information about how the map is styled. * * @author Alec */ public class MapTheme { protected Color backgroundColor, pointColor; protected HashMap<String, ColorRamp> colorRamps; protected HashMap<String, IconStyle> iconStyles; protected HashMap<String, LineStyle> lineStyles; protected HashMap<String, PolygonStyle> polygonStyles; protected HashMap<String, StyleMap> styleMaps; protected LabelStyle noLabel; protected Visibility lvl1, lvl2, lvl3, lvl4, lvl5; protected ResourceHelper resourceHelper; protected String themeName; public static final Font DEFAULT_FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 12); public static final LabelStyle DEFAULT_LABEL = new LabelStyle(Color.WHITE, new Color(68, 68, 68), DEFAULT_FONT); public MapTheme(String themeName) { this.themeName = themeName; this.backgroundColor = new Color(244, 243, 240); lvl1 = new Visibility(25, 16); lvl2 = new Visibility(25, 12); lvl3 = new Visibility(25, 8); lvl4 = new Visibility(25, 4); lvl5 = new Visibility(25, 2); this.colorRamps = new HashMap<String, ColorRamp>(); this.iconStyles = new HashMap<String, IconStyle>(); this.lineStyles = new HashMap<String, LineStyle>(); this.polygonStyles = new HashMap<String, PolygonStyle>(); this.styleMaps = new HashMap<String, StyleMap>(); this.resourceHelper = ResourceHelper.getInstance(); addStyleElement(new IconStyle( "(Unspecified Point)", new Color(68, 68, 68, 128))); addStyleElement(new LineStyle( "(Unspecified Linestring)", new Color(68, 68, 68, 128), 1.0f, LineStyle.SOLID, false)); addStyleElement(new PolygonStyle("(Unspecified Polygon)", new Color(188, 190, 178))); } /** * Adds a ColorRamp to this Theme. * * @param colorRamp */ public final void addColorRamp(ColorRamp colorRamp) { colorRamps.put(colorRamp.getID(), colorRamp); } /** * Add a Style Element * @param cs */ public final void addStyleElement(ColorStyle cs) { if (cs instanceof IconStyle) { IconStyle is = (IconStyle) cs; is.setResourceHelper(resourceHelper); iconStyles.put(cs.getID(), is); } else if (cs instanceof LineStyle) { lineStyles.put(cs.getID(), (LineStyle) cs); } else if (cs instanceof PolygonStyle) { polygonStyles.put(cs.getID(), (PolygonStyle) cs); } } /** * Returns an ArrayList of all the ColorRamps in this Theme. * * @return */ public ArrayList<ColorRamp> getAllColorRamps() { return new ArrayList<ColorRamp>(colorRamps.values()); } /** * Returns all the IconStyles in this MapTheme. * * @return */ public ArrayList<IconStyle> getAllIconStyles() { return new ArrayList<IconStyle>(iconStyles.values()); } /** * Returns all the LineStyles in this MapTheme. * * @return */ public ArrayList<LineStyle> getAllLineStyles() { return new ArrayList<LineStyle>(lineStyles.values()); } /** * Returns all the PolygonStyles in this MapTheme. * * @return */ public ArrayList<PolygonStyle> getAllPolygonStyles() { return new ArrayList<PolygonStyle>(polygonStyles.values()); } /** * Returns all styles for this theme, in an ArrayList. * * @return */ public ArrayList<ColorStyle> getAllStyles() { ArrayList<ColorStyle> styles = new ArrayList<ColorStyle>(); styles.addAll(iconStyles.values()); styles.addAll(lineStyles.values()); styles.addAll(polygonStyles.values()); return styles; } /** * Returns all the StyleMaps in this Theme. * * @return */ public ArrayList<StyleMap> getAllStyleMaps() { if (styleMaps.values() != null) { return new ArrayList<StyleMap>(styleMaps.values()); } else { return new ArrayList<StyleMap>(); } } /** * Returns the background style of this Theme. * * @return */ public Color getBackgroundColor() { return backgroundColor; } /** * Returns the ColorRamp with the given is. If no ColorRamp exists with * that id in this theme, null is returned. * * @param id * @return */ public ColorRamp getColorRamp(String id) { return colorRamps.get(id); } /** * Returns an IconStyle with a given Name. Returns null if that name * doesn't exist in the HashMap. * * @param elementName * @return */ public IconStyle getIconStyle(String elementName) { IconStyle returnIconStyle; returnIconStyle = iconStyles.get(elementName); return returnIconStyle; } /** * Returns an ImageIcon of a given image file located in this program's * .jar file. * * @param fileName * @return */ public ImageIcon getImageFromResourceMap(String fileName) { ImageIcon imageIcon; try { imageIcon = resourceHelper.getImage(fileName); } catch (Exception e) { imageIcon = null; Logger.log(Logger.ERR, "Error in MapTheme.getImageFromResourceMap(String) - " + e); } return imageIcon; } /** * Returns a LineStyle with a given name. Returns null if that LineStyle * does not exist in the HashMap. * * @param elementName * @return */ public LineStyle getLineStyle(String elementName) { LineStyle returnLineStyle; returnLineStyle = lineStyles.get(elementName); return returnLineStyle; } /** * Returns the name of this theme. * * @return */ public String getName() { return this.themeName; } /** * Returns the color that should be used in Edit Mode for object points. * The default is black. * * @return */ public Color getPointColor() { if (pointColor == null) { return Color.BLACK; } else { return pointColor; } } /** * Returns a PolygonStyle with a given name. Returns null if that * PolygonStyle does not exist in the HashMap. * * @param elementName * @return */ public PolygonStyle getPolygonStyle(String elementName) { PolygonStyle returnPolygonStyle; returnPolygonStyle = polygonStyles.get(elementName); return returnPolygonStyle; } /** * Creates a basic stroke with the given width and stroke style. * * @param stroke A String from the ThemeConstancts class for the stroke style to use. * @param width Width of stroke to draw. * @return */ public static BasicStroke getStroke(String stroke, float width) { BasicStroke newStroke; if (stroke.equalsIgnoreCase(ThemeConstants.DASHED)) { newStroke = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 10.0f, LineStyle.DASHED_STYLE, 0.0f); } else if (stroke.equalsIgnoreCase(ThemeConstants.DOTTED)) { newStroke = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 2f, new float[] {1, 4}, 0f); } else if (stroke.equalsIgnoreCase(ThemeConstants.SOLID)) { newStroke = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); } else { newStroke = new BasicStroke(width, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); } return newStroke; } /** * Returns and Style with a given name; * * @param elementName * @return * * @deprecated Use getStyle(VectorObject) instead. */ public ColorStyle getStyle(String elementName) { ColorStyle style; style = this.getIconStyle(elementName); if (style == null) style = this.getLineStyle(elementName); if (style == null) style = this.getPolygonStyle(elementName); return style; } /** * Returns the ColorStyle that best fits the given VectorObject. * * @param vectorObject The VectorObject we are seeking the style for. * @param zoom The zoom level to get the style for. * @return The ColorStyle that best fits the given VectorObject, null if none can be found. */ public ColorStyle getStyle(VectorObject vectorObject, float zoom) { ColorStyle style = null; // TODO: add other options such as looking for styles based on the Key-Value property pairs of the object. if (vectorObject instanceof LineString) { style = this.getLineStyle(vectorObject.getObjectClass()); } else if (vectorObject instanceof MapPoint) { style = this.getIconStyle(vectorObject.getObjectClass()); } else if (vectorObject instanceof Polygon) { style = this.getPolygonStyle(vectorObject.getObjectClass()); } return style; } /** * Returns a StyleMap with with a given name. Will Return null if the * given name does not exist in the HashMap. * * @param elementName * @return */ public StyleMap getStyleMap(String elementName) { return styleMaps.get(elementName); } /** * Removes a ColorRamp from this Theme. * * @param colorRamp */ public void removeColorRamp(ColorRamp colorRamp) { colorRamps.remove(colorRamp.getID()); } /** * Sets this Theme's background color. * * @param c */ public void setBackgroundColor(Color c) { this.backgroundColor = c; } /** * Returns the name of this Theme. * * @return */ @Override public String toString() { return themeName; } public void toXML(XmlOutput xmlWriter) { ArrayList<ColorRamp> colorRampList; ArrayList<IconStyle> iconStylesList; ArrayList<LineStyle> lineStylesList; ArrayList<PolygonStyle> polygonStylesList; ArrayList<StyleMap> styleMapsList; try { colorRampList = new ArrayList<ColorRamp> (getAllColorRamps()); iconStylesList = new ArrayList<IconStyle> (getAllIconStyles()); lineStylesList = new ArrayList<LineStyle> (getAllLineStyles()); polygonStylesList = new ArrayList<PolygonStyle> (getAllPolygonStyles()); styleMapsList = new ArrayList<StyleMap> (getAllStyleMaps()); xmlWriter.openTag("Style"); xmlWriter.writeTag("BackColor", ColorHelper.getColorHexStandard(backgroundColor)); xmlWriter.closeTag("Style"); for (IconStyle currentIconStyle: iconStylesList) currentIconStyle.toXML(xmlWriter); for (LineStyle currentStyle: lineStylesList) currentStyle.toXML(xmlWriter); for (PolygonStyle currentStyleMap: polygonStylesList) currentStyleMap.toXML(xmlWriter); for (StyleMap currentStyle: styleMapsList) currentStyle.toXML(xmlWriter); for (ColorRamp currentRamp: colorRampList) currentRamp.toXML(xmlWriter); } catch (Exception e) { Logger.log(Logger.ERR, "Error in MapTheme.toXML(XmlOutput) - " + e); } } }