那些惊艳的 GIS 轮子 (2)

那些惊艳的 GIS 轮子

2.几何图形计算 // 几何创建工厂(也可不使用工厂模式直接创建几何图形) var gf = new GeometryFactory(); var pg3 = gf.CreatePolygon(new[] { new Coordinate(612, 612), new Coordinate(144, 355), new Coordinate(165, 188), new Coordinate(277, 328), new Coordinate(612, 612) }); var pg4 = gf.CreatePolygon(new[] { new Coordinate(412, 612), new Coordinate(555, 455), new Coordinate(655, 188), new Coordinate(577, 328), new Coordinate(412, 612) });

绿色是 pg3,金色是 pg4

那些惊艳的 GIS 轮子

求并集:var union = pg3.Union(pg4);

那些惊艳的 GIS 轮子

求交集:var intersection = pg3.Intersection(pg4);

那些惊艳的 GIS 轮子

求差集:var difference = pg3.Difference(pg4);
中间的连线是绘制时导致的,但是计算结果正确。我们查看其 WKT 描述为:MULTIPOLYGON (((478.68239179148486 538.78926215899912, 612 612, 499.14366946688551 516.32478247341942, 478.68239179148486 538.78926215899912)), ((478 498.4, 277 328, 165 188, 144 355, 460.37522887113056 528.73596970059953, 478 498.4)))的确是两个多边形。

那些惊艳的 GIS 轮子

其他能力,比如计算几何间距、面积、凸包、判断是否相交、是否覆盖等可查看项目的介绍或者 test 例子。详情访问https://github.com/NetTopologySuite/NetTopologySuite。去 star。

四、CoordinateSharp 与 NetTopologySuite

这么多优秀产品为何单独介绍 CoordinateSharp 与 NetTopologySuite?

假设有需求为画出某一城区的缓冲区,间距为 10km。这可怎么办?

在 NetTopologySuite 中直接提供缓冲区的计算函数public Geometry Buffer(double distance),效果也非常好:

红色为原始直线,按彩虹色依次相距为 10 的缓冲区

那些惊艳的 GIS 轮子

但是我们却忽略了一个重要的事情,NetTopologySuite 的计算的距离为平面坐标系下的欧氏距离。二维平面欧式距离的计算为Math.Sqrt(Math.Pow(x1-x2,2),Math.Pow(y1-y2,2)),直接用经纬度计算首都机场与虹桥机场的二维欧式距离为:10.06。而这个值显然对应着球面距离1074.07千米。考虑到随着维度的不同,两者之间的比例也并非是定值。最简单的例子就是,在赤道附近,一个经度差对应球面距离为 111.19 千米,而在 80° 纬度上则缩小到 19.31 千米,而在 90° 极点则几乎为 0 千米。

这时,我们就可以利用 CoordinateSharp 中点的移动功能,计算出给定球面距离对应的经纬度,然后利用移动前后的经纬度再计算欧式距离,得出的结果才较为准确。

还是以虹桥机场为例,绘制其半径为 100 千米的缓冲区:

// 对move进行简单的封装 public static double[] ConvertEarthDToPlaneXY(double lat, double lon, double distance, double bearing, Shape shape = Shape.Ellipsoid) { var c0 = new CoordinateSharp.Coordinate(lat, lon); c0.Move(distance, bearing, shape); return new[] { c0.Latitude.ToDouble(), c0.Longitude.ToDouble() }; } // 虹桥的位置 var hongqiao = new Coordinate(31.1982791377, 121.3356526703); var hqPoint = gf.CreatePoint(hongqiao); // 得出正西方向的100千米的位置hqMove var hqMove = ConvertEarthDToPlaneXY(hongqiao.X, hongqiao.Y,100000, 270); // 计算移动前后的欧式距离 var hqR = hongqiao.Distance(new Coordinate(hqMove[0], hqMove[1]); // 计算buffer var hqCircle = hqPoint.Buffer(hqR); //验证得出的buffer上的点与虹桥机场的位置 hqCircle .Coordinates .ToList() .ForEach(t => { var c1 = new CoordinateSharp.Coordinate(t.X, t.Y); var c2 = new CoordinateSharp.Coordinate(31.1982791377, 121.3356526703); var d0 = new CoordinateSharp.Distance(c1, c2, Shape.Sphere); Console.WriteLine(d0.Kilometers); });

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpypjg.html