231 lines
8.2 KiB
C#
231 lines
8.2 KiB
C#
using GeoJSON.Net.Geometry;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using TurfCS;
|
||
|
||
namespace Assets.Scenes.Ride.Scripts
|
||
{
|
||
public class TurfHelper
|
||
{
|
||
|
||
//static TurfHelper()
|
||
//{
|
||
// string name = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + ".Resources.turf.min.js";
|
||
// System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||
|
||
//}
|
||
|
||
private LineString _line;
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="points">坐标(lat,lon)</param>
|
||
public TurfHelper(IEnumerable<double[]> points)
|
||
{
|
||
//var list = new GeoJSON.Net.Geometry.GeographicPosition();
|
||
var list = points.Select(p => new GeoJSON.Net.Geometry.GeographicPosition(p[0], p[1]));
|
||
|
||
_line = new LineString(list);
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="distance">km</param>
|
||
public GeographicPosition Along(double distance)
|
||
{
|
||
var pt1 = Turf.Along(_line, distance);
|
||
return ((GeographicPosition)((GeoJSON.Net.Geometry.Point)pt1.Geometry).Coordinates);
|
||
}
|
||
|
||
public double Bearing(double[] p1, double[] p2)
|
||
{
|
||
var pt1 = Turf.Point(p1);
|
||
var pt2 = Turf.Point(p2);
|
||
return Turf.Bearing(pt1, pt2);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取两个点的距离m
|
||
/// </summary>
|
||
/// <param name="from"></param>
|
||
/// <param name="to"></param>
|
||
/// <returns></returns>
|
||
public static double GetDistances(double[] from, double[] to)
|
||
{
|
||
var pt1 = Turf.Point(from);
|
||
var pt2 = Turf.Point(to);
|
||
var value = Turf.Distance(pt1, pt2, "kilometers") * 1000;
|
||
return Math.Round(value, 2);
|
||
}
|
||
|
||
/// <summary>
|
||
///
|
||
/// https://gist.github.com/neilkennedy/9227665
|
||
/// </summary>
|
||
/// <param name="neLng"></param>
|
||
/// <param name="neLat"></param>
|
||
/// <param name="swLng"></param>
|
||
/// <param name="swLat">SouthWest</param>
|
||
/// <param name="point">lon,lat</param>
|
||
/// <returns></returns>
|
||
public static bool Inside(double neLng, double neLat, double swLng, double swLat, double[] point)
|
||
{
|
||
var poly = Turf.BboxPolygon(new List<double>() { neLng, neLat, swLng, swLat });
|
||
var ptIn = Turf.Point(point);
|
||
|
||
return Turf.Inside(ptIn, poly);
|
||
}
|
||
|
||
|
||
///// <summary>
|
||
/////
|
||
///// </summary>
|
||
///// <param name="bottomLeft">lng, lat</param>
|
||
///// <param name="bottomRight"></param>
|
||
///// <param name="topRight"></param>
|
||
///// <param name="topLeft"></param>
|
||
///// <param name="point"></param>
|
||
///// <returns></returns>
|
||
//public static bool Inside(List<double[]> points, double[] point)
|
||
//{
|
||
// var script = new StringBuilder("var points = [];");
|
||
// foreach (var item in points)
|
||
// {
|
||
// script.AppendLine($"points.push([{ string.Join(",", item) }]);");
|
||
// }
|
||
// script.AppendLine($"points.push([{ string.Join(",", points.First()) }]);");
|
||
// script.AppendLine("var poly = turf.polygon([points]);");
|
||
// script.AppendLine($"turf.booleanPointInPolygon([{ string.Join(",", point) }], poly);");
|
||
|
||
|
||
// var result = (bool)engine.Evaluate(script.ToString());
|
||
|
||
// return result;
|
||
//}
|
||
|
||
public class location
|
||
{
|
||
public double lat;
|
||
public double lng;
|
||
}
|
||
/// <summary>
|
||
/// 坐标点是否在多边形内判断
|
||
/// https://www.cnblogs.com/yushuo/p/9304471.html
|
||
/// </summary>
|
||
/// <param name="point"></param>
|
||
/// <param name="pts"></param>
|
||
/// <returns></returns>
|
||
public static bool isPointInPolygon(location point, List<location> pts)
|
||
{
|
||
|
||
//检查类型
|
||
if (point == null || pts == null)
|
||
return false;
|
||
|
||
var N = pts.Count;
|
||
var boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
|
||
var intersectCount = 0; //cross points count of x
|
||
var precision = 2e-10; //浮点类型计算时候与0比较时候的容差
|
||
location p1, p2; //neighbour bound vertices
|
||
var p = point; //测试点
|
||
p1 = pts[0]; //left vertex
|
||
for (var i = 1; i <= N; ++i)
|
||
{
|
||
//check all rays
|
||
if (p.lat.Equals(p1.lat) && p.lng.Equals(p1.lng))
|
||
{
|
||
return boundOrVertex; //p is an vertex
|
||
}
|
||
|
||
p2 = pts[i % N]; //right vertex
|
||
if (p.lat < Math.Min(p1.lat, p2.lat) || p.lat > Math.Max(p1.lat, p2.lat))
|
||
{
|
||
//ray is outside of our interests
|
||
p1 = p2;
|
||
continue; //next ray left point
|
||
}
|
||
|
||
if (p.lat > Math.Min(p1.lat, p2.lat) && p.lat < Math.Max(p1.lat, p2.lat))
|
||
{
|
||
//ray is crossing over by the algorithm (common part of)
|
||
if (p.lng <= Math.Max(p1.lng, p2.lng))
|
||
{
|
||
//x is before of ray
|
||
if (p1.lat == p2.lat && p.lng >= Math.Min(p1.lng, p2.lng))
|
||
{
|
||
//overlies on a horizontal ray
|
||
return boundOrVertex;
|
||
}
|
||
|
||
if (p1.lng == p2.lng)
|
||
{
|
||
//ray is vertical
|
||
if (p1.lng == p.lng)
|
||
{
|
||
//overlies on a vertical ray
|
||
return boundOrVertex;
|
||
}
|
||
else
|
||
{
|
||
//before ray
|
||
++intersectCount;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//cross point on the left side
|
||
var xinters =
|
||
(p.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) +
|
||
p1.lng; //cross point of lng
|
||
if (Math.Abs(p.lng - xinters) < precision)
|
||
{
|
||
//overlies on a ray
|
||
return boundOrVertex;
|
||
}
|
||
|
||
if (p.lng < xinters)
|
||
{
|
||
//before ray
|
||
++intersectCount;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//special case when ray is crossing through the vertex
|
||
if (p.lat == p2.lat && p.lng <= p2.lng)
|
||
{
|
||
//p crossing over p2
|
||
var p3 = pts[(i + 1) % N]; //next vertex
|
||
if (p.lat >= Math.Min(p1.lat, p3.lat) && p.lat <= Math.Max(p1.lat, p3.lat))
|
||
{
|
||
//p.lat lies between p1.lat & p3.lat
|
||
++intersectCount;
|
||
}
|
||
else
|
||
{
|
||
intersectCount += 2;
|
||
}
|
||
}
|
||
}
|
||
p1 = p2; //next ray left point
|
||
}
|
||
|
||
if (intersectCount % 2 == 0)
|
||
{
|
||
//偶数在多边形外
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
//奇数在多边形内
|
||
return true;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|