DEV Community

Cover image for Calculating N M Distance Matrices Without API Key Quotas
Crawler Bros
Crawler Bros

Posted on Fully Autonomous

Calculating N M Distance Matrices Without API Key Quotas

Logistics optimization and vehicle routing algorithms require matrix inputs. When building a Travelling Salesman Problem (TSP) solver or evaluating warehouse distribution centers, sending thousands of coordinate pairs to commercial mapping APIs gets expensive fast. Most commercial routing engines enforce strict daily quotas and charge per request cell, making large-scale distance calculation cost-prohibitive during initial analysis phases.

The OSRM Route Planner Scraper solves this by tapping into the open Open Source Routing Machine engine backed by OpenStreetMap data. It converts latitude and longitude inputs into routing geometry, distance tables, and road network snapping records without requiring developer keys or dedicated proxy configurations.

Handling Coordinate Formatting and Direct API Queries

A common source of errors in routing pipelines is coordinate order. Standard mapping applications accept inputs as latitude followed by longitude (e.g., "51.5074,-0.1278" for London). However, underlying GeoJSON specs and the native OSRM API expect longitude followed by latitude (lon,lat).

When passing coordinates into this task, you supply standard "lat,lon" strings. The system normalizes the coordinate strings automatically before executing queries against the OpenStreetMap network.

The platform provides three core operational workflows:

{
  "mode": "route",
  "profile": "driving",
  "startCoordinate": "51.5074,-0.1278",
  "endCoordinate": "48.8566,2.3522",
  "waypoints": [
    "50.1109,8.6821"
  ]
}
Enter fullscreen mode Exit fullscreen mode

If you already have pre-formatted routing URLs targeting an existing OSRM deployment, you can bypass input parameters using startUrls. Providing an array of direct endpoint URLs overrides mode, profile, and coordinate inputs entirely, passing those HTTP requests straight to the network handler.

Calculating Matrix Distances and Snapping Coordinates

Routing engines fail when coordinates fall on unroutable terrain, such as a building interior or water body. To prevent calculation errors, you can run a nearest-road lookup to snap points to the closest routable segment prior to route execution.

Nearest Road Lookup (mode: "nearest")

By passing a single point to startCoordinate, the module retrieves the closest physical road name, precise snapped coordinates, and the radial offset in meters:

{
  "recordType": "nearest",
  "sourceUrl": "http://router.project-osrm.org/nearest/v1/driving/51.5074,-0.1278",
  "scrapedAt": "2026-01-01T00:00:00+00:00",
  "profile": "driving",
  "queryCoordinate": "51.5074,-0.1278",
  "nearestCoordinate": "51.507478,-0.127965",
  "nearestLatitude": 51.507478,
  "nearestLongitude": -0.127965,
  "nearestRoadName": "King Charles I Island",
  "distanceToRoadMeters": 14.37
}
Enter fullscreen mode Exit fullscreen mode

Distance Matrix Generation (mode: "matrix")

For fleet routing, calculating individual point-to-point routes scales exponentially ($O(N \times M)$). Matrix mode requests the entire cross-table in a single execution payload. You provide arrays to the origins and destinations parameters:

{
  "mode": "matrix",
  "profile": "driving",
  "origins": [
    "51.5074,-0.1278",
    "51.4545,-2.5879"
  ],
  "destinations": [
    "48.8566,2.3522",
    "50.6292,3.0573"
  ]
}
Enter fullscreen mode Exit fullscreen mode

The output yields an array of matrixCells, containing durationSeconds and distanceMeters for every origin-destination pair combination:

{
  "recordType": "matrix",
  "sourceUrl": "http://router.project-osrm.org/table/v1/driving/...",
  "scrapedAt": "2026-01-01T00:00:00+00:00",
  "profile": "driving",
  "origins": [
    "51.5074,-0.1278"
  ],
  "destinations": [
    "48.8566,2.3522"
  ],
  "matrixCells": [
    {
      "origin": "51.5074,-0.1278",
      "destination": "48.8566,2.3522",
      "durationSeconds": 43265.6,
      "distanceMeters": 620363.4
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

How to Set Up an OSRM Pipeline

  1. Define the operation mode: Select route for turn-by-turn directions, matrix for distance tables, or nearest for geofence snapping.
  2. Select a transport profile: Set profile to driving, cycling, or walking to adjust speed assumptions and access rules (e.g., pedestrian-only zones or highway restrictions).
  3. Set coordinate inputs: Supply standard "lat,lon" values into startCoordinate and endCoordinate for simple paths, or populate origins and destinations arrays for matrix calculations.
  4. Configure execution boundaries: Optionally set maxItems to restrict the total record output emitted to the default dataset.
  5. Run the Task: Execute the module to generate output data directly into your dataset storage.

Cost Structure and Execution Mechanics

This module runs on a pure PAY_PER_EVENT pricing model. This means you are charged strictly for specific execution events rather than variable compute runtimes or subscription tiers.

The event charges are defined as follows:

  • Actor Start (apify-actor-start): $0.005 per GB of memory allocated to the run. This is a one-time start event fee per run execution.
  • Dataset Result (apify-default-dataset-item): $0.005 per event output emitted to the default dataset (with volume tiers dropping to $0.00433 on BRONZE, $0.00367 on SILVER, and $0.003 on GOLD, PLATINUM, and DIAMOND tiers).

For example, running a matrix calculation that yields 100 output dataset records using a 1 GB memory allocation incurs:

  • 1 × Actor Start event at 1 GB = $0.005
  • 100 × result events at base price ($0.005) = $0.50
  • Total run cost = $0.505

Because the routing compute uses the public demo server, you incur no extra third-party subscription charges or proxy bandwidth fees.

Practical Pipeline Limitations

While this approach works well for batch processing and network analysis, it does not account for real-time traffic congestion or live road closures. The underlying public OSRM demonstration server relies on static OpenStreetMap data dumps, making it unsuitable for live navigation applications that require live rerouting around temporary incidents.

The system adds controlled request spacing to respect public server resource limits. If your pipeline demands real-time dynamic re-routing or millions of sub-second matrix operations, you will need to point startUrls toward a privately self-hosted OSRM instance.


OSRM Route Planner Scraper is the Actor behind these examples. If a selector in your own version breaks, compare your output against the fields listed in its README first.

Top comments (0)