Package org.geoserver.wms

Source Code of org.geoserver.wms.GetFeatureInfo

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

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Logger;

import net.opengis.wfs.FeatureCollectionType;
import net.opengis.wfs.WfsFactory;

import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.platform.ServiceException;
import org.geoserver.wms.featureinfo.FeatureCollectionDecorator;
import org.geoserver.wms.featureinfo.LayerIdentifier;
import org.geotools.data.DataUtilities;
import org.geotools.data.Query;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.NameImpl;
import org.geotools.util.logging.Logging;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.Name;
import org.opengis.filter.Filter;

/**
* WMS GetFeatureInfo operation
*
* @author Gabriel Roldan
*/
public class GetFeatureInfo {

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

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public FeatureCollectionType run(final GetFeatureInfoRequest request) throws ServiceException {
        List<FeatureCollection> results;
        try {
            results = execute(request);
        } catch (ServiceException se) {
            se.printStackTrace();
            throw se;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("Internal error occurred", e);
        }
        return buildResults(results);
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private FeatureCollectionType buildResults(List<FeatureCollection> results) {

        FeatureCollectionType result = WfsFactory.eINSTANCE.createFeatureCollectionType();
        result.setTimeStamp(Calendar.getInstance());
        result.getFeature().addAll(results);

        return result;
    }

    @SuppressWarnings("rawtypes")
    private List<FeatureCollection> execute(GetFeatureInfoRequest request) throws Exception {
        final List<MapLayerInfo> requestedLayers = request.getQueryLayers();
        FeatureInfoRequestParameters requestParams = new FeatureInfoRequestParameters(request);

        List<FeatureCollection> results = new ArrayList<FeatureCollection>(requestedLayers.size());

        int maxFeatures = request.getFeatureCount();
        List<LayerIdentifier> identifiers = GeoServerExtensions.extensions(LayerIdentifier.class);
        for (int i = 0; i < requestedLayers.size(); i++) {
            final MapLayerInfo layer = requestedLayers.get(i);

            LayerIdentifier identifier = getLayerIdentifier(layer, identifiers);
            List<FeatureCollection> identifiedCollections = identifier.identify(requestParams,
                    maxFeatures);
            if (identifiedCollections != null) {
                for (FeatureCollection identifierCollection : identifiedCollections) {
                    FeatureCollection fc = selectProperties(requestParams, identifierCollection);
                    maxFeatures = addToResults(fc, results, layer, request, maxFeatures);
                }

                // exit when we have collected enough features
                if (maxFeatures <= 0) {
                    break;
                }
            }

            requestParams.nextLayer();
        }
        return results;
    }

    private LayerIdentifier getLayerIdentifier(MapLayerInfo layer, List<LayerIdentifier> identifiers) {
        for (LayerIdentifier identifier : identifiers) {
            if (identifier.canHandle(layer)) {
                return identifier;
            }
        }

        throw new ServiceException("Could not find any identifier that can handle layer "
                + layer.getLayerInfo().prefixedName() + " among these identifiers: " + identifiers);
    }

    private int addToResults(FeatureCollection collection, List<FeatureCollection> results,
            final MapLayerInfo layer, GetFeatureInfoRequest request, int maxFeatures) {
        if (collection != null) {
            if (!(collection.getSchema() instanceof SimpleFeatureType)) {
                // put wrapper around it with layer name
                Name name = new NameImpl(layer.getFeature().getNamespace().getName(), layer
                        .getFeature().getName());
                collection = new FeatureCollectionDecorator(name, collection);
            }

            int size = collection.size();
            if (size != 0) {

                // HACK HACK HACK
                // For complex features, we need the targetCrs and version in scenario where we have
                // a top level feature that does not contain a geometry(therefore no crs) and has a
                // nested feature that contains geometry as its property.Furthermore it is possible
                // for each nested feature to have different crs hence we need to reproject on each
                // feature accordingly.
                // This is a Hack, this information should not be passed through feature type
                // appschema will need to remove this information from the feature type again
                if (!(collection instanceof SimpleFeatureCollection)) {
                    collection.getSchema().getUserData()
                            .put("targetCrs", request.getGetMapRequest().getCrs());
                    collection.getSchema().getUserData().put("targetVersion", "wms:getfeatureinfo");

                }

                results.add(collection);

                // don't return more than FEATURE_COUNT
                maxFeatures -= size;
                if (maxFeatures <= 0) {
                    return 0;
                }
            }
        }
        return maxFeatures;
    }

    protected FeatureCollection selectProperties(FeatureInfoRequestParameters params,
            FeatureCollection collection) throws IOException {
        String[] names = params.getPropertyNames();
        if (names != Query.ALL_NAMES) {
            Query q = new Query(collection.getSchema().getName().getLocalPart(), Filter.INCLUDE,
                    names);
            return DataUtilities.source(collection).getFeatures(q);
        } else {
            return collection;
        }
    }

}
TOP

Related Classes of org.geoserver.wms.GetFeatureInfo

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.