概述
上次[http://blog.csdn.net/sinat_25295611/article/details/79110368] 遇到一个神奇的BUG,怀疑是openlayers这个版本中自动绘制 Text 的一个Bug,其他要素的Text背景样式失效了,一直没有解决。
于是换了另外一种方式来实现,也就是 使用 ol.Overlay 来添加标签。
当加载完Source要素的时候,获取每个要素的’name’属性,将其作为标签,这里需要注意一点的是,经常有人问怎么监听要素已经加载完毕,由于使用 ol.source.Vector 加载要素(wfs服务/geojson文件等等)是异步加载,所以,在代码中要给要素绑定事件的时候可能还没有该要素,比如下面这样:
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: [-72.980624870461128, 48.161307640513321],
zoom: 8,
projection: 'EPSG:4326'
}),
target: 'map'
});
var vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector({
url: '../data/geojson/line.geojson',
format: new ol.format.GeoJSON()
})
});
map.addLayer(vectorLayer);
// 如果在此处调用vectorLayer.getSource().getFeatures()是完全有可能获取不到任何Feature的
去查Openlayers的 API文档会看到 ol.source.Vector
有一个loader
的属性,并在后面有一段示例代码:
var vectorSource = new ol.source.Vector({
format: new ol.format.GeoJSON(),
loader: function(extent, resolution, projection) {
var proj = projection.getCode();
var url = 'https://ahocevar.com/geoserver/wfs?service=WFS&' +
'version=1.1.0&request=GetFeature&typename=osm:water_areas&' +
'outputFormat=application/json&srsname=' + proj + '&' +
'bbox=' + extent.join(',') + ',' + proj;
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
var onError = function() {
vectorSource.removeLoadedExtent(extent);
}
xhr.onerror = onError;
xhr.onload = function() {
if (xhr.status == 200) {
vectorSource.addFeatures(
vectorSource.getFormat().readFeatures(xhr.responseText));
} else {
onError();
}
}
xhr.send();
},
strategy: ol.loadingstrategy.bbox
});
后面一段说明:The loader function used to load features, from a remote source for example. If this is not set and url is set, the source will create and use an XHR feature loader.
也就是说,loader是一个函数用于加载数据源,但如果未设置,并且设置了url,就会用XHR异步请求来加载数据源。也就是说,我们完全可以用 loader
这个函数来代替 url
,在其中我们可以自定义的发送请求,然后在回调函数中,对获取的要素源进行处理。
于是用loader来给每个要素手工添加标签,当加载完Source要素的时候,获取每个要素的’name’属性,将其作为标签。就像这样:
var beijingSource=new ol.source.Vector({
format: new ol.format.GeoJSON(),
loader:function (extent,resolution,projection) {
var url='http://'+host+'/geoserver/wfs?' +
'service=wfs&version=1.1.0&request=GetFeature&typeNames=ztbr:beijing_pq&outputFormat=application/json&srsname=EPSG:3857';
$.ajax({
url:url,
type:'GET',
success:function (res) {
beijingSource.addFeatures(beijingSource.getFormat().readFeatures(res));
var features=beijingSource.getFeatures();
features.forEach(x =>{
//创建标签的函数,由于我采用的vue组件开发的,vm是我的Vue的this对象
vm.creatLabelForFeature(x,"beijing_pq");
});
},
error:function () {
alert("error")
}
})
}
});
//然后是创建标签的函数`creatLabelForFeature`
/** 1.根据传入的要素,添加对应的Lable。并在lable上绑定点击事件,点击lable可以进行缩放,请求下一级的矢量地图,同时隐藏lable */
creatLabelForFeature: function(feature,layerId) {
var vm=this;
var map=vm.map;
var beijingLayer = vm.layers.beijing_pq;
var jiedaoLayer = vm.layers.beijing_jd;
var shequLayer = vm.layers.beijing_sq;
var extent=feature.getGeometry().getExtent();
var geom = feature.getGeometry();
var pos=ol.extent.getCenter(extent);
var content = feature.get('name');
var ele=$("<div class='nameLabel'></div>");
ele.attr("layerId", layerId);
ele.html(content);
ele.css({
'font-size':'12px',
'color': '#ffffff',
'background-color':'#4D98DD' ,
'cursor': 'pointer',
'padding':'1px 4px',
'border-radius': '4px'
});
//给ele 绑点点击事件,点击获取指定下一级的 wfs
ele.click(function (evt) {
map.getView().fit(geom,map.getSize());
var lid = ele.attr("layerId");
var featureName = ele.html();
// console.log(featureName);
if(lid == 'beijing_pq'){
//点击北京区域图层,到指定区,加载街道
beijingLayer.setVisible(false);
jiedaoLayer.setSource(new ol.source.Vector()); //每次点击要把之前的 Source清空 fixme
vm.getWFS('beijing_jd', ol.format.filter.equalTo('district', featureName), jiedaoLayer);
}else if(lid == 'beijing_jd'){
//点击街道图层,到指定街道,加载社区
jiedaoLayer.setVisible(false);
shequLayer.setSource(new ol.source.Vector());
vm.getWFS('beijing_sq', ol.format.filter.equalTo('street', featureName),shequLayer);
}else if(lid == 'beijing_sq'){
//TODO 显示一个社区
shequLayer.setSource(new ol.source.Vector());
vm.getWFS('beijing_sq', ol.format.filter.equalTo('name', featureName),shequLayer);
}
//隐藏上一级的 Overlayers
vm.clearOverlayers(lid);
});
var label = new ol.Overlay({
position: pos,
positioning: 'center-center',
element: ele[0],
stopEvent: false
});
map.addOverlay(label);
//标签的缓存数组,下次加载时直接取用
vm.overlays[layerId].push(label);
}
于是就实现了下面的效果:(这是鼠标移入移出时就没有了上篇文章中的Bug了。。。)
最后
以上就是冷艳大白为你收集整理的openlayers 3 开发,点击 Overlay 请求WFS并进入下一级别(顺带解决上一次问题)的全部内容,希望文章能够帮你解决openlayers 3 开发,点击 Overlay 请求WFS并进入下一级别(顺带解决上一次问题)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复