概述:

本文说说geotools中坐标转换的那点事情,以WGS84和web墨卡托相互转换为例。

效果:

转换前

转换后

单个Geometry转换

实现代码:

package com.lzugis.geotools;

import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.geotools.data.FeatureWriter;
import org.geotools.data.FileDataStoreFactorySpi;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.io.WKTReader;
import com.vividsolutions.jts.io.WKTWriter;

public class ProjectTrans {
	private static GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory( null );
	private static WKTReader reader = new WKTReader( geometryFactory );
	private static WKTWriter write = new WKTWriter();
	static ProjectTrans proj = new ProjectTrans();

	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]]";
	/**
	 * 经纬度转WEB墨卡托
	 * @param geom
	 * @return
	 */
	public Geometry lonlat2WebMactor(Geometry geom){
		try{
			//这里是以OGC WKT形式定义的是World Mercator投影,网页地图一般使用该投影

//			CoordinateReferenceSystem crsTarget = CRS.parseWKT(strWKTMercator);
	        CoordinateReferenceSystem crsTarget = CRS.decode("EPSG:3857");

	        // 投影转换
	        MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, crsTarget);
	        return JTS.transform(geom, transform);
		}
		catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	public void projectShape(String inputShp, String outputShp){
		try {
			//源shape文件
			ShapefileDataStore shapeDS = (ShapefileDataStore) new ShapefileDataStoreFactory().createDataStore(new File(inputShp).toURI().toURL());
			//创建目标shape文件对象
			Map<String, Serializable> params = new HashMap<String, Serializable>();
	        FileDataStoreFactorySpi factory = new ShapefileDataStoreFactory();
	        params.put(ShapefileDataStoreFactory.URLP.key, new File(outputShp).toURI().toURL());
	        ShapefileDataStore ds = (ShapefileDataStore) factory.createNewDataStore(params);
	        // 设置属性
	        SimpleFeatureSource fs = shapeDS.getFeatureSource(shapeDS.getTypeNames()[0]);
	        //下面这行还有其他写法,根据源shape文件的simpleFeatureType可以不用retype,而直接用fs.getSchema设置
	        CoordinateReferenceSystem crs = CRS.parseWKT(strWKTMercator);
	        ds.createSchema(SimpleFeatureTypeBuilder.retype(fs.getSchema(), crs));

	        //设置writer
	        FeatureWriter<SimpleFeatureType, SimpleFeature> writer = ds.getFeatureWriter(ds.getTypeNames()[0], Transaction.AUTO_COMMIT);

	        //写记录
	        SimpleFeatureIterator it = fs.getFeatures().features();
	        try {
	            while (it.hasNext()) {
	                SimpleFeature f = it.next();
	                SimpleFeature fNew = writer.next();
	                fNew.setAttributes(f.getAttributes());
	                Geometry geom = proj.lonlat2WebMactor((Geometry)f.getAttribute("the_geom"));
	                fNew.setAttribute("the_geom", geom);
	            }
	        }
	        finally {
	            it.close();
	        }
	        writer.write();
	        writer.close();
	        ds.dispose();
	        shapeDS.dispose();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 工具类测试方法
	 * @param args
	 */
	public static void main(String[] args){
		String wktPoint = "POINT(100.02715479879 33.462715497945)";
		String wktLine = "LINESTRING(108.32803893589 41.306670233001,99.950999898452 25.84722546391)";
		String wktPolygon = "POLYGON((100.02715479879 32.168082192159,102.76873121104 37.194305614622,107.0334056301 34.909658604412,105.96723702534 30.949603786713,100.02715479879 32.168082192159))";
		try {
			long start = System.currentTimeMillis();

			Geometry geom1 = (Geometry) reader.read(wktPoint);
			Geometry geom1T = proj.lonlat2WebMactor(geom1);

			Geometry geom2 = (Geometry) reader.read(wktLine);
			Geometry geom2T = proj.lonlat2WebMactor(geom2);

			Geometry geom3 = (Geometry) reader.read(wktPolygon);
			Geometry geom3T = proj.lonlat2WebMactor(geom3);

			System.out.println(write.write(geom1T));
			System.out.println(write.write(geom2T));
			System.out.println(write.write(geom3T));
			String inputShp = "D:\\data\\beijing\\China4326.shp",
					outputShp = "D:\\data\\beijing\\China3857.shp";
			proj.projectShape(inputShp, outputShp);
			System.out.println("坐标转换完成,共耗时"+(System.currentTimeMillis() - start)+"ms");
		}
		catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

相关引用:

        <dependency>
		  <groupId>org.geotools</groupId>
		  <artifactId>gt-epsg-extension</artifactId>
		  <version>${geotools.version}</version>
		</dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-referencing</artifactId>
            <version>${geotools.version}</version>
        </dependency>

---------------------------------------------------------------------------------------------------------------

技术博客

CSDN:http://blog.csdn.NET/gisshixisheng

博客园:http://www.cnblogs.com/lzugis/

在线教程

http://edu.csdn.Net/course/detail/799

Github

https://github.com/lzugis/

联系方式

q       q:1004740957

e-mail:niujp08@qq.com

公众号:lzugis15

Q Q 群:452117357(webgis)

337469080(Android)

说说geotools中坐标转换那点事的更多相关文章

  1. 开发中关于Git那些事

    如果你想精通Git,直接到 Git官网 把这本ProGit掌握已足以Pro Git 此文主要介绍一切开发中常用的git命令和一些配置技巧(诸如git别名配置,log打印技巧,版本回退以及分支管理等). ...

  2. 开发中关于Git那些事(续:Git变基)

    其实上一篇写的内容仅仅是Git的冰山一角,如果你认为Git就是简简单单的几行命令,那只能说明你还没有真正了解Git这个强大的内容寻址文件系统.这篇文章,还是接着介绍一些实用但是很少有人知晓的一些命令, ...

  3. geotools中泰森多边形的生成

    概述 本文讲述如何在geotools中生成泰森多边形,并shp输出. 泰森多边形 1.定义 泰森多边形又叫冯洛诺伊图(Voronoi diagram),得名于Georgy Voronoi,是由一组由连 ...

  4. 探讨 JS 的面向对象中继承的那些事

    最近学了 JS 的面向对象,这篇文章主要是探讨 JS 的面向对象中继承的那些事. JS中继承的特点: 1.子类继承父类: 2.子类可以用父类的方法和属性 3.子类的改变可以不影响父类 下面用一个例子来 ...

  5. django基础之day09,Forms组件在程序中做了哪些事? 校验数据、渲染标签、展示信息

    ******************************* Forms组件 *************************************************** Forms组件在 ...

  6. 「译」forEach循环中你不知道的3件事

    前言 本文925字,阅读大约需要7分钟. 总括: forEach循环中你不知道的3件事. 原文地址:3 things you didn't know about the forEach loop in ...

  7. GeoJson的生成与解析,JSON解析,Java读写geojson,geotools读取shp文件,Geotools中Geometry对象与GeoJson的相互转换

    GeoJson的生成与解析 一.wkt格式的geometry转成json格式 二.json格式转wkt格式 三.json格式的数据进行解析 四.Java读写geojson 五.geotools读取sh ...

  8. vue项目中遇到的那些事。

    前言 有好几天没更新文章了.这段实际忙着做了一个vue的项目,从 19 天前开始,到今天刚好 20 天,独立完成. 做vue项目做这个项目一方面能为工作做一些准备,一方面也精进一下技术. 技术栈:vu ...

  9. JavaScript中继承的那些事

    引言 JS是一门面向对象的语言,但是在JS中没有引入类的概念,之前特别疑惑在JS中继承的机制到底是怎样的,一直学了JS的继承这块后才恍然大悟,遂记之. 假如现在有一个“人类”的构造函数: functi ...

随机推荐

  1. Codeforces - 55D Beautiful numbers (数位dp+数论)

    题意:求[L,R](1<=L<=R<=9e18)区间中所有能被自己数位上的非零数整除的数的个数 分析:丛数据量可以分析出是用数位dp求解,区间个数可以转化为sum(R)-sum(L- ...

  2. Linux网络相关命令firewalld和netfilter、iptables 使用(6/22)

    iptables和netfilter的关系: netfilter在内核空间的代码根据table中的rules,完成对packet的分析和处置.但是这些table中的具体的防火墙rules,还是必须由系 ...

  3. Docker 使用指南 —— 基本操作

    Docker 是一个能够把开发应用程序自动部署到容器的开源引擎.它由Docker公司的团队编写,基于Apache 2.0开源协议授权.它提供了一个简单.轻量的建模方式,使开发生命周期更高效快速,鼓励了 ...

  4. Entity FrameWork Code First 之 MVC4 数据库初始化策略用法

    通过启用迁移和更新数据库可以很容易的生成一张表.但是对数据库修改之后,通过数据迁移就没那么好实现了. 这里用到数据库生成策略,进行对数据库操作: 一.3种主要数据库生成策略 1 CreateDatab ...

  5. 【Head First Servlets and JSP】笔记2:MVC迷你教程

    1.采用MVC,不仅要求业务逻辑和表示分离.实际上,业务逻辑甚至根本不知道表示的存在.MVC的关键是,业务逻辑要与表示分离,而要求在中间放上别的东西,这样业务逻辑本身就可以作为一个可以重用的Java类 ...

  6. 较常用的Math方法及ES6中的扩展

    记录下与Math有关的常用方法,如:求最大值.最小值等,或者是保留几位数啥的 1.数据 let floatA = 2.325232; let floatB = 2.3456; let temporar ...

  7. 抗DDOS攻击

    2016年10月的某天,“半个美国互联网”都瘫痪了,就是因为遭受了DDoS攻击——Twitter.GitHub.Spotify.Airbnb.Etsy等大量站点都因此受到影响.DNS服务提供商Dyn公 ...

  8. menubar下面的选项不可以输入中文

    这是一个QT5的bug. 1.不用中文,使用英文: 2.先输入中文,然后在属性Action里面的text里改成中文.

  9. BUG: scheduling while atomic 分析【转】

    本文转载自:https://blog.csdn.net/cfy_phonex/article/details/12090943 遇到一个典型的schedule问题.   <3>[26578 ...

  10. mongodb 的Cursor 作为 stream 的时候,读出来的数据数字开头的key没法访问(又踩了一个坑)

    mongdb 用Cursor 读取数据的时候,直接用流读出来的数据key是数字开头的话,就是独具不到,用Object.keys() 把所有的key 打印出来的话如下:怎么会是这样的呢? 查看了一下文档 ...