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; /// /// /// /// 坐标(lat,lon) public TurfHelper(IEnumerable 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); } /// /// /// /// km 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); } /// /// 获取两个点的距离m /// /// /// /// 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); } /// /// /// https://gist.github.com/neilkennedy/9227665 /// /// /// /// /// SouthWest /// lon,lat /// public static bool Inside(double neLng, double neLat, double swLng, double swLat, double[] point) { var poly = Turf.BboxPolygon(new List() { neLng, neLat, swLng, swLat }); var ptIn = Turf.Point(point); return Turf.Inside(ptIn, poly); } ///// ///// ///// ///// lng, lat ///// ///// ///// ///// ///// //public static bool Inside(List 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; } /// /// 坐标点是否在多边形内判断 /// https://www.cnblogs.com/yushuo/p/9304471.html /// /// /// /// public static bool isPointInPolygon(location point, List 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; } } } }