GML全称为Geography Markup Language,也就是地理标记语言,是开放地理空间联盟制定的基于XML的地理空间数据编码标准,用来描述地理要素、空间几何对象以及相关的属性信息,实现不同地理信息系统之间的数据互通。

GML的核心定位
GML本质是XML的一个应用子集,它继承了XML的可扩展、自描述、平台无关的特性,同时针对地理空间数据的特点做了专门的规范。和普通的XML文档不同,GML文档必须遵循开放地理空间联盟定义的GML Schema,才能被正确解析和使用。
它的核心作用是将地理要素(比如道路、河流、建筑物)的空间位置信息(点、线、面等几何类型)和属性信息(比如道路名称、河流长度、建筑物层数)统一封装在一个结构化的文档中,避免不同系统之间因为数据格式不兼容导致的信息丢失。
GML与XML的关系
GML完全基于XML的语法规则构建,所有GML文档都是合法的XML文档,但合法的XML文档不一定是GML文档。两者的核心区别如下:
| 对比维度 | XML | GML |
|---|---|---|
| 定义主体 | 万维网联盟 | 开放地理空间联盟 |
| 适用领域 | 通用数据描述 | 地理空间数据描述 |
| Schema约束 | 用户自定义或通用Schema | 必须遵循GML专用Schema |
| 内置元素 | 无领域特定元素 | 内置<Point>、<LineString>、<Polygon>等地理元素 |
GML的基本结构示例
下面是一个描述一个城市公园的GML文档示例,包含公园的位置(面几何)和属性信息:
<?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的常见应用场景
- 地理信息系统之间的数据交换:不同厂商的GIS软件可以通过GML格式导出导入数据,避免格式壁垒。
- Web地理服务的数据传输:很多OGC标准的Web服务(比如WFS)默认使用GML作为数据输出格式。
- 地理数据的长期归档:GML是开放标准,不依赖特定软件,适合长期存储地理数据。
- 移动端地理数据轻量传输:GML的结构化特性可以让移动端快速解析需要的地理要素信息。
GML的使用注意事项
在使用GML处理地理数据时,需要注意坐标系的定义,所有几何元素都需要通过srsName属性指定对应的空间参考系,否则解析出来的位置信息会出现偏差。另外,GML的版本较多,不同版本的元素定义有差异,开发时需要确认使用的Schema版本和解析工具的兼容性。
如果需要生成GML数据,可以使用常见的GIS库,比如Java的GeoTools、Python的OGR库,这些库都内置了GML的编码和解码功能,不需要手动拼接XML字符串,避免语法错误。
# Python使用OGR库生成简单GML示例
from osgeo import ogr, osr
# 创建内存数据源
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