前面也提到过,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()函数读取数据,获取特征列
[代码]js代码:
02
if
(
typeof
data ==
"string"
) {
03
data = OpenLayers.Format.XML.prototype.read.apply(
this
, [data]);
05
var
featureNodes =
this
.getElementsByTagNameNS (data.documentElement,
this
.gmlns,
this
.featureName);
07
for
(
var
i=0; i<featureNodes.length; i++) {
08
var
feature =
this
.parseFeature(featureNodes[i]);
10
features.push(feature);
//函数parseFeature()是OpenLayers中GML数据格式解析的核心,就是它创建地理对象 //和其属性。 //实际上,每一个Foramt 子类都实现了这个成员函数,完成类似的功能。
[代码]js代码:
01
parseFeature:
function
(node) {
02
// only accept on geometry per feature - look for highest "order"
03
var
order = [
"MultiPolygon"
,
"Polygon"
,
04
"MultiLineString"
,
"LineString"
,
05
"MultiPoint"
,
"Point"
];
06
var
type, nodeList, geometry, parser;
07
for
(
var
i=0; i<order.length; ++i) {
09
nodeList =
this
.getElementsByTagNameNS(node,
this
.gmlns, type);
10
if
(nodeList.length > 0) {
11
// only deal with first geometry of this type
12
var
parser =
this
.parseGeometry[type.toLowerCase()];
14
geometry = parser.apply(
this
, [nodeList[0]]);
16
OpenLayers.Console.error(
"Unsupported geometry type: "
+
19
// stop looking for different geometry types
23
// construct feature (optionally with attributes)
25
if
(
this
.extractAttributes) {
26
attributes =
this
.parseAttributes(node);
28
var
feature =
new
OpenLayers.Feature.Vector(geometry, attributes);
29
// assign fid - this can come from a "fid" or "id" attribute
30
var
childNode = node.firstChild;
33
if
(childNode.nodeType == 1) {
34
fid = childNode.getAttribute(
"fid"
) ||
35
childNode.getAttribute(
"id"
);
40
childNode = childNode.nextSibling;
剩下就是由具体的函数parse and bulid基本的地理对象(还有Attribute),包括point、multipoint、linestring、multilinestring、polygon、multipolygon等,然后在write出来。 结合前面的“OpenLayers空间数据的组织”,我们可以看到OpenLayers在解析获取GML数据的时候,比如涉及到面、线的时候,总是以点为基础构建的。有的朋友做过测试,说这时候,直接用SVG画出来,性能上会好很多(具体没测试过,不想多说什么)。