Coordinately

Why Latitude Comes First (and When It Doesn’t)

ISO 6709 specifies latitude before longitude; GeoJSON, WKT, PostGIS, and KML specify longitude first. Where each convention came from, the 90° detection rule, and the defensive patterns that prevent order-swap bugs.

By . Published . Last updated .

A pair of numbers like 48, 2 is not a complete coordinate description. Whether it means “48° latitude, 2° longitude” (Paris) or “48° longitude, 2° latitude” (in the western Indian Ocean, offshore Somalia) depends entirely on which convention the producer used. The bytes are identical; the geographic meaning differs by thousands of kilometres.

Most coordinate-integration bugs trace back to this single ambiguity. A street-address geocoder returns [-74.006, 40.7128] because that is GeoJSON convention. The consuming code reads it as lat, lon because that is ISO 6709 convention. The displayed pin lands deep under the Antarctic ice cap instead of in New York City.

This article walks through where each convention came from, why both are correct in their respective domains, how to detect order errors when they happen, and the defensive code patterns that prevent them entirely.

The ISO 6709 rule

ISO 6709:2008Standard representation of geographic point location by coordinates — is the global standard for representing a point on Earth as a human-readable string. Annex H gives the canonical formats. In every one of them, for both decimal and DMS notation, latitude precedes longitude.

Examples from the standard:

  • +40.7484-073.9857/ — Empire State Building, decimal
  • +40-074/ — same point, lower precision
  • +40443/N+074043/W — same point, sexagesimal

The order matches spoken convention in most languages: “latitude and longitude” in English, “latitud y longitud” in Spanish, “Breite und Länge” in German, “緯度・経度” in Japanese. The pair has been written this way since pre-modern navigation, when latitude was easy to measure with a sextant and longitude required chronometers — see /learn/what-is-longitude for the history. Latitude was the answer first; longitude was the harder problem solved second.

Within ISO 6709, the order is mandatory. North American convention follows ISO. So do almost every cartographic publication, every paper topographic map, and most APIs that surface human-readable coordinate strings.

The longitude-first exceptions

A handful of widely-used technical specifications use the reverse order — longitude first, then latitude. They share the same rationale: a coordinate is treated as a Cartesian (x, y) pair, where x is the horizontal axis (east-west = longitude) and y is the vertical axis (north-south = latitude). This is the convention of every plotted map and every computer-graphics coordinate system.

GeoJSON (RFC 7946), §3.1.1: “A position is an array of numbers. There MUST be two or more elements. The first two elements are longitude and latitude, or easting and northing, precisely in that order and using decimal numbers.” Every GeoJSON Point, LineString, Polygon, and MultiPolygon places longitude first inside each coordinate array.

Well-Known Text (WKT), defined in OGC Simple Features Access and adopted by every major GIS package. A POINT in WKT is POINT(lon lat). WKT was designed for the (x, y) Cartesian coordinate model and the order is inherited from that lineage.

PostGIS follows WKT for both text input and the convenience constructors. ST_MakePoint(x, y) takes longitude first when storing geographic data. ST_GeographyFromText('POINT(-74.006 40.7128)') is New York City — longitude first.

KML 2.2, defined in OGC KML 2.2. The <coordinates> element is documented as longitude,latitude[,altitude] — explicitly longitude first.

The pattern is summarised in one table:

| Spec | Order | Reference | | --------------------- | ---------------------- | ------------------ | | ISO 6709 | Latitude, longitude | ISO 6709:2008 | | GeoJSON | Longitude, latitude | RFC 7946 §3.1.1 | | WKT (Simple Features) | Longitude, latitude | OGC 06-103r4 | | PostGIS WKT functions | Longitude, latitude | postgis.net | | KML 2.2 | Longitude, latitude | OGC 07-147r2 |

In short: anywhere a coordinate is treated as a point in a Cartesian plane, the convention is (x, y) = (lon, lat). Anywhere the coordinate is treated as a human-readable description of “where on Earth”, the convention is (lat, lon).

Why the split exists

The ISO 6709 convention preserves the historical and spoken order. The GeoJSON / WKT / PostGIS / KML convention preserves the cartographic plotting order. Each is internally consistent with the use case it was designed for.

If you flatten the Earth onto a map with east to the right and north upward, plotting a point requires writing the east-coordinate first, then the north-coordinate. The (x, y) tuple becomes (longitude, latitude). GeoJSON serialises a structure that plots directly: a Point's coordinates array can be passed verbatim into a 2D rendering routine. ISO 6709 serialises a description that reads naturally: a string a navigator could dictate aloud.

Neither convention is wrong. Both are precisely correct in their respective domains. The bug is never in either standard — it is in code that crosses the boundary between them without converting.

A small piece of historical context. The (x, y) cartographic convention long predates GeoJSON; it was already standard when analytical geometry took shape in the seventeenth century. WKT and the OGC Simple Features model inherited it directly from Cartesian geometry. GeoJSON, drafted in the late 2000s and standardised as RFC 7946 in 2016, kept the same order because it was already the working convention in every JavaScript mapping library at the time. ISO 6709 moves in the opposite tradition: it formalises the spoken “latitude and longitude” convention from celestial navigation and surveying, where latitude was historically the easier-to-measure and earlier-known half of the pair.

The 90° / 180° detection rule

Latitude is bounded to the range [−90°, +90°]. Longitude is bounded to [−180°, +180°]. The asymmetry gives a one-way test for order errors:

  • If the first number's magnitude exceeds 90, the pair cannot be lat-first. Any “latitude” greater than 90° in magnitude is geometrically impossible — the pair must be longitude-first.
  • If both numbers' magnitudes are ≤90, the rule is silent. Many populated regions live in this ambiguous zone — most of North America, all of Europe, much of Australia have longitude magnitudes less than 90, so the pair parses both ways.

The rule catches the wrong-order coordinates that happen to involve high-longitude regions (most of Asia, much of the Pacific, far western North America) by accident. The other half — coordinates whose longitude magnitude is below 90 — slip through and need a second signal.

How to detect order errors

Three diagnostic signals, in order of usefulness:

Magnitude exceeds 90 in the latitude position. Apply the 90° rule. A first-number magnitude of 151 (Sydney longitude) or 121 (Beijing longitude) is impossible as a latitude — the pair is unambiguously longitude-first.

Result plots far from expected location. The canonical symptom is “the address geocoded into the Indian Ocean off Somalia.” That is precisely what happens when a low-magnitude European coordinate gets parsed in the wrong order: (48.85, 2.35) lands in Paris if read lat-first, in the western Indian Ocean if read lon-first. The further-from-expected the result, the louder the signal.

Implausible context. A US-address geocoder returning a coordinate that plots in Asia. A city-name lookup that lands in the middle of an ocean. A delivery address far from the customer's billing region. Each is a signal to check whether the consumer expected the producer's order. The Coordinates to Address tool surfaces the resolved address alongside the input pin, which catches order errors visually in seconds.

How to fix order errors

Defensive patterns that prevent the bug at source rather than after the symptom appears:

Name the fields at the parsing boundary. Never carry a bare [number, number] array through business logic. Convert to a named-field structure ({ lat: number; lon: number }) at the parser. The order question is asked once, at parse time, not every time the value is touched.

Document the wire convention at every system boundary. API contracts state explicitly which order is on the wire. Database columns are named lat/lon, not x/y. JSON Schema and OpenAPI specifications annotate the order. The order question becomes a documented attribute of the interface, not a tribal convention.

Validate on ingest. Any latitude with magnitude greater than 90 is rejected at the parser. Any longitude outside [−180, 180] is rejected. Validation catches the half of wrong-order errors that the 90° rule can catch — before they become geocoding bugs.

Convert at the boundary, never in business logic. When a system emits GeoJSON and consumes ISO 6709 input, the conversion happens at the I/O layer (parser/serialiser). Internal representation stays in one convention. The same rule applies in reverse: never let a GeoJSON array escape into a context that expects ISO order without an explicit transform.

The minimal version of the parser-boundary pattern is three lines. The wire payload [number, number] arrives; the parser asserts the expected order, validates the latitude bound, and emits the named record:

function parseGeoJsonPosition([lon, lat]) {
  if (Math.abs(lat) > 90) throw new Error('latitude out of range');
  return { lat, lon };
}

Everything downstream consumes { lat, lon } and the wire order is forgotten. Reverse the wrapper for ISO-style input; the rest of the codebase is unchanged.

Worked examples

48, 2 — read lat-first: 48°N, 2°E → Paris (within ~1° of the actual 48.85°N, 2.35°E). Read lon-first: 48°E, 2°N → western Indian Ocean, offshore Somalia. The same pair of bytes resolves to two locations roughly 7,000 km apart.

151, -34 — read lat-first: 151°N is impossible (magnitude >90). Must be lon-first → 151°E, 34°S → Sydney area (close to the actual 33.87°S, 151.21°E). The 90° rule catches this immediately and deterministically.

-74.006, 40.7128 — read lat-first: −74° latitude, +40.7° longitude → Antarctic continent (the Princess Astrid Coast region). Read lon-first: −74°W, 40.7°N → New York City. Both interpretations pass the 90° rule, so the only signal is the expected location. If the source documents the pair as GeoJSON output, lon-first is correct; if as ISO 6709, lat-first is correct. The pair carries no internal evidence — context settles the question.

The conversion math itself (DMS, DDM, sexagesimal display) is unaffected by the order question; see /learn/decimal-degrees-vs-dms for that arithmetic.

Common misconceptions

“GeoJSON has the order wrong.” No. GeoJSON's order is a deliberate choice that maps to the (x, y) cartographic convention. The standard explicitly states longitude first. Treating GeoJSON as “ISO-broken” misreads the standard; treating both as different-but-correct in their respective domains is the accurate posture.

“If a number looks like a latitude, it is a latitude.” The intuition that “small magnitude = latitude” is wrong outside of regions with high-magnitude longitudes. Berlin is (52.52, 13.40) — both numbers under 90, either could syntactically be a latitude. Only the source's documented convention or an external sanity check settles it.

“Databases always store latitude first.” PostGIS — the most widely-deployed geographic database extension — follows WKT, which is longitude-first. SQL Server's geography type takes latitude first in its Point() constructor but longitude first in WKT text. Each engine documents its own convention; there is no industry-wide default.

“The 90° rule always catches order errors.” It catches order errors only when one of the numbers has magnitude greater than 90. For coordinates in the ambiguous zone — most populated regions of Europe, the eastern US, much of Africa, Australia outside its western extremes — both numbers parse both ways and the rule is silent. External context is required.

“Sign conventions follow the order.” They do not. The sign convention is independent of the order: positive latitude is north, negative is south; positive longitude is east, negative is west. Swapping the order does not change which hemisphere a positive number represents — it changes which axis the positive number is applied to. The forthcoming /learn/positive-and-negative-coordinates (when shipped) covers the full sign discipline.

Frequently asked questions

Should I write latitude or longitude first?

It depends on the convention of the system you are writing for. ISO 6709 (the human-readable standard) mandates latitude first. GeoJSON, WKT, PostGIS, and KML all specify longitude first because they treat coordinates as Cartesian (x, y) pairs. For human-facing strings, use latitude first; for GeoJSON / WKT / PostGIS / KML output, use longitude first. The order is documented at every system boundary, never assumed.

Why does GeoJSON use longitude first when ISO 6709 says latitude first?

GeoJSON’s RFC 7946 (§3.1.1) treats each coordinate as a Cartesian (x, y) pair, where x is the horizontal axis (longitude) and y is the vertical axis (latitude). This matches the convention of WKT, PostGIS, and most GIS software. ISO 6709 instead preserves the spoken convention “latitude and longitude” for human-readable strings. Both standards are deliberate and internally consistent in their respective domains.

How do I tell if a coordinate pair is in the wrong order?

The 90° rule: latitude is bounded to ±90°, so any “latitude” with magnitude greater than 90 must actually be a longitude — the pair is in the wrong order. The rule catches order errors only when the longitude magnitude exceeds 90 (most of Asia, much of the Pacific). When both numbers are ≤90 in magnitude, the rule is silent and you need the source’s documented convention or a visual sanity check on the plotted point.

Does the order convention affect database storage?

PostGIS — the most widely deployed geographic extension — follows WKT, which is longitude first. ST_MakePoint(x, y) and ST_GeographyFromText(‘POINT(x y)’) both take longitude before latitude. SQL Server’s geography type takes latitude first in its Point() constructor but longitude first in WKT text. There is no industry-wide default; each engine documents its own convention. If you store separate latitude and longitude columns, the column names settle the question regardless of internal order.

How do I prevent order-swap bugs in code?

Never accept a bare [number, number] array as a coordinate inside business logic. Convert to a named-field structure ({ lat, lon }) at the parsing boundary. Validate latitudes are within [−90, 90] on every ingest. Document the wire order at every API contract. Convert between conventions only at the I/O layer (parser/serialiser), keeping the internal representation in one convention. These four habits eliminate almost every order-swap bug.

Sources

  1. ISOISO 6709 — Standard representation of geographic point location · https://www.iso.org/standard/39242.html · Accessed .
  2. IETFRFC 7946 — The GeoJSON Format · https://datatracker.ietf.org/doc/html/rfc7946 · Accessed .
  3. OGCOGC Simple Features Access (WKT) · https://www.ogc.org/standards/sfa · Accessed .
  4. PostGISPostGIS Reference — ST_MakePoint and geometry constructors · https://postgis.net/docs/ST_MakePoint.html · Accessed .
  5. OGCOGC KML 2.2 — Coordinates element · https://www.ogc.org/standards/kml · Accessed .

Cite this article

APA format:

Steve K. (2026). Why Latitude Comes First (and When It Doesn’t). Coordinately. https://coordinately.org/learn/why-latitude-comes-first

BibTeX:

@misc{coordinately_whylatitudecomes_2026,
  author = {K., Steve},
  title  = {Why Latitude Comes First (and When It Doesn’t)},
  year   = {2026},
  publisher = {Coordinately},
  url    = {https://coordinately.org/learn/why-latitude-comes-first},
  note   = {Accessed: 2026-06-05}
}