Gis坐标系4326与3857
Posted 言成言成啊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gis坐标系4326与3857相关的知识,希望对你有一定的参考价值。
参考
- GIS基础知识 - 坐标系、投影、EPSG:4326、EPSG:3857
- GIS基础教程之坐标系 - 知乎
- Axis Order — GeoTools 28-SNAPSHOT User Guide
- EPSG.io: Coordinate Systems Worldwide
- 区域面积-距离/面积计算-示例中心-JS API 示例 | 高德地图API
一、坐标系
分类
坐标系分为两种
- 地理坐标系(Geographic Coordinate System, GCS)
- 投影坐标系(Projected Coordinate System, PCS)
这边知乎老哥的文章描述很容易理解,我直接cv过来。
地理坐标系,就是一个球,说成球面坐标系反而好理解一点。就比如一个完整的橘子。
投影坐标系,就是将球展开后的一个面。就比如橘子剥皮展开。
地理坐标系和投影坐标系的最大区分,就是单位不同。
地理坐标系以度为单位。
投影坐标系以米为单位。
常用坐标系
对于地图开发人员来说,常见的测量系统就是WGS84测量系统(1984年全球测量系统)。
基于WGS84的常用坐标系为两种。
- EPSG:4326
- EPSG:3857
4326是地理坐标系,以度为单位。广泛用于GPS定位等。
3857是投影坐标系,以米为单位。用于平面地图,如GoogleMap、OpenStreetMap、BingMap等。
如果想要找取专属于自己地区、更精确的坐标系。可以去epsg.io搜索。
二、geotools
作为用java做饭碗的人来说,想要研究Gis,肯定少不了跟geotools打交道。
maven依赖
pom.xml
<repositories>
<repository>
<id>osgeo</id>
<name>OSGeo Release Repository</name>
<url>https://repo.osgeo.org/repository/release/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-grid</artifactId>
<version>$geotools.version</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-opengis</artifactId>
<version>$geotools.version</version>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
<version>$geotools.version</version>
<exclusions>
<exclusion>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-main</artifactId>
<version>$geotools.version</version>
<exclusions>
<exclusion>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-geojson</artifactId>
<version>$geotools.version</version>
<exclusions>
<exclusion>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
简单使用
下面简单演示一些常见用法。我这边就全以wkt为例了。wkt的绘制可以参考meethigher/wkt-show-on-openlayers: 基于openlayers的wkt绘制展示功能。
/**
* GeoTools简单使用
*
* @author chenchuancheng github.com/meethigher
* @since 2022/5/22 20:30
*/
public class GeotoolsUsing
@Test
public void testCreateGeo() throws Exception
//这是4326坐标系的wkt
String wkt = "LINESTRING(110.26968650499015 35.774090269456565,118.2156404214427 35.973104738241815)";
WKTReader reader = new WKTReader();
Geometry geometry = reader.read(wkt);
System.out.println(geometry.buffer(1));
Assert.assertNotNull(geometry);
@Test
public void testGeoApi() throws Exception
//area1是包含area2的
String area1 = "POLYGON((113.36572265625 38.80204526520603,107.28369301557538 33.994384090476174,112.38134926557541 28.960087983961387,119.2368153333664 31.690781121452815,113.36572265625 38.80204526520603))";
String area2 = "LINESTRING(110.35095139165554 33.90070434182671,116.21651043156132 33.564288629604945)";
WKTReader reader = new WKTReader();
Geometry geometry1 = reader.read(area1);
Geometry geometry2 = reader.read(area2);
System.out.println(geometry1.contains(geometry2));//true
//获取边界,即获取最北、最南、最东、最西,组成一个矩形
Geometry envelope = geometry1.getEnvelope();
System.out.println(envelope.toString());//输出wkt
//获取边界的点
Envelope internal = geometry1.getEnvelopeInternal();
double minX = internal.getMinX();
double minY = internal.getMinY();
//返回其中一个顶点
Coordinate coordinate = geometry1.getCoordinate();
System.out.println(coordinate);
//拓宽区域,由于使用的是4326坐标系,1在此处表示1度。这个单位也是跟着坐标系走的
//以面的边向外拓宽1,顶点处就是以1为半径的圆弧。如果是线,就是四周拓宽
Geometry buffer = geometry1.buffer(1);
System.out.println(buffer);
//判断交叉,我画的是个不相交,但包含的。
//这个方法有两个含义。a.相交 b. 包含 满足其一即可
boolean intersects = geometry1.intersects(geometry2);
System.out.println(intersects);//true
//面求面积,线求长度。单位同样是跟着坐标系走
System.out.println(geometry1.getArea());
System.out.println(geometry2.getLength());
@Test
public void testTransformCrs() throws Exception
//我使用的wkt都是经度在前,一般正常使用也是经度在前。将4326转换为3857计算面积(㎡)
CRSAuthorityFactory factory = CRS.getAuthorityFactory(true);
CoordinateReferenceSystem source = factory.createCoordinateReferenceSystem("EPSG:4326");
CoordinateReferenceSystem target = factory.createCoordinateReferenceSystem("EPSG:3857");
MathTransform transform = CRS.findMathTransform(source, target);
//高德地图面积https://developer.amap.com/demo/javascript-api/example/calcutation/ring-area
// 该区域高德面积125178908819平方米,坐标系不同,有误差很正常
String wkt = "POLYGON((110.4141583943802 36.03154311769477,110.54418331527785 33.09352034423874,114.95057594167424 33.32318635566811,114.73386810758919 35.99648515314789,110.4141583943802 36.03154311769477))";
WKTReader reader = new WKTReader();
Geometry geometry = reader.read(wkt);
System.out.println(geometry.getArea());//度为单位,12.258110818164612
Geometry geometry1 = JTS.transform(geometry, transform);
//用bigdecimal只是单纯不想看到科学计数法。
System.out.println(BigDecimal.valueOf(geometry1.getArea()));//米为单位,184591949648.2439
以上是关于Gis坐标系4326与3857的主要内容,如果未能解决你的问题,请参考以下文章
记一次 CesiumJS 中非 4326/3857 WMTS 数据的加载