encikpiee
encikpiee

Reputation: 69

Making query to find nearest multiple(Lat,Long) from the single(Lat,Long)

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

Answers (2)

Imantas
Imantas

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

EzLo
EzLo

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

Related Questions