コード例 #1
0
        /// <summary>
        /// <para>Decodes a polyline from string into points as GPS Position as latitude (X) longitude (Y)</para>
        /// <para>Source: https://github.com/mapbox/polyline/blob/master/src/polyline.js</para>
        /// </summary>
        /// <param name="encodedPolyline">Encoded polyline</param>
        /// <param name="precisionFactor">Precision factor of the encoded polyline. Same as the one you encoded with if you encoded yourself.</param>
        /// <returns>Points of the polyline as latitude, longitude</returns>
        private static List <ProjVector2> DecodePoints(string encodedPolyline, double precisionFactor)
        {
            List <ProjVector2> points = new List <ProjVector2>();
            int latitude  = 0;
            int longitude = 0;

            for (int i = 0; i < encodedPolyline.Length;)
            {
                int b;
                int shift  = 0;
                int result = 0;
                do
                {
                    b       = encodedPolyline[i++] - 63;
                    result |= (b & 31) << shift;
                    shift  += 5;
                }while (32 <= b);
                latitude += (result & 1) > 0 ? ~(result >> 1) : result >> 1;

                result = shift = 0;
                do
                {
                    b       = encodedPolyline[i++] - 63;
                    result |= (b & 31) << shift;
                    shift  += 5;
                }while (32 <= b);
                longitude += (result & 1) > 0 ? ~(result >> 1) : result >> 1;
                ProjVector2 p = new ProjVector2(latitude / precisionFactor, longitude / precisionFactor, Projection.LatitudeLongitude);
                points.Add(p);
            }

            return(points);
        }
コード例 #2
0
        public double?ProjectedDistance(ProjVector2 point, double distanceLimit)
        {
            point = point.ToProjection(Points.First().Projection);

            int    bestIndex = -1;
            double bestProj  = 0;
            double bestDist  = 0;

            for (int i = 1; i < Points.Count; i++)
            {
                ProjVector2 a    = Points[i] - Points[i - 1];
                ProjVector2 b    = point - Points[i - 1];
                double      proj = a.Dot(b) / a.LengthSquared;

                if (proj < 0)
                {
                    proj = 0;
                }
                else if (proj > 1)
                {
                    proj = 1;
                }

                double dist = (point - (Points[i] + a * proj)).MeterLength / 1000;

                if ((bestIndex == -1 || dist < bestDist) && dist < distanceLimit)
                {
                    bestIndex = i;
                    bestProj  = proj;
                    bestDist  = dist;
                }
            }

            // The point could not be projected
            if (bestIndex == -1)
            {
                return(null);
            }

            double km = 0;

            for (int i = 1; i <= bestIndex; i++)
            {
                km += (Points[i] - Points[i - 1]).MeterLength / 1000;
            }

            km += bestProj * (Points[bestIndex + 1] - Points[bestIndex]).MeterLength / 1000;

            return(km);
        }
コード例 #3
0
        private static List <PlacesAPIData> Scan(ProjVector2 position, double radius)
        {
            List <PlacesAPIData> ret     = new List <PlacesAPIData>();
            HttpWebRequest       request = WebRequest.CreateHttp("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=" + position.Vec.ToString() + "&radius=" + radius + "&type=train_station&key=" + APIKey);

            request.Method = "GET";
            try
            {
                using (WebResponse response = request.GetResponse())
                {
                    using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                    {
                        string  json   = reader.ReadToEnd();
                        JObject whole  = JObject.Parse(json);
                        string  status = whole["status"].ToString();
                        if (status == "OK" || status == "ZERO_RESULTS")
                        {
                            if (whole["results"] is JArray results)
                            {
                                foreach (JObject place in results)
                                {
                                    ret.Add(new PlacesAPIData(
                                                place["name"].ToString(),
                                                new ProjVector2(double.Parse(place["geometry"]["location"]["lat"].ToString()), double.Parse(place["geometry"]["location"]["lng"].ToString()), Projection.LatitudeLongitude)));
                                }
                            }
                        }
                        else
                        {
                            throw new PlacesAPIException("Places API is unavailable. Status code: " + status);
                        }
                    }
                }
            }
            catch (WebException)
            {
                // TODO: Log
                throw new PlacesAPIException("Places API is unavailable.");
            }

            return(ret);
        }
コード例 #4
0
        public static ProjVector2?Search(Station station, ProjVector2 position, double radius, int maxLevenshtein)
        {
            int           minDist = 0;
            PlacesAPIData?minRes  = null;
            var           results = Scan(position.ToProjection(Projection.LatitudeLongitude), radius);

            foreach (var result in results)
            {
                int dist = LevenshteinDistance(station.NormalizedName, Station.NormalizeName(result.StationName));
                if (dist == 0)
                {
                    return(result.Position);
                }

                if (dist <= maxLevenshtein && (minRes == null || dist < minDist))
                {
                    minRes  = result;
                    minDist = dist;
                }
            }

            return(minRes?.Position);
        }
コード例 #5
0
 public PlacesAPIData(string stationName, ProjVector2 position)
 {
     StationName = stationName;
     Position    = position;
 }