Skip to content
Browse files

Merge pull request #40 from jive/wmsGetMap

WMS 1.3.0 support with transforms in Layer.getEnvelope and GetMap.setBounds( Envelope )
  • Loading branch information...
2 parents 753457a + 056965f commit 61724bd3219c4921255e9006cd44ff3d4f826fea @jodygarnett jodygarnett committed Oct 13, 2012
View
23 modules/extension/wms/src/main/java/org/geotools/data/ows/CRSEnvelope.java
@@ -16,6 +16,7 @@
*/
package org.geotools.data.ows;
+import org.geotools.data.wms.request.AbstractGetMapRequest;
import org.geotools.factory.GeoTools;
import org.geotools.factory.Hints;
import org.geotools.geometry.GeneralDirectPosition;
@@ -107,7 +108,7 @@ public CRSEnvelope(String epsgCode, double minX, double minY, double maxX, doubl
this.maxY = maxY;
}
public CRSEnvelope(Envelope envelope) {
- this.srsName = envelope.getCoordinateReferenceSystem().getIdentifiers().iterator().next().toString();
+ this.srsName = CRS.toSRS( envelope.getCoordinateReferenceSystem());
//this.srsName = epsgCode;
this.minX = envelope.getMinimum(0);
this.maxX = envelope.getMaximum(0);
@@ -123,24 +124,12 @@ public CoordinateReferenceSystem getCoordinateReferenceSystem() {
synchronized (this) {
if (crs == null) {
try {
- if( srsName != null ){
- if( forceXY == null ){
- crs = CRS.decode(srsName);
- }
- else if( forceXY == Boolean.TRUE ){
- crs = CRS.decode(srsName,true);
- }
- else if( srsName.startsWith("EPSG:") && Boolean.getBoolean(GeoTools.FORCE_LONGITUDE_FIRST_AXIS_ORDER)){
- // how do we look up the unmodified axis order?
- String explicit = srsName.replace("EPSG:", "urn:x-ogc:def:crs:EPSG:");
- crs = CRS.decode(explicit,false);
- }
- else {
- crs = CRS.decode(srsName,false);
- }
+ String srs = srsName != null ? srsName : "CRS:84";
+ if( forceXY == null ){
+ crs = CRS.decode(srs);
}
else {
- crs = CRS.decode("CRS:84"); // implicit
+ crs = AbstractGetMapRequest.toServerCRS(srsName, forceXY );
}
} catch (NoSuchAuthorityCodeException e) {
crs = DefaultEngineeringCRS.CARTESIAN_2D;
View
25 modules/extension/wms/src/main/java/org/geotools/data/ows/Layer.java
@@ -816,7 +816,7 @@ public GeneralEnvelope getEnvelope(CoordinateReferenceSystem crs) {
Collection<Object> identifiers = new ArrayList<Object>();
identifiers.addAll( crs.getIdentifiers() );
if (crs == DefaultGeographicCRS.WGS84 || crs == DefaultGeographicCRS.WGS84_3D) {
- identifiers.add( "EPSG:4326" );
+ identifiers.add( "CRS:84" );
}
for (Object identifier : identifiers ) {
String srsName = identifier.toString();
@@ -850,12 +850,12 @@ public GeneralEnvelope getEnvelope(CoordinateReferenceSystem crs) {
layer = layer.getParent();
}
- if (latLonBBox == null) {
- // TODO could convert another bbox to latlon?
- tempBBox = new CRSEnvelope("EPSG:4326", -180, -90, 180, 90);
- } else {
- tempBBox = new CRSEnvelope("EPSG:4326", latLonBBox.getMinX(), latLonBBox
+ if (latLonBBox != null) {
+ tempBBox = new CRSEnvelope("CRS:84", latLonBBox.getMinX(), latLonBBox
.getMinY(), latLonBBox.getMaxX(), latLonBBox.getMaxY());
+ } else {
+ tempBBox = new CRSEnvelope("CRS:84", -180, -90, 180, 90);
+ // TODO could convert another bbox to latlon?
}
}
@@ -914,10 +914,15 @@ public GeneralEnvelope getEnvelope(CoordinateReferenceSystem crs) {
// TODO Attempt to figure out the valid area of the CRS and use that.
if (tempBBox != null) {
- GeneralEnvelope env = new GeneralEnvelope(new double[] { tempBBox.getMinX(),
- tempBBox.getMinY() },
- new double[] { tempBBox.getMaxX(), tempBBox.getMaxY() });
- env.setCoordinateReferenceSystem(crs);
+ GeneralEnvelope env;
+ try {
+ Envelope fixed = CRS.transform( tempBBox, crs );
+ env = new GeneralEnvelope( fixed );
+ } catch (TransformException e) {
+ env = new GeneralEnvelope(new double[] { tempBBox.getMinX(),tempBBox.getMinY() },
+ new double[] { tempBBox.getMaxX(), tempBBox.getMaxY() });
+ env.setCoordinateReferenceSystem(crs);
+ }
return env;
}
View
72 modules/extension/wms/src/main/java/org/geotools/data/wms/request/AbstractGetMapRequest.java
@@ -27,7 +27,15 @@
import org.geotools.data.ows.CRSEnvelope;
import org.geotools.data.ows.Layer;
import org.geotools.data.ows.StyleImpl;
+import org.geotools.factory.GeoTools;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.crs.DefaultEngineeringCRS;
import org.opengis.geometry.BoundingBox;
+import org.opengis.geometry.Envelope;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.TransformException;
/**
*
@@ -168,34 +176,62 @@ public void setSRS(String srs) {
* server has declared that a Layer is not subsettable, then the Client
* shall specify exactly the declared Bounding Box values in the GetMap
* request and the Server may issue a Service Exception otherwise."
- *
+ * <p>
+ * Yu must also call setSRS to provide the spatial reference system
+ * information (or CRS:84 will be assumed)
+ *
* @param bbox A string representing a bounding box in the format
* "minx,miny,maxx,maxy"
*/
public void setBBox(String bbox) {
//TODO enforce non-subsettable layers
properties.setProperty(BBOX, bbox);
}
-
- public void setBBox(CRSEnvelope box){
- StringBuffer sb = new StringBuffer();
- sb.append(box.getMinX());
- sb.append(",");
- sb.append(box.getMinY()+",");
- sb.append(box.getMaxX()+",");
- sb.append(box.getMaxY());
- setBBox(sb.toString());
+
+ public static CoordinateReferenceSystem toServerCRS(String srsName, boolean forceXY) {
+ try {
+ if (srsName != null) {
+ if (forceXY) {
+ return CRS.decode(srsName, true);
+ } else if (srsName.startsWith("EPSG:")
+ && Boolean.getBoolean(GeoTools.FORCE_LONGITUDE_FIRST_AXIS_ORDER)) {
+ // how do we look up the unmodified axis order?
+ String explicit = srsName.replace("EPSG:", "urn:x-ogc:def:crs:EPSG::");
+ return CRS.decode(explicit, false);
+ } else {
+ return CRS.decode(srsName, false);
+ }
+ }
+ else {
+ return CRS.decode("CRS:84");
+ }
+ } catch (NoSuchAuthorityCodeException e) {
+ } catch (FactoryException e) {
+ }
+ return DefaultEngineeringCRS.CARTESIAN_2D;
}
- public void setBBox(BoundingBox box) {
+ /**
+ * Sets BBOX and SRS using the provided Envelope.
+ */
+ public void setBBox(Envelope envelope){
+ String version = properties.getProperty(VERSION);
+ boolean forceXY = version == null || !version.startsWith("1.3");
+ String srsName = CRS.toSRS( envelope.getCoordinateReferenceSystem() );
+ setSRS( srsName );
+
+ CoordinateReferenceSystem crs = toServerCRS( srsName, forceXY );
+ Envelope bbox;
+ try {
+ bbox = CRS.transform( envelope, crs);
+ } catch (TransformException e) {
+ bbox = envelope;
+ }
StringBuffer sb = new StringBuffer();
- sb.append(box.getMinX());
- sb.append(",");
- sb.append(box.getMinY());
+ sb.append(bbox.getMinimum(0));
sb.append(",");
- sb.append(box.getMaxX());
- sb.append(",");
- sb.append(box.getMaxY());
-
+ sb.append(bbox.getMinimum(1)+",");
+ sb.append(bbox.getMaximum(0)+",");
+ sb.append(bbox.getMaximum(1));
setBBox(sb.toString());
}
/**
View
10 modules/extension/wms/src/main/java/org/geotools/data/wms/request/GetMapRequest.java
@@ -24,6 +24,7 @@
import org.geotools.data.ows.Request;
import org.geotools.data.ows.StyleImpl;
import org.opengis.geometry.BoundingBox;
+import org.opengis.geometry.Envelope;
/**
* Construct a WMS getMap request.
@@ -224,8 +225,13 @@
* "minx,miny,maxx,maxy"
*/
public void setBBox(String bbox);
- public void setBBox(CRSEnvelope box);
- public void setBBox(BoundingBox box);
+
+ /**
+ * Sets the BBOX and SRS information from the provided Envelope (such as a CRSEnvelope).
+ * @param box
+ */
+ public void setBBox(Envelope box);
+
/**
* From the Web Map Service Implementation Specification: "The required
View
151 modules/extension/wms/src/test/java/org/geotools/data/wms/test/LocalGeoServerOnlineTest.java
@@ -16,29 +16,49 @@
*/
package org.geotools.data.wms.test;
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.Properties;
+
+import javax.imageio.ImageIO;
import junit.framework.TestCase;
import org.geotools.data.ResourceInfo;
import org.geotools.data.ServiceInfo;
import org.geotools.data.ows.CRSEnvelope;
import org.geotools.data.ows.Layer;
+import org.geotools.data.ows.OperationType;
import org.geotools.data.ows.WMSCapabilities;
import org.geotools.data.wms.WebMapServer;
+import org.geotools.data.wms.request.GetMapRequest;
+import org.geotools.data.wms.response.GetMapResponse;
+import org.geotools.factory.GeoTools;
+import org.geotools.geometry.GeneralEnvelope;
import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.CRS.AxisOrder;
+import org.geotools.referencing.crs.DefaultEngineeringCRS;
+import org.geotools.referencing.crs.DefaultGeographicCRS;
+import org.opengis.geometry.Envelope;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
-
-import com.vividsolutions.jts.geom.Coordinate;
+import org.opengis.referencing.cs.CoordinateSystem;
+import org.opengis.referencing.cs.CoordinateSystemAxis;
+import org.opengis.util.GenericName;
/**
* This test case assume you have a default GeoServer 2.2 installed on 127.0.0.1 (ie localhost).
* <p>
* This is being used to look at WMS 1.1.1 vs WMS 1.3.0 compatibility issues for uDig.
* <p>
*
- * <pre><code>
+ * <pre>
+ * <code>
* &lt;Layer queryable="1"&gt;
* &lt;Name&gt;nurc:Img_Sample&lt;/Name&gt;
* &lt;Title&gt;North America sample imagery&lt;/Title&gt;
@@ -70,7 +90,8 @@
* &lt;/LegendURL&gt;
* &lt;/Style&gt;
* &lt;/Layer&gt;
- * </code></pre>
+ * </code>
+ * </pre>
*
* </p>
*
@@ -159,50 +180,130 @@ public void testServiceInfo() {
assertNotNull(info.getDescription());
}
- String axisName(CoordinateReferenceSystem crs, int dimension ){
+ String axisName(CoordinateReferenceSystem crs, int dimension) {
return crs.getCoordinateSystem().getAxis(dimension).getName().getCode();
}
-
- public void testImgSample130() {
- Layer img_sample = find( "nurc:Img_Sample");
- assertNotNull("Img_Sample layer found", img_sample );
+
+ public void testImgSample130() throws Exception {
+ Layer img_sample = find("nurc:Img_Sample");
+ assertNotNull("Img_Sample layer found", img_sample);
CRSEnvelope latLon = img_sample.getLatLonBoundingBox();
- assertEquals( "LatLonBoundingBox axis 0 name", "Geodetic longitude", axisName( latLon.getCoordinateReferenceSystem(), 0) );
- assertEquals( "LatLonBoundingBox axis 0 name", "Geodetic latitude", axisName( latLon.getCoordinateReferenceSystem(), 1) );
+ assertEquals("LatLonBoundingBox axis 0 name", "Geodetic longitude",
+ axisName(latLon.getCoordinateReferenceSystem(), 0));
+ assertEquals("LatLonBoundingBox axis 0 name", "Geodetic latitude",
+ axisName(latLon.getCoordinateReferenceSystem(), 1));
+
+ boolean globalXY = Boolean.getBoolean("org.geotools.referencing.forceXY");
CRSEnvelope bounds = img_sample.getBoundingBoxes().get("EPSG:4326");
- assertEquals( "EPSG:4326 axis 0 name", "Geodetic latitude", axisName( bounds.getCoordinateReferenceSystem(), 0) );
- assertEquals( "EPSG:4326 axis 1 name", "Geodetic longitude", axisName( bounds.getCoordinateReferenceSystem(), 1) );
+ CoordinateReferenceSystem boundsCRS = bounds.getCoordinateReferenceSystem();
+ assertEquals( "EPSG:4326", AxisOrder.EAST_NORTH, CRS.getAxisOrder(boundsCRS) );
assertEquals("axis order 0 min", latLon.getMinimum(1), bounds.getMinimum(0));
assertEquals("axis order 1 min", latLon.getMinimum(0), bounds.getMinimum(1));
assertEquals("axis order 1 max", latLon.getMaximum(0), bounds.getMaximum(1));
assertEquals("axis order 1 min", latLon.getMaximum(1), bounds.getMaximum(0));
+
+ // GETMAP
+ checkGetMap(wms, img_sample, DefaultGeographicCRS.WGS84);
+ checkGetMap(wms, img_sample, CRS.decode("CRS:84"));
+ checkGetMap(wms, img_sample, CRS.decode("EPSG:4326"));
+ checkGetMap(wms, img_sample, CRS.decode("urn:x-ogc:def:crs:EPSG::4326"));
}
-
+
public void testImageSample111() throws Exception {
- WebMapServer wms111 = new WebMapServer( new URL(serverURL +"&VERSION=1.1.1") );
+ WebMapServer wms111 = new WebMapServer(new URL(serverURL + "&VERSION=1.1.1"));
WMSCapabilities caps = wms111.getCapabilities();
- assertEquals( "1.1.1", caps.getVersion() );
-
- Layer img_sample = find("nurc:Img_Sample",caps );
- assertNotNull("Img_Sample layer found", img_sample );
+ assertEquals("1.1.1", caps.getVersion());
+
+ Layer img_sample = find("nurc:Img_Sample", caps);
+ assertNotNull("Img_Sample layer found", img_sample);
CRSEnvelope latLon = img_sample.getLatLonBoundingBox();
- assertEquals( "LatLonBoundingBox axis 0 name", "Geodetic longitude", axisName( latLon.getCoordinateReferenceSystem(), 0) );
- assertEquals( "LatLonBoundingBox axis 1 name", "Geodetic latitude", axisName( latLon.getCoordinateReferenceSystem(), 1) );
-
+ assertEquals("LatLonBoundingBox axis 0 name", "Geodetic longitude",
+ axisName(latLon.getCoordinateReferenceSystem(), 0));
+ assertEquals("LatLonBoundingBox axis 1 name", "Geodetic latitude",
+ axisName(latLon.getCoordinateReferenceSystem(), 1));
+
CRSEnvelope bounds = img_sample.getBoundingBoxes().get("EPSG:4326");
- assertEquals( "EPSG:4326 axis 0 name", "Geodetic longitude", axisName( bounds.getCoordinateReferenceSystem(), 0) );
- assertEquals( "EPSG:4326 axis 1 name", "Geodetic latitude", axisName( bounds.getCoordinateReferenceSystem(), 1) );
-
+ CoordinateReferenceSystem boundsCRS = bounds.getCoordinateReferenceSystem();
+ assertEquals( "EPSG:4326", AxisOrder.EAST_NORTH, CRS.getAxisOrder(boundsCRS) );;
+
assertEquals("axis order 0 min", latLon.getMinimum(0), bounds.getMinimum(0));
assertEquals("axis order 1 min", latLon.getMinimum(1), bounds.getMinimum(1));
assertEquals("axis order 1 max", latLon.getMaximum(0), bounds.getMaximum(0));
assertEquals("axis order 1 min", latLon.getMaximum(1), bounds.getMaximum(1));
+
+ // GETMAP
+ checkGetMap(wms111, img_sample, DefaultGeographicCRS.WGS84);
+ checkGetMap(wms111, img_sample, CRS.decode("CRS:84"));
+ checkGetMap(wms111, img_sample, CRS.decode("EPSG:4326"));
+ checkGetMap(wms111, img_sample, CRS.decode("urn:x-ogc:def:crs:EPSG::4326"));
+
+ }
+
+ /**
+ * Check GetMap request functionality in the provided CRS.
+ * <p>
+ * Attempt is made to request the entire image.
+ *
+ * @param wms
+ * @param layer
+ * @param crs
+ */
+ private void checkGetMap(WebMapServer wms, Layer layer, CoordinateReferenceSystem crs)
+ throws Exception {
+ layer.clearCache();
+ CRSEnvelope latLon = layer.getLatLonBoundingBox();
+ GeneralEnvelope envelope = wms.getEnvelope(layer, crs);
+ assertFalse(envelope.isEmpty() || envelope.isNull() || envelope.isInfinite());
+ assertNotNull("Envelope "+CRS.toSRS(crs), envelope);
+
+ GetMapRequest getMap = wms.createGetMapRequest();
+ OperationType operationType = wms.getCapabilities().getRequest().getGetMap();
+
+ getMap.addLayer(layer);
+ String version = wms.getCapabilities().getVersion();
+ String srs = CRS.toSRS(envelope.getCoordinateReferenceSystem());
+ getMap.setBBox(envelope);
+ //getMap.setSRS( srs );
+ String format = format(operationType, "jpeg");
+ getMap.setFormat(format);
+ getMap.setDimensions(500, 500);
+
+ URL url = getMap.getFinalURL();
+ GetMapResponse response = wms.issueRequest(getMap);
+ assertEquals("image/jpeg", response.getContentType());
+
+ InputStream stream = response.getInputStream();
+ BufferedImage image = ImageIO.read(stream);
+ assertNotNull("jpeg", image);
+ assertEquals(500, image.getWidth());
+ assertEquals(500, image.getHeight());
+ int rgb = image.getRGB(250, 250);
+ Color sample = new Color(rgb);
+ boolean forceXY = Boolean.getBoolean(GeoTools.FORCE_LONGITUDE_FIRST_AXIS_ORDER);
+ String context = "srs="+srs+" forceXY="+forceXY+" Version="+version;
+ if(Color.WHITE.equals(sample)){
+ System.out.println("FAIL: "+ context+": GetMap BBOX=" + envelope);
+ System.out.println("--> " + url);
+ fail( context+": GetMap BBOX=" + envelope );
+ }
+ else {
+ //System.out.println("PASS: "+ context+": GetMap BBOX=" + bbox);
+ }
}
+
+ private String format(OperationType operationType, String search) {
+ for (String format : operationType.getFormats()) {
+ if (format.contains(search)) {
+ return format;
+ }
+ }
+ return null; // not found
+ }
}

0 comments on commit 61724bd

Please sign in to comment.
Something went wrong with that request. Please try again.