Package org.geoserver.wfs.response

Source Code of org.geoserver.wfs.response.DXFOutputFormat

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wfs.response;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.xml.namespace.QName;

import org.apache.commons.lang.StringUtils;
import org.geoserver.config.GeoServer;
import org.geoserver.platform.Operation;
import org.geoserver.platform.ServiceException;
import org.geoserver.wfs.WFSGetFeatureOutputFormat;
import org.geoserver.wfs.request.FeatureCollectionResponse;
import org.geoserver.wfs.request.GetFeatureRequest;
import org.geoserver.wfs.request.Query;
import org.geoserver.wfs.response.dxf.DXFWriter;
import org.geoserver.wfs.response.dxf.DXFWriterFinder;
import org.geoserver.wfs.response.dxf.LineType;
import org.geotools.util.logging.Logging;


/**
* This class returns a dxf  encoded results of the users's query
* (optionally zipped).
* Several format options are available to control output generation.
*  - version: (number) creates a DXF in the specified version format (a DXFWriter
*    implementation supporting the requested version needs to be available
*    or an exception will be thrown); the default implementation creates
*    a version 14 DXF.
*  - asblock: (true/false) if true, all geometries are written
*    as blocks and then inserted as entities. If false, simple geometries
*    are directly written as entities.
*  - colors: (comma delimited list of numbers): colors to be used for
*    the DXF layers, in sequence. If layers are more than the specified
*    colors, they will be reused many times. A set of default colors is
*    used if the option is not used. Colors are AutoCad color numbers
*    (7=white, etc.).
*  - ltypes: (comma delimited list of line type descriptors): line types
*    to be used for the DXF layers, in sequence. If layers are more than
*    the specified line types, they will be reused many times. If not specified,
*    all layers will be given a solid, continuous line type. A descriptor
*    has the following format: <name>!<repeatable pattern>[!<base length>], where
*    <name> is the name assigned to the line type, <base length> (optional)
*    is a real number that tells how long is each part of the line pattern
*    (defaults to 0.125), and <repeatable pattern> is a visual description
*    of the repeatable part of the line pattern, as a sequence of - (solid line),
*    * (dot) and _ (empty space).
*  - layers: (comma delimited list of strings) names to be assigned to
*    the DXF layers. If specified, must contain a name for each requested
*    query. By default a standard name will be assigned to layers.
*   
*  A different layer will be generated for each requested query.
*  Layer names can be chosen using the layers format option, or
*  in POST mode, using the handle attribute of the Query tag.
*  The name of the resulting file can be chosen using the handle
*  attribute of the GetFeature tag. By default, the names of layers
*  concatenated with _ will be used. 
*
* @author Mauro Bartolomeoli, mbarto@infosia.it
*
*/
public class DXFOutputFormat extends WFSGetFeatureOutputFormat {

    private static final Logger LOGGER = Logging.getLogger(DXFOutputFormat.class);
   
    public static final Set<String> formats = new HashSet<String>();

    static {
        // list of supported output formats
        formats.add("DXF");
        formats.add("DXF-ZIP");
    }

    public DXFOutputFormat(GeoServer gs) {
        super(gs,formats);       
    }

    /**
     * Gets current request extension (dxf or zip).
     *
     * @param operation
     * @return
     */
    public String getDxfExtension(Operation operation) {
        GetFeatureRequest request = GetFeatureRequest.adapt(operation
                .getParameters()[0]);

        String outputFormat = request.getOutputFormat().toUpperCase();
        // DXF
        if (outputFormat.equals("DXF"))
            return "dxf";
        // DXF-ZIP
        return "zip";
    }

    /**
     * Mime type: application/dxf or application/zip
     */
    @Override
    public String getMimeType(Object value, Operation operation) throws ServiceException {
        return "application/" + getDxfExtension(operation);
    }

    @Override
    public String getPreferredDisposition(Object value, Operation operation) {
        return DISPOSITION_ATTACH;
    }
   
    /**
     * Gets output filename.
     * If the handle attribute is defined on the GetFeature tag it
     * will be used, else the name is obtained concatenating layer names
     * with underscore as a separator (up to a maximum name length).
     */
    private String getFileName(Operation operation) {
        GetFeatureRequest request = GetFeatureRequest.adapt(operation
                .getParameters()[0]);
   
        if (request.getHandle() != null) {
            LOGGER.log(Level.FINE,
                    "Using handle for file name: " + request.getHandle());
            return request.getHandle();
        }
   
        List<String> names = new ArrayList<String>();
        for (Query query : request.getQueries()) {
            addLayerNames(names, query, false);
        }
        String layerNames = StringUtils.join(names.toArray(), '_');
        LOGGER.log(Level.FINE, "Using layer names for file name: " + layerNames);
        if (layerNames.length() > 20) {
            LOGGER.log(Level.WARNING,
                    "Calculated filename too long. Returing a shorter one: "
                            + layerNames.substring(0, 20));
            return layerNames.substring(0, 20);
        }
        return layerNames;
    }
   
    private void addLayerNames(List<String> names, Query query, boolean toUpper) {
        for (QName name : query.getTypeNames()) {
            String localName = name.getLocalPart();
            if (toUpper) {
                localName = localName.toUpperCase();
            }
            names.add(localName);
        }
   
    }

    @Override
    public String getAttachmentFileName(Object value, Operation operation) {
        return getFileName(operation) + '.' + getDxfExtension(operation);
    }

   
    /**
     * Actually write the given featurecollection as a dxf file to
     * the output stream.
     *
     * @see org.geoserver.wfs.WFSGetFeatureOutputFormat#write(net.opengis.wfs.FeatureCollectionType,
     *      java.io.OutputStream, org.geoserver.platform.Operation)
     */
    @Override
    protected void write(FeatureCollectionResponse featureCollection, OutputStream output,
            Operation operation) throws IOException, ServiceException {
        // output format (zipped or not)
        String format = getDxfExtension(operation);
        BufferedWriter w = null;
        ZipOutputStream zipStream = null;
        // DXF: use a simple buffered writer
        if (format.equals("dxf")) {
            LOGGER.log(Level.FINE,"Plain DXF output");
            w = new BufferedWriter(new OutputStreamWriter(output));
        } else {
            LOGGER.log(Level.FINE,"Zipped DXF output");
            // DXF-ZIP: use a zip stream wrapped with the buffered writer
            zipStream = new ZipOutputStream(output);
            ZipEntry entry = new ZipEntry(getFileName(operation) + ".dxf");
            zipStream.putNextEntry(entry);
            w = new BufferedWriter(new OutputStreamWriter(zipStream));
        }
        // extract format_options (GET mode)
        GetFeatureRequest gft = GetFeatureRequest.adapt(operation.getParameters()[0]);
        String version = (String) gft.getFormatOptions().get("VERSION");
        String blocks = (String) gft.getFormatOptions().get("ASBLOCKS");
        String colors = (String) gft.getFormatOptions().get("COLORS");
        String ltypes = (String) gft.getFormatOptions().get("LTYPES");
        String[] layers = null;
        if(gft.getFormatOptions().get("LAYERS") instanceof String) {
            layers = ((String) gft.getFormatOptions().get("LAYERS")).split(",");
        } else if(gft.getFormatOptions().get("LAYERS") instanceof List) {
            layers = (String[]) ((List) gft.getFormatOptions().get("LAYERS")).toArray(new String[0]);
        }
        if(layers != null) {
            for(int count = 0; count < layers.length; count++) {
                layers[count] = layers[count].toUpperCase();
            }
        }
        String writeAttributes = (String) gft.getFormatOptions().get("WITHATTRIBUTES");
        LOGGER.log(Level.FINE,"Format options: "+version+"; "+blocks+"; "+colors+"; "+ltypes+"; "+StringUtils.join(layers, ",")+"; "+writeAttributes);
        // get a suitable DXFWriter, for the requested version (null -> get any writer)
        DXFWriter dxfWriter = DXFWriterFinder.getWriter(version, w);
       
        if (dxfWriter != null) {
            LOGGER.log(Level.INFO,"DXFWriter: "+dxfWriter.getDescription());

            if(layers == null) {
                layers=getLayerNames(gft.getQueries());
            }
            LOGGER.log(Level.FINE,"Layers names: "+StringUtils.join(layers,","));
            dxfWriter.setOption("layers", layers);
            if(writeAttributes != null) {
                dxfWriter.setOption("writeattributes", writeAttributes.toLowerCase().equals("true"));
            }
            if (blocks != null && blocks.toLowerCase().equals("true"))
                dxfWriter.setOption("geometryasblock", true);
            // set optional colors
            if (colors != null) {
                try {
                    String[] sColors = colors.split(",");
                    int[] icolors = new int[sColors.length];
                    for (int count = 0; count < sColors.length; count++)
                        icolors[count] = Integer.parseInt(sColors[count]);
                    dxfWriter.setOption("colors", icolors);
                } catch (Throwable t) {
                    LOGGER.log(Level.WARNING,"format option colors ignored by DXFOutputFormat due to a wrong format: "+t.getMessage());
                }
            }
            // set optional line types
            if (ltypes != null) {
                try {
                    String[] sLTypes = ltypes.split(",");
                    LineType[] ltypesArr = new LineType[sLTypes.length];
                    for (int count = 0; count < sLTypes.length; count++)
                        ltypesArr[count] = LineType.parse(sLTypes[count]);
                    dxfWriter.setOption("linetypes", ltypesArr);

                } catch (Throwable t) {
                    LOGGER
                            .warning("format option ltypes ignored by DXFOutputFormat due to a wrong format: "+t.getMessage());
                }
            }

            // do the real job, please
            dxfWriter.write(featureCollection.getFeature(),version);

            w.flush();           
            if (zipStream != null) {
                zipStream.closeEntry();
                zipStream.close();
            }
            dxfWriter = null;
            zipStream = null;
            w = null;

        } else
            throw new UnsupportedOperationException("Version " + version
                    + " not supported by dxf output format");

    }

    /**
     * Gets a list of names for layers, one
     * for each query.
     * @param it
     * @return
     */
    private String[] getLayerNames(List<Query> queries) {
        List<String> names = new ArrayList<String>();
        for (Query query : queries) {
            addLayerNames(names, query, true);
        }

        return names.toArray(new String[] {});
    }

}
TOP

Related Classes of org.geoserver.wfs.response.DXFOutputFormat

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.