Package org.geoserver.wms.featureinfo

Source Code of org.geoserver.wms.featureinfo.GetFeatureInfoKvpReader

/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org.  All rights reserved.
* This code is licensed under the GPL 2.0 license, availible at the root
* application directory.
*/
package org.geoserver.wms.featureinfo;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.geoserver.catalog.LayerInfo;
import org.geoserver.ows.KvpRequestReader;
import org.geoserver.platform.ServiceException;
import org.geoserver.wms.GetFeatureInfoRequest;
import org.geoserver.wms.GetMapRequest;
import org.geoserver.wms.MapLayerInfo;
import org.geoserver.wms.WMS;
import org.geoserver.wms.WMSErrorCode;
import org.geoserver.wms.kvp.MapLayerInfoKvpParser;
import org.geoserver.wms.map.GetMapKvpRequestReader;
import org.geotools.util.Version;

/**
* Builds a GetFeatureInfo request object given by a set of CGI parameters supplied in the
* constructor.
* <p>
* Reads both WMS 1.1.1 and 1.3.0 GetFeatureInfo requests.
* </p>
* <p>
* Request parameters:
* </p>
*
* @author Gabriel Roldan
* @version $Id: GetFeatureInfoKvpReader.java 15292 2011-01-20 17:24:04Z groldan $
*/
public class GetFeatureInfoKvpReader extends KvpRequestReader {

    /** GetMap request reader used to parse the map context parameters needed. */
    private GetMapKvpRequestReader getMapReader;

    private WMS wms;

    public GetFeatureInfoKvpReader(WMS wms) {
        super(GetFeatureInfoRequest.class);
        getMapReader = new GetMapKvpRequestReader(wms);
        setWMS(wms);
    }

    public void setWMS(final WMS wms) {
        this.wms = wms;
    }

    public WMS getWMS() {
        return wms;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public Object read(Object req, Map kvp, Map rawKvp) throws Exception {
        GetFeatureInfoRequest request = (GetFeatureInfoRequest) super.read(req, kvp, rawKvp);
        request.setRawKvp(rawKvp);

        request.setQueryLayers(new MapLayerInfoKvpParser("QUERY_LAYERS", wms).parse((String) rawKvp
                .get("QUERY_LAYERS")));

        if (request.getQueryLayers() == null || request.getQueryLayers().size() == 0) {
            throw new ServiceException("No QUERY_LAYERS has been requested, or no "
                    + "queriable layer in the request anyways");
        }

        GetMapRequest getMapPart = new GetMapRequest();
        try {
            getMapPart = getMapReader.read(getMapPart, kvp, rawKvp);
        } catch (ServiceException se) {
            throw se;
        } catch (Exception e) {
            throw new ServiceException(e);
        }

        request.setGetMapRequest(getMapPart);

        // make sure they are a subset of layers
        List<MapLayerInfo> getMapLayers = getMapPart.getLayers();
        List<MapLayerInfo> queryLayers = new ArrayList<MapLayerInfo>(request.getQueryLayers());
        queryLayers.removeAll(getMapLayers);
        if (queryLayers.size() > 0) {
            // we've already expanded base layers so let's avoid list the names, they are not
            // the original ones anymore
            throw new ServiceException("QUERY_LAYERS contains layers not cited in LAYERS. "
                    + "It should be a proper subset of those instead");
        }
        for (MapLayerInfo l : request.getQueryLayers()) {
            LayerInfo layerInfo = l.getLayerInfo();
            if (!wms.isQueryable(layerInfo)) {
                throw new ServiceException("Layer " + l.getName() + " is not queryable",
                    WMSErrorCode.LAYER_NOT_QUERYABLE.get(request.getVersion()), "QUERY_LAYERS");
            }
        }

        String format = (String) (kvp.containsKey("INFO_FORMAT") ? kvp.get("INFO_FORMAT") : null);

        if (format == null) {
            format = "text/plain";
        } else {
            List<String> infoFormats = wms.getAvailableFeatureInfoFormats();
            if (!infoFormats.contains(format)) {
                throw new ServiceException("Invalid format '" + format
                        + "', supported formats are " + infoFormats, "InvalidFormat", "info_format");
            }
        }

        request.setInfoFormat(format);

        request.setFeatureCount(1); // DJB: according to the WMS spec (7.3.3.7 FEATURE_COUNT) this
                                    // should be 1. also tested for by cite
        try {
            int maxFeatures = Integer.parseInt(String.valueOf(kvp.get("FEATURE_COUNT")));
            request.setFeatureCount(maxFeatures);
        } catch (NumberFormatException ex) {
            // do nothing, FEATURE_COUNT is optional
        }

        Version version = wms.negotiateVersion(request.getVersion());
        request.setVersion(version.toString());
       
        //JD: most wms 1.3 client implementations still use x/y rather than i/j, so we support those
        // too when i/j not specified when not running in strict cite compliance mode
        String colPixel, rowPixel;
        if(version.compareTo(WMS.VERSION_1_3_0) >= 0) {
            colPixel = "I";
            rowPixel = "J";
           
            if (!kvp.containsKey(colPixel) && !kvp.containsKey(rowPixel)) {
                if (!wms.getServiceInfo().isCiteCompliant() && kvp.containsKey("X")
                    && kvp.containsKey("Y")) {
                    colPixel = "X";
                    rowPixel = "Y";
                }
            }
        }
        else {
            colPixel = "X";
            rowPixel = "Y";
        }
       
        try {
            String colParam = String.valueOf(kvp.get(colPixel));
            String rowParam = String.valueOf(kvp.get(rowPixel));
            int x = Integer.parseInt(colParam);
            int y = Integer.parseInt(rowParam);
           
            //ensure x/y in dimension of image
            if (x < 0 || x > getMapPart.getWidth() || y < 0 || y > getMapPart.getHeight()) {
                throw new ServiceException(
                    String.format("%d, %d not in dimensions of image: %d, %d", x, y,
                        getMapPart.getWidth(), getMapPart.getHeight()), "InvalidPoint");
            }
            request.setXPixel(x);
            request.setYPixel(y);
        } catch (NumberFormatException ex) {
            String msg = colPixel + " and " + rowPixel + " incorrectly specified";
            throw new ServiceException(msg, "InvalidPoint");
        }

        return request;
    }
}
TOP

Related Classes of org.geoserver.wms.featureinfo.GetFeatureInfoKvpReader

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.