/// <summary> /// Read map geometry data, automatically retrieving map data from the OpenStreetMap servers /// </summary> /// <param name="latitude">The latitude, in degrees</param> /// <param name="longitude">The longitude, in degrees</param> /// <param name="range">The range around the specified latitude and longitude to be collected, in degrees</param> /// <param name="layerNames"></param> /// <returns></returns> public GeometryLayerTable ReadMap(double latitude, double longitude, double range = 0.005, IList <string> layerNames = null) { //FilePath osmFile = FilePath.Temp + "TempMap.osm"; //DownloadMap(latitude, longitude, osmFile, range); //return ReadMap(osmFile, latitude, longitude); var data = DownloadMapData(longitude - range, latitude - range, longitude + range, latitude + range); using (var stream = new MemoryStream(data)) { return(ReadMap(stream, AnglePair.FromDegrees(latitude, longitude), layerNames)); } }
/// <summary> /// Get the longitude and latitude for an address string /// </summary> /// <param name="address"></param> /// <returns></returns> public AnglePair LatitudeAndLongitudeFromAddress(string address, AlertLog log = null) { // Nominatim requires a contact email address string queryString = NominatimAPI + "q=" + address + "&format=xml&[email protected]"; var web = new WebClient(); string xml = web.DownloadString(queryString); XElement xmlTree = XElement.Parse(xml); var place = xmlTree.Element("place"); string lat = place.Attribute("lat").Value; string lon = place.Attribute("lon").Value; double latitude; double.TryParse(lat, NumberStyles.Any, CultureInfo.InvariantCulture, out latitude); double longitude; double.TryParse(lon, NumberStyles.Any, CultureInfo.InvariantCulture, out longitude); return(AnglePair.FromDegrees(latitude, longitude)); /*var geocoder = new ForwardGeocoder(); * var task = geocoder.Geocode(new ForwardGeocodeRequest * { * queryString = address, * BreakdownAddressElements = true, * ShowExtraTags = true, * ShowAlternativeNames = true, * }); * * if (task.Result.Length > 0) * { * var response = task.Result[0]; * return AnglePair.FromDegrees(response.Latitude, response.Longitude); * } * else * throw new Exception("Address '" + address + "' could not be found."); */ /*var gls = new GoogleLocationService(); * try * { * var mapPt = gls.GetLatLongFromAddress(address); * if (mapPt == null) return Vector.Unset; * return new Vector(mapPt.Longitude, mapPt.Latitude); * } * catch * { * return Vector.Unset; * }*/ }
/// <summary> /// Read map geometry data from a file /// </summary> /// <param name="filePath"></param> /// <returns></returns> public GeometryLayerTable ReadMap(FilePath filePath, double originLatitude, double originLongitude, IList <string> layerNames = null) { if (filePath.Exists) { using (var fileStream = filePath.Info.OpenRead()) { return(ReadMap(fileStream, AnglePair.FromDegrees(originLatitude, originLongitude), layerNames)); } } else { return(null); } }
/// <summary> /// Read map geometry data, automatically retrieving map data from the OpenStreetMap servers /// </summary> /// <param name="latitude">The latitude, in degrees</param> /// <param name="longitude">The longitude, in degrees</param> /// <param name="range">The range around the specified latitude and longitude to be collected, in degrees</param> /// <param name="layerNames"></param> /// <returns></returns> public GeometryLayerTable ReadMap(double latitude, double longitude, double range = 0.005, IList <string> layerNames = null, AlertLog log = null) { //FilePath osmFile = FilePath.Temp + "TempMap.osm"; //DownloadMap(latitude, longitude, osmFile, range); //return ReadMap(osmFile, latitude, longitude); var data = DownloadMapData(longitude - range, latitude - range, longitude + range, latitude + range); try { using (var stream = new MemoryStream(data)) { return(ReadMap(stream, AnglePair.FromDegrees(latitude, longitude), layerNames)); } } catch (Exception ex) { log?.RaiseAlert("Error reading map " + ex.Message, AlertLevel.Information); return(null); } }
/// <summary> /// Read a map from a stream /// </summary> /// <param name="stream"></param> /// <param name="originLatLong"></param> /// <param name="layerNames"></param> /// <returns></returns> public GeometryLayerTable ReadMap(Stream stream, AnglePair originLatLong, IList <string> layerNames = null) { var result = new GeometryLayerTable(); var source = new XmlOsmStreamSource(stream); var nodes = new Dictionary <long, OsmSharp.Node>(); var ways = new Dictionary <long, OsmSharp.Way>(); if (layerNames == null) { layerNames = new List <string>(); layerNames.Add("Building"); layerNames.Add("Highway"); } foreach (var element in source) { if (element.Id != null) { if (element.Type == OsmSharp.OsmGeoType.Node) { nodes.Add((long)element.Id, (OsmSharp.Node)element); } else if (element.Type == OsmSharp.OsmGeoType.Way) { ways.Add((long)element.Id, (OsmSharp.Way)element); } //TODO: Relations? } } foreach (var way in ways.Values) { var pts = new List <Vector>(way.Nodes.Length); for (int i = 0; i < way.Nodes.Length; i++) { long nodeID = way.Nodes[i]; if (nodes.ContainsKey(nodeID)) { var node = nodes[nodeID]; pts.Add(node.Position(originLatLong)); } } VertexGeometry geometry = null; if (pts.Count == 2) { geometry = new Line(pts[0], pts[1]); } else if (pts.Count > 2) { geometry = new PolyLine(pts); //TODO: Areas } if (geometry != null) { string layerName = "Miscellaneous"; //Assign layer according to keys: if (way.Tags != null) { foreach (string name in layerNames) { string lName = name.ToLower(); if (way.Tags.ContainsKey(lName)) { string value = way.Tags[lName]; if (LayerSeparator != null && !string.IsNullOrWhiteSpace(value) && value != "yes") { layerName = name + LayerSeparator + value; } else { layerName = name; } break; } } if (ExtrudeBuildings) { if (geometry is Curve && way.Tags.ContainsKey("height")) { string heightTag = way.Tags["height"]; heightTag = heightTag.TrimEnd('m').Trim(); double height; if (double.TryParse(heightTag, out height)) { // TODO: Deal with tags with different units on the end! geometry = new Extrusion((Curve)geometry, new Vector(0, 0, height)); } } if (geometry is Curve && way.Tags.ContainsKey("building:levels")) { // Height not supplied - fall back to storeys: string levelsTag = way.Tags["building:levels"]; double levels; if (double.TryParse(levelsTag, out levels)) { geometry = new Extrusion((Curve)geometry, new Vector(0, 0, levels * StoreyHeight + ByStoreysExtraHeight)); } } if (geometry is Curve && DefaultBuildingHeight > 0 && way.Tags.ContainsKey("building")) { // No indication of height supplied - fall back to default: geometry = new Extrusion((Curve)geometry, new Vector(0, 0, DefaultBuildingHeight)); } } } var layer = result.GetOrCreate(layerName); layer.Add(geometry); } } return(result); }
/// <summary> /// Read map geometry data, automatically retrieving map data from the OpenStreetMap servers /// </summary> /// <param name="latLong">The latitude and longitude of the map origin</param> /// <param name="range">The range around the specified latitude and longitude to be collected, in degrees</param> /// <param name="layerNames"></param> /// <returns></returns> public GeometryLayerTable ReadMap(AnglePair latLong, double range = 0.005, IList <string> layerNames = null) { return(ReadMap(latLong.Elevation.Degrees, latLong.Azimuth.Degrees, range, layerNames)); }
/// <summary> /// Get the position of this node in m, relative to the specified origin /// </summary> /// <param name="node"></param> /// <param name="origin">The origin latitude and longitude</param> /// <returns></returns> public static Vector Position(this Osm.Node node, AnglePair origin) { return(node.Position(origin.Elevation.Degrees, origin.Azimuth.Degrees)); }