---
title: GML 地理标记语言
date: 2020-03-02
author: ac
tags:
- GML
categories:
- GIS
---

## 1 GML简介
GML(OpenGIS® Geography Markup Language Encoding Standard)是一种基于XML的地理要素描述语言标准,用以在不同的软件或系统间交换空间数据,比如WFS标准就使用GML作为输入和输出格式。同时GML也是地理系统的建模语言,也是Internet上地理事务的开放交换格式。与大多数基于XML的语法一样,语法分为两部分:
- 描述文档的`schema`模式;
- 包含实际数据的实例文档。
地理标记语言(GML)是开放地理空间联盟(OGC)定义的基于XML的规范,用于表达地理特征。
- 较旧的GML标准GML 2对地理信息进行编码,包括空间和非空间属性。
- GML3将GML2支持范围扩展到3D形状(曲面和实体)以及其他高级功能。
- GML3采用不同的方式指定几何要素。GeoServer支持GML3和GML2格式的请求。
GML 3是GML 2的模块化超集,它通过允许用户选择必要的部分来简化并最小化实现规模。GML 3中的新增功能包括对复杂的几何图形,空间和时间参考系统,拓扑,度量单位,元数据,网格数据以及用于要素和覆盖范围可视化的默认样式的支持。GML 3几乎完全向后兼容GML 2。
版本之间对几何字段的xml表示方式不同,有很多标签不一样,比如 MultiLineString 在GML3中已经没有了,详细差异可以对比相关规范。
## 2 XML
> 由于GML是基于XML的,所以我们现在了解一下XML的相关知识。
### 2.1 XML基础
XML(Extend Markup Languge,可扩展标签语言)是一种*标记语言*,很类似 HTML 。但XML被设计出来的目的为了传输和存储数据,其标签可以有开发者自定义(当然要按照一定的语法),XML 没有预定义的标签 。作用:
- 描述带关系的数据(可以作为软件的配置文件):包含与被包含的关系。
properties文件是键值对的形式:key-value;
```properties
name=Jack
password=67017
```
使用xml文件描述就是:
```xml
Jack
67017
```
- 作为数据的载体(存储数据,小型的"数据库")
XML文件格式是纯文本格式,使用需要注意:
1. 必须有声明语句。XML文档的第一句必须是:
```xml
```
> 版本应该就只有1.0了,因为XML相对于另一种数据传输格式JSON,太过臃肿。
2. 注意大小写。XML是大小写敏感的。
3. XML文档有且只有一个根元素。
4. 属性值使用引号。
5. 所有的标记必须有相应的结束标记 ,空标签也要关闭。
### 2.2 DTD
> [GML1.0](https://portal.ogc.org/files/?artifact_id=7197)的文档中使用的约束是DTD约束。
DTD(文档类型定义)文件是定义 XML 文档的合法构建模块。它使用一系列的合法元素来定义XML文档结构。
上述我们知道XML文档的标签是可以开发者自定义的,所以这会导致一个问题:不同的开发者可能会根据不同的需求,对同一个对象使用XML描述会有多种多样的形式。为了避免这种情况,所以出现了DTD文件对XML文档的结构进行约束。
DTD文件也是XML文档,在使用的时候可以在XML文件内部使用`DOCTYPE`声明,也可以作为一个外部引用。
1. XML内部声明。语法:
```xml
```
带有DTD的XML实例:
```xml
]>
George
John
Reminder
Don't forget the meeting!
```
第三行定义 *note* 元素有四个子元素:"to、from、heading、body"
>
> PCDATA 的意思是被解析的字符数据(parsed character data),也就是一个文本。比如你定义个年龄,姓名等等,都是字符串。约束的时候,它的顺序必须也是按着顺序来,否则就会报错。
2. 外部引用。语法:
```xml
```
XML文档引用外部DTD示例:
```xml
George
John
Reminder
Don't forget the meeting!
```
包含的note.dtd文件:
```xml
```
从上面的示例可以了解到,DTD元素的声明格式为:
```xml
或
```
对于元素的内容的限定,dtd也提供了支持:
1. 空元素:\
2. 带有任何内容的元素:\
3. 带有子元素(序列)的元素:\ 或者 \
4. 声明最少出现一次的元素:\
5. 声明出现零次或多次的元素:\
6. 声明出现零次或一次的元素:\
7. 声明“非.../既...”类型的内容:\
```xml
]>
```
**DTD属性**:声明标签内的属性及约束。语法:
```xml
```
以下是**属性类型**的选项:
| 类型 | 描述 |
| :----------------- | :---------------------------- |
| CDATA | 值为字符数据 (character data) |
| (*en1*\|*en2*\|..) | 此值是枚举列表中的一个值 |
| ID | 值为唯一的 id |
| IDREF | 值为另外一个元素的 id |
| IDREFS | 值为其他 id 的列表 |
| NMTOKEN | 值为合法的 XML 名称 |
| NMTOKENS | 值为合法的 XML 名称的列表 |
| ENTITY | 值是一个实体 |
| ENTITIES | 值是一个实体列表 |
| NOTATION | 此值是符号的名称 |
| xml: | 值是一个预定义的 XML 值 |
**默认值**参数可使用下列值:
| 值 | 解释 |
| :----------- | :------------- |
| 值 | 属性的默认值 |
| #REQUIRED | 属性值是必需的 |
| #IMPLIED | 属性不是必需的 |
| #FIXED value | 属性值是固定的 |
### 2.3 schema
> GML2.0开始,使用的约束都是schema。
XML Schema 是基于 XML 的 DTD 替代者,也是用于描述 XML 文档的结构。
XML Schema 语言也称作 XML Schema 定义(XML Schema Definition, XSD)
**Schema示例:**
创建一个叫note.xsd的Schema文件:
```xml
```
note 元素是一个复合类型,因为它包含其他的子元素。其他元素 (to, from, heading, body) 是String类型,因为它们没有包含其他元素。
引用Schema:
```xml
George
John
Reminder
Don't forget the meeting!
```
## 3 GML
### 3.1 理论基础
GML模型是用于存储和传输地理信息的,包含几何形状(`geometry`)和地理要素的属性(`properties`)信息,这个规范的最初发布与OGC的`OpenGIS Abstract Specification`有关。
"A feature is an abstraction of a real world phenomenon; it is a geographic feature if it is associated with a location relative to the Earth."
真实世界的数字表示可以被认为是一组特征(`Features`)。特性(`feature`)的状态是由一组属性定义的,其中每个属性可以看作是`{name, type, value}`三元组。一个`feature`拥有的属性数量,以及它的名称`name`和类型`type`,由它的feature type决定。地理要素(Geographic Feature)的值(`value`)可以是一个`geometry`。
### 3.2 GML1.0
`GML1.0`中涉及的简单要素模型如下图:
`GML1.0`提供的`geometry`元素有以下的类:
1. Point
2. LineString
3. LinearRing
4. Polygon
5. MultiPoint
6. MultiLineString
7. MultiPolygon
8. GeometryCollection
另外提供一个`coordinatres`元素用于编码坐标和一个`Box`元素用于表示范围(extents),
---
**Coordinates Element**
坐标元素标签是一组坐标的几何,用于描述几何对象的位置信息。
coordinates 的DTD约束如下:
```xml
```
示例:
```xml
1.03,2.167 4.167,2.34 4.87,3.0 1.06,2.3
```
> 注意:坐标值必须是相同的维度。 cs(coordinate separated):坐标之间的分隔符; ts(tuples separated):坐标元组之间分隔符;
---
**Point Element**
点元素标签用于描述一个点要素实例,坐标标签中有且只有一个坐标点。
Point 的DTD(XML的约束文件)如下:
```xml
```
Point 标签下面可以有 coordinates 标签用于描述点位信息。有ID、srsName 属性,srsName 指定要素的空间参考。
示例:
```xml
56.1,0.45
```
---
**Box Element**
用于描述一个范围 extent,坐标值为范围的左下角(最小值)和右上角(最大值)点。
其DTD约束如下:
```xml
```
示例:
```xml
0.0,0.0 100.0,100.0
```
---
**LineString Element**
是一个分段的线状路径,用于描述线要素,至少两个点。
其DTD约束如下:
```xml
```
示例:
```xml
0.0,0.0 100.0,100.0
```
---
**LinearRing Element**
是一段封闭的分段的线状路径,(coordinates 标签中)至少4个坐标点,三个坐标可以确定 LinearRing,第四个坐标用于闭合,与第一个坐标相同。
其DTD约束如下:
```xml
```
> 用于构造面元素(Polygon),所以不需要SRS属性,
示例:
```xml
0.0,0.0 100.0,0.0 50.0,100.0 0.0,0.0
```
---
**Polygon Element**
用于描述面要素(surface)。
必须有一个且最多只有一个 Exterior boundary 和 零个或多个 Interior boundary。Interior boundary 之间不能相交或包含。
其DTD约束如下:
```xml
```
示例:
```xml
0.0,0.0 100.0,0.0 100.0,100.0 0.0,100.0 0.0,0.0
10.0,10.0 10.0,40.0 40.0,40.0 40.0,10.0 10.0,10.0
60.0,60.0 60.0,90.0 90.0,90.0 90.0,60.0 60.0,60.0
```
---
**MultiPointElement**
是点要素的集合。
其DTD约束如下:
```xml
```
> srsName 属性只能出现在最外层要素的标签内,且其包含的子要素不能再出现 srsName属性。
示例:
```xml
56.1,0.45
46.71,9.25
56.88,10.44
```
---
**MultiLineString**
线要素的集合。
其DTD约束如下:
```xml
```
> 跟 MuliPointElement 标签一样,srsName 属性只能出现在最外层要素上。
示例:
```xml
56.1,0.45 67.23,0.67
46.71,9.25 56.88,10.44
324.1,219.7 0.45,0.56
```
---
**MultiPolygon Element**
是面要素的集合。
其DTD约束如下:
```xml
```
示例:
```xml
0.0,0.0 10.0,0.0 10.0,10.0 0.0,10.0
0.0,0.0
40.0,40.0 50.0,40.0 50.0,50.0 40.0,50.0
40.0,40.0
```
---
**GeometryCollection (几何对象集合)**
可以包含任意几何类型的要素。
>srsName 属性应该在最外层要素对象中定义,且在其包含的几何对象中不能再出现。
其DTD如下:
```xml
```
其中的 geometryMember 子标签可以包含任意类型的几何对象。
示例:
```xml
50.0,50.0
0.0,0.0 0.0,50.0 100.0,50.0 100.0,100.0
0.0,0.0 100.0,0.0 50.0,100.0 0.0,0.0
```
### 3.3 GML2.0
`GML2.0`延续了1.0中使用的要素模型,并提供了更精确的几何模型。

The geometry model for simple features
简单特征的几何对象模型有一个(抽象的)基本geometry类,并将每个几何对象与描述定义对象的坐标空间的SRS关联起来。
> GML2.0开始使用的是schema约束
GML 2.0对空间要素`feature`进行编码需要使用两个`XML Schemas`:
- `Geometry.xsd`:包括抽象几何元素和具体几何元素的类型,定义(多)点、线和多边形几何元素,以及基础几何类型的复杂类型。
- `feature.xsd`:定义了要素的全局属性(*Feature*,*FeatureCollection*)、基本的几何属性及其别名(*geometryProperty*),其约束包含了上面的`geometry.xsd`用于限定要素表中的几何字段的类型。
通过这两个简单的模式,可以对各种地理空间信息进行编码。
可以看出`feature.xsd`已经包含所有的约束,所以在资源表的约束上引用该xsd文件即可。
以一个`WFS`的`DescribeFeatureType`操作为例:
url:`http://localhost:8080/geoserver/wfs`
Post内容如下:
```xml
topp:states
```
> WFS 1.0.0请求以默认格式返回GML 2。
响应结果是一个是`states`资源表的`Schema`:
```xml
```
**GML2.0中的Geometry编码方式**
在`Geometry.xsd`文件中描述了几何对象的约束,该`Schema`的UML图如下:
增加一个`Coord`元素,用于分隔坐标。所以坐标有两种表达方式:
```xml
5.040.0
5.0,40.0
```
其他的几何对象的与`GML1.0`的没有太大区别,但空间参考`srs`的表达方式采用了`OGC HTTP URL` (http://www.opengis.net/gml/srs/epsg.xml#4326),一个具有EPSG code标识的url。坐标顺序跟直接使用EPSG Code的表达方式一样为`longitude/latitude (x/y) order`。
### 3.4 GML 3.0
GML 3是GML 2的模块化超集,它通过允许用户选择必要的部分来简化并最小化实现规模。GML 3中的新增功能包括对复杂的几何图形、空间和时间参考系统、拓扑、度量单位、元数据、网格数据以及用于要素和覆盖范围可视化的默认样式的支持。
在GML中的地理要素(`Geographic features`)包含`coverages`和`observations`子类型:
- `coverages`:是具有空间域和2到n维元组值的范围集的覆盖函数,可以表示单个feature或要素集featureCollection,所以可以模拟和可视化要素之间的空间关系以及地理现象的空间分布情况。
- `observations`:observation模拟观察的行为,通常是用相机、人或某种形式的仪器(一种识别和记录事实或事件的行为,通常涉及仪器的测量)。一个observation 被认为是一个GML的feature,带有观察发生的时间time和观察的值value。
GML3.0添加了ISO的一致性,并解决了以下需求,这些需求是上一个版本没有解决或充分满足的:
- 除了简单的二维线性特征外,还可以表示地理空间现象,包括复杂complex、非线性、三维几何特征、二维拓扑特征`topology`、具有时间`temporal`属性的特征、动态特征、覆盖`coverages`和观测`observations`;
- 为特性的属性和其他值复杂的对象提供更显式的支持;
- 提供了表示时间和空间的参考系统、度量`measure`单位和标准信息;
- 在表示地理空间现象、观测`observations`和值时使用参考系统、单位和标准信息;
- 提供feature和coverage可视化的默认样式;
- 符合ISO的相关标准(Spatial、Temporal、Encoding、 Coverages)
GML3 数据模型
GML3的geometry类型UML图
## 参考文章
[1] WFS settings https://docs.geoserver.org/latest/en/user/services/wfs/webadmin.html#gml
[2] Geography Markup Language https://www.ogc.org/standards/gml
[3] 可扩展标记语言 https://baike.baidu.com/item/%E5%8F%AF%E6%89%A9%E5%B1%95%E6%A0%87%E8%AE%B0%E8%AF%AD%E8%A8%80/2885849
[4] DTD简介 https://www.w3school.com.cn/dtd/dtd_intro.asp
[5] 如何使用 XSD https://www.w3school.com.cn/schema/schema_howto.asp