/******************************************************************************* * Gisgraphy Project * * This library 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; either * version 2.1 of the License, or (at your option) any later version. * * This library 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. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA * * Copyright 2008 Gisgraphy project * David Masclet <davidmasclet@gisgraphy.com> * * *******************************************************************************/ package com.gisgraphy.helper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.gisgraphy.domain.geoloc.entity.GisFeature; import com.gisgraphy.domain.valueobject.Constants; import com.gisgraphy.domain.valueobject.FeatureCode; import com.gisgraphy.domain.valueobject.SRID; import com.vividsolutions.jts.geom.Point; /** * Provides useful methods for geolocalisation * * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a> */ public class GisHelper { private static final double COS0 = Math.cos(0); private static final double SIN90 = Math.sin(90); private static final String INTERSECTION = "&&"; private static final String BBOX = "BOX3D"; /** * The logger */ protected static final Logger logger = LoggerFactory .getLogger(GeolocHelper.class); /** * Return the class corresponding to the specified String or null if not * found. The Class will be searched in the 'entity' package. The search is * not case sensitive. This method is mainly used to determine an entity * Class from a web parameter * * @param classNameWithoutPackage * the simple name of the Class we want to retrieve * @return The class corresponding to the specified String or null if not * found. */ @SuppressWarnings("unchecked") public static Class<? extends GisFeature> getClassEntityFromString( String classNameWithoutPackage) { if (classNameWithoutPackage != null) { return FeatureCode.entityClass.get(classNameWithoutPackage .toLowerCase()); } return null; } /** * @param alias the * sql alias * @param latInDegree * the latitude in degree * @param longInDegree * the longitude in degree * @param distance * the boundingbox distance * @return a sql String that represents the bounding box */ public static String getBoundingBox(String alias, double latInDegree, double longInDegree, double distance) { double lat = Math.toRadians(latInDegree); double lon = Math.toRadians(longInDegree); double deltaXInDegrees = Math.abs(Math.asin(Math .sin(distance / Constants.RADIUS_OF_EARTH_IN_METERS) / Math.cos(lat))); double deltaYInDegrees = Math.abs(distance / Constants.RADIUS_OF_EARTH_IN_METERS); double minX = Math.toDegrees(lon - deltaXInDegrees); double maxX = Math.toDegrees(lon + deltaXInDegrees); double minY = Math.toDegrees(lat - deltaYInDegrees); double maxY = Math.toDegrees(lat + deltaYInDegrees); StringBuffer sb = new StringBuffer(); // {alias}.location && setSRID(BOX3D(...), 4326) sb.append(alias); sb.append(".").append(GisFeature.LOCATION_COLUMN_NAME); sb.append(" "); sb.append(INTERSECTION); sb.append(" st_setSRID("); // Construct the BBOX : 'BOX3D(-119.2705528794688 // 33.15289952334886,-117.2150071205312 34.95154047665114)'::box3d sb.append("cast ("); sb.append("'"); sb.append(BBOX); sb.append("("); sb.append(minX); // minX sb.append(" "); sb.append(minY); // minY sb.append(","); sb.append(maxX); // maxX sb.append(" "); sb.append(maxY); // maxY sb.append(")'as box3d)"); // cannot use the ::box3d notation, since // nativeSQL interprets :param as a named // parameter // end of the BBOX, finish the setSRID sb.append(", "); sb.append(SRID.WGS84_SRID.getSRID()); sb.append(") "); return sb.toString(); } /** * @param alias the * sql alias * @param latInDegree * the latitude in degree * @param longInDegree * the longitude in degree * @param distance * the boundingbox distance * @return a sql String that represents an envelope */ public static String makeEnvelope(String alias, double latInDegree, double longInDegree, double distance) { double lat = Math.toRadians(latInDegree); double lon = Math.toRadians(longInDegree); double deltaXInDegrees = Math.abs( Math.asin( Math.sin(distance / Constants.RADIUS_OF_EARTH_IN_METERS)/ Math.cos(lat) ) ); double deltaYInDegrees = Math.abs(distance / Constants.RADIUS_OF_EARTH_IN_METERS); double minX = Math.toDegrees(lon - deltaXInDegrees); double maxX = Math.toDegrees(lon + deltaXInDegrees); double minY = Math.toDegrees(lat - deltaYInDegrees); double maxY = Math.toDegrees(lat + deltaYInDegrees); //"ST_MakeEnvelope(39.875947845588854, -6.649904839690944,57.85738955675488, 11.316505067046899, 4326)"; StringBuffer sb = new StringBuffer(); // {alias}.location && setSRID(BOX3D(...), 4326) sb.append("st_contains("); sb.append("ST_MakeEnvelope("); sb.append(minX); // minX sb.append(", "); sb.append(minY); // minY sb.append(", "); sb.append(maxX); // maxX sb.append(", "); sb.append(maxY); // maxY sb.append(", "); sb.append(SRID.WGS84_SRID.getSRID()); sb.append(") "); sb.append(","); sb.append(alias); sb.append(".").append(GisFeature.LOCATION_COLUMN_NAME); sb.append(")=true "); return sb.toString(); } }