Mercurial > dive4elements > river
diff flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticWKmsArtifact.java @ 3272:31168ac9c7e7
Partial fix for issue694 (heightmarks snap to nearest cross section).
flys-artifacts/trunk@4916 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Felix Wolfsteller <felix.wolfsteller@intevation.de> |
---|---|
date | Tue, 10 Jul 2012 15:31:56 +0000 |
parents | ed07dd55f487 |
children | 739aa90eb79e |
line wrap: on
line diff
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticWKmsArtifact.java Tue Jul 10 13:26:13 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/StaticWKmsArtifact.java Tue Jul 10 15:31:56 2012 +0000 @@ -16,6 +16,7 @@ import de.intevation.artifacts.Artifact; import de.intevation.artifacts.ArtifactFactory; import de.intevation.artifacts.CallMeta; +import de.intevation.flys.artifacts.math.Distance; import de.intevation.flys.artifacts.math.Linear; import de.intevation.flys.artifacts.model.CrossSectionWaterLineFacet; @@ -34,6 +35,7 @@ import de.intevation.flys.model.FastCrossSectionLine; + /** * Artifact to access additional "waterlevel"-type of data, like the height * of protective measures (dikes). @@ -52,6 +54,11 @@ public static final String STATIC_STATE_NAME = "state.additional_wkms.static"; + /** Data Item name to know whether we are Heighmarks and reveive + * some data slightly different. */ + public static final String DATA_HEIGHT_TYPE = + "height_marks"; + /** One and only state to be in. */ protected transient State state = null; @@ -110,6 +117,7 @@ String name; if (parts[0].equals(HEIGHTMARKS_POINTS)) { name = HEIGHTMARKS_POINTS; + addStringData(DATA_HEIGHT_TYPE, "true"); } else { name = STATIC_WKMS; @@ -266,6 +274,34 @@ /** + * Get the W at a specific km, only if it is closer to km than to any of + * the other given km. + * Return Double.NaN otherwise + * + * @param wkms WKms in which to search for a spatially close W value. + * @param km the input km, which is compared to values from wkms. + * @param next the next available input km. + * @param prev the previous available input km. + * + * @return W in wkms that is closer to km than to next and prev, or Double.NaN. + */ + public double getWAtCloseKm(WKms wkms, double km, double next, double prev) { + int size = wkms.size(); + // TODO handle edge cases (with no next or prev). + for (int i = 0; i < size; i++) { + double wkmsKm = wkms.getKm(i); + double dist = Distance.distance(wkmsKm, km); + if ((prev != km && dist <= Distance.distance(wkmsKm, prev)) + && dist <= Distance.distance(wkmsKm, next)) { + return wkms.getW(i); + } + } + + return Double.NaN; + } + + + /** * Returns W at Km of WKms, searching linearly. * Returns -1 if not found. * @param wkms the WKms object to search for given km. @@ -273,10 +309,11 @@ * @return W at given km if in WKms, -1 if not found. */ public static double getWAtKm(WKms wkms, double km) { - // Uninformed search. + // Uninformed search, intolerant. + double TOLERANCE = 0.0d; int size = wkms.size(); for (int i = 0; i < size; i++) { - if (wkms.getKm(i) == km) { + if (Distance.within(wkms.getKm(i), km, TOLERANCE)) { return wkms.getW(i); } } @@ -288,12 +325,19 @@ /** * Get points of line describing the surface of water at cross section. * + * @param idx Index of facet and in wkms array. + * @param csl FastCrossSectionLine to compute water surface agains. + * @param next The km of the next crosssectionline. + * @param prev The km of the previous crosssectionline. + * * @return an array holding coordinates of points of surface of water ( * in the form {{x1, x2}, {y1, y2}} ). */ @Override - public Lines.LineData getWaterLines(int idx, FastCrossSectionLine csl) { - logger.debug("getWaterLines(" + idx + ")"); + public Lines.LineData getWaterLines(int idx, FastCrossSectionLine csl, + double next, double prev + ) { + logger.debug("getWaterLines(" + idx + ")/" + identifier()); List<Point2D> points = csl.getPoints(); @@ -302,8 +346,18 @@ double km = csl.getKm(); // Find W at km. - double wAtKm = getWAtKm(wkms, km); - if (wAtKm == -1) { + double wAtKm; + + // If heightmarks, only deliver if data snaps. + if (getDataAsString(DATA_HEIGHT_TYPE) != null && + getDataAsString(DATA_HEIGHT_TYPE).equals("true")) { + wAtKm = getWAtCloseKm(wkms, km, next, prev); + } + else { + wAtKm = getWAtKm(wkms, km); + } + + if (wAtKm == -1 || Double.isNaN(wAtKm)) { logger.warn("Waterlevel at km " + km + " unknown."); return new Lines.LineData(new double[][] {{}}, 0d, 0d); }