001: /*---------------- FILE HEADER ------------------------------------------
002:
003: This file is part of deegree.
004: Copyright (C) 2001 by:
005: EXSE, Department of Geography, University of Bonn
006: http://www.giub.uni-bonn.de/exse/
007: lat/lon Fitzke/Fretter/Poth GbR
008: http://www.lat-lon.de
009:
010: This library is free software; you can redistribute it and/or
011: modify it under the terms of the GNU Lesser General Public
012: License as published by the Free Software Foundation; either
013: version 2.1 of the License, or (at your option) any later version.
014:
015: This library is distributed in the hope that it will be useful,
016: but WITHOUT ANY WARRANTY; without even the implied warranty of
017: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
018: Lesser General Public License for more details.
019:
020: You should have received a copy of the GNU Lesser General Public
021: License along with this library; if not, write to the Free Software
022: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
023:
024: Contact:
025:
026: Andreas Poth
027: lat/lon Fitzke/Fretter/Poth GbR
028: Meckenheimer Allee 176
029: 53115 Bonn
030: Germany
031: E-Mail: poth@lat-lon.de
032:
033: Jens Fitzke
034: Department of Geography
035: University of Bonn
036: Meckenheimer Allee 166
037: 53115 Bonn
038: Germany
039: E-Mail: jens.fitzke@uni-bonn.de
040:
041:
042: ---------------------------------------------------------------------------*/
043: package de.latlon.deejump.plugin.style;
044:
045: import java.io.File;
046: import java.io.FileInputStream;
047: import java.io.FileOutputStream;
048: import java.io.FileWriter;
049: import java.io.IOException;
050: import java.io.InputStream;
051: import java.io.InputStreamReader;
052: import java.io.OutputStreamWriter;
053: import java.io.StringWriter;
054: import java.io.UnsupportedEncodingException;
055: import java.net.URL;
056: import java.util.HashMap;
057: import java.util.Iterator;
058:
059: import javax.swing.Icon;
060: import javax.swing.ImageIcon;
061: import javax.swing.JFileChooser;
062: import javax.xml.transform.Transformer;
063: import javax.xml.transform.TransformerConfigurationException;
064: import javax.xml.transform.TransformerException;
065: import javax.xml.transform.TransformerFactory;
066: import javax.xml.transform.TransformerFactoryConfigurationError;
067: import javax.xml.transform.stream.StreamResult;
068: import javax.xml.transform.stream.StreamSource;
069:
070: import org.openjump.core.ui.util.ScreenScale;
071:
072: import com.vividsolutions.jts.geom.Geometry;
073: import com.vividsolutions.jump.I18N;
074: import com.vividsolutions.jump.feature.BasicFeature;
075: import com.vividsolutions.jump.feature.Feature;
076: import com.vividsolutions.jump.task.TaskMonitor;
077: import com.vividsolutions.jump.util.java2xml.Java2XML;
078: import com.vividsolutions.jump.workbench.WorkbenchContext;
079: import com.vividsolutions.jump.workbench.model.Layer;
080: import com.vividsolutions.jump.workbench.plugin.AbstractPlugIn;
081: import com.vividsolutions.jump.workbench.plugin.EnableCheck;
082: import com.vividsolutions.jump.workbench.plugin.EnableCheckFactory;
083: import com.vividsolutions.jump.workbench.plugin.MultiEnableCheck;
084: import com.vividsolutions.jump.workbench.plugin.PlugInContext;
085: import com.vividsolutions.jump.workbench.ui.GUIUtil;
086: import com.vividsolutions.jump.workbench.ui.LayerViewPanel;
087: import com.vividsolutions.jump.workbench.ui.MenuNames;
088: import com.vividsolutions.jump.workbench.ui.MultiInputDialog;
089: import com.vividsolutions.jump.workbench.ui.plugin.FeatureInstaller;
090:
091: /**
092: * ...
093: *
094: * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei </a>
095: *
096: */
097: public class LayerStyle2SLDPlugIn extends AbstractPlugIn {
098:
099: /**
100: * The <code>Transformer</code> object used in the transformation of a task/project/layer xml
101: * to sld.
102: */
103: protected static Transformer transformer = null;
104:
105: private static String WMS_LAYER_NAME = I18N
106: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.WMS-Layer-name");
107:
108: private static String STYLE_NAME = I18N
109: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.Style-name");
110:
111: private static String STYLE_TITLE = I18N
112: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.Style-title");
113:
114: private static String FEATURETYPE_STYLE = I18N
115: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.Feature-Type-Style");
116:
117: private static String GEOTYPE = I18N
118: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.geoType");
119:
120: private static final String UTF_8 = "UTF-8";
121:
122: private static String GEOM_PROPERTY = I18N
123: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.geomProperty");
124:
125: private static String SCALE_MIN = I18N
126: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.minScale");
127:
128: private static String SCALE_MAX = I18N
129: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.maxScale");
130:
131: static {
132: initTransformer();
133: }
134:
135: private Java2XML java2Xml = new Java2XML();
136:
137: private JFileChooser fileChooser;
138:
139: private MultiInputDialog dialog;
140:
141: private String wmsLayerName = WMS_LAYER_NAME;
142:
143: private String styleName = STYLE_NAME;
144:
145: private String styleTitle = STYLE_TITLE;
146:
147: private String featureTypeStyle = FEATURETYPE_STYLE;
148:
149: private double scaleFactor = 1d;
150:
151: private String geoProperty = "GEOM";
152:
153: public String getName() {
154: return I18N
155: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.Transform-layer-style-into-sld");
156: }
157:
158: /**
159: * use this method to install the LayerStyle2SLD plugin in the toolbar
160: * @param context
161: * @throws Exception
162: */
163: public void install(PlugInContext context) throws Exception {
164:
165: context
166: .getWorkbenchContext()
167: .getWorkbench()
168: .getFrame()
169: .getToolBar()
170: .addPlugIn(
171: getIcon(),
172: this ,
173: createEnableCheck(context.getWorkbenchContext()),
174: context.getWorkbenchContext());
175:
176: }
177:
178: public void initialize(PlugInContext context) throws Exception {
179:
180: FeatureInstaller featureInstaller = new FeatureInstaller(
181: context.getWorkbenchContext());
182: featureInstaller.addMainMenuItem(this , //exe
183: new String[] { MenuNames.VIEW }, //menu path
184: this .getName() + "{pos:2}", //name methode .getName recieved by AbstractPlugIn
185: false, //checkbox
186: null, //icon
187: createEnableCheck(context.getWorkbenchContext())); //enable check
188: }
189:
190: private void initStrings() {
191:
192: WMS_LAYER_NAME = I18N
193: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.WMS-Layer-name");
194: STYLE_NAME = I18N
195: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.Style-name");
196: STYLE_TITLE = I18N
197: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.Style-title");
198: FEATURETYPE_STYLE = I18N
199: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.Feature-Type-Style");
200: GEOTYPE = I18N
201: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.geoType");
202: GEOM_PROPERTY = I18N
203: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.geomProperty");
204: SCALE_MIN = I18N
205: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.minScale");
206: String SCALE_MAX = I18N
207: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.maxScale");
208:
209: }
210:
211: public boolean execute(PlugInContext context) throws Exception {
212: reportNothingToUndoYet(context);
213:
214: this .initStrings();
215:
216: Layer layer = context.getSelectedLayer(0);
217: if (layer == null) {
218: return false;
219: }
220:
221: initDialog(context);
222:
223: dialog.setVisible(true);
224:
225: if (!dialog.wasOKPressed()) {
226: return false;
227: }
228:
229: wmsLayerName = dialog.getText(WMS_LAYER_NAME);
230: styleName = dialog.getText(STYLE_NAME);
231: styleTitle = dialog.getText(STYLE_TITLE);
232: featureTypeStyle = dialog.getText(FEATURETYPE_STYLE);
233: geoProperty = dialog.getText(GEOM_PROPERTY);
234:
235: if (fileChooser == null) {
236: fileChooser = new JFileChooser();
237: fileChooser
238: .setApproveButtonText(I18N
239: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.Save"));
240: fileChooser
241: .setDialogTitle(I18N
242: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.Save-style-as-SLD"));
243: }
244:
245: if (JFileChooser.APPROVE_OPTION == fileChooser
246: .showOpenDialog(context.getWorkbenchFrame())) {
247:
248: //FIXME no good: saving to file to transform...
249: File file = File.createTempFile("temptask", ".xml");
250: file.deleteOnExit();
251:
252: activateVertexStyle(layer);
253:
254: scaleFactor = calcScaleFactor(context.getLayerViewPanel());
255:
256: transformXML(layer, file, fileChooser.getSelectedFile(),
257: scaleFactor);
258:
259: }
260:
261: return true;
262: }
263:
264: /**
265: * When starting up, vertex styles might be deactivated, though they are "shown". So, if
266: * layer if of point type, and basic style is activated, activated vertex style too.
267: * @param layer
268: */
269: private void activateVertexStyle(Layer layer) {
270: Iterator iter = layer.getFeatureCollectionWrapper()
271: .getUltimateWrappee().getFeatures().iterator();
272: String type = "";
273: if (iter.hasNext()) {
274: Feature f = (Feature) iter.next();
275: type = f.getGeometry().getGeometryType();
276:
277: }
278: if (layer.getBasicStyle().isEnabled()) {
279: if ("MultiPoint".equals(type) || "Point".equals(type)) {
280: layer.getVertexStyle().setEnabled(true);
281: }
282: }
283: }
284:
285: private void initDialog(PlugInContext context) {
286: if (dialog == null) {
287:
288: dialog = new MultiInputDialog(
289: context.getWorkbenchFrame(),
290: I18N
291: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.SLD-Parameters"),
292: true);
293:
294: dialog.addSeparator();
295:
296: dialog
297: .addTextField(
298: GEOM_PROPERTY,
299: geoProperty,
300: 25,
301: null,
302: I18N
303: .get("deejump.pluging.style.LayerStyle2SLDPlugIn.Input-the-name-of-the-geometry-property"));
304:
305: dialog.addSeparator();
306: String name = context.getCandidateLayer(0).getName();
307:
308: dialog.addTextField(WMS_LAYER_NAME, name, 25, null,
309: WMS_LAYER_NAME);
310: dialog.addTextField(STYLE_NAME, name, 25, null, STYLE_NAME);
311: dialog.addTextField(STYLE_TITLE, name, 25, null,
312: STYLE_TITLE);
313: dialog.addTextField(FEATURETYPE_STYLE, name, 25, null,
314: FEATURETYPE_STYLE);
315: GUIUtil.centreOnWindow(dialog);
316: }
317: }
318:
319: private void transformXML(Layer layer, File inputXML,
320: File outputXML, double scaleFactor) throws Exception {
321:
322: //TODO don't assume has 1 item!!!
323: BasicFeature bf = (BasicFeature) layer
324: .getFeatureCollectionWrapper().getFeatures().get(0);
325: Geometry geo = bf.getGeometry();
326: String geoType = geo.getGeometryType();
327:
328: java2Xml.write(layer, "layer", inputXML);
329:
330: FileInputStream input = new FileInputStream(inputXML);
331:
332: //FileWriter fw = new FileWriter( outputXML );
333: OutputStreamWriter fw = new OutputStreamWriter(
334: new FileOutputStream(outputXML), UTF_8);
335:
336: HashMap map = new HashMap(10);
337: map.put(WMS_LAYER_NAME, wmsLayerName);
338: map.put(FEATURETYPE_STYLE, featureTypeStyle);
339: map.put(STYLE_NAME, styleName);
340: map.put(STYLE_TITLE, styleTitle);
341: map.put(GEOTYPE, geoType);
342: map.put(GEOM_PROPERTY, geoProperty);
343:
344: // ATENTION : note that min and max are swapped in JUMP!!!
345: // will swap later, in transformContext
346: Double d = layer.getMinScale();
347: d = d != null ? d : new Double(0);
348:
349: map.put(SCALE_MIN, toRealWorldScale(scaleFactor, d
350: .doubleValue()));
351:
352: // using Double.MAX_VALUE is creating a large number - too many 0's
353: // make it simple and hardcde a large number
354: final double largeNumber = 99999999999d;
355: d = layer.getMaxScale();
356: d = d != null ? d : new Double(largeNumber);
357:
358: map.put(SCALE_MAX, toRealWorldScale(scaleFactor, d
359: .doubleValue()));
360:
361: fw.write(transformContext(input, map));
362: fw.close();
363:
364: }
365:
366: public Icon getIcon() {
367: return new ImageIcon(LayerStyle2SLDPlugIn.class
368: .getResource("sldstyle.png"));
369: }
370:
371: public void run(TaskMonitor monitor, PlugInContext context)
372: throws Exception {
373: // will need this? extend threaded plug-in
374: }
375:
376: public static String transformContext(InputStream layerXML,
377: HashMap parMap) throws TransformerException,
378: UnsupportedEncodingException {
379:
380: StringWriter sw = new StringWriter();
381: StreamResult sr = new StreamResult(sw);
382:
383: InputStreamReader isr = new InputStreamReader(layerXML, UTF_8);
384: StreamSource streamSource = new StreamSource(isr);
385:
386: //if you don't clear the pars, xalan throws a nasty NPE
387: transformer.clearParameters();
388:
389: //TODO ths is getting too long -> iterate over pars and set them
390: transformer.setParameter("wmsLayerName", parMap
391: .get(WMS_LAYER_NAME));
392: transformer.setParameter("featureTypeStyle", parMap
393: .get(FEATURETYPE_STYLE));
394: transformer.setParameter("styleName", parMap.get(STYLE_NAME));
395: transformer.setParameter("styleTitle", parMap.get(STYLE_TITLE));
396: transformer.setParameter(GEOTYPE, parMap.get(GEOTYPE));
397: transformer.setParameter(GEOM_PROPERTY, parMap
398: .get(GEOM_PROPERTY));
399: transformer.setParameter(SCALE_MIN, parMap.get(SCALE_MIN));
400: transformer.setParameter(SCALE_MAX, parMap.get(SCALE_MAX));
401:
402: transformer.transform(streamSource, sr);
403:
404: try {
405: sw.close();
406: } catch (IOException e) {
407: e.printStackTrace();
408: }
409: //System.out.println( "sw.toString(): " + sw.toString() );
410:
411: return sw.toString();
412: }
413:
414: private static void initTransformer() {
415:
416: try {
417:
418: URL xslUrl = LayerStyle2SLDPlugIn.class
419: .getResource("layerstyle2sld.xsl");
420: TransformerFactory transformerFactory = TransformerFactory
421: .newInstance();
422:
423: InputStreamReader isr = new InputStreamReader(xslUrl
424: .openStream(), UTF_8);
425:
426: StreamSource streamSrc = new StreamSource(isr);
427:
428: transformer = transformerFactory.newTransformer(streamSrc);
429: }
430: //-- [sstein] evtl. comment out for test reasons, because it could be, that appears a problem
431: // in initializing the exceptions while starting up OJUMP on WinXP?
432: // (see email by Johannes Metzler, on Jump-User, 10.Aug.2006]
433: catch (TransformerConfigurationException e) {
434: e.printStackTrace();
435: } catch (TransformerFactoryConfigurationError e) {
436: e.printStackTrace();
437: } catch (IOException e) {
438: e.printStackTrace();
439: }
440: //-- used instead the simple form
441: }
442:
443: public EnableCheck createEnableCheck(
444: final WorkbenchContext workbenchContext) {
445: EnableCheckFactory ecf = new EnableCheckFactory(
446: workbenchContext);
447:
448: MultiEnableCheck mec = new MultiEnableCheck()
449: .add(
450: ecf
451: .createWindowWithLayerNamePanelMustBeActiveCheck())
452: .add(
453: ecf
454: .createExactlyNLayerablesMustBeSelectedCheck(
455: 1, Layer.class));
456:
457: return mec;
458:
459: }
460:
461: public static final Double toRealWorldScale(double scaleFactor,
462: double jumpScale) {
463:
464: return new Double(jumpScale / scaleFactor);
465: }
466:
467: private double calcScaleFactor(LayerViewPanel panel) {
468: double internalScale = 1d / panel.getViewport().getScale();
469: double realScale = ScreenScale.getHorizontalMapScale(panel
470: .getViewport());
471: return internalScale / realScale;
472: }
473:
474: public static void main(String[] args) {
475:
476: try {
477:
478: FileInputStream input = new FileInputStream(new File(
479: "f:/temp/input_layer_style2.xml"));
480:
481: FileWriter sw = new FileWriter("f:/temp/sldoutput.xml");
482:
483: HashMap map = new HashMap(4);
484: map.put(WMS_LAYER_NAME, "mrh:sehenswert");
485: map.put(FEATURETYPE_STYLE, "feature_test");
486: map.put(STYLE_NAME, "mrh:sehenswert2");
487: map.put(STYLE_TITLE, "mrh:sehenswert2");
488: map.put(GEOTYPE, "Point");
489:
490: // StringWriter sw = new StringWriter();
491: sw.write(transformContext(input, map));
492: sw.close();
493: } catch (Exception e) {
494: // TODO Auto-generated catch block
495: e.printStackTrace();
496: }
497: }
498:
499: }
|