2008-10-06 12 views
18

¿Alguien sabe de una forma, en Java, para convertir una posición de la superficie terrestre de Lat, Lon a UTM (por ejemplo, en WGS84)? Actualmente estoy buscando Geotools, pero desafortunadamente la solución no es obvia.Java, convertir lat/lon a UTM

+1

Sí La documentación de GeoTools asume que el usuario final ya estará muy familiarizado con la API y el SIG en general. Es muy difícil de entender Actualmente estoy teniendo dificultades para obtener puntos de la trama en un mapa que lo usa. http://stackoverflow.com/questions/29567231/why-cant-this-code-produce-a-points-layer-in-geotools – cj5

Respuesta

19

Pude usar Geotools 2.4 para obtener algo que funciona, basado en algunos example code.

double utmZoneCenterLongitude = ... // Center lon of zone, example: zone 10 = -123 
int zoneNumber = ...     // zone number, example: 10 
double latitude, longitude = ...  // lat, lon in degrees 

MathTransformFactory mtFactory = ReferencingFactoryFinder.getMathTransformFactory(null); 
ReferencingFactoryContainer factories = new ReferencingFactoryContainer(null); 

GeographicCRS geoCRS = org.geotools.referencing.crs.DefaultGeographicCRS.WGS84; 
CartesianCS cartCS = org.geotools.referencing.cs.DefaultCartesianCS.GENERIC_2D; 

ParameterValueGroup parameters = mtFactory.getDefaultParameters("Transverse_Mercator"); 
parameters.parameter("central_meridian").setValue(utmZoneCenterLongitude); 
parameters.parameter("latitude_of_origin").setValue(0.0); 
parameters.parameter("scale_factor").setValue(0.9996); 
parameters.parameter("false_easting").setValue(500000.0); 
parameters.parameter("false_northing").setValue(0.0); 

Map properties = Collections.singletonMap("name", "WGS 84/UTM Zone " + zoneNumber); 
ProjectedCRS projCRS = factories.createProjectedCRS(properties, geoCRS, null, parameters, cartCS); 

MathTransform transform = CRS.findMathTransform(geoCRS, projCRS); 

double[] dest = new double[2]; 
transform.transform(new double[] {longitude, latitude}, 0, dest, 0, 1); 

int easting = (int)Math.round(dest[0]); 
int northing = (int)Math.round(dest[1]); 
5

la respuesta de Alberta 10 TM es probablemente exagerada para lo que necesita: this link de trabajos de desarrollador probablemente tenga toda la información que necesita.

+1

Si bien este enlace puede responder a la pregunta, es mejor incluir las partes esenciales del responda aquí y proporcione el enlace de referencia. Las respuestas de solo enlace pueden dejar de ser válidas si la página vinculada cambia. - [De la reseña] (/ crítica/mensajes de baja calidad/17991146) –

1

Steve Dutch at University of Wisconson tiene una muy buena redacción sobre el algoritmo. También incluye un documento de Excel para ayudar a verificar sus números.

+1

Si bien este enlace puede responder a la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace de referencia. Las respuestas de solo enlace pueden dejar de ser válidas si la página vinculada cambia. - [De la opinión] (/ reseña/mensajes de baja calidad/17991149) –

9

Sugiero JCoord. Le permite convertir entre varios esquemas de coordenadas cartográficas usando una API muy simple.

Iy te sientes descarado, eche un vistazo al código fuente; son páginas y páginas de trigonometría densa. Espléndido.

También hay una versión de javascript llamada JSCoord.

0

quizás estés manipulando una gran cantidad de datos espaciales, supongo que estás utilizando una especie de dbms relacionales espacialmente habilitados como Postgres con extensión PostGIS. Podría hacer fácilmente este tipo de transformación en PostGIS, ofrece un amplio soporte de operaciones y relaciones geométricas tal como se define en los estándares OGC ...

¡solo un pensamiento!

19

Sin biblioteca, nada. ¡Copia esto!

Usando estas dos clases, puede convertir el grado (latitud/longitud) en UTM y viceversa.

private class Deg2UTM 
{ 
    double Easting; 
    double Northing; 
    int Zone; 
    char Letter; 
    private Deg2UTM(double Lat,double Lon) 
    { 
     Zone= (int) Math.floor(Lon/6+31); 
     if (Lat<-72) 
      Letter='C'; 
     else if (Lat<-64) 
      Letter='D'; 
     else if (Lat<-56) 
      Letter='E'; 
     else if (Lat<-48) 
      Letter='F'; 
     else if (Lat<-40) 
      Letter='G'; 
     else if (Lat<-32) 
      Letter='H'; 
     else if (Lat<-24) 
      Letter='J'; 
     else if (Lat<-16) 
      Letter='K'; 
     else if (Lat<-8) 
      Letter='L'; 
     else if (Lat<0) 
      Letter='M'; 
     else if (Lat<8) 
      Letter='N'; 
     else if (Lat<16) 
      Letter='P'; 
     else if (Lat<24) 
      Letter='Q'; 
     else if (Lat<32) 
      Letter='R'; 
     else if (Lat<40) 
      Letter='S'; 
     else if (Lat<48) 
      Letter='T'; 
     else if (Lat<56) 
      Letter='U'; 
     else if (Lat<64) 
      Letter='V'; 
     else if (Lat<72) 
      Letter='W'; 
     else 
      Letter='X'; 
     Easting=0.5*Math.log((1+Math.cos(Lat*Math.PI/180)*Math.sin(Lon*Math.PI/180-(6*Zone-183)*Math.PI/180))/(1-Math.cos(Lat*Math.PI/180)*Math.sin(Lon*Math.PI/180-(6*Zone-183)*Math.PI/180)))*0.9996*6399593.62/Math.pow((1+Math.pow(0.0820944379, 2)*Math.pow(Math.cos(Lat*Math.PI/180), 2)), 0.5)*(1+ Math.pow(0.0820944379,2)/2*Math.pow((0.5*Math.log((1+Math.cos(Lat*Math.PI/180)*Math.sin(Lon*Math.PI/180-(6*Zone-183)*Math.PI/180))/(1-Math.cos(Lat*Math.PI/180)*Math.sin(Lon*Math.PI/180-(6*Zone-183)*Math.PI/180)))),2)*Math.pow(Math.cos(Lat*Math.PI/180),2)/3)+500000; 
     Easting=Math.round(Easting*100)*0.01; 
     Northing = (Math.atan(Math.tan(Lat*Math.PI/180)/Math.cos((Lon*Math.PI/180-(6*Zone -183)*Math.PI/180)))-Lat*Math.PI/180)*0.9996*6399593.625/Math.sqrt(1+0.006739496742*Math.pow(Math.cos(Lat*Math.PI/180),2))*(1+0.006739496742/2*Math.pow(0.5*Math.log((1+Math.cos(Lat*Math.PI/180)*Math.sin((Lon*Math.PI/180-(6*Zone -183)*Math.PI/180)))/(1-Math.cos(Lat*Math.PI/180)*Math.sin((Lon*Math.PI/180-(6*Zone -183)*Math.PI/180)))),2)*Math.pow(Math.cos(Lat*Math.PI/180),2))+0.9996*6399593.625*(Lat*Math.PI/180-0.005054622556*(Lat*Math.PI/180+Math.sin(2*Lat*Math.PI/180)/2)+4.258201531e-05*(3*(Lat*Math.PI/180+Math.sin(2*Lat*Math.PI/180)/2)+Math.sin(2*Lat*Math.PI/180)*Math.pow(Math.cos(Lat*Math.PI/180),2))/4-1.674057895e-07*(5*(3*(Lat*Math.PI/180+Math.sin(2*Lat*Math.PI/180)/2)+Math.sin(2*Lat*Math.PI/180)*Math.pow(Math.cos(Lat*Math.PI/180),2))/4+Math.sin(2*Lat*Math.PI/180)*Math.pow(Math.cos(Lat*Math.PI/180),2)*Math.pow(Math.cos(Lat*Math.PI/180),2))/3); 
     if (Letter<'M') 
      Northing = Northing + 10000000; 
     Northing=Math.round(Northing*100)*0.01; 
    } 
} 

private class UTM2Deg 
{ 
    double latitude; 
    double longitude; 
    private UTM2Deg(String UTM) 
    { 
     String[] parts=UTM.split(" "); 
     int Zone=Integer.parseInt(parts[0]); 
     char Letter=parts[1].toUpperCase(Locale.ENGLISH).charAt(0); 
     double Easting=Double.parseDouble(parts[2]); 
     double Northing=Double.parseDouble(parts[3]);   
     double Hem; 
     if (Letter>'M') 
      Hem='N'; 
     else 
      Hem='S';    
     double north; 
     if (Hem == 'S') 
      north = Northing - 10000000; 
     else 
      north = Northing; 
     latitude = (north/6366197.724/0.9996+(1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2)-0.006739496742*Math.sin(north/6366197.724/0.9996)*Math.cos(north/6366197.724/0.9996)*(Math.atan(Math.cos(Math.atan((Math.exp((Easting - 500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*Math.pow((Easting - 500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2)))),2)/2*Math.pow(Math.cos(north/6366197.724/0.9996),2)/3))-Math.exp(-(Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2))))*(1 - 0.006739496742*Math.pow((Easting - 500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2)))),2)/2*Math.pow(Math.cos(north/6366197.724/0.9996),2)/3)))/2/Math.cos((north-0.9996*6399593.625*(north/6366197.724/0.9996-0.006739496742*3/4*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.pow(0.006739496742*3/4,2)*5/3*(3*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/4-Math.pow(0.006739496742*3/4,3)*35/27*(5*(3*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/4+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/3))/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*Math.pow((Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2)))),2)/2*Math.pow(Math.cos(north/6366197.724/0.9996),2))+north/6366197.724/0.9996)))*Math.tan((north-0.9996*6399593.625*(north/6366197.724/0.9996 - 0.006739496742*3/4*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.pow(0.006739496742*3/4,2)*5/3*(3*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/4-Math.pow(0.006739496742*3/4,3)*35/27*(5*(3*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/4+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/3))/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*Math.pow((Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2)))),2)/2*Math.pow(Math.cos(north/6366197.724/0.9996),2))+north/6366197.724/0.9996))-north/6366197.724/0.9996)*3/2)*(Math.atan(Math.cos(Math.atan((Math.exp((Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*Math.pow((Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2)))),2)/2*Math.pow(Math.cos(north/6366197.724/0.9996),2)/3))-Math.exp(-(Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*Math.pow((Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2)))),2)/2*Math.pow(Math.cos(north/6366197.724/0.9996),2)/3)))/2/Math.cos((north-0.9996*6399593.625*(north/6366197.724/0.9996-0.006739496742*3/4*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.pow(0.006739496742*3/4,2)*5/3*(3*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/4-Math.pow(0.006739496742*3/4,3)*35/27*(5*(3*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/4+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/3))/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*Math.pow((Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2)))),2)/2*Math.pow(Math.cos(north/6366197.724/0.9996),2))+north/6366197.724/0.9996)))*Math.tan((north-0.9996*6399593.625*(north/6366197.724/0.9996-0.006739496742*3/4*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.pow(0.006739496742*3/4,2)*5/3*(3*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/4-Math.pow(0.006739496742*3/4,3)*35/27*(5*(3*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/4+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/3))/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*Math.pow((Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2)))),2)/2*Math.pow(Math.cos(north/6366197.724/0.9996),2))+north/6366197.724/0.9996))-north/6366197.724/0.9996))*180/Math.PI; 
     latitude=Math.round(latitude*10000000); 
     latitude=latitude/10000000; 
     longitude =Math.atan((Math.exp((Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*Math.pow((Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2)))),2)/2*Math.pow(Math.cos(north/6366197.724/0.9996),2)/3))-Math.exp(-(Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*Math.pow((Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2)))),2)/2*Math.pow(Math.cos(north/6366197.724/0.9996),2)/3)))/2/Math.cos((north-0.9996*6399593.625*(north/6366197.724/0.9996-0.006739496742*3/4*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.pow(0.006739496742*3/4,2)*5/3*(3*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.sin(2* north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/4-Math.pow(0.006739496742*3/4,3)*35/27*(5*(3*(north/6366197.724/0.9996+Math.sin(2*north/6366197.724/0.9996)/2)+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/4+Math.sin(2*north/6366197.724/0.9996)*Math.pow(Math.cos(north/6366197.724/0.9996),2)*Math.pow(Math.cos(north/6366197.724/0.9996),2))/3))/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2))))*(1-0.006739496742*Math.pow((Easting-500000)/(0.9996*6399593.625/Math.sqrt((1+0.006739496742*Math.pow(Math.cos(north/6366197.724/0.9996),2)))),2)/2*Math.pow(Math.cos(north/6366197.724/0.9996),2))+north/6366197.724/0.9996))*180/Math.PI+Zone*6-183; 
     longitude=Math.round(longitude*10000000); 
     longitude=longitude/10000000;  
    } 
} 
+0

Tal vez un breve comentario para una mejor comprensión sería genial. –

+0

Utilice estas clases como esta: UTM2Deg pos = new UTM2Deg ("35 R 312915.84 4451481.33") Y lat = pos.latitude. – user2548538

+1

¿Esto tiene en cuenta que la Tierra es un esferoide y no una esfera? –

0

Para mis proyectos que he usando la biblioteca LatLongLib, de Ahmed Taha. Creo que es muy fácil convertir las coordenadas del sistema UTM al sistema Latitud-Longitud y viceversa. Solo necesita jugar con las clases UTMUtils, UTMPoint y LatLonPoint.

Hace tiempo también consideré elegir Jcoord. Fue fácil y directo al grano también. Sin embargo, necesitaba usar el elipsoide WGS84 y, en ese momento, solo LatLongLib parecía tener esa característica.

1

Puede usar este proyecto https://github.com/Berico-Technologies/Geo-Coordinate-Conversion-Java/, agregándolo a su pom.xml existente usando jitpack.

He logrado convertir las coordenadas UTM (30N, esto es, zona 30 y hemisferio norte) en Latitud y Longitud. Ver mi ejemplo a continuación:

public void setPunto(Point punto) { 
    this.punto = punto; 
    LatLon latlon = UTMCoord.locationFromUTMCoord(30, AVKey.NORTH, punto.getX(), punto.getY()); 
    this.latitud = latlon.getLatitude().degrees; 
    this.longitud = latlon.getLongitude().degrees; 
} 

Tenga en cuenta que la clase Point es de com.vividsolutions.jts.geom.Point tipo de clase.

2

La transformación de una coordenada en realidad se puede hacer en sólo unas pocas líneas de código:

Coordinate coordinate = new Coordinate(x, y); 
MathTransform transform = CRS.findMathTransform(CRS.decode("EPSG:4326"), CRS.decode("EPSG:3857"), false); 
JTS.transform(coordinate, coordinate, transform); 

Esto transformará una coordenada de longitud/latitud (EPSG: 4326) en Web proyección de Mercator (EPSG: 3857) coordinar.

sólo tiene que depender de las dos bibliotecas siguientes GeoTools en su herramienta de construcción (por ejemplo experto):

<repositories> 
    <repository> 
     <id>osgeo</id> 
     <name>Open Source Geospatial Foundation Repository</name> 
     <url>http://download.osgeo.org/webdav/geotools/</url> 
    </repository> 
</repositories> 

<dependencies> 
    <dependency> 
     <groupId>org.geotools</groupId> 
     <artifactId>gt-api</artifactId> 
     <version>${geotools.version}</version> 
    </dependency> 
    <dependency> 
     <groupId>org.geotools</groupId> 
     <artifactId>gt-epsg-hsql</artifactId> 
     <version>${geotools.version}</version> 
    </dependency> 
</dependencies> 

Esta respuesta se basa en un question/reply en gis.stackexchange.com. Publiqué mi respuesta porque las respuestas actuales aquí parecen ser bastante detalladas.

+0

¿qué tal desde UTM a lat/long usando JTS? –