gis
gis
管理员
管理员
  • 注册日期2003-07-16
  • 发帖数15945
  • QQ554730525
  • 铜币25337枚
  • 威望15352点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
  • 帝国沙发管家
  • GIS帝国明星
  • GIS帝国铁杆
阅读:9254回复:2

你可能用到的百度地图效果(附源码)

楼主#
更多 发布于:2015-07-10 17:04
   这段时间需要实现百度地图的一些展示效果,虽然最终效果做出来了,可是这中间也走了很多的弯路,希望有用到的可以直接拿来用,少走一些弯路。百度地图为开发者提供了一系列的接口,点百度接口去百度接口。本文主要用到了以下几个效果:
1、热力图显示
2、自定义图标的聚合显示
3、云麻点显示
      热力图显示
      
百度地图热力图是通过设置热力图半径、颜色、透明度等参数直观展示数据分布情况,而我这段时间所做的,就是通过一段时间内的订单数量,再结合经纬度,在地
图上显示热力分布图。百度地图官方的API给的示例很Easy,创建地图实例,初始化参数,生成点的数组,然后创建热力图对象,并将热力图对象添加到地图
实例,设置数据源,这样这个热力图的效果就可以展示出来了。(当然申请AK和引入Js就不用说了),这部分源码比较简单,就不展示了,只需要看热力图API相信都是可以明白的。
      可是自己做的时候,效果却没这么容易出来。我在做的过程中,开始最大的一处疑问就是,其他代码部分代码都跟官方API示例一样,只是换了个数据源,热力图效果就是出不来。后来在试了无数遍之后,发现如果当前地图放大的级别过大,也就是有些点没有在当前地图可视区域内展示的话,热力图效果是不会出来的!当然了,关于这点没有百度地图官方的解释,也没有得到求证,只是我在开发过程中发现的一个解决方案。如果你也在做这部分,恰好遇到这个问题的话不妨试试。其次为了效果明显,最好是多添加几个点,这样效果会更好一些。以下是效果图:

 
      自定义图标聚合显示
      
说到这个聚合显示,哎,说多了都是泪啊。本来提出的需求只是需要将数据库中的店铺展示出来,然后点击的时候弹出详细信息的提示框。我一想,这还不简单?通
过Handler从后台获取到数据,然后以Json的格式传给前台,然后来个for循环,依次添加到地图不就解决了?第一版我确实是这么干的。拿到数据之
后再做foreach……以下是Js脚本。
View Code
      
我在本地添加了将近100个点的数据,测试没问题之后就提交到Svn了,然后跟项目经理说这个东东做完了。然后项目经理将数据切成正式数据,叫我给他演示
一下。这一演示不要紧啊,脸全没了。正式数据库中有5000多条数据,而我取数据时后台做了过滤,只提取有经纬度的点,即使这样也有1500多条记录。没
错,1500多条,这意味着浏览器客户端这边要循环1500多次来做这个操作!然后奇迹就发生了,页面就假死了!无论怎么刷新都没有效果了,即使等了很长
时间地图加载出来了,只要稍微一放大或者移动地图页面就会直接挂掉。然后项目经理就一顿巴拉巴拉巴拉,这就是你给我的结果么?
      谁让我确实这个东东没做好呢?也没脸跟别人争辩,拿回来重新研究吧。于是在网上搜了一下,发现很多人也都遇到了这个问题,就是当点大于一定的数量之后,浏览器都会出现假死的情况。然后上百度论坛浏览了一下,确实有提到这个问题,当点的数量在150个以内时,这么做是没有问题的,但当点数量大于300个时,这么做就行不通了。百度给出了两种解决方案:
No1:Marker聚合:http://tieba.baidu.com/f?kz=1031097376
No2:数据抽希:比如有10个marker,选择其中6个做为显示点。
      这里对比了一下需求,Marker聚合是将所有的点聚合起来,显示一个总数,然后点击的时候再分开;而数据抽希字面的意思是从中选取一部分来展示。而我所接到的任务是展示所有点,显然数据抽希这里是用不上了,那就来聚合吧。这是第二版。
      首先简单介绍一下,百度聚合展示提供了开源的类库,只需要在页面中引用即可。以下是Js脚本代码:
View Code
      这段代码大部分都很简单,只有一个地方做个简单的说明,网上很多人也问到了这里。就是说循环添加点,然后给每一个点都绑定了Click事件,然后实际点击的时候却弹出的内容都是一样的。这是由于Js的作用域以及闭包引起的,详情请看我的另一篇博客:那些必须要知道的Javascript,这里不再赘述。其中代码里setIcon是为了把百度默认的图标换成我们自己预先设定的图标,下图是运行之后的效果:

      
与第一版相比,性能确实有了很大的改进,至少在本地加载个1500多条数据已经没问题了。可是通过聚合之后又引入了新的问题,就像上图中的绿色圆圈,有两
个4,一个6,正常这些数据点击之后都会散开的,当一直点击的时候应该可以看到没有聚合的点。可是这里出现的问题是有些可以点开,有些居然点不开。开始我
以为是数据的问题,以为相隔比较近的点是无法展开的,后来就对数据做了处理,如果有相同的数据则通过加减随机数,确保拿出来的数据没有相同的,可是这个问
题还是没有解决。希望有了解的朋友可以告知一二。通过这样聚合,展示数据确实比第一版快很多,可是当在公网上的时候,页面缩放或者移动的时候还是会卡。所
以还得重新找解决方案。
    
 这里值得一提的就是百度地图我们可以看到那种鼠标在左边搜索列表滑动,右边地图中搜到的结果跟着变化的那种效果,这里我们也是可以做的。监测左边列表的
MoueEnter事件,然后根据当前Enter的点的经纬度创建一个点,然后Foreach右边搜索结果中的点,如果通过point的equals方
法,判断是否是同一个点,如果是则改变当前的Icon即可。Js脚本:
View Code
      云麻点效果展示
      最初没有用这个云麻点展示效果是因为一些敏感数据,可是后来发现没有其他合适的解决方案的时候,就采用了这个方案。云麻点效果也就是LBS云存储,用户将数据存放在百度的云服务器,然后直接从百度云获取数据。这个流程是:先在LBS开放平台创建数据表,然后添加需要的字段,然后就可以在后台批量上传数据。数据上传至百度服务器后,会生产相应的云麻点图层,这些图层在加载的时候直接被展示出来,这样可以很大程度上提高性能。现在假设后台数据已经准备完毕了,前台所作的操作:
首先,初始化地图的数据:
View Code
然后,设置筛选的条件:
View Code
之后就是最关键的一步,请求数据:
View Code
完了之后再调整一下样式,结果如图:

      
通过LBS云存储,可以很好的解决海量数据加载缓慢的问题,但是这样做的缺点就是一方面数据必须上传到百度的云服务器,另一方面数据维护还是比较麻烦的,
必须得通过接口来操作。以上是最近做百度接口总结的一些问题,希望对您能有所帮助,如果您遇到了跟我类似的问题还没有解决,欢迎随时跟我交流。如果您觉得
文章对您有一点点作用,一定要顶哦,原创不容易啊!
喜欢0 评分0
gis
gis
管理员
管理员
  • 注册日期2003-07-16
  • 发帖数15945
  • QQ554730525
  • 铜币25337枚
  • 威望15352点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
  • 帝国沙发管家
  • GIS帝国明星
  • GIS帝国铁杆
1楼#
发布于:2015-07-10 17:07
  上篇博文你可能用到的百度地图效果(付源码)
绍了几个比较实用的百度地图特效,其中重点介绍了海量数据上传及响应的问题,前端展示可以通过LBS云麻点来展示,通过这个可以解决批量数据Marker
响应特慢的性能问题。首先在百度云服务器上建完表之后,我们可以通过后台的管理平台直接把数据传上去,作为我们的初始数据。这部分数据有了之后,接下来要
做的就是想办法手动同步数据,更智能一点就是实时同步数据,接下来就带你一步步实现这个过程。


     
首先,说说这次同步过程中发现的几个问题及解决方案。1、百度云麻点样式无法自定义,只能使用官方的一些坐标点的样式;2、虽然官方给出的数据是一天请求
10万次,但是如果请求频繁的话,会返回错误的数据;3、百度云检索最多只能返回2000条数据,如果需要返回更多数据,可以通过云存储里的查询指定条件
的数据列表接口来实现;4、云服务器数据会有缓存,有时候更新不及时;5、上传数据的csv格式里有一列是空的,不知道是干什么用的。      

     
接下来开始今天的正文,数据同步这块儿,这里经历了文章开头说到的两个过程,由手动同步升级成自动同步。刚开始做的是傻瓜似的,在页面上放了一个按钮,在
按钮点击的时候向handler发送请求,然后去获取本地数据,然后更新到百度云服务器。下图是上传数据需要的接口:


   
 通过API接口可以看到,发送的请求参数也比较少,三个必须参数,一个表ID
geotable_id,一个csv文件,即需要上传的数据,另外一个是访问权限ak。到这里我们大致的思路就出来了,首先生成csv格式的数据文件,然
后获取配置的ak和geotable_id,然后封装参数,接着发送Post请求。下面我们来一步一步实现这个过程:

     
首先生成csv格式的数据文件。这里发生的场景是这样的:当我们最初在百度云服务器建表的时候,表建完之后我们会把最初的数据通过API控制台的数据管理
后台把数据批量上传上去,然后本地数据会不断更新,当我们点击页面同步数据按钮的时候,最重要的一个判断就是——需要同步哪些数据。这里可以有两种方案,
第一,通过配置表的参数来存本地更新之前最大的一条记录的主键,然后同步的时候去找比这条数据主键更大的数据;第二,直接向百度服务器获取数据,因为百度
云存储那边可以对查询出来的数据进行倒叙排序,所以我们只需要按排序字段进行倒叙排列,然后取top1条记录,这样也可以得到最大记录的主键。得到这个主
键之后,接下来做的操作就简单了,每次点击同步的时候,对比服务器上存的最大记录主键跟本地数据库当前最大记录主键的大小,如果服务器上的数据比本地小,
则有数据需要同步,反之则不。关键代码:

     以下是同步数据的关键代码:
View Code
    这里涉及了两个方法,一个是将DataTable转成CSV文件,一个是发送Post请求,以下是代码:  
View Code
    以下是直接发送Post请求的代码,之前在网上找了很多C#发送Post请求的,用的时候都是各种问题,后来才找到下边这个,确实是可以用:
View Code
   
 这里有点奇怪啊,开始我是通过PostMan直接操作的,抓取了提交的参数等信息,然后在后台去拼这个请求,跟PostMan提交的参数完全一致,可是
百度返回的提示却一直都是少参数,无奈之下只能放弃最初自己写的,采用了上边的那种方式,不过好在最终目的还是实现了。

   
 手动同步用了一段时间之后,就发现问题了,每当需要同步数据的时候,都得点一下,这样领导就不高兴了。莫非我要叫个人实时去点这个按钮么?好吧,我做个
自动同步的工具。这里说的自动同步工具,其实就是隔一段时间就自己去同步一下数据,隔一段时间去同步一下数据。这里最初也想了两个方案,一个就是做一个页
面,隔一段时间向后台发请求,检查是否有可更新的数据,如果有可以更新的数据,就调一下上边的方法。这样做的优势是改动量最小,只需要加一个页面然后写个
定时器就搞定了,可是缺点就是如果有多个人同时打开这个页面,数据就会混乱。另一个方案就是建一个Windows服务,定期去跑这个同步数据的代码。这样
做的优势是不依赖于IIS,稳定。最终执行的方案也是后者,通过构建windows服务来做这个事情。

   
 构建Windows服务这里就不赘述了,网上有很多示例,基本上都是一搜一大把。在服务里,我们每隔5分钟去跑一次自动同步的代码,这样就实现了数据自
动同步功能。关于百度LBS数据同步这块儿到此结束。这两天正在做一个新用户注册特效和用户下单特效。大致需求就是在以下这个云麻点地图上,一旦有新用户
注册,以动态图片显示出他的坐标位置信息,用户下单也是一样,每个用户都是一个云麻点,一旦某个用户下单成功,展示一个烟花绽放的特效。基本功能都做得差
不多了,哪天有时间再更新上来!
举报 回复(0) 喜欢(0)     评分
kid1412
路人甲
路人甲
  • 注册日期2016-02-23
  • 发帖数1
  • QQ
  • 铜币1枚
  • 威望0点
  • 贡献值0点
  • 银元0个
2楼#
发布于:2016-02-23 16:51
唉,关键代码的图片总是坏的,看都看不到,,,
举报 回复(0) 喜欢(0)     评分
游客

返回顶部