Ето нещо, което написах преди доста време, което може да ви насочи в правилната посока.
Докато поискахте VB.Net, това, от което наистина се нуждаете, е заявка, която прави "Great Circle Разстояние " изчисление за определяне на разстоянието между две точки, идентифицирани по географска ширина и дължина.
И така, правейки следните предположения:
- Данните за пощенския ви код са в една таблица.
- Спомената таблица има атрибути за ширина и дължина, които са приблизителният центроид на пощенския код
Можете да използвате LINQ към SQL заявка, която произвежда желания набор от резултати, като използвате нещо подобно
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
Изглежда сложно, защото е така. Тук в SO има много по-умни хора, които могат да обяснят алгоритъма. Просто внедрих това от някакъв SQL код, който намерих в интернет - не мога да си спомня откъде. Търсене в Google трябва да ви отведе до там.
Първата заявка (zipQry) връща ширината и дължината на началния пощенски код в градуси и радиани. След това тези резултати се използват за изпълнение на втората заявка.
Първата част от клаузата WHERE във втората заявка:
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) _
Просто стесних списъка с пощенски кодове, които трябва да бъдат разгледани, правейки заявката да се изпълнява много по-бързо. Той добавя произволно количество към ширината и дължината, така че да не проверявате всички пощенски кодове в Охайо, когато търсите радиус в Калифорния. Всичко останало е част от гореспоменатия алгоритъм за голямо кръгово разстояние.
Това вероятно можеше да бъде направено с една заявка за по-голяма ефективност, но имах нужда от това по този начин навремето, причините сега бяха изгубени за мен.