Package org.geoserver.geosearch.rest

Source Code of org.geoserver.geosearch.rest.GeoSearchLayer

/* (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.geosearch.rest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogInfo;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.config.GeoServer;
import org.geoserver.config.GeoServerInfo;
import org.geoserver.kml.KMLEncoder;
import org.geoserver.kml.KMZMapOutputFormat;
import org.geoserver.kml.KmlEncodingContext;
import org.geoserver.kml.builder.SimpleNetworkLinkBuilder;
import org.geoserver.kml.sequence.PlainFolderSequenceFactory;
import org.geoserver.kml.sequence.SequenceFactory;
import org.geoserver.kml.sequence.SequenceList;
import org.geoserver.ows.util.KvpMap;
import org.geoserver.platform.ServiceException;
import org.geoserver.rest.AbstractResource;
import org.geoserver.rest.RestletException;
import org.geoserver.rest.format.DataFormat;
import org.geoserver.rest.util.RESTUtils;
import org.geoserver.wms.DefaultWebMapService;
import org.geoserver.wms.GetMap;
import org.geoserver.wms.GetMapOutputFormat;
import org.geoserver.wms.GetMapRequest;
import org.geoserver.wms.MapLayerInfo;
import org.geoserver.wms.MapProducerCapabilities;
import org.geoserver.wms.WMS;
import org.geoserver.wms.WMSMapContent;
import org.geoserver.wms.WebMap;
import org.geoserver.wms.map.GetMapKvpRequestReader;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.map.Layer;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.util.logging.Logging;
import org.restlet.Context;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.data.Status;
import org.restlet.resource.Representation;

import de.micromata.opengis.kml.v_2_2_0.Document;
import de.micromata.opengis.kml.v_2_2_0.Feature;
import de.micromata.opengis.kml.v_2_2_0.Kml;
import de.micromata.opengis.kml.v_2_2_0.atom.Author;

/**
* @author groldan
* @see LayerKMLDocumentFormat
*/
public class GeoSearchLayer extends AbstractResource {

    private static final Logger LOGGER = Logging.getLogger(GeoSearchLayer.class);

    private final CatalogInfo layer;

    private final GeoServer geoserver;

    private KMLEncoder encoder;

    public GeoSearchLayer(final Context context, final Request request, final Response response,
            final CatalogInfo layer, GeoServer geoserver, KMLEncoder encoder) {
        super(context, request, response);
        this.layer = layer;
        this.geoserver = geoserver;
        this.encoder = encoder;
    }

    @Override
    public void handleGet() {
        final WMS wms = new WMS(geoserver) {
            @Override
            public GetMapOutputFormat getMapOutputFormat(final String mimeType) {
                return new GetMapSnatcher();
            }
        };

        GetMapKvpRequestReader reader = new GetMapKvpRequestReader(wms);
        reader.setHttpRequest(RESTUtils.getServletRequest(getRequest()));

        GetMapRequest getMapRequest = getRequest(layer);
        final String title;
        final String description;
        String[] keywords = {};
        if (layer instanceof LayerInfo) {
            LayerInfo layerInfo = (LayerInfo) layer;
            title = layerInfo.getResource().getTitle();
            description = layerInfo.getResource().getAbstract();
            List<String> kws = layerInfo.getResource().keywordValues();
            if (kws != null) {
                keywords = kws.toArray(new String[kws.size()]);
            }
        } else {
            LayerGroupInfo lgi = (LayerGroupInfo) layer;
            title = getTitle(lgi);
            description = getDescription(lgi);
            keywords = getKeyWords(lgi);
        }

        WMSMapContent context = new WMSMapContent(getMapRequest);
        context.setTitle(title);
        context.setAbstract(description);
        context.setKeywords(keywords);
        context.setMapWidth(getMapRequest.getWidth());
        context.setMapHeight(getMapRequest.getHeight());
        context.getViewport().setBounds((ReferencedEnvelope) getMapRequest.getBbox());

        MapContentWebMap webMap;
        try {
            webMap = (MapContentWebMap) new GetMap(wms).run(getMapRequest, context);
        } catch (Exception e) {
            throw new RestletException(e.getMessage(), Status.SERVER_ERROR_INTERNAL, e);
        }
       
        KmlEncodingContext encodingContext = new KmlEncodingContext(webMap.getMapContent(), wms, true);
        KmlEncodingBundle kml = buildKml(encodingContext);

        DataFormat format = getFormatGet();
        Representation representation = format.toRepresentation(kml);
        Response response = getResponse();
        response.setEntity(representation);
    }

    private KmlEncodingBundle buildKml(KmlEncodingContext encodingContext) {
        SimpleNetworkLinkBuilder nlBuilder = new SimpleNetworkLinkBuilder(encodingContext);
        Kml kml = nlBuilder.buildKMLDocument();

        Document doc = (Document) kml.getFeature();
        doc.createAndSetAtomAuthor();
        doc.setOpen(true);
        GeoServerInfo gsInfo = encodingContext.getWms().getGeoServer().getGlobal();
        String authorName = gsInfo.getSettings().getContact().getContactPerson();
        Author author = doc.createAndSetAtomAuthor();
        author.addToNameOrUriOrEmail(authorName);
        doc.createAndSetAtomLink(gsInfo.getSettings().getOnlineResource());
       
        WMSMapContent mapContent = encodingContext.getMapContent();
        doc.setDescription(buildDescription(mapContent));

        // see if we have to include sample data
        List<Layer> layers = mapContent.layers();
        boolean includeSampleData = false;
        for (int i = 0; i < layers.size(); i++) {
            // layer and info
            MapLayerInfo layerInfo = mapContent.getRequest().getLayers().get(i);
            final int type = layerInfo.getType();
            if (MapLayerInfo.TYPE_VECTOR == type || MapLayerInfo.TYPE_REMOTE_VECTOR == type) {
                includeSampleData = true;
            }
        }
        if(includeSampleData) {
            SequenceFactory<Feature> generatorFactory = new PlainFolderSequenceFactory(encodingContext);
            SequenceList<Feature> folders = new SequenceList<Feature>(generatorFactory);
            encodingContext.addFeatures(doc, folders);
        }
       
        return new KmlEncodingBundle(kml, encodingContext);
    }
   
    private String buildDescription(WMSMapContent mapContent) {
        StringBuilder sb = new StringBuilder();
        if (null != mapContent.getAbstract()) {
            sb.append(mapContent.getAbstract());
        }
        if (null != mapContent.getKeywords()) {
            sb.append("\n");
            for (String kw : mapContent.getKeywords()) {
                if (null != kw) {
                    sb.append(kw).append(" ");
                }
            }
        }
        return sb.toString();
    }

    /**
     * @see org.geoserver.rest.AbstractResource#createSupportedFormats(org.restlet.data.Request,
     *      org.restlet.data.Response)
     */
    @Override
    protected List<DataFormat> createSupportedFormats(final Request request, final Response response) {
        final List<DataFormat> siteMapFormats = new ArrayList<DataFormat>(1);
        siteMapFormats.add(new LayerKMLDocumentFormat(encoder));
        return siteMapFormats;
    }

    @SuppressWarnings("unchecked")
    private GetMapRequest getRequest(CatalogInfo info) {
        GetMapRequest request = new GetMapRequest();
        request.setVersion("1.1.1");
        Catalog catalog = geoserver.getCatalog();
        List<MapLayerInfo> layers = expandLayers(catalog, info);
        request.setLayers(layers);
        request.setFormat(KMZMapOutputFormat.MIME_TYPE);
        request.setBbox(getLatLonBbox(info));
        request.setSRS("EPSG:4326");

        // proxy aware base url?
        String baseurl = getRequest().getRootRef().getParentRef().toString();
        request.setBaseUrl(baseurl);
        request.setRawKvp(new KvpMap());
        int maxFeatures = 1000;
        if (info instanceof LayerGroupInfo) {
            maxFeatures = maxFeatures / ((LayerGroupInfo) info).getLayers().size();
        }
        request.setMaxFeatures(maxFeatures);

        try {
            DefaultWebMapService.autoSetMissingProperties(request);
        } catch (Exception e) {
            throw new RestletException(
                    "Could not set figure out automatically a good preview link for " + info,
                    Status.SERVER_ERROR_INTERNAL, e);
        }
        return request;
    }

    private ReferencedEnvelope getLatLonBbox(CatalogInfo info) {
        if (info instanceof LayerInfo) {
            return ((LayerInfo) info).getResource().getLatLonBoundingBox();
        }
        LayerGroupInfo lgi = (LayerGroupInfo) info;
        ReferencedEnvelope latLonBoundingBox;
        latLonBoundingBox = lgi.getBounds();
        try {
            latLonBoundingBox = latLonBoundingBox.transform(DefaultGeographicCRS.WGS84, true);
        } catch (Exception e) {
            LOGGER.log(Level.INFO, "Error transforming " + lgi.getName()
                    + " LayerGroup's bounds to EPSG:4326", e);
            latLonBoundingBox = new ReferencedEnvelope(DefaultGeographicCRS.WGS84);
            try {
                for (LayerInfo li : lgi.layers()) {
                    ReferencedEnvelope llbb = li.getResource().getLatLonBoundingBox();
                    latLonBoundingBox.expandToInclude(llbb.transform(DefaultGeographicCRS.WGS84,
                            true));
                }
            } catch (Exception e2) {
                throw new RuntimeException(e2);
            }
        }
        return latLonBoundingBox;
    }

    /**
     * Expands the specified name into a list of layer info names
     */
    private List<MapLayerInfo> expandLayers(Catalog catalog, CatalogInfo info) {
        List<MapLayerInfo> layers = new ArrayList<MapLayerInfo>();

        if (info instanceof LayerInfo) {
            layers.add(new MapLayerInfo((LayerInfo) info));
        } else {
            for (LayerInfo l : ((LayerGroupInfo) info).layers()) {
                layers.add(new MapLayerInfo(l));
            }
        }
        return layers;
    }

    private String[] getKeyWords(LayerGroupInfo lgi) {
        Set<String> kws = new TreeSet<String>();
        for (LayerInfo li : lgi.layers()) {
            List<String> keywords = li.getResource().keywordValues();
            if (keywords != null) {
                kws.addAll(keywords);
            }
        }
        return kws.toArray(new String[kws.size()]);
    }

    private String getDescription(LayerGroupInfo lgi) {
        StringBuilder desc = new StringBuilder();
        for (LayerInfo li : lgi.layers()) {
            desc.append(li.getResource().getPrefixedName());
            desc.append(": ");
            String lidesc = li.getResource().getAbstract();
            if (lidesc != null) {
                desc.append(lidesc);
            }
            desc.append("\n");
        }
        return desc.toString();
    }

    private String getTitle(LayerGroupInfo lgi) {
        StringBuilder title = new StringBuilder("Layer Group composed of: ");
        for (LayerInfo li : lgi.layers()) {
            title.append("\"").append(li.getResource().getTitle()).append("\"  ");
        }
        return title.toString();
    }
   
    private static class GetMapSnatcher implements GetMapOutputFormat {

        @Override
        public WebMap produceMap(WMSMapContent mapContent) throws ServiceException, IOException {
            return new MapContentWebMap(mapContent);
        }

        @Override
        public Set<String> getOutputFormatNames() {
            return null;
        }

        @Override
        public String getMimeType() {
            return null;
        }

        @Override
        public MapProducerCapabilities getCapabilities(String format) {
            return new MapProducerCapabilities(false, false, false, false, "fake/mime");
        }
       
    }
   
    private static class MapContentWebMap extends WebMap {

        private WMSMapContent content;

        public MapContentWebMap(WMSMapContent context) {
            super(context);
            this.content = context;
        }
       
        public WMSMapContent getMapContent() {
            return content;
        }
       
    }

}
TOP

Related Classes of org.geoserver.geosearch.rest.GeoSearchLayer

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.