Is there a way to cluster markers within openlayers as there is within leaflet.
I have many markers which display the various listed buildings within wales and I am wondering if I am able to cluster them and then as a user zooms in the clusters get smaller until an individual marker is left. And then on zoom out a the markers regroup/cluster showing a cluster with numbers on such as how many markers are within a set distance of lets say 10 miles or so?
Is there also a way to ensure that when a cluster size is at 1 it could show the LSMarker
style being that of the original cross showed in the image below?
Link to current project so you can see what I mean by the need to cluster data: https://ces-web2.southwales.ac.uk/students/18018815/mitchtut/giscw2/openlayer.htm
Mobile chrome showing previous amount of markers
UPDATE 1 (THIS ISSUE HAS BEEN SOLVED)
Currently getting the error
current code
Uncaught ha {message: "Assertion failed. See https://openlayers.org/en/v4.6.5/doc/errors/#58 for details.", code: 58, name: "AssertionError"}
UPDATE 2 Error fixed but geo data not loading within correct area
Current code
var distance = document.getElementById('distance'); //getting the distance from the slider
<!-- var count = 1000; -->
<!-- var features = new Array(count); //creating an array to hold the amount of features for the cluster -->
<!-- var e = 4000; -->
<!-- for (var i = 0; i<count; i++){ -->
<!-- var coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e]; -->
<!-- features [i] = new ol.Feature(new ol.geom.Point(coordinates)); -->
<!-- } -->
var clusterSource = new ol.source.Cluster({
distance: parseInt(distance.value,10),
source: new ol.source.Vector({
url: 'geoJSON/LSB.kml',
format: new ol.format.KML({
extractStyles:false,
}),
})
});
var styleCache = {};
var clusters = new ol.layer.Vector({
source: clusterSource,
style: function (feature) {
var size = feature.get('features').length;
var 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({
colo:'#3399CC'
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color:'#fff'
})
})
});
styleCache[size] = style;
}
return style;
}
});
var raster = new ol.layer.Tile({
source:new ol.source.OSM()
});
distance.addEventListener('input', function(){
clusterSource.setDistance(parseInt(distance.value));
});
//instantiation of the map within the div class 'mapspce'
var Omap = new ol.Map({
layers:[raster, clusters],
target:'mapspce',
view: new ol.View({
center: ol.proj.transform(cWales,'EPSG:4326','EPSG:3857'),
zoom: 8
})
});
2 Answers 2
If your KML source is not working with a cluster source it may contain features which are not Point geometry. You can add a geometryFunction
to the cluster source options to ensure only point features are used when clustering:
var clusterSource = new ol.source.Cluster({
distance: parseInt(distance.value,10),
geometryFunction: function (feature) {
var geometry = feature.getGeometry();
if (geometry.getType() === "Point") {
return geometry;
} else if (geometry.getType() === "MultiPoint") {
return geometry.getPoint(0);
}
},
source: new ol.source.Vector({
url: 'geoJSON/LSB.kml',
format: new ol.format.KML({
extractStyles:false,
}),
})
});
-
The KML data does appear to be point data however , I cannot seem to get it to show even with your script, I can get it to work with random coordinate data but the data no longer appears to load, any chance of something missing? Live Code here: ces-web2.southwales.ac.uk/students/18018815/mitchtut/giscw2/…WMTS– WMTS2021年02月17日 16:18:34 +00:00Commented Feb 17, 2021 at 16:18
-
Could it be that the KML coordinate data within the file is listed like <MultiGeometry><Point><coordinates>-3.08246357229187,53.2285595916199</coordinates></Point></MultiGeometry> is multigeometry the issue?WMTS– WMTS2021年02月17日 17:02:03 +00:00Commented Feb 17, 2021 at 17:02
-
The error was to do with the KML file, Its fixed, thank you for the helpWMTS– WMTS2021年02月17日 17:55:44 +00:00Commented Feb 17, 2021 at 17:55
-
1A MultiGeometry consisting only of points would result in a MultiPoint geometry in OpenLayers, The geometry function could extract the point from that. You can reduce any geometry to a point using
new ol.geom.Point(ol.extent.getCenter(feature.getGeometry().getExtent()))
Mike– Mike2021年02月17日 19:15:00 +00:00Commented Feb 17, 2021 at 19:15
Clustering function now complete issue being that the KML coordinate data within the file is listed as
<MultiGeometry><Point><coordinates>-3.08246357229187,53.2285595916199</coordinates></Point></MultiGeometry>
With Multigeometry data not being picked up by leaflet as this must be a single point
//clustering 2 Eletricboogaloo
var distance = document.getElementById('distance');
var Source = new ol.source.Vector({
url:'geoJSON/LSB.KML',
format: new ol.format.KML({
extractStyles:false
})
});
var clusterSource = new ol.source.Cluster({
distance: parseInt(distance.value,10),
source: Source
});
vector = new ol.layer.Vector({
source: clusterSource,
style: LSMarker
});
var raster = new ol.layer.Tile({
source:new ol.source.OSM()
});
//instantiation of the map within the div class 'mapspce'
var Omap = new ol.Map({
layers:[raster, vector],
target:'mapspce',
view: new ol.View({
center: ol.proj.transform(cWales,'EPSG:4326','EPSG:3857'),
zoom: 8
})
});
distance.addEventListener('input',function() {
clusterSource.setDistance(parseInt(distance.value,10));
});
ol.source.Cluster
should be theol.source.Vector
for the KML not just its url.