说说geotools中坐标转换那点事

概述:

本文说说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确实不支持直接的投影换到EPSG:4479坐标系。 EPSG:4479代表了ETRS89地理坐标系,它使用欧洲地面参考系统1989(ETRS89)作为基准。在Geotools,大多数投影换都是基于投影坐标系,而不是地理坐标系。 如果你希望进行与EPSG:4479相关的操作,可能需要考虑以下两种方式: 1. 将你的数据从投影坐标换到EPSG:4326(WGS84)地理坐标系,然后再进行与EPSG:4479的换。这可以通过使用Geotools投影换工具来实现。 2. 考虑使用其他的GIS库或工具,如GDAL(Geospatial Data Abstraction Library),它提供了更广泛的坐标系支持,包括对EPSG:4479的换。 请注意,无论你选择哪种方式,确保你有正确的Bursa-Wolf参数(七参数或三参数)用于进行换。这些参数通常用于处理不同基准之间的差异。 对于EPSG:4479,下面是一个示例使用Geotools进行从投影坐标系(如EPSG:3857)到EPSG:4479地理坐标系的换代码: ```java CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:3857"); CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4479"); MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true); DirectPosition2D sourcePos = new DirectPosition2D(sourceCRS, x, y); DirectPosition2D targetPos = new DirectPosition2D(); transform.transform(sourcePos, targetPos); double targetX = targetPos.getX(); double targetY = targetPos.getY(); ``` 请注意,以上示例换是从EPSG:3857投影坐标系到EPSG:4479地理坐标系。确保你根据实际情况调整源和目标坐标系的EPSG代码。 希望这可以帮助到你。再次对之前的回答错误表示抱歉。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛老师讲GIS

感谢老板支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值