Spherical triangle area calculator from latitude and longitude
This spherical triangle area calculator finds the surface area enclosed by three latitude and longitude vertices on a sphere.
Run — free
It converts the coordinates to unit vectors, measures the three interior angles along shortest great-circle arcs, and applies Girard's theorem: the angle sum minus 180 degrees is the spherical excess. Multiplying that excess in radians by the squared sphere radius gives the area. Use the mean Earth radius supplied by default, or provide another positive radius for a different spherical body or mathematical model.
Define the triangle with three geographic vertices
Enter exactly three vertices in boundary order, giving each latitude and longitude in decimal degrees. Latitude must remain between -90 and 90, while longitude must remain between -180 and 180. The order may be clockwise or counterclockwise because the returned area is unsigned. Each edge is interpreted as the shorter great-circle arc connecting its endpoints, not as a straight line on a flat map and not as a rhumb line of constant bearing. That distinction matters whenever the triangle covers a noticeable fraction of a globe. The default radius is 6,371,008.8 meters, the IUGG mean Earth radius, so the primary result is expressed in square meters and a convenient secondary result is expressed in square kilometers. You may replace the radius with any positive finite value in meters when modeling another sphere. The calculator requires distinct vertices, rejects antipodal endpoint pairs because their connecting great circle is ambiguous, and rejects collinear great-circle points that enclose no usable surface area. These checks prevent a plausible-looking number from hiding an undefined geometric construction.
Understand spherical excess and the returned angles
A planar triangle always has an interior angle sum of 180 degrees, but a triangle drawn with great-circle edges on a sphere has a larger sum. The difference is called spherical excess. This calculator first converts every latitude and longitude pair to a three-dimensional unit vector. At each vertex, it projects directions toward the other two points onto the local tangent plane and measures the angle between those directions with a stable atan2 calculation. If the resulting angles are A, B, and C in radians, the excess is E = A + B + C - pi. Girard's theorem then gives area = E times radius squared. The response includes all three angles in input order and reports the excess in degrees so you can inspect the geometry, while the area calculation itself uses radians. A useful reference case has vertices at the equator and prime meridian, the equator at 90 degrees east, and the North Pole. Its three angles are each 90 degrees, its excess is 90 degrees, and it occupies one eighth of the complete sphere.
Interpret the spherical result responsibly
The result is exact for the spherical model represented by the supplied radius, subject only to floating-point rounding. Earth is not a perfect sphere, so this value can differ from an ellipsoidal geodesic area computed on WGS84, especially for large regions or work that demands surveying precision. Use this calculator for educational geometry, quick geographic estimates, planetary models, simulations, and systems whose coordinates already live on a sphere. Do not treat it as a cadastral or legal land-area measurement. The precision option controls displayed decimal places from zero through twelve; it does not change the underlying calculation. Extremely narrow triangles may approach the limits of ordinary floating-point arithmetic and are rejected when their spherical excess is indistinguishable from zero. The output is deterministic: identical coordinates, radius, and precision always produce the same fields, with no network access, random values, or current-time dependency. Browser use can be free, while an automated API request uses the displayed base price of $0.002. Store the original vertices alongside the result if an audit must later reproduce which spherical model and boundary produced the reported area.
What you can do with it
Estimate a three-point geographic region
Measure the spherical surface enclosed by three waypoints without projecting them onto a flat coordinate system.
Check a navigation or GIS implementation
Compare interior angles, spherical excess, and area against a deterministic reference calculation.
Model triangles on another world
Supply a planetary or abstract sphere radius and calculate the corresponding surface area from angular coordinates.
FAQ
Which formula does the calculator use?
It uses Girard's theorem: area equals the spherical excess in radians multiplied by the sphere radius squared.
What radius is used by default?
The default is the IUGG mean Earth radius of 6,371,008.8 meters. You may provide another positive radius in meters.
Does vertex order change the area?
No. Clockwise and counterclockwise orders return the same unsigned area, although each vertex still corresponds to the angle at the same input position.
Is this an ellipsoidal WGS84 area?
No. It is a spherical calculation. Use an ellipsoidal geodesic method when survey-grade Earth accuracy is required.
Why are antipodal or degenerate points rejected?
Antipodal points do not define one unique shortest great-circle edge, and collinear or repeated points do not enclose a valid positive-area triangle.
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/triangle-geodesic-area \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"vertices":[{"lat":0,"lon":0},{"lat":0,"lon":90},{"lat":90,"lon":0}]}'const res = await fetch("https://api.kit.forhosting.com/geo/triangle-geodesic-area", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"vertices": [
{
"lat": 0,
"lon": 0
},
{
"lat": 0,
"lon": 90
},
{
"lat": 90,
"lon": 0
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/geo/triangle-geodesic-area",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"vertices": [
{
"lat": 0,
"lon": 0
},
{
"lat": 0,
"lon": 90
},
{
"lat": 90,
"lon": 0
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/geo/triangle-geodesic-area", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"vertices":[{"lat":0,"lon":0},{"lat":0,"lon":90},{"lat":90,"lon":0}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"vertices":[{"lat":0,"lon":0},{"lat":0,"lon":90},{"lat":90,"lon":0}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/geo/triangle-geodesic-area", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"vertices": [
{
"lat": 0,
"lon": 0
},
{
"lat": 0,
"lon": 90
},
{
"lat": 90,
"lon": 0
}
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "geo.triangle_geodesic_area",
"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.
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. |