Subversion Repositories Projects

Rev

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 GMap.NET.Projections;
6
   using System.Globalization;
7
   using GMap.NET.Internals;
8
   using System.Collections.Generic;
9
   using System.Xml;
10
   using System.Diagnostics;
11
 
12
   public abstract class CloudMadeMapProviderBase : GMapProvider, RoutingProvider, DirectionsProvider
13
   {
14
      public readonly string ServerLetters = "abc";
15
      public readonly string DoubleResolutionString = "@2x";
16
 
17
      public bool DoubleResolution = true;
18
      public string Key;
19
      public int StyleID;
20
 
21
      public string Version = "0.3";
22
 
23
      public CloudMadeMapProviderBase()
24
      {
25
         MaxZoom = null;
26
      }
27
 
28
      #region GMapProvider Members
29
      public override Guid Id
30
      {
31
         get
32
         {
33
            throw new NotImplementedException();
34
         }
35
      }
36
 
37
      public override string Name
38
      {
39
         get
40
         {
41
            throw new NotImplementedException();
42
         }
43
      }
44
 
45
      public override PureProjection Projection
46
      {
47
         get
48
         {
49
            return MercatorProjection.Instance;
50
         }
51
      }
52
 
53
      GMapProvider[] overlays;
54
      public override GMapProvider[] Overlays
55
      {
56
         get
57
         {
58
            if(overlays == null)
59
            {
60
               overlays = new GMapProvider[] { this };
61
            }
62
            return overlays;
63
         }
64
      }
65
 
66
      public override PureImage GetTileImage(GPoint pos, int zoom)
67
      {
68
         throw new NotImplementedException();
69
      }
70
      #endregion
71
 
72
      #region RoutingProvider Members
73
 
74
      public MapRoute GetRoute(PointLatLng start, PointLatLng end, bool avoidHighways, bool walkingMode, int Zoom)
75
      {
76
         List<PointLatLng> points = GetRoutePoints(MakeRoutingUrl(start, end, walkingMode ? TravelTypeFoot : TravelTypeMotorCar, LanguageStr, "km"));
77
         MapRoute route = points != null ? new MapRoute(points, walkingMode ? WalkingStr : DrivingStr) : null;
78
         return route;
79
      }
80
 
81
      /// <summary>
82
      /// NotImplemented
83
      /// </summary>
84
      /// <param name="start"></param>
85
      /// <param name="end"></param>
86
      /// <param name="avoidHighways"></param>
87
      /// <param name="walkingMode"></param>
88
      /// <param name="Zoom"></param>
89
      /// <returns></returns>
90
      public MapRoute GetRoute(string start, string end, bool avoidHighways, bool walkingMode, int Zoom)
91
      {
92
         throw new NotImplementedException();
93
      }
94
 
95
      #region -- internals --
96
 
97
      string MakeRoutingUrl(PointLatLng start, PointLatLng end, string travelType, string language, string units)
98
      {
99
         // http://developers.cloudmade.com/projects/routing-http-api/examples/
100
         // http://routes.cloudmade.com/YOUR-API-KEY-GOES-HERE/api/0.3/start_point,[[transit_point1,...,transit_pointN]],end_point/route_type[/route_type_modifier].output_format[?lang=(en|de)][&units=(km|miles)]
101
         return string.Format(CultureInfo.InvariantCulture, UrlFormat, Key, Version, start.Lat, start.Lng, end.Lat, end.Lng, travelType, language, units);
102
      }
103
 
104
      List<PointLatLng> GetRoutePoints(string url)
105
      {
106
         List<PointLatLng> points = null;
107
         try
108
         {
109
            string route = GMaps.Instance.UseRouteCache ? Cache.Instance.GetContent(url, CacheType.RouteCache) : string.Empty;
110
            if(string.IsNullOrEmpty(route))
111
            {
112
               route = GetContentUsingHttp(url);
113
               if(!string.IsNullOrEmpty(route))
114
               {
115
                  if(GMaps.Instance.UseRouteCache)
116
                  {
117
                     Cache.Instance.SaveContent(url, CacheType.RouteCache, route);
118
                  }
119
               }
120
            }
121
 
122
            #region -- gpx response --
123
            //<?xml version="1.0" encoding="UTF-8"?>
124
            //<gpx creator="" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"
125
            //    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
126
            //    xsi:schemaLocation="http://www.topografix.com/GPX/1/1 gpx.xsd ">
127
            //    <extensions>
128
            //        <distance>293</distance>
129
            //        <time>34</time>
130
            //        <start>Perckhoevelaan</start>
131
            //        <end>Goudenregenlaan</end>
132
            //    </extensions>
133
            //    <wpt lat="51.17702" lon="4.39630" />
134
            //    <wpt lat="51.17656" lon="4.39655" />
135
            //    <wpt lat="51.17639" lon="4.39670" />
136
            //    <wpt lat="51.17612" lon="4.39696" />
137
            //    <wpt lat="51.17640" lon="4.39767" />
138
            //    <wpt lat="51.17668" lon="4.39828" />
139
            //    <wpt lat="51.17628" lon="4.39874" />
140
            //    <wpt lat="51.17618" lon="4.39888" />
141
            //    <rte>
142
            //        <rtept lat="51.17702" lon="4.39630">
143
            //            <desc>Head south on Perckhoevelaan, 0.1 km</desc>
144
            //            <extensions>
145
            //                <distance>111</distance>
146
            //                <time>13</time>
147
            //                <offset>0</offset>
148
            //                <distance-text>0.1 km</distance-text>
149
            //                <direction>S</direction>
150
            //                <azimuth>160.6</azimuth>
151
            //            </extensions>
152
            //        </rtept>
153
            //        <rtept lat="51.17612" lon="4.39696">
154
            //            <desc>Turn left at Laarstraat, 0.1 km</desc>
155
            //            <extensions>
156
            //                <distance>112</distance>
157
            //                <time>13</time>
158
            //                <offset>3</offset>
159
            //                <distance-text>0.1 km</distance-text>
160
            //                <direction>NE</direction>
161
            //                <azimuth>58.1</azimuth>
162
            //                <turn>TL</turn>
163
            //                <turn-angle>269.0</turn-angle>
164
            //            </extensions>
165
            //        </rtept>
166
            //        <rtept lat="51.17668" lon="4.39828">
167
            //            <desc>Turn right at Goudenregenlaan, 70 m</desc>
168
            //            <extensions>
169
            //                <distance>70</distance>
170
            //                <time>8</time>
171
            //                <offset>5</offset>
172
            //                <distance-text>70 m</distance-text>
173
            //                <direction>SE</direction>
174
            //                <azimuth>143.4</azimuth>
175
            //                <turn>TR</turn>
176
            //                <turn-angle>89.8</turn-angle>
177
            //            </extensions>
178
            //        </rtept>
179
            //    </rte>
180
            //</gpx> 
181
            #endregion
182
 
183
            if(!string.IsNullOrEmpty(route))
184
            {
185
               XmlDocument xmldoc = new XmlDocument();
186
               xmldoc.LoadXml(route);
187
               System.Xml.XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(xmldoc.NameTable);
188
               xmlnsManager.AddNamespace("sm", "http://www.topografix.com/GPX/1/1");
189
 
190
               XmlNodeList wpts = xmldoc.SelectNodes("/sm:gpx/sm:wpt", xmlnsManager);
191
               if(wpts != null && wpts.Count > 0)
192
               {
193
                  points = new List<PointLatLng>();
194
                  foreach(XmlNode w in wpts)
195
                  {
196
                     double lat = double.Parse(w.Attributes["lat"].InnerText, CultureInfo.InvariantCulture);
197
                     double lng = double.Parse(w.Attributes["lon"].InnerText, CultureInfo.InvariantCulture);
198
                     points.Add(new PointLatLng(lat, lng));
199
                  }
200
               }
201
            }
202
         }
203
         catch(Exception ex)
204
         {
205
            Debug.WriteLine("GetRoutePoints: " + ex);
206
         }
207
 
208
         return points;
209
      }
210
 
211
      static readonly string UrlFormat = "http://routes.cloudmade.com/{0}/api/{1}/{2},{3},{4},{5}/{6}.gpx?lang={7}&units={8}";
212
      static readonly string TravelTypeFoot = "foot";
213
      static readonly string TravelTypeMotorCar = "car";
214
      static readonly string WalkingStr = "Walking";
215
      static readonly string DrivingStr = "Driving";
216
 
217
      #endregion
218
 
219
      #endregion
220
 
221
      #region DirectionsProvider Members
222
 
223
      public DirectionsStatusCode GetDirections(out GDirections direction, PointLatLng start, PointLatLng end, bool avoidHighways, bool avoidTolls, bool walkingMode, bool sensor, bool metric)
224
      {
225
         return GetDirectionsUrl(MakeRoutingUrl(start, end, walkingMode ? TravelTypeFoot : TravelTypeMotorCar, LanguageStr, metric ? "km" : "miles"), out direction);
226
      }
227
 
228
      /// <summary>
229
      /// NotImplemented
230
      /// </summary>
231
      /// <param name="direction"></param>
232
      /// <param name="start"></param>
233
      /// <param name="end"></param>
234
      /// <param name="avoidHighways"></param>
235
      /// <param name="avoidTolls"></param>
236
      /// <param name="walkingMode"></param>
237
      /// <param name="sensor"></param>
238
      /// <param name="metric"></param>
239
      /// <returns></returns>
240
      public DirectionsStatusCode GetDirections(out GDirections direction, string start, string end, bool avoidHighways, bool avoidTolls, bool walkingMode, bool sensor, bool metric)
241
      {
242
         throw new NotImplementedException();
243
      }
244
 
245
      /// <summary>
246
      /// NotImplemented
247
      /// </summary>
248
      /// <param name="status"></param>
249
      /// <param name="start"></param>
250
      /// <param name="end"></param>
251
      /// <param name="avoidHighways"></param>
252
      /// <param name="avoidTolls"></param>
253
      /// <param name="walkingMode"></param>
254
      /// <param name="sensor"></param>
255
      /// <param name="metric"></param>
256
      /// <returns></returns>
257
      public IEnumerable<GDirections> GetDirections(out DirectionsStatusCode status, string start, string end, bool avoidHighways, bool avoidTolls, bool walkingMode, bool sensor, bool metric)
258
      {
259
         throw new NotImplementedException();
260
      }
261
 
262
      /// <summary>
263
      /// NotImplemented
264
      /// </summary>
265
      /// <param name="status"></param>
266
      /// <param name="start"></param>
267
      /// <param name="end"></param>
268
      /// <param name="avoidHighways"></param>
269
      /// <param name="avoidTolls"></param>
270
      /// <param name="walkingMode"></param>
271
      /// <param name="sensor"></param>
272
      /// <param name="metric"></param>
273
      /// <returns></returns>
274
      public IEnumerable<GDirections> GetDirections(out DirectionsStatusCode status, PointLatLng start, PointLatLng end, bool avoidHighways, bool avoidTolls, bool walkingMode, bool sensor, bool metric)
275
      {
276
         throw new NotImplementedException();
277
      }
278
 
279
      /// <summary>
280
      /// NotImplemented
281
      /// </summary>
282
      /// <param name="direction"></param>
283
      /// <param name="start"></param>
284
      /// <param name="wayPoints"></param>
285
      /// <param name="avoidHighways"></param>
286
      /// <param name="avoidTolls"></param>
287
      /// <param name="walkingMode"></param>
288
      /// <param name="sensor"></param>
289
      /// <param name="metric"></param>
290
      /// <returns></returns>
291
      public DirectionsStatusCode GetDirections(out GDirections direction, PointLatLng start, IEnumerable<PointLatLng> wayPoints, PointLatLng end, bool avoidHighways, bool avoidTolls, bool walkingMode, bool sensor, bool metric)
292
      {
293
          throw new NotImplementedException();
294
      }
295
 
296
      /// <summary>
297
      /// NotImplemented
298
      /// </summary>
299
      /// <param name="direction"></param>
300
      /// <param name="start"></param>
301
      /// <param name="wayPoints"></param>
302
      /// <param name="avoidHighways"></param>
303
      /// <param name="avoidTolls"></param>
304
      /// <param name="walkingMode"></param>
305
      /// <param name="sensor"></param>
306
      /// <param name="metric"></param>
307
      /// <returns></returns>
308
      public DirectionsStatusCode GetDirections(out GDirections direction, string start, IEnumerable<string> wayPoints, string end, bool avoidHighways, bool avoidTolls, bool walkingMode, bool sensor, bool metric)
309
      {
310
          throw new NotImplementedException();
311
      }
312
 
313
      #region -- internals --
314
 
315
      DirectionsStatusCode GetDirectionsUrl(string url, out GDirections direction)
316
      {
317
         DirectionsStatusCode ret = DirectionsStatusCode.UNKNOWN_ERROR;
318
         direction = null;
319
 
320
         try
321
         {
322
            string route = GMaps.Instance.UseRouteCache ? Cache.Instance.GetContent(url, CacheType.DirectionsCache) : string.Empty;
323
            if(string.IsNullOrEmpty(route))
324
            {
325
               route = GetContentUsingHttp(url);
326
               if(!string.IsNullOrEmpty(route))
327
               {
328
                  if(GMaps.Instance.UseRouteCache)
329
                  {
330
                     Cache.Instance.SaveContent(url, CacheType.DirectionsCache, route);
331
                  }
332
               }
333
            }
334
 
335
            #region -- gpx response --
336
            //<?xml version="1.0" encoding="UTF-8"?>
337
            //<gpx creator="" version="1.1" xmlns="http://www.topografix.com/GPX/1/1"
338
            //    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
339
            //    xsi:schemaLocation="http://www.topografix.com/GPX/1/1 gpx.xsd ">
340
            //    <extensions>
341
            //        <distance>293</distance>
342
            //        <time>34</time>
343
            //        <start>Perckhoevelaan</start>
344
            //        <end>Goudenregenlaan</end>
345
            //    </extensions>
346
            //    <wpt lat="51.17702" lon="4.39630" />
347
            //    <wpt lat="51.17656" lon="4.39655" />
348
            //    <wpt lat="51.17639" lon="4.39670" />
349
            //    <wpt lat="51.17612" lon="4.39696" />
350
            //    <wpt lat="51.17640" lon="4.39767" />
351
            //    <wpt lat="51.17668" lon="4.39828" />
352
            //    <wpt lat="51.17628" lon="4.39874" />
353
            //    <wpt lat="51.17618" lon="4.39888" />
354
            //    <rte>
355
            //        <rtept lat="51.17702" lon="4.39630">
356
            //            <desc>Head south on Perckhoevelaan, 0.1 km</desc>
357
            //            <extensions>
358
            //                <distance>111</distance>
359
            //                <time>13</time>
360
            //                <offset>0</offset>
361
            //                <distance-text>0.1 km</distance-text>
362
            //                <direction>S</direction>
363
            //                <azimuth>160.6</azimuth>
364
            //            </extensions>
365
            //        </rtept>
366
            //        <rtept lat="51.17612" lon="4.39696">
367
            //            <desc>Turn left at Laarstraat, 0.1 km</desc>
368
            //            <extensions>
369
            //                <distance>112</distance>
370
            //                <time>13</time>
371
            //                <offset>3</offset>
372
            //                <distance-text>0.1 km</distance-text>
373
            //                <direction>NE</direction>
374
            //                <azimuth>58.1</azimuth>
375
            //                <turn>TL</turn>
376
            //                <turn-angle>269.0</turn-angle>
377
            //            </extensions>
378
            //        </rtept>
379
            //        <rtept lat="51.17668" lon="4.39828">
380
            //            <desc>Turn right at Goudenregenlaan, 70 m</desc>
381
            //            <extensions>
382
            //                <distance>70</distance>
383
            //                <time>8</time>
384
            //                <offset>5</offset>
385
            //                <distance-text>70 m</distance-text>
386
            //                <direction>SE</direction>
387
            //                <azimuth>143.4</azimuth>
388
            //                <turn>TR</turn>
389
            //                <turn-angle>89.8</turn-angle>
390
            //            </extensions>
391
            //        </rtept>
392
            //    </rte>
393
            //</gpx> 
394
            #endregion
395
 
396
            if(!string.IsNullOrEmpty(route))
397
            {
398
               XmlDocument xmldoc = new XmlDocument();
399
               xmldoc.LoadXml(route);
400
               System.Xml.XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(xmldoc.NameTable);
401
               xmlnsManager.AddNamespace("sm", "http://www.topografix.com/GPX/1/1");
402
 
403
               XmlNodeList wpts = xmldoc.SelectNodes("/sm:gpx/sm:wpt", xmlnsManager);
404
               if(wpts != null && wpts.Count > 0)
405
               {
406
                  ret = DirectionsStatusCode.OK;
407
 
408
                  direction = new GDirections();
409
                  direction.Route = new List<PointLatLng>();
410
 
411
                  foreach(XmlNode w in wpts)
412
                  {
413
                     double lat = double.Parse(w.Attributes["lat"].InnerText, CultureInfo.InvariantCulture);
414
                     double lng = double.Parse(w.Attributes["lon"].InnerText, CultureInfo.InvariantCulture);
415
                     direction.Route.Add(new PointLatLng(lat, lng));
416
                  }
417
 
418
                  if(direction.Route.Count > 0)
419
                  {
420
                     direction.StartLocation = direction.Route[0];
421
                     direction.EndLocation = direction.Route[direction.Route.Count - 1];
422
                  }
423
 
424
                  XmlNode n = xmldoc.SelectSingleNode("/sm:gpx/sm:metadata/sm:copyright/sm:license", xmlnsManager);
425
                  if(n != null)
426
                  {
427
                     direction.Copyrights = n.InnerText;
428
                  }
429
 
430
                  n = xmldoc.SelectSingleNode("/sm:gpx/sm:extensions/sm:distance", xmlnsManager);
431
                  if(n != null)
432
                  {
433
                     direction.Distance = n.InnerText + "m";
434
                  }
435
 
436
                  n = xmldoc.SelectSingleNode("/sm:gpx/sm:extensions/sm:time", xmlnsManager);
437
                  if(n != null)
438
                  {
439
                     direction.Duration = n.InnerText + "s";
440
                  }
441
 
442
                  n = xmldoc.SelectSingleNode("/sm:gpx/sm:extensions/sm:start", xmlnsManager);
443
                  if(n != null)
444
                  {
445
                     direction.StartAddress = n.InnerText;
446
                  }
447
 
448
                  n = xmldoc.SelectSingleNode("/sm:gpx/sm:extensions/sm:end", xmlnsManager);
449
                  if(n != null)
450
                  {
451
                     direction.EndAddress = n.InnerText;
452
                  }
453
 
454
                  wpts = xmldoc.SelectNodes("/sm:gpx/sm:rte/sm:rtept", xmlnsManager);
455
                  if(wpts != null && wpts.Count > 0)
456
                  {
457
                     direction.Steps = new List<GDirectionStep>();
458
 
459
                     foreach(XmlNode w in wpts)
460
                     {
461
                        GDirectionStep step = new GDirectionStep();
462
 
463
                        double lat = double.Parse(w.Attributes["lat"].InnerText, CultureInfo.InvariantCulture);
464
                        double lng = double.Parse(w.Attributes["lon"].InnerText, CultureInfo.InvariantCulture);
465
 
466
                        step.StartLocation = new PointLatLng(lat, lng);
467
 
468
                        XmlNode nn = w.SelectSingleNode("sm:desc", xmlnsManager);
469
                        if(nn != null)
470
                        {
471
                           step.HtmlInstructions = nn.InnerText;
472
                        }
473
 
474
                        nn = w.SelectSingleNode("sm:extensions/sm:distance-text", xmlnsManager);
475
                        if(nn != null)
476
                        {
477
                           step.Distance = nn.InnerText;
478
                        }
479
 
480
                        nn = w.SelectSingleNode("sm:extensions/sm:time", xmlnsManager);
481
                        if(nn != null)
482
                        {
483
                           step.Duration = nn.InnerText + "s";
484
                        }
485
 
486
                        direction.Steps.Add(step);
487
                     }
488
                  }
489
               }
490
            }
491
         }
492
         catch(Exception ex)
493
         {
494
            ret = DirectionsStatusCode.ExceptionInCode;
495
            direction = null;
496
            Debug.WriteLine("GetDirectionsUrl: " + ex);
497
         }
498
 
499
         return ret;
500
      }
501
 
502
      #endregion
503
 
504
      #endregion      
505
   }
506
 
507
   /// <summary>
508
   /// CloudMadeMap demo provider, http://maps.cloudmade.com/
509
   /// </summary>
510
   public class CloudMadeMapProvider : CloudMadeMapProviderBase
511
   {
512
      public static readonly CloudMadeMapProvider Instance;
513
 
514
      CloudMadeMapProvider()
515
      {
516
         Key = "5937c2bd907f4f4a92d8980a7c666ac0"; // demo key of CloudMade
517
         StyleID = 45363; // grab your style here http://maps.cloudmade.com/?styleId=45363
518
      }
519
 
520
      static CloudMadeMapProvider()
521
      {
522
         Instance = new CloudMadeMapProvider();
523
      }
524
 
525
      #region GMapProvider Members
526
 
527
      readonly Guid id = new Guid("00403A36-725F-4BC4-934F-BFC1C164D003");
528
      public override Guid Id
529
      {
530
         get
531
         {
532
            return id;
533
         }
534
      }
535
 
536
      readonly string name = "CloudMade, Demo";
537
      public override string Name
538
      {
539
         get
540
         {
541
            return name;
542
         }
543
      }
544
 
545
      public override PureImage GetTileImage(GPoint pos, int zoom)
546
      {
547
         string url = MakeTileImageUrl(pos, zoom, LanguageStr);
548
 
549
         return GetTileImageUsingHttp(url);
550
      }
551
 
552
      #endregion
553
 
554
      string MakeTileImageUrl(GPoint pos, int zoom, string language)
555
      {
556
         return string.Format(UrlFormat, ServerLetters[GetServerNum(pos, 3)], Key, StyleID, (DoubleResolution ? DoubleResolutionString : string.Empty), zoom, pos.X, pos.Y);
557
      }
558
 
559
      static readonly string UrlFormat = "http://{0}.tile.cloudmade.com/{1}/{2}{3}/256/{4}/{5}/{6}.png";
560
   }
561
}