Bing Maps中使用Google全球本地化搜索服务详解

简介:

 微软Bing Maps推出了四大在线地图服务,以满足地理位置、路由、影像以及搜索等常用GIS开发需求,去年我写的《Bing Maps开发系列博文》中介绍了这四种公关服务的特点和基本使用方法。但是很多朋友以及本人在使用这四种服务的时候发现了,使用微软提供的服务实现本地化搜索对于亚洲地区的支持不够友好,这一点比起Google还存在很大的距离。不过不用灰心,虽然Google没有像微软那样直接提供公共服务接口供开发者调用,我们还是可以通过某些手段调用Google的全球本地化搜索服务,实现功能完善的本地搜索。

 

  我们可以通过Google Maps的在线示例查看我们将要实现的功能,只不过是将Google Maps API开发的地图端给移植到了Silverlight版本的Bing Maps中。    

        

 

  首先,我们通过HttpWatch来分析此示例所发起的http请求,可获取到全球本地化搜索服务的请求路径和相关的参数,下图为HttpWatch请求跟踪截图:

    

 

  由此,我们可以得到Google全球本地化搜索服务的地址,通过分析并可得到所请求的URL地址中的q即为所查询的地点名,详细如下URL:

http://www.google.com/uds/GlocalSearch?callback=google.search.LocalSearch.RawCompletion &context =7 &rsz =small &hl =zh-CN &gss =.com &sig =3268c2f995b8fbd3048de51c45033694 & q =%E5%8C%97%E4%BA%AC &near =(39.904214%2C%20116.40741300000002) &key =ABQIAAAAjU0EJWnWPMv7oQ-jjS7dYxQ82LsCgTSsdpNEnBsExtoeJv4cdBSUkiLH6ntmAr_5O4EfjDwOa0oZBQ &v =1.0 &nocache =1298294307822

 

  实际上很多的很多的参数我们都是可以省略的,只要保持关键的请求参数同样不影响请求且能够正确的返回我们需要的结果,因此,可以对上面长段的URL地址进行瘦身,得到如下的简化版全球本地化请求地址:

http://www.google.com/uds/GlocalSearch?q=%E5%8C%97%E4%BA%AC &key =ABQIAAAAjU0EJWnWPMv7oQ-jjS7dYxQ82LsCgTSsdpNEnBsExtoeJv4cdBSUkiLH6ntmAr_5O4EfjDwOa0oZBQ &v =1.0 &nocache =1298223400032

 

  在实际使用中指需要将q参数替换为我们要搜索的地点名就可以了,因此可以将上面的URL地址改写为如下字符串格式,方便程序中灵活的设值并调用该服务。

http://www.google.com/uds/GlocalSearch? q={0} &key =ABQIAAAAjU0EJWnWPMv7oQ-jjS7dYxQ82LsCgTSsdpNEnBsExtoeJv4cdBSUkiLH6ntmAr_5O4EfjDwOa0oZBQ &v =1.0 &nocache =1298223400032

 

   做过Silverlight开发的朋友都知道,在Silverlight中发起HTTP请求会受到跨域安全性的限制,如果所请求的服务器没有配置Silverlight的安全访问策略,Silverlight所发起的HTTP请求将会产生“System.Security.SecurityException ---> System.Security.SecurityException: 安全性错误。”的异常。因此要想在Silverlight中直接向此地址发起HTTP请求是行不通的了,我们需要通过别的间接方式去实现访问该地址来达到我们的目的,实际上要做的工作就是避开HTTP访问安全性限制。

 

  通常情况下我们有两种方式可以避免HTTP请求安全访问的限制,既采用AJAX技术异步请求和在服务器端实现HTTP的同步或异步请求。接下来将要介绍的就是通过服务器端实现HTTP请求,然后将结果中转到Silverlight客户端。这里我们需要开发一个HTTP接口供Silverlight调用。

///   <summary>
///  接口实现向Google全球本地化搜索服务发起HTTP请求,然后将结果处理后返回到客户端。
///   </summary>
public   class  GoogleHandler : IHttpHandler
{
    
private   string  url  =   @" http://www.google.com/uds/GlocalSearch?q={0}&key=ABQIAAAAjU0EJWnWPMv7oQ-jjS7dYxQ82LsCgTSsdpNEnBsExtoeJv4cdBSUkiLH6ntmAr_5O4EfjDwOa0oZBQ&v=1.0&nocache=1298223400032 " ;

    
public   void  ProcessRequest(HttpContext context)
    {
        context.Response.ContentType 
=   " text/plain " ;

        
if  (context.Request.QueryString[ " q " ==   null return ;

        
string  q  =  HttpUtility.UrlEncode(context.Request.QueryString[ " q " ]).ToUpper();
        url 
=   string .Format(url, q);

        WebClient client 
=   new  WebClient();

        
string  result  =  client.DownloadString( new  Uri(url));
        result 
=  result.Substring(result.IndexOf( " GsearchResultClass " ) - 2 );
        result 
=  result.Substring( 0 , result.IndexOf( " cursor " -   3 );
            
        context.Response.Write(result);
    }

    
public   bool  IsReusable
    {
        
get
        {
            
return   false ;
        }
    }
}

 

  编译以上请求Google全球本地化搜索服务接口的HTTP接口后可以得到这样的地址:“http://localhost:28768/GoogleHandler.ashx?q={0}”,在Silverlight中就通过向自己编写的这个接口发起HTTP请求,然后此接口负责请求Google接口,实现本地上搜索功能。通过上面接口的代码可知,我特意将请求的结果进行了相应的处理,以便客户端能够更加方面的使用接口所返回的数据,其接口返回的数据为JSON格式字符串,通过上面的处理将一些不必要的数据字段给干掉了,剩下的数据我们可以定义如下实体对象。

public   class  QueryResult
{
    
public   string  GsearchResultClass {  get set ; }
    
public   string  listingType {  get set ; }
    
public   string  lat {  get set ; }
    
public   string  lng {  get set ; }
    
public   string  accuracy {  get set ; }
    
public   string  title {  get set ; }
    
public   string  titleNoFormatting {  get set ; }
    
public   string  ddUrl {  get set ; }
    
public   string  ddUrlToHere {  get set ; }
    
public   string  ddUrlFromHere {  get set ; }
    
public   string  streetAddress {  get set ; }
    
public   string  city {  get set ; }
    
public   string  region {  get set ; }
    
public   string  country {  get set ; }
    
public   string  staticMapUrl {  get set ; }
    
public   string  url {  get set ; }
    
public   string  postalCode {  get set ; }
    
public   string  maxAge {  get set ; }
    
public   string  addressLines {  get set ; }
}

 

  有了上面的实体对象,当得到请求所返回的JSON字符串后就可以通过JSON序列化既可实现JSON字符串到对象的转换,因此我们还需要定义一个JSON序列号方法以便开发中使用。

public   sealed   class  JsonHelper < T >
{
    
///   <summary>
    
///  解析JSON格式字符串为指定的对象数据结构
    
///   </summary>
    
///   <param name="jsonString"> JSON字符串 </param>
    
///   <returns> T </returns>
     public   static  T ResolveObject( string  jsonString)
    {
        DataContractJsonSerializer ds 
=   new  DataContractJsonSerializer( typeof (T));
        MemoryStream ms 
=   new  MemoryStream(Encoding.Unicode.GetBytes(jsonString));
        T t 
=  (T)ds.ReadObject(ms);

        
return  t;
    }
}

 

  到处,就只剩下最后一步了,在Bing Maps(Silverlight)中将要搜索的地名通过自己开发的接口传递给Google全球本地化搜索服务接口。下图为示例程序解决方案截图:

        

  在示例程序中提供一个文本输入空间实现地名录入,通过按钮发起请求,然后将部分结果呈现在地图指定的UI面板上,返回的数据中由于带有地理坐标(经度,纬度),还可以使用此地理坐标进行地图定位,每当成功搜索到某地名后就将地图定位带该地名所在的位置。

< StackPanel  Margin ="2"  Width ="160"  Height ="140"  VerticalAlignment ="Top"  HorizontalAlignment ="Right" >
    
< TextBox  Name ="tbAddress"  Margin ="5"  Height ="23" ></ TextBox >
    
< Button  Content ="搜索"  x:Name ="btnQuery"  Width ="70"  Height ="30"  Click ="btnQuery_Click" ></ Button >
    
< Border  CornerRadius ="8"  BorderThickness ="1"  Height ="70"  Margin ="3"  x:Name ="queryResult" >
        
< StackPanel >
        
< StackPanel.Background >
            
< LinearGradientBrush  EndPoint ="0.5,1"  StartPoint ="0.5,0" >
                
< GradientStop  Color ="#FF305867"  Offset ="0"   />
                
< GradientStop  Color ="#FFABE2F7"  Offset ="1"   />
            
</ LinearGradientBrush >
        
</ StackPanel.Background >
        
< TextBlock  Text =" {Binding city} "  Height ="23"  Margin ="0,8,0,0" ></ TextBlock >
            
< StackPanel  Orientation ="Horizontal" >
                
< TextBlock  Text =" {Binding lng} "  Height ="30"  Width ="Auto" ></ TextBlock >
                
< TextBlock  Text =","  Height ="30"  Width ="Auto" ></ TextBlock >
                
< TextBlock  Text =" {Binding lat} "  Height ="30"  Width ="Auto" ></ TextBlock >
            
</ StackPanel >
        
</ StackPanel >
    
</ Border >
    
< StackPanel.Background >
        
< LinearGradientBrush  EndPoint ="0.5,1"  StartPoint ="0.5,0" >
            
< GradientStop  Color ="#cccccc"  Offset ="0"   />
            
< GradientStop  Color ="White"  Offset ="1"   />
        
</ LinearGradientBrush >
    
</ StackPanel.Background >
</ StackPanel >

 

  在Silverlight中可以通过WebClient发起简单的HTTP请求,如下代码块所示:

///   <summary>
///  请求Google全球本地化搜索服务的接口地址
///   </summary>
private   string  service  =   " http://localhost:28768/GoogleHandler.ashx?q={0} " ;

private   void  btnQuery_Click( object  sender, RoutedEventArgs e)
{
    var address 
=   this .tbAddress.Text.Trim();
    var client 
=   new  WebClient();
    client.DownloadStringCompleted 
+=  client_DownloadStringCompleted;
    client.DownloadStringAsync(
new  Uri( string .Format(service, address), UriKind.Absolute));
}

private   void  client_DownloadStringCompleted( object  sender, DownloadStringCompletedEventArgs e)
{
    
if  (e.Error  ==   null )
    {
        
try
        {
            QueryResult result 
=  JsonHelper < QueryResult > .ResolveObject(e.Result);

            
this .queryResult.DataContext  =  result;

            
this .map.Center  =   new  Location( double .Parse(result.lat),  double .Parse(result.lng));
        }
        
catch  (Exception)
        {
        }
    }
}

 

         

 

  通过这种方式请求所得到的结果是英文的,如果要返回中文数据,只需要将Google全球本地化搜索服务的请求路径稍加修改,在请求参数中加上hl=zh-CN就行了。





本文转自 beniao 51CTO博客,原文链接:http://blog.51cto.com/beniao/498747,如需转载请自行联系原作者

目录
相关文章
|
1月前
|
人工智能 自然语言处理 API
Google Gemma 模型服务:开放的生成式 AI 模型服务
Google Gemma 模型服务:开放的生成式 AI 模型服务
109 4
|
1月前
|
运维 监控 Serverless
一键开启 GPU 闲置模式,基于函数计算低成本部署 Google Gemma 模型服务
本文介绍如何使用函数计算 GPU 实例闲置模式低成本、快速的部署 Google Gemma 模型服务。
164774 57
|
4月前
|
JSON 定位技术 API
谷歌地图接口Google Maps APIs中地图样式设计配置调整与JSON或URL导出
谷歌地图接口Google Maps APIs中地图样式设计配置调整与JSON或URL导出
|
4月前
|
开发工具
阿里云的镜像服务(mirrors.aliyun.com)可以同步 Google Cloud SDK 的软件包
阿里云的镜像服务(mirrors.aliyun.com)可以同步 Google Cloud SDK 的软件包
183 3
|
6月前
|
人工智能 自然语言处理 数据可视化
Google SGE 正在添加人工智能图像生成器,现已推出:从搜索中的生成式 AI 中获取灵感的新方法
Google SGE 正在添加人工智能图像生成器,现已推出:从搜索中的生成式 AI 中获取灵感的新方法
179 1
|
9月前
|
数据采集 JavaScript 搜索推荐
对于Python抓取Google搜索结果的一些了解
对于Python抓取Google搜索结果的一些了解
|
10月前
|
开发框架 算法 搜索推荐
涨知识|Google语法快速高效的搜索
涨知识|Google语法快速高效的搜索
137 0
|
10月前
|
前端开发 JavaScript Python
10 个使用 Google 搜索的小技巧
最近 Twitter 上有一篇介绍 Google 搜索技巧的帖子,觉得非常实用,所以分享给大家,原帖子地址放在文末了。
92 0
10 个使用 Google 搜索的小技巧
|
算法 搜索推荐 SEO
2023年谷歌搜索排名规则揭秘,Google排名机制
也许流量不会很多,就几个点击,但也足以让谷歌判断你的内容是否满足用户的需求。
277 0
2023年谷歌搜索排名规则揭秘,Google排名机制
|
JavaScript 前端开发 定位技术
最佳网络地图服务对比分析:Google Maps 与 OpenStreetMap
最佳网络地图服务对比分析:Google Maps 与 OpenStreetMap
374 0
最佳网络地图服务对比分析:Google Maps 与 OpenStreetMap

热门文章

最新文章