From 1bdef9f1a52744323785f5c430a606174f2c0087 Mon Sep 17 00:00:00 2001 From: Lyn Goltz Date: Wed, 2 Dec 2015 21:44:21 +0100 Subject: [PATCH 001/135] throw exception if request crs is not supported --- .../org/deegree/protocol/wms/ops/GetMap.java | 16 +++++++++++++++- .../org/deegree/services/wms/MapService.java | 18 ++++++++++++++---- .../services/wms/controller/WMSController.java | 3 +++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetMap.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetMap.java index ed3e3b6bfe..1d29d94f2e 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetMap.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetMap.java @@ -109,6 +109,8 @@ public class GetMap extends RequestBase { private ICRS crs; + private ICRS requestCrs; + private Envelope bbox; private String format; @@ -175,6 +177,7 @@ public GetMap( Collection layers, Collection styles, int wid this.width = width; this.height = height; this.bbox = boundingBox; + this.requestCrs = boundingBox.getCoordinateSystem(); this.crs = boundingBox.getCoordinateSystem(); this.bgcolor = white; format = "image/png"; @@ -198,6 +201,7 @@ public GetMap( List layers, int width, int height, Envelope envelope, IC this.width = width; this.height = height; this.bbox = envelope; + this.requestCrs = crs; this.crs = crs; this.format = format; this.transparent = transparent; @@ -211,6 +215,7 @@ public GetMap( List layers, List styles, int width, int heig this.width = width; this.height = height; this.bbox = envelope; + this.requestCrs = crs; this.crs = crs; this.format = format; this.transparent = transparent; @@ -235,6 +240,7 @@ public GetMap( List> layers, int width, int height, Envelop this.width = width; this.height = height; this.bbox = boundingBox; + this.requestCrs = boundingBox.getCoordinateSystem(); this.crs = boundingBox.getCoordinateSystem(); this.bgcolor = white; this.format = format; @@ -257,6 +263,7 @@ private void parse111( Map map, MapOptionsMaps exts ) if ( c == null || c.trim().isEmpty() ) { throw new OWSException( "The SRS parameter is missing.", OWSException.MISSING_PARAMETER_VALUE ); } + requestCrs = CRSManager.getCRSRef( c ); crs = getCRS111( c ); String box = map.get( "BBOX" ); @@ -579,7 +586,7 @@ private void parse130( Map map, MapOptionsMaps exts ) throw new OWSException( "The maxy component of the BBOX was smaller that the miny component.", OWSException.INVALID_PARAMETER_VALUE ); } - + requestCrs = CRSManager.getCRSRef( c ); bbox = getCRSAndEnvelope130( c, vals ); crs = bbox.getCoordinateSystem(); @@ -593,6 +600,13 @@ public ICRS getCoordinateSystem() { return crs; } + /** + * @return the requested coordinate system + */ + public ICRS getRequestCoordinateSystem() { + return requestCrs; + } + /** * @return the bbox */ diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java index dd009e9f84..00cdd28e5b 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java @@ -57,6 +57,7 @@ import org.deegree.commons.annotations.LoggingNotes; import org.deegree.commons.ows.exception.OWSException; import org.deegree.commons.utils.Pair; +import org.deegree.cs.coordinatesystems.ICRS; import org.deegree.feature.Feature; import org.deegree.feature.FeatureCollection; import org.deegree.feature.Features; @@ -187,6 +188,14 @@ public boolean hasTheme( String name ) { return themeMap.get( name ) != null; } + public boolean isCrsSupported( String name, ICRS requestedCrs ) { + Theme theme = themeMap.get( name ); + if ( theme == null ) + return false; + List supportedCrs = theme.getLayerMetadata().getSpatialMetadata().getCoordinateSystems(); + return supportedCrs.contains( requestedCrs ); + } + public void getMap( org.deegree.protocol.wms.ops.GetMap gm, List headers, RenderContext ctx ) throws OWSException { Iterator styleItr = gm.getStyles().iterator(); @@ -292,11 +301,11 @@ public FeatureCollection getFeatures( org.deegree.protocol.wms.ops.GetFeatureInf || l.getMetadata().getScaleDenominators().second < scale ) { continue; } - - if (!l.getMetadata().isQueryable()) { + + if ( !l.getMetadata().isQueryable() ) { continue; } - + list.add( l.infoQuery( query, headers ) ); } } @@ -373,7 +382,8 @@ public Pair getLegendSize( Style style ) { return getLegendHandler.getLegendSize( style ); } - public BufferedImage getLegend( GetLegendGraphic req ) throws OWSException { + public BufferedImage getLegend( GetLegendGraphic req ) + throws OWSException { return getLegendHandler.getLegend( req ); } diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java index 3b29ddfb6c..681afadcea 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java @@ -534,6 +534,9 @@ private void checkGetMap( Version version, org.deegree.protocol.wms.ops.GetMap g throw new OWSException( "The layer with name " + lr.getName() + " is not defined.", "LayerNotDefined", "layers" ); } + if ( !service.isCrsSupported( lr.getName(), gm.getRequestCoordinateSystem() ) ) { + controllers.get( version ).throwSRSException( gm.getCoordinateSystem().getAlias() ); + } } for ( StyleRef sr : gm.getStyles() ) { // TODO check style availability here instead of the layer From 9235a6e02720bbc2bc2d32a98c509e5677b5376c Mon Sep 17 00:00:00 2001 From: Lyn Goltz Date: Thu, 3 Dec 2015 08:11:18 +0100 Subject: [PATCH 002/135] added check for crs support in GetFeatureInfo request processing --- .../deegree/protocol/wms/ops/GetFeatureInfo.java | 15 ++++++++++++++- .../services/wms/controller/WMSController.java | 5 ++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java index 907068d2bc..6a988e6ef7 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java @@ -58,6 +58,7 @@ import org.deegree.commons.ows.exception.OWSException; import org.deegree.commons.tom.ows.Version; import org.deegree.cs.coordinatesystems.ICRS; +import org.deegree.cs.persistence.CRSManager; import org.deegree.geometry.Envelope; import org.deegree.geometry.GeometryFactory; import org.deegree.layer.LayerRef; @@ -79,6 +80,8 @@ public class GetFeatureInfo extends RequestBase { private static final GeometryFactory fac = new GeometryFactory(); + private ICRS requestCrs; + private ICRS crs; private Envelope bbox; @@ -128,6 +131,7 @@ public GetFeatureInfo( List layers, int width, int height, int x, int y, this.x = x; this.y = y; this.bbox = envelope; + this.requestCrs = crs; this.crs = crs; this.featureCount = featureCount; scale = RenderHelper.calcScaleWMS130( width, height, bbox, crs, DEFAULT_PIXEL_SIZE ); @@ -144,6 +148,7 @@ public GetFeatureInfo( List layers, List styles, List map ) if ( c == null || c.trim().isEmpty() ) { throw new OWSException( "The SRS parameter is missing.", OWSException.MISSING_PARAMETER_VALUE ); } + requestCrs = CRSManager.getCRSRef( c ); crs = GetMap.getCRS111( c ); - bbox = fac.createEnvelope( new double[] { vals[0], vals[1] }, new double[] { vals[2], vals[3] }, crs ); String xs = map.get( "X" ); @@ -194,6 +199,7 @@ private void parse130( Map map ) throw new OWSException( "The CRS parameter is missing.", MISSING_PARAMETER_VALUE ); } + requestCrs = CRSManager.getCRSRef( c ); bbox = GetMap.getCRSAndEnvelope130( c, vals ); crs = bbox.getCoordinateSystem(); @@ -363,6 +369,13 @@ public ICRS getCoordinateSystem() { return crs; } + /** + * @return the requested coordinate system + */ + public ICRS getRequestCoordinateSystem() { + return requestCrs; + } + /** * @param crs */ diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java index 681afadcea..61881fbc4f 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java @@ -504,6 +504,9 @@ private void checkGetFeatureInfo( Version version, org.deegree.protocol.wms.ops. throw new OWSException( "The layer with name " + lr.getName() + " is not defined.", "LayerNotDefined", "layers" ); } + if ( !service.isCrsSupported( lr.getName(), gfi.getRequestCoordinateSystem() ) ) { + controllers.get( version ).throwSRSException( gfi.getRequestCoordinateSystem().getAlias() ); + } } for ( StyleRef sr : gfi.getStyles() ) { // TODO check style availability @@ -535,7 +538,7 @@ private void checkGetMap( Version version, org.deegree.protocol.wms.ops.GetMap g "layers" ); } if ( !service.isCrsSupported( lr.getName(), gm.getRequestCoordinateSystem() ) ) { - controllers.get( version ).throwSRSException( gm.getCoordinateSystem().getAlias() ); + controllers.get( version ).throwSRSException( gm.getRequestCoordinateSystem().getAlias() ); } } for ( StyleRef sr : gm.getStyles() ) { From 6df9aa67747d31d5e36f1a1c9abcf094da0268ae Mon Sep 17 00:00:00 2001 From: Lyn Goltz Date: Thu, 3 Dec 2015 08:31:07 +0100 Subject: [PATCH 003/135] enhanced WMS configuration to configure if crs check should be strict --- .../deegree/services/wms/controller/WMSController.java | 9 +++++++-- .../schemas/services/wms/3.4.0/wms_configuration.xsd | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java index 61881fbc4f..3c5da63bcc 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java @@ -212,6 +212,8 @@ public class WMSController extends AbstractOWS { private DeegreeWMS conf; + private boolean isCrsCheckStrict = false; + private final GetMapLimitChecker getMapLimitChecker = new GetMapLimitChecker(); public WMSController( ResourceMetadata metadata, Workspace workspace, DeegreeWMS jaxbConfig ) { @@ -274,6 +276,9 @@ public void init( DeegreeServicesMetadataType serviceMetadata, DeegreeServiceCon } } + if ( conf.isCrsCheckStrict() != null ) + isCrsCheckStrict = conf.isCrsCheckStrict(); + try { addSupportedCapabilitiesFormats( conf ); addSupportedImageFormats( conf ); @@ -504,7 +509,7 @@ private void checkGetFeatureInfo( Version version, org.deegree.protocol.wms.ops. throw new OWSException( "The layer with name " + lr.getName() + " is not defined.", "LayerNotDefined", "layers" ); } - if ( !service.isCrsSupported( lr.getName(), gfi.getRequestCoordinateSystem() ) ) { + if ( isCrsCheckStrict && !service.isCrsSupported( lr.getName(), gfi.getRequestCoordinateSystem() ) ) { controllers.get( version ).throwSRSException( gfi.getRequestCoordinateSystem().getAlias() ); } } @@ -537,7 +542,7 @@ private void checkGetMap( Version version, org.deegree.protocol.wms.ops.GetMap g throw new OWSException( "The layer with name " + lr.getName() + " is not defined.", "LayerNotDefined", "layers" ); } - if ( !service.isCrsSupported( lr.getName(), gm.getRequestCoordinateSystem() ) ) { + if ( isCrsCheckStrict && !service.isCrsSupported( lr.getName(), gm.getRequestCoordinateSystem() ) ) { controllers.get( version ).throwSRSException( gm.getRequestCoordinateSystem().getAlias() ); } } diff --git a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd index 307a161cb3..75c2f13f57 100644 --- a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd +++ b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd @@ -47,6 +47,7 @@ + From 1d5f11cdf285b5c0d1366bf40e5f11b1b04afc80 Mon Sep 17 00:00:00 2001 From: Lyn Goltz Date: Thu, 3 Dec 2015 08:44:42 +0100 Subject: [PATCH 004/135] enhanced documentation for new config option CrsCheckStrict --- .../src/main/sphinx/webservices.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst b/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst index 9ed7b3e3e1..6884792af6 100644 --- a/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst +++ b/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst @@ -397,6 +397,8 @@ The following table shows what top level options are available. +--------------------------+--------------+---------+------------------------------------------------------------------------------+ | MaxHeight | 0..1 | Integer | Maximum height in a GetMap request, default: unlimited | +--------------------------+--------------+---------+------------------------------------------------------------------------------+ +| CrsCheckStrict | 0..1 | Boolean | Configures if the check of the CRS should be strict or not, default: false | ++--------------------------+--------------+---------+------------------------------------------------------------------------------+ ^^^^^^^^^^^^^ @@ -406,6 +408,7 @@ Basic options * ``SupportedVersions``: By default, all implemented WMS protocol versions (1.1.1 and 1.3.0) are activated. You can control offered WMS protocol versions using the element ``SupportedVersions``. This element allows any of the child elements ``1.1.1`` and ``1.3.0``. * ``MetadataStoreId``: If set to a valid metadata store, the store is queried upon startup with all configured layer metadata set ids. If a metadata set does not exist in the metadata store, it will not be exported as metadata URL in the capabilties. This is a useful option if you want to automatically check for configuration errors/typos. By default, no checking is done. * ``MetadataURLTemplate``: By default, no metadata URLs are generated for layers in the capabilities. You can set this option either to a unique URL, which will be exported as is, or to a template with a placeholder. In any case, a metadata URL will only be exported if the layer has a metadata set id set. A template looks like this: http://discovery.eu/csw?service=CSW&request=GetRecordById&version=2.0.2&id=${metadataSetId}&outputSchema=http://www.isotc211.org/2005/gmd&elementSetName=full. Please note that you'll need to escape the & symbols with & as shown in the example. The ${metadataSetId} will be replaced with the metadata set id from each layer. +* ``CrsCheckStrict``: By default the requested CRS are limited by the CRS supported by deegree. Set this to false if an exception (with code InvalidCRS or InvalidSRS) should be thrown if the request CRS is not support by the layer. Here is a snippet for quick copy & paste: From 0b30829c55666468d4eeefcb1a2d5b675b769a3b Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Thu, 31 Mar 2016 14:50:25 +0200 Subject: [PATCH 005/135] enhanced RemoteWMSLayers configuration by ScaleDenominators config for each layer --- .../layer/persistence/remotewms/RemoteWmsLayerBuilder.java | 7 +++++++ .../META-INF/schemas/layers/remotewms/3.2.0/remotewms.xsd | 1 + 2 files changed, 8 insertions(+) diff --git a/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWmsLayerBuilder.java b/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWmsLayerBuilder.java index 3d326188c8..b8fa44d239 100644 --- a/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWmsLayerBuilder.java +++ b/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWmsLayerBuilder.java @@ -48,11 +48,13 @@ Occam Labs UG (haftungsbeschränkt) import org.deegree.commons.ows.metadata.Description; import org.deegree.commons.ows.metadata.DescriptionConverter; +import org.deegree.commons.utils.DoublePair; import org.deegree.geometry.metadata.SpatialMetadata; import org.deegree.geometry.metadata.SpatialMetadataConverter; import org.deegree.layer.Layer; import org.deegree.layer.config.ConfigUtils; import org.deegree.layer.metadata.LayerMetadata; +import org.deegree.layer.persistence.base.jaxb.ScaleDenominatorsType; import org.deegree.layer.persistence.remotewms.jaxb.LayerType; import org.deegree.layer.persistence.remotewms.jaxb.RemoteWMSLayers; import org.deegree.layer.persistence.remotewms.jaxb.RequestOptionsType; @@ -100,7 +102,12 @@ Map buildLayerMap() { l.getDescription().getAbstract(), l.getDescription().getKeywords() ); } + LayerMetadata md = new LayerMetadata( name, desc, smd ); + ScaleDenominatorsType denoms = l.getScaleDenominators(); + if ( denoms != null ) { + md.setScaleDenominators( new DoublePair( denoms.getMin(), denoms.getMax() ) ); + } md.setMapOptions( ConfigUtils.parseLayerOptions( l.getLayerOptions() ) ); configured.put( l.getOriginalName(), md ); } diff --git a/deegree-layers/deegree-layers-remotewms/src/main/resources/META-INF/schemas/layers/remotewms/3.2.0/remotewms.xsd b/deegree-layers/deegree-layers-remotewms/src/main/resources/META-INF/schemas/layers/remotewms/3.2.0/remotewms.xsd index 5a0b74b95e..4b56d762df 100644 --- a/deegree-layers/deegree-layers-remotewms/src/main/resources/META-INF/schemas/layers/remotewms/3.2.0/remotewms.xsd +++ b/deegree-layers/deegree-layers-remotewms/src/main/resources/META-INF/schemas/layers/remotewms/3.2.0/remotewms.xsd @@ -42,6 +42,7 @@ + From 6797889f7a809cc0c1791a179a66d72255a636d5 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Thu, 12 May 2016 15:03:28 +0200 Subject: [PATCH 006/135] #182 - refactoring: implemented MapOptionsBuilder --- .../org/deegree/layer/config/ConfigUtils.java | 7 +- .../deegree/layer/metadata/LayerMetadata.java | 5 +- .../rendering/r2d/context/MapOptions.java | 101 ++++++++++++++++-- .../rendering/r2d/context/MapOptionsMaps.java | 30 +++--- .../services/wms/MapServiceBuilder.java | 8 +- .../theme/LayerMetadataMerger.java | 2 +- 6 files changed, 122 insertions(+), 31 deletions(-) diff --git a/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/config/ConfigUtils.java b/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/config/ConfigUtils.java index d65e538588..e22fcad4eb 100644 --- a/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/config/ConfigUtils.java +++ b/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/config/ConfigUtils.java @@ -243,7 +243,12 @@ public static MapOptions parseLayerOptions( LayerOptionsType cfg ) { } else if ( cfg.getFeatureInfoRadius() != null ) { rad = Math.max( 0, cfg.getFeatureInfoRadius() ); } - return new MapOptions( quali, interpol, alias, maxFeats, rad ); + return new MapOptions.Builder(). + quality( quali ). + interpolation( interpol ). + antialias( alias ). + maxFeatures( maxFeats ). + featureInfoRadius( rad ).build(); } public static Map> parseDimensions( String layerName, List dimensions ) { diff --git a/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/metadata/LayerMetadata.java b/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/metadata/LayerMetadata.java index a17aeee247..c0e79c6246 100644 --- a/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/metadata/LayerMetadata.java +++ b/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/metadata/LayerMetadata.java @@ -192,10 +192,9 @@ public void setQueryable( boolean queryable ) { mapOptions.setFeatureInfoRadius( 0 ); } } - } else if ( queryable ) { - mapOptions = new MapOptions( null, null, null, -1, 1 ); } else { - mapOptions = new MapOptions( null, null, null, -1, 0 ); + int featureInfoRadius = queryable ? 1 : 0; + mapOptions = new MapOptions.Builder().featureInfoRadius( featureInfoRadius ).build(); } } diff --git a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/MapOptions.java b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/MapOptions.java index f90ba31f87..143cdf11ea 100644 --- a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/MapOptions.java +++ b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/MapOptions.java @@ -52,8 +52,17 @@ public class MapOptions { private int featureInfoRadius; - public MapOptions( Quality quality, Interpolation interpol, Antialias antialias, int maxFeatures, - int featureInfoRadius ) { + /** + * Instantiates {@link MapOptions} with default values (quality = null, interpol = null, antialias = null, + * maxFeatures = -1, featureInfoRadius = -1) + * + */ + public MapOptions() { + this( null, null, null, -1, -1 ); + } + + private MapOptions( Quality quality, Interpolation interpol, Antialias antialias, int maxFeatures, + int featureInfoRadius ) { this.quality = quality; this.interpol = interpol; this.antialias = antialias; @@ -146,8 +155,10 @@ public void setFeatureInfoRadius( int featureInfoRadius ) { */ public static enum Quality { /***/ - LOW, /***/ - NORMAL, /***/ + LOW, + /***/ + NORMAL, + /***/ HIGH } @@ -161,9 +172,12 @@ public static enum Quality { */ public static enum Interpolation { /***/ - NEARESTNEIGHBOR, /***/ - NEARESTNEIGHBOUR, /***/ - BILINEAR, /***/ + NEARESTNEIGHBOR, + /***/ + NEARESTNEIGHBOUR, + /***/ + BILINEAR, + /***/ BICUBIC } @@ -177,9 +191,12 @@ public static enum Interpolation { */ public static enum Antialias { /***/ - IMAGE, /***/ - TEXT, /***/ - BOTH, /***/ + IMAGE, + /***/ + TEXT, + /***/ + BOTH, + /***/ NONE } @@ -244,4 +261,68 @@ public Interpolation getOption( String layer ) { } }; } + + public static class Builder { + + private Quality quality; + + private Interpolation interpolation; + + private Antialias antialias; + + private int maxFeatures; + + private int featureInfoRadius; + + /** + * @param quality + * the quality to set + */ + public Builder quality( Quality quality ) { + this.quality = quality; + return this; + } + + /** + * @param interpolation + * the interpolation to set + */ + public Builder interpolation( Interpolation interpolation ) { + this.interpolation = interpolation; + return this; + } + + /** + * @param antialias + * the antialias to set + */ + public Builder antialias( Antialias antialias ) { + this.antialias = antialias; + return this; + } + + /** + * @param maxFeatures + * the maxFeatures to set + */ + public Builder maxFeatures( int maxFeatures ) { + this.maxFeatures = maxFeatures; + return this; + } + + /** + * @param featureInfoRadius + * the featureInfoRadius to set, a value < 1 means default, 0 means disabled and > 0 for the radius + */ + public Builder featureInfoRadius( int featureInfoRadius ) { + this.featureInfoRadius = featureInfoRadius; + return this; + } + + public MapOptions build() { + return new MapOptions( quality, interpolation, antialias, maxFeatures, featureInfoRadius ); + } + + } + } diff --git a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/MapOptionsMaps.java b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/MapOptionsMaps.java index b60f3ddd89..89fc564e69 100644 --- a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/MapOptionsMaps.java +++ b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/MapOptionsMaps.java @@ -52,30 +52,28 @@ */ public class MapOptionsMaps { - private Map options; + private final Map options = new HashMap(); public MapOptionsMaps() { - options = new HashMap(); } public MapOptionsMaps( Map qualities, Map interpolations, Map antialiases, Map maxFeatures ) { - options = new HashMap(); for ( Entry e : qualities.entrySet() ) { - options.put( e.getKey(), new MapOptions( e.getValue(), null, null, -1, -1 ) ); + options.put( e.getKey(), new MapOptions.Builder().quality( e.getValue() ).build() ); } for ( Entry e : interpolations.entrySet() ) { if ( options.get( e.getKey() ) != null ) { options.get( e.getKey() ).setInterpolation( e.getValue() ); } else { - options.put( e.getKey(), new MapOptions( null, e.getValue(), null, -1, -1 ) ); + options.put( e.getKey(), new MapOptions.Builder().interpolation( e.getValue() ).build() ); } } for ( Entry e : antialiases.entrySet() ) { if ( options.get( e.getKey() ) != null ) { options.get( e.getKey() ).setAntialias( e.getValue() ); } else { - options.put( e.getKey(), new MapOptions( null, null, e.getValue(), -1, -1 ) ); + options.put( e.getKey(), new MapOptions.Builder().antialias( e.getValue() ).build() ); } } for ( Entry e : maxFeatures.entrySet() ) { @@ -110,7 +108,7 @@ public Interpolation getInterpolation( String layer ) { public void setMaxFeatures( String layer, int maxFeatures ) { if ( options.get( layer ) == null ) { - options.put( layer, new MapOptions( null, null, null, maxFeatures, -1 ) ); + options.put( layer, new MapOptions.Builder().maxFeatures( maxFeatures ).build() ); } else { options.get( layer ).setMaxFeatures( maxFeatures ); } @@ -118,7 +116,7 @@ public void setMaxFeatures( String layer, int maxFeatures ) { public void setFeatureInfoRadius( String layer, int radius ) { if ( options.get( layer ) == null ) { - options.put( layer, new MapOptions( null, null, null, -1, radius ) ); + options.put( layer, new MapOptions.Builder().featureInfoRadius( radius ).build() ); } else { options.get( layer ).setFeatureInfoRadius( radius ); } @@ -126,7 +124,7 @@ public void setFeatureInfoRadius( String layer, int radius ) { public void setQuality( String layer, Quality q ) { if ( options.get( layer ) == null ) { - options.put( layer, new MapOptions( q, null, null, -1, -1 ) ); + options.put( layer, new MapOptions.Builder().quality( q ).build() ); } else { options.get( layer ).setQuality( q ); } @@ -134,7 +132,7 @@ public void setQuality( String layer, Quality q ) { public void setInterpolation( String layer, Interpolation interpol ) { if ( options.get( layer ) == null ) { - options.put( layer, new MapOptions( null, interpol, null, -1, -1 ) ); + options.put( layer, new MapOptions.Builder().interpolation( interpol ).build() ); } else { options.get( layer ).setInterpolation( interpol ); } @@ -142,15 +140,19 @@ public void setInterpolation( String layer, Interpolation interpol ) { public void setAntialias( String layer, Antialias alias ) { if ( options.get( layer ) == null ) { - options.put( layer, new MapOptions( null, null, alias, -1, -1 ) ); + options.put( layer, new MapOptions.Builder().antialias( alias ).build() ); } else { options.get( layer ).setAntialias( alias ); } } public MapOptions get( String layer ) { - return new MapOptions( getQuality( layer ), getInterpolation( layer ), getAntialias( layer ), - getMaxFeatures( layer ), getFeatureInfoRadius( layer ) ); + return new MapOptions.Builder(). + quality( getQuality( layer ) ). + interpolation( getInterpolation( layer ) ). + antialias( getAntialias( layer ) ). + maxFeatures( getMaxFeatures( layer ) ). + featureInfoRadius( getFeatureInfoRadius( layer ) ).build(); } -} +} \ No newline at end of file diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapServiceBuilder.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapServiceBuilder.java index 75da3a4b3d..b504220165 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapServiceBuilder.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapServiceBuilder.java @@ -52,7 +52,6 @@ Occam Labs UG (haftungsbeschränkt) import org.deegree.rendering.r2d.context.MapOptions.Quality; import org.deegree.services.jaxb.wms.LayerOptionsType; import org.deegree.services.jaxb.wms.ServiceConfigurationType; -import org.deegree.workspace.Workspace; import org.slf4j.Logger; /** @@ -104,7 +103,12 @@ MapOptions buildMapOptions() { } else { LOG.debug( "Using default feature info radius of {}.", featureInfoRadius ); } - return new MapOptions( quali, interpol, alias, maxFeatures, featureInfoRadius ); + return new MapOptions.Builder(). + quality( quali ). + interpolation( interpol ). + antialias( alias ). + maxFeatures( maxFeatures). + featureInfoRadius( featureInfoRadius ).build(); } return null; } diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/theme/LayerMetadataMerger.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/theme/LayerMetadataMerger.java index 438e45f405..b392ece536 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/theme/LayerMetadataMerger.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/capabilities/theme/LayerMetadataMerger.java @@ -90,7 +90,7 @@ LayerMetadata merge( final Theme theme ) { themeMetadata.merge( layerMetadata ); if ( themeMetadata.getMapOptions() == null ) { - themeMetadata.setMapOptions( new MapOptions( null, null, null, -1, -1 ) ); + themeMetadata.setMapOptions( new MapOptions() ); } if ( queryable == QUERYABLE_DISABLED_MASK ) { From c0fafe5ac44b1165148610b50de2ff18c1b6d21b Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Thu, 12 May 2016 15:55:39 +0200 Subject: [PATCH 007/135] #181 - added copyright config option in WMS ServiceConfiguration --- .../META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd | 1 + 1 file changed, 1 insertion(+) diff --git a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd index fdb8a41242..55ba3ac26c 100644 --- a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd +++ b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd @@ -57,6 +57,7 @@ + From fd4ea6b7dbcc9151e892947c70ace97cde48a2fc Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Thu, 12 May 2016 15:56:24 +0200 Subject: [PATCH 008/135] #182 - render copyright --- .../r2d/context/Java2DRenderContext.java | 47 +++++++++++++------ .../r2d/context/LazyImageRenderContext.java | 7 +++ .../rendering/r2d/context/RenderContext.java | 4 +- .../org/deegree/services/wms/MapService.java | 5 ++ 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/Java2DRenderContext.java b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/Java2DRenderContext.java index 294598f55f..c9a3afec9a 100644 --- a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/Java2DRenderContext.java +++ b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/Java2DRenderContext.java @@ -1,5 +1,7 @@ package org.deegree.rendering.r2d.context; +import java.awt.Color; +import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.IOException; @@ -13,25 +15,25 @@ import org.deegree.rendering.r2d.labelplacement.AutoLabelPlacement; public abstract class Java2DRenderContext implements RenderContext { - + protected final Graphics2D graphics; - + protected final OutputStream outputStream; - + protected final Java2DRenderer renderer; protected final Java2DTextRenderer textRenderer; - + protected final Java2DLabelRenderer labelRenderer; protected final Java2DRasterRenderer rasterRenderer; protected final Java2DTileRenderer tileRenderer; - public Java2DRenderContext( RenderingInfo info, Graphics2D graphics, OutputStream outputStream ) { + public Java2DRenderContext( RenderingInfo info, Graphics2D graphics, OutputStream outputStream ) { this.graphics = graphics; this.outputStream = outputStream; - + renderer = new Java2DRenderer( graphics, info.getWidth(), info.getHeight(), info.getEnvelope(), info.getPixelSize() * 1000 ); textRenderer = new Java2DTextRenderer( renderer ); @@ -39,7 +41,7 @@ public Java2DRenderContext( RenderingInfo info, Graphics2D graphics, OutputStrea rasterRenderer = new Java2DRasterRenderer( graphics ); tileRenderer = new Java2DTileRenderer( graphics, info.getWidth(), info.getHeight(), info.getEnvelope() ); } - + @Override public Java2DRenderer getVectorRenderer() { return renderer; @@ -64,25 +66,40 @@ public Java2DRasterRenderer getRasterRenderer() { public Java2DTileRenderer getTileRenderer() { return tileRenderer; } - + @Override public void optimizeAndDrawLabels() { - //Optimize Label Placement here, if pointplacement set to auto=true - try{ - new AutoLabelPlacement(labelRenderer.getLabels(), renderer ); + // Optimize Label Placement here, if pointplacement set to auto=true + try { + new AutoLabelPlacement( labelRenderer.getLabels(), renderer ); } catch ( Throwable e ) { e.printStackTrace(); } - labelRenderer.render( ); + labelRenderer.render(); } - + @Override public void paintImage( BufferedImage img ) { graphics.drawImage( img, 0, 0, null ); } - + + @Override + public void paintCopyright( String copyright, int mapHeight ) { + if ( copyright != null ) { + graphics.setFont( new Font( "SANSSERIF", Font.PLAIN, 14 ) ); + graphics.setColor( Color.BLACK ); + graphics.drawString( copyright, 8, mapHeight - 15 ); + graphics.drawString( copyright, 10, mapHeight - 15 ); + graphics.drawString( copyright, 8, mapHeight - 13 ); + graphics.drawString( copyright, 10, mapHeight - 13 ); + graphics.setColor( Color.WHITE ); + graphics.setFont( new Font( "SANSSERIF", Font.PLAIN, 14 ) ); + graphics.drawString( copyright, 9, mapHeight - 14 ); + } + } + @Override - public boolean close() + public boolean close() throws IOException { graphics.dispose(); return true; diff --git a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/LazyImageRenderContext.java b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/LazyImageRenderContext.java index 43ae1fdba9..6f96f94d6c 100644 --- a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/LazyImageRenderContext.java +++ b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/LazyImageRenderContext.java @@ -98,6 +98,13 @@ public void paintImage( BufferedImage img ) { } } + @Override + public void paintCopyright( String copyright, int mapHeight ) { + LOG.trace( "Paint copyright" ); + + getRenderContext().paintCopyright( copyright, mapHeight ); + } + @Override public boolean close() throws IOException { diff --git a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/RenderContext.java b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/RenderContext.java index d3f9a36dad..406640a3ee 100644 --- a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/RenderContext.java +++ b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/RenderContext.java @@ -70,9 +70,11 @@ public interface RenderContext { void paintImage( BufferedImage img ); + void paintCopyright( String copyright, int mapHeight ); + boolean close() throws IOException; void applyOptions( MapOptions options ); -} +} \ No newline at end of file diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java index 5457bb83ee..a38a1373f3 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java @@ -111,6 +111,8 @@ public class MapService { HashMap themeMap; private final GetLegendHandler getLegendHandler; + + private String copyright; /** * @param conf @@ -146,6 +148,7 @@ public MapService( ServiceConfigurationType conf, Workspace workspace, int updat } } } + copyright = conf.getCopyright(); } getLegendHandler = new GetLegendHandler( this ); } @@ -220,6 +223,8 @@ public void getMap( org.deegree.protocol.wms.ops.GetMap gm, List headers } } ctx.optimizeAndDrawLabels(); + if ( copyright != null ) + ctx.paintCopyright( copyright, gm.getHeight() ); ScaleFunction.getCurrentScaleValue().remove(); } From 97164ecbf3ef73a5075b5214fbf0a392b2bb15af Mon Sep 17 00:00:00 2001 From: Dirk Stenger Date: Fri, 13 May 2016 10:49:15 +0200 Subject: [PATCH 009/135] Extended deegree handbook regarding copyright in GetMap response --- .../src/main/sphinx/webservices.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst b/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst index a0e31627db..574a669368 100644 --- a/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst +++ b/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst @@ -426,6 +426,20 @@ Here is a snippet for quick copy & paste: Service content configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The following table shows what options are available. + +.. table:: Service content configuration + ++---------------------+-------------+---------+-----------------------------------------------------------+ +| Option | Cardinality | Value | Description | ++=====================+=============+=========+===========================================================+ +| DefaultLayerOptions | 0..1 | Complex | Configure the behaviour of layers | ++---------------------+-------------+---------+-----------------------------------------------------------+ +| ThemeId | 0..n | String | Configure the WMS to use one or more preconfigured themes | ++---------------------+-------------+---------+-----------------------------------------------------------+ +| Copyright | 0..1 | String | Adds a watermark to image of GetMap response | ++---------------------+-------------+---------+-----------------------------------------------------------+ + You can configure the behaviour of layers using the ``DefaultLayerOptions`` element. Have a look at the layer options and their values: @@ -460,6 +474,8 @@ Here is an example snippet of the content section: mytheme + (c) deegree + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 6a512ac1c61b26c73329cd572c44fe69e23c3f12 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Thu, 30 Jun 2016 08:42:32 +0200 Subject: [PATCH 010/135] #191 - enhanced copyright configuration --- .../org/deegree/services/wms/MapService.java | 2 +- .../services/wms/3.4.0/wms_configuration.xsd | 21 ++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java index a38a1373f3..23bf6325a9 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java @@ -148,7 +148,7 @@ public MapService( ServiceConfigurationType conf, Workspace workspace, int updat } } } - copyright = conf.getCopyright(); + copyright = conf.getCopyright() != null ? conf.getCopyright().getText() : null; } getLegendHandler = new GetLegendHandler( this ); } diff --git a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd index 55ba3ac26c..7054426ee8 100644 --- a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd +++ b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/3.4.0/wms_configuration.xsd @@ -57,7 +57,7 @@ - + @@ -150,6 +150,25 @@ + + + Configure a copyright displayed in GetMap responses. A text or image + (via relative or absolute file reference or http url) can be configured. + Furthermore the position of the copyright can be specified with OffsetX/OffsetY (default is 8/13). + Anchor point in the GetMap response as well as the text or image is the lower-left corner. + + + + + + + + + + + + + From e8f80a1b5253bd0303be06ef0c386d4d69877df1 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Thu, 30 Jun 2016 10:23:33 +0200 Subject: [PATCH 011/135] #192 - implemented support of full copyright configuration (text or image; offsetX/offsetY) --- .../org/deegree/rendering/r2d/Copyright.java | 100 ++++++++++++++++++ .../r2d/context/Java2DRenderContext.java | 39 +++++-- .../r2d/context/LazyImageRenderContext.java | 3 +- .../rendering/r2d/context/RenderContext.java | 3 +- .../org/deegree/services/wms/MapService.java | 59 +++++++++-- .../wms/controller/WMSController.java | 2 +- 6 files changed, 187 insertions(+), 19 deletions(-) create mode 100644 deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/Copyright.java diff --git a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/Copyright.java b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/Copyright.java new file mode 100644 index 0000000000..cec7e64e1d --- /dev/null +++ b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/Copyright.java @@ -0,0 +1,100 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2015 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org +----------------------------------------------------------------------------*/ +package org.deegree.rendering.r2d; + +import java.awt.image.BufferedImage; + +/** + * Encapsulates a copyright image or text. + * + * @author Lyn Goltz + */ +public class Copyright { + + private final String copyrightText; + + private final BufferedImage copyrightImage; + + private final int offsetX; + + private final int offsetY; + + /** + * @param copyrightText + * the text of the copyright, may be null if an copyrightImage is not + * @param copyrightImage + * the text of the copyright, may be null if an copyrightImage is not + * @param offsetX + * the offset to draw the copyright from the left of the image to the left of the copyright + * @param offsetY + * the offset to draw the copyright from the bottom of the image to the bottom of the copyright + */ + public Copyright( String copyrightText, BufferedImage copyrightImage, int offsetX, int offsetY ) { + this.copyrightText = copyrightText; + this.copyrightImage = copyrightImage; + this.offsetX = offsetX; + this.offsetY = offsetY; + } + + /** + * @return the text of the copyright, may be null if an copyrightImage is not + */ + public String getCopyrightText() { + return copyrightText; + } + + /** + * @return the text of the copyright, may be null if an copyrightImage is not + */ + public BufferedImage getCopyrightImage() { + return copyrightImage; + } + + /** + * @return the offset to draw the copyright from the left of the image to the left of the copyright + */ + public int getOffsetX() { + return offsetX; + } + + /** + * @return the offset to draw the copyright from the bottom of the image to the bottom of the copyright + */ + public int getOffsetY() { + return offsetY; + } + +} \ No newline at end of file diff --git a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/Java2DRenderContext.java b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/Java2DRenderContext.java index c9a3afec9a..07eb7f88ef 100644 --- a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/Java2DRenderContext.java +++ b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/Java2DRenderContext.java @@ -6,7 +6,9 @@ import java.awt.image.BufferedImage; import java.io.IOException; import java.io.OutputStream; +import java.net.URL; +import org.deegree.rendering.r2d.Copyright; import org.deegree.rendering.r2d.Java2DLabelRenderer; import org.deegree.rendering.r2d.Java2DRasterRenderer; import org.deegree.rendering.r2d.Java2DRenderer; @@ -84,17 +86,17 @@ public void paintImage( BufferedImage img ) { } @Override - public void paintCopyright( String copyright, int mapHeight ) { + public void paintCopyright( Copyright copyright, int mapHeight ) { if ( copyright != null ) { - graphics.setFont( new Font( "SANSSERIF", Font.PLAIN, 14 ) ); - graphics.setColor( Color.BLACK ); - graphics.drawString( copyright, 8, mapHeight - 15 ); - graphics.drawString( copyright, 10, mapHeight - 15 ); - graphics.drawString( copyright, 8, mapHeight - 13 ); - graphics.drawString( copyright, 10, mapHeight - 13 ); - graphics.setColor( Color.WHITE ); - graphics.setFont( new Font( "SANSSERIF", Font.PLAIN, 14 ) ); - graphics.drawString( copyright, 9, mapHeight - 14 ); + String copyrightText = copyright.getCopyrightText(); + BufferedImage copyrightImage = copyright.getCopyrightImage(); + int offsetX = copyright.getOffsetX(); + int offsetY = copyright.getOffsetY(); + if ( copyrightText != null ) { + drawCopyrightText( copyrightText, offsetX, offsetY, mapHeight ); + } else if ( copyrightImage != null ) { + drawCopyrightImage( copyrightImage, offsetX, offsetY, mapHeight ); + } } } @@ -104,4 +106,21 @@ public boolean close() graphics.dispose(); return true; } + + private void drawCopyrightText( String copyright, int offsetX, int offsetY, int mapHeight ) { + graphics.setFont( new Font( "SANSSERIF", Font.PLAIN, 14 ) ); + graphics.setColor( Color.BLACK ); + graphics.drawString( copyright, offsetX, mapHeight - offsetY + 2 ); + graphics.drawString( copyright, offsetX + 2, mapHeight - offsetY + 2 ); + graphics.drawString( copyright, offsetX, mapHeight - offsetY ); + graphics.drawString( copyright, offsetX + 2, mapHeight - offsetY ); + graphics.setColor( Color.WHITE ); + graphics.setFont( new Font( "SANSSERIF", Font.PLAIN, 14 ) ); + graphics.drawString( copyright, offsetX + 1, mapHeight - offsetY + 1 ); + } + + private void drawCopyrightImage( BufferedImage copyrightImage, int offsetX, int offsetY, int mapHeight ) { + int y = mapHeight - copyrightImage.getHeight() - offsetY; + graphics.drawImage( copyrightImage, offsetX, y, null ); + } } diff --git a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/LazyImageRenderContext.java b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/LazyImageRenderContext.java index 6f96f94d6c..3032619e9a 100644 --- a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/LazyImageRenderContext.java +++ b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/LazyImageRenderContext.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.io.OutputStream; +import org.deegree.rendering.r2d.Copyright; import org.deegree.rendering.r2d.LabelRenderer; import org.deegree.rendering.r2d.RasterRenderer; import org.deegree.rendering.r2d.Renderer; @@ -99,7 +100,7 @@ public void paintImage( BufferedImage img ) { } @Override - public void paintCopyright( String copyright, int mapHeight ) { + public void paintCopyright( Copyright copyright, int mapHeight ) { LOG.trace( "Paint copyright" ); getRenderContext().paintCopyright( copyright, mapHeight ); diff --git a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/RenderContext.java b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/RenderContext.java index 406640a3ee..1ee5fc53cc 100644 --- a/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/RenderContext.java +++ b/deegree-core/deegree-core-rendering-2d/src/main/java/org/deegree/rendering/r2d/context/RenderContext.java @@ -41,6 +41,7 @@ import org.deegree.rendering.r2d.RasterRenderer; import org.deegree.rendering.r2d.Renderer; import org.deegree.rendering.r2d.TextRenderer; +import org.deegree.rendering.r2d.Copyright; import org.deegree.rendering.r2d.LabelRenderer; import org.deegree.rendering.r2d.TileRenderer; @@ -70,7 +71,7 @@ public interface RenderContext { void paintImage( BufferedImage img ); - void paintCopyright( String copyright, int mapHeight ); + void paintCopyright( Copyright copyright, int mapHeight ); boolean close() throws IOException; diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java index 23bf6325a9..4e9651945d 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/MapService.java @@ -45,7 +45,9 @@ import java.awt.Color; import java.awt.image.BufferedImage; +import java.io.IOException; import java.net.MalformedURLException; +import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -54,6 +56,8 @@ import java.util.List; import java.util.ListIterator; +import javax.imageio.ImageIO; + import org.deegree.commons.annotations.LoggingNotes; import org.deegree.commons.ows.exception.OWSException; import org.deegree.commons.utils.Pair; @@ -70,9 +74,12 @@ import org.deegree.protocol.wms.filter.ScaleFunction; import org.deegree.protocol.wms.ops.GetFeatureInfoSchema; import org.deegree.protocol.wms.ops.GetLegendGraphic; +import org.deegree.rendering.r2d.Copyright; import org.deegree.rendering.r2d.context.MapOptions; import org.deegree.rendering.r2d.context.MapOptionsMaps; import org.deegree.rendering.r2d.context.RenderContext; +import org.deegree.services.OWS; +import org.deegree.services.jaxb.wms.CopyrightType; import org.deegree.services.jaxb.wms.ServiceConfigurationType; import org.deegree.style.StyleRef; import org.deegree.style.se.unevaluated.Style; @@ -80,6 +87,7 @@ import org.deegree.theme.Theme; import org.deegree.theme.Themes; import org.deegree.theme.persistence.ThemeProvider; +import org.deegree.workspace.ResourceMetadata; import org.deegree.workspace.Workspace; import org.slf4j.Logger; @@ -111,16 +119,17 @@ public class MapService { HashMap themeMap; private final GetLegendHandler getLegendHandler; - - private String copyright; + + private Copyright copyright; /** * @param conf + * @param metadata * @param adapter * @throws MalformedURLException */ - public MapService( ServiceConfigurationType conf, Workspace workspace, int updateSequence ) - throws MalformedURLException { + public MapService( ServiceConfigurationType conf, Workspace workspace, ResourceMetadata metadata, + int updateSequence ) throws MalformedURLException { this.updateSequence = updateSequence; this.registry = new StyleRegistry(); @@ -148,7 +157,7 @@ public MapService( ServiceConfigurationType conf, Workspace workspace, int updat } } } - copyright = conf.getCopyright() != null ? conf.getCopyright().getText() : null; + copyright = parseCopyright( metadata, conf.getCopyright() ); } getLegendHandler = new GetLegendHandler( this ); } @@ -232,7 +241,7 @@ public void getMap( org.deegree.protocol.wms.ops.GetMap gm, List headers private List checkStyleValidAndBuildLayerDataList( org.deegree.protocol.wms.ops.GetMap gm, List headers, double scale, ListIterator queryIter ) - throws OWSException { + throws OWSException { List layerDataList = new ArrayList(); for ( LayerRef lr : gm.getLayers() ) { LayerQuery query = queryIter.next(); @@ -407,4 +416,42 @@ public int getCurrentUpdateSequence() { return updateSequence; } + private Copyright parseCopyright( ResourceMetadata metadata, CopyrightType copyright ) { + if ( copyright != null ) { + String copyrightText = copyright.getText(); + BufferedImage copyrightImage = parseCopyrightImage( metadata, copyright.getImage() ); + int offsetX = copyright.getOffsetX() != null ? copyright.getOffsetX() : 8; + int offsetY = copyright.getOffsetY() != null ? copyright.getOffsetY() : 13; + return new Copyright( copyrightText, copyrightImage, offsetX, offsetY ); + } + return null; + } + + private BufferedImage parseCopyrightImage( ResourceMetadata metadata, String image ) { + if ( image != null ) { + URL copyrightImageAsUrl = parseCopyrightImageAsUrl( metadata, image ); + if ( copyrightImageAsUrl != null ) { + try { + return ImageIO.read( copyrightImageAsUrl ); + } catch ( IOException e ) { + LOG.warn( "Could not read copyright as image from {}: {}", copyrightImageAsUrl, e.getMessage() ); + } + } + } + return null; + } + + private URL parseCopyrightImageAsUrl( ResourceMetadata metadata, String image ) { + URL url = metadata.getLocation().resolveToUrl( image ); + if ( url != null ) + return url; + try { + return new URL( image ); + } catch ( MalformedURLException e ) { + LOG.debug( "Could not resolve copyright {}.", image, e ); + } + LOG.warn( "Could not resolve copyright {}.", image ); + return null; + } + } diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java index 2a55971a79..248ad6461c 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java @@ -312,7 +312,7 @@ public void init( DeegreeServicesMetadataType serviceMetadata, DeegreeServiceCon ServiceConfigurationType sc = conf.getServiceConfiguration(); int capabilitiesVersion = conf.getUpdateSequence() != null ? conf.getUpdateSequence().intValue() : 0; - service = new MapService( sc, workspace, capabilitiesVersion ); + service = new MapService( sc, workspace, metadata, capabilitiesVersion ); // after the service knows what layers are available: handleMetadata( conf.getMetadataURLTemplate(), conf.getMetadataStoreId() ); From 393d5f1085a60f2c59a11938558160d796ef73d3 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Thu, 30 Jun 2016 10:45:03 +0200 Subject: [PATCH 012/135] #193 - documented configuration of the copyright --- .../src/main/sphinx/webservices.rst | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst b/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst index 574a669368..3848057da2 100644 --- a/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst +++ b/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst @@ -437,7 +437,7 @@ The following table shows what options are available. +---------------------+-------------+---------+-----------------------------------------------------------+ | ThemeId | 0..n | String | Configure the WMS to use one or more preconfigured themes | +---------------------+-------------+---------+-----------------------------------------------------------+ -| Copyright | 0..1 | String | Adds a watermark to image of GetMap response | +| Copyright | 0..1 | Complex | Adds a watermark to the image of GetMap response | +---------------------+-------------+---------+-----------------------------------------------------------+ You can configure the behaviour of layers using the ``DefaultLayerOptions`` element. @@ -474,10 +474,35 @@ Here is an example snippet of the content section: mytheme - (c) deegree - +.. table:: Copyright + ++----------+-------------+---------+----------------------------------------------------------------------------------------------------------------+ +| Option | Cardinality | Value | Description | ++==========+=============+=========+================================================================================================================+ +| Text | 0..1 | String | The text of the copyright. | ++----------+-------------+---------+----------------------------------------------------------------------------------------------------------------+ +| Image | 0..1 | String | An image used as copyright. May be a relative or absolute reference to a file or a http url. | ++----------+-------------+---------+----------------------------------------------------------------------------------------------------------------+ +| OffsetX | 0..1 | Integer | The offset from the left of the GetMap response image to the left of the copyright in pixel (default: 8). | ++----------+-------------+---------+----------------------------------------------------------------------------------------------------------------+ +| OffsetY | 0..1 | Integer | The offset from the bottom of the GetMap response image to the bottom of the copyright in pixel (default: 13). | ++----------+-------------+---------+----------------------------------------------------------------------------------------------------------------+ + + +Here is an example snippet of the content section: + +.. code-block:: xml + + + (c) deegree + 10 + 20 + + +At least one of Text or Image must be configured. OffsetX and OffsetY are optional, but if OffsetX is configured, OffsetY must be configured, too (and vice versa). + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Custom capabilities formats ^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 3dfce7a3fcfbbef1c5ff8ece959eaf8250874f58 Mon Sep 17 00:00:00 2001 From: Dirk Stenger Date: Thu, 30 Jun 2016 12:23:21 +0200 Subject: [PATCH 013/135] Updated description of copyright configuration in handbook --- .../src/main/sphinx/webservices.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst b/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst index 3848057da2..58e8100c4a 100644 --- a/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst +++ b/deegree-services/deegree-webservices-handbook/src/main/sphinx/webservices.rst @@ -476,6 +476,8 @@ Here is an example snippet of the content section: +The following table shows the Copyright configuration: + .. table:: Copyright +----------+-------------+---------+----------------------------------------------------------------------------------------------------------------+ @@ -490,8 +492,9 @@ Here is an example snippet of the content section: | OffsetY | 0..1 | Integer | The offset from the bottom of the GetMap response image to the bottom of the copyright in pixel (default: 13). | +----------+-------------+---------+----------------------------------------------------------------------------------------------------------------+ +At least one of Text or Image must be configured. OffsetX and OffsetY are optional, but if OffsetX is configured, OffsetY must be configured, too (and vice versa). -Here is an example snippet of the content section: +Here is an example snippet: .. code-block:: xml @@ -501,8 +504,6 @@ Here is an example snippet of the content section: 20 -At least one of Text or Image must be configured. OffsetX and OffsetY are optional, but if OffsetX is configured, OffsetY must be configured, too (and vice versa). - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Custom capabilities formats ^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 85cb749ec130d8e881aae4d7e695455c7df30a74 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Fri, 1 Jul 2016 14:27:31 +0200 Subject: [PATCH 014/135] #196 - added configuration option in RemoteLayerWMS to configure a xslt script transforming get feature info response from remote wms --- .../layers/remotewms/3.2.0/remotewms.xsd | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/deegree-layers/deegree-layers-remotewms/src/main/resources/META-INF/schemas/layers/remotewms/3.2.0/remotewms.xsd b/deegree-layers/deegree-layers-remotewms/src/main/resources/META-INF/schemas/layers/remotewms/3.2.0/remotewms.xsd index 5a0b74b95e..6e69530ea0 100644 --- a/deegree-layers/deegree-layers-remotewms/src/main/resources/META-INF/schemas/layers/remotewms/3.2.0/remotewms.xsd +++ b/deegree-layers/deegree-layers-remotewms/src/main/resources/META-INF/schemas/layers/remotewms/3.2.0/remotewms.xsd @@ -43,6 +43,15 @@ + + + + + + + + + @@ -53,6 +62,15 @@ + + + + + + + + + From bcef91822cd2743d13e4cfd9195bef20e61b78eb Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Fri, 1 Jul 2016 15:00:05 +0200 Subject: [PATCH 015/135] #197 - refactored FeatureInfoParser: removed static keyword from public method, extracted interface --- .../parsing/DefaultFeatureInfoParser.java | 233 ++++++++++++++++++ .../parsing/FeatureInfoParser.java | 202 +-------------- ...java => DefaultFeatureInfoParserTest.java} | 19 +- .../protocol/wms/client/WMSClient.java | 4 +- .../wmts/client/GetFeatureInfoResponse.java | 8 +- 5 files changed, 262 insertions(+), 204 deletions(-) create mode 100644 deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParser.java rename deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/{FeatureInfoParserTest.java => DefaultFeatureInfoParserTest.java} (81%) diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParser.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParser.java new file mode 100644 index 0000000000..ba1f959987 --- /dev/null +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParser.java @@ -0,0 +1,233 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2012 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + and + - Occam Labs UG (haftungsbeschränkt) - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + Occam Labs UG (haftungsbeschränkt) + Godesberger Allee 139, 53175 Bonn + Germany + + e-mail: info@deegree.org + ----------------------------------------------------------------------------*/ +package org.deegree.featureinfo.parsing; + +import static org.deegree.commons.tom.primitive.BaseType.STRING; +import static org.deegree.commons.xml.stax.XMLStreamUtils.nextElement; +import static org.deegree.commons.xml.stax.XMLStreamUtils.skipElement; +import static org.deegree.gml.GMLInputFactory.createGMLStreamReader; +import static org.deegree.gml.GMLVersion.GML_2; +import static org.slf4j.LoggerFactory.getLogger; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.deegree.commons.tom.gml.property.Property; +import org.deegree.commons.tom.gml.property.PropertyType; +import org.deegree.commons.xml.XMLParsingException; +import org.deegree.commons.xml.stax.XMLStreamUtils; +import org.deegree.cs.exceptions.UnknownCRSException; +import org.deegree.feature.FeatureCollection; +import org.deegree.feature.GenericFeature; +import org.deegree.feature.GenericFeatureCollection; +import org.deegree.feature.property.SimpleProperty; +import org.deegree.feature.types.DynamicAppSchema; +import org.deegree.feature.types.GenericFeatureType; +import org.deegree.feature.types.property.SimplePropertyType; +import org.deegree.gml.GMLStreamReader; +import org.slf4j.Logger; + +/** + * Responsible for parsing 'feature collections', even if they are broken (eg. ESRI or UMN mapserver feature info + * responses). Used by the WMS and WMTS clients. Currently, ESRI, UMN mapserver, mywms and normal GML2 feature + * collections are supported. + * + * @author Andreas Schmitz + * @author last edited by: $Author: stranger $ + * + * @version $Revision: $, $Date: $ + */ +public class DefaultFeatureInfoParser implements FeatureInfoParser { + + private static final Logger LOG = getLogger( DefaultFeatureInfoParser.class ); + + @Override + public FeatureCollection parseAsFeatureCollection( XMLStreamReader xmlReader, String csvLayerNames ) + throws XMLStreamException { + try { + // yes, some versions use a namespace, some do not + if ( ( xmlReader.getNamespaceURI() == null || xmlReader.getNamespaceURI().isEmpty() || xmlReader.getNamespaceURI().equals( "http://www.esri.com/wms" ) ) + && xmlReader.getLocalName().equals( "FeatureInfoResponse" ) ) { + return readESRICollection( xmlReader, csvLayerNames ); + } + if ( ( xmlReader.getNamespaceURI() == null || xmlReader.getNamespaceURI().isEmpty() ) + && xmlReader.getLocalName().equals( "featureInfo" ) ) { + return readMyWMSCollection( xmlReader ); + } + if ( ( xmlReader.getNamespaceURI() == null || xmlReader.getNamespaceURI().isEmpty() ) + && xmlReader.getLocalName().equals( "msGMLOutput" ) ) { + return readUMNCollection( xmlReader ); + } + return readGml2FeatureCollection( xmlReader ); + } catch ( Exception e ) { + String msg = "Unable to parse WMS GetFeatureInfo response as feature collection: " + e.getMessage(); + throw new XMLStreamException( msg, e ); + } + } + + private FeatureCollection readGml2FeatureCollection( XMLStreamReader xmlReader ) + throws XMLStreamException, XMLParsingException, UnknownCRSException { + GMLStreamReader reader = createGMLStreamReader( GML_2, xmlReader ); + reader.setApplicationSchema( new DynamicAppSchema() ); + return reader.readFeatureCollection(); + } + + private FeatureCollection readESRICollection( XMLStreamReader reader, String idPrefix ) + throws XMLStreamException { + GenericFeatureCollection col = new GenericFeatureCollection(); + + int count = 0; + nextElement( reader ); + while ( reader.isStartElement() && reader.getLocalName().equals( "FIELDS" ) ) { + List props = new ArrayList( reader.getAttributeCount() ); + List propValues = new ArrayList( reader.getAttributeCount() ); + for ( int i = 0; i < reader.getAttributeCount(); ++i ) { + String name = reader.getAttributeLocalName( i ); + name = name.substring( name.lastIndexOf( "." ) + 1 ); + String value = reader.getAttributeValue( i ); + SimplePropertyType tp = new SimplePropertyType( new QName( name ), 0, 1, STRING, null, null ); + propValues.add( new SimpleProperty( tp, value ) ); + props.add( tp ); + } + GenericFeatureType ft = new GenericFeatureType( new QName( "feature" ), props, false ); + col.add( new GenericFeature( ft, idPrefix + "_esri_" + ++count, propValues, null ) ); + skipElement( reader ); + nextElement( reader ); + } + LOG.debug( "Found {} features.", col.size() ); + return col; + } + + private FeatureCollection readMyWMSCollection( XMLStreamReader reader ) + throws XMLStreamException { + GenericFeatureCollection col = new GenericFeatureCollection(); + + nextElement( reader ); + while ( reader.isStartElement() && reader.getLocalName().equals( "query_layer" ) ) { + + String ftName = reader.getAttributeValue( null, "name" ); + int count = 0; + + nextElement( reader ); + while ( reader.isStartElement() && reader.getLocalName().equals( "object" ) ) { + + List props = new ArrayList(); + List propValues = new ArrayList(); + + nextElement( reader ); + while ( !( reader.isEndElement() && reader.getLocalName().equals( "object" ) ) ) { + String name = reader.getLocalName(); + String value = reader.getElementText(); + SimplePropertyType tp = new SimplePropertyType( new QName( name ), 0, 1, STRING, null, null ); + propValues.add( new SimpleProperty( tp, value ) ); + props.add( tp ); + nextElement( reader ); + } + + GenericFeatureType ft = new GenericFeatureType( new QName( ftName ), props, false ); + col.add( new GenericFeature( ft, "ftName_" + ++count, propValues, null ) ); + nextElement( reader ); + } + nextElement( reader ); + } + return col; + } + + private FeatureCollection readUMNCollection( XMLStreamReader reader ) + throws XMLStreamException { + GenericFeatureCollection col = new GenericFeatureCollection(); + nextElement( reader ); + + String ftName = reader.getLocalName(); + String singleFeatureTagName = ftName.split( "_" )[0] + "_feature"; + + while ( reader.isStartElement() && reader.getLocalName().equals( ftName ) ) { + + int count = 0; + nextElement( reader ); + + // gml:name seems to be an optional element + if ( reader.getLocalName().equals( "name" ) ) { + skipElement( reader ); + reader.nextTag(); + } + + while ( reader.isStartElement() && reader.getLocalName().equals( singleFeatureTagName ) ) { + List props = new ArrayList(); + List propValues = new ArrayList(); + + nextElement( reader ); + while ( !( reader.isEndElement() && reader.getLocalName().equals( singleFeatureTagName ) ) ) { + + // Skip boundedBy + if ( reader.isStartElement() && reader.getLocalName().equals( "boundedBy" ) ) { + XMLStreamUtils.skipElement( reader ); + nextElement( reader ); + } + + // skip geometry + if ( reader.isStartElement() && reader.getLocalName().equals( "geometry" ) ) { + XMLStreamUtils.skipElement( reader ); + nextElement( reader ); + } + + String name = reader.getLocalName(); + String value = reader.getElementText(); + SimplePropertyType tp = new SimplePropertyType( new QName( name ), 0, 1, STRING, null, null ); + propValues.add( new SimpleProperty( tp, value ) ); + props.add( tp ); + nextElement( reader ); + } + GenericFeatureType ft = new GenericFeatureType( new QName( ftName ), props, false ); + col.add( new GenericFeature( ft, "ftName_" + ++count, propValues, null ) ); + nextElement( reader ); + } + nextElement( reader ); + } + return col; + } + +} diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/FeatureInfoParser.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/FeatureInfoParser.java index 4c71292cf5..1e439bc853 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/FeatureInfoParser.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/FeatureInfoParser.java @@ -1,12 +1,10 @@ //$HeadURL$ /*---------------------------------------------------------------------------- This file is part of deegree, http://deegree.org/ - Copyright (C) 2001-2012 by: + Copyright (C) 2001-2015 by: - Department of Geography, University of Bonn - and - lat/lon GmbH - - and - - Occam Labs UG (haftungsbeschränkt) - This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free @@ -33,209 +31,33 @@ Germany http://www.geographie.uni-bonn.de/deegree/ - Occam Labs UG (haftungsbeschränkt) - Godesberger Allee 139, 53175 Bonn - Germany - e-mail: info@deegree.org - ----------------------------------------------------------------------------*/ +----------------------------------------------------------------------------*/ package org.deegree.featureinfo.parsing; -import static org.deegree.commons.tom.primitive.BaseType.STRING; -import static org.deegree.commons.xml.stax.XMLStreamUtils.nextElement; -import static org.deegree.commons.xml.stax.XMLStreamUtils.skipElement; -import static org.deegree.gml.GMLInputFactory.createGMLStreamReader; -import static org.deegree.gml.GMLVersion.GML_2; -import static org.slf4j.LoggerFactory.getLogger; - -import java.util.ArrayList; -import java.util.List; - -import javax.xml.namespace.QName; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; -import org.deegree.commons.tom.gml.property.Property; -import org.deegree.commons.tom.gml.property.PropertyType; -import org.deegree.commons.xml.XMLParsingException; -import org.deegree.commons.xml.stax.XMLStreamUtils; -import org.deegree.cs.exceptions.UnknownCRSException; import org.deegree.feature.FeatureCollection; -import org.deegree.feature.GenericFeature; -import org.deegree.feature.GenericFeatureCollection; -import org.deegree.feature.property.SimpleProperty; -import org.deegree.feature.types.DynamicAppSchema; -import org.deegree.feature.types.GenericFeatureType; -import org.deegree.feature.types.property.SimplePropertyType; -import org.deegree.gml.GMLStreamReader; -import org.slf4j.Logger; /** - * Responsible for parsing 'feature collections', even if they are broken (eg. ESRI or UMN mapserver feature info - * responses). Used by the WMS and WMTS clients. Currently, ESRI, UMN mapserver, mywms and normal GML2 feature - * collections are supported. - * - * @author Andreas Schmitz - * @author last edited by: $Author: stranger $ + * Responsible for parsing 'feature collections'. * - * @version $Revision: $, $Date: $ + * @author Lyn Goltz */ -public class FeatureInfoParser { - - private static final Logger LOG = getLogger( FeatureInfoParser.class ); +public interface FeatureInfoParser { /** * @param xmlReader - * input XML stream + * input XML stream to parse, never null * @param csvLayerNames - * a comma separated list of layer names - * @return all features that could be reconstructed or synthesized + * a comma separated list of layer names, should not be null + * @return a feature collection containingall features that could be reconstructed or synthesized, never + * null * @throws XMLStreamException * if the content could not be parsed as feature collection */ - public static FeatureCollection parseAsFeatureCollection( XMLStreamReader xmlReader, String csvLayerNames ) - throws XMLStreamException { - try { - // yes, some versions use a namespace, some do not - if ( ( xmlReader.getNamespaceURI() == null || xmlReader.getNamespaceURI().isEmpty() || xmlReader.getNamespaceURI().equals( "http://www.esri.com/wms" ) ) - && xmlReader.getLocalName().equals( "FeatureInfoResponse" ) ) { - return readESRICollection( xmlReader, csvLayerNames ); - } - if ( ( xmlReader.getNamespaceURI() == null || xmlReader.getNamespaceURI().isEmpty() ) - && xmlReader.getLocalName().equals( "featureInfo" ) ) { - return readMyWMSCollection( xmlReader ); - } - if ( ( xmlReader.getNamespaceURI() == null || xmlReader.getNamespaceURI().isEmpty() ) - && xmlReader.getLocalName().equals( "msGMLOutput" ) ) { - return readUMNCollection( xmlReader ); - } - return readGml2FeatureCollection( xmlReader ); - } catch ( Exception e ) { - String msg = "Unable to parse WMS GetFeatureInfo response as feature collection: " + e.getMessage(); - throw new XMLStreamException( msg, e ); - } - } - - private static FeatureCollection readGml2FeatureCollection( XMLStreamReader xmlReader ) - throws XMLStreamException, XMLParsingException, UnknownCRSException { - GMLStreamReader reader = createGMLStreamReader( GML_2, xmlReader ); - reader.setApplicationSchema( new DynamicAppSchema() ); - return reader.readFeatureCollection(); - } - - private static FeatureCollection readESRICollection( XMLStreamReader reader, String idPrefix ) - throws XMLStreamException { - GenericFeatureCollection col = new GenericFeatureCollection(); - - int count = 0; - nextElement( reader ); - while ( reader.isStartElement() && reader.getLocalName().equals( "FIELDS" ) ) { - List props = new ArrayList( reader.getAttributeCount() ); - List propValues = new ArrayList( reader.getAttributeCount() ); - for ( int i = 0; i < reader.getAttributeCount(); ++i ) { - String name = reader.getAttributeLocalName( i ); - name = name.substring( name.lastIndexOf( "." ) + 1 ); - String value = reader.getAttributeValue( i ); - SimplePropertyType tp = new SimplePropertyType( new QName( name ), 0, 1, STRING, null, null ); - propValues.add( new SimpleProperty( tp, value ) ); - props.add( tp ); - } - GenericFeatureType ft = new GenericFeatureType( new QName( "feature" ), props, false ); - col.add( new GenericFeature( ft, idPrefix + "_esri_" + ++count, propValues, null ) ); - skipElement( reader ); - nextElement( reader ); - } - LOG.debug( "Found {} features.", col.size() ); - return col; - } - - private static FeatureCollection readMyWMSCollection( XMLStreamReader reader ) - throws XMLStreamException { - GenericFeatureCollection col = new GenericFeatureCollection(); - - nextElement( reader ); - while ( reader.isStartElement() && reader.getLocalName().equals( "query_layer" ) ) { - - String ftName = reader.getAttributeValue( null, "name" ); - int count = 0; - - nextElement( reader ); - while ( reader.isStartElement() && reader.getLocalName().equals( "object" ) ) { - - List props = new ArrayList(); - List propValues = new ArrayList(); - - nextElement( reader ); - while ( !( reader.isEndElement() && reader.getLocalName().equals( "object" ) ) ) { - String name = reader.getLocalName(); - String value = reader.getElementText(); - SimplePropertyType tp = new SimplePropertyType( new QName( name ), 0, 1, STRING, null, null ); - propValues.add( new SimpleProperty( tp, value ) ); - props.add( tp ); - nextElement( reader ); - } - - GenericFeatureType ft = new GenericFeatureType( new QName( ftName ), props, false ); - col.add( new GenericFeature( ft, "ftName_" + ++count, propValues, null ) ); - nextElement( reader ); - } - nextElement( reader ); - } - return col; - } - - private static FeatureCollection readUMNCollection( XMLStreamReader reader ) - throws XMLStreamException { - GenericFeatureCollection col = new GenericFeatureCollection(); - nextElement( reader ); - - String ftName = reader.getLocalName(); - String singleFeatureTagName = ftName.split( "_" )[0] + "_feature"; - - while ( reader.isStartElement() && reader.getLocalName().equals( ftName ) ) { - - int count = 0; - nextElement( reader ); - - // gml:name seems to be an optional element - if ( reader.getLocalName().equals( "name" ) ) { - skipElement( reader ); - reader.nextTag(); - } - - while ( reader.isStartElement() && reader.getLocalName().equals( singleFeatureTagName ) ) { - List props = new ArrayList(); - List propValues = new ArrayList(); - - nextElement( reader ); - while ( !( reader.isEndElement() && reader.getLocalName().equals( singleFeatureTagName ) ) ) { - - // Skip boundedBy - if ( reader.isStartElement() && reader.getLocalName().equals( "boundedBy" ) ) { - XMLStreamUtils.skipElement( reader ); - nextElement( reader ); - } - - // skip geometry - if ( reader.isStartElement() && reader.getLocalName().equals( "geometry" ) ) { - XMLStreamUtils.skipElement( reader ); - nextElement( reader ); - } - - String name = reader.getLocalName(); - String value = reader.getElementText(); - SimplePropertyType tp = new SimplePropertyType( new QName( name ), 0, 1, STRING, null, null ); - propValues.add( new SimpleProperty( tp, value ) ); - props.add( tp ); - nextElement( reader ); - } - GenericFeatureType ft = new GenericFeatureType( new QName( ftName ), props, false ); - col.add( new GenericFeature( ft, "ftName_" + ++count, propValues, null ) ); - nextElement( reader ); - } - nextElement( reader ); - } - return col; - } + FeatureCollection parseAsFeatureCollection( XMLStreamReader xmlReader, String csvLayerNames ) + throws XMLStreamException; -} +} \ No newline at end of file diff --git a/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/FeatureInfoParserTest.java b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParserTest.java similarity index 81% rename from deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/FeatureInfoParserTest.java rename to deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParserTest.java index 940ea87f04..006c4066d3 100644 --- a/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/FeatureInfoParserTest.java +++ b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParserTest.java @@ -47,9 +47,8 @@ Occam Labs UG (haftungsbeschränkt) import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; -import junit.framework.Assert; - import org.deegree.feature.FeatureCollection; +import org.junit.Assert; import org.junit.Test; /** @@ -60,38 +59,40 @@ Occam Labs UG (haftungsbeschränkt) * * @version $Revision: $, $Date: $ */ -public class FeatureInfoParserTest { +public class DefaultFeatureInfoParserTest { + + private final DefaultFeatureInfoParser featureInfoParser = new DefaultFeatureInfoParser(); @Test public void testEsriCollection() throws XMLStreamException { - InputStream in = FeatureInfoParserTest.class.getResourceAsStream( "esri1.xml" ); + InputStream in = DefaultFeatureInfoParserTest.class.getResourceAsStream( "esri1.xml" ); XMLInputFactory fac = XMLInputFactory.newInstance(); XMLStreamReader xin = fac.createXMLStreamReader( in ); xin.next(); - FeatureCollection fc = FeatureInfoParser.parseAsFeatureCollection( xin, "test" ); + FeatureCollection fc = featureInfoParser.parseAsFeatureCollection( xin, "test" ); Assert.assertEquals( 1, fc.size() ); } @Test public void testEmptyEsriCollection() throws XMLStreamException { - InputStream in = FeatureInfoParserTest.class.getResourceAsStream( "esri2.xml" ); + InputStream in = DefaultFeatureInfoParserTest.class.getResourceAsStream( "esri2.xml" ); XMLInputFactory fac = XMLInputFactory.newInstance(); XMLStreamReader xin = fac.createXMLStreamReader( in ); xin.next(); - FeatureCollection fc = FeatureInfoParser.parseAsFeatureCollection( xin, "test" ); + FeatureCollection fc = featureInfoParser.parseAsFeatureCollection( xin, "test" ); Assert.assertEquals( 0, fc.size() ); } @Test public void testNamespacedEsriCollection() throws XMLStreamException { - InputStream in = FeatureInfoParserTest.class.getResourceAsStream( "esriwithnamespace.xml" ); + InputStream in = DefaultFeatureInfoParserTest.class.getResourceAsStream( "esriwithnamespace.xml" ); XMLInputFactory fac = XMLInputFactory.newInstance(); XMLStreamReader xin = fac.createXMLStreamReader( in ); xin.next(); - FeatureCollection fc = FeatureInfoParser.parseAsFeatureCollection( xin, "test" ); + FeatureCollection fc = featureInfoParser.parseAsFeatureCollection( xin, "test" ); Assert.assertEquals( 8, fc.size() ); } diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/client/WMSClient.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/client/WMSClient.java index 13016c700d..16bee9b89f 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/client/WMSClient.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/client/WMSClient.java @@ -96,7 +96,7 @@ import org.deegree.cs.coordinatesystems.ICRS; import org.deegree.cs.persistence.CRSManager; import org.deegree.feature.FeatureCollection; -import org.deegree.featureinfo.parsing.FeatureInfoParser; +import org.deegree.featureinfo.parsing.DefaultFeatureInfoParser; import org.deegree.geometry.Envelope; import org.deegree.geometry.GeometryFactory; import org.deegree.geometry.GeometryTransformer; @@ -349,7 +349,7 @@ public FeatureCollection doGetFeatureInfo( GetFeatureInfo request, Map Date: Fri, 1 Jul 2016 15:43:06 +0200 Subject: [PATCH 016/135] #197 - parse from input stream instead of xmlstream reader --- .../parsing/DefaultFeatureInfoParser.java | 8 +++++++- .../parsing/FeatureInfoParser.java | 9 +++++---- .../parsing/DefaultFeatureInfoParserTest.java | 19 ++++--------------- .../protocol/wms/client/WMSClient.java | 8 +++++--- .../wmts/client/GetFeatureInfoResponse.java | 8 +++++++- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParser.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParser.java index ba1f959987..c649f868b9 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParser.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParser.java @@ -48,10 +48,12 @@ Occam Labs UG (haftungsbeschränkt) import static org.deegree.gml.GMLVersion.GML_2; import static org.slf4j.LoggerFactory.getLogger; +import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; @@ -84,9 +86,13 @@ public class DefaultFeatureInfoParser implements FeatureInfoParser { private static final Logger LOG = getLogger( DefaultFeatureInfoParser.class ); + private static final XMLInputFactory XML_FACTORY = XMLInputFactory.newInstance(); + @Override - public FeatureCollection parseAsFeatureCollection( XMLStreamReader xmlReader, String csvLayerNames ) + public FeatureCollection parseAsFeatureCollection( InputStream inputStream, String csvLayerNames ) throws XMLStreamException { + XMLStreamReader xmlReader = XML_FACTORY.createXMLStreamReader( inputStream ); + XMLStreamUtils.skipStartDocument( xmlReader ); try { // yes, some versions use a namespace, some do not if ( ( xmlReader.getNamespaceURI() == null || xmlReader.getNamespaceURI().isEmpty() || xmlReader.getNamespaceURI().equals( "http://www.esri.com/wms" ) ) diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/FeatureInfoParser.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/FeatureInfoParser.java index 1e439bc853..60775cc1fd 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/FeatureInfoParser.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/FeatureInfoParser.java @@ -35,8 +35,9 @@ ----------------------------------------------------------------------------*/ package org.deegree.featureinfo.parsing; +import java.io.InputStream; + import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; import org.deegree.feature.FeatureCollection; @@ -48,8 +49,8 @@ public interface FeatureInfoParser { /** - * @param xmlReader - * input XML stream to parse, never null + * @param featureInfoToParse + * the feature info to parse, never null * @param csvLayerNames * a comma separated list of layer names, should not be null * @return a feature collection containingall features that could be reconstructed or synthesized, never @@ -57,7 +58,7 @@ public interface FeatureInfoParser { * @throws XMLStreamException * if the content could not be parsed as feature collection */ - FeatureCollection parseAsFeatureCollection( XMLStreamReader xmlReader, String csvLayerNames ) + FeatureCollection parseAsFeatureCollection( InputStream featureInfoToParse, String csvLayerNames ) throws XMLStreamException; } \ No newline at end of file diff --git a/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParserTest.java b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParserTest.java index 006c4066d3..e964557c42 100644 --- a/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParserTest.java +++ b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/DefaultFeatureInfoParserTest.java @@ -43,9 +43,7 @@ Occam Labs UG (haftungsbeschränkt) import java.io.InputStream; -import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; import org.deegree.feature.FeatureCollection; import org.junit.Assert; @@ -67,21 +65,15 @@ public class DefaultFeatureInfoParserTest { public void testEsriCollection() throws XMLStreamException { InputStream in = DefaultFeatureInfoParserTest.class.getResourceAsStream( "esri1.xml" ); - XMLInputFactory fac = XMLInputFactory.newInstance(); - XMLStreamReader xin = fac.createXMLStreamReader( in ); - xin.next(); - FeatureCollection fc = featureInfoParser.parseAsFeatureCollection( xin, "test" ); + FeatureCollection fc = featureInfoParser.parseAsFeatureCollection( in, "test" ); Assert.assertEquals( 1, fc.size() ); } @Test public void testEmptyEsriCollection() throws XMLStreamException { - InputStream in = DefaultFeatureInfoParserTest.class.getResourceAsStream( "esri2.xml" ); - XMLInputFactory fac = XMLInputFactory.newInstance(); - XMLStreamReader xin = fac.createXMLStreamReader( in ); - xin.next(); - FeatureCollection fc = featureInfoParser.parseAsFeatureCollection( xin, "test" ); + InputStream in = DefaultFeatureInfoParserTest.class.getResourceAsStream( "esri2.xml" ); + FeatureCollection fc = featureInfoParser.parseAsFeatureCollection( in, "test" ); Assert.assertEquals( 0, fc.size() ); } @@ -89,10 +81,7 @@ public void testEmptyEsriCollection() public void testNamespacedEsriCollection() throws XMLStreamException { InputStream in = DefaultFeatureInfoParserTest.class.getResourceAsStream( "esriwithnamespace.xml" ); - XMLInputFactory fac = XMLInputFactory.newInstance(); - XMLStreamReader xin = fac.createXMLStreamReader( in ); - xin.next(); - FeatureCollection fc = featureInfoParser.parseAsFeatureCollection( xin, "test" ); + FeatureCollection fc = featureInfoParser.parseAsFeatureCollection( in, "test" ); Assert.assertEquals( 8, fc.size() ); } diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/client/WMSClient.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/client/WMSClient.java index 16bee9b89f..4caf2a5505 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/client/WMSClient.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/client/WMSClient.java @@ -76,9 +76,9 @@ import javax.imageio.ImageIO; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamReader; import org.apache.axiom.om.OMElement; +import org.apache.commons.io.IOUtils; import org.deegree.commons.concurrent.Executor; import org.deegree.commons.ows.exception.OWSException; import org.deegree.commons.proxy.ProxySettings; @@ -343,14 +343,16 @@ public FeatureCollection doGetFeatureInfo( GetFeatureInfo request, Map Date: Fri, 1 Jul 2016 16:05:11 +0200 Subject: [PATCH 017/135] #197 - implemented XsltFeatureInfoParser --- .../parsing/XsltFeatureInfoParser.java | 123 ++++++++++++++++++ .../parsing/XsltFeatureInfoParserTest.java | 70 ++++++++++ .../parsing/esriwithnamespaceTo2gml2.xsl | 23 ++++ 3 files changed, 216 insertions(+) create mode 100644 deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/XsltFeatureInfoParser.java create mode 100644 deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/XsltFeatureInfoParserTest.java create mode 100644 deegree-core/deegree-core-featureinfo/src/test/resources/org/deegree/featureinfo/parsing/esriwithnamespaceTo2gml2.xsl diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/XsltFeatureInfoParser.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/XsltFeatureInfoParser.java new file mode 100644 index 0000000000..67d5872412 --- /dev/null +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/XsltFeatureInfoParser.java @@ -0,0 +1,123 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2015 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org +----------------------------------------------------------------------------*/ +package org.deegree.featureinfo.parsing; + +import static org.slf4j.LoggerFactory.getLogger; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.net.URL; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.deegree.commons.xml.XMLParsingException; +import org.deegree.commons.xml.XsltUtils; +import org.deegree.cs.exceptions.UnknownCRSException; +import org.deegree.feature.FeatureCollection; +import org.deegree.feature.types.DynamicAppSchema; +import org.deegree.gml.GMLInputFactory; +import org.deegree.gml.GMLStreamReader; +import org.deegree.gml.GMLVersion; +import org.slf4j.Logger; + +/** + * Responsible for parsing 'feature collections' with a xslt file. + * + * @author Lyn Goltz + */ +public class XsltFeatureInfoParser implements FeatureInfoParser { + + private static final Logger LOG = getLogger( XsltFeatureInfoParser.class ); + + private static final XMLInputFactory XML_FACTORY = XMLInputFactory.newInstance(); + + private final URL xsltFile; + + private final GMLVersion targetGmlVersion; + + /** + * @param xsltFile + * the xslt file used to transform the feature info xml, never null + * @param targetGmlVersion + * the gml version the xslt is transforming to, never null + **/ + public XsltFeatureInfoParser( URL xsltFile, GMLVersion targetGmlVersion ) { + this.xsltFile = xsltFile; + this.targetGmlVersion = targetGmlVersion; + } + + @Override + public FeatureCollection parseAsFeatureCollection( InputStream featureInfoToParse, String csvLayerNames ) + throws XMLStreamException { + XMLStreamReader transformedReader = transform( featureInfoToParse ); + return readAsGmlFeatureCollection( transformedReader ); + } + + private XMLStreamReader transform( InputStream featureInfoToParse ) + throws XMLStreamException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try { + XsltUtils.transform( featureInfoToParse, xsltFile, outputStream ); + ByteArrayInputStream inputStream = new ByteArrayInputStream( outputStream.toByteArray() ); + return XML_FACTORY.createXMLStreamReader( inputStream ); + } catch ( Exception e ) { + LOG.warn( "Unable to transform remote feature info xml stream: {}.", e.getLocalizedMessage() ); + LOG.trace( "Stack trace:", e ); + throw new XMLStreamException( "Unable to transform remote feature info xml stream." ); + } + } + + private FeatureCollection readAsGmlFeatureCollection( XMLStreamReader transformedReader ) + throws XMLStreamException { + try { + GMLStreamReader reader = GMLInputFactory.createGMLStreamReader( targetGmlVersion, transformedReader ); + reader.setApplicationSchema( new DynamicAppSchema() ); + return reader.readFeatureCollection(); + } catch ( XMLParsingException e ) { + LOG.warn( "Unable to read transfomed feature info xml stream: {}.", e.getLocalizedMessage() ); + LOG.trace( "Stack trace:", e ); + throw new XMLStreamException( "Unable to read transfomed feature info xml stream." ); + } catch ( UnknownCRSException e ) { + LOG.warn( "Unable to read transfomed feature info xml stream: {}.", e.getLocalizedMessage() ); + LOG.trace( "Stack trace:", e ); + throw new XMLStreamException( "Unable to read transfomed feature info xml stream." ); + } + } + +} \ No newline at end of file diff --git a/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/XsltFeatureInfoParserTest.java b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/XsltFeatureInfoParserTest.java new file mode 100644 index 0000000000..be6425fa70 --- /dev/null +++ b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/parsing/XsltFeatureInfoParserTest.java @@ -0,0 +1,70 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2015 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org +----------------------------------------------------------------------------*/ +package org.deegree.featureinfo.parsing; + +import java.io.InputStream; +import java.net.URL; + +import javax.xml.stream.XMLStreamException; + +import org.deegree.feature.FeatureCollection; +import org.deegree.gml.GMLVersion; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * @author Lyn Goltz + */ +public class XsltFeatureInfoParserTest { + + private static XsltFeatureInfoParser featureInfoParser; + + @BeforeClass + public static void initParser() { + URL xsltFile = XsltFeatureInfoParserTest.class.getResource( "esriwithnamespaceTo2gml2.xsl" ); + featureInfoParser = new XsltFeatureInfoParser( xsltFile, GMLVersion.GML_2 ); + } + + @Test + public void testEsriCollection() + throws XMLStreamException { + InputStream in = XsltFeatureInfoParser.class.getResourceAsStream( "esriwithnamespace.xml" ); + FeatureCollection fc = featureInfoParser.parseAsFeatureCollection( in, "test" ); + Assert.assertEquals( 8, fc.size() ); + } + +} \ No newline at end of file diff --git a/deegree-core/deegree-core-featureinfo/src/test/resources/org/deegree/featureinfo/parsing/esriwithnamespaceTo2gml2.xsl b/deegree-core/deegree-core-featureinfo/src/test/resources/org/deegree/featureinfo/parsing/esriwithnamespaceTo2gml2.xsl new file mode 100644 index 0000000000..6c294a2acd --- /dev/null +++ b/deegree-core/deegree-core-featureinfo/src/test/resources/org/deegree/featureinfo/parsing/esriwithnamespaceTo2gml2.xsl @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 7f439a0e9a805bd913ca13292d88ccbefbebaf23 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Fri, 1 Jul 2016 16:34:46 +0200 Subject: [PATCH 018/135] #197 - parse xsltfile from config, create and pass XSLTFeatureInfoParser --- .../deegree/layer/metadata/LayerMetadata.java | 18 +++++ .../org/deegree/layer/metadata/XsltFile.java | 78 +++++++++++++++++++ .../protocol/wms/client/WMSClient.java | 24 +++++- .../persistence/remotewms/RemoteWMSLayer.java | 19 ++++- .../remotewms/RemoteWMSLayerData.java | 10 ++- .../remotewms/RemoteWmsLayerBuilder.java | 31 +++++++- .../remotewms/RemoteWmsLayerStoreBuilder.java | 2 +- 7 files changed, 173 insertions(+), 9 deletions(-) create mode 100644 deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/metadata/XsltFile.java diff --git a/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/metadata/LayerMetadata.java b/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/metadata/LayerMetadata.java index a17aeee247..58e9cc5fb5 100644 --- a/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/metadata/LayerMetadata.java +++ b/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/metadata/LayerMetadata.java @@ -38,6 +38,7 @@ import static java.lang.Double.NEGATIVE_INFINITY; import static java.lang.Double.POSITIVE_INFINITY; +import java.net.URL; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -89,6 +90,8 @@ public class LayerMetadata { private List> authorities = new ArrayList>(); private boolean requestable = true; + + private XsltFile xsltFile; public LayerMetadata( String name, Description description, SpatialMetadata spatialMetadata ) { this.name = name; @@ -372,6 +375,21 @@ public void setAuthorities( List> authorities ) { this.authorities = authorities; } + /** + * @return the xslt file used to transform a feature info response from remote layer, may be null + */ + public XsltFile getXsltFile() { + return xsltFile; + } + + /** + * @param xsltFile + * the xslt file used to transform a feature info response from remote layer, may be null + */ + public void setXsltFile( XsltFile xsltFile ) { + this.xsltFile = xsltFile; + } + private void mergeDescription( Description desc ) { if ( desc != null ) { if ( description.getTitles() == null || description.getTitles().isEmpty() ) { diff --git a/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/metadata/XsltFile.java b/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/metadata/XsltFile.java new file mode 100644 index 0000000000..b3d50c607f --- /dev/null +++ b/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/metadata/XsltFile.java @@ -0,0 +1,78 @@ +//$HeadURL$ +/*---------------------------------------------------------------------------- + This file is part of deegree, http://deegree.org/ + Copyright (C) 2001-2015 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + lat/lon GmbH + Aennchenstr. 19, 53177 Bonn + Germany + http://lat-lon.de/ + + Department of Geography, University of Bonn + Prof. Dr. Klaus Greve + Postfach 1147, 53001 Bonn + Germany + http://www.geographie.uni-bonn.de/deegree/ + + e-mail: info@deegree.org +----------------------------------------------------------------------------*/ +package org.deegree.layer.metadata; + +import java.net.URL; + +import org.deegree.gml.GMLVersion; + +/** + * Encapsulates the xslt file as well as the gml version the xslt file transfoms to. + * + * @author Lyn Goltz + */ +public class XsltFile { + + private final URL xsltFile; + + private final GMLVersion targetGmlVersion; + + /** + * @param xsltFile + * the xslt file used to transform, never null + * @param gmlVersion + * the gml version the xsltFile transforms to, never null + */ + public XsltFile( URL xsltFile, GMLVersion targetGmlVersion ) { + this.xsltFile = xsltFile; + this.targetGmlVersion = targetGmlVersion; + } + + /** + * @return the xslt file used to transform, never null + */ + public URL getXsltFile() { + return xsltFile; + } + + /** + * @return the gml version the xsltFile transforms to, never null + */ + public GMLVersion getTargetGmlVersion() { + return targetGmlVersion; + } + +} diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/client/WMSClient.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/client/WMSClient.java index 4caf2a5505..0adda50f14 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/client/WMSClient.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/client/WMSClient.java @@ -97,6 +97,7 @@ import org.deegree.cs.persistence.CRSManager; import org.deegree.feature.FeatureCollection; import org.deegree.featureinfo.parsing.DefaultFeatureInfoParser; +import org.deegree.featureinfo.parsing.FeatureInfoParser; import org.deegree.geometry.Envelope; import org.deegree.geometry.GeometryFactory; import org.deegree.geometry.GeometryTransformer; @@ -338,6 +339,27 @@ public Pair getMap( GetMap getMap, Map ha */ public FeatureCollection doGetFeatureInfo( GetFeatureInfo request, Map hardParams ) throws IOException, OWSExceptionReport, XMLStreamException { + return doGetFeatureInfo( request, hardParams, new DefaultFeatureInfoParser() ); + } + + /** + * Performs a GetFeatureInfo request and returns the response as a {@link FeatureCollection}. + * + * @param request + * request parameter, must not be null + * @param hardParams + * raw parameters for augmenting overriding KVPs, must not be null + * @param featureInfoParser + * used to parse the feature info response as feature collection, never null + * @return response parsed as feature collection, never null + * @throws IOException + * @throws OWSExceptionReport + * @throws XMLStreamException + */ + public FeatureCollection doGetFeatureInfo( GetFeatureInfo request, Map hardParams, + FeatureInfoParser featureInfoParser ) + throws IOException, OWSExceptionReport, + XMLStreamException { Map params = buildGetFeatureInfoParamMap( request, hardParams ); overrideHardParams( params, hardParams ); @@ -350,7 +372,7 @@ public FeatureCollection doGetFeatureInfo( GetFeatureInfo request, Map headers ) { GetFeatureInfo gfi = new GetFeatureInfo( Collections.singletonList( originalName ), query.getWidth(), query.getHeight(), query.getX(), query.getY(), query.getEnvelope(), crs, query.getFeatureCount() ); - return new RemoteWMSLayerData( client, gfi, extraParams ); + return new RemoteWMSLayerData( client, gfi, extraParams, featureInfoParser ); + } + + private FeatureInfoParser createFeatureInfoParser( XsltFile xsltFile ) { + if ( xsltFile != null ) + return new XsltFeatureInfoParser( xsltFile.getXsltFile(), xsltFile.getTargetGmlVersion() ); + return new DefaultFeatureInfoParser(); } } diff --git a/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWMSLayerData.java b/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWMSLayerData.java index 0b2fddc61a..6c31882c55 100644 --- a/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWMSLayerData.java +++ b/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWMSLayerData.java @@ -43,6 +43,7 @@ import org.deegree.commons.utils.Pair; import org.deegree.feature.FeatureCollection; import org.deegree.feature.GenericFeatureCollection; +import org.deegree.featureinfo.parsing.FeatureInfoParser; import org.deegree.layer.LayerData; import org.deegree.protocol.wms.client.WMSClient; import org.deegree.protocol.wms.ops.GetFeatureInfo; @@ -69,16 +70,20 @@ public class RemoteWMSLayerData implements LayerData { private GetFeatureInfo gfi; + private FeatureInfoParser featureInfoParser; + public RemoteWMSLayerData( WMSClient client, GetMap gm, Map extraParams ) { this.client = client; this.gm = gm; this.extraParams = extraParams; } - public RemoteWMSLayerData( WMSClient client, GetFeatureInfo gfi, Map extraParams ) { + public RemoteWMSLayerData( WMSClient client, GetFeatureInfo gfi, Map extraParams, + FeatureInfoParser featureInfoParser ) { this.client = client; this.gfi = gfi; this.extraParams = extraParams; + this.featureInfoParser = featureInfoParser; } @Override @@ -98,8 +103,7 @@ public void render( RenderContext context ) { @Override public FeatureCollection info() { try { - FeatureCollection col = client.doGetFeatureInfo( gfi, extraParams ); - return col; + return client.doGetFeatureInfo( gfi, extraParams, featureInfoParser ); } catch ( Exception e ) { LOG.warn( "Error when retrieving remote feature info: {}", e.getLocalizedMessage() ); LOG.trace( "Stack trace:", e ); diff --git a/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWmsLayerBuilder.java b/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWmsLayerBuilder.java index 3d326188c8..72b0115443 100644 --- a/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWmsLayerBuilder.java +++ b/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWmsLayerBuilder.java @@ -41,6 +41,7 @@ Occam Labs UG (haftungsbeschränkt) ----------------------------------------------------------------------------*/ package org.deegree.layer.persistence.remotewms; +import java.net.URL; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; @@ -50,13 +51,19 @@ Occam Labs UG (haftungsbeschränkt) import org.deegree.commons.ows.metadata.DescriptionConverter; import org.deegree.geometry.metadata.SpatialMetadata; import org.deegree.geometry.metadata.SpatialMetadataConverter; +import org.deegree.gml.GMLVersion; import org.deegree.layer.Layer; import org.deegree.layer.config.ConfigUtils; import org.deegree.layer.metadata.LayerMetadata; +import org.deegree.layer.metadata.XsltFile; +import org.deegree.layer.persistence.LayerStore; +import org.deegree.layer.persistence.remotewms.jaxb.GMLVersionType; import org.deegree.layer.persistence.remotewms.jaxb.LayerType; +import org.deegree.layer.persistence.remotewms.jaxb.LayerType.XSLTFile; import org.deegree.layer.persistence.remotewms.jaxb.RemoteWMSLayers; import org.deegree.layer.persistence.remotewms.jaxb.RequestOptionsType; import org.deegree.protocol.wms.client.WMSClient; +import org.deegree.workspace.ResourceMetadata; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -76,9 +83,12 @@ class RemoteWmsLayerBuilder { private RemoteWMSLayers cfg; - RemoteWmsLayerBuilder( WMSClient client, RemoteWMSLayers cfg ) { + private ResourceMetadata metadata; + + RemoteWmsLayerBuilder( WMSClient client, RemoteWMSLayers cfg, ResourceMetadata metadata ) { this.client = client; this.cfg = cfg; + this.metadata = metadata; } Map buildLayerMap() { @@ -102,6 +112,7 @@ Map buildLayerMap() { } LayerMetadata md = new LayerMetadata( name, desc, smd ); md.setMapOptions( ConfigUtils.parseLayerOptions( l.getLayerOptions() ) ); + md.setXsltFile( parseXsltFile( md, l.getXSLTFile() ) ); configured.put( l.getOriginalName(), md ); } } @@ -119,11 +130,25 @@ Map buildLayerMap() { LayerMetadata confMd = configured.get( name ); if ( confMd != null ) { confMd.merge( md ); - map.put( confMd.getName(), new RemoteWMSLayer( name, confMd, client, opts ) ); + map.put( confMd.getName(), new RemoteWMSLayer( name, confMd, client, opts, confMd.getXsltFile() ) ); } } } return map; } -} + private XsltFile parseXsltFile( LayerMetadata md, XSLTFile xsltFileConfig ) { + if(xsltFileConfig != null){ + GMLVersion gmlVersion = GMLVersion.valueOf( xsltFileConfig.getTargetGmlVersion().value() ); + String xslFile = xsltFileConfig.getValue(); + URL xsltFileUrl = metadata.getLocation().resolveToUrl( xslFile ); + if ( xsltFileUrl == null ) { + LOG.warn( "Could not resolve xslt file url {}.", xslFile ); + } else { + return new XsltFile( xsltFileUrl, gmlVersion ); + } + } + return null; + } + +} \ No newline at end of file diff --git a/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWmsLayerStoreBuilder.java b/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWmsLayerStoreBuilder.java index 1b4651ee98..56f49503bd 100644 --- a/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWmsLayerStoreBuilder.java +++ b/deegree-layers/deegree-layers-remotewms/src/main/java/org/deegree/layer/persistence/remotewms/RemoteWmsLayerStoreBuilder.java @@ -72,7 +72,7 @@ public LayerStore build() { + " is not available or not of type WMS." ); } - RemoteWmsLayerBuilder builder = new RemoteWmsLayerBuilder( ( (RemoteWMS) store ).getClient(), cfg ); + RemoteWmsLayerBuilder builder = new RemoteWmsLayerBuilder( ( (RemoteWMS) store ).getClient(), cfg, metadata ); Map map = builder.buildLayerMap(); From 9e41b36daff8970b32f13e917e1699a104fe0a27 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Mon, 4 Jul 2016 12:12:21 +0200 Subject: [PATCH 019/135] #200 -added description of XSLTFile transformation per RemoteWMSLayer --- .../deegree-webservices-handbook/src/main/sphinx/layers.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/deegree-services/deegree-webservices-handbook/src/main/sphinx/layers.rst b/deegree-services/deegree-webservices-handbook/src/main/sphinx/layers.rst index 33ec494980..98c5e57016 100644 --- a/deegree-services/deegree-webservices-handbook/src/main/sphinx/layers.rst +++ b/deegree-services/deegree-webservices-handbook/src/main/sphinx/layers.rst @@ -516,8 +516,12 @@ The manual configuration allows you to pick out a layer, rename it, and optional + Please note that once you specify one layer, you'll need to specify each layer you want to make available. If you want all layers to be available, don't specify a ``Layer`` element. Of course, you can specify as many ``Layer`` elements as you like. +With the element ``XSLTFile`` a xslt-Script can be configured transforming the response of a GetFeatureInfo request of the remote WMS to gml per layer. The values GML_2, GML_30, GML_31 and GML_32 are allowed as values of the attribute ``targetGmlVersion``. \ No newline at end of file From 5c1282dd76f573fe5c57bf0ff9a6258dc15407fe Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Mon, 4 Jul 2016 15:41:40 +0200 Subject: [PATCH 020/135] #197 - added debug statement --- .../org/deegree/featureinfo/parsing/XsltFeatureInfoParser.java | 1 + 1 file changed, 1 insertion(+) diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/XsltFeatureInfoParser.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/XsltFeatureInfoParser.java index 67d5872412..b3afc6b824 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/XsltFeatureInfoParser.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/parsing/XsltFeatureInfoParser.java @@ -91,6 +91,7 @@ public FeatureCollection parseAsFeatureCollection( InputStream featureInfoToPars private XMLStreamReader transform( InputStream featureInfoToParse ) throws XMLStreamException { + LOG.debug( "Apply xslt transformation {}.", xsltFile ); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { XsltUtils.transform( featureInfoToParse, xsltFile, outputStream ); From 6c5225eea3f64a08723091492fd91de0ac4d781b Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Tue, 1 Nov 2016 12:01:11 +0100 Subject: [PATCH 021/135] #216 - added optional configuration of the StyleTitle in the base layer config --- .../main/resources/META-INF/schemas/layers/base/3.4.0/base.xsd | 1 + 1 file changed, 1 insertion(+) diff --git a/deegree-core/deegree-core-layer/src/main/resources/META-INF/schemas/layers/base/3.4.0/base.xsd b/deegree-core/deegree-core-layer/src/main/resources/META-INF/schemas/layers/base/3.4.0/base.xsd index dae5e78a82..b6a2c86f3e 100644 --- a/deegree-core/deegree-core-layer/src/main/resources/META-INF/schemas/layers/base/3.4.0/base.xsd +++ b/deegree-core/deegree-core-layer/src/main/resources/META-INF/schemas/layers/base/3.4.0/base.xsd @@ -36,6 +36,7 @@ + From fab507e89f84771da80054ccb7b1fcaecf8dabd2 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Tue, 1 Nov 2016 13:36:47 +0100 Subject: [PATCH 022/135] #217 - export of the style title in the capabilities --- .../org/deegree/layer/config/ConfigUtils.java | 2 ++ .../org/deegree/style/se/unevaluated/Style.java | 17 +++++++++++++++++ .../theme/WmsCapabilities111ThemeWriter.java | 14 +++++++++----- .../theme/WmsCapabilities130ThemeWriter.java | 14 +++++++++----- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/config/ConfigUtils.java b/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/config/ConfigUtils.java index d65e538588..9de3e5c0df 100644 --- a/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/config/ConfigUtils.java +++ b/deegree-core/deegree-core-layer/src/main/java/org/deegree/layer/config/ConfigUtils.java @@ -127,6 +127,7 @@ private static Pair useSelectedStyles( Workspace workspace, StyleS for ( org.deegree.layer.persistence.base.jaxb.StyleRefType.Style s : srt.getStyle() ) { boolean isDefault = false; String name = s.getStyleName(); + String title = s.getStyleTitle(); String nameRef = s.getStyleNameRef(); String layerRef = s.getLayerNameRef(); Style st = store.getStyle( layerRef, nameRef ); @@ -141,6 +142,7 @@ private static Pair useSelectedStyles( Workspace workspace, StyleS } st = st.copy(); st.setName( name ); + st.setTitle( title ); styleMap.put( name, st ); if ( isDefault && !styleMap.containsKey( "default" ) ) { styleMap.put( "default", st ); diff --git a/deegree-core/deegree-core-style/src/main/java/org/deegree/style/se/unevaluated/Style.java b/deegree-core/deegree-core-style/src/main/java/org/deegree/style/se/unevaluated/Style.java index fa041c6c3e..2284f454ee 100644 --- a/deegree-core/deegree-core-style/src/main/java/org/deegree/style/se/unevaluated/Style.java +++ b/deegree-core/deegree-core-style/src/main/java/org/deegree/style/se/unevaluated/Style.java @@ -106,6 +106,8 @@ public class Style implements Copyable