Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2498 | - | 1 | |
2 | namespace GMap.NET.MapProviders |
||
3 | { |
||
4 | using System; |
||
5 | using System.Collections.Generic; |
||
6 | using System.Diagnostics; |
||
7 | using System.Globalization; |
||
8 | using System.Xml; |
||
9 | using GMap.NET.Internals; |
||
10 | using GMap.NET.Projections; |
||
11 | |||
12 | public abstract class OpenStreetMapProviderBase : GMapProvider, RoutingProvider, GeocodingProvider |
||
13 | { |
||
14 | public OpenStreetMapProviderBase() |
||
15 | { |
||
16 | MaxZoom = null; |
||
17 | RefererUrl = "http://www.openstreetmap.org/"; |
||
18 | Copyright = string.Format("© OpenStreetMap - Map data ©{0} OpenStreetMap", DateTime.Today.Year); |
||
19 | } |
||
20 | |||
21 | public readonly string ServerLetters = "abc"; |
||
22 | public int MinExpectedRank = 0; |
||
23 | |||
24 | #region GMapProvider Members |
||
25 | |||
26 | public override Guid Id |
||
27 | { |
||
28 | get |
||
29 | { |
||
30 | throw new NotImplementedException(); |
||
31 | } |
||
32 | } |
||
33 | |||
34 | public override string Name |
||
35 | { |
||
36 | get |
||
37 | { |
||
38 | throw new NotImplementedException(); |
||
39 | } |
||
40 | } |
||
41 | |||
42 | public override PureProjection Projection |
||
43 | { |
||
44 | get |
||
45 | { |
||
46 | return MercatorProjection.Instance; |
||
47 | } |
||
48 | } |
||
49 | |||
50 | public override GMapProvider[] Overlays |
||
51 | { |
||
52 | get |
||
53 | { |
||
54 | throw new NotImplementedException(); |
||
55 | } |
||
56 | } |
||
57 | |||
58 | public override PureImage GetTileImage(GPoint pos, int zoom) |
||
59 | { |
||
60 | throw new NotImplementedException(); |
||
61 | } |
||
62 | |||
63 | #endregion |
||
64 | |||
65 | #region GMapRoutingProvider Members |
||
66 | |||
67 | public MapRoute GetRoute(PointLatLng start, PointLatLng end, bool avoidHighways, bool walkingMode, int Zoom) |
||
68 | { |
||
69 | List<PointLatLng> points = GetRoutePoints(MakeRoutingUrl(start, end, walkingMode ? TravelTypeFoot : TravelTypeMotorCar)); |
||
70 | MapRoute route = points != null ? new MapRoute(points, walkingMode ? WalkingStr : DrivingStr) : null; |
||
71 | return route; |
||
72 | } |
||
73 | |||
74 | /// <summary> |
||
75 | /// NotImplemented |
||
76 | /// </summary> |
||
77 | /// <param name="start"></param> |
||
78 | /// <param name="end"></param> |
||
79 | /// <param name="avoidHighways"></param> |
||
80 | /// <param name="walkingMode"></param> |
||
81 | /// <param name="Zoom"></param> |
||
82 | /// <returns></returns> |
||
83 | public MapRoute GetRoute(string start, string end, bool avoidHighways, bool walkingMode, int Zoom) |
||
84 | { |
||
85 | throw new NotImplementedException("use GetRoute(PointLatLng start, PointLatLng end..."); |
||
86 | } |
||
87 | |||
88 | #region -- internals -- |
||
89 | string MakeRoutingUrl(PointLatLng start, PointLatLng end, string travelType) |
||
90 | { |
||
91 | return string.Format(CultureInfo.InvariantCulture, RoutingUrlFormat, start.Lat, start.Lng, end.Lat, end.Lng, travelType); |
||
92 | } |
||
93 | |||
94 | List<PointLatLng> GetRoutePoints(string url) |
||
95 | { |
||
96 | List<PointLatLng> points = null; |
||
97 | try |
||
98 | { |
||
99 | string route = GMaps.Instance.UseRouteCache ? Cache.Instance.GetContent(url, CacheType.RouteCache) : string.Empty; |
||
100 | if(string.IsNullOrEmpty(route)) |
||
101 | { |
||
102 | route = GetContentUsingHttp(url); |
||
103 | if(!string.IsNullOrEmpty(route)) |
||
104 | { |
||
105 | if(GMaps.Instance.UseRouteCache) |
||
106 | { |
||
107 | Cache.Instance.SaveContent(url, CacheType.RouteCache, route); |
||
108 | } |
||
109 | } |
||
110 | } |
||
111 | |||
112 | if(!string.IsNullOrEmpty(route)) |
||
113 | { |
||
114 | XmlDocument xmldoc = new XmlDocument(); |
||
115 | xmldoc.LoadXml(route); |
||
116 | System.Xml.XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(xmldoc.NameTable); |
||
117 | xmlnsManager.AddNamespace("sm", "http://earth.google.com/kml/2.0"); |
||
118 | |||
119 | ///Folder/Placemark/LineString/coordinates |
||
120 | var coordNode = xmldoc.SelectSingleNode("/sm:kml/sm:Document/sm:Folder/sm:Placemark/sm:LineString/sm:coordinates", xmlnsManager); |
||
121 | |||
122 | string[] coordinates = coordNode.InnerText.Split('\n'); |
||
123 | |||
124 | if(coordinates.Length > 0) |
||
125 | { |
||
126 | points = new List<PointLatLng>(); |
||
127 | |||
128 | foreach(string coordinate in coordinates) |
||
129 | { |
||
130 | if(coordinate != string.Empty) |
||
131 | { |
||
132 | string[] XY = coordinate.Split(','); |
||
133 | if(XY.Length == 2) |
||
134 | { |
||
135 | double lat = double.Parse(XY[1], CultureInfo.InvariantCulture); |
||
136 | double lng = double.Parse(XY[0], CultureInfo.InvariantCulture); |
||
137 | points.Add(new PointLatLng(lat, lng)); |
||
138 | } |
||
139 | } |
||
140 | } |
||
141 | } |
||
142 | } |
||
143 | } |
||
144 | catch(Exception ex) |
||
145 | { |
||
146 | Debug.WriteLine("GetRoutePoints: " + ex); |
||
147 | } |
||
148 | |||
149 | return points; |
||
150 | } |
||
151 | |||
152 | 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"; |
||
153 | static readonly string TravelTypeFoot = "foot"; |
||
154 | static readonly string TravelTypeMotorCar = "motorcar"; |
||
155 | |||
156 | static readonly string WalkingStr = "Walking"; |
||
157 | static readonly string DrivingStr = "Driving"; |
||
158 | #endregion |
||
159 | |||
160 | #endregion |
||
161 | |||
162 | #region GeocodingProvider Members |
||
163 | |||
164 | public GeoCoderStatusCode GetPoints(string keywords, out List<PointLatLng> pointList) |
||
165 | { |
||
166 | // http://nominatim.openstreetmap.org/search?q=lithuania,vilnius&format=xml |
||
167 | |||
168 | #region -- response -- |
||
169 | //<searchresults timestamp="Wed, 01 Feb 12 09:46:00 -0500" attribution="Data Copyright OpenStreetMap Contributors, Some Rights Reserved. CC-BY-SA 2.0." querystring="lithuania,vilnius" polygon="false" exclude_place_ids="29446018,53849547,8831058,29614806" more_url="http://open.mapquestapi.com/nominatim/v1/search?format=xml&exclude_place_ids=29446018,53849547,8831058,29614806&accept-language=en&q=lithuania%2Cvilnius"> |
||
170 | //<place place_id="29446018" osm_type="way" osm_id="24598347" place_rank="30" boundingbox="54.6868133544922,54.6879043579102,25.2885360717773,25.2898139953613" lat="54.6873633486028" lon="25.289199818878" display_name="National Museum of Lithuania, 1, Arsenalo g., Senamiesčio seniūnija, YAHOO-HIRES-20080313, Vilnius County, Šalčininkų rajonas, Vilniaus apskritis, 01513, Lithuania" class="tourism" type="museum" icon="http://open.mapquestapi.com/nominatim/v1/images/mapicons/tourist_museum.p.20.png"/> |
||
171 | //<place place_id="53849547" osm_type="way" osm_id="55469274" place_rank="30" boundingbox="54.6896553039551,54.690486907959,25.2675743103027,25.2692089080811" lat="54.6900227236882" lon="25.2683589759401" display_name="Ministry of Foreign Affairs of the Republic of Lithuania, 2, J. Tumo Vaižganto g., Naujamiesčio seniūnija, Vilnius, Vilnius County, Vilniaus m. savivaldybė, Vilniaus apskritis, LT-01104, Lithuania" class="amenity" type="public_building"/> |
||
172 | //<place place_id="8831058" osm_type="node" osm_id="836234960" place_rank="30" boundingbox="54.6670935059,54.6870973206,25.2638857269,25.2838876343" lat="54.677095" lon="25.2738876" display_name="Railway Museum of Lithuania, 15, Mindaugo g., Senamiesčio seniūnija, Vilnius, Vilnius County, Vilniaus m. savivaldybė, Vilniaus apskritis, 03215, Lithuania" class="tourism" type="museum" icon="http://open.mapquestapi.com/nominatim/v1/images/mapicons/tourist_museum.p.20.png"/> |
||
173 | //<place place_id="29614806" osm_type="way" osm_id="24845629" place_rank="30" boundingbox="54.6904983520508,54.6920852661133,25.2606296539307,25.2628803253174" lat="54.6913385159005" lon="25.2617684209873" display_name="Seimas (Parliament) of the Republic of Lithuania, 53, Gedimino pr., Naujamiesčio seniūnija, Vilnius, Vilnius County, Vilniaus m. savivaldybė, Vilniaus apskritis, LT-01111, Lithuania" class="amenity" type="public_building"/> |
||
174 | //</searchresults> |
||
175 | #endregion |
||
176 | |||
177 | return GetLatLngFromGeocoderUrl(MakeGeocoderUrl(keywords), out pointList); |
||
178 | } |
||
179 | |||
180 | public PointLatLng? GetPoint(string keywords, out GeoCoderStatusCode status) |
||
181 | { |
||
182 | List<PointLatLng> pointList; |
||
183 | status = GetPoints(keywords, out pointList); |
||
184 | return pointList != null && pointList.Count > 0 ? pointList[0] : (PointLatLng?) null; |
||
185 | } |
||
186 | |||
187 | public GeoCoderStatusCode GetPoints(Placemark placemark, out List<PointLatLng> pointList) |
||
188 | { |
||
189 | // http://nominatim.openstreetmap.org/search?street=&city=vilnius&county=&state=&country=lithuania&postalcode=&format=xml |
||
190 | |||
191 | #region -- response -- |
||
192 | //<searchresults timestamp="Thu, 29 Nov 12 08:38:23 +0000" attribution="Data © OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright" querystring="vilnius, lithuania" polygon="false" exclude_place_ids="98093941" more_url="http://nominatim.openstreetmap.org/search?format=xml&exclude_place_ids=98093941&accept-language=de-de,de;q=0.8,en-us;q=0.5,en;q=0.3&q=vilnius%2C+lithuania"> |
||
193 | //<place place_id="98093941" osm_type="relation" osm_id="1529146" place_rank="16" boundingbox="54.5693359375,54.8323097229004,25.0250644683838,25.4815216064453" lat="54.6843135" lon="25.2853984" display_name="Vilnius, Vilniaus m. savivaldybė, Distrikt Vilnius, Litauen" class="boundary" type="administrative" icon="http://nominatim.openstreetmap.org/images/mapicons/poi_boundary_administrative.p.20.png"/> |
||
194 | //</searchresults> |
||
195 | #endregion |
||
196 | |||
197 | return GetLatLngFromGeocoderUrl(MakeDetailedGeocoderUrl(placemark), out pointList); |
||
198 | } |
||
199 | |||
200 | public PointLatLng? GetPoint(Placemark placemark, out GeoCoderStatusCode status) |
||
201 | { |
||
202 | List<PointLatLng> pointList; |
||
203 | status = GetPoints(placemark, out pointList); |
||
204 | return pointList != null && pointList.Count > 0 ? pointList[0] : (PointLatLng?) null; |
||
205 | } |
||
206 | |||
207 | public GeoCoderStatusCode GetPlacemarks(PointLatLng location, out List<Placemark> placemarkList) |
||
208 | { |
||
209 | throw new NotImplementedException("use GetPlacemark"); |
||
210 | } |
||
211 | |||
212 | public Placemark? GetPlacemark(PointLatLng location, out GeoCoderStatusCode status) |
||
213 | { |
||
214 | //http://nominatim.openstreetmap.org/reverse?format=xml&lat=52.5487429714954&lon=-1.81602098644987&zoom=18&addressdetails=1 |
||
215 | |||
216 | #region -- response -- |
||
217 | /* |
||
218 | <reversegeocode timestamp="Wed, 01 Feb 12 09:51:11 -0500" attribution="Data Copyright OpenStreetMap Contributors, Some Rights Reserved. CC-BY-SA 2.0." querystring="format=xml&lat=52.5487429714954&lon=-1.81602098644987&zoom=18&addressdetails=1"> |
||
219 | <result place_id="2061235282" osm_type="way" osm_id="90394420" lat="52.5487800131654" lon="-1.81626922291265"> |
||
220 | 137, Pilkington Avenue, Castle Vale, City of Birmingham, West Midlands, England, B72 1LH, United Kingdom |
||
221 | </result> |
||
222 | <addressparts> |
||
223 | <house_number> |
||
224 | 137 |
||
225 | </house_number> |
||
226 | <road> |
||
227 | Pilkington Avenue |
||
228 | </road> |
||
229 | <suburb> |
||
230 | Castle Vale |
||
231 | </suburb> |
||
232 | <city> |
||
233 | City of Birmingham |
||
234 | </city> |
||
235 | <county> |
||
236 | West Midlands |
||
237 | </county> |
||
238 | <state_district> |
||
239 | West Midlands |
||
240 | </state_district> |
||
241 | <state> |
||
242 | England |
||
243 | </state> |
||
244 | <postcode> |
||
245 | B72 1LH |
||
246 | </postcode> |
||
247 | <country> |
||
248 | United Kingdom |
||
249 | </country> |
||
250 | <country_code> |
||
251 | gb |
||
252 | </country_code> |
||
253 | </addressparts> |
||
254 | </reversegeocode> |
||
255 | */ |
||
256 | |||
257 | #endregion |
||
258 | |||
259 | return GetPlacemarkFromReverseGeocoderUrl(MakeReverseGeocoderUrl(location), out status); |
||
260 | } |
||
261 | |||
262 | #region -- internals -- |
||
263 | |||
264 | string MakeGeocoderUrl(string keywords) |
||
265 | { |
||
266 | return string.Format(GeocoderUrlFormat, keywords.Replace(' ', '+')); |
||
267 | } |
||
268 | |||
269 | string MakeDetailedGeocoderUrl(Placemark placemark) |
||
270 | { |
||
271 | var street = String.Join(" ", new[] { placemark.HouseNo, placemark.ThoroughfareName }).Trim(); |
||
272 | return string.Format(GeocoderDetailedUrlFormat, |
||
273 | street.Replace(' ', '+'), |
||
274 | placemark.LocalityName.Replace(' ', '+'), |
||
275 | placemark.SubAdministrativeAreaName.Replace(' ', '+'), |
||
276 | placemark.AdministrativeAreaName.Replace(' ', '+'), |
||
277 | placemark.CountryName.Replace(' ', '+'), |
||
278 | placemark.PostalCodeNumber.Replace(' ', '+')); |
||
279 | } |
||
280 | |||
281 | string MakeReverseGeocoderUrl(PointLatLng pt) |
||
282 | { |
||
283 | return string.Format(CultureInfo.InvariantCulture, ReverseGeocoderUrlFormat, pt.Lat, pt.Lng); |
||
284 | } |
||
285 | |||
286 | GeoCoderStatusCode GetLatLngFromGeocoderUrl(string url, out List<PointLatLng> pointList) |
||
287 | { |
||
288 | var status = GeoCoderStatusCode.Unknow; |
||
289 | pointList = null; |
||
290 | |||
291 | try |
||
292 | { |
||
293 | string geo = GMaps.Instance.UseGeocoderCache ? Cache.Instance.GetContent(url, CacheType.GeocoderCache) : string.Empty; |
||
294 | |||
295 | bool cache = false; |
||
296 | |||
297 | if(string.IsNullOrEmpty(geo)) |
||
298 | { |
||
299 | geo = GetContentUsingHttp(url); |
||
300 | |||
301 | if(!string.IsNullOrEmpty(geo)) |
||
302 | { |
||
303 | cache = true; |
||
304 | } |
||
305 | } |
||
306 | |||
307 | if(!string.IsNullOrEmpty(geo)) |
||
308 | { |
||
309 | if(geo.StartsWith("<?xml") && geo.Contains("<place")) |
||
310 | { |
||
311 | if(cache && GMaps.Instance.UseGeocoderCache) |
||
312 | { |
||
313 | Cache.Instance.SaveContent(url, CacheType.GeocoderCache, geo); |
||
314 | } |
||
315 | |||
316 | XmlDocument doc = new XmlDocument(); |
||
317 | doc.LoadXml(geo); |
||
318 | { |
||
319 | XmlNodeList l = doc.SelectNodes("/searchresults/place"); |
||
320 | if(l != null) |
||
321 | { |
||
322 | pointList = new List<PointLatLng>(); |
||
323 | |||
324 | foreach(XmlNode n in l) |
||
325 | { |
||
326 | var nn = n.Attributes["place_rank"]; |
||
327 | |||
328 | int rank = 0; |
||
329 | #if !PocketPC |
||
330 | if (nn != null && Int32.TryParse(nn.Value, out rank)) |
||
331 | { |
||
332 | #else |
||
333 | if(nn != null && !string.IsNullOrEmpty(nn.Value)) |
||
334 | { |
||
335 | rank = int.Parse(nn.Value, NumberStyles.Integer, CultureInfo.InvariantCulture); |
||
336 | #endif |
||
337 | if(rank < MinExpectedRank) |
||
338 | continue; |
||
339 | } |
||
340 | |||
341 | nn = n.Attributes["lat"]; |
||
342 | if(nn != null) |
||
343 | { |
||
344 | double lat = double.Parse(nn.Value, CultureInfo.InvariantCulture); |
||
345 | |||
346 | nn = n.Attributes["lon"]; |
||
347 | if(nn != null) |
||
348 | { |
||
349 | double lng = double.Parse(nn.Value, CultureInfo.InvariantCulture); |
||
350 | pointList.Add(new PointLatLng(lat, lng)); |
||
351 | } |
||
352 | } |
||
353 | } |
||
354 | |||
355 | status = GeoCoderStatusCode.G_GEO_SUCCESS; |
||
356 | } |
||
357 | } |
||
358 | } |
||
359 | } |
||
360 | } |
||
361 | catch(Exception ex) |
||
362 | { |
||
363 | status = GeoCoderStatusCode.ExceptionInCode; |
||
364 | Debug.WriteLine("GetLatLngFromGeocoderUrl: " + ex); |
||
365 | } |
||
366 | |||
367 | return status; |
||
368 | } |
||
369 | |||
370 | Placemark? GetPlacemarkFromReverseGeocoderUrl(string url, out GeoCoderStatusCode status) |
||
371 | { |
||
372 | status = GeoCoderStatusCode.Unknow; |
||
373 | Placemark? ret = null; |
||
374 | |||
375 | try |
||
376 | { |
||
377 | string geo = GMaps.Instance.UsePlacemarkCache ? Cache.Instance.GetContent(url, CacheType.PlacemarkCache) : string.Empty; |
||
378 | |||
379 | bool cache = false; |
||
380 | |||
381 | if(string.IsNullOrEmpty(geo)) |
||
382 | { |
||
383 | geo = GetContentUsingHttp(url); |
||
384 | |||
385 | if(!string.IsNullOrEmpty(geo)) |
||
386 | { |
||
387 | cache = true; |
||
388 | } |
||
389 | } |
||
390 | |||
391 | if(!string.IsNullOrEmpty(geo)) |
||
392 | { |
||
393 | if(geo.StartsWith("<?xml") && geo.Contains("<result")) |
||
394 | { |
||
395 | if(cache && GMaps.Instance.UsePlacemarkCache) |
||
396 | { |
||
397 | Cache.Instance.SaveContent(url, CacheType.PlacemarkCache, geo); |
||
398 | } |
||
399 | |||
400 | XmlDocument doc = new XmlDocument(); |
||
401 | doc.LoadXml(geo); |
||
402 | { |
||
403 | XmlNode r = doc.SelectSingleNode("/reversegeocode/result"); |
||
404 | if(r != null) |
||
405 | { |
||
406 | var p = new Placemark(r.InnerText); |
||
407 | |||
408 | XmlNode ad = doc.SelectSingleNode("/reversegeocode/addressparts"); |
||
409 | if(ad != null) |
||
410 | { |
||
411 | var vl = ad.SelectSingleNode("country"); |
||
412 | if(vl != null) |
||
413 | { |
||
414 | p.CountryName = vl.InnerText; |
||
415 | } |
||
416 | |||
417 | vl = ad.SelectSingleNode("country_code"); |
||
418 | if(vl != null) |
||
419 | { |
||
420 | p.CountryNameCode = vl.InnerText; |
||
421 | } |
||
422 | |||
423 | vl = ad.SelectSingleNode("postcode"); |
||
424 | if(vl != null) |
||
425 | { |
||
426 | p.PostalCodeNumber = vl.InnerText; |
||
427 | } |
||
428 | |||
429 | vl = ad.SelectSingleNode("state"); |
||
430 | if(vl != null) |
||
431 | { |
||
432 | p.AdministrativeAreaName = vl.InnerText; |
||
433 | } |
||
434 | |||
435 | vl = ad.SelectSingleNode("region"); |
||
436 | if(vl != null) |
||
437 | { |
||
438 | p.SubAdministrativeAreaName = vl.InnerText; |
||
439 | } |
||
440 | |||
441 | vl = ad.SelectSingleNode("suburb"); |
||
442 | if(vl != null) |
||
443 | { |
||
444 | p.LocalityName = vl.InnerText; |
||
445 | } |
||
446 | |||
447 | vl = ad.SelectSingleNode("road"); |
||
448 | if(vl != null) |
||
449 | { |
||
450 | p.ThoroughfareName = vl.InnerText; |
||
451 | } |
||
452 | } |
||
453 | |||
454 | ret = p; |
||
455 | |||
456 | status = GeoCoderStatusCode.G_GEO_SUCCESS; |
||
457 | } |
||
458 | } |
||
459 | } |
||
460 | } |
||
461 | } |
||
462 | catch(Exception ex) |
||
463 | { |
||
464 | ret = null; |
||
465 | status = GeoCoderStatusCode.ExceptionInCode; |
||
466 | Debug.WriteLine("GetPlacemarkFromReverseGeocoderUrl: " + ex); |
||
467 | } |
||
468 | |||
469 | return ret; |
||
470 | } |
||
471 | |||
472 | static readonly string ReverseGeocoderUrlFormat = "http://nominatim.openstreetmap.org/reverse?format=xml&lat={0}&lon={1}&zoom=18&addressdetails=1"; |
||
473 | static readonly string GeocoderUrlFormat = "http://nominatim.openstreetmap.org/search?q={0}&format=xml"; |
||
474 | static readonly string GeocoderDetailedUrlFormat = "http://nominatim.openstreetmap.org/search?street={0}&city={1}&county={2}&state={3}&country={4}&postalcode={5}&format=xml"; |
||
475 | |||
476 | #endregion |
||
477 | |||
478 | #endregion |
||
479 | } |
||
480 | |||
481 | /// <summary> |
||
482 | /// OpenStreetMap provider - http://www.openstreetmap.org/ |
||
483 | /// </summary> |
||
484 | public class OpenStreetMapProvider : OpenStreetMapProviderBase |
||
485 | { |
||
486 | public static readonly OpenStreetMapProvider Instance; |
||
487 | |||
488 | OpenStreetMapProvider() |
||
489 | { |
||
490 | } |
||
491 | |||
492 | static OpenStreetMapProvider() |
||
493 | { |
||
494 | Instance = new OpenStreetMapProvider(); |
||
495 | } |
||
496 | |||
497 | #region GMapProvider Members |
||
498 | |||
499 | readonly Guid id = new Guid("0521335C-92EC-47A8-98A5-6FD333DDA9C0"); |
||
500 | public override Guid Id |
||
501 | { |
||
502 | get |
||
503 | { |
||
504 | return id; |
||
505 | } |
||
506 | } |
||
507 | |||
508 | readonly string name = "OpenStreetMap"; |
||
509 | public override string Name |
||
510 | { |
||
511 | get |
||
512 | { |
||
513 | return name; |
||
514 | } |
||
515 | } |
||
516 | |||
517 | GMapProvider[] overlays; |
||
518 | public override GMapProvider[] Overlays |
||
519 | { |
||
520 | get |
||
521 | { |
||
522 | if(overlays == null) |
||
523 | { |
||
524 | overlays = new GMapProvider[] { this }; |
||
525 | } |
||
526 | return overlays; |
||
527 | } |
||
528 | } |
||
529 | |||
530 | public override PureImage GetTileImage(GPoint pos, int zoom) |
||
531 | { |
||
532 | string url = MakeTileImageUrl(pos, zoom, string.Empty); |
||
533 | |||
534 | return GetTileImageUsingHttp(url); |
||
535 | } |
||
536 | |||
537 | #endregion |
||
538 | |||
539 | string MakeTileImageUrl(GPoint pos, int zoom, string language) |
||
540 | { |
||
541 | char letter = ServerLetters[GetServerNum(pos, 3)]; |
||
542 | return string.Format(UrlFormat, letter, zoom, pos.X, pos.Y); |
||
543 | } |
||
544 | |||
545 | static readonly string UrlFormat = "http://{0}.tile.openstreetmap.org/{1}/{2}/{3}.png"; |
||
546 | } |
||
547 | } |