美国邮政编码查询工具开发

受到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。

重要类

  • ZipCodeUtil:ZipCodeUtil类提供了通过邮政编码查找城市/州,或通过城市/州查找邮政编码的方法。
  • Location:Location代表一个城市、州、邮政编码、县、纬度、经度和邮政编码类别。这恰好对应于ZIP_CODES表的列。
  • LocationInRadius:派生自Location,增加了DistanceToCenter属性。
  • Distance:Distance类的静态GetDistance方法接受两个Location对象,并使用它们的纬度和经度来确定它们之间的距离。
  • Radius:提供一个静态方法,接受一个Location和一个半径(以英里为单位),并返回在该半径内的所有LocationInRadius。

使用代码

使用代码非常简单。

下载邮政编码数据库(参见文章顶部的链接)。

在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月以来就没有更新过。不能保证这些数据的准确性。如果计划在生产环境中使用它,可能想要投资一个由制造商保证并定期更新的商业邮政编码数据库。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485