Openlayers 实战教程 (opens new window)

# 坐标转换 proj4js

在初始化map实例时,如果不在view中用projection参数指定投影坐标系,则将会使用默认的空间参考EPSG:3857(Web 墨卡托投影)。后续叠加的图层,都会将数据进行投影转换,确保在同一个空间参考内

Openlayers中的指定空间参考可以直接使用EPSG code指定,如EPSG:4326,ol.proj.Projection已经帮我们定义好EPSG:4326和EPSG:3857这两个空间参考的参数

  • 引用proj4js文件
<script src="https://cdn.bootcss.com/proj4js/2.5.0/proj4.js"></script>
  • 定义投影坐标系统
// 国家2000地理坐标系
proj4.defs("EPSG:4490","+proj=longlat +ellps=GRS80 +no_defs");
// 国家2000平面坐标系
"EPSG:4548",
"+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// 西安 1980
"EPSG:4610",
"+proj=longlat +a=6378140 +b=6356755.288157528 +no_defs"
// WGS 84
"EPSG:4326",
"+proj=longlat +datum=WGS84 +no_defs"
// CGCS2000 / Gauss-Kruger zone 13
"EPSG:4491",
"+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=13500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger zone 14
"EPSG:4492",
"+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=14500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger zone 15
"EPSG:4493",
"+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=15500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger zone 16
"EPSG:4494",
"+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=16500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger zone 17
"EPSG:4495",
"+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=17500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger zone 18
"EPSG:4496",
"+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=18500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger zone 19
"EPSG:4497",
"+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=19500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger zone 20
"EPSG:4498",
"+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=20500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger zone 21
"EPSG:4499",
"+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=21500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger zone 22
"EPSG:4500",
"+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=22500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger zone 23
"EPSG:4501",
"+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=23500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger CM 75E
"EPSG:4502",
"+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger CM 81E
"EPSG:4503",
"+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger CM 87E
"EPSG:4504",
"+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger CM 93E
"EPSG:4505",
"+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger CM 99E
"EPSG:4506",
"+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger CM 105E
"EPSG:4507",
"+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger CM 111E
"EPSG:4508",
"+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger CM 117E
"EPSG:4509",
"+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger CM 123E
"EPSG:4510",
"+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger CM 129E
"EPSG:4511",
"+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / Gauss-Kruger CM 135E
"EPSG:4512",
"+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 25
"EPSG:4513",
"+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=25500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 26
"EPSG:4514",
"+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=26500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 27
"EPSG:4515",
"+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=27500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 28
"EPSG:4516",
"+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=28500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 29
"EPSG:4517",
"+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=29500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 30
"EPSG:4518",
"+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=30500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 31
"EPSG:4519",
"+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=31500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 32
"EPSG:4520",
"+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=32500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 33
"EPSG:4521",
"+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=33500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 34
"EPSG:4522",
"+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=34500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 35
"EPSG:4523",
"+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=35500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 36
"EPSG:4524",
"+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=36500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 37
"EPSG:4525",
"+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 38
"EPSG:4526",
"+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=38500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 39
"EPSG:4527",
"+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=39500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 40
"EPSG:4528",
"+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=40500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 41
"EPSG:4529",
"+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=41500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 42
"EPSG:4530",
"+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=42500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 43
"EPSG:4531",
"+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=43500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 44
"EPSG:4532",
"+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=44500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger zone 45
"EPSG:4533",
"+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=45500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 75E
"EPSG:4534",
"+proj=tmerc +lat_0=0 +lon_0=75 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 78E
"EPSG:4535",
"+proj=tmerc +lat_0=0 +lon_0=78 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 81E
"EPSG:4536",
"+proj=tmerc +lat_0=0 +lon_0=81 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 84E
"EPSG:4537",
"+proj=tmerc +lat_0=0 +lon_0=84 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 87E
"EPSG:4538",
"+proj=tmerc +lat_0=0 +lon_0=87 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 90E
"EPSG:4539",
"+proj=tmerc +lat_0=0 +lon_0=90 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 93E
"EPSG:4540",
"+proj=tmerc +lat_0=0 +lon_0=93 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 96E
"EPSG:4541",
"+proj=tmerc +lat_0=0 +lon_0=96 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 99E
"EPSG:4542",
"+proj=tmerc +lat_0=0 +lon_0=99 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 102E
"EPSG:4543",
"+proj=tmerc +lat_0=0 +lon_0=102 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 105E
"EPSG:4544",
"+proj=tmerc +lat_0=0 +lon_0=105 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 108E
"EPSG:4545",
"+proj=tmerc +lat_0=0 +lon_0=108 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 111E
"EPSG:4546",
"+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 114E
"EPSG:4547",
"+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 117E
"EPSG:4548",
"+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 120E
"EPSG:4549",
"+proj=tmerc +lat_0=0 +lon_0=120 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 123E
"EPSG:4550",
"+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 126E
"EPSG:4551",
"+proj=tmerc +lat_0=0 +lon_0=126 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 129E
"EPSG:4552",
"+proj=tmerc +lat_0=0 +lon_0=129 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 132E
"EPSG:4553",
"+proj=tmerc +lat_0=0 +lon_0=132 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
// CGCS2000 / 3-degree Gauss-Kruger CM 135E
"EPSG:4554",
"+proj=tmerc +lat_0=0 +lon_0=135 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs"
  • 注册proj4
ol.proj.proj4.register(proj4);
  • 实现坐标投影转换(国家2000平面坐标系到国家2000地理坐标系)
var gcs4490 = ol.proj.transform([605906.540647357,2723639.37418766], 
                        new ol.proj.Projection({code:'EPSG:4548'}),
                        new ol.proj.Projection({code:'EPSG:4490'})
					);

# 查找Proj4js地图投影参数

  • 进入EPSG.io网站,搜索EPSG代码
  • 在查到的结果下方,点击Transform coordinates Proj4js
  • 进入详情,点击More details Proj4js
  • 在新进入的页面中向下滚动,找到Export,Proj4js是用于Openlayers的投影语句 Proj4js

# 矢量地图

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<link rel="stylesheet" href="./ol/ol.css" type="text/css">
	<script src="./ol/ol.js"></script>
	<title>map</title>
</head>
<body>
	<div id="popup" class="ol-popup">
		<a href="#" id="popup-closer" class="ol-popup-closer"></a>
		<div id="popup-content"></div>
	</div>
	<div id="map" class="map"></div>
	<script>
		//使用变量缓存弹窗需要的DOM对象
		var container = document.getElementById("popup");
		var content = document.getElementById("popup-content");
		var closer = document.getElementById("popup-closer");
		
		//将十六进制的颜色值转为RGB格式
		function colorRgba(sHex, alpha) {
			// 十六进制颜色值的正则表达式
			var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/
			/* 16进制颜色转为RGB格式 */
			let sColor = sHex.toLowerCase()
			if (sColor && reg.test(sColor)) {
				if (sColor.length === 4) {
					var sColorNew = '#'
					for (let i = 1; i < 4; i += 1) {
						sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1))
					}
					sColor = sColorNew
				}
				//  处理六位的颜色值
				var sColorChange = []
				for (let i = 1; i < 7; i += 2) {
					sColorChange.push(parseInt('0x' + sColor.slice(i, i + 2)))
				}
				// return sColorChange.join(',')
				// 或
				return 'rgba(' + sColorChange.join(',') + ',' + alpha + ')'
			} else {
				return sColor
			}
		}

		var styleFunction = function(feature) {
			return new ol.style.Style({
				stroke: new ol.style.Stroke({
					color: feature.get('stroke'),//通过要素拿到具体的值
					width: 2,
					opacity: 1
				}),
				fill: new ol.style.Fill({
					color: colorRgba(feature.get('fill'), feature.get('fill-opacity')),
					///opacity: feature.get('fill-opacity')
				}),
				text: new ol.style.Text({
					text: feature.get('name'),
					font: '12px bold serif',
					fill: new ol.style.Fill({
						color: '#000'
					}),
					stroke: new ol.style.Stroke({
						color: '#fff',
						width: 2
					})
				})
			})
		};
		//创建图层渲染geoJson文件
		var vectorMy=new ol.layer.Vector({
			title: 'add Layer',
			source: new ol.source.Vector({
				url: "./data.json", 
				//设置数据的默认坐标系
				format: new ol.format.GeoJSON({dataProjection:'EPSG:4548'})
			}),
		   // style: styleFunction
		})
		vectorMy.on('change', function (evt) {
			// 获取矢量图层数据源
			var source = evt.target.getSource();
			if (source.getState() === 'ready') {
				// 获取数据集
				var features = source.getFeatures();
				//console.log(features);
				//console.log(features.length);
				//console.log(features[0].get('要素名称'));
				//map.addLayer(vectorMy);
			}
		});
		
		var layers = [
			new ol.layer.Tile({
				source: new ol.source.OSM()
			}),
			//天地图矢量图
			new Tile({
				source: new XYZ({
				  url: 'http://t3.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=403f767db16f190d4d6513ba7a1670af',
				  crossOrigin: 'anonymous',
				  wrapX: false
				})
			  }),
			//天地图路网
			new ol.layer.Tile({
				source: new ol.source.XYZ({
				   url: "http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=403f767db16f190d4d6513ba7a1670af",
				   crossOrigin: 'anonymous',
				   wrapX: false
				})
			}),
			//天地图注记
			new ol.layer.Tile({
				source: new ol.source.XYZ({
				   url: "http://t3.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=403f767db16f190d4d6513ba7a1670af",
				   crossOrigin: 'anonymous',
				   wrapX: false
				})
			}),
			//天地图卫星影像
			var tian_di_tu_satellite_layer = new ol.layer.Tile({
				title: "天地图卫星影像",
				source: new ol.source.XYZ({
					url: 'http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=403f767db16f190d4d6513ba7a1670af'
				})
			});
			vectorMy
		];

		//创建一个Overlay叠加层对象用作显示弹窗
		var overlay = new ol.Overlay({
			element: container,
			// autoPan: true,
			autoPanAnimation: {
				duration: 250
			}
		});

		var map = new ol.Map({
			target: 'map',
			layers: layers,
			overlays: [overlay],
			view: new ol.View({
				center: [513888.32359999977,4059618.8928999994],
				zoom: 17,
				//最小级别
				minZoom: 4,
				//最大级别
				maxZoom: 17,
				//projection: "EPSG:4326",
				projection:sphereMollweideProjection
			})
		});

		//为弹窗添加一个响应关闭的函数
		closer.onclick = function() {
			overlay.setPosition(undefined);
			closer.blur();
			return false;
		};

		//添加单击响应函数来处理弹窗动作
		map.on("click", function(e) {
			 /* var feature = map.getFeaturesAtPixel(e.pixel);
			 console.log(feature) */
			var pixel = map.getEventPixel(e.originalEvent);
			var hit = map.hasFeatureAtPixel(pixel);
			
			 //获取到当前像素下的feature
			var feature = map.forEachFeatureAtPixel(pixel, function (feature, layer) {
				return feature;
			});
			console.log(feature)
			var coordinate = e.coordinate;
			content.innerHTML = "<p>" + feature.values_.name + "</p>";
			overlay.setPosition(coordinate);
		});
	</script>
</body>
</html>


# 加载离线瓦片(天地图)

<template>
  <div id="map"></div>
</template>

<script>
import "ol/ol.css";
import { Map, View } from "ol";
import XYZ from "ol/source/XYZ";
import { Vector as VectorSource } from "ol/source";
import { Vector as VectorLayer, Tile as TileLayer } from "ol/layer";
export default {
  data() {
    return {
      map: null,
      roadmap: null,
      vectorLayer: null, //创建图层
      vectorSource: null, //图层数据容器
    }
  },
  methods: {
    initMap() {
      let _self = this;
      //线路图
      this.roadmap = new TileLayer({
        visible: true,
        name: '电子图',
        source: new XYZ({
          url: 服务地址+"/tiles/ZhengZhouShi/roadmap/{z}/{x}/{y}.png",
          crossOrigin: "anonymous", //离线瓦片跨域处理
        }),
      });
      this.map = new Map({
        target: "map",
        layers: [this.roadmap],
        view: new View({
          center: [114.028222,31.914839],
          projection: "EPSG:4326",
          zoom: 14,
          minZoom: 12,
          maxZoom: 17,
        }),
      });

      // 创建图层
      this.vectorLayer = new VectorLayer();
      // 创建数据容器
      this.vectorSource = new VectorSource();
      // 把数据容器添加到图层
      this.vectorLayer.setSource(this.vectorSource);
      // 添加到地图上
      this.map.addLayer(this.vectorLayer);
    }
  }
};
</script>

<style scoped lang="scss">
	#map{
		width: 100%;
		height: 800px;
	}
</style>

# 现filter过滤查询发布的WFS服务

在通过openlayers请求geoserver发布的WFS地图服务时,有时需要对请求的地图做一些过滤,选择需要加载的矢量数据。

在openlayers官网案例中,关于WFS的过滤只有属性过滤,缺少空间过滤,在空间过滤时,需要对构建的多边形进行投影转换,然后再引入到过滤方法中。

例如构建一个多边形:

var polygon1 = new Polygon([[
      [117.12499999999999, 31.00586290462421],
      [117.12499999999999, 32.091882620021806],
      [116.90551757812499, 32.091882620021806],
      [116.90551757812499, 31.00586290462421],
      [117.12499999999999, 31.00586290462421]
]]);

构建完多边形时,需要使用applyTransform进行投影转换

polygon1.applyTransform(getTransforms('EPSG:4326','EPSG:3857'));

接着发送WFS请求,并带入多边形矢量信息进行空间过滤,这里示例为intersects相交查询

const featureRequest = new WFS().writeGetFeature({
  srsName: 'EPSG:3857', //投影坐标
  featureNS: 'http://localhost/map', //自己的工作区命名空间URL
  featurePrefix: 'osm',
  featureTypes: ['xxxxx'],	//需要查询的图层名称
  outputFormat: 'application/json',
  filter:
   intersects('the_geom',polygon1) //相交查询
});

完整代码

const vectorSource = new VectorSource();
const vector = new VectorLayer({
  source: vectorSource,
  style: new Style({
    stroke: new Stroke({
      color: 'rgba(0, 0, 255, 1.0)',
      width: 2,
    }),
  }),
});
this.map.addLayer(vector);

var polygon1=new Polygon([[
      [117.12499999999999, 31.00586290462421],
      [117.12499999999999, 32.091882620021806],
      [116.90551757812499, 32.091882620021806],
      [116.90551757812499, 31.00586290462421],
      [117.12499999999999, 31.00586290462421]]]);
      
//需要将构建的面要素进行坐标转换,变成一个polygon要素
polygon1.applyTransform(getTransformss('EPSG:4326','EPSG:3857'));



const featureRequest = new WFS().writeGetFeature({
  srsName: 'EPSG:3857',
  featureNS: 'http://localhost/map',
  featurePrefix: 'osm',
  featureTypes: ['xxxxx'],
  outputFormat: 'application/json',
 
  filter:
  // equalToFilter('region', '澳门特别行政区')
  //  andFilter(
  //   likeFilter('SCENEDATE', '2022/3/*'),
  //   equalToFilter('region', '安徽省')
  // ),
   intersects('the_geom',polygon1)
   // equalToFilter('SCENEDATE', '2013/5/21')
    
});
var that = this.map
fetch('http://localhost:8080/geoserver/map/wfs', {
  method: 'POST',
  body: new XMLSerializer().serializeToString(featureRequest),
})
  .then(function (response) {
    return response.json()
  
  })
  .then(function (json) {
    const features = new GeoJSON().readFeatures(json);
    vectorSource.addFeatures(features);
    that.getView().fit(vectorSource.getExtent());
  });

在openlayers官网中,还有很多查询,基本上都大同小异

openlayer_filter