/** * H2GIS is a library that brings spatial support to the H2 Database Engine * <http://www.h2database.com>. H2GIS is developed by CNRS * <http://www.cnrs.fr/>. * * This code is part of the H2GIS project. H2GIS is free software; * you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License as published by the Free Software Foundation; * version 3.0 of the License. * * H2GIS is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details <http://www.gnu.org/licenses/>. * * * For more information, please consult: <http://www.h2gis.org/> * or contact directly: info_at_h2gis.org */ package org.h2gis.functions.spatial.trigonometry; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Point; import org.h2gis.api.DeterministicScalarFunction; /** * Returns the azimuth of the segment defined by the given Point geometries. * Return value is in radians. */ public class ST_Azimuth extends DeterministicScalarFunction{ public ST_Azimuth(){ addProperty(PROP_REMARKS, "Returns the azimuth of the segment defined by the given Point geometries, \n" + "or Null if the two points are coincident. Return value is in radians. \n" + " Angle is computed clockwise from the north equals to 0."); } @Override public String getJavaStaticMethod() { return "azimuth"; } /** * This code compute the angle in radian as postgis does. * @author : Jose Martinez-Llario from JASPA. JAva SPAtial for SQL * @param pointA * @param pointB * @return */ public static Double azimuth(Geometry pointA, Geometry pointB){ if(pointA == null||pointB == null){ return null; } if ((pointA instanceof Point) && (pointB instanceof Point)) { Double angle ; double x0 = ((Point) pointA).getX(); double y0 = ((Point) pointA).getY(); double x1 = ((Point) pointB).getX(); double y1 = ((Point) pointB).getY(); if (x0 == x1) { if (y0 < y1) { angle = 0.0; } else if (y0 > y1) { angle = Math.PI; } else { angle = null; } } else if (y0 == y1) { if (x0 < x1) { angle = Math.PI / 2; } else if (x0 > x1) { angle = Math.PI + (Math.PI / 2); } else { angle = null; } } else if (x0 < x1) { if (y0 < y1) { angle = Math.atan(Math.abs(x0 - x1) / Math.abs(y0 - y1)); } else { /* ( y0 > y1 ) - equality case handled above */ angle = Math.atan(Math.abs(y0 - y1) / Math.abs(x0 - x1)) + (Math.PI / 2); } } else { /* ( x0 > x1 ) - equality case handled above */ if (y0 > y1) { angle = Math.atan(Math.abs(x0 - x1) / Math.abs(y0 - y1)) + Math.PI; } else { /* ( y0 < y1 ) - equality case handled above */ angle = Math.atan(Math.abs(y0 - y1) / Math.abs(x0 - x1)) + (Math.PI + (Math.PI / 2)); } } return angle; } return null; } }