1

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
 })
});
 
asked Feb 12, 2021 at 23:19
4
  • 1
    Yes, place your KML source inside a cluster source as in openlayers.org/en/v4.6.5/examples/cluster.html Commented Feb 12, 2021 at 23:48
  • Thank you, tried adapting that but got some errors, could be because its late but thank you Commented Feb 13, 2021 at 1:03
  • The source for your ol.source.Cluster should be the ol.source.Vector for the KML not just its url. Commented Feb 13, 2021 at 9:58
  • @Mike I have included this within my code but the points locations are not loading in the correct geographic area now Commented Feb 13, 2021 at 18:59

2 Answers 2

1

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,
 }),
 })
 });
answered Feb 17, 2021 at 15:43
4
  • 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/… Commented 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? Commented Feb 17, 2021 at 17:02
  • The error was to do with the KML file, Its fixed, thank you for the help Commented Feb 17, 2021 at 17:55
  • 1
    A 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())) Commented Feb 17, 2021 at 19:15
0

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));
});
answered Feb 17, 2021 at 18:32

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.