📄 getmapkvpreader.java
字号:
/* 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 java.awt.Color;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import javax.servlet.http.HttpServletRequest;
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.factory.CommonFactoryFinder;
import org.geotools.feature.FeatureType;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.styling.FeatureTypeConstraint;
import org.geotools.styling.NamedLayer;
import org.geotools.styling.NamedStyle;
import org.geotools.styling.SLDParser;
import org.geotools.styling.Style;
import org.geotools.styling.StyleAttributeExtractor;
import org.geotools.styling.StyleFactory;
import org.geotools.styling.StyledLayer;
import org.geotools.styling.StyledLayerDescriptor;
import org.geotools.styling.UserLayer;
import org.opengis.filter.Filter;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.vfny.geoserver.Request;
import org.vfny.geoserver.ServiceException;
import org.vfny.geoserver.config.PaletteManager;
import org.vfny.geoserver.global.CoverageInfo;
import org.vfny.geoserver.global.Data;
import org.vfny.geoserver.global.FeatureTypeInfo;
import org.vfny.geoserver.global.MapLayerInfo;
import org.vfny.geoserver.global.TemporaryFeatureTypeInfo;
import org.vfny.geoserver.global.WMS;
import org.vfny.geoserver.util.SLDValidator;
import org.vfny.geoserver.wms.WmsException;
import org.vfny.geoserver.wms.responses.palette.InverseColorMapOp;
import org.vfny.geoserver.wms.servlets.WMService;
import org.xml.sax.InputSource;
import com.vividsolutions.jts.geom.Envelope;
/**
* Builds a GetMapRequest object given by a set of CGI parameters supplied in
* the constructor.
*
* <p>
* Mandatory parameters:
*
* <ul>
* <li> LAYERS layer names, as exposed by the capabilities document, to compose
* a map with, in the order they may appear, being the first layer the one at
* the bottom of the layer stack and the last one the one at the top. </li>
* <li> STYLES list of named styles known by this server and applicable to the
* requested layers. It can be empty or contain exactly as many style names as
* layers was requested, in which case empty strings could be used to denote
* that the default layer style should be used. (exaple:
* <code>LAYERS=buildings,roads,railroads&STYLES=,centerline,</code>. This
* example says create a map with roads layer using its default style, roads
* with "centerline" style, and railroads with its default style. </li>
* <li> BBOX Area of interest for which to contruct the map image, in the
* Coordinate Reference System given by the SRS parameter. </li>
* <li> FORMAT MIME type of the resulting map, must be one of the advertised in
* the capabilities document. </li>
* <li> WIDTH desired map witdth in output units (pixels). UNITS support should
* be added to the spec, and UNITS and DPI parameters added. </li>
* <li> HEIGHT desired map height in output units (pixels). UNITS support should
* be added to the spec, and UNITS and DPI parameters added. </li>
* </ul>
* </p>
*
* <p>
* Optional parameters:
*
* <ul>
* <li> SRS </li>
* <li> TRANSPARENT boolean indicatin wether to create a map with transparent
* background or not (if transparency is supported by the requested output
* format). </li>
* <li> EXCEPTIONS MIME type of the exception report. </li>
* <li> BGCOLOR map background color, in <code>0xRRGGBB</code> format. </li>
* <li> SLD client supplies a URL for a remote SLD document through this
* parameter. This parameter takes precedence over STYLES. If present, replaces
* the LAYERS and STYLES parameters, since they're defined in the remote
* document itself. The document send by this way will be used in "literal" or
* "library" mode, see explanation bellow. </li>
* <li> SLD_BODY client spplies the SLD document itself through this parameter,
* properly encoded for an HTTP query string. This parameter takes precendence
* over STYLES and SLD. If present, replaces the LAYERS and STYLES parameters,
* since they're defined in the inline document itself. The document send by
* this way will be used in "literal" or "library" mode, see explanation bellow.
* </li>
* </ul>
* </p>
*
* <p>
* As defined by the Styled Layer Descriptor specification, version 1.0.0, the
* SLD document supplied by the SLD or SLD_BODY parameter can be used in
* "literal" or "library" mode, depending on whether the <strong>LAYERS=</strong>
* parameter is present.
* </p>
*
* <p>
* Here is the explanation from the spec, section 6.4, page 10: "the SLD can
* also be used in one of two different modes depending on whether the LAYERS
* parameter is present in the request. If it is not present, then all layers
* identified in the SLD document are rendered with all defined styles, which is
* equivalent to the XML-POST method of usage. If the LAYERS parameter is
* present, then only the layers identified by that parameter are rendered and
* the SLD is used as a style library . "
* </p>
*
* @author Gabriel Roldan, Axios Engineering
* @author Simone Giannecchini, GeoSolutions
* @version $Id: GetMapKvpReader.java 7749 2007-11-13 20:52:54Z jdeolive $
*
* @task TODO: parse and respect SRS parameter (needs reprojection support)
* @deprecated
*/
public class GetMapKvpReader extends WmsKvpRequestReader {
/** DOCUMENT ME! */
private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.vfny.geoserver.requests.readers.wms");
/** Used to parse SLD documents from SLD and SLD_BODY parameters */
private static final StyleFactory styleFactory = CommonFactoryFinder
.getStyleFactory(null);
/**
* Indicates wether STYLES parameter must be parsed. Defaults to
* <code>true</code>, but can be set to false, for example, when parsing
* a GetFeatureInfo request, which shares most of the getmap parameter but
* not STYLES.
*
* @task TODO: refactor this so it dont stay _so_ ugly
*/
private boolean stylesRequired = true;
/**
* Creates a new GetMapKvpReader object.
*
* @param kvpPairs
* Key Values pairs of the request
* @param service
* The service handling the request
*/
public GetMapKvpReader(Map kvpPairs, WMService service) {
super(kvpPairs, service);
}
/**
* Sets wether the STYLES parameter must be parsed
*
* @param parseStyles
*/
public void setStylesRequired(boolean parseStyles) {
this.stylesRequired = parseStyles;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public boolean isStylesRquired() {
return this.stylesRequired;
}
/**
* Produces a <code>GetMapRequest</code> instance by parsing the GetMap
* mandatory, optional and custom parameters.
*
* @param httpRequest
* the servlet request who's application object holds the server
* configuration
*
* @return a <code>GetMapRequest</code> completely setted up upon the
* parameters passed to this reader
*
* @throws ServiceException
* DOCUMENT ME!
*/
public Request getRequest(HttpServletRequest httpRequest)
throws ServiceException {
GetMapRequest request = new GetMapRequest((WMService) service);
request.setHttpServletRequest(httpRequest);
String version = getRequestVersion();
request.setVersion(version);
parseMandatoryParameters(request, true);
parseOptionalParameters(request);
return request;
}
/**
* Parses the optional parameters:
*
* <ul>
* <li> SRS </li>
* <li> TRANSPARENT </li>
* <li> EXCEPTIONS </li>
* <li> BGCOLOR </li>
* </ul>
*
*
* @param request
* DOCUMENT ME!
*
* @throws WmsException
* DOCUMENT ME!
*
* @task TODO: implement parsing of transparent, exceptions and bgcolor
*/
public void parseOptionalParameters(GetMapRequest request)
throws WmsException {
// SRS
String epsgCode = getValue("SRS");
if (epsgCode != null) {
try {
CoordinateReferenceSystem mapcrs = CRS.decode(epsgCode);
request.setCrs(mapcrs);
request.setSRS(epsgCode);
} catch (Exception e) {
// couldnt make it - we send off a service exception with the
// correct info
throw new WmsException(e.getLocalizedMessage(), "InvalidSRS");
}
}
// transparency
String transparentValue = getValue("TRANSPARENT");
boolean transparent = (transparentValue == null) ? false : Boolean
.valueOf(transparentValue).booleanValue();
request.setTransparent(transparent);
// background
String bgcolor = getValue("BGCOLOR");
if (bgcolor != null) {
try {
request.setBgColor(Color.decode(bgcolor));
} catch (NumberFormatException nfe) {
throw new WmsException("BGCOLOR " + bgcolor
+ " incorrectly specified (0xRRGGBB format expected)");
}
}
// filter parsing
parseFilterParam(request);
// buffer
String bufferValue = getValue("BUFFER");
int buffer = 0;
if (bufferValue != null) {
try {
buffer = Integer.parseInt(bufferValue);
} catch (NumberFormatException nfe) {
throw new WmsException("BUFFER " + bufferValue
+ " incorrectly specified (expected an integer)");
}
}
request.setBuffer(buffer);
// palette
String paletteValue = getValue("PALETTE");
if (paletteValue != null) {
try {
final InverseColorMapOp eicm = PaletteManager
.getPalette(paletteValue);
if (eicm == null) {
throw new WmsException("Palette " + paletteValue
+ " could not be found "
+ "in $GEOSERVER_DATA_DIR/palettes directory");
}
request.setPalette(eicm);
} catch (Exception e) {
throw new WmsException(e, "Palette " + paletteValue
+ " could not be loaded", null);
}
}
// tiling hint
String tiledValue = getValue("TILED");
request.setTiled("TRUE".equalsIgnoreCase(tiledValue));
// tiling origin
String origin = getValue("TILESORIGIN");
if (origin != null) {
request.setTilesOrigin(parseTilesOrigin(origin));
}
// feature version (for versioned requests)
String featureVersion = getValue("FEATUREVERSION");
request.setFeatureVersion(featureVersion);
/** KML/KMZ score value */
String KMScore = getValue("KMSCORE");
if (KMScore != null) {
try {
// handle special string cases of "vector" or "raster"
if (KMScore.equalsIgnoreCase("vector")) {
KMScore = "100"; // vector default
} else if (KMScore.equalsIgnoreCase("raster")) {
KMScore = "0"; // raster default
}
Integer s = new Integer(KMScore);
int score = s.intValue();
if ((score < 0) || (score > 100)) {
throw new NumberFormatException(
"KMScore not between 0 and 100. "
+ "If you wish not to use it, do not specify KMScore as a parameter.");
}
request.setKMScore(score);
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.info("Set KMScore: " + score);
}
} catch (NumberFormatException e) {
throw new WmsException(
"KMScore parameter ("
+ KMScore
+ ") incorrectly specified. "
+ "Expecting an integer value between between 0 and 100");
}
}
/** KMattr: 'full' or 'no' attribution for KML placemark <description> */
String KMAttr = getValue("KMATTR");
if (KMAttr != null) {
if (KMAttr.equalsIgnoreCase("no")
|| KMAttr.equalsIgnoreCase("false")
|| KMAttr.equalsIgnoreCase("0")) {
request.setKMattr(false);
} else {
request.setKMattr(true); // default to true
}
}
/** KML super overlay */
String superOverlay = getValue("SUPEROVERLAY");
if (superOverlay != null) {
request.setSuperOverlay("TRUE".equalsIgnoreCase(superOverlay));
}
/** KML legend */
String legend = getValue("LEGEND");
if (legend != null) {
request.setLegend("TRUE".equalsIgnoreCase(legend)
|| "ON".equalsIgnoreCase(legend));
}
// /** TIME: a time stamp for multidim coverages <description> */
// String time = getValue("TIME");
//
// if (time != null) {
// request.setTime(Integer.valueOf(time));
//
// if (LOGGER.isLoggable(Level.INFO)) {
// LOGGER.info("Set TIME: " + time);
// }
// }
/**
* ELEVATION: elevation (or depth) valu for multidim coverages
* <description>
*/
String elev = getValue("ELEVATION");
if (elev != null) {
request.setElevation(Integer.valueOf(elev));
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.info("Set ELEVATION: " + elev);
}
}
}
private Point2D parseTilesOrigin(String origin) {
Object[] coordValues = readFlat(origin, INNER_DELIMETER).toArray();
if (coordValues.length != 2) {
throw new ServiceException(origin + " is not a valid coordinate",
getClass().getName());
}
try {
double minx = Double.parseDouble(coordValues[0].toString());
double miny = Double.parseDouble(coordValues[1].toString());
return new Point2D.Double(minx, miny);
} catch (NumberFormatException ex) {
throw new ServiceException(ex,
"Illegal value for TILESORIGIN parameter: " + origin,
getClass().getName() + "::parseTilesOrigin()");
}
}
/**
* Parses the mandatory GetMap request parameters:
*
* <p>
* Mandatory parameters:
*
* <ul>
* <li> LAYERS </li>
* <li> STYLES ommited if SLD or SLD_BODY parameters are supplied </li>
* <li> BBOX </li>
* <li> FORMAT </li>
* <li> WIDTH </li>
* <li> HEIGHT </li>
* </ul>
* </p>
*
* @param request
* DOCUMENT ME!
* @parseStylesLayers true = normal operation, false = dont parse the styles
* and layers (used by the SLD GET/POST)
*
* @throws WmsException
* DOCUMENT ME!
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -