/* (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.geopkg; import static org.geoserver.geopkg.GeoPkg.*; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import org.apache.commons.io.IOUtils; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.FeatureTypeInfo; 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.geotools.data.simple.SimpleFeatureCollection; import org.geotools.feature.FeatureCollection; import org.geotools.feature.NameImpl; import org.geotools.geopkg.FeatureEntry; import org.geotools.geopkg.GeoPackage; import org.opengis.feature.type.FeatureType; import org.opengis.feature.type.Name; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; /** * * WFS GetFeature OutputFormat for GeoPackage * * @author Niels Charlier * */ public class GeoPackageGetFeatureOutputFormat extends WFSGetFeatureOutputFormat { public final static String PROPERTY_INDEXED = "geopackage.wfs.indexed"; public GeoPackageGetFeatureOutputFormat(GeoServer gs) { super(gs, Sets.union(Sets.newHashSet(MIME_TYPE), Sets.newHashSet(NAMES))); } @Override public String getMimeType(Object value, Operation operation) throws ServiceException { return MIME_TYPE; } @Override public String getCapabilitiesElementName() { return NAMES.iterator().next(); } @Override public List<String> getCapabilitiesElementNames() { return Lists.newArrayList(NAMES); } @Override public String getPreferredDisposition(Object value, Operation operation) { return DISPOSITION_ATTACH; } @Override public String getAttachmentFileName(Object value, Operation operation) { GetFeatureRequest req = GetFeatureRequest.adapt(operation.getParameters()[0]); return Joiner.on("_").join(Iterables.transform(req.getQueries(), new Function<Query,String>() { @Override public String apply(Query input) { return input.getTypeNames().get(0).getLocalPart(); } })) + "." + EXTENSION; } @Override protected void write(FeatureCollectionResponse featureCollection, OutputStream output, Operation getFeature) throws IOException, ServiceException { GeoPackage geopkg = new GeoPackage(); for (FeatureCollection collection: featureCollection.getFeatures()) { FeatureEntry e = new FeatureEntry(); if (! (collection instanceof SimpleFeatureCollection)) { throw new ServiceException("GeoPackage OutputFormat does not support Complex Features."); } SimpleFeatureCollection features = (SimpleFeatureCollection) collection; FeatureTypeInfo meta = lookupFeatureType(features); if (meta != null) { // initialize entry metadata e.setIdentifier(meta.getTitle()); e.setDescription(abstractOrDescription(meta)); } geopkg.add(e, features); if ("true".equals(System.getProperty(PROPERTY_INDEXED))) { geopkg.createSpatialIndex(e); } } geopkg.close(); //write to output and delete temporary file InputStream temp = new FileInputStream(geopkg.getFile()); IOUtils.copy(temp, output); output.flush(); temp.close(); geopkg.getFile().delete(); } FeatureTypeInfo lookupFeatureType(SimpleFeatureCollection features) { FeatureType featureType = features.getSchema(); if (featureType != null) { Catalog cat = gs.getCatalog(); FeatureTypeInfo meta = cat.getFeatureTypeByName(featureType.getName()); if (meta != null) { return meta; } LOGGER.fine("Unable to load feature type metadata for: " + featureType.getName()); } else { LOGGER.fine("No feature type for collection, unable to load metadata"); } return null; } String abstractOrDescription(FeatureTypeInfo meta) { return meta.getAbstract() != null ? meta.getAbstract() : meta.getDescription(); } }