PGIS大数据量点位显示方案

2023-07-29,,

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个步骤进行:

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

现行做法存在的问题

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

优化措施

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

视野范围内加载

思路

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

分析

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

实现

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

    查询当前地图显示范围:var boundsMBR =_MapApp.getBoundsLatLng()。
    查询指定点是否在指定显示范围内:boundsMBR.containsPoint(Point)
    隐藏一个图层。 PGIS没有提供隐藏一个图层的接口,但一个图层根本上来说是一个div,可以通过隐藏div来实现:pOverLay.div.style.display='none';
    删除一个图层: _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的专题图叠加接口调用该图层。

实现

    首先利用GeoServer生成一个安装点图层。
    利用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大数据量点位显示方案的相关教程结束。

《PGIS大数据量点位显示方案.doc》

下载本文的Word格式文档,以方便收藏与打印。