⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getmapxmlreader.java

📁 电子地图服务器,搭建自己的地图服务
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* 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.vfny.geoserver.wms.requests;

import com.vividsolutions.jts.geom.Coordinate;
import org.geotools.data.DefaultQuery;
import org.geotools.data.FeatureReader;
import org.geotools.data.Query;
import org.geotools.data.Transaction;
import org.geotools.data.crs.ForceCoordinateSystemFeatureReader;
import org.geotools.data.memory.MemoryDataStore;
import org.geotools.feature.FeatureType;
import org.geotools.filter.ExpressionDOMParser;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.styling.SLDParser;
import org.geotools.styling.StyleFactory;
import org.geotools.styling.StyleFactoryFinder;
import org.geotools.styling.StyledLayer;
import org.geotools.styling.StyledLayerDescriptor;
import org.geotools.styling.UserLayer;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.vfny.geoserver.Request;
import org.vfny.geoserver.global.MapLayerInfo;
import org.vfny.geoserver.global.TemporaryFeatureTypeInfo;
import org.vfny.geoserver.util.GETMAPValidator;
import org.vfny.geoserver.util.SLDValidator;
import org.vfny.geoserver.util.requests.readers.XmlRequestReader;
import org.vfny.geoserver.wms.WmsException;
import org.vfny.geoserver.wms.servlets.WMService;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXParseException;
import java.awt.Color;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.servlet.http.HttpServletRequest;


/**
 * reads in a GetFeature XML WFS request from a XML stream
 *
 * @author Rob Hranac, TOPP
 * @author Chris Holmes, TOPP
 * @version $Id: GetMapXmlReader.java 7749 2007-11-13 20:52:54Z jdeolive $
 */
public class GetMapXmlReader extends XmlRequestReader {
    private static final StyleFactory styleFactory = StyleFactoryFinder.createStyleFactory();

    /**
     * Creates a new GetMapXmlReader object.
     * @param service this is the service that handles the request
     */
    public GetMapXmlReader(WMService service) {
        super(service);
    }

    /**
     * Reads the GetMap XML request into a GetMap Request object.
     *
     * @param reader The plain POST text from the client.
     * @param req DOCUMENT ME!
     *
     * @return The GetMap Request from the xml reader.
     *
     * @throws WmsException For any problems reading the request.
     */
    public Request read(Reader reader, HttpServletRequest req)
        throws WmsException {
        GetMapRequest getMapRequest = new GetMapRequest((WMService) getServiceRef());
        getMapRequest.setHttpServletRequest(req);

        boolean validateSchema = wantToValidate(req);

        try {
            parseGetMapXML(reader, getMapRequest, validateSchema);
        } catch (java.net.UnknownHostException unh) {
            //J--
            //http://www.oreilly.com/catalog/jenut2/chapter/ch19.html ---
            // There is one complication to this example. Most web.xml files contain a <!DOCTYPE> tag that specifies
            //the document type (or DTD). Despite the fact that Example 19.1 specifies that the parser should not
            //validate the document, a conforming XML parser must still read the DTD for any document that has a
            //<!DOCTYPE> declaration. Most web.xml have a declaration like this:
            //..
            //In order to read the DTD, the parser must be able to read the specified URL. If your system is not
            //connected to the Internet when you run the example, it will hang.
            //. Another workaround to this DTD problem is to simply remove (or comment out) the <!DOCTYPE> declaration from the web.xml file you process with ListServlets1./
            //
            //also see:
            //http://doctypechanger.sourceforge.net/
            //J+
            throw new WmsException("unknown host - " + unh.getLocalizedMessage()
                + " - if its in a !DOCTYPE, remove the !DOCTYPE tag.");
        } catch (SAXParseException se) {
            throw new WmsException("line " + se.getLineNumber() + " column " + se.getColumnNumber()
                + " -- " + se.getLocalizedMessage());
        } catch (Exception e) {
            throw new WmsException(e);
        }

        return getMapRequest;
    }

    /**
     * Actually read in the XML request and stick it in the request object. We
     * do this using the DOM parser (because the SLD parser is DOM based and
     * we can integrate).  1. parse into DOM 2. parse the SLD  3. grab the
     * rest of the attribute 4. stuff #3 attributes in the request object 5.
     * stuff the SLD info into the request object 6. return  GetMap schema is
     * at http://www.opengeospatial.org/docs/02-017r1.pdf (page 18)  NOTE: see
     * handlePostGet() for people who put the SLD in the POST and the
     * parameters in the GET.
     *
     * @param xml
     * @param getMapRequest
     * @param validateSchema DOCUMENT ME!
     *
     * @throws Exception DOCUMENT ME!
     */
    private void parseGetMapXML(Reader xml, GetMapRequest getMapRequest, boolean validateSchema)
        throws Exception {
        File temp = null;

        if (validateSchema) //copy POST to a file
         {
            //make tempfile
            temp = File.createTempFile("getMapPost", "xml");
            temp.deleteOnExit();

            FileOutputStream fos = new FileOutputStream(temp);
            BufferedOutputStream out = new BufferedOutputStream(fos);

            int c;

            while (-1 != (c = xml.read())) {
                out.write(c);
            }

            xml.close();
            out.flush();
            out.close();
            xml = new BufferedReader(new FileReader(temp)); // pretend like nothing has happened
        }

        try {
            javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory
                .newInstance();

            dbf.setExpandEntityReferences(false);
            dbf.setValidating(false);
            dbf.setNamespaceAware(true);

            javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();

            InputSource input = new InputSource(xml);
            org.w3c.dom.Document dom = db.parse(input);

            SLDParser sldParser = new SLDParser(styleFactory);

            Node rootNode = dom.getDocumentElement();

            // we have the SLD component, now we get all the GetMAp components
            // step a  -- attribute "version"
            Node nodeGetMap = rootNode;

            if (!(nodeNameEqual(nodeGetMap, "getmap"))) {
                if (nodeNameEqual(nodeGetMap, "StyledLayerDescriptor")) //oopsy!!  its a SLD POST with get parameters!
                 {
                    if (validateSchema) {
                        validateSchemaSLD(temp, getMapRequest);
                    }

                    handlePostGet(rootNode, sldParser, getMapRequest);

                    return;
                }

                throw new Exception(
                    "GetMap XML parser - start node isnt 'GetMap' or 'StyledLayerDescriptor' tag");
            }

            if (validateSchema) {
                validateSchemaGETMAP(temp, getMapRequest);
            }

            NamedNodeMap atts = nodeGetMap.getAttributes();
            Node wmsVersion = atts.getNamedItem("version");

            if (wmsVersion == null) {
                throw new Exception(
                    "GetMap XML parser - couldnt find attribute 'version' in GetMap tag");
            }

            getMapRequest.setVersion(wmsVersion.getNodeValue());

            //ignore the OWSType since we know its supposed to be WMS
            //step b -bounding box
            parseBBox(getMapRequest, nodeGetMap);

            // for SLD we already have it (from above) (which we'll handle as layers later)
            StyledLayerDescriptor sld = sldParser.parseDescriptor(getNode(rootNode,
                        "StyledLayerDescriptor"));
            processStyles(getMapRequest, sld);

            //step c - "Output"
            parseXMLOutput(nodeGetMap, getMapRequest); //make this function easier to read

            //step d - "exceptions"
            getMapRequest.setExceptions(getNodeValue(nodeGetMap, "Exceptions"));

            //step e - "VendorType
            // we dont actually do anything with this, so...
            //step f - rebuild SLD info.  Ie. fill in the Layer and Style information, just like SLD post-get
        } finally {
            if (temp != null) {
                temp.delete();
            }
        }
    }

    /**
     * This is the hybrid SLD POST way. Normal is the GetMap - with a built in
     * SLD.  The alternate, for stupid people, is the WMS parameters in the
     * GET, and the SLD in the post. This handles that case.
     *
     * @param rootNode
     * @param sldParser
     * @param getMapRequest
     *
     * @throws Exception DOCUMENT ME!
     */
    private void handlePostGet(Node rootNode, SLDParser sldParser, GetMapRequest getMapRequest)
        throws Exception {
        //get the GET parmeters
        HttpServletRequest request = getMapRequest.getHttpServletRequest();

        String qString = request.getQueryString();

        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.fine(new StringBuffer("reading request: ").append(qString).toString());
        }

        //Map requestParams = KvpRequestReader.parseKvpSet(qString);
        Map requestParams = new HashMap();
        String paramName;
        String paramValue;

        for (Enumeration pnames = request.getParameterNames(); pnames.hasMoreElements();) {
            paramName = (String) pnames.nextElement();
            paramValue = request.getParameter(paramName);
            requestParams.put(paramName.toUpperCase(), paramValue);
        }

        GetMapKvpReader kvpReader = new GetMapKvpReader(requestParams, (WMService) getServiceRef());

        String version = kvpReader.getRequestVersion();
        getMapRequest.setVersion(version);

        kvpReader.parseMandatoryParameters(getMapRequest, false); //false means dont do styles/layers (see below)
        kvpReader.parseOptionalParameters(getMapRequest);

        //get styles/layers from the sld.
        StyledLayerDescriptor sld = sldParser.parseDescriptor(rootNode); //root = <StyledLayerDescriptor>
        processStyles(getMapRequest, sld);
    }

    /**
     * taken from the kvp reader, with modifications
     *
     * @param getMapRequest
     * @param sld
     *
     * @throws Exception DOCUMENT ME!
     * @throws WmsException DOCUMENT ME!
     */
    private void processStyles(GetMapRequest getMapRequest, StyledLayerDescriptor sld)
        throws Exception {
        final StyledLayer[] styledLayers = sld.getStyledLayers();
        final int slCount = styledLayers.length;

        if (slCount == 0) {
            throw new WmsException("SLD document contains no layers");
        }

        final List layers = new ArrayList();
        final List styles = new ArrayList();
        MapLayerInfo currLayer;

        StyledLayer sl = null;

        for (int i = 0; i < slCount; i++) {
            currLayer = new MapLayerInfo();
            sl = styledLayers[i];

            String layerName = sl.getName();

            if (null == layerName) {
                throw new WmsException("A UserLayer without layer name was passed");
            }

            // TODO: add support for remote WFS here
            //handle the InLineFeature stuff
            boolean isBaseMap = false;
            if ((sl instanceof UserLayer)
                    && ((((UserLayer) sl)).getInlineFeatureDatastore() != null)) {
                //SPECIAL CASE - we make the temporary version
                UserLayer ul = ((UserLayer) sl);
                GetMapKvpReader.initializeInlineFeatureLayer(getMapRequest, ul, currLayer);
            } else {
                
                //look for a base map layer
                String layerGroup = (String) getMapRequest.getWMS().getBaseMapLayers().get( layerName );
                if ( layerGroup != null ) {
                    isBaseMap = true;
                    List layerGroupExpanded = GetMapKvpReader.parseLayerGroup(layerGroup);
                    for (Iterator it = layerGroupExpanded.iterator(); it.hasNext();) {
                        layerName = (String) it.next();
                        currLayer = new MapLayerInfo();
                        try {
                            currLayer.setFeature(GetMapKvpReader.findFeatureLayer(getMapRequest, layerName));    
                        }
                        catch( Exception e ) {
                            currLayer.setCoverage(GetMapKvpReader.findCoverageLayer(getMapRequest, layerName));
                        }
                        
                        GetMapKvpReader.addStyles(getMapRequest, currLayer, styledLayers[i], layers, styles);
                    }
                }
                else {
                    try {
                        currLayer.setFeature(GetMapKvpReader.findFeatureLayer(getMapRequest, layerName));    
                    }
                    catch( Exception e ) {
                        currLayer.setCoverage(GetMapKvpReader.findCoverageLayer(getMapRequest, layerName));
                    }
                }
            }

            if (!isBaseMap) {
                GetMapKvpReader.addStyles(getMapRequest, currLayer, styledLayers[i], layers, styles);    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -