Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: set default styles parameter in GetMap requests #553

Merged
merged 2 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletResponse;
import org.jdom2.Document;
import org.jdom2.Element;
Expand All @@ -20,13 +19,9 @@
import org.jdom2.xpath.XPathFactory;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.lang.invoke.MethodHandles;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import thredds.test.util.TestOnLocalServer;
Expand All @@ -40,7 +35,6 @@
import static com.google.common.truth.Truth.assertWithMessage;

public class TestWmsServer {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

private static final double TOLERANCE = 1.0e-8;
private final Namespace NS_WMS = Namespace.getNamespace("wms", "http://www.opengis.net/wms");
Expand Down Expand Up @@ -72,8 +66,8 @@ public void testCapabilities() throws IOException, JDOMException {
public void testGetPng() {
String endpoint =
TestOnLocalServer.withHttpPath("/wms/scanCdmUnitTests/conventions/cf/ipcc/tas_A1.nc?service=WMS&version=1.3.0"
+ "&request=GetMap&CRS=CRS:84&WIDTH=512&HEIGHT=512&LAYERS=tas&BBOX=0,-90,360,90&format="
+ ContentType.png.toString() + "&time=1850-01-16T12:00:00Z");
+ "&request=GetMap&CRS=CRS:84&WIDTH=512&HEIGHT=512&LAYERS=tas&BBOX=0,-90,360,90&format=" + ContentType.png
+ "&time=1850-01-16T12:00:00Z");
testGetPng(endpoint);
}

Expand All @@ -83,17 +77,26 @@ public void testGetPngInAnotherProjection() {
String endpoint =
TestOnLocalServer.withHttpPath("/wms/scanCdmUnitTests/conventions/cf/ipcc/tas_A1.nc?service=WMS&version=1.3.0"
+ "&request=GetMap&CRS=EPSG:3857&WIDTH=512&HEIGHT=512&LAYERS=tas&BBOX=0,-90,360,90&format="
+ ContentType.png.toString() + "&time=1850-01-16T12:00:00Z");
+ ContentType.png + "&time=1850-01-16T12:00:00Z");
testGetPng(endpoint);
}

private static void testGetPng(String endpoint) {
byte[] result = TestOnLocalServer.getContent(endpoint, HttpServletResponse.SC_OK, ContentType.png.toString());
// make sure we get a png back
// first byte (unsigned) should equal 137 (decimal)
assertThat(result[0] & 0xFF).isEqualTo(137);
// bytes 1, 2, and 3, when interperted as ASCII, should be P N G
assertThat(new String(((byte[]) Arrays.copyOfRange(result, 1, 4)), Charset.forName("US-ASCII"))).isEqualTo("PNG");
@Test
@Category(NeedsCdmUnitTest.class)
public void testGetMapPaletteDefault() {
String basePath = "/wms/scanLocal/2004050300_eta_211.nc?TRANSPARENT=TRUE&LAYERS=Z_sfc&"
+ "TIME=2003-09-25T00%3A00%3A00.000Z&COLORSCALERANGE=0%2C2920&NUMCOLORBANDS=20&ABOVEMAXCOLOR=0x000000&"
+ "BELOWMINCOLOR=0xFF0000FF&BGCOLOR=transparent&LOGSCALE=false&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&"
+ "SRS=EPSG%3A4326&BBOX=-171.36,32.88,-48.48,155.76&WIDTH=256&HEIGHT=256&format=" + ContentType.png;

String endpointNoStyles = TestOnLocalServer.withHttpPath(basePath);
String endpointEmptyStyles = TestOnLocalServer.withHttpPath(basePath + "&STYLES=");
String endpointExpectedStyles = TestOnLocalServer.withHttpPath(basePath + "&STYLES=default-scalar%2Fx-Occam");
String endpointDiffStyles = TestOnLocalServer.withHttpPath(basePath + "&STYLES=default-scalar%2Fx-Rainbow");

assertThat(testGetPng(endpointNoStyles)).isEqualTo(testGetPng(endpointExpectedStyles));
assertThat(testGetPng(endpointEmptyStyles)).isEqualTo(testGetPng(endpointExpectedStyles));
assertThat(testGetPng(endpointDiffStyles)).isNotEqualTo(testGetPng(endpointExpectedStyles));
}

@Test
Expand All @@ -102,13 +105,9 @@ public void testGetLegendGraphic() {
String endpoint =
TestOnLocalServer.withHttpPath("/wms/scanCdmUnitTests/conventions/cf/ipcc/tas_A1.nc?service=WMS&version=1.3.0"
+ "&request=GetLegendGraphic&Layers=tas&colorscalerange=225.0,310.0&style=default-scalar/x-Rainbow&format="
+ ContentType.png.toString());
byte[] result = TestOnLocalServer.getContent(endpoint, HttpServletResponse.SC_OK, ContentType.png.toString());
// make sure we get a png back
// first byte (unsigned) should equal 137 (decimal)
assertThat(result[0] & 0xFF).isEqualTo(137);
// bytes 1, 2, and 3, when interperted as ASCII, should be P N G
assertThat(new String(((byte[]) Arrays.copyOfRange(result, 1, 4)), Charset.forName("US-ASCII"))).isEqualTo("PNG");
+ ContentType.png);

testGetPng(endpoint);
}

@Test
Expand All @@ -118,14 +117,9 @@ public void testGetLegendGraphicWithSLD() {
try {
String endpoint = TestOnLocalServer.withHttpPath(
"/wms/scanCdmUnitTests/conventions/cf/ipcc/tas_A1.nc?service=WMS&version=1.3.0&request=GetLegendGraphic&Layers=tas&format="
+ ContentType.png.toString()
+ ContentType.png
+ "&SLD_BODY=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22ISO-8859-1%22%3F%3E%20%3CStyledLayerDescriptor%20version%3D%221.1.0%22%20xsi%3AschemaLocation%3D%22http%3A%2F%2Fwww.opengis.net%2Fsld%20StyledLayerDescriptor.xsd%22%20xmlns%3D%22http%3A%2F%2Fwww.opengis.net%2Fsld%22%20xmlns%3Aogc%3D%22http%3A%2F%2Fwww.opengis.net%2Fogc%22%20xmlns%3Ase%3D%22http%3A%2F%2Fwww.opengis.net%2Fse%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20xmlns%3Axsi%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%3E%20%3CNamedLayer%3E%20%3Cse%3AName%3Etas%3C%2Fse%3AName%3E%20%3CUserStyle%3E%20%3Cse%3AName%3EThesholded%20colour%20scheme%3C%2Fse%3AName%3E%20%3Cse%3ACoverageStyle%3E%20%3Cse%3ARule%3E%20%3Cse%3ARasterSymbolizer%3E%20%3Cse%3AOpacity%3E1.0%3C%2Fse%3AOpacity%3E%20%3Cse%3AColorMap%3E%20%3Cse%3ACategorize%20fallbackValue%3D%22%2300000000%22%3E%20%3Cse%3ALookupValue%3ERasterdata%3C%2Fse%3ALookupValue%3E%20%3Cse%3AValue%3E%23FF0000FF%3C%2Fse%3AValue%3E%20%3Cse%3AThreshold%3E275.0%3C%2Fse%3AThreshold%3E%20%3Cse%3AValue%3E%23FF00FFFF%3C%2Fse%3AValue%3E%20%3Cse%3AThreshold%3E280.0%3C%2Fse%3AThreshold%3E%20%3Cse%3AValue%3E%23FF00FF00%3C%2Fse%3AValue%3E%20%3Cse%3AThreshold%3E285.0%3C%2Fse%3AThreshold%3E%20%3Cse%3AValue%3E%23FFFFFF00%3C%2Fse%3AValue%3E%20%3Cse%3AThreshold%3E290.0%3C%2Fse%3AThreshold%3E%20%3Cse%3AValue%3E%23FFFFC800%3C%2Fse%3AValue%3E%20%3Cse%3AThreshold%3E295.0%3C%2Fse%3AThreshold%3E%20%3Cse%3AValue%3E%23FFFFAFAF%3C%2Fse%3AValue%3E%20%3Cse%3AThreshold%3E300.0%3C%2Fse%3AThreshold%3E%20%3Cse%3AValue%3E%23FFFF0000%3C%2Fse%3AValue%3E%20%3C%2Fse%3ACategorize%3E%20%3C%2Fse%3AColorMap%3E%20%3C%2Fse%3ARasterSymbolizer%3E%20%3C%2Fse%3ARule%3E%20%3C%2Fse%3ACoverageStyle%3E%20%3C%2FUserStyle%3E%20%3C%2FNamedLayer%3E%20%3C%2FStyledLayerDescriptor%3E");
byte[] result = TestOnLocalServer.getContent(endpoint, HttpServletResponse.SC_OK, ContentType.png.toString());
// make sure we get a png back
// first byte (unsigned) should equal 137 (decimal)
assertThat(result[0] & 0xFF).isEqualTo(137);
// bytes 1, 2, and 3, when interperted as ASCII, should be P N G
assertThat(new String(((byte[]) Arrays.copyOfRange(result, 1, 4)), Charset.forName("US-ASCII"))).isEqualTo("PNG");
byte[] result = testGetPng(endpoint);
} finally {
System.setProperty("httpservices.urlencode", "true");
}
Expand Down Expand Up @@ -192,7 +186,7 @@ public void shouldGetMapInParallel() throws InterruptedException {
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}).collect(Collectors.toList());
}).toList();

assertWithMessage("result codes = " + Arrays.toString(resultCodes.toArray()))
.that(resultCodes.stream().allMatch(code -> code.equals(HttpServletResponse.SC_OK))).isTrue();
Expand Down Expand Up @@ -227,4 +221,14 @@ private void checkValue(String endpoint, double expectedValue) throws IOExceptio
assertThat(element.getContentSize()).isEqualTo(1);
assertThat(Double.valueOf(element.getText())).isWithin(TOLERANCE).of(expectedValue);
}

private static byte[] testGetPng(String endpoint) {
byte[] result = TestOnLocalServer.getContent(endpoint, HttpServletResponse.SC_OK, ContentType.png.toString());
// make sure we get a png back
// first byte (unsigned) should equal 137 (decimal)
assertThat(result[0] & 0xFF).isEqualTo(137);
// bytes 1, 2, and 3, when interpreted as ASCII, should be P N G
assertThat(new String(Arrays.copyOfRange(result, 1, 4), StandardCharsets.US_ASCII)).isEqualTo("PNG");
return result;
}
}
8 changes: 8 additions & 0 deletions tds/src/main/java/thredds/server/wms/ThreddsWmsServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.google.common.cache.RemovalListener;
import com.google.common.util.concurrent.UncheckedExecutionException;
import java.io.IOException;
import java.util.Collections;
import java.util.Formatter;
import java.util.concurrent.ExecutionException;
import org.slf4j.Logger;
Expand Down Expand Up @@ -70,6 +71,8 @@
public class ThreddsWmsServlet extends WmsServlet {
private static final Logger logger = LoggerFactory.getLogger(ThreddsWmsServlet.class);

private static final Map<String, String> defaultStyles = Collections.singletonMap("styles", "default");

private static class CachedWmsCatalogue {
public final ThreddsWmsCatalogue wmsCatalogue;
public final long lastModified;
Expand Down Expand Up @@ -112,6 +115,11 @@ protected void dispatchWmsRequest(String request, RequestParams params, HttpServ
TdsRequestedDataset tdsDataset = new TdsRequestedDataset(httpServletRequest, removePrefix);
ThreddsWmsCatalogue catalogue = acquireCatalogue(httpServletRequest, httpServletResponse, tdsDataset.getPath());

// set default style if needed
if (request.equals("GetMap") && params.getString("styles", "").isEmpty()) {
params = params.mergeParameters(defaultStyles);
}

/*
* Now that we've got a WmsCatalogue, we can pass this request to the
* super implementation which will handle things from here.
Expand Down
Loading