Openlayers 加载 Geoserver 图层以及范围过滤
- 范围过滤核心代码
- 完整代码:
- 在线示例
Openlayers 加载 Geoserver 图层,除了会遇到属性条件查询需求,还经常遇到空间查询,这里介绍一些范围查询。
其实就是利用 Geoserver 的 CQL_FILTER 实现功能,即增加 BOX(EXTENT )条件。
本文包括范围过滤核心代码、完整代码以及在线示例。
范围过滤核心代码
Geoserver 范围过滤核心代码:
// 定义矩形
let geometryFunction = ol.interaction.Draw.createBox(4);
drawObject = new ol.interaction.Draw({
source: drawLayer.getSource(),
type: 'Circle',
geometryFunction: geometryFunction,
});
// 清空之前标绘
drawObject.on('drawstart', function () {
drawLayer && drawLayer.getSource().clear();
geoserverFilter();
})
// 标绘完成回调
drawObject.on('drawend', function (e) {
// 查询范围内数据
geoserverFilter(e.feature.getGeometry().getExtent());
});
map.addInteraction(drawObject);
// 图层资源
const source = layer.getSource()
// 资源参数
let param = source.getParams();
let filter;
if (box) {
box = box.join(",");
// 注意空间字段名称和大小写
filter = ' BBOX(the_geom,' + box + ')';
}
//过滤条件赋值
param.CQL_FILTER = filter;
//更新图层资源
source.updateParams(param);
//刷新资源
source.refresh();
完整代码:
<html lang="en">
<head>
<meta charSet="utf-8">
<!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
<link rel="stylesheet" href="http://openlayers.vip/examples/css/ol.css" type="text/css">
<style>
/* 注意:这里必须给高度,否则地图初始化之后不显示;一般是计算得到高度,然后才初始化地图 */
.map {
height: 500px;
width: 100%;
float: left;
}
.ol-zoom {
display: none;
}
</style>
<!--注意:openlayers 原版的比较慢,这里引起自己服务器版-->
<script src="http://openlayers.vip/examples/resources/ol.js"></script>
<script src="http://openlayers.vip/examples/resources/turf.min.js"></script>
<script src="./tiandituLayers.js"></script>
<title>OpenLayers example</title>
<script>
var _hmt = _hmt || [];
(function () {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?f80a36f14f8a73bb0f82e0fdbcee3058";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
</head>
<body>
<h2 style="height: 60px;">Openlayers geoserver extent</h2>
<!--地图容器,需要指定 id -->
<div id="map" class="map"></div>
<script type="text/javascript">
// 初始化地图
var map = new ol.Map({
// 地图容器
target: 'map',
// 地图图层,比如底图、矢量图等
layers: [
getVEC_CLayer(),
getCVA_CLayer(),
],
// 地图视野
view: new ol.View({
projection: "EPSG:4326",
// 定位
center: [115.67724700667199, 37.73879478106912],
// 缩放
zoom: 6,
maxZoom: 18,
minZoom: 1,
})
});
// 加载 geoserver 图层
let layer;
// 添加图层
function geoserverFunc() {
clearFunc();
layer = new ol.layer.Tile({
extent: [
115.41380999600005,
39.44197808500007,
117.49920000500002,
41.05928408300005
],
source: new ol.source.TileWMS({
// geoserver 地址
url: 'http://openlayers.vip/geoserver/cite/wms',
params: {
// 图层名称
LAYERS: 'cite:2000',
TILED: true
},
serverType: 'geoserver',
transition: 0
})
})
map.addLayer(layer);
// 定位
map.getView().fit(layer.getExtent(), map.getSize());
draw();
}
// 图层过滤
function geoserverFilter(box) {
if (layer) {
// 图层资源
const source = layer.getSource()
// 资源参数
let param = source.getParams();
let filter;
if (box) {
box = box.join(",");
// 注意空间字段名称和大小写
filter = ' BBOX(the_geom,' + box + ')';
}
//过滤条件赋值
param.CQL_FILTER = filter;
//更新图层资源
source.updateParams(param);
//刷新资源
source.refresh();
}
}
// 标绘样式
var defaultStyle = [
new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#0000ff',
width: 0.5,
})
}), new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#00f0f0',
width: 6,
})
}), new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#0000ff',
width: 0.5,
})
}), new ol.style.Style({
//填充样式
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.3)',
}),
image: new ol.style.Circle({
radius: 5,
fill: new ol.style.Fill({
color: 'white',
})
})
})]
/**
* @todo 矢量图层
* @returns {VectorLayer}
* @constructor
*/
function initVectorLayer() {
//实例化一个矢量图层Vector作为绘制层
let source = new ol.source.Vector();
//创建一个图层
let customVectorLayer = new ol.layer.Vector({
source: source,
zIndex: 2,
//设置样式
style: defaultStyle,
});
//将绘制层添加到地图容器中
map.addLayer(customVectorLayer);
return customVectorLayer;
}
// 标绘图层
var drawLayer = initVectorLayer();
// 标绘对象、查询到的图形要素
let drawObject, feature;
// 标绘查询方法
// openlayers 范围查询(extent)
function draw() {
// 移除上次标绘
drawObject && map.removeInteraction(drawObject);
// 定义矩形
let geometryFunction = ol.interaction.Draw.createBox(4);
drawObject = new ol.interaction.Draw({
source: drawLayer.getSource(),
type: 'Circle',
geometryFunction: geometryFunction,
});
// 清空之前标绘
drawObject.on('drawstart', function () {
drawLayer && drawLayer.getSource().clear();
geoserverFilter();
})
// 标绘完成回调
drawObject.on('drawend', function (e) {
// 查询范围内数据
geoserverFilter(e.feature.getGeometry().getExtent());
});
map.addInteraction(drawObject);
}
// 清空
function clearFunc() {
layer && map.removeLayer(layer) , layer = undefined;
drawLayer && drawLayer.getSource().clear();
drawObject && map.removeInteraction(drawObject);
}
geoserverFunc();
</script>
<button id="geoserverFunc" onClick="geoserverFunc()">geoserver</button>
<button id="restoreFunc" onClick="geoserverFilter()">restoreFunc</button>
<button id="clearFunc" onClick="clearFunc()">清空</button>
</body>
</html>
在线示例
Openlayers 在线示例:Geoserver 图层以及范围过滤