经纬度坐标和投影坐标的转换
Posted 卡尔曼和玻尔兹曼谁曼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经纬度坐标和投影坐标的转换相关的知识,希望对你有一定的参考价值。
昨天,有朋友要我帮忙看看一个将经纬度坐标转换成墨卡托投影(墨卡托投影有很多变种,我也不知道他说的是哪一种)的程序,他说转换以后的坐标精度太差。当时,他的程序没怎么看懂,然后研究了一下Geotools,自己写了一个转换小程序,很简单的几行代码!
Geotools是Java语言编写的开源GIS工具包。该项目已有十多年历史,生命力旺盛,代码非常丰富,包含多个开源GIS项目,并且基于标准的GIS接口。Geotools主要提供各种GIS算法,各种数据格式的读写和显示。由于Geotools库依赖比较复杂,所以在Eclipse中我采用Maven进行建构。对于在Eclipse下怎么使用Maven,请自己百度之。貌似最新的Eclipse是直接集成Maven插件的不需要自己单独安装了。虽说Eclipse不需要安装Maven插件了,可以使用Eclipse自带的Eclipse Maven插件,但是还是建议自己安装一个最新的Maven二进制包。
在Eclipse新建Maven工程,添加库和依赖:
这里主要添加的是要下载Geotools的库:
<repositories>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net repository</name>
<url>http://download.java.net/maven/2</url>
</repository>
<repository>
<id>osgeo</id>
<name>Open Source Geospatial Foundation Repository</name> <url>http://download.osgeo.org/webdav/geotools/</url>
</repository>
</repositories>
以及用到的Geotools库:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-referencing</artifactId>
<version>$geotools.version</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-wkt</artifactId>
<version>$geotools.version</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-api</artifactId>
<version>$geotools.version</version>
</dependency>
<dependency>
<groupId>com.vividsolutions</groupId>
<artifactId>jts</artifactId>
<version>1.13</version>
</dependency>
</dependencies>
最后的pom.xml文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.tzy</groupId>
<artifactId>geotools</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>geotools</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<geotools.version>14.1</geotools.version>
</properties>
<repositories>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net repository</name>
<url>http://download.java.net/maven/2</url>
</repository>
<repository>
<id>osgeo</id>
<name>Open Source Geospatial Foundation Repository</name> <url>http://download.osgeo.org/webdav/geotools/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-referencing</artifactId>
<version>$geotools.version</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-wkt</artifactId>
<version>$geotools.version</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-api</artifactId>
<version>$geotools.version</version>
</dependency>
<dependency>
<groupId>com.vividsolutions</groupId>
<artifactId>jts</artifactId>
<version>1.13</version>
</dependency>
</dependencies>
</project>
下面开始写程序:
package cn.tzy.geotools;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.geometry.MismatchedDimensionException;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.Point;
/**
* Hello world!
*
*/
public class CoordConverter
public static double[] convert(double lon, double lat)
throws FactoryException, MismatchedDimensionException, TransformException
// 传入原始的经纬度坐标
Coordinate sourceCoord = new Coordinate(lon, lat);
GeometryFactory geoFactory = new GeometryFactory();
Point sourcePoint = geoFactory.createPoint(sourceCoord);
// 这里是以OGC WKT形式定义的是World Mercator投影,网页地图一般使用该投影
final String strWKTMercator = "PROJCS[\\"World_Mercator\\","
+ "GEOGCS[\\"GCS_WGS_1984\\","
+ "DATUM[\\"WGS_1984\\","
+ "SPHEROID[\\"WGS_1984\\",6378137,298.257223563]],"
+ "PRIMEM[\\"Greenwich\\",0],"
+ "UNIT[\\"Degree\\",0.017453292519943295]],"
+ "PROJECTION[\\"Mercator_1SP\\"],"
+ "PARAMETER[\\"False_Easting\\",0],"
+ "PARAMETER[\\"False_Northing\\",0],"
+ "PARAMETER[\\"Central_Meridian\\",0],"
+ "PARAMETER[\\"latitude_of_origin\\",0],"
+ "UNIT[\\"Meter\\",1]]";
CoordinateReferenceSystem mercatroCRS = CRS.parseWKT(strWKTMercator);
// 做投影转换,将WCG84坐标转换成世界墨卡托投影转
MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, mercatroCRS);
Point targetPoint = (Point) JTS.transform(sourcePoint, transform);
// 返回转换以后的X和Y坐标
double[] targetCoord = targetPoint.getX(), targetPoint.getY();
return targetCoord;
// 将目标投影坐标系作为参数输入,其实和第一个程序类似,我懒得提取公共部分再抽取函数了
public static double[] convert(double lon, double lat, String strWKT)
throws FactoryException, MismatchedDimensionException, TransformException
Coordinate sourceCoord = new Coordinate(lon, lat);
GeometryFactory geoFactory = new GeometryFactory();
Point sourcePoint = geoFactory.createPoint(sourceCoord);
CoordinateReferenceSystem mercatroCRS = CRS.parseWKT(strWKT);
MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, mercatroCRS);
Point targetPoint = (Point) JTS.transform(sourcePoint, transform);
double[] targetCoord = targetPoint.getX(), targetPoint.getY();
return targetCoord;
// main函数进行验证
public static void main( String[] args ) throws Exception
double longitude = 113.926982;
double latitude = 22.53089;
double[] coordinate = convert(longitude, latitude);
System.out.println("X: " + coordinate[0] + ", Y: " + coordinate[1]);
程序很简单:CRS.findMathTransform()方法定义转换的坐标系,JTS.transform()进行坐标的转换。
其中第一个方法是我专门写的将WGS84经纬度坐标转成World Mercator投影坐标的函数。第二个函数是对第一个函数的抽象,将要转换到的投影坐标提取出来作为参数,如果想要转换到某种投影坐标系,只需要传递一个该投影坐标系的OGC WKT(Well Known Text)给函数,就可以做转换了。常见投影的WKT表示可以在http://spatialreference.org/进行查询!
看懂了该程序的朋友,就可以写自己的实现了,上面只是一个简单的Hello World示例程序。
以上是关于经纬度坐标和投影坐标的转换的主要内容,如果未能解决你的问题,请参考以下文章