private static string GetProjectionName(double latitude, double longitude) { List <StatePlanePolygon> polygons = LoadStatePlanePolygons(); foreach (StatePlanePolygon p in polygons) { if (latitude >= p.minLat && latitude <= p.maxLat && longitude >= p.minLon && longitude <= p.maxLon) { int intersections = 0; StatePlaneNode previousNode = null; foreach (StatePlaneNode n in p.Nodes) { if (previousNode != null && DoLinesIntersect(previousNode, n, latitude, longitude)) { intersections++; } previousNode = n; } if (DoLinesIntersect(p.Nodes[0], p.Nodes.Last(), latitude, longitude)) { intersections++; } if (intersections % 2 == 1) { return(p.ID); } } } return(""); }
private static bool DoLinesIntersect(StatePlaneNode v1, StatePlaneNode v2, double lat, double lon) { StatePlaneNode v3 = new StatePlaneNode("whatev", lat, lon); StatePlaneNode v4 = new StatePlaneNode("whatev", lat, double.MaxValue); double m = SolveM(v1, v2); double b = SolveB(v1, m); double m2 = SolveM(v3, v4); double b2 = SolveB(v3, m2); double x = (b2 - b) / (m - m2); double y = (m * x) + b; if (double.IsNaN(x) || double.IsNaN(y)) { return(false); } return(IsBetween(v1, v2, y, x) && IsBetween(v3, v4, y, x)); }
private static bool IsBetween(StatePlaneNode v1, StatePlaneNode v2, double lat, double lon) { //Handling perfectly straight in one direction lines... if (v1.Latitude == v2.Latitude) { if (v1.Longitude >= v2.Longitude) { if (lon > v2.Longitude && lon < v1.Longitude) { return(true); } else { return(false); } } else { if (lon < v2.Longitude && lon > v1.Longitude) { return(true); } else { return(false); } } } if (v1.Longitude == v2.Longitude) { if (v1.Latitude >= v2.Latitude) { if (lat > v2.Latitude && lat < v1.Latitude) { return(true); } else { return(false); } } else { if (lat < v2.Latitude && lat > v1.Latitude) { return(true); } else { return(false); } } } if (v1.Latitude > v2.Latitude) { if (v1.Longitude > v2.Longitude) { if (lat < v1.Latitude && lat > v2.Latitude && lon > v2.Longitude && lon < v1.Longitude) { return(true); } else { return(false); } } else { if (lat < v1.Latitude && lat > v2.Latitude && lon > v1.Longitude && lon < v2.Longitude) { return(true); } else { return(false); } } } else { if (v1.Longitude > v2.Longitude) { if (lat < v2.Latitude && lat > v1.Latitude && lon > v2.Longitude && lon < v1.Longitude) { return(true); } else { return(false); } } else { if (lat < v2.Latitude && lat > v1.Latitude && lon > v1.Longitude && lon < v2.Longitude) { return(true); } else { return(false); } } } }
private static double SolveB(StatePlaneNode v1, double m) { return(v1.Latitude - (m * v1.Longitude)); }
private static double SolveM(StatePlaneNode v1, StatePlaneNode v2) { return((v2.Latitude - v1.Latitude) / (v2.Longitude - v1.Longitude)); }
private static List <StatePlanePolygon> LoadStatePlanePolygons() { List <StatePlanePolygon> polygons = new List <StatePlanePolygon>(); DirectoryInfo dirInfo = new DirectoryInfo( string.Format("{0}\\Levrum\\Temp\\SRID", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)) ); using (StreamReader reader = new StreamReader(dirInfo.FullName + @"\StateProjectionShapes.geojson")) { string geoJSON = reader.ReadToEnd(); int nodeCount = 0; FeatureCollection features = JsonConvert.DeserializeObject <FeatureCollection>(geoJSON); foreach (Feature subFeature in features.Features) { if (subFeature.Geometry is MultiPolygon) { foreach (GeoJSONPolygon subPolygon in (subFeature.Geometry as MultiPolygon).Coordinates) { StatePlanePolygon statePlanePolygon = new StatePlanePolygon(); foreach (var property in subFeature.Properties) { if (property.Key == "ZONENAME") { statePlanePolygon.ID = Convert.ToString(property.Value); } } foreach (var coordinate in subPolygon.Coordinates) { foreach (var actualCoordinate in coordinate.Coordinates) { nodeCount++; StatePlaneNode node = new StatePlaneNode(Convert.ToString(nodeCount), actualCoordinate.Latitude, actualCoordinate.Longitude); if (node.Latitude < statePlanePolygon.minLat) { statePlanePolygon.minLat = node.Latitude; } if (node.Latitude > statePlanePolygon.maxLat) { statePlanePolygon.maxLat = node.Latitude; } if (node.Longitude < statePlanePolygon.minLon) { statePlanePolygon.minLon = node.Longitude; } if (node.Longitude > statePlanePolygon.maxLon) { statePlanePolygon.maxLon = node.Longitude; } statePlanePolygon.Nodes.Add(node); } } polygons.Add(statePlanePolygon); } } } } return(polygons); }