OpenLayers项目分析——空间数据的组织与实现
来源:互联网 发布:最新非农数据查询 编辑:程序博客网 时间:2024/06/05 00:25
提到数据,先思考几个问题:
GIS,核心是什么?数据?平台?服务?
空间数据的特征、表达方式?
地理数据的模型(结构)?
在OpenLayers空间数据的实现主要存在OpenLayers. Geometry类及其子类中。我们先看下面的两个图片,表现了这些类的继承关系。从图上可以清楚的看出MultiPoint、Polygon和MultiLineString 这三个类实现了多重继承,即直接继承于Geometry类,又继承于Collection类(为什么要这样实现?)。
OpenLyers对于Geometry对象的组织是这样的,其实最基础的就是点,然后MultiPoint由点构成,继承自Openlayers.Geometry.Collection,而LinearRing,LineString均由Point构成,
Polygon由OpenLayers.Geometry.LinearRing构成。OpenLyers在解析数据时候,将所有的面、线包含的点全部都对象化为Openlayers.Geometry.Point。有人测试这里面存在问题:解析矢量数据慢,甚至在点数多的情况下,会使浏览器“崩溃”掉。想想是有道理的:OpenLyers在解析数据时候,将所有的面、线包含的点全部都对象化为点对象t,并首先将所有的对象读取到内存,得到一个Feature的集合,然后将这个集合提交给渲染器进行渲染。这样渲染起来当然慢了。至于为什么要这样,可能是OpenLayers项目本身在标准上,在框架结构上做的比较好,更细部的东西还得优化呀。可话又说回来,OpenLayers作为一个优秀的开源JS框架,学习借鉴的意义要比应用的意义大吧。
下面以Point和Collection为例来说明其内部实现过程,先看Point。
我们知道一个点就是一个坐标对(x,y)嘛,当然它得有两个属性x,y。在point类里,提供了六个成员函数,分别是clone、distanceTo、equals、move、rotate和resize。看看计算两点距离的函数是怎么写的:
distanceTo: function(point) {
var distance = 0.0;
if ( (this.x != null) && (this.y != null) &&
(point != null) && (point.x != null) && (point.y != null) ) {
var dx2 = Math.pow(this.x - point.x, 2);
var dy2 = Math.pow(this.y - point.y, 2);
distance = Math.sqrt( dx2 + dy2 );
}
return distance;
}
在collection集合对象中,可以存放同一类型的地理对象,也可以放不同的地理对象。定义了一个属性component ,以数组对象的形式存储组成collection对象的“组件”。别的不说了,看一个获取集合大小的函数getLength:
getLength: function() {
var length = 0.0;
for (var i = 0; i < this.components.length; i++) {
length += this.components[i].getLength();
}
return length;
}
细心的朋友也许会发现,每一个基类都有一个destroy函数。它是OpenLayers实现的垃圾回收机制,以防止内存泄露,优化性能:
/* APIMethod: destroy
* Destroy this geometry.
*/
destroy: function () {
this.components.length = 0;
this.components = null;
}。
前面也提到过,OpenLayers设计是符合标准的,有良好的框架结构和实现机制,非常值得学习。OpenLayers支持的格式比较多,有XML、GML、GeoJSON、GeoRSS、JSON、KML、WFS等。这回主要以GML为例来看OpenLayers 数据的解析过程。 先来了解一下GML: GML (Geography Markup Language)即地理标识语言,它由OGC(开放式地理信息系统协会)于1999年提出,目前版本是3.0。GML是XML在地理空间信息领域的应用。利用GML可以存储和发布各种特征的地理信息,并控制地理信息在Web浏览器中的显示。地理空间互联网络作为全球信息基础架构的一部分,已成为Internet上技术追踪的热点。许多公司和相关研究机构通过Web将众多的地理信息源集成在一起,向用户提供各种层次的应用服务,同时支持本地数据的开发和管理。GML可以在地理空间Web领域完成了同样的任务。GML技术的出现是地理空间数据管理方法的一次飞跃。 介绍一篇文章:GML3.0的WebGlS研究。 我们从总体上来把握一下OpenLayers对于GML数据的解析,首先通过调用得到GML文本数据,然后通过Formate.GML类的read方法来解析这个文本,解析得到Geometry对象,然后Geometry对象用相应的渲染器画出来。其实解析得到还是那些基本的Point呀、LineString呀之类的Geometry对象,就是我们在地图上看到的那些内容。 下面看其实现过程: //read()函数读取数据,获取特征列表 read: function(data) { if(typeof data == "string") { data = OpenLayers.Format.XML.prototype.read.apply(this, [data]); } var featureNodes = this.getElementsByTagNameNS (data.documentElement,this.gmlns, this.featureName); var features = []; for(var i=0; i<featureNodes.length; i++) { var feature = this.parseFeature(featureNodes[i]); if(feature) { features.push(feature); } } return features; } //函数parseFeature()是OpenLayers中GML数据格式解析的核心,就是它创建地理对象 //和其属性。 //实际上,每一个Foramt 子类都实现了这个成员函数,完成类似的功能。 parseFeature: function(node) { // only accept on geometry per feature - look for highest "order" var order = ["MultiPolygon", "Polygon", "MultiLineString", "LineString", "MultiPoint", "Point"]; var type, nodeList, geometry, parser; for(var i=0; i<order.length; ++i) { type = order[i]; nodeList = this.getElementsByTagNameNS(node, this.gmlns, type); if(nodeList.length > 0) { // only deal with first geometry of this type var parser = this.parseGeometry[type.toLowerCase()]; if(parser) { geometry = parser.apply(this, [nodeList[0]]); } else { OpenLayers.Console.error("Unsupported geometry type: " + type); } // stop looking for different geometry types break; } } // construct feature (optionally with attributes) var attributes; if(this.extractAttributes) { attributes = this.parseAttributes(node); } var feature = new OpenLayers.Feature.Vector(geometry, attributes); // assign fid - this can come from a "fid" or "id" attribute var childNode = node.firstChild; var fid; while(childNode) { if(childNode.nodeType == 1) { fid = childNode.getAttribute("fid") || childNode.getAttribute("id"); if(fid) { break; } } childNode = childNode.nextSibling; } feature.fid = fid; return feature; } 剩下就是由具体的函数parse and bulid基本的地理对象(还有Attribute),包括point、multipoint、linestring、multilinestring、polygon、multipolygon等,然后在write出来。 结合前面的“OpenLayers空间数据的组织”,我们可以看到OpenLayers在解析获取GML数据的时候,比如涉及到面、线的时候,总是以点为基础构建的。有的朋友做过测试,说这时候,直接用SVG画出来,性能上会好很多(具体没测试过,不想多说什么)。
- OpenLayers项目分析(四)空间数据的组织与实现
- OpenLayers项目分析——空间数据的组织与实现
- OpenLayers项目分析——(四)空间数据的组织与实现
- OpenLayers项目分析——(五)空间数据的组织与实现
- OpenLayers项目分析[转](四)空间数据的组织与实现
- OpenLayers----------空间数据的组织与实现
- OpenLayers----------空间数据的组织与实现
- OpenLayers项目分析——数据渲染分析
- OpenLayers项目分析——(六)数据渲染分析
- OpenLayers项目分析——(七)数据渲染分析
- 1.空间数据的采集与组织
- OpenLayers 项目分析——BaseTypes
- 空间数据库的建立1——数据采集与组织
- OpenLayers项目分析——(五) 数据解析——以JSON为例
- OpenLayers项目分析——(六) 数据解析——以GML为例
- OpenLayers项目分析[转](五):数据解析——以GML为例
- OpenLayers项目分析------------- 数据解析——以GML为例
- OpenLayers项目分析------------- 数据解析——以GML为例
- 在后台验证-正则表达式
- 地理信息系统(GIS)
- Seam 敏捷开发与 JavaEE 经典分层架构
- 视觉欺骗 A和B的颜色相同吗?
- 为Linux系统手工添加SWAP空间
- OpenLayers项目分析——空间数据的组织与实现
- 【转帖】基于NDIS(网络驱动接口标准)包拦截技术
- SEO菜鸟需要掌握哪些基本SEO技巧?
- xerces-c和icu编译
- 子域名和子目录
- 关于URL组成部分的指南
- 【转帖】passthru的说明书!!!
- 与Googbot的第一次约会:标头和压缩
- 百度为什么不收录我的站点?