/// <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)); }
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); }
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); }
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); }
/// <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); }
/// <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); } } } } }
/// <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); }
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); }
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 }
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); }
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); }
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); }
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); } } } } }
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); }
/// <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)); }
/// <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); }
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); }