Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/utils/WKTUtils.java @ 469:62fc63d0f71d
Added a new State in Product Verticalprofile in Timeseriespoints.
Now it will be displayed the Years where measurements happened and than only the dates of the chosen Year will be fetched and displayed.
gnv-artifacts/trunk@532 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Tim Englich <tim.englich@intevation.de> |
---|---|
date | Tue, 12 Jan 2010 12:42:53 +0000 |
parents | 7ba4c7222265 |
children | 06887e2e3f7a |
line wrap: on
line source
package de.intevation.gnv.utils; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.io.ParseException; import com.vividsolutions.jts.io.WKTReader; import de.intevation.gnv.geobackend.base.Result; import de.intevation.gnv.geobackend.base.query.QueryExecutor; import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory; import de.intevation.gnv.geobackend.base.query.exception.QueryException; import de.intevation.gnv.math.LinearFunction; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.commons.math.optimization.OptimizationException; import org.apache.commons.math.optimization.fitting.CurveFitter; import org.apache.commons.math.optimization.general.GaussNewtonOptimizer; import org.apache.commons.math.FunctionEvaluationException; import org.apache.log4j.Logger; public abstract class WKTUtils { private static Logger log = Logger.getLogger(WKTUtils.class); public static final double NAUTICAL_MILE = 1852.216d; public static final double KILOMETER = 1000d; public static boolean different(Result a, Result b, int [] indices) { for (int i = 0; i < indices.length; ++i) { String oa = a.getString(indices[i]); String ob = b.getString(indices[i]); if (oa == null && ob == null) { continue; } if (oa == null || ob == null) { return true; } if (!oa.equals(ob)) { if (log.isDebugEnabled()) { log.debug("+++++++++++++++ differs ++++++++++++++"); log.debug(" " + oa + " != " + ob); } return true; } } return false; } public static Coordinate toCoordinate(String shape) { try { return ((Point)(new WKTReader().read(shape))).getCoordinate(); } catch (ParseException pe) { log.error(pe); } return null; } public static final double toKM(double distance) { return (distance * NAUTICAL_MILE) / KILOMETER; } public static String toWKT(Coordinate coordinate) { StringBuilder sb = new StringBuilder("POINT("); sb.append(coordinate.x) .append(' ') .append(coordinate.y) .append(')'); return sb.toString(); } public static String worldEnvelopeCoordinatesToIndex( Coordinate [] coords, Collection<Result> result, String meshid, String ijkQueryID ) throws QueryException { List<java.awt.Point> points = new ArrayList<java.awt.Point>(coords.length); ArrayList<Object []> missingPoints = new ArrayList<Object []>(); createIJKPoints(coords, meshid, ijkQueryID, points, missingPoints); String additionWhere = "FEATUREID=FEATUREID"; if (missingPoints.size() == coords.length) { log.debug("cannot create index buffer"); }else { if (points.get(0) != null && points.get(2) != null){ additionWhere = "(MEDIAN.MESHPOINT.IPOSITION >= "+points.get(0).x+" AND " + " MEDIAN.MESHPOINT.JPOSITION >= "+points.get(0).y+" AND " + " MEDIAN.MESHPOINT.IPOSITION <= "+points.get(2).x+" AND " + " MEDIAN.MESHPOINT.JPOSITION <= "+points.get(2).y+")"; }else if (points.get(1) != null && points.get(3) != null){ additionWhere = "(MEDIAN.MESHPOINT.IPOSITION >= "+points.get(1).x+" AND " + " MEDIAN.MESHPOINT.JPOSITION <= "+points.get(1).y+" AND " + " MEDIAN.MESHPOINT.IPOSITION <= "+points.get(3).x+" AND " + " MEDIAN.MESHPOINT.JPOSITION >= "+points.get(3).y+")"; }else{ // 3 Points are Missing or the Points one one Side of the Envelopes are Missing boolean remainsMissingPoints = calculateIJ4MissingPoints(coords, points, missingPoints); if (!remainsMissingPoints || (points.get(0) != null && points.get(2) != null)){ additionWhere = "(MEDIAN.MESHPOINT.IPOSITION >= "+points.get(0).x+" AND " + " MEDIAN.MESHPOINT.JPOSITION >= "+points.get(0).y+" AND " + " MEDIAN.MESHPOINT.IPOSITION <= "+points.get(2).x+" AND " + " MEDIAN.MESHPOINT.JPOSITION <= "+points.get(2).y+")"; }else if (points.get(1) != null && points.get(3) != null){ additionWhere = "(MEDIAN.MESHPOINT.IPOSITION >= "+points.get(1).x+" AND " + " MEDIAN.MESHPOINT.JPOSITION <= "+points.get(1).y+" AND " + " MEDIAN.MESHPOINT.IPOSITION <= "+points.get(3).x+" AND " + " MEDIAN.MESHPOINT.JPOSITION >= "+points.get(3).y+")"; } } } return additionWhere; } public static String worldCoordinatesToIndex( Coordinate [] coords, Collection<Result> result, String meshid, String ijkQueryID ) throws QueryException { // 1. IJK Anfragen für Stuetzpunkte im Netz ausführen. List<java.awt.Point> points = new ArrayList<java.awt.Point>(coords.length); ArrayList<Object []> missingPoints = new ArrayList<Object []>(); createIJKPoints(coords, meshid, ijkQueryID, points, missingPoints); String additionWhere = "FEATUREID=FEATUREID"; if (missingPoints.size() == coords.length) { log.debug("cannot create index buffer"); } else { // generate index filter boolean remainsMissingPoints = calculateIJ4MissingPoints(coords, points, missingPoints); if (!remainsMissingPoints) { // TODO: Make Tablenames and Columns Configurable IndexBuffer ib = new IndexBuffer( points, "MEDIAN.MESHPOINT.IPOSITION", "MEDIAN.MESHPOINT.JPOSITION" ); additionWhere = ib.toWhereClause(); log.debug("Additional Where Clause = "+additionWhere); // 2. Aus diesen Stuetzpunkten den Resultset generieren. } } // if generate index filter return additionWhere; } /** * @param coords * @param points * @param missingPoints * @return */ private static boolean calculateIJ4MissingPoints( Coordinate[] coords, List<java.awt.Point> points, ArrayList<Object[]> missingPoints) { boolean remainsMissingPoints = !missingPoints.isEmpty(); if (remainsMissingPoints) { // try to guess the missing (i, j) CurveFitter iFitter = new CurveFitter(new GaussNewtonOptimizer(true)); CurveFitter jFitter = new CurveFitter(new GaussNewtonOptimizer(true)); for (int i = 0, N = points.size(); i < N; ++i) { java.awt.Point p = (java.awt.Point)points.get(i); if (p != null) { Coordinate coord = coords[i]; iFitter.addObservedPoint(coord.x, p.x); jFitter.addObservedPoint(coord.y, p.y); } } try { // XXX: Assumption: (i, j) are created by componentwise linear function. // This is surely not correct because (x, y) are in a ellipsoid projection. // TODO: use ellipsoid functions and fit with Levenberg Marquardt. double [] iParams = iFitter.fit( LinearFunction.INSTANCE, new double [] { 1d, 1d }); double [] jParams = jFitter.fit( LinearFunction.INSTANCE, new double [] { 1d, 1d }); for (int i = missingPoints.size()-1; i >= 0; --i) { Object [] a = (Object [])missingPoints.get(i); Coordinate coord = (Coordinate)a[1]; int pi = (int)Math.round(iParams[0]*coord.x + iParams[1]); int pj = (int)Math.round(jParams[0]*coord.y + jParams[1]); points.set( ((Integer)a[0]).intValue(), new java.awt.Point(pi, pj)); } remainsMissingPoints = false; // we filled the gaps } catch (FunctionEvaluationException fee) { log.error(fee); } catch (OptimizationException oe) { log.error(oe); } } return remainsMissingPoints; } /** * @param coords * @param meshid * @param ijkQueryID * @param points * @param missingPoints * @throws QueryException */ private static void createIJKPoints(Coordinate[] coords, String meshid, String ijkQueryID, List<java.awt.Point> points, ArrayList<Object []> missingPoints) throws QueryException { Collection<Result> result; QueryExecutor queryExecutor = QueryExecutorFactory .getInstance() .getQueryExecutor(); for (int i = 0; i < coords.length; i++) { String wkt = toWKT(coords[i]); result = queryExecutor.executeQuery(ijkQueryID, new String[]{meshid,wkt}); if (!result.isEmpty()){ Result resultValue = result.iterator().next(); int iPos = resultValue.getInteger(1); int jPos = resultValue.getInteger(0); log.debug("Found Pos "+iPos+"/"+jPos +" for "+wkt); points.add(i, new java.awt.Point(iPos,jPos)); }else{ log.debug("No i/j Pos found for "+wkt); missingPoints.add(new Object [] { Integer.valueOf(i), coords[i] }); points.add(i, null); // Special Case no i,j found for Coordinate } } } public static Coordinate [] toCoordinates(String wkt) { try { LineString ls = (LineString)new WKTReader().read(wkt); return ls.getCoordinates(); } catch (ParseException pe) { log.error("cannot read WKT line string", pe); } catch (ClassCastException cce) { log.error("cannot read WKT line string", cce); } return null; } }