Skip to content

Commit

Permalink
[GEOS-6977] Fixed WCS 1.0.0 KVP ignoring the elevation parameter.
Browse files Browse the repository at this point in the history
  • Loading branch information
sikeoka committed Mar 7, 2019
1 parent 1e224be commit 0d11a53
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 46 deletions.
5 changes: 5 additions & 0 deletions src/wcs1_0/src/main/java/applicationContext.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@
<constructor-arg ref="geoServer"/>
</bean>

<bean id="wcs100ElevationKvpParser" class="org.geoserver.wcs.kvp.ElevationKvpParser">
<constructor-arg value="ELEVATION"/>
<constructor-arg ref="geoServer"/>
</bean>


<!-- kvp request readers -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import org.geotools.referencing.operation.transform.AffineTransform2D;
import org.geotools.referencing.util.CRSUtilities;
import org.geotools.util.DateRange;
import org.geotools.util.NumberRange;
import org.opengis.coverage.grid.GridCoverage;
import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.filter.Filter;
Expand Down Expand Up @@ -385,7 +386,7 @@ public GridCoverage[] getCoverage(final GetCoverageType request) {
if (elevationDimension != null
&& elevationDimension.isEnabled()
&& dimensions.hasElevation()) {
List<Double> elevations = new ArrayList<Double>();
List<Object> elevations = new ArrayList<Object>();
// extract elevation values
List axisSubset = null;
if (request.getRangeSubset() != null) {
Expand All @@ -396,29 +397,17 @@ public GridCoverage[] getCoverage(final GetCoverageType request) {

String axisName = axis.getName();
if (axisName.equalsIgnoreCase(WCSUtils.ELEVATION)) {
if (axis.getSingleValue().size() > 0) {
for (int s = 0; s < axis.getSingleValue().size(); s++) {
elevations.add(
Double.parseDouble(
((TypedLiteralType)
axis.getSingleValue()
.get(s))
.getValue()));
}
} else if (axis.getInterval().size() > 0) {
IntervalType interval =
(IntervalType) axis.getInterval().get(0);
int min = Integer.parseInt(interval.getMin().getValue());
int max = Integer.parseInt(interval.getMax().getValue());
int res =
(interval.getRes() != null
? Integer.parseInt(interval.getRes().getValue())
: 1);

int count = (int) (Math.floor(max - min) / res + 1);
for (int b = 0; b < count; b++) {
elevations.add(new Double(min + b * res));
}
// grab the elevation values
for (Object object : axis.getSingleValue()) {
TypedLiteralType value = (TypedLiteralType) object;
elevations.add(Double.parseDouble(value.getValue()));
}
// grab the elevation intervals
for (Object object : axis.getInterval()) {
IntervalType interval = (IntervalType) object;
double min = Double.parseDouble(interval.getMin().getValue());
double max = Double.parseDouble(interval.getMax().getValue());
elevations.add(NumberRange.create(min, max));
}
}
}
Expand Down Expand Up @@ -970,28 +959,6 @@ private static void checkRangeSubset(CoverageInfo info, RangeSubsetType rangeSub
"Invalid values for axis " + axisSubset.getName(),
InvalidParameterValue,
"AxisSubset");
} else if (axisSubset.getName().equalsIgnoreCase(WCSUtils.ELEVATION)) {
double[] elevations = null;
if (axisSubset.getSingleValue().size() > 0) {
elevations = new double[axisSubset.getSingleValue().size()];
for (int s = 0; s < axisSubset.getSingleValue().size(); s++) {
elevations[s] =
Double.parseDouble(
((TypedLiteralType) axisSubset.getSingleValue().get(s))
.getValue());
}
} else if (axisSubset.getInterval().size() > 0) {
IntervalType interval = (IntervalType) axisSubset.getInterval().get(0);
int min = Integer.parseInt(interval.getMin().getValue());
int max = Integer.parseInt(interval.getMax().getValue());
int res =
(interval.getRes() != null
? Integer.parseInt(interval.getRes().getValue())
: 1);

elevations = new double[(int) (Math.floor(max - min) / res + 1)];
for (int b = 0; b < elevations.length; b++) elevations[b] = (min + b * res);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* (c) 2019 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wcs.kvp;

import org.geoserver.config.GeoServer;
import org.geoserver.ows.kvp.ElevationParser;
import org.geoserver.wcs.WCSInfo;

/**
* A {@link ElevationKvpParser} picking the max number of values to be parsed from the WCS
* configuration
*/
public class ElevationKvpParser extends org.geoserver.ows.kvp.ElevationKvpParser {

private final GeoServer geoServer;

/**
* Creates the parser specifying the name of the key to latch to.
*
* @param key The key whose associated value to parse.
*/
public ElevationKvpParser(String key, GeoServer geoServer) {
super(key);
this.geoServer = geoServer;
}

protected ElevationParser getElevationParser() {
WCSInfo info = geoServer.getService(WCSInfo.class);
int maxRequestedDimensionValues = info.getMaxRequestedDimensionValues();
return new ElevationParser(maxRequestedDimensionValues);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.util.DateRange;
import org.geotools.util.NumberRange;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
Expand Down Expand Up @@ -396,6 +397,7 @@ private RangeSubsetType parseRangeSubset(Map kvp, String coverageName) {
* @param rangeSubset
* @param axis
*/
@SuppressWarnings("unchecked")
private void checkTypeAxisRange(
final RangeSubsetType rangeSubset, Object axis, String axisName) {
if (axis instanceof String) {
Expand Down Expand Up @@ -467,6 +469,27 @@ private void checkTypeAxisRange(

axisSubset.getSingleValue().add(singleValue);

rangeSubset.getAxisSubset().add(axisSubset);
} else if (axis instanceof Collection) {
AxisSubsetType axisSubset = Wcs10Factory.eINSTANCE.createAxisSubsetType();
axisSubset.setName(axisName);
for (Object value : (Collection<?>) axis) {
if (value instanceof NumberRange) {
NumberRange<?> range = (NumberRange<?>) value;
IntervalType interval = Wcs10Factory.eINSTANCE.createIntervalType();
TypedLiteralType min = Wcs10Factory.eINSTANCE.createTypedLiteralType();
TypedLiteralType max = Wcs10Factory.eINSTANCE.createTypedLiteralType();
min.setValue(Double.toString(range.getMinimum()));
max.setValue(Double.toString(range.getMaximum()));
interval.setMin(min);
interval.setMax(max);
axisSubset.getInterval().add(interval);
} else {
TypedLiteralType singleValue = Wcs10Factory.eINSTANCE.createTypedLiteralType();
singleValue.setValue(String.valueOf(value));
axisSubset.getSingleValue().add(singleValue);
}
}
rangeSubset.getAxisSubset().add(axisSubset);
}
}
Expand Down
75 changes: 75 additions & 0 deletions src/wcs1_0/src/test/java/org/geoserver/wcs/GetCoverageTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,18 @@ public void testElevationFirst() throws Exception {
checkPixelValue(response, 10, 10, 18.2849999185419);
}

@Test
public void testElevationFirstKVP() throws Exception {
String queryString =
"request=getcoverage&service=wcs&version=1.0.0&format=image/geotiff"
+ "&bbox=0.237,40.562,14.593,44.558&crs=EPSG:4326&width=25&height=25"
+ "&elevation=0.0&coverage="
+ getLayerId(WATTEMP);
MockHttpServletResponse response = getAsServletResponse("wcs?" + queryString);
assertEquals("image/tiff", response.getContentType());
checkPixelValue(response, 10, 10, 18.2849999185419);
}

@Test
public void testElevationSecond() throws Exception {
String request = getWaterTempElevationRequest("100.0");
Expand All @@ -701,6 +713,69 @@ public void testElevationSecond() throws Exception {
checkPixelValue(response, 10, 10, 13.337999683572);
}

@Test
public void testElevationSecondKVP() throws Exception {
String queryString =
"request=getcoverage&service=wcs&version=1.0.0&format=image/geotiff"
+ "&bbox=0.237,40.562,14.593,44.558&crs=EPSG:4326&width=25&height=25"
+ "&elevation=100.0&coverage="
+ getLayerId(WATTEMP);
MockHttpServletResponse response = getAsServletResponse("wcs?" + queryString);
assertEquals("image/tiff", response.getContentType());
checkPixelValue(response, 10, 10, 13.337999683572);
}

@Test
public void testElevationTooMany() throws Exception {
GeoServer gs = getGeoServer();
WCSInfo wcs = gs.getService(WCSInfo.class);
wcs.setMaxRequestedDimensionValues(2);
gs.save(wcs);
try {
String queryString =
"request=getcoverage&service=wcs&version=1.0.0&format=image/geotiff"
+ "&bbox=0.237,40.562,14.593,44.558&crs=EPSG:4326&width=25&height=25"
+ "&elevation=0.0/1000.0/1.0&coverage="
+ getLayerId(WATTEMP);
MockHttpServletResponse response = getAsServletResponse("wcs?" + queryString);
assertEquals("application/vnd.ogc.se_xml", response.getContentType());
Document dom = dom(response, true);
print(dom);
String text =
checkLegacyException(
dom, ServiceException.INVALID_PARAMETER_VALUE, "elevation");
assertThat(text, containsString("More than 2 elevations"));
} finally {
wcs.setMaxRequestedDimensionValues(
DimensionInfo.DEFAULT_MAX_REQUESTED_DIMENSION_VALUES);
gs.save(wcs);
}
}

@Test
public void testElevationRangeKVP() throws Exception {
String baseUrl =
"wcs?request=getcoverage&service=wcs&version=1.0.0&format=image/geotiff"
+ "&bbox=0.237,40.562,14.593,44.558&crs=EPSG:4326&width=25&height=25"
+ "&coverage="
+ getLayerId(WATTEMP);

// last range
MockHttpServletResponse response = getAsServletResponse(baseUrl + "&ELEVATION=75.0/100.0");
assertEquals("image/tiff", response.getContentType());
checkPixelValue(response, 10, 10, 13.337999683572);

// middle hole, no data --> we should get back an exception
Document dom = getAsDOM(baseUrl + "&ELEVATION=25.0/75.0");
// print(dom);
XMLAssert.assertXpathEvaluatesTo("1", "count(//ServiceExceptionReport)", dom);

// first range
response = getAsServletResponse(baseUrl + "&ELEVATION=0.0/25.0");
assertEquals("image/tiff", response.getContentType());
checkPixelValue(response, 10, 10, 18.2849999185419);
}

private String getWaterTempElevationRequest(String elevation) {
String request =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
Expand Down

0 comments on commit 0d11a53

Please sign in to comment.