ArcGIS客户端API中加载大量数据的几种解决办法
|
REST风格的一切事物方兴未艾,ArcGIS Server的客户端API(Javascript/Flex/Silverlight API)也逐渐站上了GIS舞台的中央。虽然客户端API给我们带来了更快捷的开发体验,更丰富的展现效果,但有些(奇怪的)需求还不能直接解决。比如要求在客户端API程序中显示大量图形(上万个),乍看之下,受到平台本身的性能制约无法完成,但我们的思维和时间一样,只要挤一挤,总还是有的。本文就来讨论一下如何在客户端API程序中显示大数据量图形的问题。以Silverlight API为例。 要将几何对象显示在客户端程序中,一般我们首先想到的办法就是GraphicsLayer。将服务器端的要素通过查询或者其他方式创建成客户端的Graphic用以显示,从而进一步交互。于是有了下面几种方法。 1、Cluster 比较成熟和理智的做法是,利用Cluster效果来处理大量的Graphic。对于这种办法,ArcGIS Server中的Javascript API,Flex API和Silverlight API均能做到。下图是Silverlight API中300,000个点的展示效果。(忽略数据从服务器到客户端的传输时间) Google Maps,Bing Maps等也都采取了这种做法。 但是,不论什么原因,就是不想采用Cluster的办法,而要看到大量密密麻麻的点时心里才觉得踏实该怎么办?对于这种需求,也有对应的解决方案。 2、直接在前台绘制Graphic 但这种办法直接受到平台性能的限制。以Flex和Silverlight为例,在不影响地图操作的情况下,视图范围内一次性能够承受的Graphic数量大约是4000-5000个。注意,相对于绘制Graphic对象的操作来说,Geometry节点的个数可以忽略,也就是说这几千个Graphic既可以是点,也可以是面。这时候你的地图看起来是这样的(4000个Graphic): 3、用ElementLayer(Silverlight API独有)来模拟GraphicsLayer ElementLayer是Silverlight API中独有的一种图层类型,直接继承自ESRI.ArcGIS.Client.Layer,用来承载Silverlight本身的一些布局控件(Framework Element)。它的最主要的用途是使得Silverlight本身的控件能够随着地图的放大缩小而自动变化。利用它我们可以在一定程度上模拟GraphicsLayer。比如Silverlight API中的InfoWindow。 GraphicsLayer之所以只能承载一定数目的Graphic,就是因为Graphic对象本身封装的内容比较多。如果我们仅需要展示这些点,并只在上面做一些简单查询,那么可以完全用ElementLayer来替代之。直接的好处就是,可以在客户端显示更多的数据。比如一个点,我们可以用更基本的Ellipse来代替Graphic。将Graphic的Attributes存储在Ellipse.Tag中,依然可以用上面提到的InfoWindow做DataBinding。初步做了一下试验,如果用ElementLayer来模拟GraphicsLayer,在不影响地图操作的情况下,视图范围内一次性能承载的图形个数大约是20,000-25,000个。这时候你的地图看起来像是这样(20,000个Ellipse): 顺便提一下,如果想在ElementLayer中来模拟动态的地图符号,甚至是时态图层也是可以的。对于Graphic,你可以定义Symbol的ControlTemplate;对于ElementLayer,则可以直接将带有任何动画的对象直接加入其中。 上面提到的3种方法都是纯客户端的,尤其第三种办法,再没有更多工作量的情况下已经基本将客户端的性能用到了极致。但对于想看到密密麻麻点的人来说,五位数的数量级很有可能并不能满足要求。要想将展示的图形个数再提高一个或两个数量级,达到几十万甚至上百万,那么只有来借用服务器端的性能了。 4、ArcGISDynamicMapServiceLayer 直接将所要展示的数据在服务器端发布成一个MapService,在客户端通过ArcGISDynamicMapServiceLayer来加载。这样的话客户端需要展示的仅仅是一张图片,没有任何压力。功能上,如果想查询的话可以使用Identify/Find/Query Task来达到目的。下图加载了一个本机的ArcGISDynamicMapServiceLayer(AGS10,msd发布,1个实例,core i7 2.6GHz,4g内存,win7 x64),服务只有一个点图层,记录数大约650,000条: 服务器端生成这张图片的时间大约13s,进行一次IdentifyTask操作时间是0.2s。这里大部分时间都花在了服务器端对数据的绘制上,因此局域网传输图片等因素可以暂不考虑。服务器端的绘制速度受硬件和软件两个方面的影响。以ArcGIS Server 10已经无法改变,理论上只能通过提高硬件配置来达到加快出图速度的目的。 ps:采用ArcGISDynamicMapServiceLayer时可结合服务器端的点抽希办法来一起使用(抽稀方法1,抽稀方法2)。但这样就失去了密密麻麻数据带给我们的“成就感”,不在赘述。 这种办法中,客户端的压力已经完全没有了,功能上也能通过变通来实现,但展现上有两个缺点:1、数据过多的话绘制速度太慢(40w条数据大约是6.7s,12w条数据大约是2.3s,3w条数据大约是0.6s,);2、出图过程中该服务一片空白,且移动过程中也会出现“白边”的现象。如果硬件配置也无法提高,还有没有更好的办法呢?办法是有的。 5、继承TiledMapServiceLayer来达到“动态切图”的目的 在Google Fusion Tables的例子中,我们可以看到,所有的点数据都是以切片的方式展现,这样的好处是,即使出图速度较慢,用户也能看到切片一个一个的加载过程,不至于长时间一片空白;移动过程中也不会有白边现象;且浏览过的地方都会被客户端缓存,不需要再次向服务器请求,既减少了服务器压力,也加快了显示速度。但明显Google不可能为上传的每张表格都去做切片处理,ArcGIS Server中如何能达到这种效果? 首先想到的是服务切图时的“Cache On Demand”设置。但第一个用户等待的时间就是服务器完成该比例尺下切图的时间,显然太长;并且切图后如果数据有变化,那么看到的切图就和实际数据不一致了。这条路走不通。 通过继承TiledMapServiceLayer,可以利用GetUrl方法来控制如何获取每一个切片。此时如果我们以动态地图服务为资源,利用REST SDK的ExportMap操作来生成每一个切片,就达到了“动态切图”的目的。不仅如此,我们还可以在服务器端发布多个相同的服务,在GetUrl方法中轮询使用这些服务,便可以达到“并行”出图的目的。此时每个服务生成的图片都是256*256大小,所包含的记录数会少很多,速度会明显加快。本机发布3个服务时,同样比例尺下的650,000条记录,所有“切片”加载完成大约需要6s,考虑到缓存服务的加载效果,用户完全可以接受。这种方法相比ArcGISDynamicMapServiceLayer,大大提高了出图的速度和效果。 关于此方法的几点说明:如何利用比例尺、行/列号来计算一个切片的范围,可以参考《ArcGIS Server的切图原理深入》;默认情况下,浏览过的“切片”会缓存在客户端,再次浏览时服务器端就不用动态出图了。如果不想在客户端缓存“切片”,保证服务器端数据发生变化后,客户端也能随时更新,则可以在请求后面加上时间戳,达到DisableClientCache的功能;对于这种数量级的数据展示来说,一般是局域网应用,因此Identify/Find/Query与服务器端的交互完全可以接受;而且通常拥有这种数据量的用户硬件资源一般都是可充分扩展的,因此多发布几个服务来加速出图完全可行。 无图无真相,看看这种办法的效果。别忘了,在服务器端你发布的仅仅是普通的动态地图服务。 好了,这几种方法各有千秋,供各位朋友按需选择。 |
ArcGIS客户端API中加载大量数据的几种解决办法的更多相关文章
- 在Spring Boot中加载初始化数据
文章目录 依赖条件 data.sql文件 schema.sql 文件 @sql注解 @SqlConfig 注解 在Spring Boot中加载初始化数据 在Spring Boot中,Spring Bo ...
- ios网络学习------4 UIWebView的加载本地数据的三种方式
ios网络学习------4 UIWebView的加载本地数据的三种方式 分类: IOS2014-06-27 12:56 959人阅读 评论(0) 收藏 举报 UIWebView是IOS内置的浏览器, ...
- Velocity中加载vm文件的三种方式
Velocity中加载vm文件的三种方式: a. 加载classpath目录下的vm文件 /** * 初始化Velocity引擎 * --VelocityEngine是单例模式,线程安全 * @th ...
- 转 Velocity中加载vm文件的三种方式
Velocity中加载vm文件的三种方式 velocitypropertiespath Velocity中加载vm文件的三种方式: 方式一:加载classpath目录下的vm文件 Prope ...
- BadImageFormatException,未能加载正确的程序集XXX的解决办法
BadImageFormatException,未能加载正确的程序集XXX的解决办法 IDE:VS2010 语言:C# 异常:System.BadImageFormatException,未能加载正确 ...
- iOS --- UIWebView的加载本地数据的三种方式
UIWebView是IOS内置的浏览器,可以浏览网页,打开文档 html/htm pdf docx txt等格式的文件. safari浏览器就是通过UIWebView做的. 服务器将MIM ...
- ExtJS4加载FormPanel数据的几种方式
我们做web应用最多的就是处理表单,extjs为我们提供了很多处理表单的功能,很多初学者疑惑怎么加载表单数据,到底能用什么方式加载?本文中,我将我自己实验过的进行一下总结,自己备忘,也希望能帮助到其他 ...
- arcgis三维球中加载2000坐标系出现错误(The tiling scheme of this layer is not supported by SceneView)
目前我们国家测绘地理信息的坐标体系基准是国家2000坐标系CGCS2000.各类地图组件如OpenLayers.Mapbox.Cesuim和ArcGIS Javascrip等都主要是支持WGS84(w ...
- javascript innerHTML 大数据量加载 导致IE 内存溢出 的解决办法
在做 ajax 滚动加载的时候,越到后面 数据量越大,使用obj.innerHTML+=row添加到页面的时候,出现ie内存不足的情况,此时使用createDocumentFragment,创建一个文 ...
随机推荐
- 学习Linux的准备
学习方式: 主动学习: 动手实践:40% 讲给别人:70% 被动学习: 听课:10% 笔记:20% 写博客的要求: 写博客是对某一方面知识的总结,输出:是知识的书面化的表达方式.写博客不同于写笔记,笔 ...
- zencart通过产品id 批量添加推荐产品
1.修改 admin/featured.php 查找 pre_add_confirmation 将 pre_add_confirmation 与 break; 之间的代码,用下面的代码替换即可 &l ...
- 一、Flux 是什么?
React 本身只涉及UI层,如果搭建大型应用,必须搭配一个前端框架.也就是说,你至少要学两样东西,才能基本满足需要:React + 前端框架. Facebook官方使用的是 Flux 框架.本文就介 ...
- Mongodb的锁 原子性 隔离性 一致性
读写锁 Mongodb使用读写锁来来控制并发操作: 当进行读操作的时候会加读锁,这个时候其他读操作可以也获得读锁.但是不能或者写锁. 当进行写操作的时候会加写锁,这个时候不能进行其他的读操作和写操作. ...
- 【The 13th Chinese Northeast Collegiate Programming Contest H 题】
题目大意:NOIP2018d1t1 支持 M 次区间查询答案和区间修改操作. 题解: 首先考虑不带区间修改的情况.从左到右进行考虑,发现对于第 i 个数来说,对答案的贡献仅仅取决于第 i-1 个数的大 ...
- 关于sparksql
1.读取json文件,并且进行查询等操作 所使用的jar包为 json文件内容 { "id":1 ,"name":" Ella"," ...
- php环境搭建总结
回顾: 搭建web服务器 Apache:接收浏览器发出的请求以及返回结果(html) php:处理php代码,操作数据库(mysql) mysql:存储和处理数据 Apache配置php 加载:Loa ...
- django 路由层(反向解析)03
目录 ORM表关系建立 Django请求生命周期流程图 urls.py 路由层 无名分组 有名分组 反向解析 无名分组的反向解析 有名分组的反向解析 以编辑功能为例 路由分发 名称空间 伪静态 虚拟环 ...
- DEDE怎么让栏目列表以权重拍排列
方法/步骤 进入后台到栏目里,新发布文章也行,编辑文章也行,你会看到有个权重值,不管你怎么改变保存后依然没有变化. 修改权重值,打开dede\album_edit.php文件,找到 UPD ...
- OpenCV笔记(6)(harris角点检测、背景建模)
一.Harris角点 如上图所示,红色框AB都是平面,蓝色框CD都是边缘,而绿色框EF就是角点. 平面:框往X或Y抽移动,变化都很小. 边缘:框沿X或Y轴移动,其中一个变化很小,而另外一个变化比较大. ...