Suite et fin de cette série d’articles… Après une 1ère partie sur l’utilisation du contrôle Map dans une application Metro, puis une 2ème partie sur la recherche de localités via les services REST Bing Maps et le Search Charm, nous allons maintenant intégrer le calcul d’itinéraire et l’affichage des incidents de circulation.
Commençons par le plus simple, l’affichage des incidents de circulation. Bing Maps met à disposition un service REST permettant de récupérer ce type d’information. Suivez ce lien pour une documentation complète du service d’incidents.
L’URL de base du service Bing Maps est la suivante : http://dev.virtualearth.net/REST/v1/Traffic/Incidents/
Il faut ensuite ajouter un paramètre représentant la zone géographique. Une zone géographique est représentée par un rectangle (Latitude Sud, Longitude Ouest, Latitude Nord, Longitude Est).
On peut également ajouter des paramètres supplémentaires optionnels afin de filtrer les résultats (severity : gravité des incidents, type : type d’incidents).
Pour l’intégration de ces informations dans notre application Bing Maps Metro, nous allons nous connecter à l’évènement ViewChangeEnded du contrôle Map :
Pour ne pas surcharger la carte avec trop d’informations, nous n’afficherons les incidents que dans le cas où le niveau de zoom est supérieur à 10 et si l’option d’affichage du trafic est activée. A chaque modification de la vue (manipulation de la carte par l’utilisateur), nous supprimons tous les points d’intérêt représentant des incidents, pour ensuite ajouter les nouveaux :
La zone géographique représentant le paramètre mapArea du service REST Bing Maps peut être composée de cette manière en utilisant la propriété TargetBounds du contrôle Map :
L’URL pour interroger le service de récupération des incidents de circulation est la suivante :
Il nous faut maintenant instancier un objet HttpClient afin d’envoyer notre requête et de récupérer le résultat :
Le résultat est un flux Json contenant la liste des incidents dans la zone demandée :
1: { 2: "authenticationResultCode": "ValidCredentials", 3: "brandLogoUri": "http://dev.virtualearth.net/Branding/logo_powered_by.png", 4: "copyright": "Copyright © 2012 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.", 5: "resourceSets": [ 6: { 7: "estimatedTotal": 2, 8: "resources": [ 9: { 10: "__type": "TrafficIncident:http://schemas.microsoft.com/search/local/ws/rest/v1", 11: "point": { 12: "type": "Point", 13: "coordinates": [ 14: 48.81982, 15: 2.32425 16: ] 17: }, 18: "description": "entre Porte d'Orléans (E2) et Porte de Gentilly - Fermé.", 19: "end": "/Date(1342258789000)/", 20: "incidentId": 323566599, 21: "lastModified": "/Date(1342085989000)/", 22: "roadClosed": true, 23: "severity": 4, 24: "start": "/Date(1342085940000)/", 25: "toPoint": { 26: "type": "Point", 27: "coordinates": [ 28: 48.81912, 29: 2.34364 30: ] 31: }, 32: "type": 8, 33: "verified": true 34: }, 35: { 36: "__type": "TrafficIncident:http://schemas.microsoft.com/search/local/ws/rest/v1", 37: "point": { 38: "type": "Point", 39: "coordinates": [ 40: 48.81982, 41: 2.32425 42: ] 43: }, 44: "description": "entre Porte d'Orléans (E2) et Porte de Gentilly - Travaux sur tronçon.", 45: "end": "/Date(1342389600000)/", 46: "incidentId": 322895570, 47: "lastModified": "/Date(1341847492000)/", 48: "roadClosed": false, 49: "severity": 2, 50: "start": "/Date(1341847260000)/", 51: "toPoint": { 52: "type": "Point", 53: "coordinates": [ 54: 48.81912, 55: 2.34364 56: ] 57: }, 58: "type": 9, 59: "verified": true 60: } 61: ] 62: } 63: ], 64: "statusCode": 200, 65: "statusDescription": "OK", 66: "traceId": "468e0ef9b5694d3e81d26623bbf5a3fe|AMSM001106|02.00.138.500|" 67: }
1: {
2: "authenticationResultCode": "ValidCredentials",
3: "brandLogoUri": "http://dev.virtualearth.net/Branding/logo_powered_by.png",
4: "copyright": "Copyright © 2012 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.",
5: "resourceSets": [
6: {
7: "estimatedTotal": 2,
8: "resources": [
9: {
10: "__type": "TrafficIncident:http://schemas.microsoft.com/search/local/ws/rest/v1",
11: "point": {
12: "type": "Point",
13: "coordinates": [
14: 48.81982,
15: 2.32425
16: ]
17: },
18: "description": "entre Porte d'Orléans (E2) et Porte de Gentilly - Fermé.",
19: "end": "/Date(1342258789000)/",
20: "incidentId": 323566599,
21: "lastModified": "/Date(1342085989000)/",
22: "roadClosed": true,
23: "severity": 4,
24: "start": "/Date(1342085940000)/",
25: "toPoint": {
26: "type": "Point",
27: "coordinates": [
28: 48.81912,
29: 2.34364
30: ]
31: },
32: "type": 8,
33: "verified": true
34: },
35: {
36: "__type": "TrafficIncident:http://schemas.microsoft.com/search/local/ws/rest/v1",
37: "point": {
38: "type": "Point",
39: "coordinates": [
40: 48.81982,
41: 2.32425
42: ]
43: },
44: "description": "entre Porte d'Orléans (E2) et Porte de Gentilly - Travaux sur tronçon.",
45: "end": "/Date(1342389600000)/",
46: "incidentId": 322895570,
47: "lastModified": "/Date(1341847492000)/",
48: "roadClosed": false,
49: "severity": 2,
50: "start": "/Date(1341847260000)/",
51: "toPoint": {
52: "type": "Point",
53: "coordinates": [
54: 48.81912,
55: 2.34364
56: ]
57: },
58: "type": 9,
59: "verified": true
60: }
61: ]
62: }
63: ],
64: "statusCode": 200,
65: "statusDescription": "OK",
66: "traceId": "468e0ef9b5694d3e81d26623bbf5a3fe|AMSM001106|02.00.138.500|"
67: }
Dans ce flux, nous devons récupérer et parcourir le tableau resources :
Pour chacun des incidents, récupérer sa description et ses coordonnées :
Et pour terminer, créer un objet de type Pushpin, le positionner et l’ajouter à la carte, puis ajouter un tooltip :
Et voilà le résultat :
Pour mieux identifier ces points d’intérêt comme étant des incidents, il est possible de personnaliser le style des contrôles Pushpin.
Nous allons ajouter cette image dans notre solution :
Ensuite dans les ressources de la page MainPage nous ajoutons le ControlTemplate suivant :
Il nous faut maintenant appliquer ce template lorsque l’on crée les objets de type Pushpin :
Voici le code complet de la méthode myMaps_ViewChangeEnded :
Et le résultat en image :
Nous allons maintenant développer la dernière fonctionnalité, qui est d’intégrer le calcul d’itinéraire. Pour consulter la documentation complète de l’API Routes des services Bing Maps, suivez ce lien.
L’URI de base pour calculer un itinéraire via les services Bing Maps est la suivante : http://dev.virtualearth.net/REST/v1/Routes/
Il faut ensuite ajouter des paramètres de type waypoint.n pour indiquer les différents points de passage. Un point de passage (début, intermédiaire, fin) est représenté soit par des coordonnées géographiques ou un requête (par exemple, une adresse).
Voici ici une URI qui nous permet de rechercher un itinéraire pour aller de Toulouse à Paris : http://dev.virtualearth.net/REST/V1/Routes/Driving?wp.0=toulouse&wp.1=paris&avoid=minimizeTolls&routePathOutput=points&key=XXXXXXXXXXXX
On remarque dans cette URI, le paramètre Driving. Ce paramètre permet d’indiquer le type de déplacement souhaité et peut prendre comme valeur driving, walking ou transit.
Le paramètre avoid permet d’indiquer comment nous voulons optimiser l’itinéraire. La valeur minimizeTolls indique d’éviter les péages autant que possible.
Et le paramètre routePathOutput permet d’indiquer si l’on veut la liste des points représentant le chemin de l’itinéraire (valeur points ou none).
Voici le format de la réponse Json :
1: { 2: "authenticationResultCode": "ValidCredentials", 3: "brandLogoUri": "http://dev.virtualearth.net/Branding/logo_powered_by.png", 4: "copyright": "Copyright © 2012 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.", 5: "resourceSets": [ 6: { 7: "estimatedTotal": 1, 8: "resources": [ 9: { 10: "__type": "Route:http://schemas.microsoft.com/search/local/ws/rest/v1", 11: "bbox": [ 12: 43.61451, 13: 1.463354, 14: 43.617219, 15: 1.465543 16: ], 17: "id": "v63,i0,a2,cen-US,dAAAAAAAAAAA=,y0,s1,m1,o1,t4,wtYbgA6hMIQA=~A1rKBEkRzUwuAADgAaxvKz8A~QXZlbnVlIGR1IENvbW1hbmRhbnQgVGFpbGxhbmRpZXIsIDMxNTAwIFRvdWxvdXNl~~~,wQ3ngA/VPIQA=~A1rKBEkhH04uAADgAQAAgD8A~QXZlbnVlIEzDqW9uIEJsdW0sIDMxNTAwIFRvdWxvdXNl~~~,k1,u", 18: "distanceUnit": "Kilometer", 19: "durationUnit": "Second", 20: "routeLegs": [ 21: { 22: "actualEnd": { 23: "type": "Point", 24: "coordinates": [ 25: 43.614548, 26: 1.46396 27: ] 28: }, 29: "actualStart": { 30: "type": "Point", 31: "coordinates": [ 32: 43.616874, 33: 1.463354 34: ] 35: }, 36: "endLocation": { 37: "bbox": [ 38: 43.610703, 39: 1.456808, 40: 43.618429, 41: 1.471034 42: ], 43: "name": "Avenue Léon Blum, 31500 Toulouse", 44: "point": { 45: "type": "Point", 46: "coordinates": [ 47: 43.614566, 48: 1.463921 49: ] 50: }, 51: "address": { 52: "addressLine": "Avenue Léon Blum", 53: "adminDistrict": "Midi-Pyrénées", 54: "adminDistrict2": "Haute-Garonne", 55: "countryRegion": "France", 56: "formattedAddress": "Avenue Léon Blum, 31500 Toulouse", 57: "locality": "Toulouse", 58: "postalCode": "31500" 59: }, 60: "confidence": "High", 61: "entityType": "RoadBlock", 62: "geocodePoints": [ 63: { 64: "type": "Point", 65: "coordinates": [ 66: 43.614566, 67: 1.463921 68: ], 69: "calculationMethod": "Interpolation", 70: "usageTypes": [ 71: "Display", 72: "Route" 73: ] 74: } 75: ], 76: "matchCodes": [ 77: "Good" 78: ] 79: }, 80: "itineraryItems": [ 81: { 82: "compassDirection": "southeast", 83: "details": [ 84: { 85: "compassDegrees": 114, 86: "endPathIndices": [ 87: 1 88: ], 89: "maneuverType": "DepartStart", 90: "mode": "Driving", 91: "names": [ 92: "Avenue du Commandant Taillandier" 93: ], 94: "roadType": "Street", 95: "startPathIndices": [ 96: 0 97: ] 98: } 99: ], 100: "exit": "", 101: "iconType": "Auto", 102: "instruction": { 103: "maneuverType": "DepartStart", 104: "text": "Depart Avenue du Commandant Taillandier toward Rue Benjamin Baillaud" 105: }, 106: "maneuverPoint": { 107: "type": "Point", 108: "coordinates": [ 109: 43.616874, 110: 1.463354 111: ] 112: }, 113: "sideOfStreet": "Unknown", 114: "tollZone": "", 115: "towardsRoadName": "Rue Benjamin Baillaud", 116: "transitTerminus": "", 117: "travelDistance": 0.078, 118: "travelDuration": 8, 119: "travelMode": "Driving" 120: }, 121: { 122: "compassDirection": "northeast", 123: "details": [ 124: { 125: "compassDegrees": 53, 126: "endPathIndices": [ 127: 5 128: ], 129: "maneuverType": "TurnLeft", 130: "mode": "Driving", 131: "names": [ 132: "Rue Benjamin Baillaud" 133: ], 134: "roadType": "Street", 135: "startPathIndices": [ 136: 1 137: ] 138: } 139: ], 140: "exit": "", 141: "iconType": "Auto", 142: "instruction": { 143: "maneuverType": "TurnLeft", 144: "text": "Turn left onto Rue Benjamin Baillaud" 145: }, 146: "maneuverPoint": { 147: "type": "Point", 148: "coordinates": [ 149: 43.6165, 150: 1.464191 151: ] 152: }, 153: "sideOfStreet": "Unknown", 154: "tollZone": "", 155: "transitTerminus": "", 156: "travelDistance": 0.142, 157: "travelDuration": 30, 158: "travelMode": "Driving" 159: }, 160: { 161: "compassDirection": "southwest", 162: "details": [ 163: { 164: "compassDegrees": 214, 165: "endPathIndices": [ 166: 8 167: ], 168: "maneuverType": "TurnRight", 169: "mode": "Driving", 170: "names": [ 171: "Avenue Yves Brunaud" 172: ], 173: "roadType": "Highway", 174: "startPathIndices": [ 175: 5 176: ] 177: } 178: ], 179: "exit": "", 180: "iconType": "Auto", 181: "instruction": { 182: "maneuverType": "TurnRight", 183: "text": "Turn right onto Avenue Yves Brunaud" 184: }, 185: "maneuverPoint": { 186: "type": "Point", 187: "coordinates": [ 188: 43.617128, 189: 1.4655 190: ] 191: }, 192: "sideOfStreet": "Unknown", 193: "tollZone": "", 194: "transitTerminus": "", 195: "travelDistance": 0.17, 196: "travelDuration": 33, 197: "travelMode": "Driving" 198: }, 199: { 200: "compassDirection": "southeast", 201: "details": [ 202: { 203: "compassDegrees": 270, 204: "endPathIndices": [ 205: 13 206: ], 207: "maneuverType": "EnterRoundabout", 208: "mode": "Driving", 209: "names": [ 210: "Rond-point du Capitaine Alfred Dreyfus" 211: ], 212: "roadType": "Highway", 213: "startPathIndices": [ 214: 8 215: ] 216: }, 217: { 218: "compassDegrees": 143, 219: "endPathIndices": [ 220: 15 221: ], 222: "maneuverType": "ExitRoundabout", 223: "mode": "Driving", 224: "names": [ 225: "Boulevard des Crêtes" 226: ], 227: "roadType": "MajorRoad", 228: "startPathIndices": [ 229: 13 230: ] 231: } 232: ], 233: "exit": "2", 234: "iconType": "Auto", 235: "instruction": { 236: "maneuverType": "EnterThenExitRoundabout", 237: "text": "At roundabout, take 2nd exit onto Boulevard des Crêtes" 238: }, 239: "maneuverPoint": { 240: "type": "Point", 241: "coordinates": [ 242: 43.615653, 243: 1.46506 244: ] 245: }, 246: "sideOfStreet": "Unknown", 247: "tollZone": "", 248: "transitTerminus": "", 249: "travelDistance": 0.168, 250: "travelDuration": 33, 251: "travelMode": "Driving" 252: }, 253: { 254: "compassDirection": "west", 255: "details": [ 256: { 257: "compassDegrees": 272, 258: "endPathIndices": [ 259: 17 260: ], 261: "maneuverType": "TurnRight", 262: "mode": "Driving", 263: "names": [ 264: "Avenue Léon Blum" 265: ], 266: "roadType": "MajorRoad", 267: "startPathIndices": [ 268: 15 269: ] 270: } 271: ], 272: "exit": "", 273: "iconType": "Auto", 274: "instruction": { 275: "maneuverType": "TurnRight", 276: "text": "Turn right onto Avenue Léon Blum" 277: }, 278: "maneuverPoint": { 279: "type": "Point", 280: "coordinates": [ 281: 43.614521, 282: 1.465543 283: ] 284: }, 285: "sideOfStreet": "Unknown", 286: "tollZone": "", 287: "transitTerminus": "", 288: "travelDistance": 0.13, 289: "travelDuration": 28, 290: "travelMode": "Driving" 291: }, 292: { 293: "compassDirection": "west", 294: "details": [ 295: { 296: "compassDegrees": 272, 297: "endPathIndices": [ 298: 17 299: ], 300: "maneuverType": "ArriveFinish", 301: "mode": "Driving", 302: "names": [ 303: "Avenue Léon Blum" 304: ], 305: "roadType": "MajorRoad", 306: "startPathIndices": [ 307: 17 308: ] 309: } 310: ], 311: "exit": "", 312: "hints": [ 313: { 314: "hintType": null, 315: "text": "The last intersection is Boulevard des Crêtes" 316: }, 317: { 318: "hintType": null, 319: "text": "If you reach Avenue Yves Brunaud, you've gone too far" 320: } 321: ], 322: "iconType": "Auto", 323: "instruction": { 324: "maneuverType": "ArriveFinish", 325: "text": "Arrive at Avenue Léon Blum, 31500 Toulouse" 326: }, 327: "maneuverPoint": { 328: "type": "Point", 329: "coordinates": [ 330: 43.614548, 331: 1.46396 332: ] 333: }, 334: "sideOfStreet": "Unknown", 335: "tollZone": "", 336: "transitTerminus": "", 337: "travelDistance": 0, 338: "travelDuration": 0, 339: "travelMode": "Driving" 340: } 341: ], 342: "startLocation": { 343: "bbox": [ 344: 43.613011, 345: 1.45624, 346: 43.620737, 347: 1.470468 348: ], 349: "name": "Avenue du Commandant Taillandier, 31500 Toulouse", 350: "point": { 351: "type": "Point", 352: "coordinates": [ 353: 43.616874, 354: 1.463354 355: ] 356: }, 357: "address": { 358: "addressLine": "Avenue du Commandant Taillandier", 359: "adminDistrict": "Midi-Pyrénées", 360: "adminDistrict2": "Haute-Garonne", 361: "countryRegion": "France", 362: "formattedAddress": "Avenue du Commandant Taillandier, 31500 Toulouse", 363: "locality": "Toulouse", 364: "postalCode": "31500" 365: }, 366: "confidence": "High", 367: "entityType": "RoadBlock", 368: "geocodePoints": [ 369: { 370: "type": "Point", 371: "coordinates": [ 372: 43.616874, 373: 1.463354 374: ], 375: "calculationMethod": "Interpolation", 376: "usageTypes": [ 377: "Display", 378: "Route" 379: ] 380: } 381: ], 382: "matchCodes": [ 383: "Good" 384: ] 385: }, 386: "travelDistance": 0.688, 387: "travelDuration": 133 388: } 389: ], 390: "routePath": { 391: "generalizations": [], 392: "line": { 393: "type": "LineString", 394: "coordinates": [ 395: [ 396: 43.616873, 397: 1.463354 398: ], 399: [ 400: 43.6165, 401: 1.464191 402: ], 403: [ 404: 43.617171, 405: 1.465092 406: ], 407: [ 408: 43.617219, 409: 1.465162 410: ], 411: [ 412: 43.617197, 413: 1.465269 414: ], 415: [ 416: 43.617128, 417: 1.465499 418: ], 419: [ 420: 43.61701, 421: 1.465419 422: ], 423: [ 424: 43.616462, 425: 1.46521 426: ], 427: [ 428: 43.615652, 429: 1.46506 430: ], 431: [ 432: 43.615652, 433: 1.464968 434: ], 435: [ 436: 43.61562, 437: 1.464877 438: ], 439: [ 440: 43.61547, 441: 1.46484 442: ], 443: [ 444: 43.6154, 445: 1.464942 446: ], 447: [ 448: 43.615438, 449: 1.465129 450: ], 451: [ 452: 43.615379, 453: 1.465172 454: ], 455: [ 456: 43.614521, 457: 1.465542 458: ], 459: [ 460: 43.61451, 461: 1.46543 462: ], 463: [ 464: 43.614547, 465: 1.46396 466: ] 467: ] 468: } 469: }, 470: "travelDistance": 0.688, 471: "travelDuration": 133 472: } 473: ] 474: } 475: ], 476: "statusCode": 200, 477: "statusDescription": "OK", 478: "traceId": "74808b399c51451dab1758f61ddd1c04|AMSM002207|02.00.138.500|AMSMSNVM002460, AMSMSNVM001314, AMSMSNVM001313, AMSMSNVM001322, AMSMSNVM002154, AMSMSNVM001307, AMSMSNVM002153, AMSMSNVM002408, AMSMSNVM001859, AMSMSNVM001857, AMSMSNVM001321, AMSMSNVM001863" 479: }
7: "estimatedTotal": 1,
10: "__type": "Route:http://schemas.microsoft.com/search/local/ws/rest/v1",
11: "bbox": [
12: 43.61451,
13: 1.463354,
14: 43.617219,
15: 1.465543
16: ],
17: "id": "v63,i0,a2,cen-US,dAAAAAAAAAAA=,y0,s1,m1,o1,t4,wtYbgA6hMIQA=~A1rKBEkRzUwuAADgAaxvKz8A~QXZlbnVlIGR1IENvbW1hbmRhbnQgVGFpbGxhbmRpZXIsIDMxNTAwIFRvdWxvdXNl~~~,wQ3ngA/VPIQA=~A1rKBEkhH04uAADgAQAAgD8A~QXZlbnVlIEzDqW9uIEJsdW0sIDMxNTAwIFRvdWxvdXNl~~~,k1,u",
18: "distanceUnit": "Kilometer",
19: "durationUnit": "Second",
20: "routeLegs": [
21: {
22: "actualEnd": {
23: "type": "Point",
24: "coordinates": [
25: 43.614548,
26: 1.46396
27: ]
28: },
29: "actualStart": {
30: "type": "Point",
31: "coordinates": [
32: 43.616874,
33: 1.463354
34: ]
35: },
36: "endLocation": {
37: "bbox": [
38: 43.610703,
39: 1.456808,
40: 43.618429,
41: 1.471034
42: ],
43: "name": "Avenue Léon Blum, 31500 Toulouse",
44: "point": {
45: "type": "Point",
46: "coordinates": [
47: 43.614566,
48: 1.463921
49: ]
50: },
51: "address": {
52: "addressLine": "Avenue Léon Blum",
53: "adminDistrict": "Midi-Pyrénées",
54: "adminDistrict2": "Haute-Garonne",
55: "countryRegion": "France",
56: "formattedAddress": "Avenue Léon Blum, 31500 Toulouse",
57: "locality": "Toulouse",
58: "postalCode": "31500"
59: },
60: "confidence": "High",
61: "entityType": "RoadBlock",
62: "geocodePoints": [
63: {
64: "type": "Point",
65: "coordinates": [
66: 43.614566,
67: 1.463921
68: ],
69: "calculationMethod": "Interpolation",
70: "usageTypes": [
71: "Display",
72: "Route"
73: ]
74: }
75: ],
76: "matchCodes": [
77: "Good"
78: ]
79: },
80: "itineraryItems": [
81: {
82: "compassDirection": "southeast",
83: "details": [
84: {
85: "compassDegrees": 114,
86: "endPathIndices": [
87: 1
88: ],
89: "maneuverType": "DepartStart",
90: "mode": "Driving",
91: "names": [
92: "Avenue du Commandant Taillandier"
93: ],
94: "roadType": "Street",
95: "startPathIndices": [
96: 0
97: ]
98: }
99: ],
100: "exit": "",
101: "iconType": "Auto",
102: "instruction": {
103: "maneuverType": "DepartStart",
104: "text": "Depart Avenue du Commandant Taillandier toward Rue Benjamin Baillaud"
105: },
106: "maneuverPoint": {
107: "type": "Point",
108: "coordinates": [
109: 43.616874,
110: 1.463354
111: ]
112: },
113: "sideOfStreet": "Unknown",
114: "tollZone": "",
115: "towardsRoadName": "Rue Benjamin Baillaud",
116: "transitTerminus": "",
117: "travelDistance": 0.078,
118: "travelDuration": 8,
119: "travelMode": "Driving"
120: },
121: {
122: "compassDirection": "northeast",
123: "details": [
124: {
125: "compassDegrees": 53,
126: "endPathIndices": [
127: 5
128: ],
129: "maneuverType": "TurnLeft",
130: "mode": "Driving",
131: "names": [
132: "Rue Benjamin Baillaud"
133: ],
134: "roadType": "Street",
135: "startPathIndices": [
136: 1
137: ]
138: }
139: ],
140: "exit": "",
141: "iconType": "Auto",
142: "instruction": {
143: "maneuverType": "TurnLeft",
144: "text": "Turn left onto Rue Benjamin Baillaud"
145: },
146: "maneuverPoint": {
147: "type": "Point",
148: "coordinates": [
149: 43.6165,
150: 1.464191
151: ]
152: },
153: "sideOfStreet": "Unknown",
154: "tollZone": "",
155: "transitTerminus": "",
156: "travelDistance": 0.142,
157: "travelDuration": 30,
158: "travelMode": "Driving"
159: },
160: {
161: "compassDirection": "southwest",
162: "details": [
163: {
164: "compassDegrees": 214,
165: "endPathIndices": [
166: 8
167: ],
168: "maneuverType": "TurnRight",
169: "mode": "Driving",
170: "names": [
171: "Avenue Yves Brunaud"
172: ],
173: "roadType": "Highway",
174: "startPathIndices": [
175: 5
176: ]
177: }
178: ],
179: "exit": "",
180: "iconType": "Auto",
181: "instruction": {
182: "maneuverType": "TurnRight",
183: "text": "Turn right onto Avenue Yves Brunaud"
184: },
185: "maneuverPoint": {
186: "type": "Point",
187: "coordinates": [
188: 43.617128,
189: 1.4655
190: ]
191: },
192: "sideOfStreet": "Unknown",
193: "tollZone": "",
194: "transitTerminus": "",
195: "travelDistance": 0.17,
196: "travelDuration": 33,
197: "travelMode": "Driving"
198: },
199: {
200: "compassDirection": "southeast",
201: "details": [
202: {
203: "compassDegrees": 270,
204: "endPathIndices": [
205: 13
206: ],
207: "maneuverType": "EnterRoundabout",
208: "mode": "Driving",
209: "names": [
210: "Rond-point du Capitaine Alfred Dreyfus"
211: ],
212: "roadType": "Highway",
213: "startPathIndices": [
214: 8
215: ]
216: },
217: {
218: "compassDegrees": 143,
219: "endPathIndices": [
220: 15
221: ],
222: "maneuverType": "ExitRoundabout",
223: "mode": "Driving",
224: "names": [
225: "Boulevard des Crêtes"
226: ],
227: "roadType": "MajorRoad",
228: "startPathIndices": [
229: 13
230: ]
231: }
232: ],
233: "exit": "2",
234: "iconType": "Auto",
235: "instruction": {
236: "maneuverType": "EnterThenExitRoundabout",
237: "text": "At roundabout, take 2nd exit onto Boulevard des Crêtes"
238: },
239: "maneuverPoint": {
240: "type": "Point",
241: "coordinates": [
242: 43.615653,
243: 1.46506
244: ]
245: },
246: "sideOfStreet": "Unknown",
247: "tollZone": "",
248: "transitTerminus": "",
249: "travelDistance": 0.168,
250: "travelDuration": 33,
251: "travelMode": "Driving"
252: },
253: {
254: "compassDirection": "west",
255: "details": [
256: {
257: "compassDegrees": 272,
258: "endPathIndices": [
259: 17
260: ],
261: "maneuverType": "TurnRight",
262: "mode": "Driving",
263: "names": [
264: "Avenue Léon Blum"
265: ],
266: "roadType": "MajorRoad",
267: "startPathIndices": [
268: 15
269: ]
270: }
271: ],
272: "exit": "",
273: "iconType": "Auto",
274: "instruction": {
275: "maneuverType": "TurnRight",
276: "text": "Turn right onto Avenue Léon Blum"
277: },
278: "maneuverPoint": {
279: "type": "Point",
280: "coordinates": [
281: 43.614521,
282: 1.465543
283: ]
284: },
285: "sideOfStreet": "Unknown",
286: "tollZone": "",
287: "transitTerminus": "",
288: "travelDistance": 0.13,
289: "travelDuration": 28,
290: "travelMode": "Driving"
291: },
292: {
293: "compassDirection": "west",
294: "details": [
295: {
296: "compassDegrees": 272,
297: "endPathIndices": [
298: 17
299: ],
300: "maneuverType": "ArriveFinish",
301: "mode": "Driving",
302: "names": [
303: "Avenue Léon Blum"
304: ],
305: "roadType": "MajorRoad",
306: "startPathIndices": [
307: 17
308: ]
309: }
310: ],
311: "exit": "",
312: "hints": [
313: {
314: "hintType": null,
315: "text": "The last intersection is Boulevard des Crêtes"
316: },
317: {
318: "hintType": null,
319: "text": "If you reach Avenue Yves Brunaud, you've gone too far"
320: }
321: ],
322: "iconType": "Auto",
323: "instruction": {
324: "maneuverType": "ArriveFinish",
325: "text": "Arrive at Avenue Léon Blum, 31500 Toulouse"
326: },
327: "maneuverPoint": {
328: "type": "Point",
329: "coordinates": [
330: 43.614548,
331: 1.46396
332: ]
333: },
334: "sideOfStreet": "Unknown",
335: "tollZone": "",
336: "transitTerminus": "",
337: "travelDistance": 0,
338: "travelDuration": 0,
339: "travelMode": "Driving"
340: }
341: ],
342: "startLocation": {
343: "bbox": [
344: 43.613011,
345: 1.45624,
346: 43.620737,
347: 1.470468
348: ],
349: "name": "Avenue du Commandant Taillandier, 31500 Toulouse",
350: "point": {
351: "type": "Point",
352: "coordinates": [
353: 43.616874,
354: 1.463354
355: ]
356: },
357: "address": {
358: "addressLine": "Avenue du Commandant Taillandier",
359: "adminDistrict": "Midi-Pyrénées",
360: "adminDistrict2": "Haute-Garonne",
361: "countryRegion": "France",
362: "formattedAddress": "Avenue du Commandant Taillandier, 31500 Toulouse",
363: "locality": "Toulouse",
364: "postalCode": "31500"
365: },
366: "confidence": "High",
367: "entityType": "RoadBlock",
368: "geocodePoints": [
369: {
370: "type": "Point",
371: "coordinates": [
372: 43.616874,
373: 1.463354
374: ],
375: "calculationMethod": "Interpolation",
376: "usageTypes": [
377: "Display",
378: "Route"
379: ]
380: }
381: ],
382: "matchCodes": [
383: "Good"
384: ]
385: },
386: "travelDistance": 0.688,
387: "travelDuration": 133
388: }
389: ],
390: "routePath": {
391: "generalizations": [],
392: "line": {
393: "type": "LineString",
394: "coordinates": [
395: [
396: 43.616873,
397: 1.463354
398: ],
399: [
400: 43.6165,
401: 1.464191
402: ],
403: [
404: 43.617171,
405: 1.465092
406: ],
407: [
408: 43.617219,
409: 1.465162
410: ],
411: [
412: 43.617197,
413: 1.465269
414: ],
415: [
416: 43.617128,
417: 1.465499
418: ],
419: [
420: 43.61701,
421: 1.465419
422: ],
423: [
424: 43.616462,
425: 1.46521
426: ],
427: [
428: 43.615652,
429: 1.46506
430: ],
431: [
432: 43.615652,
433: 1.464968
434: ],
435: [
436: 43.61562,
437: 1.464877
438: ],
439: [
440: 43.61547,
441: 1.46484
442: ],
443: [
444: 43.6154,
445: 1.464942
446: ],
447: [
448: 43.615438,
449: 1.465129
450: ],
451: [
452: 43.615379,
453: 1.465172
454: ],
455: [
456: 43.614521,
457: 1.465542
458: ],
459: [
460: 43.61451,
461: 1.46543
462: ],
463: [
464: 43.614547,
465: 1.46396
466: ]
467: ]
468: }
469: },
470: "travelDistance": 0.688,
471: "travelDuration": 133
472: }
473: ]
474: }
475: ],
476: "statusCode": 200,
477: "statusDescription": "OK",
478: "traceId": "74808b399c51451dab1758f61ddd1c04|AMSM002207|02.00.138.500|AMSMSNVM002460, AMSMSNVM001314, AMSMSNVM001313, AMSMSNVM001322, AMSMSNVM002154, AMSMSNVM001307, AMSMSNVM002153, AMSMSNVM002408, AMSMSNVM001859, AMSMSNVM001857, AMSMSNVM001321, AMSMSNVM001863"
479: }
Dans ce flux Json nous avons l’objet bbox qui va nous permettre de centrer la carte sur la zone géographique de l’itinéraire via la méthode SetView :
Dans le flux Json nous retrouvons également les valeurs travelDistance et travelDuration, ainsi que distanceUnit et durationUnit. Nous avons ici accès aux informations de temps de parcours et de la distance totale.
Ensuite 2 objets nous intéresse particulièrement dans le cadre de notre recherche d’itinéraire. Tout d’abord l’objet routePath, qui lui même contient un objet line avec les coordonnées de notre parcours :
Avec ces coordonnées nous allons pouvoir construire un objet MapPolyline pour représenter le parcours sur la carte. Un objet MapPolyline est composé d’un objet LocationCollection, d’une couleur et d’une taille :
Ce type d’objet doit être ajouté à la carte par l’intermédiaire d’un layer de type MapShapeLayer :
Voici le résultat que l’on obtient après ajout de l’objet MapPolyline :
Il nous reste à positionner les différentes étapes de l’itinéraire.
Dans le flux Json nous retrouvons la liste de ces étapes au niveau du tableau itineraryItems :
Dans une étape d’itinéraire, nous récupérons les coordonnées du point de manœuvre et les instructions. Nous utilisons un incrément afin de représenter le numéro de l’étape sur l’objet Pushpin :
Et voici le résultat :
On peut ensuite mettre en place un UserControl qui va nous permettre de saisir les adresses de départ, de destination et afficher les instructions dans une ListView :
L’archive suivante contient la solution complète au format VS 2012 RC :
Dans cette archive vous retrouverez les exemples décrits dans les 3 articles.
Il vous faudra éditer le fichier App.xaml afin de renseigner le paramètre BingMapsKey avec votre propre clé :
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.