/** * OrbisGIS is a java GIS application dedicated to research in GIScience. * OrbisGIS is developed by the GIS group of the DECIDE team of the * Lab-STICC CNRS laboratory, see <http://www.lab-sticc.fr/>. * * The GIS group of the DECIDE team is located at : * * Laboratoire Lab-STICC – CNRS UMR 6285 * Equipe DECIDE * UNIVERSITÉ DE BRETAGNE-SUD * Institut Universitaire de Technologie de Vannes * 8, Rue Montaigne - BP 561 56017 Vannes Cedex * * OrbisGIS is distributed under GPL 3 license. * * Copyright (C) 2007-2014 CNRS (IRSTV FR CNRS 2488) * Copyright (C) 2015-2017 CNRS (Lab-STICC UMR CNRS 6285) * * This file is part of OrbisGIS. * * OrbisGIS 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. * * OrbisGIS 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 * OrbisGIS. If not, see <http://www.gnu.org/licenses/>. * * For more information, please consult: <http://www.orbisgis.org/> * or contact directly: * info_at_ orbisgis.org */ package org.orbisgis.coremap.renderer.se; import com.vividsolutions.jts.geom.Geometry; import java.awt.Graphics2D; import java.io.IOException; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.xml.bind.JAXBElement; import net.opengis.se._2_0.core.*; import net.opengis.se._2_0.raster.RasterSymbolizerType; import org.orbisgis.coremap.map.MapTransform; import org.orbisgis.coremap.renderer.se.SeExceptions.InvalidStyle; import org.orbisgis.coremap.renderer.se.parameter.ParameterException; import org.orbisgis.coremap.renderer.se.visitors.FeaturesVisitor; /** * Entry point for all kind of symbolizer * This abstract class contains only the name, the way to retrieve the geometry * and a description of the symbolizer. * @todo Add a general draw method that fit well for vectors and raster; implement fetch default geometry * @author Maxence Laurent, Alexis Guéganno */ public abstract class Symbolizer extends AbstractSymbolizerNode implements SymbolizerNode, Comparable { /** * The default name affected to a new Symbolizer instance. */ public static final String DEFAULT_NAME = "Default Symbolizer"; /** * The current version of the Symbolizer */ public static final String VERSION = "2.0.0"; protected String name; protected String desc; //protected GeometryAttribute the_geom; protected int level; private Set<String> features; private Map<String,Object> featuresMap; private FeaturesVisitor featuresVisitor = new FeaturesVisitor(); /** * Build an empty Symbolizer, with the default name and no description. */ public Symbolizer() { name = Symbolizer.DEFAULT_NAME; desc = ""; level = -1; } /** * Build a Symbolizer from a JAXB element. This constructor will only retrieve * the name and description - it's up to the inheriting classes to retrieve the other * needed informations. * @param st * @throws org.orbisgis.coremap.renderer.se.SeExceptions.InvalidStyle */ public Symbolizer(JAXBElement<? extends SymbolizerType> st) throws InvalidStyle { SymbolizerType t = st.getValue(); if (t.getName() != null) { this.name = t.getName(); } else { this.name = Symbolizer.DEFAULT_NAME; } if (t.getVersion() != null && !t.getVersion().value().equals(Symbolizer.VERSION)) { throw new InvalidStyle("Unsupported version !"); } if (t.getDescription() != null) { // TODO implement ows:Description } if (t.getExtension() != null) { for (ExtensionParameterType param : t.getExtension().getExtensionParameter()) { if (param.getName().equalsIgnoreCase("level")) { level = Integer.parseInt(param.getContent()); break; } } } } /** * Gets the name of this Symbolizer. * @return * the name of the Symbolizer. */ @Override public String toString() { return name; } /** * Gets the name of this <code>Symbolizer</code>. * @return * the name of the <code>Symbolizer</code>. */ public String getName() { return name; } /** * Set <code>name</code> as the name of this <code>Symbolizer</code> * @param name */ public void setName(String name) { if (name == null || name.equalsIgnoreCase("")) { this.name = Symbolizer.DEFAULT_NAME; } else { this.name = name; } } /** * Get the description associated to this <code>Symbolizer</code>. * @return */ public String getDescription() { return desc; } /** * Set the description associated to this <code>Symbolizer</code>. * @param description */ public void setDescription(String description) { desc = description; } /** * Get the display level of this <code>Symbolizer</code> * @return */ public int getLevel() { return level; } /** * Set the display level of this <code>Symbolizer</code> * @param level */ public void setLevel(int level) { this.level = level; } /** * Fill the {@code SymbolizerType s} with the properties contained in this * {@code Symbolizer}. * @param s */ public void setJAXBProperty(SymbolizerType s) { // TODO Load description from XML s.setDescription(null); s.setName(name); s.setVersion(VersionType.VALUE_1); } /** * Using the given JAXBElement, this method tries to build the correct * spacialization of {@code Symbolizer}. * @param st * @return * @throws org.orbisgis.coremap.renderer.se.SeExceptions.InvalidStyle */ public static Symbolizer createSymbolizerFromJAXBElement(JAXBElement<? extends SymbolizerType> st) throws InvalidStyle { if (st.getDeclaredType() == AreaSymbolizerType.class) { return new AreaSymbolizer((JAXBElement<AreaSymbolizerType>) st); } else if (st.getDeclaredType() == LineSymbolizerType.class) { return new LineSymbolizer((JAXBElement<LineSymbolizerType>) st); } else if (st.getDeclaredType() == PointSymbolizerType.class) { return new PointSymbolizer((JAXBElement<PointSymbolizerType>) st); } else if (st.getDeclaredType() == TextSymbolizerType.class) { return new TextSymbolizer((JAXBElement<TextSymbolizerType>) st); } else if (st.getDeclaredType() == RasterSymbolizerType.class) { return new RasterSymbolizer((JAXBElement<RasterSymbolizerType>) st); } else { return null; } } /** * Makes a comparison between this and o. Be aware that <b>this operation is absolutely * not concistent with <code>equals(Object o)</code> !!!</b> * @param o * @return * <ul><li>-1 if <code>(!o instanceof Symbolizer) || o.level < this.level </code></li> * <li>0 if <code>(o instanceof Symbolizer) && s.level == this.level</code></li> * <li>1 otherwise</li> * </ul> */ @Override public int compareTo(Object o) { if (o instanceof Symbolizer) { Symbolizer s = (Symbolizer) o; if (s.level < this.level) { return 1; } else if (s.level == this.level) { return 0; } else { return -1; } } return -1; } /** * Go through parents and return the rule */ public Rule getRule() { SymbolizerNode pIt = getParent(); while (pIt != null && !(pIt instanceof Rule)) { pIt = pIt.getParent(); } return (Rule) pIt; } /** * Gets the features that are needed to build this Symbolizer in a {@code * Map<String,Object>}. This method is based on {@see * SymbolizerNode#dependsOnFeature()}. Using the field names retrieved with * this method, we search for {@code Values} at index {@code fid} in {@code * sds}. * @param sds * @param fid * @return * @throws SQLException */ public Map<String,Object> getFeaturesMap(ResultSet sds, long fid) throws SQLException{ if(features==null){ acceptVisitor(featuresVisitor); features = featuresVisitor.getResult(); } if(featuresMap == null){ featuresMap = new HashMap<String,Object>(); } if(sds != null) { for(String s : features){ featuresMap.put(s, sds.getObject(s)); } } return featuresMap; } public void refreshFeatures(){ features = null; } @Override public void update(){ refreshFeatures(); if(getParent() != null){ getParent().update(); } } /** * Draw the symbols in g2, using infos that are found in sds at index fid. * @param g2 * @param rs * @param fid * @param selected * @param mt * @param theGeom * @param perm * @throws ParameterException * @throws IOException * @throws SQLException */ public abstract void draw(Graphics2D g2, ResultSet rs, long fid, boolean selected, MapTransform mt, Geometry theGeom) throws ParameterException, IOException, SQLException; /** * Get a JAXB representation of this Symbolizer. * @return */ public abstract JAXBElement<? extends SymbolizerType> getJAXBElement(); }