GML的全称是Geography Markup Language,中文称为地理标记语言,它是开放地理空间联盟制定的一套基于XML的地理空间数据编码标准。GML的主要用途在于描述地理要素、空间几何对象以及它们所关联的属性信息,从而让不同地理信息系统之间能够进行无损的数据交换。由于GML建立在XML语法基础之上,它天然具备平台无关、可扩展以及自描述等特性,这也使其成为地理空间数据领域中一种非常重要的开放格式。

GML的设计目标与核心定位
从定位上看,GML本质上是XML在特定领域中的应用子集。它一方面继承了XML通用数据描述的能力,另一方面又加入了地理空间数据表达所需的专门规则。换句话说,GML并不是一种完全独立于XML的全新语言,而是在XML语法框架之上,通过定义专用的元素、属性和Schema来规范地理信息的编码方式。因此,所有合法的GML文档一定同时也是合法的XML文档,但反过来并不成立。
GML需要解决的核心问题在于地理要素的表达。在地理信息系统中,一个地理要素通常既包含空间位置信息,也包含属性信息。空间位置信息可以是点、线、面等几何类型,属性信息则可以包括名称、编号、长度、面积、类别等。GML将这两类信息统一封装在一个结构化文档内,使得接收方能够完整地还原原始地理数据,而不必依赖特定的商业软件或专有格式。这种统一封装的能力,是GML能够在跨平台、跨系统场景下得到广泛应用的重要原因。
除了表达单个地理要素之外,GML还支持要素集合的概念。一个GML文档可以包含多个地理要素,并通过FeatureCollection结构将它们组织在一起。这种设计非常符合实际的地理数据交换需求,因为在现实中,一块区域的地理数据往往包含道路、河流、建筑等多种要素,而不是孤立地只描述某一个对象。
GML与XML的关系及差异
GML的基本语法完全遵循XML的规则,例如所有标签必须正确闭合、属性值必须使用引号、文档必须有且只有一个根元素等。GML文档同样以XML声明开头,并通过命名空间来区分GML专用元素与普通自定义元素。常见的GML命名空间通常指向开放地理空间联盟规定的URI,例如http://www.opengis.net/gml/3.2。通过命名空间机制,GML文档可以在同一个文件中同时使用GML内置的元素和用户自定义的领域元素,这为实际应用提供了很大的灵活性。
虽然GML在格式上与XML高度一致,但两者在定义主体、适用领域和约束机制方面存在明显区别。XML本身由万维网联盟负责维护,它提供的是通用的数据描述能力,不针对任何特定行业。而GML由开放地理空间联盟制定,专门用于地理空间数据领域。此外,普通XML文档的结构约束可以由用户自己定义,也可以使用通用Schema,而GML文档必须遵循开放地理空间联盟发布的GML Schema才能被正确解析。GML Schema内置了地理空间领域常用的元素,例如<gml:Point>、<gml:LineString>、<gml:Polygon>等,这些元素在普通XML中并不存在。
下面通过一个对比表来更清晰地展示XML与GML之间的差异:
| 对比维度 | XML | GML |
|---|---|---|
| 维护机构 | 万维网联盟 | 开放地理空间联盟 |
| 适用范围 | 通用数据描述与交换 | 地理空间数据编码与交换 |
| 结构约束 | 可自定义或使用通用Schema | 必须遵循GML专用Schema |
| 内置领域元素 | 无行业特定元素 | 包含点、线、面等地理几何元素 |
| 命名空间 | 可由用户自定义 | 通常使用OGC定义的GML命名空间 |
理解GML与XML的关系,有助于开发者在实际项目中正确处理数据格式。例如,当使用XML解析器读取GML数据时,虽然从语法角度可以正常解析,但如果不了解GML的Schema约束,就可能无法正确提取几何信息和属性信息。因此,处理GML数据通常需要借助专门的地理数据解析库,而不是仅依赖通用的XML解析工具。
GML文档结构解析与示例
一个完整的GML文档通常会包含XML声明、命名空间声明、根元素、地理要素以及几何对象等部分。根元素一般使用<gml:FeatureCollection>来表示一个要素集合,集合内部可以包含多个<gml:featureMember>子元素,每个子元素对应一个具体的地理要素。地理要素中既可以定义名称、面积等属性字段,也可以通过<gml:boundedBy>和<gml:geometry>来描述空间范围和几何形状。
下面是一个描述城市公园的GML文档示例。该示例展示了一个面几何类型,通过<gml:Polygon>元素定义了公园的边界,并同时给出了公园的名称和面积属性。需要注意的是,示例中的坐标数据使用了WGS84坐标系,这是地理数据中最常见的空间参考系之一。
<?xml version="1.0" encoding="UTF-8"?>
<gml:FeatureCollection
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/gml/3.2 http://schemas.opengis.net/gml/3.2.1/gml.xsd">
<!-- 单个地理要素:城市公园 -->
<gml:featureMember>
<Park gml:id="park_001">
<name>中心公园</name>
<area>120000</area>
<gml:boundedBy>
<gml:Envelope srsName="EPSG:4326">
<gml:lowerCorner>39.908 116.397</gml:lowerCorner>
<gml:upperCorner>39.912 116.402</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
<!-- 公园的几何范围,为一个多边形 -->
<gml:geometry>
<gml:Polygon gml:id="polygon_001" srsName="EPSG:4326">
<gml:exterior>
<gml:LinearRing>
<gml:posList>39.908 116.397 39.908 116.402 39.912 116.402 39.912 116.397 39.908 116.397</gml:posList>
</gml:LinearRing>
</gml:exterior>
</gml:Polygon>
</gml:geometry>
</Park>
</gml:featureMember>
</gml:FeatureCollection>
在这个示例中,<gml:Envelope>元素给出了整个要素的最小外接矩形范围,即下角点和上角点坐标。而<gml:Polygon>元素则通过外环坐标串精确描述了多边形的边界。这种先给出范围信息、再给出精确几何信息的方式,可以在数据预览和快速检索时减少不必要的计算开销。
需要注意的是,GML中的几何元素通常必须指定srsName属性。这个属性用于声明几何坐标所使用的空间参考系统。如果省略该属性或者使用了错误的坐标系定义,那么在数据交换过程中就可能导致坐标解析错误,进而造成位置偏差。因此,编写GML文档时,为每个几何对象明确设置坐标系是一项基本要求。
GML的典型应用场景与工程实践
GML在多个地理信息相关场景中都有广泛的应用。在传统地理信息系统之间的数据交换中,GML可以作为一种中立的交换格式,帮助不同厂商的软件彼此导入和导出地理数据,从而降低系统集成的难度。在Web地理信息服务领域,许多符合开放地理空间联盟规范的服务接口都默认使用GML作为数据响应格式,客户端通过解析GML可以方便地获取地理要素信息。此外,由于GML是一种开放且不依赖特定商业软件的文本格式,它也非常适合用来进行地理数据的长期归档保存。
- 地理信息系统之间的数据交换:不同厂商的GIS平台可以通过GML实现数据互操作。
- Web地理服务的数据传输:开放地理空间联盟定义的Web要素服务等接口常以GML作为输出格式。
- 地理数据的长期归档:开放文本格式适合长期保存,不会因为软件版本更新而失效。
- 移动端或轻量级应用的地理数据获取:结构化文本便于按需解析和提取局部数据。
在实际工程中生成GML数据时,通常不建议手工拼接XML字符串。因为GML的结构较为复杂,而且不同版本之间的元素定义存在差异,手动拼接容易产生语法错误或Schema校验失败的问题。更合理的做法是使用成熟的地理数据操作库来完成GML的编码和解码工作。例如,在Java环境下可以使用GeoTools,在Python环境下可以使用OGR库。这些工具已经内置了对GML格式的支持,开发者只需要关注业务逻辑,而不必关心底层的XML细节。
下面给出一个使用Python的OGR库生成简单GML数据文件的示例。该示例创建了一个包含点要素的GML图层,设置坐标系为WGS84,并写入一个字段和一个测试点。
# Python使用OGR库生成简单GML示例
from osgeo import ogr, osr
# 创建GML数据源,输出到文件
driver = ogr.GetDriverByName('GML')
data_source = driver.CreateDataSource('test.gml')
# 定义坐标系为WGS84
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)
# 创建点几何类型的图层
layer = data_source.CreateLayer('point_layer', srs, ogr.wkbPoint)
# 添加一个字符串类型的字段
field_name = ogr.FieldDefn('name', ogr.OFTString)
layer.CreateField(field_name)
# 创建点要素并设置几何与属性
point = ogr.Geometry(ogr.wkbPoint)
point.AddPoint(116.4, 39.9)
feature = ogr.Feature(layer.GetLayerDefn())
feature.SetGeometry(point)
feature.SetField('name', '测试点')
layer.CreateFeature(feature)
# 释放资源,确保数据写入文件
feature = None
data_source = None
在工程实践中,除了坐标系和版本兼容性问题之外,还需要关注GML数据量的问题。由于GML是基于文本的XML格式,它在数据体积上通常比二进制格式更大,因此在海量地理数据传输场景中,可能需要结合压缩手段或者选择更高效的编码方式。不过,对于那些注重开放性、可读性和长期可维护性的应用场景,GML仍然是一个非常可靠的选择。
总体而言,GML的价值在于它为地理空间数据提供了一套标准化、可扩展、可验证的编码方案。使用GML可以降低不同系统之间的集成成本,提升地理数据的共享效率,同时也为地理数据的长期保存提供了可靠保障。对于从事地理信息系统开发或数据处理的工程人员来说,理解GML的基本结构、掌握GML与XML的关系,并熟悉常用工具库中与GML相关的操作方法,是构建高质量地理数据应用的重要基础。
总结来看,GML作为基于XML的地理空间数据标准,其核心优势体现在开放性、结构化和跨平台能力上。在实际应用中,开发者应当重视坐标系统的声明、Schema版本的匹配以及专用解析工具的选用,从而避免数据解析错误和互操作性问题。通过合理使用GML,可以有效打通不同地理信息系统之间的数据壁垒,让地理信息在更广泛的场景中顺畅流动。