📄 getmapkvpreader.java
字号:
// - }
// - if (errors.size() != 0)
// - {
// - in = new StringBufferInputStream(sldBody);
// - throw new
// WmsException(SLDValidator.getErrorMessage(in,errors));
// - }
}
// - InputStream in = new StringBufferInputStream(sldBody);
// - SLDParser parser = new SLDParser(styleFactory, in);
Reader reader = getReaderFromString(sldBody);
SLDParser parser = new SLDParser(styleFactory, reader);
StyledLayerDescriptor sld = parser.parseSLD();
parseStyledLayerDescriptor(request, sld);
}
/**
* Create a reader of the given String. This reader will be used in the
* InputSource for the sld parser. The advantage with a reader over a input
* stream is that we don't have to consider encoding. The xml declaration
* with encoding is ignored using a Reader in parser. The encoding of the
* string has been appropiate handled by the servlet when streaming in.
*
* @param sldBody
* the sldbody to create a reader of.
* @return The created reader
* @see Reader
*/
private Reader getReaderFromString(String sldBody) {
return new StringReader(sldBody);
}
/**
* Gets a sequence of url encoded filters and parses them into Filter
* objects that will be set into the request object
*
* @param request
* @throws WmsException
*/
protected void parseFilterParam(GetMapRequest request) throws WmsException {
String rawFilter = getValue("FILTER");
String rawCqlFilter = getValue("CQL_FILTER");
String rawIdFilter = getValue("FEATUREID");
// in case of a mixed request, get with sld in post body, layers
// are not parsed, so we can't parse filters neither...
if (request.getLayers() == null) {
return;
}
int numLayers = request.getLayers().length;
if (numLayers == 0) {
throw new RuntimeException(
"parseFilterParam must be called after the layer list has been built!");
}
List filters = null;
// if no filter, no need to proceed
if ((rawFilter != null) && !rawFilter.equals("")) {
try {
filters = readOGCFilter(rawFilter);
} catch (ServiceException e) {
throw new WmsException(e);
}
}
if ((rawIdFilter != null) && !rawIdFilter.equals("")) {
if (filters != null) {
throw new WmsException("GetMap KVP request contained "
+ "conflicting filters. Filter: " + rawFilter
+ ", fid: " + rawFilter);
}
filters = readFidFilters(rawIdFilter);
}
if ((rawCqlFilter != null) && !rawCqlFilter.equals("")) {
if (filters != null) {
throw new WmsException("GetMap KVP request contained "
+ "conflicting filters. Filter: " + rawFilter
+ ", fid: " + rawFilter + ", cql: " + rawCqlFilter);
}
try {
filters = readCQLFilter(rawCqlFilter);
} catch (ServiceException e) {
throw new WmsException(e);
}
}
if (filters == null) {
return;
}
if (numLayers != filters.size()) {
// as in wfs getFeatures, perform lenient parsing, if just one
// filter, it gets
// applied to all layers
if (filters.size() == 1) {
Filter f = (Filter) filters.get(0);
filters = new ArrayList(numLayers);
for (int i = 0; i < numLayers; i++) {
filters.add(f);
}
} else {
String msg = numLayers
+ " layers requested, but found "
+ filters.size()
+ " filters specified. "
+ "When you specify the FILTER parameter, you must provide just one, \n"
+ " that will be applied to all layers, or exactly one for each requested layer";
throw new WmsException(msg, getClass().getName());
}
}
request.setFilters(filters);
}
/**
* DOCUMENT ME!
*
* @param request
* DOCUMENT ME!
*
* @throws WmsException
* DOCUMENT ME!
*/
protected void parseSldParam(GetMapRequest request) throws WmsException {
String urlValue = getValue("SLD");
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER
.fine(new StringBuffer(
"about to load remote SLD document: '").append(
urlValue).append("'").toString());
}
URL sldUrl;
try {
sldUrl = new URL(fixURL(urlValue));
} catch (MalformedURLException e) {
String msg = new StringBuffer("Creating remote SLD url: ").append(
e.getMessage()).toString();
if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.log(Level.WARNING, msg, e);
}
throw new WmsException(e, msg, "parseSldParam");
}
if (getValue("VALIDATESCHEMA") != null) {
// user requested to validate the schema.
SLDValidator validator = new SLDValidator();
List errors = null;
try {
// JD: GEOS-420, Wrap the sldUrl in getINputStream method in
// order
// to do compression
InputStream in = getInputStream(sldUrl);
errors = validator.validateSLD(in, request
.getHttpServletRequest().getSession()
.getServletContext());
in.close();
if (errors.size() != 0) {
throw new WmsException(SLDValidator.getErrorMessage(sldUrl
.openStream(), errors));
}
} catch (IOException e) {
String msg = new StringBuffer("Creating remote SLD url: ")
.append(e.getMessage()).toString();
if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.log(Level.WARNING, msg, e);
}
throw new WmsException(e, msg, "parseSldParam");
}
}
SLDParser parser;
try {
// JD: GEOS-420, Wrap the sldUrl in getINputStream method in order
// to do compression
parser = new SLDParser(styleFactory, getInputStream(sldUrl));
} catch (IOException e) {
String msg = new StringBuffer("Creating remote SLD url: ").append(
e.getMessage()).toString();
if (LOGGER.isLoggable(Level.WARNING)) {
LOGGER.log(Level.WARNING, msg, e);
}
throw new WmsException(e, msg, "parseSldParam");
}
StyledLayerDescriptor sld = parser.parseSLD();
parseStyledLayerDescriptor(request, sld);
}
/**
* URLEncoder.encode does not respect the RFC 2396, so we rolled our own
* little encoder. It's not complete, but should work in most cases
*
* @param url
* @return
*/
static String fixURL(String url) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < url.length(); i++) {
char c = url.charAt(i);
// From RFC, "Only alphanumerics [0-9a-zA-Z], the special
// characters "$-_.+!*'(),", and reserved characters used
// for their reserved purposes may be used unencoded within a URL
// Here we keep all the good ones, and remove the few uneeded in
// their
// ascii range. We also keep / and : to make sure basic URL elements
// don't get encoded
if ((c > ' ') && (c < '{') && ("\"\\<>%^[]`+$,".indexOf(c) == -1)) {
sb.append(c);
} else {
sb.append("%").append(Integer.toHexString(c));
}
}
return sb.toString();
}
/**
* Looks in <code>sld</code> for the layers and styles to use in the map
* composition and sets them to the <code>request</code>
*
* <p>
* If <code>sld</code> is used in "library" mode, that is, the LAYERS
* param is also present, saying what layers must be taken in count, then
* only the layers from the LAYERS parameter are used and <code>sld</code>
* is used as a style library, which means that for each layer requested
* through LAYERS=..., if a style if found in it for that layer it is used,
* and if not, the layers default is used.
* </p>
*
* <p>
* By the other hand, if the LAYERS parameter is not present all the layers
* found in <code>sld</code> are setted to <code>request</code>.
* </p>
*
* @param request
* the GetMap request to which to set the layers and styles
* @param sld
* a SLD document to take layers and styles from, following the
* "literal" or "library" rule.
*
* @throws WmsException
* if anything goes wrong
* @throws RuntimeException
* DOCUMENT ME!
*/
private void parseStyledLayerDescriptor(final GetMapRequest request,
final StyledLayerDescriptor sld) throws WmsException {
MapLayerInfo[] libraryModeLayers = null;
if (null != getValue("LAYERS")) {
if (LOGGER.isLoggable(Level.INFO)) {
LOGGER.info("request comes in \"library\" mode");
}
libraryModeLayers = parseLayersParam(request);
}
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 = null;
Style currStyle = null;
if (null != libraryModeLayers) {
int lCount = libraryModeLayers.length;
for (int i = 0; i < lCount; i++) {
currLayer = libraryModeLayers[i];
if (currLayer.getType() == MapLayerInfo.TYPE_VECTOR) {
currStyle = findStyleOf(request, currLayer.getFeature(),
styledLayers);
} else if (currLayer.getType() == MapLayerInfo.TYPE_RASTER) {
try {
currStyle = findStyleOf(request,
currLayer.getFeature(), styledLayers);
} catch (WmsException wm) {
currStyle = findStyleOf(request,
currLayer.getFeature(), styledLayers);
if (currStyle == null) {
// nope, there's no default raster style. Give up.
throw new WmsException(
wm.getMessage()
+ " Also tried to use "
+ "the generic raster style 'raster', but it wasn't available.");
}
}
}
layers.add(currLayer);
styles.add(currStyle);
}
} else {
StyledLayer sl = null;
String layerName;
UserLayer ul;
for (int i = 0; i < slCount; i++) {
sl = styledLayers[i];
layerName = sl.getName();
if (null == layerName) {
throw new WmsException(
"A UserLayer without layer name was passed");
}
currLayer = new MapLayerInfo();
// handle the InLineFeature stuff
// TODO: add support for remote WFS here
if ((sl instanceof UserLayer)
&& ((((UserLayer) sl)).getInlineFeatureDatastore() != null)) {
// SPECIAL CASE - we make the temporary version
ul = ((UserLayer) sl);
try {
initializeInlineFeatureLayer(request, ul, currLayer);
} catch (Exception e) {
throw new WmsException(e);
}
} else {
try {
currLayer.setFeature(GetMapKvpReader.findFeatureLayer(
request, layerName));
} catch (WmsException e) {
currLayer.setCoverage(GetMapKvpReader
.findCoverageLayer(request, layerName));
}
}
if (currLayer.getType() == MapLayerInfo.TYPE_VECTOR) {
// currStyle = findStyleOf(request, currLayer,
// styledLayers); // DJB: this looks like a bug, we should
// get the style from styledLayers[i]
// the correct thing to do its grab the style from
// styledLayers[i]
// inside the styledLayers[i] will either be :
// a) nothing - in which case grab the layer's default style
// b) a set of:
// i) NameStyle -- grab it from the pre-loaded styles
// ii)UserStyle -- grab it from the sld the user uploaded
//
// NOTE: we're going to get a set of layer->style pairs for
// (b).
addStyles(request, currLayer, styledLayers[i], layers,
styles);
} else if (currLayer.getType() == MapLayerInfo.TYPE_RASTER) {
try {
addStyles(request, currLayer, styledLayers[i], layers,
styles);
} catch (WmsException wm) {
// hmm, well, the style they specified in the wms
// request
// wasn't found. Let's try the default raster style
// named 'raster'
currStyle = findStyle(request, "raster");
if (currStyle == null) {
// nope, there's no default raster style. Give up.
throw new WmsException(
wm.getMessage()
+ " Also tried to use "
+ "the generic raster style 'raster', but it wasn't available.");
}
layers.add(currLayer);
styles.add(currStyle);
}
}
}
}
request.setLayers((MapLayerInfo[]) layers
.toArray(new MapLayerInfo[layers.size()]));
request.setStyles(styles);
}
/**
* the correct thing to do its grab the style from styledLayers[i] inside
* the styledLayers[i] will either be : a) nothing - in which case grab the
* layer's default style b) a set of: i) NameStyle -- grab it from the
* pre-loaded styles ii)UserStyle -- grab it from the sld the user uploaded
*
* NOTE: we're going to get a set of layer->style pairs for (b). these are
* added to layers,styles
*
* NOTE: we also handle some featuretypeconstraints
*
* @param request
* @param currLayer
* @param layer
* @param layers
* @param styles
*/
public static void addStyles(GetMapRequest request, MapLayerInfo currLayer,
StyledLayer layer, List layers, List styles) throws WmsException {
if (currLayer == null) {
return; // protection
}
Style[] layerStyles = null;
FeatureTypeConstraint[] ftcs = null;
if (layer instanceof NamedLayer) {
ftcs = ((NamedLayer) layer).getLayerFeatureConstraints();
layerStyles = ((NamedLayer) layer).getStyles();
} else if (layer instanceof UserLayer) {
ftcs = ((UserLayer) layer).getLayerFeatureConstraints();
layerStyles = ((UserLayer) layer).getUserStyles();
}
// DJB: TODO: this needs to do the whole thing, not just names
if (ftcs != null) {
FeatureTypeConstraint ftc;
final int length = ftcs.length;
for (int t = 0; t < length; t++) {
ftc = ftcs[t];
if (ftc.getFeatureTypeName() != null) {
String ftc_name = ftc.getFeatureTypeName();
// taken from lite renderer
boolean matches;
try {
matches = currLayer.getFeature().getFeatureType()
.isDescendedFrom(null, ftc_name)
|| currLayer.getFeature().getFeatureType()
.getTypeName().equalsIgnoreCase(
ftc_name);
} catch (Exception e) {
matches = false; // bad news
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -