受到Ben Fry的zipdecode小程序的启发,决定编写一个小型的美国邮政编码实用工具,该工具允许通过邮政编码、城市/州或全部三个来查找美国的位置。由于数据已经以纬度/经度对的形式存在于数据库中,增加了计算两个点之间距离的功能,并找到原始位置X英里半径内的所有其他邮政编码。
MS Access数据库包含以下字段:
查找操作是使用OleDb类进行的简单的数据库查询。
为了计算两点之间的距离,使用了Haversine公式,该公式可以在Ask Dr. Math网站上找到。
数据库中的大多数邮政编码都包含纬度/经度坐标。为了使SQL查询尽可能简单,使用了2Rx2R大小的正方形(其中R是圆的半径)来包含搜索区域,如下图所示。
不幸的是,这会导致搜索区域比实际需要的大约22%大,但这些“异常值”在返回给调用应用程序之前会在客户端过滤掉。本可以添加一个存储过程来执行距离计算,但不想以任何方式修改数据库。这样,如果作者决定更新数据,(希望)所有这个库的用户都只需要用新的数据库文件替换旧的数据库文件。
现在,使用这种近似方法,SQL查询变得非常简单:
SELECT * FROM ZIP_CODES WHERE LATITUDE >= <Southern Latitude Line> AND LATITUDE <= <Northern Latitude Line> AND LONGITUDE >= <Western Longitude Line> AND LONGITUDE <= <Eastern Longitude Line>
为了计算北部/南部纬度和西部/东部经度线,再次求助于Ask Dr. Math。
使用代码非常简单。
下载邮政编码数据库(参见文章顶部的链接)。
在VS.NET中编译ZipCodeUtil库。
将对新DLL的引用(SagaraSoftware.ZipCodeUtil.dll)添加到应用程序中。
在应用程序的config文件中添加以下appSettings(如果不存在config文件,则需要添加一个):
<add key="ZipCodeProviderType" value="Access" />
<add key="ZipCodeConnString" value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Example\Path\To\Database\zipbase.mdb" />
添加代码以使用邮政编码实用工具库。
以下是示例应用程序的示例代码:
// 通过邮政编码查找位置
Location location = ZipCodeUtil.LookupByZipCode("93275");
if (null != location)
Console.WriteLine(location.ToString());
// 通过城市/州查找位置
Location[] locs = ZipCodeUtil.LookupByCityState("Tulare", "CA");
if (null != locs && locs.Length > 0)
{
foreach (Location loc in locs)
{
Console.WriteLine(loc.ToString());
}
}
// 通过城市/州/邮政编码查找位置
location = ZipCodeUtil.LookupByCityStateZip("Tulare", "CA", "93275");
if (null != location)
Console.WriteLine(location.ToString());
// 两个位置之间的距离
Location sf = ZipCodeUtil.LookupByZipCode("94175");
Location la = ZipCodeUtil.LookupByZipCode("90185");
Double dDistance = sf.DistanceFrom(la);
Console.WriteLine("{0} is {1} miles from {2}", sf.City, dDistance, la.City);
// 特定位置X英里半径内的其他位置
locs = sf.LocationsWithinRadius(5.0);
if (null != locs && locs.Length > 0)
{
foreach (Location loc in locs)
{
Console.WriteLine(loc.ToString());
}
}
注意:为了运行示例应用程序,首先需要下载数据库并修改config文件以指向硬盘上的数据库。
这个库依赖于一个免费数据库的数据,看起来这个数据库自2001年9月以来就没有更新过。不能保证这些数据的准确性。如果计划在生产环境中使用它,可能想要投资一个由制造商保证并定期更新的商业邮政编码数据库。