How to Create 5-, 10-, and 15-Minute Travel-Time Zones

API or service
Isoline API + MapLibre GL
Task
Origin + several time limits → nested reachability zones
Examples
URLMapLibre GL
Difficulty
Beginner
Time
10 min

Create several travel-time zones

You have one origin and need to compare what is reachable within 5, 10, and 15 minutes. Send all three limits to the Isoline API in one request and render each returned feature as a nested zone.

Task flow: origin + 5/10/15-minute limits → one Isoline API request → three GeoJSON features → nested map zones.

Multiple ranges are useful for response-time bands, delivery promises, retail catchments, and facility planning. Each larger feature is cumulative: the 15-minute area includes locations that are also reachable within 5 or 10 minutes.

Request 5-, 10-, and 15-minute zones

Pass one comma-separated range value containing 300, 600, and 900 seconds. The API accepts between one and ten ranges per calculation.

https://api.geoapify.com/v1/isoline?lat=52.52&lon=13.405&type=time&mode=drive&range=300,600,900&traffic=free_flow&format=geojson&apiKey=YOUR_API_KEY

Reduced response: Geometry coordinates are omitted. Match each feature to its band through properties.range, not its array position.

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": { "mode": "drive", "type": "time", "range": 300 },
      "geometry": { "type": "MultiPolygon" }
    },
    {
      "type": "Feature",
      "properties": { "mode": "drive", "type": "time", "range": 600 },
      "geometry": { "type": "MultiPolygon" }
    },
    {
      "type": "Feature",
      "properties": { "mode": "drive", "type": "time", "range": 900 },
      "geometry": { "type": "MultiPolygon" }
    }
  ]
}

The same request pattern works for distance zones: use type=distance and provide ranges in meters when units=metric or miles when units=imperial.

Style nested travel-time zones

Add the complete FeatureCollection as a GeoJSON source. Sort larger ranges first so smaller zones remain visible, then color each feature from its range property.

// `zones` is the complete response from the 300,600,900 request.
zones.features.sort((a, b) => b.properties.range - a.properties.range);

map.addSource("travel-time-zones", { type: "geojson", data: zones });
map.addLayer({
  id: "travel-time-zones-fill",
  type: "fill",
  source: "travel-time-zones",
  paint: {
    "fill-color": [
      "match", ["get", "range"],
      300, "#00ac17",
      600, "#ffb703",
      900, "#ff005c",
      "#623aff"
    ],
    "fill-opacity": 0.3
  }
});
map.addLayer({
  id: "travel-time-zones-outline",
  type: "line",
  source: "travel-time-zones",
  paint: { "line-color": "#ffffff", "line-width": 1 }
});

Label the legend as 5 min, 10 min, and 15 min, while keeping seconds in the data. If the bands must not overlap for analysis, subtract the preceding polygon from each larger polygon; map display usually does not require that conversion.