rrenkert@243: /* rrenkert@243: * Copyright (c) 2011 by Intevation GmbH, Germany rrenkert@243: * rrenkert@243: * This file is part of MXD2map. rrenkert@243: * rrenkert@243: * This program is free software under the LGPL (>=v2.1) rrenkert@243: * Read the file LICENCE.txt coming with the software for details rrenkert@243: * or visit http://www.gnu.org/licenses/ if it does not exist. rrenkert@243: * rrenkert@243: * MXD2map has been developed on behalf of the rrenkert@243: * Bundesamt fuer Seeschifffahrt und Hydrographie (BSH) in Hamburg rrenkert@243: * by Intevation GmbH. rrenkert@243: * rrenkert@243: * Authors: rrenkert@243: * Raimund Renkert rrenkert@243: * Bjoern Schilberg rrenkert@243: * Stephan Holl rrenkert@243: */ rrenkert@243: rrenkert@87: package de.intevation.mxd.writer; rrenkert@87: rrenkert@87: import org.apache.log4j.Logger; rrenkert@87: rrenkert@87: import org.w3c.dom.Element; rrenkert@87: rrenkert@87: import edu.umn.gis.mapscript.mapObj; rrenkert@87: import edu.umn.gis.mapscript.classObj; rrenkert@87: import edu.umn.gis.mapscript.styleObj; rrenkert@87: import edu.umn.gis.mapscript.symbolObj; rrenkert@87: import edu.umn.gis.mapscript.symbolSetObj; rrenkert@87: import edu.umn.gis.mapscript.lineObj; rrenkert@87: import edu.umn.gis.mapscript.pointObj; raimund@192: import edu.umn.gis.mapscript.fontSetObj; raimund@192: import edu.umn.gis.mapscript.hashTableObj; rrenkert@87: import edu.umn.gis.mapscript.MS_SYMBOL_TYPE; rrenkert@87: raimund@174: import java.io.File; rrenkert@87: rrenkert@87: /** rrenkert@87: * The interface to the mapfile writer. rrenkert@87: * rrenkert@87: * @author Raimund Renkert rrenkert@87: */ rrenkert@87: public class SymbolWriter { rrenkert@87: rrenkert@87: /** rrenkert@87: * The Logger. rrenkert@87: */ rrenkert@87: private static final Logger logger = Logger.getLogger(SymbolWriter.class); rrenkert@87: rrenkert@181: /** rrenkert@181: * Private member. rrenkert@181: */ rrenkert@87: private mapObj map; rrenkert@87: private classObj cl; rrenkert@87: rrenkert@181: /** rrenkert@181: * Contructor with map object and class object. rrenkert@181: * rrenkert@181: * @param map The map object. rrenkert@181: * @param cl The class object containing the style. rrenkert@181: */ rrenkert@87: public SymbolWriter (mapObj map, classObj cl) { rrenkert@87: this.map = map; rrenkert@87: this.cl = cl; rrenkert@87: } rrenkert@87: rrenkert@87: /** rrenkert@87: * Write the content. rrenkert@181: * rrenkert@181: * @param symbolElement DOM element containg the style and symbol rrenkert@181: * attributes. rrenkert@87: */ rrenkert@120: public boolean write(Element symbolElement) { rrenkert@87: logger.debug("write(Element)"); rrenkert@87: symbolSetObj symbolSet = map.getSymbolset(); rrenkert@87: rrenkert@87: String name = symbolElement.getAttribute("name"); rrenkert@87: symbolObj sym = symbolSet.getSymbolByName(name); rrenkert@87: String symType = symbolElement.getAttribute("style"); rrenkert@97: String type = symbolElement.getAttribute("type"); rrenkert@87: if(symType.equals("point")) { rrenkert@87: writeSimple(sym); rrenkert@87: } rrenkert@87: else if (symType.equals("arrow")) { rrenkert@87: writeArrow(sym, symbolElement); rrenkert@87: } rrenkert@87: else if (symType.equals("char")) { vc11884admin@141: int exists = symbolExists(symbolElement); vc11884admin@141: if(exists == -1) { vc11884admin@141: String old = symbolElement.getAttribute("name"); vc11884admin@141: symbolElement.setAttribute( vc11884admin@141: "name", vc11884admin@141: old + symbolSet.getNumsymbols() + 1); vc11884admin@141: writeCharacter(sym, symbolElement); vc11884admin@141: } vc11884admin@141: else { vc11884admin@141: symbolElement.setAttribute( vc11884admin@141: "name", vc11884admin@141: symbolSet.getSymbol(exists).getName()); vc11884admin@141: } rrenkert@87: } rrenkert@97: else if (type.equals("line")) { rrenkert@97: writeHatch(sym); rrenkert@97: } rrenkert@87: else { rrenkert@87: return false; rrenkert@87: } rrenkert@90: rrenkert@120: try { rrenkert@120: saveSymbolSet(symbolSet); rrenkert@120: } rrenkert@120: catch(Exception e) { rrenkert@120: logger.error("Error saving symbol set."); rrenkert@120: return false; rrenkert@120: } rrenkert@90: rrenkert@87: return true; rrenkert@87: } rrenkert@87: rrenkert@181: /** rrenkert@181: * Create a simple point symbol. rrenkert@181: * rrenkert@181: * @param symbol The symbol object. rrenkert@181: */ rrenkert@87: private void writeSimple(symbolObj symbol) { rrenkert@87: logger.debug("writeSimple(symbolObj)"); rrenkert@87: lineObj points = new lineObj(); rrenkert@87: points.add(new pointObj(1,1,0)); rrenkert@87: symbol.setType(MS_SYMBOL_TYPE.MS_SYMBOL_ELLIPSE.swigValue()); rrenkert@87: symbol.setPoints(points); rrenkert@87: symbol.setFilled(1); rrenkert@87: } rrenkert@87: rrenkert@181: /** rrenkert@181: * Create an arrow symbol. rrenkert@181: * rrenkert@181: * @param symbol The symbol object. rrenkert@181: * @param symbolElement DOM element containing symbol attributes. rrenkert@181: */ rrenkert@87: private void writeArrow(symbolObj symbol, Element symbolElement) { rrenkert@87: logger.debug("writeArrow(symbolObj, Element)"); rrenkert@145: double len = 0; rrenkert@145: double width = 1; rrenkert@145: try { rrenkert@145: len = rrenkert@145: Double.parseDouble(symbolElement.getAttribute("length")); rrenkert@145: width = rrenkert@145: Double.parseDouble(symbolElement.getAttribute("width")); rrenkert@145: } rrenkert@145: catch(NumberFormatException nfe) { rrenkert@145: logger.warn ("Error setting arrow symbol."); rrenkert@145: return; rrenkert@145: } rrenkert@87: double ratio = len/width; rrenkert@87: lineObj points = new lineObj(); rrenkert@87: rrenkert@87: points.add(new pointObj(0, 0, 0)); rrenkert@87: points.add(new pointObj((1*ratio), 0.5, 0)); rrenkert@87: points.add(new pointObj(0, 1, 0)); rrenkert@87: points.add(new pointObj(0, 0, 0)); rrenkert@87: symbol.setType(MS_SYMBOL_TYPE.MS_SYMBOL_VECTOR.swigValue()); rrenkert@87: symbol.setPoints(points); rrenkert@87: symbol.setFilled(1); rrenkert@87: } rrenkert@87: rrenkert@181: /** rrenkert@181: * Create a character marker symbol. rrenkert@181: * rrenkert@181: * @param symbol The symbol object. rrenkert@181: * @param symbolElement DOM element containing symbol attributes. rrenkert@181: */ rrenkert@87: private void writeCharacter(symbolObj symbol, Element symbolElement) { rrenkert@87: logger.debug("writeCharacter(symbolObj, Element)"); rrenkert@93: String font = symbolElement.getAttribute("font"); rrenkert@93: //Remove all blank character to match the mapserver fonts.txt. rrenkert@93: font = font.replaceAll(" ", ""); raimund@192: fontSetObj fso = this.map.getFontset(); raimund@192: hashTableObj fonts = fso.getFonts(); raimund@192: String mapFont = fonts.get(font,""); raimund@192: if (mapFont == null || mapFont.equals("")) { raimund@192: logger.warn( raimund@192: "Could not find font " + font + " in font set. " + raimund@192: "Setting FreeSans as symbol font." + raimund@192: "Please add " + font + " to fonts.txt and replace the alias " + raimund@192: "in symbol \"" + symbolElement.getAttribute("name") + "\"."); raimund@192: font = "FreeSans"; raimund@192: } vc11884admin@141: symbol.setName(symbolElement.getAttribute("name")); rrenkert@93: symbol.setFont(font); rrenkert@87: symbol.setType(MS_SYMBOL_TYPE.MS_SYMBOL_TRUETYPE.swigValue()); rrenkert@87: symbol.setAntialias(1); rrenkert@93: symbol.setCharacter("&#" + symbolElement.getAttribute("char") + ";"); rrenkert@87: } rrenkert@87: rrenkert@181: /** rrenkert@181: * Create a hatch symbol for polygon fill. rrenkert@181: * rrenkert@181: * @param symbol The symbol object. rrenkert@181: */ rrenkert@97: private void writeHatch(symbolObj symbol) { rrenkert@97: logger.debug("writeHatch(symbolObj)"); rrenkert@97: symbol.setType(MS_SYMBOL_TYPE.MS_SYMBOL_HATCH.swigValue()); rrenkert@97: } rrenkert@97: rrenkert@181: /** rrenkert@181: * Determine whether this writer can create the symbol. rrenkert@181: * rrenkert@181: * @param type The symbol type. rrenkert@181: */ rrenkert@87: public boolean canWrite(String type) { rrenkert@87: if (type.equals("point") || rrenkert@87: type.equals("arrow") || rrenkert@97: type.equals("char") || rrenkert@97: type.equals("line")) { rrenkert@87: return true; rrenkert@87: } rrenkert@87: else { rrenkert@87: return false; rrenkert@87: } rrenkert@87: } rrenkert@90: rrenkert@181: /** rrenkert@181: * Save the symbol set. rrenkert@181: * rrenkert@181: * @param symbols The symbol set object. rrenkert@181: */ raimund@184: public void saveSymbolSet(symbolSetObj symbols) rrenkert@90: throws Exception { rrenkert@93: String path = this.map.getMappath(); raimund@184: String filename = path.substring(path.lastIndexOf(File.separator) + 1, raimund@184: path.lastIndexOf(".")); raimund@184: String symbolPath = filename + "-symbols.sym"; rrenkert@90: if(path.equals("")) { rrenkert@90: return; rrenkert@90: } raimund@174: raimund@174: if (path.endsWith(".map")) { raimund@174: path = path.substring(0, path.lastIndexOf(File.separator) + 1); raimund@175: path += symbolPath; raimund@174: } rrenkert@93: else { raimund@175: path += symbolPath; rrenkert@90: } raimund@175: path = path.replaceAll("\\\\", "/"); rrenkert@90: symbols.save(path); raimund@184: this.map.setSymbolSet(path); rrenkert@90: } vc11884admin@141: rrenkert@181: /** rrenkert@181: * Determine whether the symbol exists. rrenkert@181: * rrenkert@181: * @param elem DOM element containing the symbol attributes. rrenkert@181: * rrenkert@181: * @return Returns the symbol index if the symbol exists, else returns -1. rrenkert@181: */ vc11884admin@141: private int symbolExists (Element elem) { vc11884admin@141: symbolSetObj symbolSet = map.getSymbolset(); vc11884admin@141: for (int i = 0; i < symbolSet.getNumsymbols(); i++) { vc11884admin@141: symbolObj sym = symbolSet.getSymbol(i); vc11884admin@141: int stype = sym.getType(); vc11884admin@141: String etype = elem.getAttribute("style"); vc11884admin@141: if(stype == MS_SYMBOL_TYPE.MS_SYMBOL_ELLIPSE.swigValue () && vc11884admin@141: etype.equals("point")) { rrenkert@145: return i; vc11884admin@141: } vc11884admin@141: else if(stype == MS_SYMBOL_TYPE.MS_SYMBOL_VECTOR.swigValue () && vc11884admin@141: etype.equals("arrow")) { rrenkert@145: return i; vc11884admin@141: } vc11884admin@141: else if(stype == MS_SYMBOL_TYPE.MS_SYMBOL_TRUETYPE.swigValue () && vc11884admin@141: etype.equals("char")) { vc11884admin@141: String font = elem.getAttribute("font"); vc11884admin@141: font = font.replaceAll(" ", ""); vc11884admin@141: String c = elem.getAttribute("char"); vc11884admin@141: c = "&#" + c + ";"; vc11884admin@141: if (font.equals(sym.getFont()) && vc11884admin@141: c.equals(sym.getCharacter())) { vc11884admin@141: return i; vc11884admin@141: } vc11884admin@141: vc11884admin@141: } vc11884admin@141: else if(stype == MS_SYMBOL_TYPE.MS_SYMBOL_HATCH.swigValue () && vc11884admin@141: etype.equals("hatch")) { rrenkert@145: return i; vc11884admin@141: } vc11884admin@141: } vc11884admin@141: return -1; vc11884admin@141: } rrenkert@87: } rrenkert@87: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :