Pergunta

I have created a table containing US zipcodes along with the latitude and longitude of these zip codes. From the latitude and longitude I created a geography column. I created a spatial index on that geography column. I want to return the closest 100 zip codes to a latitude and longitude so I created the following stored procedure

CREATE PROCEDURE [dbo].[Geo_Locate]
@Latitude DECIMAL,
@Longitude DECIMAL
AS
BEGIN
SET NOCOUNT ON;

DECLARE @GeogTemp NVARCHAR(200)
DECLARE @Geog GEOGRAPHY

-- Create a geography type variable from the passed in latitude and longitude. This will be used to find the closest point in the database
SET @GeogTemp = 'POINT(' + convert(NVARCHAR(100), @Longitude) + ' ' + convert(NVARCHAR(100), @Latitude) + ')'
SET @Geog = geography::STGeomFromText(@GeogTemp, 4326)

-- Run the main query
SELECT TOP 100
    [Id],
    [Country],
    [ZipPostalCode],
    [City],
    [County],
    [Latitude],
    [Longitude],
    [GeographyCol],
    GeographyCol.STDistance(@Geog) AS Distance
FROM 
    [dbo].[ZipCode] WITH(INDEX(ZipCode_SpatialIndex))
WHERE 
    GeographyCol.STDistance(@Geog) < 100000     -- 100 KM
ORDER BY
    GeographyCol.STDistance(@Geog) ASC
END

However when I pass the latitude = 35.48330 and longitude = -97.17340 to this stored procedure I get the following returned at item 55

869531 US 73045 Harrah Oklahoma OK 35.48330 -97.17340 0xE6100000010C12143FC6DCBD4140174850FC184B58C0 55894.2236191955

The last column is the distance. Basically the query is saying that this record is nearly 56KM from the entered point but the latitude and longitude are the same.

I've read MSDN and my query looks correct. Can anyone help me please?

Foi útil?

Solução

This one was a doozy and I'm not sure I got it. I started with trying to replicate in purest terms what you were seeing: incorrect STDistance() between two geography points.

DECLARE @zipcode geography
DECLARE @searchpoint geography
SET @zipcode = geography::STPointFromText('POINT(-97.17340 35.48330)', 4326);
SET @searchpoint = geography::STPointFromText('POINT(-97.17340 35.48330)', 4326);

SELECT @zipcode.STDistance(@searchpoint)

The results is, correctly, 0 meters (SRID 4326 uses meters as the distance unit), so I kept scratching my head. The only thing I noticed that I can't replicate is this: you flipped between geography and geometry (your code from question):

SET @Geog = geography::STGeomFromText(@GeogTemp, 4326)

When I plopped that into my code I still got 0 for distance. So my only question, and perhaps you could post the T-SQL, is about your spatial index. I think the STDistance() calculation is going to use the index. So without seeing the index and knowing that you hopped between Geography and Geometry at least in this instance, I'd wonder if the odd results are in there since I can't replicate it with my above code.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top