[英]Cluster in Openlayers with map.animatedcluster: style and cluster of layers
我需要使用 Openlayers 对要显示在我的 map 上的点进行分组。 我正在关注示例http://viglino.github.io/ol-ext/examples/animation/map.animatedcluster.html 。
我能够更改它,以便我的层是 WFS 层。 在下图中,我有两个层,但是,它们并没有将两者组合在一起,而是分开。 在以红色突出显示的部分中,我们可以看到绿色和橙色的分组非常接近,每个分组都代表一个层。 如何对 map 上显示的所有层进行聚类?
几个月前我已经发了一篇关于这个例子的帖子 Openlayers: cluster with different layers
另一件事,层层有不同的风格。 I would like to keep this style, when the cluster is selected and/or when there is only one point in the cluster. 有小费吗?
[编辑]
// Cluster Source
var clusterSource1=new ol.source.Cluster({
distance: 60,
source: new ol.source.Vector({
format: new ol.format.GeoJSON(),
url: function(extent) {
return urlGeoserver + 'wfs?service=WFS&' +
'version='+versionGeoserver+'&request=GetFeature&typename=geo:MyLAYER1&' +
'outputFormat=application/json&srsname=EPSG:4326&' +
'all=' + extent.join(',') + ',EPSG:4326';
},
strategy: ol.loadingstrategy.all
})
});
// Animated cluster layer
var clusterLayer1 = new ol.layer.AnimatedCluster({
name: 'Cluster1',
source: clusterSource1,
animationDuration: 700,
style: getStyle
});
var clusterSource2=new ol.source.Cluster({
distance: 60,
source: new ol.source.Vector({
format: new ol.format.GeoJSON(),
url: function(extent) {
return urlGeoserver + 'wfs?service=WFS&' +
'version='+versionGeoserver+'&request=GetFeature&typename=geo:MyLAYER2&' +
'outputFormat=application/json&srsname=EPSG:4326&' +
'all=' + extent.join(',') + ',EPSG:4326';
strategy: ol.loadingstrategy.all
})
});
var clusterLayer2 = new ol.layer.AnimatedCluster({
name: 'Cluster2',
source: clusterSource2,
animationDuration: 700,
style: getStyle
});
map.addLayer(clusterLayer1);
map.addLayer(clusterLayer2);
谢谢
这就是我解决这个问题的方法。 您将在一个功能集中拥有来自不同来源的所有功能。 每个功能都被标记,因此您没有不同的层。 您设置一个属性来区分您的功能。 如果你想删除一个“层”,你只需从源中删除该功能,如果它在那里,则将其推回。 希望这就是你想要的。
https://jsfiddle.net/komarara/8jbzL019/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
.map {
height: 100%;
width: 100%;
}
html,
body {
height: 100%
}
</style>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.11.0/build/ol.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.11.0/css/ol.css">
</head>
<body>
<Button onClick="handleVisibilityLayer1()">Layer1</Button>
<Button onClick="handleVisibilityLayer2()">Layer2</Button>
<div id="map" class="map"></div>
<script type="text/javascript">
let source;
let featureCollection = [];
document.addEventListener("DOMContentLoaded", function () {
drawMap();
});
function handleVisibilityLayer1(){
for(const feature of featureCollection){
const layerId = feature.get('layer');
if(layerId === 'layer1' && source.hasFeature(feature)){
source.removeFeature(feature);
} else if(layerId === 'layer1' && !source.hasFeature(feature)){
source.addFeature(feature);
}
}
}
function handleVisibilityLayer2(){
for(const feature of featureCollection){
const layerId = feature.get('layer');
if(layerId === 'layer2' && source.hasFeature(feature)){
source.removeFeature(feature);
} else if(layerId === 'layer2' && !source.hasFeature(feature)){
source.addFeature(feature);
}
}
}
function drawMap() {
const feature1 = new ol.Feature({
geometry: new ol.geom.Point([818131.46, 5846162.87]),
layer: 'layer1',
});
const feature2 = new ol.Feature({
geometry: new ol.geom.Point([818130.46, 5846162.87]),
layer: 'layer1',
});
const feature11 = new ol.Feature({
geometry: new ol.geom.Point([818131.46, 5846161.87]),
layer: 'layer2',
});
const feature22 = new ol.Feature({
geometry: new ol.geom.Point([818130.46, 5846161.87]),
layer: 'layer2',
});
featureCollection = [feature1, feature2, feature11, feature22];
source = new ol.source.Vector({
features: featureCollection,
});
const clusterSource = new ol.source.Cluster({
source: source,
});
const styleCache = {};
const clusterLayer = new ol.layer.Vector({
source: clusterSource,
style: function (feature) {
const size = feature.get('features').length;
let style = styleCache[size];
if (!style) {
style = new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: '#fff',
}),
fill: new ol.style.Fill({
color: '#3399CC',
}),
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff',
}),
}),
});
styleCache[size] = style;
}
return style;
},
});
const osmLayer = new ol.layer.Tile({
source: new ol.source.OSM({
attributions: '© OpenStreetMap',
})
});
map = new ol.Map({
target: 'map',
layers: [
osmLayer,
clusterLayer
],
view: new ol.View(),
});
map.getView().fit(source.getExtent());
}
</script>
</body>
</html>
我有几个层,我可以选择一个或多个显示在map上。图中,我是两次,每个都有不同的标签。
每一层都有一个对应的源,也就是一个WFS。
var layer 1 = new ol.layer.Vector({
source: new ol.source.Vector({
//code })
})
当你点击任何一点时,它会显示一个带有特定图层信息的弹出窗口。
我想要的是? 将此信息分组以避免污染 map。我已经使用 Leaflet 进行了开发,但我没有使用 Openlayers。 在宣传册中,我使用了 L.markerClusterGroup.layerSupport
我按照代码http://viglino.github.io/ol-ext/examples/animation/map.animatedcluster.html开始了测试。 我什至发布了我的初始测试代码,但它没有对来自不同层的数据进行分组,我没有给出即将进行的更改的顺序。
[编辑] 如何将一个来源的特征添加到另一个来源? 不管用
// Cluster Source
var clusterSource_=new ol.source.Cluster({
distance: 40,
source: new ol.source.Vector()
});
// Animated cluster layer
var clusterLayer_ = new ol.layer.AnimatedCluster(
{ name: 'Cluster',
source: clusterSource_,
style: getStyle
});
map.addLayer(clusterLayer_);
var teste = new ol.source.Vector({
format: new ol.format.GeoJSON(),
url: function(extent) {
return urlGeoserver + 'wfs?service=WFS&' +
'version='+versionGeoserver+'&request=GetFeature&typename=geo:MYLAYER1&' +
'outputFormat=application/json&srsname=EPSG:4326&' +
'all=' + extent.join(',') + ',EPSG:4326';
},
strategy: ol.loadingstrategy.all
})
var features = teste.getFeatures();
alert(features.length); //this alerts '0', but there's more than 10 features!!
clusterSource_.getSource().clear();
clusterSource_.getSource().addFeatures(teste.getSource().getFeatures());
只有一个集群源/层的多层。 我只是将所有功能推送到一个阵列。 然而,这只是一个概念验证,在一定数量的功能下,你会遇到性能问题,因此还有改进的空间。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
.map {
height: 100%;
width: 100%;
}
html,
body {
height: 100%
}
</style>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.13.0/build/ol.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.13.0/css/ol.css">
</head>
<body>
<input type="checkbox" onChange="handleLayerVisibility('layer1', this.checked)">Layer1</input>
<input type="checkbox" onChange="handleLayerVisibility('layer2', this.checked)">Layer2</Checkbox>
<div id="map" class="map"></div>
<script type="text/javascript">
let intermediateClusterSource;
const feature1 = new ol.Feature({
geometry: new ol.geom.Point([818131.46, 5846162.87]),
layer: 'layer2'
});
const feature2 = new ol.Feature({
geometry: new ol.geom.Point([818130.46, 5846162.87]),
layer: 'layer2'
});
const feature3 = new ol.Feature({
geometry: new ol.geom.Point([818131.46, 5846161.87]),
layer: 'layer2'
});
const feature4 = new ol.Feature({
geometry: new ol.geom.Point([818130.46, 5846161.87]),
layer: 'layer2'
});
const featureCollection = [feature1, feature2, feature3, feature4];
document.addEventListener("DOMContentLoaded", function () {
drawMap();
});
function handleLayerVisibility(layerId, checked){
for(const feature of featureCollection){
const id = feature.get('layer');
if(id !== layerId){
continue;
}
if(checked){
intermediateClusterSource.addFeature(feature);
} else {
intermediateClusterSource.removeFeature(feature);
}
}
}
function drawMap() {
const source1 = new ol.source.Vector({
format: new ol.format.GeoJSON(),
loader: function(extent, resolution, projection, success, failure) {
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;
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
var onError = function() {
source1.removeLoadedExtent(extent);
failure();
}
xhr.onerror = onError;
xhr.onload = function() {
if (xhr.status == 200) {
var features = source1.getFormat().readFeatures(xhr.responseText);
for(const [index, feature] of features.entries()){
const geometry = feature.getGeometry();
if(geometry instanceof ol.geom.SimpleGeometry){
if(index < 100){
const coords = geometry.getCoordinates()[0][0][0];
if(coords && coords.length === 2){
const feat = new ol.Feature({
geometry: new ol.geom.Point(coords),
layer: 'layer1'
});
featureCollection.push(feat);
}
}
}
}
success(features);
} else {
onError();
}
}
xhr.send();
},
});
const layer1 = new ol.layer.Vector({
id: 'layer1',
source: source1,
})
const source2 = new ol.source.Vector({
features: [feature1, feature2, feature3, feature4]
})
const layer2 = new ol.layer.Vector({
id: 'layer2',
source: source2,
visible: false,
})
intermediateClusterSource = new ol.source.Vector();
const clusterSource = new ol.source.Cluster({
source: intermediateClusterSource,
});
const styleCache = {};
const clusterLayer = new ol.layer.Vector({
source: clusterSource,
style: function (feature) {
const size = feature.get('features').length;
let style = styleCache[size];
if (!style) {
style = new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: '#fff',
}),
fill: new ol.style.Fill({
color: '#3399CC',
}),
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff',
}),
}),
});
styleCache[size] = style;
}
return style;
},
});
const osmLayer = new ol.layer.Tile({
source: new ol.source.OSM({
attributions: '© OpenStreetMap',
})
});
map = new ol.Map({
target: 'map',
layers: [
osmLayer,
layer1,
layer2,
clusterLayer
],
view: new ol.View({
projection: 'EPSG:3857',
zoom: 1,
center: [0,0],
}),
});
}
</script>
</body>
</html>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.