sqlt-sqlgeospatialspatialspatial-query

Spatial SQL (in SSMS - using T-SQL) - STIntersect and STContains doesn't return the correct result


Trying to find:

  1. All the routes that pass through a buffer of 5km around a random point.

Background:

  1. I have multiple routes stored as linestring of type geography using the following query. The linestring is valid.
INSERT INTO routes (route_id, route_name, route_geography)
VALUES (
    8,
    'route-test-8',
    geography::STGeomFromText('LINESTRING(50.47959 -80.518649, 50.47923 -80.519601, ......)', 4326)
);
  1. I have a random point near the routes.

NOTE: For testing purposes, this random point is a point that exists in one of the routes. So in theory I should at least get 1 route in true result

  1. Table structure that stores routes:

Columns and it's types: route_geography of type geography

Tried the following query:

  1. Used STContains: doesn't return any route as true when in fact it should, because the (lat,long) point I select is in the route itself
-- Declare the "random" point

DECLARE @startPoint geography;
SET @startPoint = geography::Point('50.47959','-80.518649' , 4326); -- this is the exact point from one of the routes 

-- Create a buffer around the "random" point

DECLARE @buffer geography;
SET @buffer = @startPoint.STBuffer(5000); -- Create a 5km radius buffer

-- Finding the routes that pass through the buffer

SELECT [route_id], [route_name],[route_geography].
FROM [test-DB].[dbo].[routes]
WHERE @buffer.STContains([route_geography]) = 1; -- when assigned 0 returns all the routes
  1. Used STIntersect: same result as with STContains
-- Declare the "random" point

DECLARE @startPoint geography;
SET @startPoint = geography::Point('50.47959','-80.518649' , 4326); -- this is the exact point from one of the routes 

-- Create a buffer around the "random" point

DECLARE @buffer geography;
SET @buffer = @startPoint.STBuffer(5000); -- Create a 5km radius buffer

-- Finding the routes that pass through the buffer

SELECT [route_id], [route_name]
FROM [test-DB].[dbo].[routes]
WHERE [route_geography].STIntersects(@buffer) = 1; -- when assigned 0 returns all the routes

Solution

  • It's probably because the arguments you are giving to geography::Point are in the wrong order. The function geography::Point takes first Lat, then Long. This is different from WKT where coordinates are given as first Long then Lat. This is helpfully pointed out in a note in the documentation: https://learn.microsoft.com/en-us/sql/t-sql/spatial-geography/point-geography-data-type?view=sql-server-ver16