Zde je něco, co jsem napsal před chvílí, co vás může navést správným směrem.
Zatímco jste se ptali na VB.Net, skutečně potřebujete dotaz, který udělá „Velký kruh Vzdálenost " výpočet k určení vzdálenosti mezi dvěma body určenými zeměpisnou šířkou a délkou.
Takže za následujících předpokladů:
- Údaje o PSČ jsou v jediné tabulce.
- Tabulka má atributy pro zeměpisnou šířku a délku, které jsou přibližným těžištěm PSČ
Můžete použít dotaz LINQ to SQL, který vytvoří požadovanou sadu výsledků pomocí něčeho takového
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
Vypadá to složitě, protože to tak je. Na SO jsou mnohem chytřejší lidé, kteří dokážou vysvětlit algoritmus. Implementoval jsem to pouze z nějakého kódu SQL, který jsem našel na internetu - nemohu si vzpomenout odkud. Vyhledávání Google by vás tam mělo dostat.
První dotaz (zipQry) vrací zeměpisnou šířku a délku počátečního PSČ ve stupních i radiánech. Tyto výsledky se pak použijí k provedení druhého dotazu.
První část klauzule WHERE ve druhém dotazu:
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) _
Právě jsme zúžili seznam PSČ, která mají být prozkoumána, takže dotaz běží mnohem rychleji. Přidává libovolnou částku k zeměpisné šířce a délce, takže při hledání okruhu v Kalifornii nekontrolujete všechna PSČ v Ohiu. Zbytek je součástí výše zmíněného algoritmu Great Circle Distance.
Pravděpodobně by to bylo možné provést v rámci jednoho dotazu pro větší efektivitu, ale v té době jsem to tímto způsobem potřeboval, důvody mi teď zmizely.