在现代的软件开发中,地理编码是一个常见的需求,它允许开发者根据经纬度查询具体的街道地址。MapPoint提供了一种经济高效的本地化解决方案,相较于其他供应商如ThinkGeo或GeoFrameworks的高昂费用,MapPoint的价格更为亲民。本文将详细介绍如何使用MapPoint进行地理编码,包括下载安装、接口调用、代码实现以及算法优化。
MapPoint North America 2009的试用版可以从以下链接下载:
下载文件大小约为1.2GB,包含了北美地区的所有地理信息。MapPoint不包含.NET程序集,只能通过COM接口进行调用。如果对COM不太熟悉,可以通过Windows SDK中的tlbimp.exe工具生成.NET程序集。
COM(组件对象模型)是一种软件架构,用于在不同应用程序之间共享软件组件。如果需要更多关于COM的信息,可以访问以下链接:
要生成.NET程序集,可以使用以下命令:
"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\tlbimp.exe"
"C:\Program Files\Microsoft MapPoint 2009\MPNA83.tlb" /out:c:\Interop.MapPoint.dll
/namespace:Interop.MapPoint
生成的程序集Interop.MapPoint.dll将包含在代码下载中,也可以自己生成。
MapPoint提供了一个方法Map.ObjectsFromPoint(int x, int y),用于查询给定经纬度的地理对象。这个方法可以返回街道地址、国家、餐馆等MapPoint数据库中的任何信息。以下是C#代码实现:
private StreetAddress LookupStreetAddress(Location loc)
{
FindResults arr = _map.ObjectsFromPoint(_map.LocationToX(loc), _map.LocationToY(loc));
return arr.OfType<Location>().Where(o => o.StreetAddress != null).Select(o => o.StreetAddress).FirstOrDefault();
}
这段代码用于筛选出街道地址。如果位置不接触街道,很可能不会返回街道地址。MapPoint不包括查找最近街道地址的方法。
街道的宽度大约为0.0001度,因此算法使用0.0001度间隔的点网格。从最近的点开始,迭代调用LookupStreetAddress方法,直到找到匹配的地址。以下是C#代码实现:
public StreetAddress GetNearestAddress(double lat, double lon)
{
if (lat == double.NaN || lon == double.NaN)
{
return null;
}
// MapPoint需要被定位
_map.GoToLatLong(lat, lon, 1);
// 缩放级别似乎会影响返回结果...
// 尚未找出这里的模式
for (int i = 0; i < 10; i++)
{
_map.ZoomIn();
}
// 制作10个正方形,每个0.0001度间隔
StreetAddress addr;
for (int i = 0; i < 10; i++)
{
foreach (Location loc in GetPointsAround(lat, lon, i, 0.0001))
{
if ((addr = LookupStreetAddress(loc)) != null)
{
return addr;
}
}
}
return null;
}