OpenLayers是什么
OpenLayers是一个开源的JavaScript地图开发库,用于在Web浏览器中创建交互式地图应用。
它可以帮助开发者在网页中实现:
- 地图显示
- 地图缩放
- 地图平移
- 图层管理
- 矢量数据展示
- GeoJSON加载
- WKT数据处理
- 地图交互
- 空间要素编辑
- 坐标转换
- 地图事件处理
简单来说:
OpenLayers是一套用于开发WebGIS地图应用的JavaScript库。
例如:
OpenLayers
↓
创建Map
↓
添加Layer
↓
加载Source
↓
管理Feature
↓
显示Geometry
↓
浏览器地图
OpenLayers能够做什么
OpenLayers主要用于构建WebGIS应用。
常见功能包括:
地图
├── 缩放
├── 平移
├── 旋转
├── 图层
├── 标注
├── 要素
├── 绘制
├── 编辑
├── 查询
└── 空间数据展示
例如一个城市地图可以包含:
底图
├── 道路
├── 河流
├── 建筑物
├── 行政区
├── POI
└── 业务数据
这些数据都可以通过OpenLayers显示在浏览器中。
OpenLayers与GIS的关系
GIS是一整套地理信息系统技术。
OpenLayers则主要负责:
Web端地图显示与交互
可以理解为:
GIS
│
├── 空间数据库
├── 空间分析
├── 坐标系统
├── 数据格式
├── 地图服务
└── WebGIS
↓
OpenLayers
OpenLayers本身不是空间数据库,也不是完整的GIS软件。
它更像是:
WebGIS前端地图引擎。
OpenLayers基本结构
OpenLayers最核心的结构可以理解为:
Map
│
├── View
│
├── Layer
│ ├── TileLayer
│ └── VectorLayer
│
└── Control
而Layer下面通常还有:
Layer
↓
Source
↓
Feature
↓
Geometry
因此完整结构可以表示为:
Map
↓
Layer
↓
Source
↓
Feature
↓
Geometry
这是理解OpenLayers最重要的结构之一。
Map
Map是OpenLayers地图的核心对象。
创建地图:
import Map from 'ol/Map.js'
const map = new Map({
target: 'map'
})
其中:
Map
↓
整个地图实例
Map负责组织:
- 图层
- 视图
- 控件
- 交互
- 地图事件
例如:
Map
├── View
├── Layers
├── Controls
└── Interactions
target
OpenLayers地图需要挂载到HTML元素。
例如:
<div id="map"></div>
然后:
const map = new Map({
target: 'map'
})
这样OpenLayers就会将地图渲染到:
#map
元素中。
View
View用于控制地图的观察状态。
例如:
import View from 'ol/View.js'
const view = new View({
center: [12950000, 4850000],
zoom: 10
})
然后:
const map = new Map({
target: 'map',
view
})
View主要负责:
- 中心点
- 缩放级别
- 旋转角度
- 分辨率
- 投影
可以理解为:
Map
↓
View
↓
决定用户看到地图的哪个位置
center
center表示地图中心点。
例如:
center: [12950000, 4850000]
这里的坐标通常需要与地图View使用的投影一致。
WebGIS中常见的是:
EPSG:3857
zoom
zoom表示地图缩放级别。
例如:
zoom: 10
通常:
zoom越小
↓
看到范围越大
zoom越大
↓
看到范围越小
可以理解为:
zoom 3
↓
全国范围
zoom 10
↓
城市范围
zoom 16
↓
街道范围
具体效果取决于地图View和分辨率配置。
Layer
Layer是地图图层。
OpenLayers常见Layer包括:
TileLayer
VectorLayer
ImageLayer
WebGLTile
例如:
import TileLayer from 'ol/layer/Tile.js'
const layer = new TileLayer({
source
})
然后:
map.addLayer(layer)
地图就可以显示这个图层。
TileLayer
TileLayer主要用于显示瓦片地图。
例如:
import TileLayer from 'ol/layer/Tile.js'
import OSM from 'ol/source/OSM.js'
const layer = new TileLayer({
source: new OSM()
})
map.addLayer(layer)
结构:
TileLayer
↓
OSM Source
↓
地图瓦片
常用于:
- OSM底图
- XYZ地图
- WMTS
- 其他瓦片服务
VectorLayer
VectorLayer用于显示矢量数据。
例如:
import VectorLayer from 'ol/layer/Vector.js'
const layer = new VectorLayer({
source
})
map.addLayer(layer)
结构:
VectorLayer
↓
VectorSource
↓
Feature
↓
Geometry
常用于:
- 点
- 线
- 面
- GeoJSON
- WKT
- 用户绘制数据
- 业务要素
Source
Source用于管理Layer的数据来源。
例如:
Layer
↓
Source
不同Layer通常对应不同类型的Source。
例如:
TileLayer
↓
TileSource
VectorLayer
↓
VectorSource
VectorSource:
import VectorSource from 'ol/source/Vector.js'
const source = new VectorSource()
它可以管理多个Feature。
Feature
Feature是OpenLayers中的地图要素。
例如一个城市:
Feature
├── Geometry
│ └── Point
│
└── Properties
├── name
└── type
创建Feature:
import Feature from 'ol/Feature.js'
例如:
const feature = new Feature({
geometry,
name: '北京'
})
Feature主要由两部分组成:
Feature
├── Geometry
└── Properties
因此:
Feature可以理解为一个具有空间几何和属性信息的GIS对象。
Geometry
Geometry负责描述空间形状。
常见类型:
Point
LineString
Polygon
MultiPoint
MultiLineString
MultiPolygon
例如:
import Point from 'ol/geom/Point.js'
const point = new Point([
12950000,
4850000
])
然后:
const feature = new Feature({
geometry: point
})
关系:
Feature
↓
Geometry
↓
Point
Feature属性
Feature除了Geometry,还可以保存业务属性。
例如:
const feature = new Feature({
geometry: point,
name: '北京',
type: 'city',
level: 1
})
读取:
feature.get('name')
得到:
北京
也可以:
feature.getProperties()
获得所有属性。
因此:
Feature
├── geometry
├── name
├── type
└── level
VectorSource
VectorSource是矢量Feature的容器。
例如:
const source = new VectorSource({
features: [
feature
]
})
也可以动态添加:
source.addFeature(feature)
添加多个:
source.addFeatures(features)
获取:
source.getFeatures()
结构:
VectorSource
├── Feature
├── Feature
├── Feature
└── Feature
VectorLayer与VectorSource
VectorLayer负责显示:
VectorLayer
VectorSource负责管理数据:
VectorSource
因此:
VectorLayer
↓
VectorSource
↓
Feature[]
可以理解为:
Layer
↓
负责地图显示
Source
↓
负责数据管理
GeoJSON
OpenLayers支持GeoJSON。
首先:
import GeoJSON from 'ol/format/GeoJSON.js'
读取GeoJSON:
const format = new GeoJSON()
const features = format.readFeatures(data)
然后:
const source = new VectorSource({
features
})
最后:
const layer = new VectorLayer({
source
})
完整流程:
GeoJSON
↓
GeoJSON Format
↓
Feature[]
↓
VectorSource
↓
VectorLayer
↓
Map
WKT
OpenLayers也支持WKT。
例如:
POINT (116.397 39.908)
可以使用:
import WKT from 'ol/format/WKT.js'
const format = new WKT()
const feature = format.readFeature(wkt)
然后:
WKT
↓
readFeature()
↓
Feature
↓
VectorSource
↓
VectorLayer
坐标系
OpenLayers中的地图坐标非常依赖坐标参考系统。
常见:
EPSG:4326
EPSG:3857
例如:
GeoJSON
EPSG:4326
↓
坐标转换
↓
OpenLayers
EPSG:3857
读取GeoJSON时:
const features = format.readFeatures(data, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
})
因此开发OpenLayers应用时必须明确:
数据坐标系
↓
地图坐标系
Projection
OpenLayers中的View可以指定projection。
例如:
const view = new View({
projection: 'EPSG:3857',
center: [12950000, 4850000],
zoom: 10
})
这样地图View就使用:
EPSG:3857
作为地图坐标系。
地图控件
OpenLayers提供了一系列Controls。
例如:
Zoom
Rotate
FullScreen
ScaleLine
MousePosition
OverviewMap
ZoomSlider
例如:
import ScaleLine from 'ol/control/ScaleLine.js'
map.addControl(
new ScaleLine()
)
可以在地图上显示比例尺。
地图交互
OpenLayers支持多种地图交互。
常见:
缩放
平移
旋转
绘制
修改
选择
拖拽
例如Draw:
import Draw from 'ol/interaction/Draw.js'
const draw = new Draw({
source,
type: 'Point'
})
map.addInteraction(draw)
用户就可以在地图上绘制Point。
Select
可以通过Select选择地图要素。
例如:
import Select from 'ol/interaction/Select.js'
const select = new Select()
map.addInteraction(select)
当用户点击Feature时,可以获取选中的要素。
select.on('select', event => {
console.log(event.selected)
})
Modify
Modify用于编辑Feature。
例如:
import Modify from 'ol/interaction/Modify.js'
const modify = new Modify({
source
})
map.addInteraction(modify)
用户可以直接拖动Geometry的节点修改空间数据。
Draw
Draw可以创建:
Point
LineString
Polygon
Circle
例如绘制Polygon:
const draw = new Draw({
source,
type: 'Polygon'
})
用户绘制完成后:
Draw
↓
Geometry
↓
Feature
↓
VectorSource
Style
OpenLayers中的Feature可以设置样式。
例如:
import Style from 'ol/style/Style.js'
import Fill from 'ol/style/Fill.js'
import Stroke from 'ol/style/Stroke.js'
const style = new Style({
fill: new Fill({
color: 'rgba(0, 120, 255, 0.2)'
}),
stroke: new Stroke({
color: '#0078ff',
width: 2
})
})
然后:
const layer = new VectorLayer({
source,
style
})
这样VectorLayer中的Feature就可以按照指定样式显示。
Point样式
Point通常使用:
Circle
Icon
Text
例如:
import CircleStyle from 'ol/style/Circle.js'
const style = new Style({
image: new CircleStyle({
radius: 6,
fill: new Fill({
color: '#1677ff'
})
})
})
LineString样式
LineString通常使用Stroke:
const style = new Style({
stroke: new Stroke({
color: '#1677ff',
width: 3
})
})
适用于:
- 道路
- 河流
- 管线
- GPS轨迹
Polygon样式
Polygon通常使用:
Fill
Stroke
例如:
const style = new Style({
fill: new Fill({
color: 'rgba(22, 119, 255, 0.2)'
}),
stroke: new Stroke({
color: '#1677ff',
width: 2
})
})
OpenLayers事件
OpenLayers提供大量事件。
例如:
click
singleclick
pointermove
movestart
moveend
监听点击:
map.on('singleclick', event => {
console.log(event.coordinate)
})
可以获得点击位置。
Feature点击查询
可以通过:
map.forEachFeatureAtPixel()
查询鼠标点击位置的Feature。
例如:
map.on('singleclick', event => {
map.forEachFeatureAtPixel(
event.pixel,
feature => {
console.log(feature)
}
)
})
流程:
用户点击地图
↓
Pixel
↓
forEachFeatureAtPixel()
↓
Feature
这是WebGIS业务开发中非常常见的功能。
地图数据来源
OpenLayers可以加载很多类型的数据。
例如:
GeoJSON
WKT
KML
GPX
TopoJSON
XYZ
WMTS
WMS
Vector Tile
可以理解为:
数据格式
↓
OpenLayers Format / Source
↓
Layer
↓
Map
WMS
WMS主要用于加载地图服务。
通常:
WMS
↓
ImageLayer / TileLayer
↓
Map
WMS返回的通常是地图图片,而不是普通Feature集合。
适合:
- 地图服务
- 专题图
- 服务端渲染地图
WMTS
WMTS是瓦片地图服务。
通常:
WMTS
↓
TileLayer
↓
Map
适合高性能地图浏览。
XYZ
XYZ是Web地图中非常常见的瓦片组织方式。
典型结构:
/{z}/{x}/{y}.png
其中:
z
↓
缩放级别
x
↓
列
y
↓
行
OpenLayers可以使用XYZ Source加载这种地图。
Vector Tile
Vector Tile用于高性能矢量地图。
例如:
MVT
↓
VectorTileSource
↓
VectorTileLayer
↓
Map
相比大量普通Feature,Vector Tile更适合:
- 大规模道路
- 城市地图
- 全国地图
- 高性能矢量地图
OpenLayers与Cesium
OpenLayers主要用于:
二维WebGIS
而Cesium主要用于:
三维地球
可以简单理解为:
OpenLayers
↓
2D地图
Cesium
↓
3D地球
如果主要需求是:
- 业务地图
- GIS数据编辑
- GeoJSON
- WMS
- WFS
- 矢量图层
OpenLayers非常适合。
如果主要需求是:
- 三维地球
- 地形
- 三维建筑
- 三维城市
- 大规模三维场景
则通常考虑Cesium。
OpenLayers完整数据结构
一个典型OpenLayers地图可以理解为:
Map
│
├── View
│
├── Controls
│
├── Interactions
│
└── Layers
│
├── TileLayer
│ └── TileSource
│
└── VectorLayer
└── VectorSource
│
├── Feature
│ ├── Geometry
│ └── Properties
│
├── Feature
│ ├── Geometry
│ └── Properties
│
└── Feature
这是学习OpenLayers最重要的一张结构图。
OpenLayers核心对象
可以将OpenLayers核心对象分成几个部分。
地图
Map
View
图层
Layer
TileLayer
VectorLayer
数据源
Source
VectorSource
XYZ
WMTS
WMS
空间要素
Feature
Geometry
数据格式
GeoJSON
WKT
KML
GPX
交互
Select
Draw
Modify
Translate
控件
Zoom
ScaleLine
FullScreen
MousePosition
OpenLayers开发基本流程
一个典型OpenLayers项目通常按照以下步骤开发:
1. 创建Map
↓
2. 创建View
↓
3. 创建地图底图
↓
4. 创建Source
↓
5. 加载数据
↓
6. 创建Layer
↓
7. 添加到Map
↓
8. 添加Interaction
↓
9. 添加Control
↓
10. 处理业务事件
例如:
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new OSM()
})
],
view: new View({
center: [12950000, 4850000],
zoom: 10
})
})
一个简单的矢量地图
import Map from 'ol/Map.js'
import View from 'ol/View.js'
import Feature from 'ol/Feature.js'
import Point from 'ol/geom/Point.js'
import VectorSource from 'ol/source/Vector.js'
import VectorLayer from 'ol/layer/Vector.js'
const feature = new Feature({
geometry: new Point([
12950000,
4850000
]),
name: '示例点'
})
const source = new VectorSource({
features: [feature]
})
const layer = new VectorLayer({
source
})
const map = new Map({
target: 'map',
layers: [
layer
],
view: new View({
center: [
12950000,
4850000
],
zoom: 10
})
})
数据关系:
Point
↓
Feature
↓
VectorSource
↓
VectorLayer
↓
Map
OpenLayers的核心思想
学习OpenLayers时,不要只记API。
最重要的是理解:
Map
↓
Layer
↓
Source
↓
Feature
↓
Geometry
其中:
Map
↓
管理整个地图
Layer
↓
负责图层
Source
↓
负责数据来源
Feature
↓
负责空间要素
Geometry
↓
负责空间形状
另外:
View
↓
控制地图视角
Interaction
↓
处理用户操作
Control
↓
提供地图控件
Format
↓
处理GIS数据格式
OpenLayers与GeoJSON的关系
GeoJSON是数据格式:
GeoJSON
OpenLayers是地图开发库:
OpenLayers
二者不是同一个概念。
通常:
GeoJSON
↓
GeoJSON Format
↓
Feature
↓
VectorSource
↓
VectorLayer
↓
OpenLayers Map
OpenLayers与Feature的关系
Feature是OpenLayers地图中的核心矢量对象。
OpenLayers
↓
Feature
↓
Geometry + Properties
Feature可以来自:
GeoJSON
WKT
KML
Draw
API
数据库
手工创建
因此Feature是连接外部GIS数据和OpenLayers地图的重要对象。
OpenLayers与Geometry的关系
Geometry描述空间形状:
Point
LineString
Polygon
Feature持有Geometry:
Feature
↓
Geometry
VectorSource管理Feature:
VectorSource
↓
Feature[]
VectorLayer显示VectorSource:
VectorLayer
↓
VectorSource
最终:
Geometry
↓
Feature
↓
VectorSource
↓
VectorLayer
↓
Map
总结
OpenLayers是一个用于开发WebGIS应用的开源JavaScript地图库。
它的核心结构可以记住:
Map
↓
Layer
↓
Source
↓
Feature
↓
Geometry
其中:
Map
↓
地图容器
View
↓
地图视角
Layer
↓
地图图层
Source
↓
数据来源
Feature
↓
空间要素
Geometry
↓
空间形状
Interaction
↓
用户交互
Control
↓
地图控件
Format
↓
GIS数据格式转换
最重要的开发思维是:
OpenLayers负责Web地图的显示和交互,Layer负责组织图层,Source负责管理数据,Feature负责描述空间要素,Geometry负责描述空间形状,而GeoJSON、WKT等负责与外部GIS数据进行交换。
掌握这套结构之后,就可以继续学习OpenLayers中的Map、View、Layer、Source、Feature、Geometry、GeoJSON、WKT、Draw、Select以及Modify等核心知识。
相关工具
使用 IYATools 在线工具快速处理 GIS 数据