Đây là điều mà tôi đã viết khá lâu có thể giúp bạn đi đúng hướng.
Trong khi bạn yêu cầu VB.Net, những gì bạn thực sự cần là một truy vấn thực hiện " Vòng kết nối tuyệt vời Khoảng cách "tính toán để xác định khoảng cách giữa hai điểm được xác định theo vĩ độ và kinh độ.
Vì vậy, đưa ra các giả định sau:
- Dữ liệu mã zip của bạn nằm trong một bảng.
- Bảng đã nói có các thuộc tính cho vĩ độ và kinh độ là tâm gần đúng của mã zip
Bạn có thể sử dụng truy vấn LINQ to SQL để tạo ra tập kết quả mong muốn bằng cách sử dụng thứ gì đó như thế này
Const EARTH_RADIUS As Single = 3956.0883313286095
Dim radCvtFactor As Single = Math.PI / 180
Dim zipCodeRadius As Integer = <Your Radius Value>
Dim zipQry = From zc In db.ZipCodes
Where zc.Zip = "<Your Zip Code>" _
Select zc.Latitude,
zc.Longitude,
ZipLatRads = RadCvtFactor * zc.Latitude,
ZipLonRads = RadCvtFactor * zc.Longitude
Dim zipRslt = zipQry.SingleOrDefault()
If zipRslt IsNot Nothing Then
Dim zcQry = From zc In db.ZipCodes _
Where zc.Latitude >= (zipRslt.Latitude - 0.5) And zc.Latitude <= (zipRslt.Latitude + 0.5) _
And zc.Longitude >= (zipRslt.Longitude - 0.5) And (zc.Longitude <= zipRslt.Longitude + 0.5) _
And Math.Abs(EARTH_RADIUS * (2 * Math.Atan2(Math.Sqrt(Math.Pow(Math.Sin(((RadCvtFactor * zc.Latitude) - zipRslt.ZipLatRads) / 2), 2) + _
Math.Cos(zipRslt.ZipLatRads) * Math.Cos(RadCvtFactor * zc.Latitude) * _
Math.Pow(Math.Sin(((RadCvtFactor * zc.Longitude) - zipRslt.ZipLonRads) / 2), 2)), _
Math.Sqrt(1 - Math.Pow(Math.Sin(((RadCvtFactor * zc.Latitude) - zipRslt.ZipLatRads) / 2), 2) + _
Math.Cos(zipRslt.ZipLatRads) * Math.Cos(RadCvtFactor * zc.Latitude) * _
Math.Pow(Math.Sin((RadCvtFactor * zc.Longitude) / 2), 2))))) <= zipCodeRadius _
Select zc
End If
Nó trông phức tạp, bởi vì nó là. Có rất nhiều người thông minh hơn ở đây trên SO có thể giải thích thuật toán. Tôi chỉ thực hiện điều này từ một số mã SQL mà tôi tìm thấy trên internet - tôi không thể nhớ lại từ đâu. Tìm kiếm của Google sẽ đưa bạn đến đó.
Truy vấn đầu tiên (zipQry) trả về vĩ độ và vĩ độ của mã zip bắt đầu theo cả độ và radian. Sau đó, các kết quả này được sử dụng để thực hiện truy vấn thứ hai.
Phần đầu tiên của mệnh đề WHERE trong truy vấn thứ hai:
Where zc.Latitude >= (zipRslt.Latitude - 0.5) And zc.Latitude <= (zipRslt.Latitude + 0.5) _
And zc.Longitude >= (zipRslt.Longitude - 0.5) And (zc.Longitude <= zipRslt.Longitude + 0.5) _
Chỉ cần thu hẹp danh sách mã zip cần kiểm tra, làm cho truy vấn chạy nhanh hơn nhiều. Nó thêm một số lượng tùy ý vào vĩ độ và kinh độ để bạn không phải kiểm tra tất cả các mã zip ở Ohio khi tìm kiếm bán kính ở California. Phần còn lại là tất cả các phần của thuật toán Khoảng cách vòng tròn lớn nói trên.
Điều này có thể được thực hiện trong một truy vấn để đạt hiệu quả cao hơn, nhưng tôi cần nó theo cách này vào thời điểm đó, lý do bây giờ tôi đã thua.