gisempire100
捉鬼专家
捉鬼专家
  • 注册日期2004-08-13
  • 发帖数552
  • QQ
  • 铜币2462枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:2078回复:0

Bing Maps进阶系列二:使用GeocodeService进行地理位置检索

楼主#
更多 发布于:2010-03-02 20:54
<P>  在《<a href="http://www.cnblogs.com/beniao/archive/2010/02/07/1665218.html" target="_blank" ><FONT color=#78afd3>Bing Maps进阶系列一:初识Bing Maps地图服务</FONT></A>》里已经对GeocodeService的功能进行了简单的描述说明,本篇将会详细的介绍如何使用GeocodeService进行地理位置检索和反向检索的实现。</P>

<P><STRONG>一、添加GeocodeService的Web服务引用</STRONG></P>
<P>  地理编码服务(GeocodeService)是以WCF技术发布的一个Web服务,地图编码服务提供了以一个有效的物理地址在地图上匹配其对应的地图地址(既地理经度和纬度坐标)和以地理经度和纬度坐标进行反向匹配物理地址路径的功能。要使用该服务需添加该服务(<a href="http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc" target="_blank" ><FONT color=#78afd3>http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc</FONT></A>)的Web服务引用,如下图:</P>
<P>        <IMG src="http://images.cnblogs.com/cnblogs_com/beniao/BingMaps/GeocodeService.jpg" border=0></P>
<P>  </P>
<P>  从上图可以清晰的看出,该服务提供了两个方法,一个是根据地名检索所对应的地理经度和纬度坐标的,另一个方法实现反向检索地名的功能。通过添加Web服务引用向导IDE工具会为我们自动生成Web服务引用的代理对象等,这些知识点数据Web Service或WCF相关的,这里不详细介绍。</P>

<P><STRONG> 二、GeocodeService的结构分析</STRONG></P>
<P>  我们可以通过查看GeocodeService的客户端代理对象类图知道,客户端的调用只支持异步调用方式,如下图:</P>
<P>        <IMG src="http://images.cnblogs.com/cnblogs_com/beniao/BingMaps/GeocodeService0.jpg" border=0></P>

<P>  地点检索和反向地理坐标检索都只支持客户端异步调用,添加Web服务引用后可通过生成的WCF客户端配置文件查看到客户端调用WCF的相关配置,这里需要注意一点,自动生成的配置有两个服务端点的地址配置,需要人为将其中一个"custom"配置删除,或者在调用GeocodeService提供的方法的时候会出现异常。以下为正确的客户端配置:</P>
<DIV class=cnblogs_code>
<DIV><!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--><FONT face="Courier New"><configuration></FONT><BR><FONT face="Courier New">    </FONT><FONT face="Courier New"><system.serviceModel></FONT><BR><FONT face="Courier New">        </FONT><FONT face="Courier New"><bindings></FONT><BR><FONT face="Courier New">            </FONT><FONT face="Courier New"><basicHttpBinding></FONT><BR><FONT face="Courier New">                </FONT><FONT face="Courier New"><binding name="BasicHttpBinding_IGeocodeService" maxBufferSize="2147483647"</FONT><BR><FONT face="Courier New">                    maxReceivedMessageSize</FONT><FONT face="Courier New">="2147483647"></FONT><BR><FONT face="Courier New">                    </FONT><FONT face="Courier New"><security mode="None"></FONT><BR><FONT face="Courier New">                        </FONT><FONT face="Courier New"><transport></FONT><BR><FONT face="Courier New">                            </FONT><FONT face="Courier New"><extendedProtectionPolicy policyEnforcement="Never" /></FONT><BR><FONT face="Courier New">                        </FONT><FONT face="Courier New"></transport></FONT><BR><FONT face="Courier New">                    </FONT><FONT face="Courier New"></security></FONT><BR><FONT face="Courier New">                </FONT><FONT face="Courier New"></binding></FONT><BR><FONT face="Courier New">            </FONT><FONT face="Courier New"></basicHttpBinding></FONT><BR><FONT face="Courier New">        </FONT><FONT face="Courier New"></bindings></FONT><BR><FONT face="Courier New">        </FONT><FONT face="Courier New"><client></FONT><BR><FONT face="Courier New">            </FONT><FONT face="Courier New"><endpoint address="http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc"</FONT><BR><FONT face="Courier New">                binding</FONT><FONT face="Courier New">="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IGeocodeService"</FONT><BR><FONT face="Courier New">                contract</FONT><FONT face="Courier New">="GeocodeService.IGeocodeService" name="BasicHttpBinding_IGeocodeService" /></FONT><BR><FONT face="Courier New">        </FONT><FONT face="Courier New"></client></FONT><BR><FONT face="Courier New">    </FONT><FONT face="Courier New"></system.serviceModel></FONT><BR><FONT face="Courier New"></configuration></FONT><BR></DIV></DIV>


<P><STRONG>三、调用GeocodeService服务</STRONG></P>
<P>  首先将界面布局设计下,通过一个TextBox来输入地点名称,一个Button来发起服务调用请求并将检索过后的结果(地名对应的地理位置经度和纬度)显示在另外两个TextBox里。界面布局大致如下:</P>

<DIV><IMG src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><IMG src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">代码
<DIV>
<DIV><!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--><FONT face="Courier New"><Grid x:Name="LayoutRoot" Width="500" Height="400"></FONT><BR><FONT face="Courier New">    </FONT><FONT face="Courier New"><m:Map CredentialsProvider="AkzZURoD0H2Sle6Nq_DE7pm7F3xOc8S3CjDTGNWkz1EFlJJkcwDKT1KcNcmYVINU" x:Name="map"></m:Map></FONT><BR><FONT face="Courier New">    </FONT><FONT face="Courier New"><StackPanel VerticalAlignment="Top" HorizontalAlignment="Right" Background="Gray" Opacity="0.78" Orientation="Vertical" Margin="2,23,2,2"></FONT><BR><FONT face="Courier New">        </FONT><FONT face="Courier New"><StackPanel Orientation="Horizontal"></FONT><BR><FONT face="Courier New">            </FONT><FONT face="Courier New"><TextBlock Text="地名:" Margin="0,5,0,5"></TextBlock></FONT><BR><FONT face="Courier New">            </FONT><FONT face="Courier New"><TextBox x:Name="tbName" Width="233"></TextBox></FONT><BR><FONT face="Courier New">            </FONT><FONT face="Courier New"><Button x:Name="btnQuery" Content="搜索" Click="btnQuery_Click" Width="80" Height="30"></Button></FONT><BR><FONT face="Courier New">        </FONT><FONT face="Courier New"></StackPanel></FONT><BR><FONT face="Courier New">        </FONT><FONT face="Courier New"><StackPanel Orientation="Horizontal"></FONT><BR><FONT face="Courier New">            </FONT><FONT face="Courier New"><TextBlock Text="经度:"></TextBlock></FONT><BR><FONT face="Courier New">            </FONT><FONT face="Courier New"><TextBox x:Name="tbLongitude" Width="110"></TextBox></FONT><BR><FONT face="Courier New">            </FONT><FONT face="Courier New"><TextBlock Text="纬度:"></TextBlock></FONT><BR><FONT face="Courier New">            </FONT><FONT face="Courier New"><TextBox x:Name="tbLatitude" Width="110"></TextBox></FONT><BR><FONT face="Courier New">            </FONT><FONT face="Courier New"><Button x:Name="btnQueryReverse" Content="反向搜索" Click="btnQueryReverse_Click" Width="60" Height="30"></Button></FONT><BR><FONT face="Courier New">        </FONT><FONT face="Courier New"></StackPanel></FONT><BR><FONT face="Courier New">    </FONT><FONT face="Courier New"></StackPanel></FONT><BR><FONT face="Courier New"></Grid></FONT></DIV></DIV></DIV>

<P>        <IMG src="http://images.cnblogs.com/cnblogs_com/beniao/BingMaps/GeocodeService1.jpg" border=0></P>

<P>  有了上面的界面结构,接下来看看如何实现的根据地名检索所对应的地理位置经度和纬度,这就需要调用GeocodeService所提供的Geocode()方法了。</P>

<DIV><IMG src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><IMG src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">代码
<DIV>
<DIV><!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--><FONT face="Courier New">private void btnQuery_Click(object</FONT><FONT face="Courier New"> sender, RoutedEventArgs e)<BR>{<BR>    //实例化GeocodeService客户端对象</FONT><BR><FONT face="Courier New">    GeocodeServiceClient client = new</FONT><FONT face="Courier New"> GeocodeServiceClient();<BR>    client.GeocodeCompleted += new EventHandler<GeocodeCompletedEventArgs></FONT><FONT face="Courier New">(OnGeocodeCompleted);<BR><BR>    //创建一个Geocode检索请求</FONT><BR><FONT face="Courier New">    GeocodeRequest request = new</FONT><FONT face="Courier New"> GeocodeRequest();<BR>    request.Credentials = new</FONT><FONT face="Courier New"> Credentials();<BR>    request.Credentials.ApplicationId = "AkzZURoD0H2Sle6Nq_DE7pm7F3xOc8S3CjDTGNWkz1EFlJJkcwDKT1KcNcmYVINU"</FONT><FONT face="Courier New">;<BR><BR>    //设置检索条件</FONT><BR><FONT face="Courier New">    request.Query = this</FONT><FONT face="Courier New">.tbName.Text.Trim();<BR><BR>    //异步调用Geocode服务方法</FONT><BR><FONT face="Courier New">    client.GeocodeAsync(request);<BR>}</FONT></DIV></DIV></DIV>


<P>  通过指定的GeocodeCompleted的回调函数来完成调用服务请求的响应结果,这里我将请求的结果地理位置获取到后直接将地图定位到该位置。</P>

<DIV class=cnblogs_code>
<DIV><!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--><FONT face="Courier New">private void OnGeocodeCompleted(object</FONT><FONT face="Courier New"> sender, GeocodeCompletedEventArgs e)<BR>{<BR>    if (e.Error == null</FONT><FONT face="Courier New">)<BR>    {<BR>        GeocodeResponse response =</FONT><FONT face="Courier New"> e.Result;<BR>        double latitude = response.Results[0].Locations[0</FONT><FONT face="Courier New">].Latitude;<BR>        double longitude = response.Results[0].Locations[0</FONT><FONT face="Courier New">].Longitude;<BR><BR>        //显示检索地点的地理位置坐标经度和纬度</FONT><BR><FONT face="Courier New">        this.tbLatitude.Text =</FONT><FONT face="Courier New"> latitude.ToString();<BR>        this.tbLongitude.Text =</FONT><FONT face="Courier New"> longitude.ToString();<BR><BR>        //将地图定位到该地理位置并设置地图缩放级别到4级</FONT><BR><FONT face="Courier New">        map.SetView(new Location(latitude, longitude), 4</FONT><FONT face="Courier New">);<BR>    }<BR>}</FONT></DIV></DIV>


<P>        <IMG src="http://images.cnblogs.com/cnblogs_com/beniao/BingMaps/GeocodeService2.jpg" border=0>  </P>
<P>  </P>
<P>  如上图输入“china”进行检索,通过GeocodeService服务检索出了china所对应的地理位置的经度和纬度坐标,在程序中将地图定位到了该坐标的4级地图,最终效果就如上图所示。</P>

<P>  GeocodeService也提供了反向检索,既根据地理位置的经度和纬度进行反向检索地名,服务中的ReverseGeocode()方法便是用来实现这一功能的。</P>
<DIV class=cnblogs_code>
<DIV><!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--><FONT face="Courier New">private void btnQueryReverse_Click(object</FONT><FONT face="Courier New"> sender, RoutedEventArgs e)<BR>{<BR>    GeocodeServiceClient client = new</FONT><FONT face="Courier New"> GeocodeServiceClient();<BR>    client.ReverseGeocodeCompleted+=new EventHandler<ReverseGeocodeCompletedEventArgs></FONT><FONT face="Courier New">(OnReverseGeocodeCompleted);<BR><BR>    ReverseGeocodeRequest request = new</FONT><FONT face="Courier New"> ReverseGeocodeRequest();<BR>    request.Credentials = new</FONT><FONT face="Courier New"> Credentials();<BR>    request.Credentials.ApplicationId = "AkzZURoD0H2Sle6Nq_DE7pm7F3xOc8S3CjDTGNWkz1EFlJJkcwDKT1KcNcmYVINU"</FONT><FONT face="Courier New">;<BR>    request.Location = new Location(36.5540000796318,104.055999666452</FONT><FONT face="Courier New">);<BR>    client.ReverseGeocodeAsync(request);<BR>}<BR><BR>private void OnReverseGeocodeCompleted(object</FONT><FONT face="Courier New"> sender, ReverseGeocodeCompletedEventArgs e)<BR>{<BR>    if (e.Error == null</FONT><FONT face="Courier New">)<BR>    {<BR>        if (e.Result.Results.Count > 0</FONT><FONT face="Courier New">)<BR>        {<BR>            GeocodeResponse response =</FONT><FONT face="Courier New"> e.Result;<BR>            this.tbName.Text = response.Results[0</FONT><FONT face="Courier New">].DisplayName;<BR>        }<BR>        else</FONT><BR><FONT face="Courier New">            MessageBox.Show(</FONT><FONT face="Courier New">"没有检索到该地理位置所对应的地点"</FONT><FONT face="Courier New">);<BR>    }<BR>}</FONT></DIV></DIV>

<P>  <STRONG style="COLOR: red">PS:貌似Bing Maps的GeocodeService有问题,难道是MS的数据有问题??通过地名检索出的地理位置坐标反向检索回去居然没有数据返回。 </STRONG></P>

<P>  其实说简单点GeocodeService所提供的两个方法就是一个实现根据地名检索对应的地理位置经度和纬度坐标,一个实现根据地理位置的经度和纬度坐标反向检索地名。这在外网GIS应用中是非常有用的,企业内网的业务支撑系统这一功能到不是很有用,通常企业业务系统的业务扩展开发中应用到地图最多的就是地图的呈现,比如将一些网络组织图以GIS的形式呈现出来,让人看着比较直观、清晰,其他扩展全的根据业务需求开发。</P>

<P>  想了解更多关于Bing Maps地图服务的知识,请查询:</P>
<P>  MSDN:<a href="http://msdn.microsoft.com/en-us/library/cc980922.aspx" target="_blank" ><FONT color=#78afd3>http://msdn.microsoft.com/en-us/library/cc980922.aspx</FONT></A> </P>
<P>  Bing Maps开发站:<a href="http://www.microsoft.com/maps/developers/" target="_blank" ><FONT color=#78afd3>http://www.microsoft.com/maps/developers/</FONT></A></P>
<P>  Bing Maps开发SDK:<a href="http://msdn.microsoft.com/en-us/library/dd877180.aspx" target="_blank" ><FONT color=#78afd3>http://msdn.microsoft.com/en-us/library/dd877180.aspx</FONT></A></P>
喜欢0 评分0
A friend is never known till a man has need. ...CL
游客

返回顶部