概述:

本文说说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. NIO服务端和客户端通信demo

    代码转自 https://www.jianshu.com/p/a9d030fec081 服务端: package nio; import java.io.IOException; import jav ...

  2. PAT 天梯赛 L1-015. 跟奥巴马一起画方块 【水】

    题目链接 https://www.patest.cn/contests/gplt/L1-015 AC代码 #include <iostream> #include <cstdio&g ...

  3. Codeforces Round #397 by Kaspersky Lab and Barcelona Bootcamp (Div. 1 + Div. 2 combined) B - Code obfuscation

    地址:http://codeforces.com/contest/765/problem/B 题目: B. Code obfuscation time limit per test 2 seconds ...

  4. 分支语句(switch case)

    /switch case 的应用 Console.WriteLine("1.汉堡包"); Console.WriteLine("2.薯条"); Console. ...

  5. datagrid 用法

    http://blog.csdn.net/xhhuang1979/article/details/8331682

  6. winform + INotifyPropertyChanged + IDataErrorInfo + ErrorProvider实现自动验证功能

    一个简单的Demo.百度下载链接:http://pan.baidu.com/s/1sj4oM2h 话不多说,上代码. 1.实体类定义: class Student : INotifyPropertyC ...

  7. Microsoft.VisualStudio.Web.PageInspector.Loader

    未能加载文件或程序集"Microsoft.VisualStudio.Web.PageInspector.Loader, Version=1.0.0.0, Culture=neutral, P ...

  8. RegExp方法解析

    RegExp 正则表达式(regular expression)的缩写 语法: 显式构造函数 var rg= new RegExp(pattern, attributes) 隐式构造函数 var rg ...

  9. Python引用多个模块,调用模块中的函数时,要注意的地方

    转自:http://blog.csdn.net/yjk13703623757/article/details/70237463 python模块是”从下到上”导入(import)的. 例如: a.py ...

  10. invalid derived query的解决办法

    标签: eclipse / invalid / derived / 解决办法 / 校验功能 479 在Eclipse的运行过程中,突然有一个接口跳出如下错误: invalid derived quer ...