Subversion Repositories Projects

Rev

Go to most recent revision | 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 YahooMapProviderBase : GMapProvider, GeocodingProvider
13
   {
14
      public YahooMapProviderBase()
15
      {
16
         RefererUrl = "http://maps.yahoo.com/";
17
         Copyright = string.Format("© Yahoo! Inc. - Map data & Imagery ©{0} NAVTEQ", DateTime.Today.Year);
18
      }
19
 
20
      public string AppId = string.Empty;
21
      public int MinExpectedQuality = 39;
22
 
23
      #region GMapProvider Members
24
      public override Guid Id
25
      {
26
         get
27
         {
28
            throw new NotImplementedException();
29
         }
30
      }
31
 
32
      public override string Name
33
      {
34
         get
35
         {
36
            throw new NotImplementedException();
37
         }
38
      }
39
 
40
      public override PureProjection Projection
41
      {
42
         get
43
         {
44
            return MercatorProjection.Instance;
45
         }
46
      }
47
 
48
      GMapProvider[] overlays;
49
      public override GMapProvider[] Overlays
50
      {
51
         get
52
         {
53
            if(overlays == null)
54
            {
55
               overlays = new GMapProvider[] { this };
56
            }
57
            return overlays;
58
         }
59
      }
60
 
61
      public override PureImage GetTileImage(GPoint pos, int zoom)
62
      {
63
         throw new NotImplementedException();
64
      }
65
      #endregion
66
 
67
      #region GeocodingProvider Members
68
 
69
      public GeoCoderStatusCode GetPoints(string keywords, out List<PointLatLng> pointList)
70
      {
71
          // http://where.yahooapis.com/geocode?q=lithuania,vilnius&appid=1234&flags=CG&gflags=QL&locale=LT-lt
72
 
73
          #region -- response --
74
          //<ResultSet version="1.0"><Error>0</Error><ErrorMessage>No error</ErrorMessage><Locale>LT-lt</Locale><Quality>40</Quality><Found>1</Found><Result><quality>40</quality><latitude>54.689850</latitude><longitude>25.269260</longitude><offsetlat>54.689850</offsetlat><offsetlon>25.269260</offsetlon><radius>46100</radius></Result></ResultSet>
75
          #endregion
76
 
77
          return GetLatLngFromGeocoderUrl(MakeGeocoderUrl(keywords), out pointList);
78
      }
79
 
80
      public PointLatLng? GetPoint(string keywords, out GeoCoderStatusCode status)
81
      {
82
          List<PointLatLng> pointList;
83
          status = GetPoints(keywords, out pointList);
84
          return pointList != null && pointList.Count > 0 ? pointList[0] : (PointLatLng?)null;
85
      }
86
 
87
      public GeoCoderStatusCode GetPoints(Placemark placemark, out List<PointLatLng> pointList)
88
      {
89
          // http://where.yahooapis.com/geocode?country=LT&state=Vilniaus+Apskritis&county=Vilniaus+Miesto+Savivaldybe&city=Vilnius&neighborhood=Naujamiestis&postal=01108&street=J.+Tumo-Vaizganto+Gatve&house=2&appid=1234&flags=CG&gflags=QL&locale=LT-lt
90
 
91
          #region -- response --
92
          //<ResultSet version="1.0"><Error>0</Error><ErrorMessage>No error</ErrorMessage><Locale>LT-lt</Locale><Quality>19</Quality><Found>1</Found><Result><quality>87</quality><latitude>54.690181</latitude><longitude>25.269483</longitude><offsetlat>54.690227</offsetlat><offsetlon>25.269278</offsetlon><radius>500</radius></Result></ResultSet>
93
          #endregion
94
 
95
          return GetLatLngFromGeocoderUrl(MakeGeocoderDetailedUrl(placemark), out pointList);
96
      }
97
 
98
      public PointLatLng? GetPoint(Placemark placemark, out GeoCoderStatusCode status)
99
      {
100
          List<PointLatLng> pointList;
101
          status = GetPoints(placemark, out pointList);
102
          return pointList != null && pointList.Count > 0 ? pointList[0] : (PointLatLng?)null;
103
      }
104
 
105
      public GeoCoderStatusCode GetPlacemarks(PointLatLng location, out List<Placemark> placemarkList)
106
      {
107
          // http://where.yahooapis.com/geocode?q=54.689850,25.269260&appid=1234&flags=G&gflags=QRL&locale=LT-lt
108
 
109
          #region -- response --
110
          //<ResultSet version="1.0"><Error>0</Error><ErrorMessage>No error</ErrorMessage><Locale>LT-lt</Locale><Quality>99</Quality><Found>1</Found><Result><quality>99</quality><latitude>54.689850</latitude><longitude>25.269260</longitude><offsetlat>54.689850</offsetlat><offsetlon>25.269260</offsetlon><radius>500</radius><name>54.689850,25.269260</name><line1>2 J. Tumo-Vaizganto Gatve</line1><line2>01108 Naujamiestis</line2><line3/><line4>Lietuvos Respublika</line4><house>2</house><street>J. Tumo-Vaizganto Gatve</street><xstreet/><unittype/><unit/><postal>01108</postal><level4>Naujamiestis</level4><level3>Vilnius</level3><level2>Vilniaus Miesto Savivaldybe</level2><level1>Vilniaus Apskritis</level1><level0>Lietuvos Respublika</level0><level0code>LT</level0code><level1code/><level2code/><hash/><woeid>12758362</woeid><woetype>11</woetype><uzip>01108</uzip></Result></ResultSet>
111
          #endregion
112
 
113
          return GetPlacemarksFromReverseGeocoderUrl(MakeReverseGeocoderUrl(location), out placemarkList);
114
      }
115
 
116
      public Placemark ? GetPlacemark(PointLatLng location, out GeoCoderStatusCode status)
117
      {
118
          List<Placemark> placemarkList;
119
          status = GetPlacemarks(location, out placemarkList);
120
          return placemarkList != null && placemarkList.Count > 0 ? placemarkList[0] : (Placemark?)null;
121
      }
122
 
123
      #region -- internals --
124
 
125
      string MakeGeocoderUrl(string keywords)
126
      {
127
         return string.Format(CultureInfo.InvariantCulture, GeocoderUrlFormat, keywords.Replace(' ', '+'), AppId, !string.IsNullOrEmpty(LanguageStr) ? "&locale=" + LanguageStr : "");
128
      }
129
 
130
      string MakeGeocoderDetailedUrl(Placemark placemark)
131
      {
132
          return string.Format(GeocoderDetailedUrlFormat,
133
                               PrepareUrlString(placemark.CountryName),
134
                               PrepareUrlString(placemark.AdministrativeAreaName),
135
                               PrepareUrlString(placemark.SubAdministrativeAreaName),
136
                               PrepareUrlString(placemark.LocalityName),
137
                               PrepareUrlString(placemark.DistrictName),
138
                               PrepareUrlString(placemark.PostalCodeNumber),
139
                               PrepareUrlString(placemark.ThoroughfareName),
140
                               PrepareUrlString(placemark.HouseNo),
141
                               AppId,
142
                               !string.IsNullOrEmpty(LanguageStr) ? "&locale=" + LanguageStr : string.Empty);
143
      }
144
 
145
      string MakeReverseGeocoderUrl(PointLatLng pt)
146
      {
147
         return string.Format(CultureInfo.InvariantCulture, ReverseGeocoderUrlFormat, pt.Lat, pt.Lng, AppId, !string.IsNullOrEmpty(LanguageStr) ? "&locale=" + LanguageStr : "");
148
      }
149
 
150
      string PrepareUrlString(string str)
151
      {
152
          if (str == null) return string.Empty;
153
          return str.Replace(' ', '+');
154
      }
155
 
156
      GeoCoderStatusCode GetLatLngFromGeocoderUrl(string url, out List<PointLatLng> pointList)
157
      {
158
          var status = GeoCoderStatusCode.Unknow;
159
          pointList = null;
160
 
161
          try
162
          {
163
              string geo = GMaps.Instance.UseGeocoderCache ? Cache.Instance.GetContent(url, CacheType.GeocoderCache) : string.Empty;
164
 
165
              bool cache = false;
166
 
167
              if (string.IsNullOrEmpty(geo))
168
              {
169
                  geo = GetContentUsingHttp(url);
170
 
171
                  if (!string.IsNullOrEmpty(geo))
172
                  {
173
                      cache = true;
174
                  }
175
              }
176
 
177
              if (!string.IsNullOrEmpty(geo))
178
              {
179
                  if (geo.StartsWith("<?xml") && geo.Contains("<Result"))
180
                  {
181
                      if (cache && GMaps.Instance.UseGeocoderCache)
182
                      {
183
                          Cache.Instance.SaveContent(url, CacheType.GeocoderCache, geo);
184
                      }
185
 
186
                      XmlDocument doc = new XmlDocument();
187
                      doc.LoadXml(geo);
188
                      {
189
                          XmlNodeList l = doc.SelectNodes("/ResultSet/Result");
190
                          if (l != null)
191
                          {
192
                              pointList = new List<PointLatLng>();
193
 
194
                              foreach (XmlNode n in l)
195
                              {
196
                                  var nn = n.SelectSingleNode("quality");
197
                                  if (nn != null)
198
                                  {
199
                                      var quality = int.Parse(nn.InnerText);
200
                                      if (quality < MinExpectedQuality) continue;
201
 
202
                                      nn = n.SelectSingleNode("latitude");
203
                                      if (nn != null)
204
                                      {
205
                                          double lat = double.Parse(nn.InnerText, CultureInfo.InvariantCulture);
206
 
207
                                          nn = n.SelectSingleNode("longitude");
208
                                          if (nn != null)
209
                                          {
210
                                              double lng = double.Parse(nn.InnerText, CultureInfo.InvariantCulture);
211
                                              pointList.Add(new PointLatLng(lat, lng));
212
                                          }
213
                                      }
214
                                  }
215
                              }
216
 
217
                              status = GeoCoderStatusCode.G_GEO_SUCCESS;
218
                          }
219
                      }
220
                  }
221
              }
222
          }
223
          catch (Exception ex)
224
          {
225
              status = GeoCoderStatusCode.ExceptionInCode;
226
              Debug.WriteLine("GetLatLngFromGeocoderUrl: " + ex);
227
          }
228
 
229
          return status;
230
      }
231
 
232
      GeoCoderStatusCode GetPlacemarksFromReverseGeocoderUrl(string url, out List<Placemark> placemarkList)
233
      {
234
          var status = GeoCoderStatusCode.Unknow;
235
          placemarkList = null;
236
 
237
          try
238
          {
239
              string geo = GMaps.Instance.UsePlacemarkCache ? Cache.Instance.GetContent(url, CacheType.PlacemarkCache) : string.Empty;
240
 
241
              bool cache = false;
242
 
243
              if (string.IsNullOrEmpty(geo))
244
              {
245
                  geo = GetContentUsingHttp(url);
246
 
247
                  if (!string.IsNullOrEmpty(geo))
248
                  {
249
                      cache = true;
250
                  }
251
              }
252
 
253
              if (!string.IsNullOrEmpty(geo))
254
              {
255
                  if (geo.StartsWith("<?xml") && geo.Contains("<ResultSet"))
256
                  {
257
                      if (cache && GMaps.Instance.UsePlacemarkCache)
258
                      {
259
                          Cache.Instance.SaveContent(url, CacheType.PlacemarkCache, geo);
260
                      }
261
 
262
                      XmlDocument doc = new XmlDocument();
263
                      doc.LoadXml(geo);
264
                      {
265
                          XmlNodeList l = doc.SelectNodes("/ResultSet/Result");
266
                          if (l != null)
267
                          {
268
                              placemarkList = new List<Placemark>();
269
 
270
                              foreach (XmlNode n in l)
271
                              {
272
                                  var vl = n.SelectSingleNode("name");
273
                                  if (vl == null) continue;
274
 
275
                                  Placemark placemark = new Placemark(vl.InnerText);
276
 
277
                                  vl = n.SelectSingleNode("level0");
278
                                  if (vl != null)
279
                                  {
280
                                      placemark.CountryName = vl.InnerText;
281
                                  }
282
 
283
                                  vl = n.SelectSingleNode("level0code");
284
                                  if (vl != null)
285
                                  {
286
                                      placemark.CountryNameCode = vl.InnerText;
287
                                  }
288
 
289
                                  vl = n.SelectSingleNode("postal");
290
                                  if (vl != null)
291
                                  {
292
                                      placemark.PostalCodeNumber = vl.InnerText;
293
                                  }
294
 
295
                                  vl = n.SelectSingleNode("level1");
296
                                  if (vl != null)
297
                                  {
298
                                      placemark.AdministrativeAreaName = vl.InnerText;
299
                                  }
300
 
301
                                  vl = n.SelectSingleNode("level2");
302
                                  if (vl != null)
303
                                  {
304
                                      placemark.SubAdministrativeAreaName = vl.InnerText;
305
                                  }
306
 
307
                                  vl = n.SelectSingleNode("level3");
308
                                  if (vl != null)
309
                                  {
310
                                      placemark.LocalityName = vl.InnerText;
311
                                  }
312
 
313
                                  vl = n.SelectSingleNode("level4");
314
                                  if (vl != null)
315
                                  {
316
                                      placemark.DistrictName = vl.InnerText;
317
                                  }
318
 
319
                                  vl = n.SelectSingleNode("street");
320
                                  if (vl != null)
321
                                  {
322
                                      placemark.ThoroughfareName = vl.InnerText;
323
                                  }
324
 
325
                                  vl = n.SelectSingleNode("house");
326
                                  if (vl != null)
327
                                  {
328
                                      placemark.HouseNo = vl.InnerText;
329
                                  }
330
 
331
                                  vl = n.SelectSingleNode("radius");
332
                                  if (vl != null)
333
                                  {
334
                                      placemark.Accuracy = int.Parse(vl.InnerText);
335
                                  }
336
 
337
                                  placemarkList.Add(placemark);
338
                              }
339
 
340
                              status = GeoCoderStatusCode.G_GEO_SUCCESS;
341
                          }
342
                      }
343
                  }
344
              }
345
          }
346
          catch (Exception ex)
347
          {
348
              status = GeoCoderStatusCode.ExceptionInCode;
349
              Debug.WriteLine("GetPlacemarkFromReverseGeocoderUrl: " + ex);
350
          }
351
 
352
          return status;
353
      }
354
 
355
      static readonly string ReverseGeocoderUrlFormat = "http://where.yahooapis.com/geocode?q={0},{1}&appid={2}&flags=G&gflags=QRL{3}";
356
      static readonly string GeocoderUrlFormat = "http://where.yahooapis.com/geocode?q={0}&appid={1}&flags=CG&gflags=QL{2}";
357
      static readonly string GeocoderDetailedUrlFormat = "http://where.yahooapis.com/geocode?country={0}&state={1}&county={2}&city={3}&neighborhood={4}&postal={5}&street={6}&house={7}&appid={8}&flags=CG&gflags=QL{9}";
358
 
359
      #endregion
360
 
361
      #endregion
362
   }
363
 
364
   /// <summary>
365
   /// YahooMap provider
366
   /// </summary>
367
   public class YahooMapProvider : YahooMapProviderBase
368
   {
369
      public static readonly YahooMapProvider Instance;
370
 
371
      YahooMapProvider()
372
      {
373
      }
374
 
375
      static YahooMapProvider()
376
      {
377
         Instance = new YahooMapProvider();
378
      }
379
 
380
      public string Version = "2.1";
381
 
382
      #region GMapProvider Members
383
 
384
      readonly Guid id = new Guid("65DB032C-6869-49B0-A7FC-3AE41A26AF4D");
385
      public override Guid Id
386
      {
387
         get
388
         {
389
            return id;
390
         }
391
      }
392
 
393
      readonly string name = "YahooMap";
394
      public override string Name
395
      {
396
         get
397
         {
398
            return name;
399
         }
400
      }
401
 
402
      public override PureImage GetTileImage(GPoint pos, int zoom)
403
      {
404
         string url = MakeTileImageUrl(pos, zoom, LanguageStr);
405
 
406
         return GetTileImageUsingHttp(url);
407
      }
408
 
409
      #endregion
410
 
411
      string MakeTileImageUrl(GPoint pos, int zoom, string language)
412
      {
413
         // http://maps1.yimg.com/hx/tl?b=1&v=4.3&.intl=en&x=12&y=7&z=7&r=1
414
         // http://2.base.maps.api.here.com/maptile/2.1/maptile/newest/normal.day/11/1169/652/256/png8?lg=EN&token=TrLJuXVK62IQk0vuXFzaig%3D%3D&app_id=eAdkWGYRoc4RfxVo0Z4B
415
         // https://4.aerial.maps.api.here.com/maptile/2.1/maptile/newest/hybrid.day/11/1167/652/256/jpg?lg=ENG&token=TrLJuXVK62IQk0vuXFzaig%3D%3D&requestid=yahoo.prod&app_id=eAdkWGYRoc4RfxVo0Z4B
416
         // https://4.aerial.maps.api.here.com/maptile/2.1/maptile/newest/satellite.day/13/4671/2604/256/jpg?lg=ENG&token=TrLJuXVK62IQk0vuXFzaig%3D%3D&requestid=yahoo.prod&app_id=eAdkWGYRoc4RfxVo0Z4B
417
 
418
         return string.Format(UrlFormat, ((GetServerNum(pos, 2)) + 1), Version, zoom, pos.X, pos.Y, language, rnd1, rnd2);
419
      }
420
 
421
      string rnd1 = Guid.NewGuid().ToString("N").Substring(0, 28);
422
      string rnd2 = Guid.NewGuid().ToString("N").Substring(0, 20);
423
 
424
      //static readonly string UrlFormat = "http://maps{0}.yimg.com/hx/tl?v={1}&.intl={2}&x={3}&y={4}&z={5}&r=1";
425
      static readonly string UrlFormat = "http://{0}.base.maps.api.here.com/maptile/{1}/maptile/newest/normal.day/{2}/{3}/{4}/256/png8?lg={5}&token={6}&requestid=yahoo.prod&app_id={7}";
426
   }
427
}