Example #1
0
        /// <summary>
        /// Retrieves the reuqest URL for the query.
        /// </summary>
        /// <returns>A string URL for the query.</returns>
        public override string GetRequestUrl()
        {
            string spatialFilter;

            double disKm = SpatialTools.ConvertDistance(Distance, DistanceUnits, DistanceUnitType.Kilometers);

            if (disKm < 0.16)
            {
                disKm = 0.16;
            }

            if (disKm > 1000)
            {
                disKm = 1000;
            }

            if (Center != null)
            {
                spatialFilter = string.Format(CultureInfo.InvariantCulture, "?spatialFilter=nearby({0:0.#####},{1:0.#####},{2})", Center.Latitude, Center.Longitude, disKm);
            }
            else if (!string.IsNullOrWhiteSpace(Address))
            {
                spatialFilter = string.Format(CultureInfo.InvariantCulture, "?spatialFilter=nearby('{0}',{1})", Uri.EscapeDataString(Address), disKm);
            }
            else
            {
                throw new Exception("Location to search nearby is not specified.");
            }

            return(string.Format(base.GetBaseRequestUrl(), spatialFilter));
        }
Example #2
0
        private async Task <CoordinateCollection> ParseRing(string wkt, int minCoords, bool closed, bool optimize)
        {
            string[] coords = wkt.Split(_commonDelimiter, StringSplitOptions.RemoveEmptyEntries);

            var locs = new CoordinateCollection();

            foreach (var coord in coords)
            {
                var c = ParseCoord(coord);
                if (c.HasValue)
                {
                    locs.Add(c.Value);
                }
            }

            if (optimize)
            {
                locs = await SpatialTools.VertexReductionAsync(locs, tolerance);
            }

            if (locs.Count > minCoords)
            {
                //Ensure the ring is closed
                if (closed && !locs[0].Equals(locs[locs.Count - 1]))
                {
                    locs.Add(locs[0]);
                }

                return(locs);
            }

            return(null);
        }
Example #3
0
        private async Task <LineString> ParseTrackSegment(XElement node)
        {
            var points = XmlUtilities.GetChildNodes(node, "trkpt");
            var coords = new CoordinateCollection();

            foreach (var p in points)
            {
                var c = ParseWaypointAsCoordinate(p);
                if (c.HasValue)
                {
                    coords.Add(c.Value);
                }
            }

            if (coords.Count >= 0)
            {
                if (optimize)
                {
                    coords = await SpatialTools.VertexReductionAsync(coords, tolerance);
                }

                return(new LineString(coords));
            }

            return(null);
        }
Example #4
0
        private static async Task <CoordinateCollection> ParseLinearRings(XElement rings, bool optimize, double tolerance)
        {
            CoordinateCollection rCoords = null;

            foreach (var c in rings.Elements())
            {
                if (c.Name.Namespace == gmlNS && string.Compare(c.Name.LocalName, "linearring", StringComparison.OrdinalIgnoreCase) == 0)
                {
                    foreach (var cc in c.Elements())
                    {
                        var coords = await ParsePosList(cc, optimize, tolerance);

                        if (coords != null && coords.Count >= 3)
                        {
                            rCoords = coords;
                            break;
                        }
                    }
                }
            }

            if (optimize)
            {
                rCoords = await SpatialTools.VertexReductionAsync(rCoords, tolerance);
            }

            return(rCoords);
        }
Example #5
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // Define i/o parameters
            Vector3d R = new Vector3d();
            Vector3d t = new Vector3d();

            // Read inputs
            if (!DA.GetData("R", ref R))
            {
                return;
            }
            if (!DA.GetData("t", ref t))
            {
                return;
            }

            // Exceptions
            if (!R.IsValid)
            {
                throw new Exception("Invalid rotation {Rx,Ry,Rz} vector");
            }
            if (!t.IsValid)
            {
                throw new Exception("Invalid translation {tx,ty,tz} vector");
            }

            Transform transform = SpatialTools.CreateTransformationMatrix(R, t);

            DA.SetData(0, transform);
        }
Example #6
0
        /// <summary>
        /// Parses a string list of coordinates. Handles 2D and 3D coordinate sets.
        /// </summary>
        /// <param name="dim">Number of values to represent coordinate.</param>
        /// <returns></returns>
        private async Task <CoordinateCollection> ParseCoordinates(XElement node)
        {
            if (node != null)
            {
                var sCoord = XmlUtilities.GetString(node, false);
                var vals   = SplitCoordString(sCoord, CoordArtifactRx, SpaceSplitter);

                var    c = new CoordinateCollection();
                double lon, lat;

                if (vals.Length >= 2)
                {
                    for (int i = 0; i < vals.Length; i = i + 2)
                    {
                        if (double.TryParse(vals[i], NumberStyles.Float, CultureInfo.InvariantCulture, out lat) &&
                            double.TryParse(vals[i + 1], NumberStyles.Float, CultureInfo.InvariantCulture, out lon))
                        {
                            c.Add(new Coordinate(lat, lon));
                        }
                    }
                }

                if (optimize)
                {
                    c = await SpatialTools.VertexReductionAsync(c, tolerance);
                }

                return(c);
            }

            return(null);
        }
        private void UpdateARView()
        {
            if (_currentLocation != null)
            {
                ItemCanvas.Children.Clear();

                if (_poiLocations != null && _poiLocations.Length > 0)
                {
                    var center = new Coordinate(_currentLocation.Position.Latitude,
                                                _currentLocation.Position.Longitude);

                    foreach (var poi in _poiLocations)
                    {
                        var c          = new Coordinate(poi.Latitude, poi.Longitude);
                        var poiHeading = SpatialTools.CalculateHeading(center, c);
                        var diff       = _currentHeading - poiHeading;

                        if (diff > 180)
                        {
                            diff = _currentHeading - (poiHeading + 360);
                        }
                        else if (diff < -180)
                        {
                            diff = _currentHeading + 360 - poiHeading;
                        }

                        if (Math.Abs(diff) <= 22.5)
                        {
                            var distance = SpatialTools.HaversineDistance(center, c, DistanceUnits.KM);

                            double left = 0;

                            if (diff > 0)
                            {
                                left = ItemCanvas.ActualWidth / 2 * ((22.5 - diff) / 22.5);
                            }
                            else
                            {
                                left = ItemCanvas.ActualWidth / 2 * (1 + -diff / 22.5);
                            }

                            double top = ItemCanvas.ActualHeight * (1 - distance / _defaultSeatchRadius);

                            var tb = new TextBlock()
                            {
                                Text                = poi.Name,
                                FontSize            = 24,
                                TextAlignment       = TextAlignment.Center,
                                HorizontalAlignment = HorizontalAlignment.Center
                            };

                            Canvas.SetLeft(tb, left);
                            Canvas.SetTop(tb, top);
                            ItemCanvas.Children.Add(tb);
                        }
                    }
                }
            }
        }
Example #8
0
        /// <summary>
        /// Reads LineString shapefile
        /// </summary>
        /// <param name="reader">The shapefile stream</param>
        /// <returns>A list of Geometry objects</returns>
        private async Task <List <Geometry> > ReadLineStringData(BinaryReader reader)
        {
            var items = new List <Geometry>();
            int numParts, numPoints;

            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                Geometry item;

                // Read Record Header.
                int id          = ReadRecordHeader(reader);
                var boundingBox = ReadBoundingBox(reader);

                // Read the number of Parts and Points in the shape.
                numParts  = NumberReader.ReadIntLE(reader);
                numPoints = NumberReader.ReadIntLE(reader);

                int[] parts = ReadParts(reader, numParts, numPoints);

                //First read all the rings
                var rings = new List <CoordinateCollection>();

                var multiline = new MultiLineString();
                for (int ringID = 0; ringID < numParts; ringID++)
                {
                    var line = new LineString();

                    for (int i = parts[ringID]; i < parts[ringID + 1]; i++)
                    {
                        line.Vertices.Add(ReadCoordinate(reader));
                    }

                    if (optimize)
                    {
                        line.Vertices = await SpatialTools.VertexReductionAsync(line.Vertices, tolerance);
                    }

                    multiline.Geometries.Add(line);
                }

                if (numParts == 1)
                {
                    item = (Geometry)multiline.Geometries[0];
                }
                else
                {
                    item = multiline;
                }

                item.Metadata.ID = id.ToString();
                item.Metadata.Properties.Add("BoundingBox", boundingBox);

                items.Add(item);
            }

            return(items);
        }
Example #9
0
        private static async Task <CoordinateCollection> ParsePosList(XElement node, bool optimize, double tolerance)
        {
            if (node.Name.Namespace == gmlNS && (string.Compare(node.Name.LocalName, "poslist", StringComparison.OrdinalIgnoreCase) == 0 ||
                                                 string.Compare(node.Name.LocalName, "coordinates", StringComparison.OrdinalIgnoreCase) == 0))
            {
                var dimension = XmlUtilities.GetDoubleAttribute(node, "dimension");
                int dim       = 2;

                if (!double.IsNaN(dimension) && dimension > 2)
                {
                    dim = (int)dimension;
                }

                var sCoord = XmlUtilities.GetString(node, false);
                var vals   = CoordArtifactRx.Replace(sCoord, " ").Split(SpaceSplitter, StringSplitOptions.RemoveEmptyEntries);

                var    c = new CoordinateCollection();
                double lat, lon, alt;

                if (dim == 3 && vals.Length >= 3)
                {
                    for (var i = 0; i < vals.Length; i = i + 3)
                    {
                        if (double.TryParse(vals[i], NumberStyles.Float, CultureInfo.InvariantCulture, out lat) &&
                            double.TryParse(vals[i + 1], NumberStyles.Float, CultureInfo.InvariantCulture, out lon) &&
                            double.TryParse(vals[i + 1], NumberStyles.Float, CultureInfo.InvariantCulture, out alt))
                        {
                            c.Add(new Coordinate(lat, lon, alt));
                        }
                    }
                }
                else if (dim == 2 && vals.Length >= 2)
                {
                    for (var i = 0; i < vals.Length; i = i + 2)
                    {
                        if (double.TryParse(vals[i], NumberStyles.Float, CultureInfo.InvariantCulture, out lat) &&
                            double.TryParse(vals[i + 1], NumberStyles.Float, CultureInfo.InvariantCulture, out lon))
                        {
                            c.Add(new Coordinate(lat, lon));
                        }
                    }
                }

                if (optimize)
                {
                    c = await SpatialTools.VertexReductionAsync(c, tolerance);
                }

                return(c);
            }

            return(null);
        }
Example #10
0
        public static Windows.Foundation.Point LocationToGlobalPixel(BasicGeoposition location, double zoom)
#endif
        {
            double x           = (location.Longitude + 180) / 360;
            double sinLatitude = Math.Sin(SpatialTools.ToRadians(location.Latitude));
            double y           = 0.5 - Math.Log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI);

            double mapSize = MapSize(zoom);

            #if WINDOWS_APP || WINDOWS_PHONE_APP
            return(new Windows.Foundation.Point((int)(x * mapSize), (int)(y * mapSize)));
            #elif WPF || WINDOWS_PHONE
            return(new System.Windows.Point((int)(x * mapSize), (int)(y * mapSize)));
            #endif
        }
Example #11
0
        private async Task <Geometry> ParseGeometry(XElement node)
        {
            if (node.Name.Namespace == geoRssNS)
            {
                switch (node.Name.LocalName)
                {
                case "point":
                    double tLat = double.NaN, tLon = double.NaN;
                    ParseCoordinate(node, out tLat, out tLon);
                    if (!double.IsNaN(tLat) && !double.IsNaN(tLon))
                    {
                        return(new Point(tLat, tLon));
                    }
                    break;

                case "line":
                    return(await ParseLineString(node));

                case "polygon":
                    return(await ParsePolygon(node));

                case "circle":
                    var sCoord = XmlUtilities.GetString(node, false);
                    var vals   = SplitCoordString(sCoord, CoordArtifactRx, SpaceSplitter);

                    double lon, lat, r;

                    if (vals.Length >= 2 &&
                        double.TryParse(vals[0], NumberStyles.Float, CultureInfo.InvariantCulture, out lat) &&
                        double.TryParse(vals[1], NumberStyles.Float, CultureInfo.InvariantCulture, out lon) &&
                        double.TryParse(vals[2], NumberStyles.Float, CultureInfo.InvariantCulture, out r))
                    {
                        var c = new Coordinate(lat, lon);
                        return(new Polygon(SpatialTools.GenerateRegularPolygon(c, r, DistanceUnits.Meters, 25, 0.0)));
                    }
                    break;

                default:
                    break;
                }
            }

            return(null);
        }
Example #12
0
        private async Task <CoordinateCollection> ParseCoordinates(JArray jsonArray)
        {
            var coords = new CoordinateCollection();

            foreach (var c in jsonArray)
            {
                var coord = ParseCoordinate(c as JArray);
                if (coord.HasValue)
                {
                    coords.Add(coord.Value);
                }
            }

            if (optimize)
            {
                coords = await SpatialTools.VertexReductionAsync(coords, tolerance);
            }

            return(coords);
        }
Example #13
0
        private async Task <CoordinateCollection> ReadCoordinates(BinaryReader reader, ByteOrder wkbByteOrder, WKBShapeType type, bool includeAltitude, bool includeM)
        {
            // Get the number of points in this linestring.
            int numPoints = (int)NumberReader.ReadUInt32(reader, wkbByteOrder);

            // Create a new array of coordinates.
            var coords = new CoordinateCollection();

            // Loop on the number of points in the ring.
            for (int i = 0; i < numPoints; i++)
            {
                coords.Add(ReadCoordinate(reader, wkbByteOrder, type, includeAltitude, includeM));
            }

            if (optimize)
            {
                coords = await SpatialTools.VertexReductionAsync(coords, tolerance);
            }

            return(coords);
        }
Example #14
0
        private async Task <CoordinateCollection> ParseCoordinates(XElement node)
        {
            if (node != null)
            {
                var    sCoord = XmlUtilities.GetString(node, false);
                double lat, lon, alt;
                var    tuples = SplitCoordString(sCoord, CoordArtifactRx, SpaceSplitter);

                var cc = new CoordinateCollection();

                foreach (var t in tuples)
                {
                    var vals = SplitCoordString(t, CoordArtifactRx, CommaSpaceSplitter);
                    if (vals.Length >= 2 &&
                        double.TryParse(vals[1], NumberStyles.Float, CultureInfo.InvariantCulture, out lat) &&
                        double.TryParse(vals[0], NumberStyles.Float, CultureInfo.InvariantCulture, out lon))
                    {
                        if (vals.Length > 3 && double.TryParse(vals[2], NumberStyles.Float, CultureInfo.InvariantCulture, out alt))
                        {
                            cc.Add(new Coordinate(lat, lon, alt));
                        }
                        else
                        {
                            cc.Add(new Coordinate(lat, lon));
                        }
                    }
                }

                if (optimize)
                {
                    cc = await SpatialTools.VertexReductionAsync(cc, tolerance);
                }

                return(cc);
            }

            return(null);
        }
        private static async Task <QueryResponse> MakeRequest(FindByPropertyRequest request)
        {
            var result = new QueryResponse();

            try
            {
                string urlRequest = request.GetRequestUrl();
                using (var responseStream = await ServiceHelper.GetStreamAsync(new Uri(urlRequest)))
                {
                    XDocument xmlDoc = XDocument.Load(responseStream);
                    string    name;

                    foreach (XElement element in xmlDoc.Descendants(XmlNamespaces.Atom + "entry"))
                    {
                        var r = new QueryResult()
                        {
                            EntityUrl = element.Element(XmlNamespaces.Atom + "id").Value,
                            Location  = new GeodataLocation()
                        };

                        XElement content = element.Element(XmlNamespaces.Atom + "content");

                        if (content != null && content.FirstNode != null)
                        {
                            XElement properties = (XElement)content.FirstNode;//.Element(XmlNamespaces.m + "properties");

                            if (properties != null)
                            {
                                foreach (var prop in properties.Descendants())
                                {
                                    name = prop.Name.LocalName;

                                    switch (name.ToLowerInvariant())
                                    {
                                    case "latitude":
                                        r.Location.Latitude = XmlUtilities.GetDouble(prop, 0);
                                        break;

                                    case "longitude":
                                        r.Location.Longitude = XmlUtilities.GetDouble(prop, 0);
                                        break;

                                    case "__distance":
                                        r.Distance = SpatialTools.ConvertDistance(XmlUtilities.GetDouble(prop, 0), DistanceUnitType.Kilometers, request.DistanceUnits);
                                        break;

                                    case "__IntersectedGeom":
                                        var wkt = XmlUtilities.GetString(prop);
                                        if (!string.IsNullOrEmpty(wkt))
                                        {
                                            r.IntersectedGeography = new Geography()
                                            {
                                                WellKnownText = wkt
                                            };
                                        }
                                        break;

                                    default:
                                        if (!r.Properties.ContainsKey(name))
                                        {
                                            var nVal = ParseNodeValue(prop);
                                            r.Properties.Add(name, nVal);

                                            if (nVal is Geography)
                                            {
                                                r.HasGeography = true;
                                            }
                                        }
                                        break;
                                    }
                                }
                            }
                        }

                        result.Results.Add(r);
                    }
                }
            }
            catch (Exception ex)
            {
                result.ErrorMessage = ex.Message;
            }

            return(result);
        }
        private void UpdateARView()
        {
            if (_currentLocation != null)
            {
                ItemCanvas.Children.Clear();

                if (_poiLocations != null && _poiLocations.Count > 0)
                {
                    var currentCoord = new Coordinate(_currentLocation.Position.Latitude,
                                                      _currentLocation.Position.Longitude);

                    foreach (var poi in _poiLocations)
                    {
                        if (Math.Abs(poi.Location.Latitude) > 90 || Math.Abs(poi.Location.Longitude) > 180)
                        {
                            continue;
                        }
                        var poiCoord   = new Coordinate(poi.Location.Latitude, poi.Location.Longitude);
                        var poiHeading = SpatialTools.CalculateHeading(currentCoord, poiCoord);
                        var diff       = _currentHeading - poiHeading;

                        if (diff > 180)
                        {
                            diff = _currentHeading - (poiHeading + 360);
                        }
                        else if (diff < -180)
                        {
                            diff = _currentHeading + 360 - poiHeading;
                        }

                        if (Math.Abs(diff) <= (_angleOfView / 2))
                        {
                            var distance = SpatialTools.HaversineDistance(currentCoord, poiCoord, DistanceUnits.Meters);

                            double left = 0;

                            if (diff > 0)
                            {
                                left = ItemCanvas.ActualWidth / 2 * (((_angleOfView / 2) - diff) / (_angleOfView / 2));
                            }
                            else
                            {
                                left = ItemCanvas.ActualWidth / 2 * (1 + -diff / (_angleOfView / 2));
                            }

                            double top = (ItemCanvas.ActualHeight - 90) * (1 - distance / RadiusSlider.Value) + 45;

                            var converter = new CategoryToPinSignConverter();
                            var symbol    = (Symbol)converter.Convert(poi.Category, null, null, null);
                            var pin       = new ArPin()
                            {
                                PinSign = symbol, PinDist = ((int)distance).ToString()
                            };

                            Canvas.SetLeft(pin, left - 32);
                            Canvas.SetTop(pin, top - 45);
                            ItemCanvas.Children.Add(pin);
                        }
                    }
                }
            }
        }
Example #17
0
        private async Task <List <Geometry> > ParseRoute(XElement node, Dictionary <string, ShapeStyle> styles)
        {
            var    geoms    = new List <Geometry>();
            var    line     = new LineString();
            var    metadata = new ShapeMetadata();
            var    coords   = new CoordinateCollection();
            var    style    = new ShapeStyle();
            string nodeName;

            foreach (var n in node.Elements())
            {
                nodeName = n.Name.LocalName;
                switch (nodeName)
                {
                case "name":
                    metadata.Title = XmlUtilities.GetString(n, stripHtml);
                    break;

                case "desc":
                    metadata.Description = XmlUtilities.GetString(n, stripHtml);
                    break;

                case "cmt":
                case "src":
                case "type":
                    SetMetadataString(metadata, nodeName, n, stripHtml);
                    break;

                case "number":    //<number> xsd:nonNegativeInteger </number> [0..1] ?
                    var i = XmlUtilities.GetInt32(n, -1);
                    if (i >= 0 && !metadata.Properties.ContainsKey(nodeName))
                    {
                        metadata.Properties.Add(nodeName, i);
                    }
                    break;

                case "link":
                    var href = XmlUtilities.GetStringAttribute(n, "href");

                    if (!string.IsNullOrWhiteSpace(href) && !metadata.Properties.ContainsKey(nodeName))
                    {
                        metadata.Properties.Add(nodeName, href);
                    }
                    break;

                case "rtept":
                    if (readRouteWaypoints)
                    {
                        var wpt = ParseWaypoint(n, styles);
                        coords.Add(wpt.Coordinate);
                        geoms.Add(wpt);
                    }
                    else
                    {
                        var c = ParseWaypointAsCoordinate(n);
                        if (c.HasValue)
                        {
                            coords.Add(c.Value);
                        }
                    }
                    break;

                case "extensions":
                    ParseExtensions(n, metadata, style);
                    break;

                default:
                    break;
                }
            }

            if (!string.IsNullOrEmpty(metadata.Title) || !string.IsNullOrEmpty(metadata.Description) || metadata.Properties.Count > 0)
            {
                line.Metadata = metadata;
            }

            if (style.StrokeColor.HasValue)
            {
                var styleKey = "embeddedStyle_" + embeddedStyleCnt;
                embeddedStyleCnt++;
                styles.Add(styleKey, style);
                line.StyleKey = styleKey;
            }

            if (coords.Count >= 2)
            {
                if (optimize)
                {
                    coords = await SpatialTools.VertexReductionAsync(coords, tolerance);
                }

                line.Vertices = coords;

                geoms.Add(line);
            }

            return(geoms);
        }
Example #18
0
        /// <summary>
        /// Calculates the Ground resolution at a specific degree of latitude in the specified units per pixel.
        /// </summary>
        /// <param name="latitude">Degree of latitude to calculate resolution at</param>
        /// <param name="zoom">Zoom level to calculate resolution at</param>
        /// <param name="unitType">Distance unit type to calculate resolution in</param>
        /// <returns>Ground resolution in distance unit per pixels</returns>
        public static double GroundResolution(double latitude, double zoom, DistanceUnits units)
        {
            double earthRadius = SpatialTools.GetEarthRadius(units);

            return((Math.Cos(SpatialTools.ToRadians(latitude)) * 2 * Math.PI * earthRadius) / MapSize(zoom));
        }
Example #19
0
        /// <summary>
        /// Read a shapefile Polygon record.
        /// </summary>
        /// <param name="reader">The Shapefile stream</param>
        /// <returns>A list of Geometry objects</returns>
        private List <Geometry> ReadPolygonData(BinaryReader reader)
        {
            var items = new List <Geometry>();
            int numParts, numPoints;

            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                Geometry item;

                // Read Record Header.
                int id          = ReadRecordHeader(reader);
                var boundingBox = ReadBoundingBox(reader);

                // Read the number of Parts and Points in the shape.
                numParts  = NumberReader.ReadIntLE(reader);
                numPoints = NumberReader.ReadIntLE(reader);

                int[] parts = ReadParts(reader, numParts, numPoints);

                //First read all the rings
                var rings = new List <CoordinateCollection>();

                for (int ringID = 0; ringID < numParts; ringID++)
                {
                    var ring = new CoordinateCollection();

                    for (int i = parts[ringID]; i < parts[ringID + 1]; i++)
                    {
                        ring.Add(ReadCoordinate(reader));
                    }

                    if (optimize)
                    {
                        ring = SpatialTools.VertexReduction(ring, tolerance);
                    }

                    rings.Add(ring);
                }

                // Vertices for a single, ringed polygon are always in clockwise order.
                // Rings defining holes in these polygons have a counterclockwise orientation.

                bool[] IsCounterClockWise = new bool[rings.Count];

                int PolygonCount = 0;

                //determine the orientation of each ring.
                for (int i = 0; i < rings.Count; i++)
                {
                    IsCounterClockWise[i] = rings[i].IsCCW();

                    if (!IsCounterClockWise[i])
                    {
                        PolygonCount++;     //count the number of polygons
                    }
                }

                //if the polygon count is 1 then there is only one polygon to create.
                if (PolygonCount == 1)
                {
                    Polygon polygon = new Polygon();
                    polygon.ExteriorRing = rings[0];
                    if (rings.Count > 1)
                    {
                        for (int i = 1; i < rings.Count; i++)
                        {
                            polygon.InteriorRings.Add(rings[i]);
                        }
                    }

                    item = polygon;
                }
                else
                {
                    MultiPolygon multPolygon = new MultiPolygon();
                    Polygon      poly        = new Polygon();
                    poly.ExteriorRing = rings[0];

                    for (int i = 1; i < rings.Count; i++)
                    {
                        if (!IsCounterClockWise[i])
                        {
                            multPolygon.Geometries.Add(poly);
                            poly = new Polygon(rings[i]);
                        }
                        else
                        {
                            poly.InteriorRings.Add(rings[i]);
                        }
                    }

                    multPolygon.Geometries.Add(poly);

                    item = multPolygon;
                }

                item.Metadata.ID = id.ToString();
                item.Metadata.Properties.Add("Bounding Box", boundingBox);

                items.Add(item);
            }

            return(items);
        }
Example #20
0
        private void PreCalculate()
        {
            //Stop the timer
            if (_timerId != null && _timerId.IsEnabled)
            {
                _timerId.Stop();
            }

            _duration = (_duration.HasValue && _duration.Value > 0) ? _duration : 150;

#if WINDOWS_PHONE
            _intervalLocs = new GeoCoordinateCollection();
#elif WINDOWS_PHONE_APP
            _intervalLocs = new List <BasicGeoposition>();
#else
            _intervalLocs = new LocationCollection();
#endif
            _intervalIdx = new List <int>();

            _intervalLocs.Add(_path[0]);
            _intervalIdx.Add(0);

            double dlat, dlon;
            double totalDistance = 0;

            if (_isGeodesic)
            {
                //Calcualte the total distance along the path in KM's.
                for (var i = 0; i < _path.Count - 1; i++)
                {
                    totalDistance += SpatialTools.HaversineDistance(_path[i].ToGeometry(), _path[i + 1].ToGeometry(), DistanceUnits.KM);
                }
            }
            else
            {
                //Calcualte the total distance along the path in degrees.
                for (var i = 0; i < _path.Count - 1; i++)
                {
                    dlat = _path[i + 1].Latitude - _path[i].Latitude;
                    dlon = _path[i + 1].Longitude - _path[i].Longitude;

                    totalDistance += Math.Sqrt(dlat * dlat + dlon * dlon);
                }
            }

            int    frameCount = (int)Math.Ceiling((double)_duration.Value / (double)_delay);
            int    idx        = 0;
            double progress;

            //Pre-calculate step points for smoother rendering.
            for (var f = 0; f < frameCount; f++)
            {
                progress = (double)(f * _delay) / (double)_duration.Value;

                double travel = progress * totalDistance;
                double alpha  = 0;
                double dist   = 0;
                double dx     = travel;

                for (var i = 0; i < _path.Count - 1; i++)
                {
                    if (_isGeodesic)
                    {
                        dist += SpatialTools.HaversineDistance(_path[i].ToGeometry(), _path[i + 1].ToGeometry(), DistanceUnits.KM);
                    }
                    else
                    {
                        dlat  = _path[i + 1].Latitude - _path[i].Latitude;
                        dlon  = _path[i + 1].Longitude - _path[i].Longitude;
                        alpha = Math.Atan2(dlat * Math.PI / 180, dlon * Math.PI / 180);
                        dist += Math.Sqrt(dlat * dlat + dlon * dlon);
                    }

                    if (dist >= travel)
                    {
                        idx = i;
                        break;
                    }

                    dx = travel - dist;
                }

                if (dx != 0 && idx < _path.Count - 1)
                {
                    if (_isGeodesic)
                    {
                        var bearing = SpatialTools.CalculateHeading(_path[idx].ToGeometry(), _path[idx + 1].ToGeometry());
                        _intervalLocs.Add(SpatialTools.CalculateDestinationCoordinate(_path[idx].ToGeometry(), bearing, dx, DistanceUnits.KM).ToBMGeometry());
                    }
                    else
                    {
                        dlat = dx * Math.Sin(alpha);
                        dlon = dx * Math.Cos(alpha);

#if WINDOWS_PHONE
                        _intervalLocs.Add(new GeoCoordinate(_path[idx].Latitude + dlat, _path[idx].Longitude + dlon));
#elif WINDOWS_PHONE_APP
                        _intervalLocs.Add(new BasicGeoposition()
                        {
                            Latitude  = _path[idx].Latitude + dlat,
                            Longitude = _path[idx].Longitude + dlon
                        });
#else
                        _intervalLocs.Add(new Location(_path[idx].Latitude + dlat, _path[idx].Longitude + dlon));
#endif
                    }

                    _intervalIdx.Add(idx);
                }
            }

            //Ensure the last location is the last coordinate in the path.
            _intervalLocs.Add(_path[_path.Count - 1]);
            _intervalIdx.Add(_path.Count - 1);
        }