Berikut adalah sesuatu yang saya tulis beberapa waktu lalu yang mungkin mengarahkan Anda ke arah yang benar.
Saat Anda meminta VB.Net, yang benar-benar Anda butuhkan adalah kueri yang melakukan "Lingkaran Hebat Jarak " perhitungan untuk menentukan jarak antara dua titik yang diidentifikasi oleh garis lintang dan garis bujur.
Jadi, buat asumsi berikut:
- Data kode pos Anda ada dalam satu tabel.
- Tabel tersebut memiliki atribut untuk lintang dan bujur yang merupakan perkiraan centroid dari kode pos
Anda dapat menggunakan kueri LINQ ke SQL yang menghasilkan kumpulan hasil yang diinginkan menggunakan sesuatu seperti ini
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
Kelihatannya rumit, karena memang begitu. Ada orang yang jauh lebih pintar di sini di SO yang dapat menjelaskan algoritme. Saya hanya menerapkan ini dari beberapa kode SQL yang saya temukan di internet - saya tidak ingat dari mana. Penelusuran Google akan membawa Anda ke sana.
Kueri pertama (zipQry) mengembalikan lat dan lon dari kode pos awal dalam derajat dan radian. Hasil ini kemudian digunakan untuk mengeksekusi kueri kedua.
Bagian pertama dari klausa WHERE dalam kueri kedua:
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) _
Hanya mempersempit daftar kode pos yang akan diperiksa, membuat kueri berjalan lebih cepat. Ini menambahkan jumlah yang sewenang-wenang ke lat dan lon sehingga Anda tidak memeriksa semua kode pos di Ohio saat mencari radius di California. Sisanya adalah bagian dari algoritma Great Circle Distance yang disebutkan di atas.
Ini mungkin bisa dilakukan dalam satu permintaan untuk efisiensi yang lebih besar, tetapi saya membutuhkannya dengan cara ini pada saat itu, alasannya sekarang hilang dari saya.