目录
一、矢量地图简介
二、在OpenLayers中直接组织矢量数据
三、通过url加载矢量数据
四、样式设置
一、矢量地图简介
前面介绍的瓦片地图将地理信息以一块块瓦片的形式进行组织并渲染,瓦片的本质是图片,因此不能对瓦片地图进行修改样式、空间分析等操作,而且瓦片不包含属性信息,隐含的空间信息也不能直接获取使用。
矢量数据使用矢量数据模型来组织地理信息,矢量数据模型采用离散对象来表示地球表面的空间要素,因此,简单来说,矢量数据包含了各个地理要素的空间坐标与属性信息,这使我们能对地理信息进行细粒度的使用与操作。
常用的矢量数据格式有GeoJSON、TopoJSON、KML、GML、shapfile等等。
在WebGIS中,使用矢量数据构成的地图被称为矢量地图,矢量地图的原理就是将包含坐标信息与属性信息的矢量数据发送到客户端,然后由客户端负责绘制矢量图层。
响应速度与交互性是矢量地图的优点,一旦从服务器获得了矢量数据,Web地图用户与数据的交互就会非常迅速,不会有任何延迟。另外,矢量图形无论进行放大、缩小或旋转等操作,图形都不会失真。
矢量地图的缺点是不能同时绘制成百上千个要素,因为矢量地图的主要操作都在客户端,所以数据量变大,客户端就会卡、慢,甚至可能崩溃。
二、在OpenLayers中直接组织矢量数据
在OpenLayers中,ol.source.Vector是矢量数据源基类,为矢量图层ol.layer.Vector类提供具体的数据来源,包括直接组织或读取的矢量数据(ol.Feature)、远程数据源的矢量数据(即通过url设置数据源路径)等。
现在我们来尝试直接在OpenLayers中组织矢量数据然后构建矢量地图:
directOrganizeVector.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>直接组织矢量数据</title>
<link rel="stylesheet" href="../../v5.3.0/css/ol.css" />
<script src="../../v5.3.0/build/ol.js"></script>
</head>
<body>
<div id="map"></div>
<script>
// 初始化一个点要素
let pointFeature = new ol.Feature({
geometry: new ol.geom.Point([12958998, 4852221]), // 空间信息
name: '点要素' // 属性信息
});
// 初始化一个线要素
let lineFeature = new ol.Feature({
// 空间信息
geometry: new ol.geom.LineString([[11590147, 4322577], [13594369, 3872784]]),
name: '线要素' // 属性信息
});
// 初始化一个多边形要素
let polygonFeature = new ol.Feature({
// 空间信息
geometry: new ol.geom.Polygon([[[11801814, 3251012], [14057391, 2748303], [12714628, 1346008], [11801814, 3251012]]]),
name: '多边形要素' // 属性信息
});
// 初始化一个矢量数据源, 并添加上面创建的要素
let vectorSource = new ol.source.Vector();
vectorSource.addFeature(pointFeature);
vectorSource.addFeature(lineFeature);
vectorSource.addFeature(polygonFeature);
// 初始化一个矢量图层
let vectorLayer = new ol.layer.Vector({
source: vectorSource
});
let map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({ // 底图
source: new ol.source.OSM()
}),
vectorLayer
],
view: new ol.View({
center: [0, 0],
zoom: 0
})
});
</script>
</body>
</html>
在OpenLayers中,使用ol.Feature类表示地理要素,一个Feature对象就表示一个地理要素。
其中,Feature对象可以包含空间信息与属性信息,在上面的示例中,Feature对象的空间信息分别通过ol.geom.Point类、ol.geom.LineString类、ol.geom.Polygon类来组织,然后再赋值给geometry参数。另外,name参数作为一个属性信息也被包含在Feature对象中。
构建了三个地理要素后,再把它们分别通过ol.source.Vector类的addFeature()方法加入到ol.source.Vector对象中,最后再通过ol.layer.Tile类构成矢量图层并一起加入到地图中。
三、通过url加载矢量数据
读取url设置的矢量数据源,需要通过解析器Format(即ol.format.Feature的子类)来解析各类矢量数据,如XML、Text、JSON、GML、KML、GPS、WFS、WKT、GeoJSON等地图数据。
解析器相关类的类结构图:
来看一个示例:
importVector_url.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>通过url加载矢量数据</title>
<link rel="stylesheet" href="../../v5.3.0/css/ol.css" />
<script src="../../v5.3.0/build/ol.js"></script>
</head>
<body>
<div id="map"></div>
<script>
// 创建地图
let map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({ // 底图
source: new ol.source.OSM()
}),
// 再加载一个geojson的矢量地图
new ol.layer.Vector({
source: new ol.source.Vector({
url: './data/line-samples.geojson', // 矢量数据来源
format: new ol.format.GeoJSON() // 解析矢量数据的解析器
})
})
],
view: new ol.View({
center: [0, 0],
zoom: 0
})
});
</script>
</body>
</html>
四、样式设置
对矢量地图进行样式设置,OpenLayers支持两种方式,一种是直接给feature设置样式,一种是给layer设置样式。系统默认优先考虑feature的样式,如果没有,则使用layer的样式,还有一种情况是layer也没有设置样式,则会采用系统默认的样式。
对于矢量地图而言,要想修改样式也只有这两种途径可选。比如之前例子中使用GeoJSON,如果要改变线条的颜色成下面这样,可以考虑在layer上设置样式:
customStyle.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>自定义矢量地图样式</title>
<link rel="stylesheet" href="../../v5.3.0/css/ol.css" />
<script src="../../v5.3.0/build/ol.js"></script>
</head>
<body>
<div id="map"></div>
<script>
// 创建地图
let map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({ // 底图
source: new ol.source.OSM()
}),
// 再加载一个geojson的矢量地图
new ol.layer.Vector({
source: new ol.source.Vector({
url: './data/line-samples.geojson', // 矢量数据来源
format: new ol.format.GeoJSON() // 解析矢量数据的解析器
}),
style: new ol.style.Style({ // 自定义矢量地图样式
stroke: new ol.style.Stroke({
color: 'red',
width: 5
})
})
})
],
view: new ol.View({
center: [0, 0],
zoom: 0
})
});
</script>
</body>
</html>
如果要在feature上设置样式,就必须先获取到所有加载的feature,然后依次设置,显然直接设置layer的样式,会在代码编写上更容易一些。
自带样式的矢量地图修改样式
有些矢量地图数据自带样式,比如KML格式的矢量地图,如果要修改样式,则相对比较麻烦。得分情况考虑:
一种是所有矢量地图都不使用自带的样式:
一种是部分矢量地图不使用自带的样式。
对于第一种情况,则相对比较简单一点,只需要把ol.format.KML的构造参数extractStyles设置为false即可,然后为layer设定自定义的样式。
对于第二种情况,则相对麻烦一些,必须要读取加载的所有feature,并进行过滤,对符合条件的feature重新设置样式。