Convertir lat / long en JTS?
j'essaie d'intégrer Hibernate spatial avec JPA pour les recherches géo. J'ai été référencement tutoriel sur le site officiel (Je ne suis pas associé à hibernatespatial).
le tutoriel, malheureusement, ne couvre pas comment créer une instance de Point à partir d'une paire latitude/longitude. J'essaie de le faire ici, mais je ne suis pas sûr que ce soit la bonne façon de convertir une paire latitude/longitude en un point JTS:
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.hibernate.annotations.Type;
import javax.persistence.*;
@Entity
public class Location {
private Double latitude;
private Double longitude;
@Type(type = "org.hibernatespatial.GeometryUserType")
private Point coordinates;
private final GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
@PrePersist
@PreUpdate
public void updateCoordinate() {
if (this.latitude == null || this.longitude == null) {
this.coordinates = null;
} else {
this.coordinates = geometryFactory.createPoint(new Coordinate(latitude, longitude));
}
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
}
4 réponses
JTS ne se soucie pas de ce que sont les unités de votre point ou le système de coordonnées.
Cependant, il suppose que les coordonnées sont sur un plan Cartésien, ainsi certaines opérations de géométrie telles que les calculs de distance peuvent être inexactes sur de longues distances. (Ils ne supportent pas encore les calculs géodésiques.)
il devrait être très bien pour les utilisations simples de stockage.
cependant, un point important à noter est que la longitude est la valeur X et la latitude Le Y valeur. Donc nous disons "lat / long", mais JTS l'attendra dans l'ordre"long/lat". Donc, vous devriez être en utilisant geometryFactory.createPoint(new Coordinate(longitude, latitude))
Voici comment créer vos coordonnées dans WGS-84 :
double EARTH_RADIUS = 6378137.0;
double x = longitude * EARTH_RADIUS * Math.PI / 180.;
double y = EARTH_RADIUS * Math.sin(Math.toRadians(latitude));
return new Coordinate(x,y,0.);
Cheers
pour résumer ce que les autres ont dit, lors de la conversion pour coordonner Il ya 3 choses principales à prendre en charge:
- Projection. JTS fonctionne dans un plan cartésien, donc toute distorsion de Mercator se propage dans votre calcul. Par conséquent, vous ne devez l'utiliser sur une zone assez courte. Je ne suis pas sûr de l'ampleur exacte, mais je pense que tout ce qui est en dessous d'un certain degré d'expansion devrait être parfait. Restez en dessous de 0.1 degré et vous êtes définitivement sur le coffre-fort côté.
- Unités. vous pouvez parfaitement mettre n'importe quelle unité dans JTS. Le problème est que vous ne pouvez pas dire JTS si vous utilisez des compteurs, ou des degrés, ou quoi que ce soit d'autre. Donc, vous devez prendre soin vous-même que vous vous en tenez à une unité, ou convertir chaque fois que nécessaire.
- Standard. la norme ISO stipule que les coordonnées géospatiales sont fournies lat en premier. Toutefois, elle est en concurrence avec les normes GeoJSON/WKT qui, toutes deux, déclarent lon en premier lieu, donc à l'inverse. Les deux les groupes standards ont des applications qui s'y collent (par exemple, Apache Lucene a changé les standards entre les versions sans changer la signature de la méthode, ce qui cause des maux de tête à des centaines d'utilisateurs qui se demandent pourquoi leurs cartes ont subitement été retournées), et JTS maintient la version GeoJSON/WKT. Faites attention à ce que partout où vous passez les données d'une autre bibliothèque - il peut suivre GeoJSON et WKT, ou ISO, vous devriez vous informer à l'avance. (Croyez-moi. J'ai déjà eu du mal avec ce, et ça peut être vraiment agaçant de parcourir tout le code et de passer la commande.)
Donc, non, ce n'est pas de droit. Tu marches droit dans le troisième problème. JTS est lon de première.
vous pouvez aussi utiliser Neo4j Spatial au lieu de mise en veille prolongée. Il utilise le graphe de la vitesse d'interrogation de Neo4j, et a intégré le support JTS. Il dispose également de L'une des API Java les plus confortables autour D'IMHO.
j'ai eu le même problème ici, et j'ai traduit les coords de Lat/Long à l'UTM (voir http://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system).
fondamentalement vous convertissez de Lat / Long à une paire (X,Y), mais le fait intéressant est que ces X et Y sont des compteurs réels, de sorte que vous pouvez faire des calculs précis qui dépendent de la distance. (En fait, vous devez tenir compte d'une petite distorsion, mais négligeable lorsque vous parlez de mètre-échelle exactitude.)
Je n'étais pas vraiment content des fonctions LatLong2UTM que les cadres Java existants fournissaient, donc j'ai déployé les miens. J'en ai porté un d'un convertisseur javascript en ligne sans trop de problèmes.