PGIS大数据量点位显示方案

问题描述

PGIS在地图上显示点位信息时,随点位数量的增加浏览器响应速度会逐渐变慢,当同时显示上千个点时浏览器会变得非常缓慢,以下是进行的测试:

测试环境:

  • 服务器:

CPU:Intel(R) Xeon(R) 2.00GHz ,4核

内存:2G

  • 客户端:

CPU: E5200@ 2.59GHz, 2核

内存:2G

下面是测试结果:

点位数量

IE内存占用

平均响应时间

放大缩小

点击响应时间

100

44.22M

基本无延时

1 S

基本无延时

400

49.09M

0.1 S

1.5 S

基本无延时

900

62.67M

0.3 S

3 S

基本无延时

1500

67.85M

1.5 S

5 S

基本无延时

10000

164.104M

不能拖动

不能缩放

 

原因分析

以下是从PGIS显示原理和平台代码实现方式两个方面进行的分析。

PGIS显示原理

山海经纬PGIS利用微软的VML技术在地图上描绘一个点位,每个点位信息最终都生成一个div图层,覆盖到地图图层上。当同时显示上千个点时,浏览器要同时渲染上千个div图层,非常影响性能。

平台显示点位信息的方法

平台在批量显示点位信息时,分3个步骤进行:

  1. 首先查询平台业务数据库,获得安装点编号的集合。
  2. 根据安装点编号集合拼接查询条件,到PGIS空间数据库中查询需要显示的安装点集合。
  3. 循环PGIS查询出来的安装点集合,显示到地图上。在循环中同时查询业务数据库,获得每个安装点的详细信息,作为弹出信息窗的内容。

现行做法存在的问题

  1. 业务数据库中没有存安装点的坐标,需要同时查询业务库和PGIS空间库才能将安装点显示出来。
  2. 安装点明细信息没有进行缓存,每显示一个安装点都需要查询一次业务数据库。
  3. 一次将所有点位显示出来,当点位太多时影响浏览器的响应速度,很多图标叠加在一起也影响界面的美观性。

优化措施

根据以上分析,可以从以下几个方面进行优化。

视野范围内加载

  • 思路

    可以考虑只加载在视野范围内的安装点,以减少浏览器渲染的压力。

  • 分析

    将当前所有点位信息储存在一个数组中。当需要批量显示点位信息时,找出数组中在当前视野范围内的点并进行展示。

  • 实现

以下是用到的PGIS相关接口:

  1. 查询当前地图显示范围:var boundsMBR =_MapApp.getBoundsLatLng()。
  2. 查询指定点是否在指定显示范围内:boundsMBR.containsPoint(Point)
  3. 隐藏一个图层。 PGIS没有提供隐藏一个图层的接口,但一个图层根本上来说是一个div,可以通过隐藏div来实现:pOverLay.div.style.display='none';
  4. 删除一个图层: _MapApp.removeOverlay(pOverLay)

具体的代码:

//隐藏当前视窗范围外的图层

function hidePointsOutOfBounds(){

var boundsMBR=_MapApp.getBoundsLatLng();

var zoomlevel=_MapApp.getZoomLevel();

for(var i=0;i<layerarray.length;i++){

pOverLay = layerarray[i];

if(boundsMBR.containsPoint(pOverLay.getPoint())){

if(layerflag &&((i+1)%zoomlevel!=0)){

_MapApp.removeOverlay(pOverLay);

pOverLay.div.style.display='none';

}else{

if(pOverLay.div.style.display=='none'){

pOverLay.div.style.display='';

_MapApp.addOverlay(pOverLay);

}

}

}else{

if(pOverLay.div.style.display==''){

_MapApp.removeOverlay(pOverLay);

pOverLay.div.style.display='none';

}

}

}

}

分层加载

  • 思路

    如果一次将所有点位显示出来,相邻的点位会紧挨在一起,整个地图看起来元素很多,也不方便用户进行操作。可以考虑分层加载方法减少同时加载的点位数量。

  • 分析

    给每个点位设定层级范围,地图显示时获得当前比例尺层级,只显示当前层级下指定的点位。

  • 实现

    新增安装点层级表。表结构如下:

    MONITOR_POINT_LAYR

名称

代码

数据类型

注释

默认值

安装点编号

POINTCODE

NVARCHAR2(16)

   

最大层级

MAXLAYER

NVARCHAR2(2)

   

最小层级

MINLAYER

NVARCHAR2(2)

   

在前台显示数据时,首先获得当前层级:

var zoomlevel=_MapApp.getZoomLevel();

然后循环安装点列表,获得每个安装点的最大层级和最小层级,判断是否满足条件:

minlevel<=Zoomlevel<=maxlayer

只有满足该条件的安装点才进行显示。

不加载标题

  • 思路

安装点标题现在默认显示在点位信息上面,可以考虑默认不显示标题,当鼠标移动到点上时再加载。

  • 分析

    每个安装点标题都占据一个单独的div层级,点位多时标题会挤在一起,影响美观性,也不方便查看。

  • 实现

    每个安装点在加载时默认隐藏标题:

    marker.hideTitle();

    添加鼠标监听事件,当鼠标移动上时显示标题,移出时隐藏标题:

marker.addListener("mouseover",function(){marker.showTitle()});    marker.addListener("mouseout",function(){marker.hideTitle()});

坐标点存储

  • 思路

    目前显示安装点需要同时查询业务库和PGIS空间数据库。业务库获得安装点明细信息,空间库获得经纬度坐标。单纯的数据展示可以考虑只查询一个数据库。设计到空间搜索等问题时再查询PGIS空间库。

  • 分析

    将安装点的坐标存到业务库中,这样在批量显示安装点时候不需要查询PGIS空间数据库就可以了。只有涉及到空间查询如点周边查询等操作时才操作PGIS空间数据库。

    另外,可以在本地业务库中建立一张安装点空间表,将空间数据储存在自己的业务库中,这样空间查询等功能就不需要依赖PGIS提供的接口了,空间字段是Oracle提供的标准格式,更便于以后功能的扩展。

  • 实现

    平台monitor_point表已经有经纬度字段来,添加安装点时将经纬度数据填进去即可。具体代码略。

    本地安装点空间表结构如下:

    MONITOR_POINT_GEOMETRY

名称

代码

数据类型

注释

默认值

安装点编号

POINTCODE

NVARCHAR2(16)

   

空间字段

GEOMETRY

MDSYS.SDO_GEOMETRY

   

数据缓存

  • 思路

    平台现在是实时查询数据库获得安装点信息,并展示在地图上。可以考虑将安装点信息缓存起来,调用的时候直接从缓存里读取数据,可以省掉查询数据库的操作。

  • 分析

    数据缓存可以在浏览器客户端缓存和服务器端缓存2种方式。

    浏览器端缓存速度最快,但需要耗费浏览器端的内存,一条安装点的所有信息约占900个字节,经过实际测试,在客户端内存中缓存2179条数据,约占1.8M内存,并不影响浏览器响应速度。但当缓存约8000个点左右时会内存溢出。

    因此可以考虑采用浏览器端和服务器端双重缓存的方案。只将基础数据(坐标点、安装点编号、名称、类型)缓存在浏览器客户端,将明细信息缓存到服务器端。

  • 实现

    首先查询数据库将安装点基础信息缓存到浏览器客户端,存在js数组里。当显示某类安装点时循环该数组将符合条件的安装点显示出来。

    在服务器端查询数据库将明细信息缓存到一个cache文件中。该文件定时刷新以保证数据的及时性。当对安装点表进行操作时也实时将数据更新到cache文件中去。

    点位聚合

    参考点位聚合方案

    专题图叠加 ※

  • 思路

    以上优化办法主要针对平台现有的地图显示需求,如果用户有大屏幕显示等特殊需求需要同时显示上千个点位,可以考虑专题图叠加功能。

  • 分析

    PGIS提供专题图叠加的接口,可以通过WMS协议调用第三方地图图片(如GeoServer)叠加到地图上。利用GeoServer等地图服务预先将安装点图层生成出来,利用PGIS的专题图叠加接口调用该图层。

  • 实现
  1. 首先利用GeoServer生成一个安装点图层。
  2. 利用PGIS的接口调用该图层进行展示:

var legendfunc=new LegendFunc();

legendfunc.format=geoserverURL+"/wms?service=WMS&version=1.1.0&request=

GetMap&layers="+layers+"&bbox=EZBOX&width=EZWIDTH

&height=EZHEIGHT&srs=EPSG:4326&format=image/png

&TRANSPARENT=true&cql_filter="+escape(cql_filter)+"

&styles="+styles;

legendfunc.open(_MapApp);

PGIS大数据量点位显示方案的更多相关文章

  1. c# 大数据量比较时-方案

    1.当面临千万条数据量的比较时,从技术的角度来说应该用泛型键值(c#键值由于用了散列算法速度很快).例如前几天我需要查的是 航空公司.出发.到达.返点可以将 航空公司-出发-到达做一个键,返点作为值. ...

  2. SQL Server 大数据量分页建议方案

    简单的说就是这个 select top(20) * from( select *, rowid = row_number() over(order by xxx) from tb with(noloc ...

  3. elasticsearch5.0集群大数据量迁移方法及注意事项

    当es集群的数据量较小的情况下elasticdump这个工具比较方便,但是当数据量达到一定级别比如上百G的时候,elasticdump速度就很慢了,此时我们可以使用快照的方法进行备份 elasticd ...

  4. 大数据量报表APPLET打印分页传输方案

     1 . 问题概述 当报表运算完成时,客户端经常需要调用润乾自带的runqianReport4Applet.jar来完成打印操作, 然而数据量比较大的时候,会导致无法加载完成,直至applet内存 ...

  5. 大数据量数据库设计与优化方案(SQL优化)

    转自:http://blog.sina.com.cn/s/blog_6c0541d50102wxen.html 一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的 ...

  6. 大数据量高并发的数据库优化详解(MSSQL)

    转载自:http://www.jb51.net/article/71041.htm 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能. ...

  7. 大数据量高并发的数据库优化,sql查询优化

    一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之前,完备的数据库模型的设计是必须的. ...

  8. 大数据量时Mysql的优化

    (转自网络) 如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB.对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求.这个时候NoSQL的出现暂时 ...

  9. 参考 ZTree 加载大数据量。加载慢问题解析

    参考 ZTree 加载大数据量. 1.一次性加载大数据量加载说明 1).zTree v3.x 针对大数据量一次性加载进行了更深入的优化,实现了延迟加载功能,即不展开的节点不创建子节点的 DOM. 2) ...

随机推荐

  1. Wi-Fi科普讲稿

    Wi-Fi 从入门到?? 组员:deleted 什么是Wi-Fi Wi-Fi 在中文里又称作"无线热点",是Wi-Fi联盟制造商的商标做为产品的品牌认证,是一个创建于IEEE 80 ...

  2. Homebrew下安装的软件自启动服务管理工具:Launchrocket

    帮助管理Homebrew安装的服务的软件,比如使用Homebrew安装的Mysql.Redis.MongoDB,传统方式需要使用命令行的命令,而使用LaunchRocket则可以在图形界面中进行管理. ...

  3. 【JSP】jsp报错:Syntax error, insert "}" to complete MethodBody

    使用MyEclipse编写JSP的时候有时会报错误如下 Syntax error, insert "}" to complete MethodBody 大体意思就是说方法体缺少缺少 ...

  4. C# 委托的一些使用上的小技巧

    1.委托是一种数据类型,我们可以在任何定义类的地方定义委托,在任何声明类的地方声明委托 2.初始化委托有两种方式,代码如下: (1).像类一样初始化委托 public delegate void Sa ...

  5. WCF系列教程之WCF客户端调用服务

    1.创建WCF客户端应用程序需要执行下列步骤 (1).获取服务终结点的服务协定.绑定以及地址信息 (2).使用该信息创建WCF客户端 (3).调用操作 (4).关闭WCF客户端对象 二.操作实例 1. ...

  6. 第3章—高级装配—bean的作用域

    bean的作用域 bean的默认作用域 Spring定义了多种作用域,可以基于这些作用域创建bean,包括: 单例(Singleton):在整个应用中,只创建bean的一个实例. 原型(Prototy ...

  7. 编译原理LL(1)文法

    从左向右扫描输入,然后产生最左推导(就是每次都把最左边的非终结字符用产生式代替). (一)First集合 比如有产生式 A-> + T | - P , 当我们读到串为 +开头的时候,我们可以很直 ...

  8. 14 线程间协作的两种方式:wait、notify、notifyAll和Condition

    原文链接:http://www.cnblogs.com/dolphin0520/p/3920385.html 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者- ...

  9. 请别再拿“String s = new String("xyz");创建了多少个String实例”来面试了吧---转

    http://www.iteye.com/topic/774673 羞愧呀,不知道多少人干过,我也干过,面壁去! 这帖是用来回复高级语言虚拟机圈子里的一个问题,一道Java笔试题的. 本来因为见得太多 ...

  10. JAVA-1NIO概述

    注意: 转载自并发编程网 – ifeve.com本文链接地址: Java NIO系列教程(一) Java NIO 概述 JAVA-1NIO概述 Java NIO 由以下几个核心部分组成: Channe ...