geography Point: Latitude Comes Before Longitude

geography Point takes latitude before longitude. I check the constructor contract before copying a coordinate pair from a WKT point description.

Two shallow ceramic bowls hold red beads joined by cream cords, with a blue bead resting in front.
Two shallow bowls of red beads joined by cream cords, with a blue bead in front.

Write down the coordinate order

A pair of plausible numbers doesn’t explain which coordinate comes first. Both ten and twenty fit ordinary latitude and longitude ranges. Swapping them can still produce a point. Successful construction alone therefore doesn’t prove the intended location.

geography::Point takes latitude, longitude and a spatial reference identifier. That order is the reverse of WKT. A WKT POINT describes longitude before latitude. The constructor and text reader need different input ordering.

I’d keep field names beside coordinates during an import review. A label such as first coordinate can lose its meaning between components. Latitude and longitude make the contract clearer. The selected constructor still needs its own argument order.

Compare matching and reversed descriptions

The first case constructs latitude ten and longitude twenty with geography::Point. Its WKT counterpart is POINT with twenty followed by ten. Both should return latitude ten and longitude twenty. The complete properties remain side by side.

The second case deliberately reverses the constructor’s numeric pair. Its WKT counterpart also reverses the text coordinate pair. Both should now return latitude twenty and longitude ten. They agree with each other while describing a different point.

A third case uses latitude minus ten and longitude twenty. It keeps the negative sign visible in both outputs. Every instance uses spatial reference identifier 4326. The examples are made-up coordinates, not claims about a person’s actual location.

WITH Inputs AS
(
    SELECT Id,CAST(CaseLabel AS varchar(20)) AS CaseLabel,
           CAST(Latitude AS decimal(8,3)) AS Latitude,
           CAST(Longitude AS decimal(8,3)) AS Longitude,
           CAST(PointText AS nvarchar(40)) AS PointText
    FROM (VALUES
        (1,'Matching',10,20,N'POINT(20 10)'),
        (2,'Reversed',20,10,N'POINT(10 20)'),
        (3,'NegativeLatitude',-10,20,N'POINT(20 -10)')
    ) AS v(Id,CaseLabel,Latitude,Longitude,PointText)
),
Points AS
(
    SELECT Id,CaseLabel,
           geography::Point(Latitude,Longitude,4326) AS ConstructorPoint,
           geography::STGeomFromText(PointText,4326) AS TextPoint
    FROM Inputs
)
SELECT Id,CaseLabel,
       CAST(ConstructorPoint.Lat AS decimal(12,6)) AS ConstructorLat,
       CAST(ConstructorPoint.Long AS decimal(12,6)) AS ConstructorLong,
       CAST(TextPoint.Lat AS decimal(12,6)) AS TextLat,
       CAST(TextPoint.Long AS decimal(12,6)) AS TextLong
FROM Points
ORDER BY Id;
Native SSMS results comparing geography point constructor and WKT latitude and longitude values.
All three coordinate pairs agree. The constructor uses latitude then longitude, while POINT text supplies longitude then latitude. The negative-latitude case retains its sign. Open the result at full size.
Constructor versus WKT order

Inspect properties rather than a familiar-looking string

The query returns Lat and Long for each construction path. Both properties are float values for single points. This example casts their display to decimal(12,6). That choice makes the paired coordinates easy to compare.

The cast doesn’t alter the stored geography instance. It also doesn’t change the constructor’s argument order. Keep the point construction and its display expression separate. Six decimal places are a presentation choice for these small literal inputs.

The case label identifies matching, reversed and negative-latitude rows. It isn’t a substitute for reading all four coordinate outputs. A row count of three wouldn’t detect a swap. Compare the complete property pairs against the intended values.

Keep the construction test narrow

The SQL contains literal rows, two CTEs and one SELECT. It writes no data and changes no connection settings. ORDER BY fixes the selected case sequence. No external geocoding or network service is required.

This demonstration doesn’t measure a distance or polygon area. Those operations introduce another spatial question and a unit contract. It checks coordinate order for single points only. A valid point doesn’t certify all later calculations or application rules.

The geography model should also remain distinct from geometry’s local planar coordinates. Reusing an X-Y habit can conceal a latitude-longitude mismatch. Read the method’s named inputs rather than inferring them from another type. The explicit Lat and Long outputs provide a useful check.

Retain the reversed pair during testing

The reversed row is intentionally constructible. It shows why range validation alone can miss an order error. The negative-latitude row checks the sign independently. All three cases belong in the expected result contract.

Compare every complete coordinate tuple and its SQL types. Keep both constructors’ Lat and Long properties together. Retain the reversed pair and negative latitude during that comparison. Checking only one output path wouldn’t verify the ordering difference.

Say the names out loud, latitude then longitude, before you paste a pair.

A constructible pair is not a confirmed location, it is input that needs the right order.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.


Discover more from SQL Authority with Pinal Dave

Subscribe to get the latest posts sent to your email.

SQL Datatype, SQL Function, SQL Scripts, SQL Server
Previous Post
Rotating the TDE Certificate
Next Post
SQL SERVER – Interesting Observation – Query Hint – FORCE ORDER

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.