专栏首页给永远比拿愉快经纬度坐标和投影坐标的转换

经纬度坐标和投影坐标的转换

昨天,有朋友要我帮忙看看一个将经纬度坐标转换成墨卡托投影(墨卡托投影有很多变种,我也不知道他说的是哪一种)的程序,他说转换以后的坐标精度太差。当时,他的程序没怎么看懂,然后研究了一下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示例程序。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ShapeFile数据到mongodb的导入

    开发环境为: 系统环境 Linux 4.4.0-36-generic #55~14.04.1-Ubuntu x86_64 x86_64 x86_64 GNU...

    卡尔曼和玻尔兹曼谁曼
  • Neo4j Spatial数据导入

    首先,安装neo4j数据库。我的开发环境是Ubuntu,安装过程参考官网:Neo4j Debian Packages,安装后配置:Post-installati...

    卡尔曼和玻尔兹曼谁曼
  • Leetcode: Permutations

    题目: Given a collection of numbers, return all possible permutations.

    卡尔曼和玻尔兹曼谁曼
  • 快速学习-springBoot入门

    接下来,我们就来利用SpringBoot搭建一个web工程,体会一下SpringBoot的魅力所在!

    cwl_java
  • MapStruct 爬坑指南

    第一步当然是引入pom依赖,目前1.3版本还是beta所以选择引入1.2版本,使用IDEA的小伙伴推荐去插件商店搜索MapStruct,下载插件可以获得更好的体...

    tanoak
  • springboot集成ueditor富文本编辑器【需要修改ueditor源码】-和上一篇不一样

    最近工作需要重新搭建公司网站,其中需要使用富文本编辑器,货比三家,最后选择了百度团队的UEditor。项目框架为springboot,所以涉及到springbo...

    凯哥Java
  • SpringBoot图文教程16—SpringBoot 多模块开发「web」「打包」

    什么是多模块开发?如图所示,项目中每一个包对应都是一个完整的项目,在IDEA中称之为模块,每一个模块都有完整的项目结构:独立的pom文件,独立的配置文件,独立的...

    鹿老师的Java笔记
  • ShapeFile数据到mongodb的导入

    开发环境为: 系统环境 Linux 4.4.0-36-generic #55~14.04.1-Ubuntu x86_64 x86_64 x86_64 GNU...

    卡尔曼和玻尔兹曼谁曼
  • 利用Jenkins pipeline配置测试工具

    最近学习了翟志军老师写的《Jenkins 2.X实践指南》书中的第5章:代码质量一节,发现两方面问题:

    小老鼠
  • 在 libevent 中使用 MariaDB(MySQL)

    在之前我翻译的官方文档中提到了 MariaDB 提供了对异步 I/O 的支持。那篇文章是一个比较简要的介绍。不过实际适配中,官方也提供了一个完整适配 libev...

    amc

扫码关注云+社区

领取腾讯云代金券