namespace GMap.NET.MapProviders { using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Xml; using GMap.NET.Internals; using GMap.NET.Projections; public abstract class OpenStreetMapProviderBase : GMapProvider, RoutingProvider, GeocodingProvider { public OpenStreetMapProviderBase() { MaxZoom = null; RefererUrl = "http://www.openstreetmap.org/"; Copyright = string.Format("© OpenStreetMap - Map data ©{0} OpenStreetMap", DateTime.Today.Year); } public readonly string ServerLetters = "abc"; public int MinExpectedRank = 22; #region GMapProvider Members public override Guid Id { get { throw new NotImplementedException(); } } public override string Name { get { throw new NotImplementedException(); } } public override PureProjection Projection { get { return MercatorProjection.Instance; } } public override GMapProvider[] Overlays { get { throw new NotImplementedException(); } } public override PureImage GetTileImage(GPoint pos, int zoom) { throw new NotImplementedException(); } #endregion #region GMapRoutingProvider Members public MapRoute GetRoute(PointLatLng start, PointLatLng end, bool avoidHighways, bool walkingMode, int Zoom) { List points = GetRoutePoints(MakeRoutingUrl(start, end, walkingMode ? TravelTypeFoot : TravelTypeMotorCar)); MapRoute route = points != null ? new MapRoute(points, walkingMode ? WalkingStr : DrivingStr) : null; return route; } /// /// NotImplemented /// /// /// /// /// /// /// public MapRoute GetRoute(string start, string end, bool avoidHighways, bool walkingMode, int Zoom) { throw new NotImplementedException("use GetRoute(PointLatLng start, PointLatLng end..."); } #region -- internals -- string MakeRoutingUrl(PointLatLng start, PointLatLng end, string travelType) { return string.Format(CultureInfo.InvariantCulture, RoutingUrlFormat, start.Lat, start.Lng, end.Lat, end.Lng, travelType); } List GetRoutePoints(string url) { List points = null; try { string route = GMaps.Instance.UseRouteCache ? Cache.Instance.GetContent(url, CacheType.RouteCache) : string.Empty; if(string.IsNullOrEmpty(route)) { route = GetContentUsingHttp(url); if(!string.IsNullOrEmpty(route)) { if(GMaps.Instance.UseRouteCache) { Cache.Instance.SaveContent(url, CacheType.RouteCache, route); } } } if(!string.IsNullOrEmpty(route)) { XmlDocument xmldoc = new XmlDocument(); xmldoc.LoadXml(route); System.Xml.XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(xmldoc.NameTable); xmlnsManager.AddNamespace("sm", "http://earth.google.com/kml/2.0"); ///Folder/Placemark/LineString/coordinates var coordNode = xmldoc.SelectSingleNode("/sm:kml/sm:Document/sm:Folder/sm:Placemark/sm:LineString/sm:coordinates", xmlnsManager); string[] coordinates = coordNode.InnerText.Split('\n'); if(coordinates.Length > 0) { points = new List(); foreach(string coordinate in coordinates) { if(coordinate != string.Empty) { string[] XY = coordinate.Split(','); if(XY.Length == 2) { double lat = double.Parse(XY[1], CultureInfo.InvariantCulture); double lng = double.Parse(XY[0], CultureInfo.InvariantCulture); points.Add(new PointLatLng(lat, lng)); } } } } } } catch(Exception ex) { Debug.WriteLine("GetRoutePoints: " + ex); } return points; } static readonly string RoutingUrlFormat = "http://www.yournavigation.org/api/1.0/gosmore.php?format=kml&flat={0}&flon={1}&tlat={2}&tlon={3}&v={4}&fast=1&layer=mapnik"; static readonly string TravelTypeFoot = "foot"; static readonly string TravelTypeMotorCar = "motorcar"; static readonly string WalkingStr = "Walking"; static readonly string DrivingStr = "Driving"; #endregion #endregion #region GeocodingProvider Members public GeoCoderStatusCode GetPoints(string keywords, out List pointList) { // http://nominatim.openstreetmap.org/search?q=lithuania,vilnius&format=xml #region -- response -- // // // // // // #endregion return GetLatLngFromGeocoderUrl(MakeGeocoderUrl(keywords), out pointList); } public PointLatLng? GetPoint(string keywords, out GeoCoderStatusCode status) { List pointList; status = GetPoints(keywords, out pointList); return pointList != null && pointList.Count > 0 ? pointList[0] : (PointLatLng?) null; } public GeoCoderStatusCode GetPoints(Placemark placemark, out List pointList) { // http://nominatim.openstreetmap.org/search?street=&city=vilnius&county=&state=&country=lithuania&postalcode=&format=xml #region -- response -- // // // #endregion return GetLatLngFromGeocoderUrl(MakeDetailedGeocoderUrl(placemark), out pointList); } public PointLatLng? GetPoint(Placemark placemark, out GeoCoderStatusCode status) { List pointList; status = GetPoints(placemark, out pointList); return pointList != null && pointList.Count > 0 ? pointList[0] : (PointLatLng?) null; } public GeoCoderStatusCode GetPlacemarks(PointLatLng location, out List placemarkList) { throw new NotImplementedException("use GetPlacemark"); } public Placemark? GetPlacemark(PointLatLng location, out GeoCoderStatusCode status) { //http://nominatim.openstreetmap.org/reverse?format=xml&lat=52.5487429714954&lon=-1.81602098644987&zoom=18&addressdetails=1 #region -- response -- /* 137, Pilkington Avenue, Castle Vale, City of Birmingham, West Midlands, England, B72 1LH, United Kingdom 137 Pilkington Avenue Castle Vale City of Birmingham West Midlands West Midlands England B72 1LH United Kingdom gb */ #endregion return GetPlacemarkFromReverseGeocoderUrl(MakeReverseGeocoderUrl(location), out status); } #region -- internals -- string MakeGeocoderUrl(string keywords) { return string.Format(GeocoderUrlFormat, keywords.Replace(' ', '+')); } string MakeDetailedGeocoderUrl(Placemark placemark) { var street = String.Join(" ", new[] { placemark.HouseNo, placemark.ThoroughfareName }).Trim(); return string.Format(GeocoderDetailedUrlFormat, street.Replace(' ', '+'), placemark.LocalityName.Replace(' ', '+'), placemark.SubAdministrativeAreaName.Replace(' ', '+'), placemark.AdministrativeAreaName.Replace(' ', '+'), placemark.CountryName.Replace(' ', '+'), placemark.PostalCodeNumber.Replace(' ', '+')); } string MakeReverseGeocoderUrl(PointLatLng pt) { return string.Format(CultureInfo.InvariantCulture, ReverseGeocoderUrlFormat, pt.Lat, pt.Lng); } GeoCoderStatusCode GetLatLngFromGeocoderUrl(string url, out List pointList) { var status = GeoCoderStatusCode.Unknow; pointList = null; try { string geo = GMaps.Instance.UseGeocoderCache ? Cache.Instance.GetContent(url, CacheType.GeocoderCache) : string.Empty; bool cache = false; if(string.IsNullOrEmpty(geo)) { geo = GetContentUsingHttp(url); if(!string.IsNullOrEmpty(geo)) { cache = true; } } if(!string.IsNullOrEmpty(geo)) { if(geo.StartsWith("(); foreach(XmlNode n in l) { var nn = n.Attributes["place_rank"]; int rank = 0; #if !PocketPC if (nn != null && Int32.TryParse(nn.Value, out rank)) { #else if(nn != null && !string.IsNullOrEmpty(nn.Value)) { rank = int.Parse(nn.Value, NumberStyles.Integer, CultureInfo.InvariantCulture); #endif if(rank < MinExpectedRank) continue; } nn = n.Attributes["lat"]; if(nn != null) { double lat = double.Parse(nn.Value, CultureInfo.InvariantCulture); nn = n.Attributes["lon"]; if(nn != null) { double lng = double.Parse(nn.Value, CultureInfo.InvariantCulture); pointList.Add(new PointLatLng(lat, lng)); } } } status = GeoCoderStatusCode.G_GEO_SUCCESS; } } } } } catch(Exception ex) { status = GeoCoderStatusCode.ExceptionInCode; Debug.WriteLine("GetLatLngFromGeocoderUrl: " + ex); } return status; } Placemark? GetPlacemarkFromReverseGeocoderUrl(string url, out GeoCoderStatusCode status) { status = GeoCoderStatusCode.Unknow; Placemark? ret = null; try { string geo = GMaps.Instance.UsePlacemarkCache ? Cache.Instance.GetContent(url, CacheType.PlacemarkCache) : string.Empty; bool cache = false; if(string.IsNullOrEmpty(geo)) { geo = GetContentUsingHttp(url); if(!string.IsNullOrEmpty(geo)) { cache = true; } } if(!string.IsNullOrEmpty(geo)) { if(geo.StartsWith(" /// OpenStreetMap provider - http://www.openstreetmap.org/ /// public class OpenStreetMapProvider : OpenStreetMapProviderBase { public static readonly OpenStreetMapProvider Instance; OpenStreetMapProvider() { } static OpenStreetMapProvider() { Instance = new OpenStreetMapProvider(); } #region GMapProvider Members readonly Guid id = new Guid("0521335C-92EC-47A8-98A5-6FD333DDA9C0"); public override Guid Id { get { return id; } } readonly string name = "OpenStreetMap"; public override string Name { get { return name; } } GMapProvider[] overlays; public override GMapProvider[] Overlays { get { if(overlays == null) { overlays = new GMapProvider[] { this }; } return overlays; } } public override PureImage GetTileImage(GPoint pos, int zoom) { string url = MakeTileImageUrl(pos, zoom, string.Empty); return GetTileImageUsingHttp(url); } #endregion string MakeTileImageUrl(GPoint pos, int zoom, string language) { char letter = ServerLetters[GetServerNum(pos, 3)]; return string.Format(UrlFormat, letter, zoom, pos.X, pos.Y); } static readonly string UrlFormat = "http://{0}.tile.openstreetmap.org/{1}/{2}/{3}.png"; } }