mapquest-agent-skills 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +156 -0
- package/examples/conversations/store-locator-with-traffic.md +34 -0
- package/index.js +21 -0
- package/package.json +28 -0
- package/skills/mapquest-directions-routing/SKILL.md +261 -0
- package/skills/mapquest-geocoding-patterns/SKILL.md +243 -0
- package/skills/mapquest-key-security/SKILL.md +183 -0
- package/skills/mapquest-search-ahead/SKILL.md +286 -0
- package/skills/mapquest-static-maps/SKILL.md +242 -0
- package/skills/mapquest-store-locator/SKILL.md +242 -0
- package/skills/mapquest-traffic-data/SKILL.md +253 -0
- package/skills/mapquest-web-integration/SKILL.md +318 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Avi Raju
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# MapQuest Agent Skills
|
|
2
|
+
|
|
3
|
+
**8 comprehensive Agent Skills** that teach AI assistants how to build fast, reliable, production-ready MapQuest applications. Covers geocoding, routing, static maps, search-ahead, web integration, key security, store locators, and real-time traffic data.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
Install all MapQuest Agent Skills:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx add-skill definingAvi/mapquest-agent-skills
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Install specific skills:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx add-skill definingAvi/mapquest-agent-skills --skill mapquest-geocoding-patterns
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
List available skills:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx add-skill definingAvi/mapquest-agent-skills --list
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## What Are Agent Skills?
|
|
26
|
+
|
|
27
|
+
Agent Skills are folders containing instructions and resources that AI assistants (like Claude Code, Cursor, GitHub Copilot) can discover and use to perform tasks more effectively. Unlike tools (which provide actions) or prompts (which provide workflows), skills provide **domain expertise** β the "know-how" that helps AI make informed decisions when working with MapQuest APIs.
|
|
28
|
+
|
|
29
|
+
## Available Skills
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
### π mapquest-geocoding-patterns
|
|
34
|
+
**Address β coordinate conversion using the MapQuest Geocoding API.**
|
|
35
|
+
|
|
36
|
+
Covers forward geocoding, reverse geocoding, batch geocoding, quality codes, and response parsing. Teaches the AI to choose the right geocoding mode, handle partial/ambiguous addresses, and interpret `geocodeQuality` scores correctly.
|
|
37
|
+
|
|
38
|
+
[View skill β](./skills/mapquest-geocoding-patterns/SKILL.md)
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
### πΊοΈ mapquest-directions-routing
|
|
43
|
+
**Turn-by-turn directions, route optimization, and multi-stop routing.**
|
|
44
|
+
|
|
45
|
+
Covers the Directions API, route types (fastest/shortest/pedestrian/bicycle), narrative maneuvers, distance/time formatting, and common mistakes like ignoring `statusCode` or mixing up lat/lng order.
|
|
46
|
+
|
|
47
|
+
[View skill β](./skills/mapquest-directions-routing/SKILL.md)
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
### πΌοΈ mapquest-static-maps
|
|
52
|
+
**Generating and embedding static map images via the Static Map API.**
|
|
53
|
+
|
|
54
|
+
Covers center/zoom, markers, shape overlays, image sizing, map types (map/sat/hyb/light/dark), and URL construction patterns. Includes when to use static vs. interactive maps.
|
|
55
|
+
|
|
56
|
+
[View skill β](./skills/mapquest-static-maps/SKILL.md)
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
### π mapquest-search-ahead
|
|
61
|
+
**Typeahead/autocomplete using the Search Ahead API.**
|
|
62
|
+
|
|
63
|
+
Covers debouncing, result categories, geographic bias, collection types (address, adminArea, airport, category, franchise, poi), and how to chain Search Ahead with Geocoding for full address resolution.
|
|
64
|
+
|
|
65
|
+
[View skill β](./skills/mapquest-search-ahead/SKILL.md)
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
### π mapquest-web-integration
|
|
70
|
+
**Integrating the MapQuest JavaScript SDK (Leaflet-based) into web applications.**
|
|
71
|
+
|
|
72
|
+
Covers SDK loading, map initialization, tile layers, markers, popups, event handling, and framework integration patterns for React, Vue, and plain HTML/JS.
|
|
73
|
+
|
|
74
|
+
[View skill β](./skills/mapquest-web-integration/SKILL.md)
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
### π mapquest-key-security
|
|
79
|
+
**Best practices for handling MapQuest API keys securely.**
|
|
80
|
+
|
|
81
|
+
Covers environment variable storage, referrer restrictions in the MapQuest developer portal, server-side proxying, key rotation, and what to do when a key is exposed.
|
|
82
|
+
|
|
83
|
+
[View skill β](./skills/mapquest-key-security/SKILL.md)
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### πͺ mapquest-store-locator
|
|
88
|
+
**Building store locators and POI finders with MapQuest APIs.**
|
|
89
|
+
|
|
90
|
+
Covers the full pattern: geocode user input β find nearby locations β display on map β calculate routes to selected location. Includes distance calculations, result sorting, and marker clustering strategies.
|
|
91
|
+
|
|
92
|
+
[View skill β](./skills/mapquest-store-locator/SKILL.md)
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### π¦ mapquest-traffic-data
|
|
97
|
+
**Integrating real-time traffic data and incidents.**
|
|
98
|
+
|
|
99
|
+
Covers the Traffic API, incident severity codes, flow segments, how to overlay traffic on maps, and when to factor traffic into routing requests.
|
|
100
|
+
|
|
101
|
+
[View skill β](./skills/mapquest-traffic-data/SKILL.md)
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## How Skills Work
|
|
106
|
+
|
|
107
|
+
### With Claude Code
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npx add-skill definingAvi/mapquest-agent-skills -a claude-code
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### With Cursor
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npx add-skill definingAvi/mapquest-agent-skills -a cursor
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### With VS Code (GitHub Copilot)
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx add-skill definingAvi/mapquest-agent-skills -a vscode
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Repository Structure
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
mapquest-agent-skills/
|
|
129
|
+
βββ skills/
|
|
130
|
+
β βββ mapquest-geocoding-patterns/SKILL.md
|
|
131
|
+
β βββ mapquest-directions-routing/SKILL.md
|
|
132
|
+
β βββ mapquest-static-maps/SKILL.md
|
|
133
|
+
β βββ mapquest-search-ahead/SKILL.md
|
|
134
|
+
β βββ mapquest-web-integration/SKILL.md
|
|
135
|
+
β βββ mapquest-key-security/SKILL.md
|
|
136
|
+
β βββ mapquest-store-locator/SKILL.md
|
|
137
|
+
β βββ mapquest-traffic-data/SKILL.md
|
|
138
|
+
βββ examples/
|
|
139
|
+
β βββ conversations/
|
|
140
|
+
βββ README.md
|
|
141
|
+
βββ package.json
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Resources
|
|
145
|
+
|
|
146
|
+
- [MapQuest Developer Portal](https://developer.mapquest.com)
|
|
147
|
+
- [MapQuest API Documentation](https://developer.mapquest.com/documentation)
|
|
148
|
+
- [MapQuest Geocoding API](https://developer.mapquest.com/documentation/geocoding-api/)
|
|
149
|
+
- [MapQuest Directions API](https://developer.mapquest.com/documentation/directions-api/)
|
|
150
|
+
- [MapQuest Static Map API](https://developer.mapquest.com/documentation/static-map-api/v5/)
|
|
151
|
+
- [MapQuest Search Ahead API](https://developer.mapquest.com/documentation/searchahead-api/)
|
|
152
|
+
- [Agent Skills Specification](https://agentskills.io)
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Example: Store Locator with Live Traffic
|
|
2
|
+
|
|
3
|
+
This shows an AI assistant using MapQuest Agent Skills to build a store locator.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
**User:** I need to build a store locator for our 200 retail locations. Users type their address, see the nearest stores on a map, and can get directions to the one they choose.
|
|
8
|
+
|
|
9
|
+
**AI Assistant:** [Uses `mapquest-store-locator`, `mapquest-geocoding-patterns`, `mapquest-search-ahead`, `mapquest-web-integration`, `mapquest-directions-routing` skills]
|
|
10
|
+
|
|
11
|
+
Great β for 200 locations, here's the pattern I'll use:
|
|
12
|
+
|
|
13
|
+
- **Search Ahead** for address autocomplete as the user types
|
|
14
|
+
- **Geocoding API** to convert their selected address to coordinates
|
|
15
|
+
- **Haversine distance** (no API needed) to find and sort the 10 nearest stores
|
|
16
|
+
- **Leaflet.markercluster** for the 200 markers (above the 50-marker threshold where individual markers cause performance issues)
|
|
17
|
+
- **Directions API** only when the user clicks "Get Directions" on a specific store
|
|
18
|
+
|
|
19
|
+
Here's the implementation...
|
|
20
|
+
|
|
21
|
+
[Generates complete working code following all skill patterns]
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
**User:** Should I show traffic on the map?
|
|
26
|
+
|
|
27
|
+
**AI Assistant:** [Uses `mapquest-traffic-data` skill]
|
|
28
|
+
|
|
29
|
+
It depends on your use case:
|
|
30
|
+
|
|
31
|
+
- **Yes** if your users are making same-day decisions about which store to visit β live traffic helps them pick the fastest route
|
|
32
|
+
- **Skip it** if users are planning ahead or if your stores are in suburban/rural areas where traffic matters less
|
|
33
|
+
|
|
34
|
+
If you add it: scope the traffic API calls to the visible map bounds, poll no faster than every 2 minutes, and give users a toggle to show/hide it. Here's how...
|
package/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const pkg = require('./package.json');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns all available skills with their absolute paths resolved.
|
|
6
|
+
*/
|
|
7
|
+
function getSkills() {
|
|
8
|
+
return pkg.skills.map(skill => ({
|
|
9
|
+
...skill,
|
|
10
|
+
absolutePath: path.resolve(__dirname, skill.path),
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Returns a single skill by name, or undefined if not found.
|
|
16
|
+
*/
|
|
17
|
+
function getSkill(name) {
|
|
18
|
+
return getSkills().find(s => s.name === name);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
module.exports = { getSkills, getSkill };
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mapquest-agent-skills",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Agent Skills for AI coding assistants (Claude Code, Cursor, Copilot) β teaches MapQuest API best practices: geocoding, directions, static maps, search-ahead, store locators, traffic, and key security.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/definingAvi/mapquest-agent-skills.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/definingAvi/mapquest-agent-skills#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/definingAvi/mapquest-agent-skills/issues"
|
|
13
|
+
},
|
|
14
|
+
"author": "definingAvi",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"keywords": ["mapquest","maps","geocoding","directions","agent-skills","ai","claude","cursor","copilot","llm"],
|
|
17
|
+
"files": ["skills/","examples/","index.js","README.md","LICENSE"],
|
|
18
|
+
"skills": [
|
|
19
|
+
{"name":"mapquest-geocoding-patterns","path":"skills/mapquest-geocoding-patterns/SKILL.md","description":"Address-to-coordinate and coordinate-to-address conversion using the MapQuest Geocoding API"},
|
|
20
|
+
{"name":"mapquest-directions-routing","path":"skills/mapquest-directions-routing/SKILL.md","description":"Turn-by-turn directions and multi-stop routing using the MapQuest Directions API"},
|
|
21
|
+
{"name":"mapquest-static-maps","path":"skills/mapquest-static-maps/SKILL.md","description":"Generating and embedding static map images via the MapQuest Static Map API"},
|
|
22
|
+
{"name":"mapquest-search-ahead","path":"skills/mapquest-search-ahead/SKILL.md","description":"Typeahead/autocomplete using the MapQuest Search Ahead API"},
|
|
23
|
+
{"name":"mapquest-web-integration","path":"skills/mapquest-web-integration/SKILL.md","description":"Integrating the MapQuest JS SDK into web applications including React and Vue"},
|
|
24
|
+
{"name":"mapquest-key-security","path":"skills/mapquest-key-security/SKILL.md","description":"Best practices for securing MapQuest API keys"},
|
|
25
|
+
{"name":"mapquest-store-locator","path":"skills/mapquest-store-locator/SKILL.md","description":"Full store locator pattern: geocode user input, find nearby locations, display on map, get directions"},
|
|
26
|
+
{"name":"mapquest-traffic-data","path":"skills/mapquest-traffic-data/SKILL.md","description":"Real-time traffic incidents, flow data, and traffic-aware routing"}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mapquest-directions-routing
|
|
3
|
+
description: Turn-by-turn directions, multi-stop routing, and route optimization using the MapQuest Directions API. Covers route types, narrative maneuvers, response parsing, and common pitfalls.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# MapQuest Directions & Routing Patterns
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
The MapQuest Directions API provides turn-by-turn directions between two or more locations. Base URL: `https://www.mapquestapi.com/directions/v2`
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Route Types
|
|
15
|
+
|
|
16
|
+
Choose the right `routeType` for the use case:
|
|
17
|
+
|
|
18
|
+
| routeType | Description | Use When |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| `fastest` | Minimize travel time (default) | Standard driving |
|
|
21
|
+
| `shortest` | Minimize distance | Fuel efficiency priority |
|
|
22
|
+
| `pedestrian` | Walking paths | Walking directions |
|
|
23
|
+
| `bicycle` | Bike-friendly routes | Cycling apps |
|
|
24
|
+
| `multimodal` | Mix of transit + walking | Urban transit apps |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Basic Directions Request
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
async function getDirections(from, to, apiKey, options = {}) {
|
|
32
|
+
const params = new URLSearchParams({
|
|
33
|
+
key: apiKey,
|
|
34
|
+
from,
|
|
35
|
+
to,
|
|
36
|
+
routeType: options.routeType || 'fastest',
|
|
37
|
+
unit: options.unit || 'm', // 'm' = miles, 'k' = kilometers
|
|
38
|
+
narrativeType: 'text', // 'text', 'microformat', 'none'
|
|
39
|
+
enhancedNarrative: false,
|
|
40
|
+
avoidTimedConditions: false,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const response = await fetch(
|
|
44
|
+
`https://www.mapquestapi.com/directions/v2/route?${params}`
|
|
45
|
+
);
|
|
46
|
+
const data = await response.json();
|
|
47
|
+
|
|
48
|
+
if (data.info.statuscode !== 0) {
|
|
49
|
+
throw new Error(`Directions error: ${data.info.messages.join(', ')}`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return data.route;
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Multi-Stop Routing
|
|
59
|
+
|
|
60
|
+
For routes with 3+ stops, use the `from`/`to` + multiple `to` parameters, or POST with a locations array:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
async function getMultiStopRoute(locations, apiKey) {
|
|
64
|
+
// locations: array of address strings or {lat, lng} objects
|
|
65
|
+
const response = await fetch(
|
|
66
|
+
`https://www.mapquestapi.com/directions/v2/route?key=${apiKey}`,
|
|
67
|
+
{
|
|
68
|
+
method: 'POST',
|
|
69
|
+
headers: { 'Content-Type': 'application/json' },
|
|
70
|
+
body: JSON.stringify({
|
|
71
|
+
locations: locations,
|
|
72
|
+
options: {
|
|
73
|
+
routeType: 'fastest',
|
|
74
|
+
unit: 'm',
|
|
75
|
+
narrativeType: 'text',
|
|
76
|
+
avoids: [], // e.g. ['Toll Road', 'Ferry', 'Unpaved']
|
|
77
|
+
doReverseGeocode: false, // Skip reverse geocoding stops (faster)
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const data = await response.json();
|
|
84
|
+
return data.route;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Example with lat/lng objects (avoid geocoding overhead)
|
|
88
|
+
const stops = [
|
|
89
|
+
{ latLng: { lat: 34.0522, lng: -118.2437 } }, // Los Angeles
|
|
90
|
+
{ latLng: { lat: 36.1699, lng: -115.1398 } }, // Las Vegas
|
|
91
|
+
{ latLng: { lat: 33.4484, lng: -112.0740 } }, // Phoenix
|
|
92
|
+
];
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Parsing the Route Response
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
function parseRoute(route) {
|
|
101
|
+
return {
|
|
102
|
+
// Overall trip summary
|
|
103
|
+
distance: route.distance, // in chosen unit (miles or km)
|
|
104
|
+
time: route.time, // seconds
|
|
105
|
+
formattedTime: route.formattedTime, // 'h:mm:ss'
|
|
106
|
+
|
|
107
|
+
// Route shape (encoded polyline)
|
|
108
|
+
shape: route.shape?.shapePoints, // flat array [lat, lng, lat, lng, ...]
|
|
109
|
+
|
|
110
|
+
// Per-leg details (one leg per stop-to-stop segment)
|
|
111
|
+
legs: route.legs.map(leg => ({
|
|
112
|
+
distance: leg.distance,
|
|
113
|
+
time: leg.time,
|
|
114
|
+
maneuvers: leg.maneuvers.map(m => ({
|
|
115
|
+
narrative: m.narrative, // Human-readable instruction
|
|
116
|
+
distance: m.distance,
|
|
117
|
+
time: m.time,
|
|
118
|
+
turnType: m.turnType, // 0=straight, 1=slight right, etc.
|
|
119
|
+
startPoint: m.startPoint, // {lat, lng}
|
|
120
|
+
signs: m.signs, // Road signs
|
|
121
|
+
iconUrl: m.iconUrl,
|
|
122
|
+
}))
|
|
123
|
+
})),
|
|
124
|
+
|
|
125
|
+
// Bounding box for fitting map view
|
|
126
|
+
boundingBox: route.boundingBox, // {ul: {lat,lng}, lr: {lat,lng}}
|
|
127
|
+
|
|
128
|
+
// Status
|
|
129
|
+
hasTollRoad: route.hasTollRoad,
|
|
130
|
+
hasHighway: route.hasHighway,
|
|
131
|
+
hasFerry: route.hasFerry,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Route Avoidances
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
const avoidOptions = [
|
|
142
|
+
'Toll Road',
|
|
143
|
+
'Limited Access',
|
|
144
|
+
'Ferry',
|
|
145
|
+
'Unpaved',
|
|
146
|
+
'Seasonal Closure',
|
|
147
|
+
'Country Border Crossing',
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
// In request options:
|
|
151
|
+
options: {
|
|
152
|
+
avoids: ['Toll Road', 'Ferry']
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Optimized Route (Traveling Salesman)
|
|
159
|
+
|
|
160
|
+
For store locators or delivery apps needing to reorder stops optimally:
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
async function getOptimizedRoute(locations, apiKey) {
|
|
164
|
+
const response = await fetch(
|
|
165
|
+
`https://www.mapquestapi.com/directions/v2/optimizedroute?key=${apiKey}`,
|
|
166
|
+
{
|
|
167
|
+
method: 'POST',
|
|
168
|
+
headers: { 'Content-Type': 'application/json' },
|
|
169
|
+
body: JSON.stringify({
|
|
170
|
+
locations,
|
|
171
|
+
options: { routeType: 'fastest', unit: 'm' }
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
const data = await response.json();
|
|
176
|
+
// data.route.locationSequence shows optimized stop order
|
|
177
|
+
return data;
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Decoding the Shape Polyline
|
|
184
|
+
|
|
185
|
+
The route shape comes as a flat array of alternating lat/lng values:
|
|
186
|
+
|
|
187
|
+
```js
|
|
188
|
+
function shapeToLatLngs(shapePoints) {
|
|
189
|
+
const latLngs = [];
|
|
190
|
+
for (let i = 0; i < shapePoints.length; i += 2) {
|
|
191
|
+
latLngs.push([shapePoints[i], shapePoints[i + 1]]);
|
|
192
|
+
}
|
|
193
|
+
return latLngs;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Draw on Leaflet/MapQuest JS:
|
|
197
|
+
const latLngs = shapeToLatLngs(route.shape.shapePoints);
|
|
198
|
+
L.polyline(latLngs, { color: '#1a73e8', weight: 4 }).addTo(map);
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Displaying Formatted Distance & Time
|
|
204
|
+
|
|
205
|
+
```js
|
|
206
|
+
function formatDistance(miles) {
|
|
207
|
+
if (miles < 0.1) return `${Math.round(miles * 5280)} ft`;
|
|
208
|
+
return `${miles.toFixed(1)} mi`;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function formatDuration(seconds) {
|
|
212
|
+
const h = Math.floor(seconds / 3600);
|
|
213
|
+
const m = Math.floor((seconds % 3600) / 60);
|
|
214
|
+
if (h === 0) return `${m} min`;
|
|
215
|
+
return `${h} hr ${m} min`;
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Turn Type Icons
|
|
222
|
+
|
|
223
|
+
MapQuest returns numeric `turnType` codes. Map them to icons/labels:
|
|
224
|
+
|
|
225
|
+
```js
|
|
226
|
+
const TURN_TYPES = {
|
|
227
|
+
0: 'Straight',
|
|
228
|
+
1: 'Slight Right', 2: 'Right', 3: 'Sharp Right',
|
|
229
|
+
4: 'Reverse', 5: 'Sharp Left', 6: 'Left', 7: 'Slight Left',
|
|
230
|
+
8: 'Right U-Turn', 9: 'Left U-Turn',
|
|
231
|
+
11: 'Becomes', 12: 'Merge', 13: 'Fork Keep Right', 14: 'Fork Keep Left',
|
|
232
|
+
15: 'First Exit', 16: 'Second Exit', 17: 'Third Exit',
|
|
233
|
+
18: 'Exit Right', 19: 'Exit Left',
|
|
234
|
+
20: 'Right Ramp', 21: 'Left Ramp',
|
|
235
|
+
22: 'Right on Ramp', 23: 'Left on Ramp',
|
|
236
|
+
24: 'Take Ferry',
|
|
237
|
+
27: 'Roundabout 1st Exit', 28: 'Roundabout 2nd Exit', 29: 'Roundabout 3rd Exit',
|
|
238
|
+
};
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Common Mistakes to Avoid
|
|
244
|
+
|
|
245
|
+
β **Don't** send raw address strings with unencoded special characters. Always `encodeURIComponent()`.
|
|
246
|
+
|
|
247
|
+
β **Don't** use `pedestrian` routes for long distances (API may return an error or empty result).
|
|
248
|
+
|
|
249
|
+
β **Don't** ignore `statuscode`. Possible values:
|
|
250
|
+
- `0` = Success
|
|
251
|
+
- `402` = Invalid key
|
|
252
|
+
- `403` = Forbidden (key disabled)
|
|
253
|
+
- `500` = Route not found
|
|
254
|
+
|
|
255
|
+
β **Don't** request narrative for apps that only need the shape/distance β set `narrativeType: 'none'` for faster responses.
|
|
256
|
+
|
|
257
|
+
β
**Do** use lat/lng objects instead of address strings when you already have coordinates β avoids extra geocoding cost.
|
|
258
|
+
|
|
259
|
+
β
**Do** cache direction results for common origin/destination pairs.
|
|
260
|
+
|
|
261
|
+
β
**Do** fit the map to `route.boundingBox` after rendering so the full route is visible.
|