在Java中将纬度和经度转换为东北坐标?

8
如何在Java中将纬度和经度转换为东北坐标?

从哪个点开始测量北距和东距?你使用的是 http://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system 吗,还是其他的方式? - Karl Knechtel
3个回答

15

我假设你是指英国 OSGB 东方坐标和北方坐标。这个问题背后的三角函数很有趣,但是你可以使用JCoord库来完成,它会让它变得容易(虽然需要相当多的CPU)。


关于@DD下面的评论,需要注意JCoord的一点是,在从Easting / Northing转换为Lat / Long(经度/纬度)以及反向转换时,必须确保使用正确的基准面(datum)。

采用@DD的代码:

LatLng latLng = new OSRef(394251,806376).toLatLng();

这将返回使用OSGB36基准的经纬度,即英国地图上使用的“平面地球”近似值。这与大多数应用程序(包括Streetmap)使用的WSG84基准显著不同,WSG84模拟了世界的球形(或多或少)。

要转换为WGS84经纬度,您需要明确指定:

LatLng latLng = new OSRef(394251,806376).toLatLng();
latLng.toWGS84();

这将把纬度和经度调整到正确的基准面。

请注意,OsRef.toLatLng()javadoc非常清楚:

使用OSGB36基准面将此OSGB网格参考转换为纬度/经度对。请注意,根据应用程序需要,可能需要将LatLng对象转换为WGS84基准面。

坐标基准面之间的转换并不简单。如果看起来很简单,那么你可能做错了。


JCoord是完全浪费时间...它的准确性很差。我将其与其他几个在线工具进行了比较,结果相差超过30。 - DD.
1
@DD:你是要就这么说一句没什么用的话就走了,还是提供一些有用的信息呢? - skaffman
@skaffman 那是个意外...我按了回车键,然后它就进入了评论...我不想让任何人浪费时间在这个库上...它不准确,我已经浪费了几个小时。 - DD.
4
@DD说:“我使用JCoord构建了许多需要位置精度的应用程序,发现它非常准确。但是,正确使用它有点棘手,很可能你没有正确使用API。所以,与其只是简单地说‘它无用’,不如给我展示一些演示它无用的样例代码。” - skaffman
1
邮政编码“AB101AA” 东距=394251 北距=806376 {new OSRef(394251,806376).toLatLng()} 返回57.14841674744993,-2.0950248639315605,而streetmap.co.uk/streetmap.dll?GridConvert返回57.148232,-2.096648。 - DD.
显示剩余2条评论

4

尝试使用GeoTools:

       CRSAuthorityFactory crsFac = ReferencingFactoryFinder
    .getCRSAuthorityFactory("EPSG", null);

    CoordinateReferenceSystem wgs84crs = crsFac
            .createCoordinateReferenceSystem("4326");
    CoordinateReferenceSystem osgbCrs = crsFac
            .createCoordinateReferenceSystem("27700");

    CoordinateOperation op = new DefaultCoordinateOperationFactory()
            .createOperation(osgbCrs, wgs84crs);

    DirectPosition eastNorth = new GeneralDirectPosition(easting, northing);
    DirectPosition latLng = op.getMathTransform().transform(eastNorth,
            eastNorth);


    double latitude=latLng.getOrdinate(0);
    double longitude=latLng.getOrdinate(1);

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

2
我知道这已经过时了,但它实际上与提问者所寻找的完全相反。如果你要从其他地方获取答案,最好引用一下。cite - Agbb
只需在.createOperation()调用中交换两个参考系统的顺序,即可得到OP所要求的转换。但是我同意@ozliftoff的观点,把别人的工作当做自己的不好。 - Matthew Wise

1
如果您不想使用GeoTools,又发现Maven中央库中不再提供JCoord,则可以使用一个小型库从英国OSGB(东/北)坐标系转换为WGS84。该库由DSTL提供:https://github.com/dstl/osgb 转自README:
import uk.gov.dstl.geo.osgb.Constants;
import uk.gov.dstl.geo.osgb.EastingNorthingConversion;
import uk.gov.dstl.geo.osgb.OSGB36;

// ...

//Convert from Easting and Northing into Cartesian Coordinates (LatLon)
double[] latlonOSGB38 = EastingNorthingConversion.toLatLon(
      new double[]{ easting, northing },
      Constants.ELLIPSOID_AIRY1830_MAJORAXIS,
      Constants.ELLIPSOID_AIRY1830_MINORAXIS,
      Constants.NATIONALGRID_N0,
      Constants.NATIONALGRID_E0,
      Constants.NATIONALGRID_F0,
      Constants.NATIONALGRID_LAT0,
      Constants.NATIONALGRID_LON0);
 
//Convert from LatLon (OSGB) to WGS84
double[] latlonWGS84 = OSGB36.toWGS84(latlonOSGB38[0], latlonOSGB38[1]);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接