Reputation: 69
I am doing the nearest point query from a single point. Here is the sequence.
I have multiple POI stored in the MSSQLServer and the table is dbo.Place
. The second table is dbo.Position
, which will stored the collected GPS point.
I am using the Stored Procedure, and LatLong of Position is defined and available. How can I make query which is based from the examples below?
dbo.Place
Id | Name | Lat | Long
1 POI1 1.735 4.73225
2 POI2 1.5665 3.9983
3 Tim2 1.4344 3.1282
The Lat Long variable is defined in the stored procedure. I would like to use the following formula to find the nearest point, which I will only take the nearest value from the 3 queries(assuming the sample data is 3 row)
SQRT(POW(X(`POI.Lat`) - 49.843317 , 2) + POW(Y(`POI.Long`) - 24.026642, 2)) * 100
Thank you.
Upvotes: 1
Views: 685
Reputation: 1662
Besides the recommended geography types, you can also achieve the similar result using regular data types like float.
DECLARE @latitude FLOAT = 4.5678; -- Latitude of the place to search around
DECLARE @longitude FLOAT = 51.234; -- Longitude of the place to search around
DECLARE @range FLOAT = 100000; -- Max range in meters
SELECT TOP(1000)
[place].[Lat],
[place].[Long],
((((ACOS((SIN((PI() * [place].[Lat]) / 180.0) * SIN((PI() * @latitude) / 180.0)) + ((COS((PI() * [place].[Lat]) / 180.0) * COS((PI() * @latitude) / 180.0)) * COS((PI() * ([place].[Long] - @longitude)) / 180.0))) * 180.0) * 60.0) * 1.1515) * 1609.344) / PI() AS [Distance]
FROM [dbo].[Place] AS [place]
WHERE (((((ACOS((SIN((PI() * [place].[Lat]) / 180.0) * SIN((PI() * @latitude) / 180.0)) + ((COS((PI() * [place].[Lat]) / 180.0) * COS((PI() * @latitude) / 180.0)) * COS((PI() * ([place].[Long] - @longitude)) / 180.0))) * 180.0) * 60.0) * 1.1515) * 1609.344) / PI()) <= @range
ORDER BY [Distance]
Upvotes: 0
Reputation: 14189
You can use SQL Server's geography functions for this.
DECLARE @InputLatitude FLOAT = 1.64
DECLARE @InputLongitude FLOAT = 4.25
DECLARE @GPS GEOGRAPHY = GEOGRAPHY::Point(@InputLatitude, @InputLongitude, 4326)
SELECT TOP 1
P.*,
Distance = @GPS.STDistance(GEOGRAPHY::Point(P.Lat, P.Long, 4326))
FROM
dbo.Place AS P
ORDER BY
@GPS.STDistance(GEOGRAPHY::Point(P.Lat, P.Long, 4326)) ASC
You should consider adding a GEOGRAPHY
column on your table with the GPS points already converted and adding a SPATIAL INDEX
to speed up queries.
Upvotes: 3