简体   繁体   中英

Match location between coordinates

I have a static table with location name, latitude, longitude, tolerance. for example:

NY, 40.7128, 74.0060, 100 x 50

There are 600 records at this time, the table will grow slowly.

Also there is a dynamic table with MAC address, and coordinates that change every few minutes:

AC233F271FE4, 40.7228, 74.0110

With 4000 records

I want to count how many MAC addresses are within tolerance for each location. Accuracy for earth being a sphere/ellipsoid is not important.

At first I was going to calculate the distance between two points in SQL query when I want to display count, but now I am thinking if it is better to calculate this in php when I update coordinates for the MAC address. I could add a location column, calculate closest point, update MACs lat/long/location every few minutes. Then SQL query for displaying count would be a simple SELECT COUNT GROUP.

The main question is - at what stage is it better to determine location within tolerance?

Second question would be - do I use geography function of SQL (I have read that it is slow) or Haversine formula and how to implement tolerance into distance between two points?

PS been goggling, current plan is to make a function that will find nearest location name for given coordinates and make a computed column in the dynamic table which will call the function. In my mind it will work like this:

receive MAC address, lat, long => update lat, long where MAC the same as received => computed column runs the function to get the name for updated coordinates => in front end I can hopefully display MAC + location name.

This looks overcomplicated and confusing to me, would be educational to find a better way.

This feels like a great use of the geospatial capabilities in SQL Server. And you can (mostly) do it with what you have, but with some augmentations for performance. Here's what I'd suggest.

Add a column to your static locations table that represents a polygon for your tolerance. I'm not sure what "100 x 50" means (a bounding box that's 100m x 50m? if so, what's the orientation?). Either way, presumably you can derive a polygon given the lat/long and the tolerance. Persist that in a column of type geography . Put an index on this column.

Similarly, add a column to your dynamic table. In some ways, this is easier than the above as you can just make it a computed column ( persisted if you can) that has the definition of newColumn as geography::Point(Latitude, Longitude, 4236) . Index this column as well.

Finally, you have what you need. You can now run a geospatial query like so:

select *
from dbo.dynamicTable as d
join dbo.staticTable as s
   on s.BoundingBox.STContains(d.Point) = 1;

The indexing on the the two tables is what makes this reasonable. Otherwise, it has to do a Cartesian join between the two. That's unlikely to perform well, regardless of the specifics.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM