[PATCH] Work on uinfo inundation duration calculation
Wald Commits
scm-commit at wald.intevation.org
Wed Oct 17 11:23:23 CEST 2018
# HG changeset patch
# User gernotbelger
# Date 1539768197 -7200
# Node ID bf6b63208f340aefd5adb299e54ff088e6118dc8
# Parent aa23225fd85fe6f1c29ebf7ab372688134af1fdf
Work on uinfo inundation duration calculation.
Using proxy-wms to induce additional style information (work in progress).
diff -r aa23225fd85f -r bf6b63208f34 artifacts/doc/conf/conf.xml
--- a/artifacts/doc/conf/conf.xml Tue Oct 16 16:42:22 2018 +0200
+++ b/artifacts/doc/conf/conf.xml Wed Oct 17 11:23:17 2018 +0200
@@ -312,6 +312,10 @@
service="org.dive4elements.river.artifacts.services.SedimentLoadInfoService"
description="Returns sedimentloads.">org.dive4elements.artifactdatabase.DefaultServiceFactory</service-factory>
</service-factories>
+
+ <restful-services>
+ <restful-service class="org.dive4elements.river.artifacts.uinfo.inundationduration.VegetationWmsResource" path="/vegetationWms/{vegetation-artifact-uuid}/{wmsUrl}"/>
+ </restful-services>
</factories>
diff -r aa23225fd85f -r bf6b63208f34 artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationAccess.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationAccess.java Tue Oct 16 16:42:22 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationAccess.java Wed Oct 17 11:23:17 2018 +0200
@@ -11,8 +11,10 @@
package org.dive4elements.river.artifacts.uinfo.inundationduration;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
-import org.dive4elements.artifacts.CallMeta;
+import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.access.RangeAccess;
import org.dive4elements.river.artifacts.common.EpochYearAccessHelper;
import org.dive4elements.river.artifacts.resources.Resources;
@@ -38,6 +40,34 @@
private final EpochYearAccessHelper helper;
+ public static enum WmsClassification {
+ asIs {
+ @Override
+ public String configureAddress(final String serverAddress, final String url, final String vegetationZoneId) {
+ return url;
+ }
+ },
+ vegetationZone {
+ @Override
+ public String configureAddress(final String serverAddress, final String url, final String vegetationZoneId) {
+
+ try {
+ final String urlEncoded = URLEncoder.encode(url, "UTF-8");
+ final String vegZoneIdEncoded = URLEncoder.encode(vegetationZoneId, "UTF-8");
+
+ return String.format("%s/%s/%s/%s", serverAddress, VegetationWmsResource.BASE_PATH, vegZoneIdEncoded, urlEncoded);
+ }
+ catch (final UnsupportedEncodingException e) {
+ /* should never happen */
+ e.printStackTrace();
+ return null;
+ }
+ }
+ };
+
+ public abstract String configureAddress(String serverAddress, String url, String vegetationZoneId);
+ }
+
// Fields from state:
//
// calculation_mode (String)
@@ -64,47 +94,42 @@
return false;
}
- public WmsLayer createWMSLayer(final CallMeta meta, final String i10nKey) {
+ public WmsLayer createWMSLayer(final CallContext context, final String i10nKey, final WmsClassification classification, final String vegZoneId)
+ throws IOException, TsvReaderException {
final YearType type = isUseYear() ? YearType.jahre : YearType.mittel;
final String selectedElement = getSelectedLabel();
- final String layerLabel = Resources.getMsg(meta, i10nKey, new Object[] { selectedElement });
+ final String layerLabel = Resources.getMsg(context.getMeta(), i10nKey, new Object[] { selectedElement });
- try {
- final UedauernConfiguration helper = UedauernConfiguration.getInstance(getRiverName(), type);
- final String url = helper.getUrl(selectedElement);
- final String layer = helper.getLayer(selectedElement);
-
- return new WmsLayer(layerLabel, url, layer, true);
- }
- catch (final IOException | TsvReaderException e) {
- e.printStackTrace();
- }
- return null;
-
+ return createWMSLayer(context, layerLabel, type, selectedElement, classification, vegZoneId);
}
- public WmsLayer createScenarioWMSLayer(final CallMeta meta, final String i10nKey) {
+ public WmsLayer createScenarioWMSLayer(final CallContext context, final String i10nKey, final WmsClassification classification, final String vegZoneId)
+ throws IOException, TsvReaderException {
// FIXME: use scenario-cm as label, and scenario-type
final YearType type = YearType.jahre;
+
final String selectedElement = Integer.toString(getDwspl());
+ final String layerLabel = Resources.getMsg(context.getMeta(), i10nKey, new Object[] { selectedElement });
- final String layerLabel = Resources.getMsg(meta, i10nKey, new Object[] { selectedElement });
+ return createWMSLayer(context, layerLabel, type, selectedElement, classification, vegZoneId);
+ }
- try {
- final UedauernConfiguration helper = UedauernConfiguration.getInstance(getRiverName(), type);
- final String url = helper.getUrl(selectedElement);
- final String layer = helper.getLayer(selectedElement);
+ private WmsLayer createWMSLayer(final CallContext context, final String layerLabel, final YearType type, final String selectedElement,
+ final WmsClassification classification, final String vegZoneId)
+ throws IOException, TsvReaderException {
- return new WmsLayer(layerLabel, url, layer, false);
- }
- catch (final IOException | TsvReaderException e) {
- e.printStackTrace();
- }
- return null;
+ final String serverAddress = context.getDatabase().getServerAddress();
+ final UedauernConfiguration config = UedauernConfiguration.getInstance(getRiverName(), type);
+ final String url = config.getUrl(selectedElement);
+ final String layer = config.getLayer(selectedElement);
+
+ final String realUrl = classification.configureAddress(serverAddress, url, vegZoneId);
+
+ return new WmsLayer(layerLabel, realUrl, layer, classification == WmsClassification.asIs);
}
private String getSelectedLabel() {
diff -r aa23225fd85f -r bf6b63208f34 artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationCalculation.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationCalculation.java Tue Oct 16 16:42:22 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationCalculation.java Wed Oct 17 11:23:17 2018 +0200
@@ -9,12 +9,15 @@
*/
package org.dive4elements.river.artifacts.uinfo.inundationduration;
+import java.io.IOException;
import java.util.List;
import org.dive4elements.artifacts.CallContext;
import org.dive4elements.river.artifacts.model.Calculation;
import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.sinfo.tkhstate.TsvHelper.TsvReaderException;
import org.dive4elements.river.artifacts.uinfo.UINFOArtifact;
+import org.dive4elements.river.artifacts.uinfo.inundationduration.InundationDurationAccess.WmsClassification;
import org.dive4elements.river.artifacts.uinfo.inundationduration.InundationDurationCalculationResult.WmsLayer;
import org.dive4elements.river.artifacts.uinfo.vegetationzones.VegetationZoneServerClientXChange;
@@ -33,35 +36,46 @@
public CalculationResult calculate(final UINFOArtifact uinfo) {
final Calculation problems = new Calculation();
- final InundationDurationAccess indurax = new InundationDurationAccess(uinfo);
+ try {
+ final InundationDurationAccess indurax = new InundationDurationAccess(uinfo);
- final String zonesRaw = indurax.getVegZones();
- final List<VegetationZoneServerClientXChange> zones = VegetationZoneServerClientXChange.parse(zonesRaw);
+ final String zonesRaw = indurax.getVegZones();
+ final List<VegetationZoneServerClientXChange> zones = VegetationZoneServerClientXChange.parse(zonesRaw);
+ // FIXME: instead find out a-uuid of referenced vegetations
+ // FIXME:
+ final String vegZoneId = "unknown";
- final boolean isUseScenario = indurax.getIsUseScenario();
+ final boolean isUseScenario = indurax.getIsUseScenario();
- final InundationDurationCalculationResult result = new InundationDurationCalculationResult();
+ final InundationDurationCalculationResult result = new InundationDurationCalculationResult();
- final WmsLayer inundationDurationLayer = indurax.createWMSLayer(this.context.getMeta(), "uinfo.export.url.inundationduration.inundationduration");
- result.addLayer(inundationDurationLayer);
+ final WmsLayer inundationDurationLayer = indurax.createWMSLayer(this.context, "uinfo.export.url.inundationduration.inundationduration",
+ WmsClassification.asIs, vegZoneId);
+ result.addLayer(inundationDurationLayer);
- // TODO: add vegetationzone-values as parameter to url and use this url as veg'zone'url
- final WmsLayer vegetationLayer = indurax.createWMSLayer(this.context.getMeta(), "uinfo.export.url.inundationduration.vegetation");
- result.addLayer(vegetationLayer);
+ final WmsLayer vegetationLayer = indurax.createWMSLayer(this.context, "uinfo.export.url.inundationduration.vegetation",
+ WmsClassification.vegetationZone, vegZoneId);
+ result.addLayer(vegetationLayer);
- if (isUseScenario) {
- // TODO: wieder einkommentieren, sobald die URL-Definition für Szenarien geklärt ist (und hoffentlich analog zu "mittel"
- // und "jahre" funktioniert)
- // final WmsLayer scenarioInundationDurationLayer = indurax.createScenarioWMSLayer(this.context.getMeta(),
- // "uinfo.export.url.inundationduration.scenario");
- // result.addLayer(scenarioInundationDurationLayer);
- //
- // // TODO: add vegetationzone-values as styles to layer
- // final WmsLayer scenarioVegetationLayer = indurax.createScenarioWMSLayer(this.context.getMeta(),
- // "uinfo.export.url.inundationduration.vegetation_scenario");
- // result.addLayer(scenarioVegetationLayer);
+ if (isUseScenario) {
+ // TODO: wieder einkommentieren, sobald die URL-Definition für Szenarien geklärt ist (und hoffentlich analog zu "mittel"
+ // und "jahre" funktioniert)
+ // final WmsLayer scenarioInundationDurationLayer = indurax.createScenarioWMSLayer(this.context.getMeta(),
+ // "uinfo.export.url.inundationduration.scenario");
+ // result.addLayer(scenarioInundationDurationLayer);
+ //
+ // // TODO: add vegetationzone-values as styles to layer
+ // final WmsLayer scenarioVegetationLayer = indurax.createScenarioWMSLayer(this.context.getMeta(),
+ // "uinfo.export.url.inundationduration.vegetation_scenario");
+ // result.addLayer(scenarioVegetationLayer);
+ }
+
+ return new CalculationResult(result, problems);
}
-
- return new CalculationResult(result, problems);
+ catch (IOException | TsvReaderException e) {
+ e.printStackTrace();
+ problems.addProblem("Invalid server configuration: " + e.getLocalizedMessage());
+ return new CalculationResult(null, problems);
+ }
}
}
\ No newline at end of file
diff -r aa23225fd85f -r bf6b63208f34 artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationCalculationResult.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationCalculationResult.java Tue Oct 16 16:42:22 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationCalculationResult.java Wed Oct 17 11:23:17 2018 +0200
@@ -18,10 +18,16 @@
*/
final class InundationDurationCalculationResult implements Serializable {
- public static final class WmsLayer {
+ public static final class WmsLayer implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
private final String label;
+
private final String url;
+
private final boolean showLayerLink;
+
private final String layer;
public WmsLayer(final String label, final String url, final String layer, final boolean showLayerLink) {
diff -r aa23225fd85f -r bf6b63208f34 artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationState.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationState.java Tue Oct 16 16:42:22 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/InundationDurationState.java Wed Oct 17 11:23:17 2018 +0200
@@ -108,8 +108,6 @@
index++; // because super.computeAdvance adds the river theme with index 0
}
- // tODO: create layer links: filter by "showLayerLink"
-
final Calculation report = res.getReport();
if (report.hasProblems())
facets.add(new ReportFacet(ComputeType.ADVANCE, hash, this.id));
diff -r aa23225fd85f -r bf6b63208f34 artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/VegetationWmsResource.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/uinfo/inundationduration/VegetationWmsResource.java Wed Oct 17 11:23:17 2018 +0200
@@ -0,0 +1,157 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.artifacts.uinfo.inundationduration;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.WritableRaster;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import javax.imageio.ImageIO;
+
+import org.dive4elements.artifactdatabase.rest.BaseResource;
+import org.restlet.Client;
+import org.restlet.Context;
+import org.restlet.Request;
+import org.restlet.Response;
+import org.restlet.data.Form;
+import org.restlet.data.MediaType;
+import org.restlet.data.Method;
+import org.restlet.data.Protocol;
+import org.restlet.data.Reference;
+import org.restlet.data.Status;
+import org.restlet.representation.OutputRepresentation;
+import org.restlet.representation.Representation;
+import org.restlet.resource.ResourceException;
+
+/**
+ * Proof of context wms proxy.
+ *
+ * @author Gernot Belger
+ */
+public class VegetationWmsResource extends BaseResource {
+
+ public static final String BASE_PATH = "vegetationWms";
+
+ private static final String ATTRIBUTE_VEGETATION_ARTIFACT_UUID = "vegetation-artifact-uuid";
+
+ private static final String ATTRIBUTE_WMS_URL = "wmsUrl";
+
+ private static final ThreadLocal<Client> CLIENT = new ThreadLocal<Client>() {
+ @Override
+ protected Client initialValue() {
+
+ final List<Protocol> protocols = Arrays.asList(Protocol.HTTPS, Protocol.HTTP);
+ final Client client = new Client(new Context(), protocols);
+ // FIXME
+ client.getContext().getParameters().add("proxyHost", "proxy.bce01.de");
+ client.getContext().getParameters().add("proxyPort", "8080");
+ return client;
+ }
+ };
+
+ @Override
+ protected Representation innerGet() throws ResourceException {
+
+ try {
+ final Request request = getRequest();
+
+ final Map<String, Object> attributes = request.getAttributes();
+ final String vegArtifactUuid = (String) attributes.get(ATTRIBUTE_VEGETATION_ARTIFACT_UUID);
+ final String baseUrl = (String) attributes.get(ATTRIBUTE_WMS_URL);
+
+ final Reference originalRef = request.getOriginalRef();
+ final String query = originalRef.getQuery();
+
+ final Form queryAsForm = originalRef.getQueryAsForm();
+ final boolean isGetMap = "GetMap".equalsIgnoreCase(queryAsForm.getFirstValue("REQUEST", true));
+
+ final String decodedBaseUrl = URLDecoder.decode(baseUrl, "UTF-8");
+
+ final Reference proxyReference = new Reference(decodedBaseUrl);
+ proxyReference.setQuery(query);
+
+ final Client client = CLIENT.get();
+
+ final Request proxyRequest = new Request(Method.GET, proxyReference);
+ final Response response = client.handle(proxyRequest);
+
+ final Status status = response.getStatus();
+
+ if (!Status.SUCCESS_OK.equals(status))
+ throw new ResourceException(status);
+
+ final Representation entity = response.getEntity();
+
+ /* simply redirect everything that is not an png image */
+ if (!isGetMap)
+ return entity;
+
+ final MediaType mediaType = entity.getMediaType();
+ if (!MediaType.IMAGE_ALL.getMainType().equals(mediaType.getMainType()))
+ return entity;
+
+ try {
+ final BufferedImage image = ImageIO.read(entity.getStream());
+
+ // FIXME: tweak image...
+ final WritableRaster raster = image.getRaster();
+ final int width = raster.getWidth();
+ final int height = raster.getHeight();
+ final int numBands = raster.getNumBands();
+ for (int x = 0; x < width; x++) {
+ for (int y = 0; y < height; y++) {
+
+ // final double sampleDouble = raster.getSampleDouble(x, y, 0);
+
+ final int red = raster.getSample(x, y, 0);
+ final int green = raster.getSample(x, y, 1);
+ final int blue = raster.getSample(x, y, 2);
+ final int alpha = raster.getSample(x, y, 3);
+
+ raster.setSample(x, y, 0, green);
+ raster.setSample(x, y, 1, red);
+ raster.setSample(x, y, 2, blue);
+ raster.setSample(x, y, 3, alpha);
+ }
+ }
+
+
+ final Representation newResponse = new OutputRepresentation(mediaType) {
+
+ @Override
+ public void write(final OutputStream outputStream) throws IOException {
+
+ // REMARK: in most cases the media-subtype can be used as image-format name.
+ final String subType = mediaType.getSubType();
+ ImageIO.write(image, subType, outputStream);
+
+ }
+ };
+
+ return newResponse;
+ }
+ catch (final IOException e) {
+ e.printStackTrace();
+ throw new ResourceException(Status.SERVER_ERROR_INTERNAL, e);
+ }
+
+ }
+ catch (final UnsupportedEncodingException e) {
+ e.printStackTrace();
+ throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, e);
+ }
+ }
+}
\ No newline at end of file
More information about the Dive4Elements-commits
mailing list