做网站那个语言好,中英文企业网站系统,保山网站建设报价,wordpress html模式文章目录前言地理坐标系和投影坐标系地理坐标系投影坐标系地图投影墨卡托/Web墨卡托常见坐标系地理坐标系和投影坐标系互转EPSG:3857和EPSG:4326Java各坐标系之间的转换#xff08;高斯、WGS84经纬度、Web墨卡托、瓦片坐标#xff09;GeotoolsJTSvividsolutions和locationtec…
文章目录前言地理坐标系和投影坐标系地理坐标系投影坐标系地图投影墨卡托/Web墨卡托常见坐标系地理坐标系和投影坐标系互转EPSG:3857和EPSG:4326Java各坐标系之间的转换高斯、WGS84经纬度、Web墨卡托、瓦片坐标GeotoolsJTSvividsolutions和locationtech jts创建几何对象点-Point多点-MultiPoint线-LineString多线-MultiLineString闭合线-LinearRing多边形-Polygon多个多边形-MultiPolygon几何[集合](https://so.csdn.net/so/search?q集合spm1001.2101.3001.7020)列表-GeometryCollection几何关系判断返回值 boolean几何关系分析返回值 几何对象距离、长度、面积计算按照代码包把所有功能介绍下图形可视化化WKT数据好用的一比项目实战几何到另一个几何最近的点求几何的交点利用缓冲画圆根据起始点求一个线的子线计算道路与起点之间指定距离之间的交点坐标前言
项目需求需要很多的空间几何计算例如点、线、面之间的距离、面积、长度、相交、最短距离点等由于相关文档是真的缺乏墙内墙外看了大量的博客和文档收集和验证了很久。现将结论和知识点整理发出来。
地理坐标系和投影坐标系
地理坐标系
地理坐标系Geographic coordinate system是以经纬度为地图的存储单位。很明显地理坐标系是球面坐标系统。我们要将地球上的数字化信息存放到球面坐标系统上如何进行操作呢地球是一个不规则的椭球如何将数据信息以科学的方法存放到椭球上这必然要求 我们找到这样的一个椭球体。这样的椭球体具有特点可以量化计算的。具有长半轴短 半轴偏心率。以下几行便是Krasovsky_1940椭球及其相应参数。 Spheroid: Krasovsky_1940 Semimajor Axis: 6378245.000000000000000000 Semiminor Axis: 6356863.018773047300000000 Inverse Flattening扁率: 298.300000000000010000 然而有了这个椭球体以后还不够还需要一个大地基准面将这个椭球定位。在坐标系统描 述中可以看到有这么一行 Datum: D_Beijing_1954 表示大地基准面是D_Beijing_1954。
投影坐标系
投影坐标系统实质上便是平面坐标系统其地图单位通常为米。
投影的意义将球面坐标转化为平面坐标的过程便称为投影。
地理坐标系右下角显示Degrees度表示经纬度投影显示的是Meters米 平常看到的WGS84、高德、百度坐标系都是地理坐标系当我们需要计算距离、面积、长度时需要用投影坐标系 地图投影
利用一定数学法则把地球表面转换到平面上的理论和方法称为地图投影。由于地球表面是一个不可展平的曲面所以运用任何数学方法进行投影转换都会产生误差和变形为按照不同的需求缩小误差就产生了各种投影方式如圆柱投影、圆锥投影、等角投影、等面积投影、切投影、割投影等。 墨卡托/Web墨卡托
一种正轴等角切圆柱投影。
等角保证对象形状不变以及方向位置正确。圆柱保证纬线经线平行相互垂直且经线间隔相同。缺点纬线间隔从赤道向两级逐渐增大面积变形大。Web墨卡托Google首创把地球模拟为球体而非椭球体近似等角。 常见坐标系
WGS84坐标系 地球坐标系国际上通用的坐标系。设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系。
GCJ02坐标系 火星坐标系是由中国国家测绘局制订的地理信息系统的坐标系统。由WGS84坐标系经加密后的坐标系。
BD09坐标系 百度地图使用坐标系GCJ02坐标系经加密后的坐标系。
转换方法
国际通用的转换做法 百度的做法
地理坐标系和投影坐标系互转
需要2个依赖库这里要注意org.geotool库的下载源。
dependencygroupIdorg.locationtech.jts/groupIdartifactIdjts-core/artifactIdversion1.18.1/version
/dependency
dependencygroupIdorg.geotools/groupIdartifactIdgt-epsg-hsql/artifactIdversion22-RC/version
/dependency
dependencygroupIdorg.geotools/groupIdartifactIdgt-main/artifactIdversion22-RC/version
/dependency
repositoriesrepositoryidgeotools/idnamegeotools/nameurlhttp://maven.icm.edu.pl/artifactory/repo//urlreleasesenabledtrue/enabled/releases/repository
/repositories转换代码示例 // WGS84(一般项目中常用的是CSR:84和EPSG:4326)CoordinateReferenceSystem sourceCRS CRS.decode(CRS:84);// Pseudo-Mercator(墨卡托投影)CoordinateReferenceSystem targetCRS CRS.decode(EPSG:3857);MathTransform transform CRS.findMathTransform(sourceCRS, targetCRS, false);Geometry geometryMercator JTS.transform(geometry, transform);// 面积、周长System.out.println(geometryMercator.getArea());System.out.println(geometryMercator.getLength());JTS包下的Geometry等类其实是代表的空间几何它所提供的几何计算只是单纯的值计算而我们提到的根据GIS经纬度等获取面积周长等其实是需要放到对应坐标系中才有意义。
EPSG:3857和EPSG:4326
墨卡托坐标 EPSG:3857 坐标系。投影坐标系EPSG:3857 的数据一般是这种的。[12914838.35,4814529.9]看上去相对数值较大。不利于存储比较占内存。
WGS-84是国际标准GPS坐标Google Earth使用、或者GPS模块 EPSG:4326 的数据一般是这种的。[22.37114.05]。利于存储可读性高 // 2437 GCJ-02中国坐标偏移标准Google Map、高德、腾讯使用 Java各坐标系之间的转换高斯、WGS84经纬度、Web墨卡托、瓦片坐标
另一种方式之后研究
https://blog.csdn.net/u010410697/article/details/110003422
Geotools
Geotools是一个java类库它提供了很多的标准类和方法来处理空间数据同时这个类库是构建在OGC标准之上的是OGC思想的一种实现。而OGC是国际标准所以geotools将来必定会成为开源空间数据处理的主要工具目前的大部分开源软件如udiggeoserver等对空间数据的处理都是由geotools来做支撑。而其他很多的web服务命令行工具和桌面程序都可以由geotools来实现。
JTS
中文文档https://max.book118.com/html/2019/0624/6154225215002041.shtm 工具包相关文档下载https://download.csdn.net/download/abu935009066/16208250
JTS(Java Topology Suite) Java拓扑套件是Java的处理地理数据的API它提供以下功能
实现了OGC关于简单要素SQL查询规范定义的空间数据模型一个完整的、一致的、基本的二维空间算法的实现包括二元运算例如touch和overlap和空间分析方法例如intersection和buffer一个显示的精确模型用算法优雅的解决导致dimensional collapse尺度坍塌–专业名词不知道对不对暂时这样译的情况。健壮的实现了关键计算几何操作提供著名文本格式的I/O接口JTS是完全100%由Java写的
JTS支持一套完整的二元谓词操作。二元谓词方法将两个几何图形作为参数返回一个布尔值来表示几何图形是否有指定的空间关系。它支持的空间关系有相等equals、分离disjoint、相交intersect、相接touches、交叉crosses、包含于within、包含contains、覆盖/覆盖于overlaps。同时也支持一般的关系relate操作符。relate可以被用来确定维度扩展的九交模型DE-9IM,它可以完全的描述两个几何图形的关系。
https://locationtech.github.io/jts/
https://github.com/locationtech/jts
vividsolutions和locationtech jts
maven仓库
看了下vividsolutions于2015年就停在更新了好像在哪儿看过jts由vividsolutions变为的locationtech一个爹 应该是。选locationtech这个就完事了
创建几何对象
JTS提供了以下空间数据类型
多数的空间数据模型都是遵从这个的。 private GeometryFactory geometryFactory new GeometryFactory();点-Point
ByCoordinate坐标
Coordinate coord new Coordinate(109.013388, 32.715519);
Point point geometryFactory.createPoint( coord );ByWKT
WKTReader reader new WKTReader( geometryFactory );
Point point (Point) reader.read(POINT (109.013388 32.715519));多点-MultiPoint
WKTReader reader new WKTReader( geometryFactory );
MultiPoint mpoint (MultiPoint) reader.read(MULTIPOINT(109.013388 32.715519,119.32488 31.435678));线-LineString
Coordinate[] coords new Coordinate[] {new Coordinate(2, 2), new Coordinate(2, 2)};
LineString line geometryFactory.createLineString(coords);
// wkt
WKTReader reader new WKTReader( geometryFactory );
LineString line (LineString) reader.read(LINESTRING(0 0, 2 0));多线-MultiLineString
Coordinate[] coords1 new Coordinate[] {new Coordinate(2, 2), new Coordinate(2, 2)};
LineString line1 geometryFactory.createLineString(coords1);
Coordinate[] coords2 new Coordinate[] {new Coordinate(2, 2), new Coordinate(2, 2)};
LineString line2 geometryFactory.createLineString(coords2);
LineString[] lineStrings new LineString[2];
lineStrings[0] line1;
lineStrings[1] line2;
MultiLineString ms geometryFactory.createMultiLineString(lineStrings);
// wkt
WKTReader reader new WKTReader( geometryFactory );
MultiLineString line (MultiLineString) reader.read(MULTILINESTRING((0 0, 2 0),(1 1,2 2)));闭合线-LinearRing
LinearRing lr new GeometryFactory().createLinearRing(new Coordinate[]{new Coordinate(0, 0), new Coordinate(0, 10), new Coordinate(10, 10), new Coordinate(10, 0), new Coordinate(0, 0)});多边形-Polygon
WKTReader reader new WKTReader( geometryFactory );
Polygon polygon (Polygon) reader.read(POLYGON((20 10, 30 0, 40 10, 30 20, 20 10)));
多个多边形-MultiPolygon
WKTReader reader new WKTReader( geometryFactory );
MultiPolygon mpolygon (MultiPolygon) reader.read(MULTIPOLYGON(((40 10, 30 0, 40 10, 30 20, 40 10),(30 10, 30 0, 40 10, 30 20, 30 10))));
几何集合列表-GeometryCollection
LineString line createLine();
Polygon poly createPolygonByWKT();
Geometry g1 geometryFactory.createGeometry(line);
Geometry g2 geometryFactory.createGeometry(poly);
Geometry[] garray new Geometry[]{g1,g2};
GeometryCollection gc geometryFactory.createGeometryCollection(garray);
几何关系判断返回值 boolean
关系解释相等(Equals)几何形状拓扑上相等。不相交(Disjoint)几何形状没有共有的点。相交(Intersects)几何形状至少有一个共有点区别于脱节接触(Touches)几何形状有至少一个公共的边界点但是没有内部点。交叉(Crosses)几何形状共享一些但不是所有的内部点。内含(Within)几何形状A的线都在几何形状B内部。包含(Contains)几何形状B的线都在几何形状A内部区别于内含重叠(Overlaps)几何形状共享一部分但不是所有的公共点而且相交处有他们自己相同的区域。
举例相交其他类似 /*** 至少一个公共点(相交)* return* throws ParseException*/public boolean intersectsGeo() throws ParseException{WKTReader reader new WKTReader( geometryFactory );LineString geometry1 (LineString) reader.read(LINESTRING(0 0, 2 0, 5 0));LineString geometry2 (LineString) reader.read(LINESTRING(0 0, 0 2));Geometry interPoint geometry1.intersection(geometry2);//相交点System.out.println(interPoint.toText());//输出 POINT (0 0)return geometry1.intersects(geometry2);}几何关系分析返回值 几何对象
JTS支持基本的空间分析方法。空间分析方法使用一个或两个几何图形作为参数返回一个新构造的几何图形。
分析解释缓冲区分析Buffer包含所有的点在一个指定距离内的多边形和多多边形凸壳分析ConvexHull包含几何形体的所有点的最小凸壳多边形外包多边形交叉分析IntersectionA∩B 交叉操作就是多边形AB中所有共同点的集合联合分析UnionAUB AB的联合操作就是AB所有点的集合差异分析Difference(A-A∩B) AB形状的差异分析就是A里有B里没有的所有点的集合对称差异分析SymDifference(AUB-A∩B) AB形状的对称差异分析就是位于A中或者B中但不同时在AB中的所有点的集合距离、长度、面积计算
1.先把坐标系都转成墨卡托2.用jts计算距离3.由于转成墨卡托坐标系结果比实际偏大要乘以系数 // WGS84(一般项目中常用的是CRS:84和EPSG:4326)CoordinateReferenceSystem sourceCRS CRS.decode(CRS:84);// Pseudo-Mercator(墨卡托投影)CoordinateReferenceSystem targetCRS CRS.decode(EPSG:3857);MathTransform transform CRS.findMathTransform(sourceCRS, targetCRS, false);GeometryFactory GeometryFactory new GeometryFactory();Coordinate k96 new Coordinate(117.41722, 31.975379);Coordinate k97 new Coordinate(117.426387, 31.970712);Geometry line JTS.transform(GeometryFactory.createLineString(new Coordinate[]{k96, k97}), transform);//double rate1 Math.cos(Math.toRadians(k96.y)); 距离短的话乘以这个就行, 大概为 0.8482973000510488double rate Math.cos((Math.toRadians(k96.y) Math.toRadians(k97.y)) / 2.000000);//距离长的话用这个System.out.println(rate: rate);// 面积、周长System.out.println(line.getArea());// 面积未验证是乘以 rate 还是其平方System.out.println(line.getLength() * rate);Coordinate tmp new Coordinate(117.417145, 31.975465);Geometry point JTS.transform(GeometryFactory.createPoint(tmp), transform);System.out.println(point.distance(line) * rate);
按照代码包把所有功能介绍下 图形可视化化WKT数据好用的一比
工具包相关文档下载https://download.csdn.net/download/abu935009066/16208250 偶然间发现可以使用jts中的工具可视化我们的WKT数据。 需要java环境 项目实战
几何到另一个几何最近的点
GeometryFactory gf JTSFactoryFinder.getGeometryFactory(null);
WKTReader reader new WKTReader(gf);
Geometry line2 reader.read(LINESTRING(0 0, 10 0, 10 10, 20 10));
Coordinate c new Coordinate(5, 5);
PointPairDistance ppd new PointPairDistance();
DistanceToPoint.computeDistance(line2, c, ppd);
System.out.println(ppd.getDistance());
for (Coordinate cc : ppd.getCoordinates()) {System.out.println(cc);
}
求几何的交点
// create ring: P1(0,0) - P2(0,10) - P3(10,10) - P4(0,10)
LinearRing lr new GeometryFactory().createLinearRing(new Coordinate[]{new Coordinate(0,0), new Coordinate(0,10), new Coordinate(10,10), new Coordinate(10,0), new Coordinate(0,0)});
// create line: P5(5, -1) - P6(5, 11) - crossing the ring vertically in the middle
LineString ls new GeometryFactory().createLineString(new Coordinate[]{new Coordinate(5,-1), new Coordinate(5,11)});
// calculate intersection points
Geometry intersectionPoints lr.intersection(ls);
// simple output of points
for(Coordinate c : intersectionPoints.getCoordinates()){System.out.println(c.toString());
}
利用缓冲画圆
创建一个包含在设定距离内的所有点的面或多面(想要圆但是没有。。。)
geometry point
Geometry buffer geometry.buffer( 2.0 ); // note distance is in same units as geometry 根据起始点求一个线的子线
已知起点、终点、道路 求解其在道路上的子轨迹 GeometryFactory GeometryFactory new GeometryFactory();WKTReader reader new WKTReader(GeometryFactory);Geometry geom reader.read(LINESTRING(0 0, 10 0, 10 10, 20 10));LocationIndexedLine lil new LocationIndexedLine(geom);LinearLocation start lil.indexOf(new Coordinate(8, 5));LinearLocation end lil.indexOf(new Coordinate(17, 10));Geometry result lil.extractLine(start, end);System.out.println(result.toText());
// 结果
LINESTRING (10 5, 10 10, 17 10)计算道路与起点之间指定距离之间的交点坐标
已知道路、在道路的距离 求解到起点坐标距离的点 public static Coordinate lengthOnLineString2(Geometry roadLine, double length) {LocationIndexedLine locationIndexedLine new LocationIndexedLine(roadLine);LinearLocation linearLocation LengthLocationMap.getLocation(roadLine, length);Coordinate result locationIndexedLine.extractPoint(linearLocation);return result;}参考
https://blog.csdn.net/yatsov/article/details/80215278https://geotools.org/http://locationtech.github.io/jts/javadoc/overview-summary.htmlhttps://www.giserdqy.com/geoanalysis/29813/http://docs.geotools.org/latest/userguide/welcome/architecture.htmlhttps://docs.geotools.org/latest/userguide/library/jts/geometry.htmlhttps://docs.geotools.org/latest/userguide/library/jts/snap.html