Point distance matrix
Enter up to 200 points and get every pairwise great-circle distance in kilometres in one table: three points give a 3 × 3 grid with zeros on the diagonal and each distance mirrored across it. Rows and columns keep your order. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
The point distance matrix calculator turns an ordered list of latitude and longitude coordinates into every pairwise great-circle distance in kilometers. It is designed for routing preparation, clustering, proximity analysis, and any workflow that needs a complete cost table before choosing paths. The output preserves input order, places zeros on the diagonal, and mirrors every distance across the matrix. Calculations are deterministic, require no network lookup, and use a spherical Earth model so the same coordinates always produce the same result.
Prepare coordinates in the order your routing system expects
Supply between two and 200 points, with each point containing a numeric <code>lat</code> and <code>lon</code> in decimal degrees. Latitude must stay between -90 and 90, while longitude must stay between -180 and 180. The position of each point in the input list becomes its row and column position in the result, so establish a stable ordering before sending data.
For example, if a depot is first and delivery stops follow, row zero contains the depot-to-stop distances and column zero contains the same values in reverse. The calculator does not reorder, merge, geocode, or label points. Keep your own identifiers beside the list and associate them by array index.
Duplicate coordinates are accepted and correctly produce a zero distance even when they occur at different indices. This behavior is useful when two routing records refer to the same physical location but must remain separate business stops. Validate the coordinate source before calculation, especially when importing values from spreadsheets where latitude and longitude columns are sometimes swapped.
Understand how the symmetric matrix is calculated
Each unique pair is evaluated with the Haversine formula and a mean Earth radius of 6,371.0088 kilometers. The formula measures the shorter arc between two coordinates on a sphere, which is commonly called great-circle distance. The implementation calculates only the upper triangle of the matrix, copies each value to its mirrored position, and sets the diagonal to exactly zero.
That construction guarantees symmetry rather than relying on two separate floating-point calculations that might differ at the final decimal place. Great-circle distance is an air-line geographic distance, not a road, walking, rail, or sailing route. It ignores terrain, access restrictions, one-way streets, bridges, borders, and the ellipsoidal variation of Earth.
Use it as an analytical cost matrix, a routing heuristic, or a first-pass filter. If operational travel times or drivable distances are required, pass the selected pairs to a road-network routing service afterward.
Use the result safely in routing and analysis
Because geographic great-circle distance is undirected, the reverse entry is identical. This structure can feed clustering algorithms, nearest-neighbor selection, minimum spanning tree analysis, facility comparisons, or an initial traveling-salesperson heuristic without further pair expansion. Remember that matrix storage grows quadratically: 200 points produce 40,000 numeric cells, which is why the capability enforces a firm input limit.
For larger collections, divide the data into meaningful regions or compute only the pairs your algorithm actually needs. A routing solver may treat this output as a cost matrix, but it should not infer road feasibility from it. Keep the original ordered coordinates with the result so indices remain traceable, and record any preprocessing that removed invalid rows.
What you can do with it
Seed a multi-stop routing heuristic
Create the complete geographic cost table needed by nearest-neighbor or insertion algorithms before requesting detailed road routes.
Compare candidate facilities
Measure every warehouse-to-site and site-to-site separation in one consistently ordered matrix for location analysis.
Cluster nearby field stops
Use pairwise kilometer distances as deterministic input to grouping, threshold, or graph-based clustering workflows.
FAQ
Are these driving distances?
No. They are great-circle distances over a spherical Earth and do not follow roads or account for travel restrictions.
What unit does the matrix use?
Every matrix value is expressed in kilometers, and the response includes the unit explicitly.
Why is the matrix symmetric?
Great-circle distance from point A to point B equals the distance from B to A, so mirrored cells contain the same value.
How many points can I submit?
A request accepts from two through 200 points. The limit bounds quadratic computation and response size.
Which formula and Earth radius are used?
The haversine formula on a sphere with a mean Earth radius of 6,371.0088 km. It gives the shorter arc between two points, which is the great-circle or air-line distance.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/geo/distance-matrix \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"points":[{"lat":40.7128,"lon":-74.006},{"lat":51.5074,"lon":-0.1278},{"lat":35.6762,"lon":139.6503}]}'const res = await fetch("https://api.kit.forhosting.com/geo/distance-matrix", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"points": [
{
"lat": 40.7128,
"lon": -74.006
},
{
"lat": 51.5074,
"lon": -0.1278
},
{
"lat": 35.6762,
"lon": 139.6503
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/geo/distance-matrix",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"points": [
{
"lat": 40.7128,
"lon": -74.006
},
{
"lat": 51.5074,
"lon": -0.1278
},
{
"lat": 35.6762,
"lon": 139.6503
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/geo/distance-matrix", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"points":[{"lat":40.7128,"lon":-74.006},{"lat":51.5074,"lon":-0.1278},{"lat":35.6762,"lon":139.6503}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"points":[{"lat":40.7128,"lon":-74.006},{"lat":51.5074,"lon":-0.1278},{"lat":35.6762,"lon":139.6503}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/geo/distance-matrix", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"points": [
{
"lat": 40.7128,
"lon": -74.006
},
{
"lat": 51.5074,
"lon": -0.1278
},
{
"lat": 35.6762,
"lon": 139.6503
}
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "geo.distance_matrix",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_items | 200 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Use the result safely in routing and analysis
The response includes <code>point_count</code>, the fixed unit <code>km</code>, and <code>distances_km</code> as a square array. Entry <code>distances_km[i][j]</code> gives the distance from input point <code>i</code> to input point <code>j</code>. The computation is pure and performs no network requests, so repeated calls with identical JSON input are reproducible.
Technical questions
What does one request cost?
The API price is $0.002 per request. The browser version can run locally without an API call.