假如你还不了解微软的MapPoint相关产品和服务,建议去看一下MSDN上的《MapPoint 2004 与 MapPoint Web 服务,该使用哪一个》这篇文章,这里为了给读者一个初步印象,引用其中的一段话。本文介绍的是如何结合.NET开发环境开发基于MapPoint 2004的应用。
MSDN中关于MapPoint 2004的叙述:
MapPoint 2004 是一个桌面地图信息工具,它可以提供奇妙和丰富的用户体验,具有专题图形、区域治理、路线优化和人口统计数据等功能。所有必要的数据都安装在本地,因此不需要网络连接。对于 MapPoint 2004,您可以方便地使用多种常见格式(Microsoft Excel、Microsoft access、开放数据库连接 (ODBC) 等)导入数据,并使用专题图形(如图 1 所示的饼形图)以图形方式显示这些信息。
MapPoint 2004
使用 MapPoint,您可以采用若干种开发方式:
·创建 COM 外接程序以扩展 MapPoint 的功能。
·使用 MapPoint 附带的 ActiveX 控件将图形嵌入到您自己的 Microsoft Visual Basic 应用程序中。
·在其他应用程序(例如,Microsoft Word 或 Excel)中使用 Microsoft Visual Basic for applications 自动实现 MapPoint 和其他应用程序之间的连接。
·使用 Visual Basic(或任何其他与 COM 兼容的编程语言)创建自动执行 MapPoint 的可执行文件或动态链接库 (DLL)。
以上内容节选自MSDN。
正文
简介
MapPoint 2004给程序员提供了丰富的对象模型来开发强大的商业化的智能地图定位应用。不过它是基于COM的思想设计的,所以假如你使用.NET Framework来编写应用程序的话,你必须结合使用COM的类库。
本文通过开发一个地址查找程序,讲解了如何一步步是使用.NET Framework来开发基于MapPoint 2004的应用,同时也介绍了开发时需要注重的一些地方和解决方法。
使用MapPoint2004编程
就像前文所说,你必须结合使用MapPoint COM库,才能使用微软的.NET Framework进行编程。假如你使用Visual Studio .NET,你可以在创建新工程之后,选择PRoject树型列表项中的Add Reference选项来添加:
MapPoint 2004
当看到Add Reference对话框窗口出现时,选择COM的Tab页,并且从列表中选择Microsoft MapPoint 11.0 Object Library ( )来添加一个对MapPoint2004类型库的引用,如下:
MapPoint 2004
下面,开始编写C#程序,首先需要引进MapPoint 2004命名空间:
//Add MapPoint namespace
using MapPoint;
引入命名空间之后,使用起MapPoint类型就非常方便了。
下一步是创建一个MapPoint 2004的应用对象:
//Define an application instance
ApplicationClass app = null;
//Create an application class instance
app = new ApplicationClass();
MapPoint 2004应用实例(application instance)提供了一个活动的地图实例来完成面向地图定位的人物,这个例子里我将使用这个实例来查找一个地址。
//Now get the location
FindResults frs = app.ActiveMap.FindAddressResults(" ", " ", string.Empty, "WA", "", null);
你可能已经注重到了,FindAddressResults方法返回的FindResults是一个查询到的地点的集合,有两种方法可以从FindResults实例中获取地点的列表:
1. 获取一个enumerator并且枚举整个地点的列表。假如你想提供符合条件的地址的列表这样的方式比较有用。
//Get an enumerator
IEnumerator ienum = frs.GetEnumerator();
//Loop through the enumerator
while(ienum.MoveNext())
{
Location loc = ienum.Current as Location;
if(loc != null)
{
//process the location
string s = loc.StreetAddress.Value;
}
}
2. 使用get/set访问方法来用索引获得地点。这个方法在你需要获得某个非凡项但又不想循环整个列表时比较有用。如查找第一个相符合的记录:
//Define an index
object index = 1;
//Access the location item using the accessor method
location = frs.get_Item(ref index) as Location;
这里必须使用get_Item和set_Item方法进行按照索引对记录进行的操作。
最后当你做完上述的操作之后,你必须记住要关闭应用程序对象,来确保MapPoint 2004的应用程序实例不会保留在内存中,可以使用如下代码:
//Quit the application
if(app != null)
app.Quit();
app = null;
以下代码完整的列出了一个根据上文的方法,查找地址的函数:
//Define an application instance
ApplicationClass app = null;
//Define a location instance
Location location = null;
//Define a FindResults instance
FindResults frs = null;
try
{
//Create an application class
app = new ApplicationClass();
//Now get the location
frs = app.ActiveMap.FindAddressResults(" ", " ", string.Empty, "WA", "", null);
//Check if the find query is sUCcesfull
if(frs != null && frs.Count 0)
{
object index = 1;
location = frs.get_Item(ref index) as Location;
//Male the MapPoint 2004 application visible
//and go to that location
app.Visible = true;
location.GoTo();
//Do your processing with the location
MessageBox.Show(location.StreetAddress.Value);
}
}
catch(Exception ex)
{
string message = ex.Message;
}
finally
{
if(app != null)
{
try
{
app.Quit();
}
catch
{
//This means your app has already quit!
}
finally
{
app = null;
}
}
}
需要注重的地方
使用可选参数的方法进行编程
当你使用有可选参数的方法时,假如你没有传递有效的参数,你必须使用缺失类型System.Reflection.Missing.Value。比如DisplayDataMap函数如下:
DisplayDataMap([DataMapType], [DataField], [ShowDataBy], [CombineDataBy], [DataRangeType], [DataRangeOrder], [ColorScheme], [DataRangeCount], [ArrayOfCustomValues], [ArrayOfCustomNames], [DivideByField], [ArrayOfDataFieldLabels], [ArrayOfPushpinSymbols])
可以看到所有的参数都是可选参数,这里就必须用到.NET Framework里的缺失类型了。下面的代码展示了如何使用:
//Define a missing value type
object missing = System.Reflection.Missing.Value;
//Use the missing type for optional parameters that are not needed
DataMap mydatamap =
mydataset.DisplayDataMap(GeoDataMapType.geoDataMapTypeShadedArea,
field, GeoShowDataBy.geoShowByRegion1,
GeoCombineDataBy.geoCombineByDefault,
GeoDataRangeType.geoRangeTypeDiscreteLogRanges,
GeoDataRangeOrder.geoRangeOrderDefault, 15, 3,
missing, missing, missing, missing, missing);