public static bool PolyContainsPointXY(List <PointXY> PointXYs, PointXY p) { bool inside = false; // An imaginary closing segment is implied, // so begin testing with that. PointXY v1 = PointXYs[PointXYs.Count - 1]; foreach (PointXY v0 in PointXYs) { double d1 = (p.Y - v0.Y) * (v1.X - v0.X); double d2 = (p.X - v0.X) * (v1.Y - v0.Y); if (p.Y < v1.Y) { // V1 below ray if (v0.Y <= p.Y) { // V0 on or above ray // Perform intersection test if (d1 > d2) { inside = !inside; // Toggle state } } } else if (p.Y < v0.Y) { // V1 is on or above ray, V0 is below ray // Perform intersection test if (d1 < d2) { inside = !inside; // Toggle state } } v1 = v0; //Store previous endPointXY as next startPointXY } return(inside); }
public List <VesselInfo> GetAllShipInArea(List <LatLngLiteral> Area) { var list = new List <VesselInfo>(); try { foreach (var item in ShipPositions.Values) { PointXY loc; VesselInfo data = null; if (item[item.Count - 1] is PositionReportClassAMessage) { var obj = item[item.Count - 1] as PositionReportClassAMessage; if (!ShipDatas.ContainsKey(obj.Mmsi)) { continue; } var shipInfo = ShipDatas[obj.Mmsi].Last() as StaticAndVoyageRelatedDataMessage; loc = new PointXY(obj.Latitude, obj.Longitude); data = new VesselInfo() { Mmsi = obj.Mmsi, Lat = obj.Latitude, Course = obj.CourseOverGround, Dest = shipInfo.Destination, ETA = $"{shipInfo.EtaDay}/{shipInfo.EtaMonth} {shipInfo.EtaHour}:{shipInfo.EtaMinute}", Lng = obj.Longitude, ShipName = shipInfo.ShipName, Speed = obj.SpeedOverGround, Status = obj.NavigationStatus.ToString(), Direction = obj.TrueHeading }; } else if (item[item.Count - 1] is ExtendedClassBCsPositionReportMessage) { var obj = item[item.Count - 1] as ExtendedClassBCsPositionReportMessage; if (!ShipDatas.ContainsKey(obj.Mmsi)) { continue; } var shipInfo = ShipDatas[obj.Mmsi].Last() as StaticAndVoyageRelatedDataMessage; loc = new PointXY(obj.Latitude, obj.Longitude); data = new VesselInfo() { Mmsi = obj.Mmsi, Lat = obj.Latitude, Course = obj.CourseOverGround, Dest = shipInfo.Destination, ETA = $"{shipInfo.EtaDay}/{shipInfo.EtaMonth} {shipInfo.EtaHour}:{shipInfo.EtaMinute}", Lng = obj.Longitude, ShipName = shipInfo.ShipName, Speed = obj.SpeedOverGround, Status = "", Direction = obj.TrueHeading }; } if (data != null) { if (Area == null) { list.Add(data); } else if (GeoFence.PointInPolygon(new LatLngLiteral() { Lat = data.Lat, Lng = data.Lng }, Area)) { list.Add(data); } } } } catch (Exception ex) { Console.WriteLine("get ships error : " + ex.Message); } return(list); }
public static PointXY Rotate(this PointXY pt, double angle, PointXY center) { Vector v = new Vector(pt.X - center.X, pt.Y - center.Y).Rotate(angle); return(new PointXY(v.X + center.X, v.Y + center.Y)); }