コード例 #1
0
        } // End Function IsInside

        public static void Test()
        {
            //GeoApis.LatLng[] polygon1 = {new GeoApis.LatLng(0, 0),
            //                new GeoApis.LatLng(10, 0),
            //                new GeoApis.LatLng(10, 10),
            //                new GeoApis.LatLng(0, 10)};


            GeoApis.LatLng[] polygon1 = new GeoApis.LatLng[] {
                new GeoApis.LatLng(47.03687500000000000000M, 8.29712870000000000000M)
                , new GeoApis.LatLng(47.03681430000000000000M, 8.29710690000000000000M)
                , new GeoApis.LatLng(47.03659660000000000000M, 8.29702870000000000000M)
                , new GeoApis.LatLng(47.03666160000000000000M, 8.29665210000000000000M)
                , new GeoApis.LatLng(47.03651580000000000000M, 8.29659780000000000000M)
                , new GeoApis.LatLng(47.03657590000000000000M, 8.29625910000000000000M)
                , new GeoApis.LatLng(47.03700750000000000000M, 8.29641350000000000000M)
                , new GeoApis.LatLng(47.03696060000000000000M, 8.29669370000000000000M)
                , new GeoApis.LatLng(47.03691760000000000000M, 8.29667890000000000000M)
                , new GeoApis.LatLng(47.03688220000000000000M, 8.29688350000000000000M)
                , new GeoApis.LatLng(47.03691530000000000000M, 8.29689480000000000000M)
                , new GeoApis.LatLng(47.03687500000000000000M, 8.29712870000000000000M)
            };

            // GeoApis.LatLng p = new GeoApis.LatLng(20, 20);
            GeoApis.LatLng p = new GeoApis.LatLng(47.03677485655230000000M, 8.29674839973449900000M);
            // GeoApis.LatLng p = new GeoApis.LatLng(46.03687500000000000000M, 8.29712870000000000000M);

            bool inside = IsInside(polygon1, p);

            System.Console.WriteLine(inside);
        } // End Sub Test
コード例 #2
0
        } // End Function OnSegment

        // To find orientation of ordered triplet (p, q, r).
        // The function returns following values
        // 0 --> p, q and r are colinear
        // 1 --> Clockwise
        // 2 --> Counterclockwise
        private static int Orientation(GeoApis.LatLng p, GeoApis.LatLng q, GeoApis.LatLng r)
        {
            decimal val = (q.lat - p.lat) * (r.lng - q.lng) -
                          (q.lng - p.lng) * (r.lat - q.lat);

            if (val == 0)
            {
                return(0);             // colinear
            }
            return((val > 0) ? 1 : 2); // clock or counterclock wise
        } // End Function Orientation
コード例 #3
0
 // Given three colinear points p, q, r,
 // the function checks if point q lies
 // on line segment 'pr'
 private static bool OnSegment(GeoApis.LatLng p, GeoApis.LatLng q, GeoApis.LatLng r)
 {
     if (q.lng <= System.Math.Max(p.lng, r.lng) &&
         q.lng >= System.Math.Min(p.lng, r.lng) &&
         q.lat <= System.Math.Max(p.lat, r.lat) &&
         q.lat >= System.Math.Min(p.lat, r.lat))
     {
         return(true);
     }
     return(false);
 } // End Function OnSegment
コード例 #4
0
        static bool isClockwise(GeoApis.LatLng[] poly)
        {
            decimal sum = 0;

            for (int i = 0; i < poly.Length - 1; i++)
            {
                GeoApis.LatLng cur = poly[i], next = poly[i + 1];
                sum += (next.lat - cur.lat) * (next.lng + cur.lng);
            } // Next i

            return(sum > 0);
        } // End Function isClockwise
コード例 #5
0
        } // End Function Orientation

        // The function that returns true if
        // line segment 'p1q1' and 'p2q2' intersect.
        private static bool DoIntersect(GeoApis.LatLng p1, GeoApis.LatLng q1,
                                        GeoApis.LatLng p2, GeoApis.LatLng q2)
        {
            // Find the four orientations needed for
            // general and special cases
            int o1 = Orientation(p1, q1, p2);
            int o2 = Orientation(p1, q1, q2);
            int o3 = Orientation(p2, q2, p1);
            int o4 = Orientation(p2, q2, q1);

            // General case
            if (o1 != o2 && o3 != o4)
            {
                return(true);
            }

            // Special Cases
            // p1, q1 and p2 are colinear and
            // p2 lies on segment p1q1
            if (o1 == 0 && OnSegment(p1, p2, q1))
            {
                return(true);
            }

            // p1, q1 and p2 are colinear and
            // q2 lies on segment p1q1
            if (o2 == 0 && OnSegment(p1, q2, q1))
            {
                return(true);
            }

            // p2, q2 and p1 are colinear and
            // p1 lies on segment p2q2
            if (o3 == 0 && OnSegment(p2, p1, q2))
            {
                return(true);
            }

            // p2, q2 and q1 are colinear and
            // q1 lies on segment p2q2
            if (o4 == 0 && OnSegment(p2, q1, q2))
            {
                return(true);
            }

            // Doesn't fall in any of the above cases
            return(false);
        } // End Function DoIntersect
コード例 #6
0
        } // End Function DoIntersect

        // Returns true if the point p lies
        // inside the polygon[] with n vertices
        public static bool IsInside(GeoApis.LatLng[] polygon, GeoApis.LatLng p)
        {
            int n = polygon.Length;


            // There must be at least 3 vertices in polygon[]
            if (n < 3)
            {
                return(false);
            }

            // Create a point for line segment from p to infinite
            GeoApis.LatLng extreme = new GeoApis.LatLng(INF, p.lat);

            // Count intersections of the above line
            // with sides of polygon
            int count = 0, i = 0;

            do
            {
                int next = (i + 1) % n;

                // Check if the line segment from 'p' to
                // 'extreme' intersects with the line
                // segment from 'polygon[i]' to 'polygon[next]'
                if (DoIntersect(polygon[i],
                                polygon[next], p, extreme))
                {
                    // If the point 'p' is colinear with line
                    // segment 'i-next', then check if it lies
                    // on segment. If it lies, return true, otherwise false
                    if (Orientation(polygon[i], p, polygon[next]) == 0)
                    {
                        return(OnSegment(polygon[i], p,
                                         polygon[next]));
                    }
                    count++;
                }
                i = next;
            } while (i != 0);

            // Return true if count is odd, false otherwise
            return(count % 2 == 1);  // Same as (count%2 == 1)
        } // End Function IsInside
コード例 #7
0
        public static GeoApis.Polygon GetNearestBuildingPolygon(decimal latitide, decimal longitude)
        {
            OpenToolkit.Mathematics.DecimalVector2 geoPoint = new OpenToolkit.Mathematics.DecimalVector2(latitide, longitude);

            GeoApis.LatLngBounds bounds = GeoApis.LatLngBounds.FromPoint(
                new GeoApis.LatLng(latitide, longitude)
                , 1000
                ); // this is, radius = 500m

            decimal area = bounds.BoundsArea;

            if (area > 0.25m)
            {
                System.Console.WriteLine("The maximum bbox size is 0.25, and your request was too large.\nEither request a smaller area, or use planet.osm.");
                return(null);
            } // End if (area > 0.25m)


            string xml = null;

#if fromFile
            xml = System.IO.File.ReadAllText(@"D:\Stefan.Steiger\Desktop\map.osm.xml", System.Text.Encoding.UTF8);
#else
            const string OSM_API_VERSION = "0.6";
            // string url = "https://www.openstreetmap.org/api/0.6/map?bbox=8.626273870468141,47.69679769756054,8.636573553085329,47.700530864557194&no_cache=1562588642802";
            string url = "https://www.openstreetmap.org/api/" + OSM_API_VERSION + "/map?bbox=" + bounds.ToBBoxString();



            string[] proxyList = ProxyHelper.GetProxyArray();
            string   proxy     = null;

REPEAT_UNTIL_SUCCESS:
            proxy = proxyList[s_rnd.Next(0, proxyList.Length)];

            // proxy = "139.162.38.191:80";
            // proxy = "178.128.51.105";
            // proxy = "105.27.237.27:80";

            proxy = "161.117.251.194:80";
            proxy = "42.3.51.114:80";
            proxy = "173.212.202.65:80";
            proxy = "47.91.105.34:80";

            try
            {
                using (System.Net.WebClient wc = new WebClientWithCustomTimeout(15))
                {
                    // wc.Proxy = new System.Net.WebProxy(proxy);

                    xml = wc.DownloadString(url);
                } // End Using wc
            }
            catch (System.Net.WebException webEx)
            {
                System.Console.WriteLine(webEx.Message);
                System.Console.WriteLine(webEx.Status);

                if (webEx.Status == System.Net.WebExceptionStatus.Timeout)
                {
                    System.Console.WriteLine("Timeout ! ");
                }
                else if (webEx.Status == System.Net.WebExceptionStatus.ProtocolError)
                {
                    System.Console.WriteLine("ProtocolError");
                }

                System.Net.HttpWebResponse response = webEx.Response as System.Net.HttpWebResponse;
                if (response != null)
                {
                    System.Console.WriteLine("HTTP Status Code: " + response.StatusCode.ToString() + ", " + response.StatusDescription);

                    if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                    {
                        System.Console.WriteLine("401");
                    }

                    string responseHtml = null;
                    using (System.IO.Stream responseStream = response.GetResponseStream())
                    {
                        using (System.IO.TextReader tr = new System.IO.StreamReader(responseStream))
                        {
                            responseHtml = tr.ReadToEnd();
                        }
                    }

                    System.Console.WriteLine(responseHtml);
                }
                else
                {
                    // no http status code available
                }

                // goto REPEAT_UNTIL_SUCCESS;
            }
            catch (System.Exception ex)
            {
                System.Console.WriteLine(ex.Message);
                // goto REPEAT_UNTIL_SUCCESS;
            }
#endif


            System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
            doc.LoadXml(xml);

            System.Xml.XmlNodeList nodes = doc.SelectNodes("//node");


            System.Collections.Generic.Dictionary <string, GeoApis.LatLng> nodeDictionary =
                new System.Collections.Generic.Dictionary <string, GeoApis.LatLng>(
                    System.StringComparer.InvariantCultureIgnoreCase
                    );

            System.Collections.Generic.Dictionary <string, GeoApis.Polygon> buildingPolygonDictionary =
                new System.Collections.Generic.Dictionary <string, GeoApis.Polygon>(
                    System.StringComparer.InvariantCultureIgnoreCase
                    );



            if (nodes.Count > 1000)
            {
                System.Console.WriteLine(nodes.Count);
                throw new System.InvalidOperationException("Densely populated area. Too many nodes to process");
                return(null);
            }


            foreach (System.Xml.XmlElement node in nodes)
            {
                string id       = node.GetAttribute("id");
                string nodeLat  = node.GetAttribute("lat");
                string nodeLong = node.GetAttribute("lon");

                decimal dlat  = 0;
                decimal dlong = 0;
                decimal.TryParse(nodeLat, out dlat);
                decimal.TryParse(nodeLong, out dlong);

                nodeDictionary[id] = new GeoApis.LatLng(dlat, dlong);
            } // Next node


            // https://stackoverflow.com/questions/1457638/xpath-get-nodes-where-child-node-contains-an-attribute
            // querySelectorAll('way tag[k="building"]')
            System.Xml.XmlNodeList buildings = doc.SelectNodes("//way[tag/@k=\"building\"]");
            foreach (System.Xml.XmlElement building in buildings)
            {
                System.Collections.Generic.List <GeoApis.LatLng> lsPolygonPoints =
                    new System.Collections.Generic.List <GeoApis.LatLng>();

                System.Xml.XmlNodeList buildingNodes = building.SelectNodes("./nd");
                foreach (System.Xml.XmlElement buildingNode in buildingNodes)
                {
                    string reff = buildingNode.GetAttribute("ref");
                    lsPolygonPoints.Add(nodeDictionary[reff]);
                } // Next buildingNode

                GeoApis.LatLng[] polygonPoints = toCounterClockWise(lsPolygonPoints.ToArray());
                string           id            = building.GetAttribute("id");

                GeoApis.Polygon poly = new GeoApis.Polygon(polygonPoints);
                poly.OsmId = id;

                buildingPolygonDictionary[id] = poly;
            } // Next building

            // System.Console.WriteLine(buildingPolygonDictionary);



            decimal?min = null;
            string  uid = null;

            foreach (System.Collections.Generic.KeyValuePair <string, GeoApis.Polygon> kvp in buildingPolygonDictionary)
            {
                if (OsmPolygonHelper.IsInside(kvp.Value.Points, geoPoint))
                {
                    uid = kvp.Key;
                    min = 0;
                    break;
                }

                decimal minDist = kvp.Value.GetMinimumDistance(geoPoint);

                if (min.HasValue)
                {
                    if (minDist < min.Value)
                    {
                        min = minDist;
                        uid = kvp.Key;
                    } // End if (minDist < min.Value)
                }
                else
                {
                    uid = kvp.Key;
                    min = minDist;
                }
            } // Next kvp

            if (uid == null || !buildingPolygonDictionary.ContainsKey(uid))
            {
                return(null);
            }

            return(buildingPolygonDictionary[uid]);
        } // End Sub