Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/themes/ThemeDocument.java @ 6906:7a9cbb3a3d5a
Artifacts: Moved logic of ThemeUtils into ThemeDocument. TODO: Remove ThemeUtils
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Fri, 23 Aug 2013 01:16:13 +0200 |
parents | 1b35b2ddfc28 |
children | 819481cc9195 |
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * This file is Free Software under the GNU AGPL (>=v3) * and comes with ABSOLUTELY NO WARRANTY! Check out the * documentation coming with Dive4Elements River for details. */ package org.dive4elements.river.themes; import java.awt.Color; import java.awt.Font; import org.apache.log4j.Logger; import org.dive4elements.artifacts.CallMeta; import org.dive4elements.artifacts.common.utils.XMLUtils; import org.dive4elements.river.artifacts.model.MapserverStyle; import org.dive4elements.river.artifacts.model.MapserverStyle.Clazz; import org.dive4elements.river.artifacts.model.MapserverStyle.Expression; import org.dive4elements.river.artifacts.model.MapserverStyle.Label; import org.dive4elements.river.artifacts.model.MapserverStyle.Style; import org.dive4elements.river.artifacts.resources.Resources; import org.w3c.dom.Document; public class ThemeDocument { private static Logger logger = Logger.getLogger(ThemeDocument.class); private static final String MSG_ISOBATH_CLASS = "floodmap.isobath.class"; private static final String MSG_ISOBATH_LASTCLASS = "floodmap.isobath.lastclass"; public final static String XPATH_FILL_COLOR = "/theme/field[@name='fillcolor']/@default"; public final static String XPATH_LINE_COLOR = "/theme/field[@name='linecolor']/@default"; public final static String XPATH_AREA_LINE_COLOR = "/theme/field[@name='areabordercolor']/@default"; public static final String XPATH_LINE_SIZE = "/theme/field[@name='linesize']/@default"; public static final String XPATH_LINE_STYLE = "/theme/field[@name='linetype']/@default"; public static final String XPATH_POINT_SIZE = "/theme/field[@name='pointsize']/@default"; public static final String XPATH_POINT_COLOR = "/theme/field[@name='pointcolor']/@default"; public final static String XPATH_SHOW_BORDER = "/theme/field[@name='showborder']/@default"; public final static String XPATH_AREA_SHOW_BORDER = "/theme/field[@name='showborder']/@default"; public final static String XPATH_SHOW_POINTS = "/theme/field[@name='showpoints']/@default"; public final static String XPATH_SHOW_LINE = "/theme/field[@name='showlines']/@default"; public final static String XPATH_SHOW_VERTICAL_LINE = "/theme/field[@name='showverticalline']/@default"; public final static String XPATH_SHOW_HORIZONTAL_LINE = "/theme/field[@name='showhorizontalline']/@default"; public final static String XPATH_SHOW_LINE_LABEL = "/theme/field[@name='showlinelabel']/@default"; public final static String XPATH_SHOW_POINT_LABEL = "/theme/field[@name='showpointlabel']/@default"; public final static String XPATH_SHOW_WIDTH = "/theme/field[@name='showwidth']/@default"; public final static String XPATH_SHOW_LEVEL = "/theme/field[@name='showlevel']/@default"; public final static String XPATH_TRANSPARENCY = "/theme/field[@name='transparency']/@default"; public final static String XPATH_AREA_TRANSPARENCY = "/theme/field[@name='areatransparency']/@default"; public final static String XPATH_SHOW_AREA = "/theme/field[@name='showarea']/@default"; public final static String XPATH_SHOW_MIDDLE_HEIGHT = "/theme/field[@name='showmiddleheight']/@default"; public final static String XPATH_LABEL_FONT_COLOR = "/theme/field[@name='labelfontcolor']/@default"; public final static String XPATH_LABEL_FONT_SIZE = "/theme/field[@name='labelfontsize']/@default"; public final static String XPATH_LABEL_FONT_FACE = "/theme/field[@name='labelfontface']/@default"; public final static String XPATH_LABEL_FONT_STYLE = "/theme/field[@name='labelfontstyle']/@default"; public final static String XPATH_TEXT_ORIENTATION = "/theme/field[@name='textorientation']/@default"; public final static String XPATH_LABEL_BGCOLOR = "/theme/field[@name='labelbgcolor']/@default"; public final static String XPATH_LABEL_SHOW_BACKGROUND = "/theme/field[@name='labelshowbg']/@default"; public final static String XPATH_BACKGROUND_COLOR = "/theme/field[@name='backgroundcolor']/@default"; public final static String XPATH_AREA_BACKGROUND_COLOR = "/theme/field[@name='areabgcolor']/@default"; public final static String XPATH_SYMBOL = "/theme/field[@name='symbol']/@default"; public final static String XPATH_SHOW_MINIMUM = "/theme/field[@name='showminimum']/@default"; public final static String XPATH_SHOW_MAXIMUM = "/theme/field[@name='showmaximum']/@default"; public final static String XPATH_WSPLGEN_FIELDS = "/theme[@name='WSPLGEN']/field"; public final static String XPATH_WSPLGEN_STARTCOLOR = "/theme/field[@name='startcolor']/@default"; public final static String XPATH_WSPLGEN_ENDCOLOR = "/theme/field[@name='endcolor']/@default"; public final static String XPATH_WSPLGEN_NUMCLASSES = "/theme/field[@name='numclasses']/@default"; /** XPATH to bandwidth field. */ public final static String XPATH_BANDWIDTH = "/theme/field[@name='bandwidth']/@default"; /** XPATH to find showextramark field. */ public final static String XPATH_SHOWEXTRAMARK = "/theme/field[@name='showextramark']/@default"; private Document document; public ThemeDocument() { } public ThemeDocument(Document document) { this.document = document; } public Document getDocument() { return document; } /** Parse string to be boolean with default if empty or unrecognized. */ public static boolean parseBoolean(String value, boolean defaultsTo) { if (value == null || value.length() == 0) { return defaultsTo; } if (value.equals("false")) { return false; } else if (value.equals("true")) { return true; } else { return defaultsTo; } } /** * Attempt converting \param value to an integer, in failing cases, * return \param defaultsTo. * @param value String to be converted to integer. * @param defaultsTo Default to return if conversion failed. * @return \param value as integer or defaultsto if conversion failed. */ public static int parseInteger(String value, int defaultsTo) { if (value == null || value.length() == 0) { return defaultsTo; } try { return Integer.parseInt(value); } catch (NumberFormatException nfe) { // do nothing } return defaultsTo; } /** * Attempt converting \param value to a double, in failing cases, * return \param defaultsTo. * @param value String to be converted to double. * @param defaultsTo Default to return if conversion failed. * @return \param value as integer or defaultsto if conversion failed. */ public static double parseDouble(String value, double defaultsTo) { if (value == null || value.length() == 0) { return defaultsTo; } try { return Double.parseDouble(value); } catch (NumberFormatException nfe) { // do nothing } return defaultsTo; } public boolean parseShowLineLabel() { String show = XMLUtils.xpathString(document, XPATH_SHOW_LINE_LABEL, null); return parseBoolean(show, false); } public boolean parseShowWidth() { String show = XMLUtils.xpathString(document, XPATH_SHOW_WIDTH, null); return parseBoolean(show, false); } public boolean parseShowLevel() { String show = XMLUtils.xpathString(document, XPATH_SHOW_LEVEL, null); return parseBoolean(show, false); } public String parseTextOrientation() { String o = XMLUtils.xpathString(document, XPATH_TEXT_ORIENTATION, null); if ("true".equals(o)) { return "horizontal"; } else { return "vertical"; } } public boolean parseShowMiddleHeight() { String show = XMLUtils.xpathString(document, XPATH_SHOW_MIDDLE_HEIGHT, null); return parseBoolean(show, false); } public boolean parseLabelShowBackground() { String show = XMLUtils.xpathString(document, XPATH_LABEL_SHOW_BACKGROUND, null); return parseBoolean(show, false); } public Font parseTextFont() { String font = XMLUtils.xpathString(document, XPATH_LABEL_FONT_FACE, null); if (font == null || font.length() == 0) { return null; } int size = parseTextSize(); int style = parseTextStyle(); Font f = new Font(font, style, size); return f; } public Color parseTextColor() { return parseRGB(getTextColorString()); } public String getTextColorString() { String textColor = XMLUtils.xpathString(document, XPATH_LABEL_FONT_COLOR, null); return textColor; } public Color parseTextBackground() { String color = getLabelBackgroundColorString(); if (color == null || color.length() == 0) { return Color.WHITE; } return parseRGB(color); } public String getLabelBackgroundColorString() { return XMLUtils.xpathString(document, XPATH_LABEL_BGCOLOR, null); } public int parseLineWidth() { String size = XMLUtils.xpathString(document, XPATH_LINE_SIZE, null); if (size == null || size.length() == 0) { return 0; } try { return Integer.parseInt(size); } catch (NumberFormatException nfe) { logger.warn("Unable to set line size from string: '" + size + "'"); } return 0; } public float [] parseLineStyle() { String dash = XMLUtils.xpathString(document, XPATH_LINE_STYLE, null); float[] def = {10}; if (dash == null || dash.length() == 0) { return def; } String[] pattern = dash.split(","); if(pattern.length == 1) { return def; } try { float[] dashes = new float[pattern.length]; for (int i = 0; i < pattern.length; i++) { dashes[i] = Float.parseFloat(pattern[i]); } return dashes; } catch(NumberFormatException nfe) { logger.warn("Unable to set dash from string: '" + dash + "'"); return def; } } public int parsePointWidth() { String width = XMLUtils.xpathString(document, XPATH_POINT_SIZE, null); return parseInteger(width, 3); } public Color parsePointColor() { String color = XMLUtils.xpathString(document, XPATH_POINT_COLOR, null); logger.debug("parsePointColor(): color = " + color); return parseColor(color); } public boolean parseShowPoints() { String show = XMLUtils.xpathString(document, XPATH_SHOW_POINTS, null); return parseBoolean(show, false); } public boolean parseShowLine() { String show = XMLUtils.xpathString(document, XPATH_SHOW_LINE, null); return parseBoolean(show, true); } public int parseTextStyle() { return parseTextStyle(XPATH_LABEL_FONT_STYLE); } public int parseTextStyle(String path) { String style = XMLUtils.xpathString(document, path, null); if (style == null || style.length() == 0) { return Font.PLAIN; } if (style.equals("italic")) { return Font.ITALIC; } else if (style.equals("bold")) { return Font.BOLD; } else { return Font.PLAIN; } } public TextStyle parseComplexTextStyle() { return new TextStyle( parseTextColor(), parseTextFont(), parseTextBackground(), parseLabelShowBackground(), !parseTextOrientation().equals("horizontal")); } public LineStyle parseComplexLineStyle() { return new LineStyle( parseLineColorField(), Integer.valueOf(parseLineWidth())); } public Color parseComplexLineColorField() { return null; } public boolean parseShowVerticalLine() { String show = XMLUtils.xpathString(document, XPATH_SHOW_VERTICAL_LINE, null); return parseBoolean(show, true); } public boolean parseShowHorizontalLine() { String show = XMLUtils.xpathString(document, XPATH_SHOW_HORIZONTAL_LINE, null); return parseBoolean(show, true); } public double parseBandWidth() { String bandWidth = XMLUtils.xpathString(document, XPATH_BANDWIDTH, null); return parseDouble(bandWidth, 0); } public static Color parseColor(String colorString) { if (colorString == null || colorString.length() == 0) { return null; } else if (colorString.indexOf("#") == 0) { return parseHexColor(colorString); } else if (colorString.indexOf(",") >= 0) { return parseRGB(colorString); } return null; } /** * Parse a string like "#00CC22" and return the corresponding color. * * @param hex The hex color value. * * @return a Color or null, if <i>hex</i> is empty. */ public static Color parseHexColor(String hex) { if (hex == null) { return null; } return Color.decode(hex); } public boolean parseShowArea() { String show = XMLUtils.xpathString(document, XPATH_SHOW_AREA, null); return parseBoolean(show, false); } public boolean parseShowPointLabel() { String show = XMLUtils.xpathString(document, XPATH_SHOW_POINT_LABEL, null); return parseBoolean(show, false); } public boolean parseShowExtraMark() { String show = XMLUtils.xpathString(document, XPATH_SHOWEXTRAMARK, null); return parseBoolean(show, false); } public int parseTextSize() { return parseTextSize(XPATH_LABEL_FONT_SIZE); } public int parseTextSize(String path) { String size = XMLUtils.xpathString(document, path, null); if (size == null || size.length() == 0) { return 10; } try { return Integer.parseInt(size); } catch (NumberFormatException nfe) { } return 10; } /** * Parse a string like "103, 100, 0" and return a corresping color. * @param rgbtext Color as string representation, e.g. "255,0,20". * @return Color, null in case of issues. */ public static Color parseRGB(String rgbtext) { if (rgbtext == null) { return null; } String rgb[] = rgbtext.split(","); Color c = null; try { c = new Color( Integer.parseInt(rgb[0].trim()), Integer.parseInt(rgb[1].trim()), Integer.parseInt(rgb[2].trim())); } catch (NumberFormatException nfe) { c = null; } return c; } public String getLineColorString() { return XMLUtils.xpathString(document, XPATH_LINE_COLOR, null); } /** Get show border as string. */ public String getShowBorderString() { return XMLUtils.xpathString(document, XPATH_SHOW_BORDER, null); } /** Get fill color as string. */ public String getFillColorString() { return XMLUtils.xpathString(document, XPATH_FILL_COLOR, null); } public String getBackgroundColorString() { return XMLUtils.xpathString(document, XPATH_BACKGROUND_COLOR, null); } public String getSymbol() { return XMLUtils.xpathString(document, XPATH_SYMBOL, null); } public String getTransparencyString() { return XMLUtils.xpathString(document, XPATH_TRANSPARENCY, null); } public String getAreaTransparencyString() { return XMLUtils.xpathString(document, XPATH_AREA_TRANSPARENCY, null); } public String getShowMinimum() { return XMLUtils.xpathString(document, XPATH_SHOW_MINIMUM, null); } public String getShowMaximum() { return XMLUtils.xpathString(document, XPATH_SHOW_MAXIMUM, null); } /** * Gets color from color field. * @param theme the theme document. * @return color. */ public Color parseFillColorField() { return parseRGB(getFillColorString()); } public boolean parseShowBorder() { return parseBoolean(getShowBorderString(), false); } public int parseTransparency() { return parseInteger(getTransparencyString(), 50); } /** * Gets color from color field. * @param theme the theme document. * @return color. */ public Color parseLineColorField() { String lineColorStr = getLineColorString(); logger.debug("parseLineColorField: lineColorStr = " + (lineColorStr == null ? "null" : lineColorStr)); return parseColor(lineColorStr); } public Color parseAreaLineColorField() { String lineColorStr = getAreaLineColorString(); logger.debug("parseLineColorField: lineColorStr = " + (lineColorStr == null ? "null" : lineColorStr)); return parseColor(lineColorStr); } private String getAreaLineColorString() { return XMLUtils.xpathString(document, XPATH_AREA_LINE_COLOR, null); } public boolean parseShowMinimum() { return parseBoolean(getShowMinimum(), false); } public boolean parseShowMaximum() { return parseBoolean(getShowMaximum(), false); } /** * Creates a MapserverStyle from the given XML theme. * This method uses a start- and endcolor to interpolate a * given number of color classes for the MapserverStyle. * @param theme * @return String representation of the MapserverStyle */ public String createDynamicMapserverStyle( float from, float to, float step, CallMeta meta) { MapserverStyle ms = new MapserverStyle(); String strStartColor = XMLUtils.xpathString(document, XPATH_WSPLGEN_STARTCOLOR, null); Color startColor = strStartColor != null ? parseColor(strStartColor) : new Color(178, 201, 215); String strEndColor = XMLUtils.xpathString(document, XPATH_WSPLGEN_ENDCOLOR, null); Color endColor = strEndColor != null? parseColor(strEndColor) : new Color(2, 27, 42); to = to != 0 ? to : 9999; step = step != 0 ? step : to; int numClasses = (int)((to - from) / step); float rd = (endColor.getRed() - startColor.getRed()) / (float)numClasses; float gd = (endColor.getGreen() - startColor.getGreen()) / (float)numClasses; float bd = (endColor.getBlue() - startColor.getBlue()) / (float)numClasses; if (numClasses > 1) { // Desktop Flys always added a last "and larger class" numClasses += 1; } for (int n = 0; n < numClasses; n++) { StringBuilder newColor = new StringBuilder(); newColor.append(startColor.getRed() + Math.round(n * rd)); newColor.append(' '); newColor.append(startColor.getGreen() + Math.round(n * gd)); newColor.append(' '); newColor.append(startColor.getBlue() + Math.round(n * bd)); String expr = createWSPLGENClassExpression(from + n * step, step, n + 1, numClasses); String name = createWSPLGENClassName(from + n * step, step, n + 1, numClasses, meta); Clazz c = new Clazz(name); Style s = new Style(); s.setColor(newColor.toString()); s.setSize(5); c.addItem(new Expression("(" + expr + ")")); c.addItem(s); ms.addClazz(c); } return ms.toString(); } protected static String createWSPLGENClassExpression(float val, float step, int idx, int maxIdx) { if (idx < maxIdx) { return "[DIFF] >= " + val + " AND [DIFF] < " + (val + step); } else { return "[DIFF] >= " + val; } } /** * Creates a class name for the mapfile style that visualizes a floodmap. * The class names are used in the map's legend. * * @param val Current isobath value. * @param step Difference between to class values. * @param idx Current class index that is being processed. * @param maxIdx Highest class index. * @param meta Caller meta object used to determine locale. * @return */ protected static String createWSPLGENClassName(float val, float step, int idx, int maxIdx, CallMeta meta) { assert meta != null : "CallMeta instance is null"; if (idx < maxIdx) { return Resources.getMsg(meta, MSG_ISOBATH_CLASS, new Object[] {val, val + step}); } else { return Resources.getMsg(meta, MSG_ISOBATH_LASTCLASS, new Object[] {val}); } } public String createMapserverStyle() { String symbol = getSymbol(); String backcolor = getLabelBackgroundColorString(); String linecolor = getLineColorString(); if (linecolor == null || "".equals(linecolor)) { logger.warn("createMapserverStyle: linecolor String is empty"); linecolor = "0,128,255"; } int linewidth = parseLineWidth(); MapserverStyle ms = new MapserverStyle(); Clazz c = new Clazz(" "); Style s = new Style(); s.setOutlineColor(linecolor.replace(",", " ")); if (backcolor != null && backcolor.length() > 0) { s.setColor(backcolor.replace(",", " ")); } s.setSize(linewidth); s.setSymbol(symbol); c.addItem(s); String textcolor = getTextColorString(); int textsize = parseTextSize(); if (textcolor != null && textcolor.length() > 0 && textsize > 0) { Label l = new Label(); l.setColor(textcolor.replace(",", " ")); l.setSize(textsize); c.addItem(l); } ms.addClazz(c); return ms.toString(); } public String getAreaBackgroundColorString() { return XMLUtils.xpathString(document, XPATH_AREA_BACKGROUND_COLOR, null); } public Color parseAreaBackgroundColor() { return parseColor(getAreaBackgroundColorString()); } public int parseAreaTransparency() { return parseInteger(getAreaTransparencyString(), 50); } public boolean parseAreaShowBorder() { return parseBoolean(getAreaShowBorderString(), false); } private String getAreaShowBorderString() { return XMLUtils.xpathString(document, XPATH_AREA_SHOW_BORDER, null); } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :