tim@616: package de.intevation.gnv.state.layer;
tim@616: 
tim@799: import java.io.File;
tim@799: import java.io.IOException;
tim@799: import java.io.OutputStream;
tim@799: import java.util.Collection;
tim@799: import java.util.Iterator;
tim@799: 
tim@799: import org.apache.log4j.Logger;
tim@799: import org.w3c.dom.Document;
tim@799: import org.w3c.dom.Element;
tim@799: import org.w3c.dom.Node;
tim@799: 
sascha@779: import com.vividsolutions.jts.geom.Geometry;
tim@649: import com.vividsolutions.jts.io.ParseException;
tim@649: import com.vividsolutions.jts.io.WKTReader;
tim@649: 
tim@616: import de.intevation.artifactdatabase.Config;
tim@616: import de.intevation.artifactdatabase.XMLUtils;
tim@616: import de.intevation.artifacts.ArtifactNamespaceContext;
tim@616: import de.intevation.artifacts.CallContext;
tim@649: import de.intevation.gnv.artifacts.context.GNVArtifactContext;
tim@616: import de.intevation.gnv.geobackend.base.Result;
tim@649: import de.intevation.gnv.geobackend.base.query.QueryExecutor;
tim@649: import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory;
tim@649: import de.intevation.gnv.geobackend.base.query.exception.QueryException;
tim@616: import de.intevation.gnv.state.InputData;
tim@616: import de.intevation.gnv.state.OutputStateBase;
tim@616: import de.intevation.gnv.state.exception.StateException;
tim@723: import de.intevation.gnv.utils.ArtifactXMLUtilities;
tim@649: import de.intevation.gnv.utils.FileUtils;
tim@649: import de.intevation.gnv.utils.MapfileGenerator;
tim@655: import de.intevation.gnv.utils.MetaWriter;
tim@649: import de.intevation.gnv.utils.ShapeFileWriter;
tim@616: 
tim@616: /**
sascha@780:  * @author <a href="mailto:tim.englich@intevation.de">Tim Englich</a>
tim@616:  *
tim@616:  */
tim@616: public class LayerOutputState extends OutputStateBase {
tim@616: 
tim@616:     /**
tim@616:      * the logger, used to log exceptions and additonaly information
tim@616:      */
tim@616:     private static Logger log = Logger.getLogger(LayerOutputState.class);
sascha@778: 
tim@616:     /**
tim@616:      * The UID of this Class.
tim@616:      */
tim@616:     private static final long serialVersionUID = 9180957321704424049L;
sascha@778: 
tim@655:     // TODO: Replace
tim@655:     public static final String LAYER_MODEL    = "layer";
tim@616: 
tim@616:     /**
tim@616:      * The ID for the Query fetching the Layer from the DB
tim@616:      */
sascha@778:     private String dataQueryID = null;
sascha@778: 
tim@649:     /**
tim@649:      * The ID for the Query fetching the Geometry from the DB
tim@649:      * which should be used to Clip the Layerdata
tim@649:      */
tim@649:     private String geometryQueryID = null;
sascha@778: 
tim@728:     private String columnQueryID = null;
sascha@778: 
tim@799:     private String geometryTypeQueryID = null;
tim@799: 
tim@649:     /**
tim@649:      * The ID for the Value which will hold the Geometrie-Value
tim@649:      */
tim@649:     private String geometryID = null;
sascha@778: 
tim@649:     private Boolean shapeFileLock = new Boolean(true);
sascha@778: 
tim@649:     private String shapeFilePath;
sascha@778: 
tim@799:     private String templateID = null;
sascha@803: 
tim@655:     private String geometryType = null;
sascha@778: 
tim@649:     public static final String SHAPEFILE_NAME   = "data.shp";
sascha@778: 
tim@616:     /**
tim@616:      * Constructor
tim@616:      */
tim@616:     public LayerOutputState() {
tim@616:         super();
tim@616:     }
tim@616: 
ingo@813: 
tim@616:     public void out(Document format, Collection<InputData> inputData,
tim@616:                     OutputStream outputStream, String uuid,
tim@616:                     CallContext callContext) throws StateException {
sascha@778: 
tim@616:         log.debug("LayerOutputState.out");
tim@616:         String outputMode = XMLUtils.xpathString(
tim@616:                 format, XPATH_OUTPUT_MODE, ArtifactNamespaceContext.INSTANCE);
tim@616:         if (outputMode.equalsIgnoreCase("wms")) {
tim@616:             Collection<Result> data = this.fetchData();
tim@723:             if (data != null && !data.isEmpty()){
tim@799:                 XMLUtils.toStream(this.getWMS(uuid, callContext,
tim@799:                                               data, geometryType),
tim@723:                                   outputStream);
tim@723:             }else{
tim@723:                 this.writeExceptionReport2Stream(outputStream);
tim@723:             }
tim@616:         }else if (outputMode.equalsIgnoreCase("zip")){
tim@616:             Collection<Result> data = this.fetchData();
tim@723:             if (data != null && !data.isEmpty()){
tim@799:                 this.writeZip(uuid, callContext, outputStream,
tim@799:                               data,geometryType);
tim@723:             }else{
tim@723:                 this.writeExceptionReport2Stream(outputStream);
tim@723:             }
sascha@778: 
tim@616:         }
tim@616:     }
tim@723: 
tim@723:     /**
ingo@813:      * Writes an exception to an output stream.
ingo@813:      *
ingo@813:      * @param outputStream The output stream used to write the exception to.
tim@723:      */
ingo@813:     @SuppressWarnings("static-access")
tim@723:     private void writeExceptionReport2Stream(OutputStream outputStream) {
tim@723:         Document document = XMLUtils.newDocument();
ingo@813:         ArtifactXMLUtilities.
tim@723:         createExceptionReport("No Data to Export", document);
tim@723:         XMLUtils.toStream(document,outputStream);
tim@723:     }
sascha@778: 
sascha@778: 
tim@649:     /**
ingo@813:      * Fetches the Data from the Databasebackend.
ingo@813:      * 
ingo@813:      * @return the resulting data.
tim@649:      */
tim@616:     protected Collection<Result> fetchData(){
tim@616:         log.debug("LayerOutputState.fetchData");
tim@616:         // TODO PUT ALL in CACHE
tim@616:         Collection<Result> result = this.getData(this.queryID);
tim@616:         Collection<Result> data = null;
tim@649:         String geometryWKT = null;
tim@616:         if (result != null){
tim@649:             QueryExecutor queryExecutor = QueryExecutorFactory.getInstance()
tim@649:                                                               .getQueryExecutor();
tim@616:             Iterator<Result> it = result.iterator();
tim@649:             String[] queryValues = null;
tim@616:             if (it.hasNext()){
tim@616:                 Result resultValue = it.next();
tim@649:                 String table = resultValue.getString(0);
tim@799: 
tim@799:                 this.geometryType = this.getGeometryType(table, queryExecutor);
tim@799: 
tim@649:                 String where = resultValue.getString(1);
tim@728:                 String columns = this.fetchColumns(table);
sascha@778: 
tim@724:                 templateID = resultValue.getString(2);
tim@649:                 if (this.geometryID != null){
sascha@778:                     InputData geometryInputData =
tim@649:                          this.inputData.get(this.geometryID);
tim@649:                     if (geometryInputData != null){
sascha@778: 
tim@649:                         try {
tim@649:                             Collection<Result> geometryData = queryExecutor
tim@649:                                                       .executeQuery(this.geometryQueryID,
tim@649:                                                                     new String[]{geometryInputData.getValue()});
tim@649:                             Iterator<Result> git = geometryData.iterator();
tim@649:                             if (git.hasNext()){
tim@649:                                 Result geometryValue = git.next();
tim@649:                                 geometryWKT = geometryValue.getString(0);
tim@649:                             }
tim@649:                         } catch (QueryException e) {
tim@649:                             log.error(e,e);
tim@649:                             // TODO: what should happen??
tim@649:                         }
tim@728:                        queryValues = new String[]{columns,
tim@728:                                                   table,
tim@649:                                                   where,
tim@649:                                                   geometryWKT};
tim@649:                     }else{
tim@729:                         //Look into the presetting for an WKT
sascha@778:                         InputData geometryWKTData = this.preSettings != null ?
tim@742:                                                     this.preSettings.get("geometry") :
tim@742:                                                     null ;
tim@729:                         if (geometryWKTData != null){
tim@729:                             queryValues = new String[]{columns,
tim@729:                                                        table,
tim@729:                                                        where,
tim@729:                                                        geometryWKTData.getValue()};
tim@729:                         }else{
tim@729:                             queryValues = new String[]{columns,table,where};
tim@729:                         }
tim@729:                     }
tim@729:                 }else{
tim@729:                     //Look into the presetting for an WKT
sascha@778:                     InputData geometryWKTData = this.preSettings != null ?
tim@742:                                                 this.preSettings.get("geometry") :
tim@742:                                                 null ;
tim@729:                     if (geometryWKTData != null){
tim@729:                         queryValues = new String[]{columns,
tim@729:                                                    table,
tim@729:                                                    where,
tim@729:                                                    geometryWKTData.getValue()};
tim@729:                     }else{
tim@728:                         queryValues = new String[]{columns,table,where};
tim@649:                     }
tim@649:                 }
tim@616:             }
sascha@778: 
tim@649:             try {
tim@649:                 data  = queryExecutor.executeQuery(dataQueryID,
tim@649:                                                    queryValues);
tim@649:                 if (data != null && geometryWKT != null){
tim@649:                     WKTReader wktReader = new WKTReader();
tim@649:                     Geometry border = wktReader.read(geometryWKT);
sascha@778: 
tim@649:                     Iterator<Result> dataIt = data.iterator();
tim@649:                     while (dataIt.hasNext()){
tim@649:                         // Trim the Geometries using the
tim@649:                         // Geometry if on is available.
tim@649:                         Result current = dataIt.next();
tim@649:                         String currentWKT = current.getString(0);
tim@649:                         Geometry currentGeometry = null;
tim@649:                         try {
tim@649:                             currentGeometry = wktReader.read(currentWKT);
tim@649:                         } catch (Exception e) {
tim@649:                             log.error("Error parsing Geometry "+ currentWKT);
tim@649:                             log.error(e,e);
tim@649:                         }
sascha@778: 
tim@649:                         if (currentGeometry != null){
tim@649:                             Geometry newGeometry = currentGeometry.intersection(border);
tim@649:                             current.addColumnValue(0, newGeometry.toText());
tim@649:                         }
tim@649:                     }
tim@649:                 }
tim@649:             } catch (QueryException e) {
tim@649:                 log.error(e,e);
tim@649:             } catch (ParseException e){
tim@649:                 log.error(e,e);
tim@649:             }
tim@616:         }
tim@616:         return data;
tim@616:     }
tim@616: 
ingo@813: 
ingo@813:     /**
ingo@813:      * This method determines the geometry type on basis of a table name.
ingo@813:      *
ingo@813:      * @param tableName Name of the table in the database.
ingo@813:      * @param queryExecutor The QueryExecutor.
ingo@813:      * @return the geometry type as string (e.g. MultiPolygon, Polygon, etc).
ingo@813:      */
tim@799:     private String getGeometryType(String tableName,
tim@799:                                    QueryExecutor queryExecutor){
tim@799:         String returnValue = null;
tim@799:         String[] tables = tableName.toUpperCase().split(",");
tim@799:         String[] filter = tables[0].split("\\.");
sascha@803: 
tim@799:         try {
sascha@803:             Collection<Result> result =
tim@799:                 queryExecutor.executeQuery(this.geometryTypeQueryID, filter);
tim@799:             if (result != null && !result.isEmpty())
tim@799:             {
tim@799:                 int geometryCode = result.iterator().next().getInteger(0);
sascha@803:                 if (geometryCode == 11 ||
tim@799:                     geometryCode == 10){
tim@799:                     returnValue = "MultiPolygon";
sascha@803:                 }else if (geometryCode == 9 ||
tim@799:                           geometryCode == 8){
tim@799:                     returnValue = "MultiLineString";
tim@799:                 }else if (geometryCode == 7){
tim@799:                     returnValue = "MultiPoint";
tim@799:                 }else if (geometryCode == 6){
tim@799:                     returnValue = "GeometryCollection";
sascha@803:                 }else if (geometryCode == 5 ||
tim@799:                           geometryCode == 4){
tim@799:                     returnValue = "Polygon";
sascha@803:                 }else if (geometryCode == 3 ||
tim@799:                           geometryCode == 2){
tim@799:                     returnValue = "LineString";
tim@799:                 }else if (geometryCode == 1){
tim@799:                     returnValue = "Point";
tim@799:                 }else if (geometryCode == 0){
tim@799:                     returnValue = "Geometry";
tim@799:                 }
tim@799:             }
tim@799:         } catch (QueryException e) {
tim@799:             log.error(e,e);
tim@799:         }
sascha@803: 
tim@799:         return returnValue;
tim@799:     }
ingo@813: 
ingo@813: 
ingo@813:     /**
ingo@813:      * Fetch the columns of a specific table.
ingo@813:      *
ingo@813:      * @param tableName The name of the table.
ingo@813:      * @return the columns as string.
ingo@813:      */
tim@728:     private String fetchColumns(String tableName){
tim@728:         String returnValue = null;
tim@728:         try {
tim@756:             String[] tables = tableName.toUpperCase().split(",");
tim@756:             String[] filter = tables[0].split("\\.");
tim@756:             // Only use the first Table the second one will be ignored.
tim@728:             QueryExecutor queryExecutor = QueryExecutorFactory.getInstance()
tim@728:             .getQueryExecutor();
sascha@778: 
tim@728:             Collection<Result> columnData = queryExecutor.
sascha@778:                                                 executeQuery(this.columnQueryID,
tim@728:                                                              filter);
tim@728:             if (columnData != null && !columnData.isEmpty()){
tim@728:                 StringBuffer sb = new StringBuffer();
tim@728:                 synchronized (sb) {
tim@728:                     Iterator<Result> it = columnData.iterator();
tim@728:                     while(it.hasNext()){
tim@728:                         Result current = it.next();
tim@728:                         sb.append(current.getString(0));
tim@728:                         if (it.hasNext()){
tim@728:                             sb.append(" , ");
tim@728:                         }
tim@728:                     }
tim@728:                 }
tim@728:                 returnValue = sb.toString();
tim@728:             }
sascha@778: 
tim@728:         } catch (QueryException e) {
tim@728:             log.error(e,e);
tim@728:         }
tim@728:         return returnValue;
tim@728:     }
ingo@813: 
ingo@813: 
tim@616:     @Override
tim@616:     public void setup(Node configuration) {
tim@616:         log.debug("LayerOutputState.setup");
tim@616:         super.setup(configuration);
tim@649:         this.dataQueryID = Config.getStringXPath(configuration,
tim@649:                                                  "queryID-layerdata");
tim@649:         this.geometryID = Config.getStringXPath(configuration,
tim@649:                                                 "inputvalue-geometry");
tim@649:         this.geometryQueryID =  Config.getStringXPath(configuration,
tim@649:                                                 "queryID-geometry");
sascha@778: 
tim@728:         this.columnQueryID =   "layer_colums"; //Config.getStringXPath(configuration,
tim@728:                                                // "queryID-columns");
tim@799:         this.geometryTypeQueryID = "geometry_type";
tim@616:     }
sascha@778: 
ingo@813: 
ingo@813:     /**
ingo@813:      * Write the resulting data to shapefiles.
ingo@813:      *
ingo@813:      * @param uuid The UUID of the current artifact.
ingo@813:      * @param data The finalized data used for shapefile creation.
ingo@813:      * @param callContext The CallContext object.
ingo@813:      * @param geometryType The geometry type.
ingo@813:      * @return the shapefile path.
ingo@813:      */
tim@649:     protected String writeToShapeFile(
tim@649:                                       String             uuid,
tim@649:                                       Collection<Result> data,
tim@799:                                       CallContext        callContext,
tim@799:                                       String geometryType
tim@649:                                   ) {
tim@649:         File baseDir = shapefileDirectory(callContext);
sascha@778: 
tim@649:         File shapeDir = new File(baseDir, uuid);
tim@649:         boolean success    = false;
tim@649:         boolean createdDir = false;
tim@649: 
tim@649:         try {
tim@649:             synchronized (shapeFileLock) {
tim@649:                 int count = 0;
tim@649:                 while (shapeDir.exists()) {
tim@649:                     shapeDir = new File(baseDir, uuid + "-" + count);
tim@649:                     ++count;
tim@649:                 }
tim@649: 
tim@649:                 if (!shapeDir.mkdirs()) {
sascha@778:                     log.error("cannot create directory '"
tim@649:                         + shapeDir.getAbsolutePath() + "'");
tim@649:                     return null;
tim@649:                 }
tim@649:                 createdDir = true;
tim@649:             }
tim@649: 
tim@649:             File shapeFile = new File(shapeDir, SHAPEFILE_NAME);
tim@799:             if (!ShapeFileWriter.writeDataToFile(shapeFile, "data", data,geometryType)){
tim@649:                 log.error("writing data into shapefile failed");
tim@649:                 return null;
tim@649:             }
sascha@778: 
tim@649:             shapeFilePath = shapeDir.getAbsolutePath();
tim@649:             success = true;
tim@649: 
tim@649:             callContext.afterCall(CallContext.STORE);
tim@649: 
tim@649:             return shapeFilePath;
tim@649:         }
tim@649:         finally {
tim@649:             if (!success && createdDir) {
tim@649:                 FileUtils.deleteRecursive(shapeDir);
tim@649:             }
tim@649:         }
tim@649:     }
sascha@778: 
ingo@813: 
ingo@813:     /**
ingo@813:      * Create a zip archive with the shapefiles of the given shapefiles path and
ingo@813:      * write it to <code>output</code>.
ingo@813:      *
ingo@813:      * @param uuid The UUID of the current artifact.
ingo@813:      * @param callContext The CallContext object.
ingo@813:      * @param output The output stream.
ingo@813:      * @param data The data to be written to shapefile.
ingo@813:      * @param geometryType The geometry type.
ingo@813:      * @throws StateException if an error occured while zipfile creation.
ingo@813:      */
tim@649:     protected void writeZip(
tim@649:             String       uuid,
tim@649:             CallContext  callContext,
tim@649:             OutputStream output,
tim@799:             Collection<Result> data,
tim@799:             String geometryType
sascha@778:         )
tim@649:         throws StateException
tim@649:         {
tim@649:             try {
tim@649:                 String p = getShapeFilePath();
tim@649:                 if (p != null) {
tim@649:                     File dir = new File(p);
tim@649:                     if (dir.isDirectory()) {
tim@649:                         FileUtils.createZipArchive(dir, output);
tim@649:                     }
tim@649:                 }
tim@649:                 else {
sascha@778: 
tim@799:                     if ((p = writeToShapeFile(uuid, data, callContext,geometryType)) != null) {
tim@649:                         FileUtils.createZipArchive(new File(p), output);
tim@649:                     }
tim@649:                 }
tim@649:             }
tim@649:             catch (IOException ioe) {
tim@649:                 log.error(ioe.getLocalizedMessage(), ioe);
tim@649:             }
tim@649:         }
sascha@778: 
ingo@813:     /**
ingo@813:      * Returns the shapefile path.
ingo@813:      *
ingo@813:      * @return the shapefile path.
ingo@813:      */
tim@649:     public String getShapeFilePath() {
tim@649:         synchronized (shapeFileLock) {
tim@649:             return shapeFilePath;
tim@649:         }
tim@649:     }
sascha@778: 
ingo@813:     
tim@649:     private static File shapefileDirectory(CallContext callContext) {
tim@649:         // TODO: Refactoring nessessary it should be used only one Shapefilepath
tim@649:         //       for alle Modes. Code was taken from HorizontalCrossSectionMeshOutputState
tim@649:         GNVArtifactContext context =
tim@649:             (GNVArtifactContext)callContext.globalContext();
tim@649:         File dir = (File)context.get(
tim@649:             GNVArtifactContext.HORIZONTAL_CROSS_SECTION_RESULT_SHAPEFILE_PATH_KEY);
tim@649:         return dir != null
tim@649:             ? dir
tim@649:             : GNVArtifactContext.DEFAULT_HORIZONTAL_CROSS_SECTION_PROFILE_SHAPEFILE_PATH;
tim@649:     }
sascha@778: 
ingo@813: 
tim@649:     @Override
tim@649:     public void endOfLife(Object globalContext) {
tim@649:         super.endOfLife(globalContext);
tim@649: 
tim@649:         // do it in background
tim@649:         new Thread() {
ingo@813:             @Override
tim@649:             public void run() {
tim@649:                 // TODO: Do the un-publishing WMS stuff.
tim@649:                 String path = resetShapeFilePath();
tim@649: 
tim@649:                 if (path == null) {
tim@649:                     return;
tim@649:                 }
tim@649: 
tim@649:                 File dir = new File(path);
tim@649: 
tim@649:                 for (int i = 0; i < 10; ++i) {
tim@649:                     if (!dir.exists() || FileUtils.deleteRecursive(dir)) {
tim@649:                         MapfileGenerator.getInstance().update();
tim@649:                         return;
tim@649:                     }
tim@649: 
tim@649:                     try {
tim@649:                         Thread.sleep(10000L);
tim@649:                     }
tim@649:                     catch (InterruptedException ie) {
tim@649:                     }
tim@649:                 }
tim@649: 
tim@649:                 log.error("failed to remove directory '" + path + "'");
tim@649:             } // run
tim@649:         }.start();
tim@649:     }
sascha@778: 
ingo@813:     
tim@649:     public String resetShapeFilePath() {
tim@649:         synchronized (shapeFileLock) {
tim@649:             String path = shapeFilePath;
tim@649:             shapeFilePath = null;
tim@724:             templateID = null;
tim@649:             return path;
tim@649:         }
tim@649:     }
ingo@813: 
ingo@813: 
ingo@813:     /**
ingo@813:      * Write data to shapefiles and feed a map service with information about
ingo@813:      * these shapefiles. The map service can be queried for displaying
ingo@813:      * corresponding layers as WMS.
ingo@813:      *
ingo@813:      * @param uuid The UUID of the current artifact.
ingo@813:      * @param callContext The CallContext object.
ingo@813:      * @param data A collection with some input data.
ingo@813:      * @param geometryType The geometry type.
ingo@813:      * @return a document with some meta information (shapefile path, geometry
ingo@813:      * type, time to live of the current artifact, etc).
ingo@813:      * @throws StateException if an error occured while shapefile writing.
ingo@813:      */
sascha@778:     protected Document getWMS(String uuid,
sascha@778:                               CallContext callContext,
tim@799:                               Collection<Result> data,
tim@799:                               String geometryType)
tim@655:     throws StateException
tim@655:     {
tim@655:         // TODO: Do the real WMS publishing here!
tim@655:         Document document = XMLUtils.newDocument();
tim@655: 
tim@655:         Element pathElement = document.createElement("path");
tim@655:         document.appendChild(pathElement);
tim@655: 
tim@655:         String path = getShapeFilePath();
tim@655: 
tim@655:         if (path != null && new File(path).isDirectory()) {
tim@655:             pathElement.setTextContent(path);
tim@655:         }
tim@655:         else {
sascha@778: 
tim@655:             if (data != null &&
tim@799:                 (path = writeToShapeFile(uuid, data, callContext,geometryType)) != null) {
tim@655: 
tim@724:                 String paramType = LAYER_MODEL+"_"+templateID;
sascha@778: 
tim@724:                 if (!MapfileGenerator.getInstance().templateExists(paramType)){
tim@724:                     // If the template doesn't exist the Defaulttemplates will be used.
sascha@803:                     paramType = LAYER_MODEL+"_"+
tim@799:                                 this.determineDefaultTemplateName(geometryType);
tim@724:                 }
sascha@778:                 Document meta = MetaWriter.writeLayerMeta(callContext, uuid,
sascha@778:                                                           path, paramType,
tim@799:                                                           this.determineGeometryType(geometryType));
tim@655:                 if (meta != null) {
tim@655:                     MapfileGenerator.getInstance().update();
tim@655:                     return meta;
tim@655:                 }
tim@655: 
tim@655:                 pathElement.setTextContent(path);
tim@655:             }
tim@655:         }
tim@655: 
tim@655:         return document;
tim@655:     }
sascha@778: 
ingo@813: 
ingo@813:     /**
ingo@813:      * Turns the geometry type into a form used for the templating mechanism
ingo@813:      * while mapfile generation.
ingo@813:      * 
ingo@813:      * @param geometryType The original geometry type.
ingo@813:      * @return a valid geometry type fpr the template mechanism.
ingo@813:      */
tim@799:     private String determineGeometryType(String geometryType){
sascha@778: 
tim@799:         String returnValue = geometryType.toLowerCase();
sascha@778: 
tim@655:         if (returnValue.equalsIgnoreCase("linestring")){
tim@655:             returnValue = "Line";
tim@799:         }else if (returnValue.equalsIgnoreCase("multilinestring")){
tim@799:             returnValue ="Line";
tim@799:         }else if (returnValue.equalsIgnoreCase("multipolygon")){
tim@799:             returnValue = "Polygon";
tim@799:         }
tim@799:         return returnValue;
tim@799:     }
sascha@803: 
ingo@813: 
ingo@813:     /**
ingo@813:      * Determine the default template name if no special template is existing
ingo@813:      * for this layer.
ingo@813:      *
ingo@813:      * @param geometryType The geometry type.
ingo@813:      * @return a default geometry fitting to the original geometry type.
ingo@813:      */
tim@799:     private String determineDefaultTemplateName(String geometryType){
tim@799: 
tim@799:         String returnValue = geometryType.toLowerCase();
tim@799: 
tim@799:         if (returnValue.equalsIgnoreCase("multilinestring")){
tim@799:             returnValue ="linestring";
tim@799:         }else if (returnValue.equalsIgnoreCase("multipolygon")){
tim@799:             returnValue = "polygon";
tim@799:         }else if (returnValue.equalsIgnoreCase("multipoint")){
tim@799:             returnValue = "point";
tim@655:         }
tim@655:         return returnValue;
tim@655:     }
tim@616: }
ingo@813: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :