Java에서 지구 표면 위치를 lat, lon에서 UTM으로 변환하는 방법을 아는 사람이 있습니까 (예 : WGS84)? 저는 현재 Geotools를보고 있지만 불행히도 해결책은 분명하지 않습니다.Java, lat/lon을 UTM으로 변환
답변
Geotools 2.4를 사용하여 일부는 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]);
알버타 10 TM 대답은 아마도 당신이 필요로하는 것에 대한 과잉 공격 일 것입니다 - 개발자의 작품에서 나온 this link에 아마도 필요한 모든 정보가있을 것입니다.
이 링크는 질문에 대한 답변 일지 모르지만 본질적인 부분을 포함하는 것이 좋습니다. 여기에 답변하고 참조 용 링크를 제공하십시오. 링크 된 페이지가 변경되면 링크 전용 답변이 유효하지 않게 될 수 있습니다. - [검토 중] (리뷰/저품각 게시물/17991146) –
OpenMap, 특히 com.bbn.openmap.proj.coords 패키지를 API에서 살펴보십시오.
Steve Dutch at University of Wisconson에는 알고리즘에 대한 훌륭한 글이 있습니다. 또한 귀하의 번호를 확인하는 데 도움이되는 Excel 문서가 포함되어 있습니다.
이 링크는 질문에 대한 답변 일지 모르지만 여기에 답변의 핵심 부분을 포함하고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 유효하지 않게 될 수 있습니다. - [리뷰에서] (리뷰/저품절 포스트/17991149) –
나는 JCoord을 제안합니다. 아주 간단한 API를 사용하여 다양한지도 제작 좌표 체계간에 변환 할 수 있습니다.
당신은 소스 코드를 살펴볼 때 짜증이납니다. 그것은 조밀 한 삼각법의 페이지와 페이지입니다. 훌륭한 재료.
또한 JSCoord라는 자바 스크립트 버전이 있습니다.
아마도 여기 공간 데이터를 많이 조작하고 있습니다. Postgres 확장과 함께 공간적으로 사용 가능한 관계형 dbms를 사용하고 있다고 가정합니다. PostGIS에서 이러한 종류의 변환을 쉽게 수행 할 수 있으며, OGC 표준에 정의 된대로 기하학적 연산과 관계를 광범위하게 지원합니다.
그냥 생각해보십시오!
라이브러리 없음, 아니요. 이것을 복사하십시오!
위의 두 클래스를 사용하면 학위 (위도/경도)를 UTM 및 그 반대로 변환 할 수 있습니다.
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;
}
}
더 나은 이해를위한 짧은 코멘트가 좋을 수도 있습니다. –
다음과 같은 클래스 사용 : UTM2Deg pos = new UTM2Deg ("35 R 312915.84 4451481.33") lat = pos.latitude. – user2548538
지구가 회전 타원체이고 구형이 아니라는 점에서이 요소가 작용합니까? –
내 프로젝트의 경우 Ahmed Taha의 LatLongLib 라이브러리를 사용했습니다. 저는 UTM 시스템에서 Latitude-Longitude 시스템으로 좌표를 변환하는 것이 매우 쉽고 그 반대도 마찬가지라고 생각합니다. UTMUtils, UTMPoint 및 LatLonPoint 클래스로 게임하면됩니다.
시간 전 나는 또한 Jcoord을 선택하는 것으로 생각했습니다. 요점까지 쉽고 직선적이었습니다. 그러나 WGS84 타원체를 사용해야하고 LatLongLib 만 그 기능을 가진 것처럼 보였습니다.
이 프로젝트 https://github.com/Berico-Technologies/Geo-Coordinate-Conversion-Java/을 사용하여 jitpack을 사용하여 기존 pom.xml에 추가 할 수 있습니다.
위도와 경도로 UTM 좌표 (30N, 30 구역 및 북반구)를 성공적으로 변환 할 수있었습니다. Point 클래스는 com.vividsolutions.jts.geom.Point 클래스 타입이다
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;
}
참고 : 아래에있는 내 예를 참조하십시오.
실제로 코드의 몇 줄에서 수행 할 수 있습니다 좌표 변환 :
Coordinate coordinate = new Coordinate(x, y);
MathTransform transform = CRS.findMathTransform(CRS.decode("EPSG:4326"), CRS.decode("EPSG:3857"), false);
JTS.transform(coordinate, coordinate, transform);
이것은 위도/경도가 (EPSG : 4326) 좌표 변환됩니다 웹 메르카토르 투영에 (EPSG : 3857) 동등 어구.
당신은 당신의 빌드 도구에서 다음과 같은 두 가지 GeoTools 라이브러리에 (예를 들어 받는다는) 의존해야
<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>
이 답변 gis.stackexchange.com에 question/reply에 구축합니다. 현재 답변은 매우 장황하기 때문에 내 답글을 올리십시오.
JTS를 사용하여 UTM에서 위도/경도로 어때요? –
예 GeoTools 설명서는 최종 사용자가 이미 API 및 일반적으로 GIS에 대해 매우 잘 알고 있다고 가정합니다. 이해하기가 매우 어렵습니다. 나는 현재지도를 사용하여지도에 점을 표시하는 데 어려움을 겪고 있습니다. http://stackoverflow.com/questions/29567231/why-cant-this-code-producea-a-points-layer-in-geotools – cj5