ingo@1115: /*
ingo@1115: * Copyright (c) 2010 by Intevation GmbH
ingo@1115: *
ingo@1115: * This program is free software under the LGPL (>=v2.1)
ingo@1115: * Read the file LGPL.txt coming with the software for details
ingo@1115: * or visit http://www.gnu.org/licenses/ if it does not exist.
ingo@1115: */
ingo@1115:
ingo@420: package de.intevation.gnv.utils;
ingo@420:
ingo@420: import com.vividsolutions.jts.geom.Coordinate;
sascha@519: import com.vividsolutions.jts.geom.LineString;
ingo@420: import com.vividsolutions.jts.geom.Point;
sascha@471: import com.vividsolutions.jts.geom.Polygon;
sascha@519:
ingo@420: import com.vividsolutions.jts.io.ParseException;
ingo@420: import com.vividsolutions.jts.io.WKTReader;
ingo@420:
sascha@519: import de.intevation.gnv.artifacts.ressource.RessourceFactory;
sascha@519:
ingo@420: import de.intevation.gnv.geobackend.base.Result;
sascha@519:
ingo@420: import de.intevation.gnv.geobackend.base.query.QueryExecutor;
ingo@420: import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory;
sascha@519:
ingo@420: import de.intevation.gnv.geobackend.base.query.exception.QueryException;
sascha@440:
ingo@420: import de.intevation.gnv.math.LinearFunction;
ingo@420:
ingo@507: import java.text.MessageFormat;
ingo@507: import java.text.NumberFormat;
sascha@519:
ingo@420: import java.util.ArrayList;
ingo@420: import java.util.Collection;
ingo@420: import java.util.List;
ingo@507: import java.util.Locale;
ingo@420:
sascha@519: import org.apache.commons.math.FunctionEvaluationException;
sascha@519:
ingo@420: import org.apache.commons.math.optimization.OptimizationException;
sascha@519:
ingo@420: import org.apache.commons.math.optimization.fitting.CurveFitter;
sascha@519:
ingo@420: import org.apache.commons.math.optimization.general.GaussNewtonOptimizer;
ingo@420:
ingo@420: import org.apache.log4j.Logger;
ingo@420:
ingo@806: /**
ingo@806: * A helper class which supports some useful methods to work with wkt strings.
ingo@806: *
ingo@806: * @author Ingo Weinzierl
ingo@806: */
ingo@420: public abstract class WKTUtils {
ingo@420:
ingo@420: private static Logger log = Logger.getLogger(WKTUtils.class);
ingo@420:
ingo@420: public static final double NAUTICAL_MILE = 1852.216d;
ingo@420: public static final double KILOMETER = 1000d;
ingo@420:
sascha@471: public static final String I_NAME = "MEDIAN.MESHPOINT.IPOSITION";
sascha@471: public static final String J_NAME = "MEDIAN.MESHPOINT.JPOSITION";
sascha@471:
sascha@471: public static final String TRUE_EXPRESSION = "FEATUREID=FEATUREID";
sascha@471:
ingo@507: public static final String[] COORDINATE_OUT_FORMAT = {
ingo@507: "coordinate.template.northeast",
ingo@507: "coordinate.template.southeast",
ingo@507: "coordinate.template.northwest",
ingo@507: "coordinate.template.southwest"
ingo@507: };
ingo@507:
ingo@507: public static final String DEFAULT_COORDINATE_TEMPLATE =
ingo@507: "{0}\u00b0N {1}'' {2}\u00b0E {3}''";
ingo@507:
ingo@806: /**
ingo@806: * Checks the difference of two Result
s.
ingo@806: *
ingo@806: * @param a A Result.
ingo@806: * @param b Another Result.
ingo@806: * @param indices Indices to be checked.
ingo@806: * @return true, if a and b are different - otherwise false.
ingo@806: */
ingo@423: public static boolean different(Result a, Result b, int [] indices) {
ingo@420: for (int i = 0; i < indices.length; ++i) {
ingo@420: String oa = a.getString(indices[i]);
ingo@420: String ob = b.getString(indices[i]);
ingo@420:
ingo@420: if (oa == null && ob == null) {
ingo@420: continue;
ingo@420: }
ingo@420:
ingo@420: if (oa == null || ob == null) {
ingo@420: return true;
ingo@420: }
ingo@420:
ingo@420: if (!oa.equals(ob)) {
ingo@420: return true;
ingo@420: }
ingo@420: }
ingo@420: return false;
ingo@420: }
ingo@420:
ingo@806: /**
ingo@806: * Turns a wkt string into a coordinate.
ingo@806: *
ingo@806: * @param shape A wkt string.
ingo@806: * @return wkt string as coordinate.
ingo@806: */
ingo@420: public static Coordinate toCoordinate(String shape) {
ingo@420: try {
sascha@482: return shape != null
sascha@482: ? ((Point)(new WKTReader().read(shape))).getCoordinate()
sascha@482: : null;
ingo@420: }
ingo@420: catch (ParseException pe) {
ingo@420: log.error(pe);
ingo@420: }
sascha@471: catch (ClassCastException cce) {
sascha@471: log.error("cannot read WKT point", cce);
sascha@471: }
ingo@420: return null;
ingo@420: }
ingo@420:
ingo@806: /**
ingo@806: * Turns a wkt string into a polygon.
ingo@806: *
ingo@806: * @param shape A wkt string.
ingo@806: * @return wkt string as polygon.
ingo@806: */
sascha@471: public static Polygon toPolygon(String shape) {
sascha@471: try {
sascha@471: return (Polygon)new WKTReader().read(shape);
sascha@471: }
sascha@471: catch (ParseException pe) {
sascha@471: log.error(pe);
sascha@471: }
sascha@471: catch (ClassCastException cce) {
sascha@471: log.error("cannot read WKT polygon", cce);
sascha@471: }
sascha@471: return null;
sascha@471: }
ingo@420:
ingo@806: /**
ingo@806: * Returns a distance in km.
ingo@806: *
ingo@806: * @param distance A distance.
ingo@806: * @return distance in km.
ingo@806: */
ingo@420: public static final double toKM(double distance) {
ingo@420: return (distance * NAUTICAL_MILE) / KILOMETER;
ingo@420: }
ingo@420:
ingo@420:
ingo@806: /**
ingo@806: * Turns a coordinate into a wkt string.
ingo@806: *
ingo@806: * @param coordinate A coordinate.
ingo@806: * @return the coordinate as wkt string.
ingo@806: */
ingo@420: public static String toWKT(Coordinate coordinate) {
ingo@420: StringBuilder sb = new StringBuilder("POINT(");
ingo@420: sb.append(coordinate.x)
ingo@420: .append(' ')
ingo@420: .append(coordinate.y)
ingo@420: .append(')');
ingo@420: return sb.toString();
ingo@420: }
ingo@420:
ingo@806:
sascha@471: public static final String indexBox(
sascha@778: java.awt.Point a,
sascha@471: java.awt.Point b,
sascha@471: String iName,
sascha@471: String jName
sascha@471: ) {
sascha@471: int minI = Math.min(a.x, b.x) - 1;
sascha@471: int maxI = Math.max(a.x, b.x) + 1;
sascha@471: int minJ = Math.min(a.y, b.y) - 1;
sascha@471: int maxJ = Math.max(a.y, b.y) + 1;
sascha@471: StringBuilder sb = new StringBuilder("(")
sascha@471: .append(iName).append(" >= ").append(minI)
sascha@471: .append(" AND ").append(iName).append(" <= ").append(maxI)
sascha@471: .append(" AND ").append(jName).append(" >= ").append(minJ)
sascha@471: .append(" AND ").append(jName).append(" <= ").append(maxJ)
sascha@471: .append(')');
sascha@471: return sb.toString();
sascha@471: }
sascha@471:
sascha@471: public static final String diagonalBox(List points) {
sascha@471:
sascha@471: if (points.get(0) != null && points.get(2) != null) {
sascha@471: return indexBox(
sascha@471: points.get(0), points.get(2),
sascha@471: I_NAME,
sascha@471: J_NAME);
sascha@471: }
sascha@471:
sascha@471: if (points.get(1) != null && points.get(3) != null) {
sascha@471: return indexBox(
sascha@471: points.get(1), points.get(3),
sascha@471: I_NAME,
sascha@471: J_NAME);
sascha@471: }
sascha@471:
sascha@471: return null;
sascha@471: }
sascha@471:
tim@468: public static String worldEnvelopeCoordinatesToIndex(
tim@468: Coordinate [] coords,
tim@468: String meshid,
tim@468: String ijkQueryID
tim@468: )
tim@468: throws QueryException
tim@468: {
sascha@471: List points =
sascha@471: new ArrayList(coords.length);
sascha@471:
sascha@471: ArrayList