diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-09-28 23:14:04 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-09-28 23:14:04 +0200 |
commit | 7f1a18283284729bfd5e4c438f0bc8675ba4e8bb (patch) | |
tree | 04f22a2e1e5b57370a80066ab2e7bc725a8bf5e7 | |
parent | 73792cf7b39b472233ebc264e8962284d76c49ed (diff) | |
download | Chimère-7f1a18283284729bfd5e4c438f0bc8675ba4e8bb.tar.bz2 Chimère-7f1a18283284729bfd5e4c438f0bc8675ba4e8bb.zip |
JS ol3: first version managing cluster (with caching)
-rw-r--r-- | chimere/static/chimere/js/jquery.chimere.js | 130 |
1 files changed, 113 insertions, 17 deletions
diff --git a/chimere/static/chimere/js/jquery.chimere.js b/chimere/static/chimere/js/jquery.chimere.js index 2cbfced..87e22ea 100644 --- a/chimere/static/chimere/js/jquery.chimere.js +++ b/chimere/static/chimere/js/jquery.chimere.js @@ -133,6 +133,13 @@ function transform(obj) { return obj.transform(EPSG_DISPLAY_PROJECTION, EPSG_PROJECTION); } +var invisibleStyleIcon = new ol.style.Style({ + image: new ol.style.Icon({ + src : STATIC_URL+'chimere/img/marker-cluster.png', //still need something even if it's invisible + opacity : 0 + }) + }); + /* * Little hasattr helper */ @@ -274,6 +281,7 @@ function transform(obj) { })]; } settings = $.extend({}, defaults); + settings._revision = 0; if ( options ) $.extend(settings, options); if (settings.controls == null){ @@ -289,13 +297,18 @@ function transform(obj) { */ settings.controls = [ new ol.control.Attribution(), - new ol.control.OverviewMap({ - collapsed: false - }), new ol.control.ScaleLine(), new ol.control.Zoom(), new ol.control.FullScreen() ]; + // OverviewMap mess with clustering + if (!settings.enable_clustering){ + settings.controls.push( + new ol.control.OverviewMap({ + collapsed: false + }) + ); + } //} } var map_element = $(this).attr('id'); @@ -635,6 +648,11 @@ function transform(obj) { } */ + + + if (settings.enable_clustering){ + methods.enableClustering(); + } /* OL3-deprecated-cluster if (settings.enable_clustering){ var style = new OpenLayers.Style({ @@ -764,9 +782,9 @@ function transform(obj) { if (!settings.edition){ if (settings.enable_clustering){ - /// OL3-TODO - settings.map.events.register('zoomend', null, - methods.cleanCluster); + /// OL3-TODO cluster + // settings.map.events.register('zoomend', null, + // methods.cleanCluster); } methods.loadCategories(); methods.loadGeoObjects(); @@ -856,6 +874,7 @@ function transform(obj) { }, register_reload_on_move: function(){ var reload_on_move = function(evnt){ + settings._revision += 1; var map = settings.map; var current_extent = ol.proj.transformExtent( map.getView().calculateExtent(map.getSize()), @@ -888,6 +907,86 @@ function transform(obj) { settings.map.on('moveend', reload_on_move); reload_on_move(); }, + enableClustering: function(){ + // Style clusters and hide items inside clusters + settings._styleCache = {}; + settings._remindOldStyle = {}; + settings._remindUpdated = {}; + settings._currentRemind = -1; + function clusterGetStyle (feature, resolution){ + var features = feature.get('features'); + var size = features.length; + var style = settings._styleCache[size]; + // no cluster for lonely marker + if (!style && size > 1){ + var color = size>25 ? "192,0,0" : size>8 ? "255,128,0" : "0,128,0"; + var radius = Math.max(8, Math.min(size*0.75, 20)); + var lbl = size.toString(); + style = settings._styleCache[size] = [ + new ol.style.Style({ + image: new ol.style.Circle({ + radius: radius, + stroke: new ol.style.Stroke({ + color:"rgba("+color+",0.5)", + width:15 + }), + fill: new ol.style.Fill({ + color:"rgba("+color+",1)" + }) + }), + text: new ol.style.Text({ + text: lbl, + fill: new ol.style.Fill({ + color: '#fff' + }) + }) + }) + ]; + } + // don't reapply the style when no modif have been opered + if (settings._currentRemind != settings._revision){ + settings._remindUpdated = []; + settings._currentRemind = settings._revision; + } + if (size > 1){ + // marker himself disappear + for (idx in features){ + var feat = features[idx]; + if (!settings._remindUpdated[feat.getId()]){ + if (!settings._remindOldStyle[feat.getId()]){ + settings._remindOldStyle[feat.getId()] = feat.getStyle(); + } + feat.setStyle(invisibleStyleIcon); + settings._remindUpdated[feat.getId()] = 1; + } + } + } else { + // or re-appear + var feat = features[0]; + if (!settings._remindUpdated[feat.getId()] && + settings._remindOldStyle[feat.getId()]){ + feat.setStyle(settings._remindOldStyle[feat.getId()]); + settings._remindUpdated[feat.getId()] = 1; + } + } + return style; + } + + // Cluster Source + settings.clusterSource = new ol.source.Cluster({ + distance: 40, + source: new ol.source.Vector() + }); + // Animated cluster layer + settings.clusterLayer = new ol.layer.Vector({ + name: 'Cluster', + source: settings.clusterSource, + // Cluster style + style: clusterGetStyle + }); + settings.map.addLayer(settings.clusterLayer); + + }, /* Preload icons */ preload_images: function(){ if (typeof extra_url == 'undefined') return; @@ -1087,20 +1186,18 @@ function transform(obj) { //var start = new Date().getTime(); settings.dbFeatures.clear(); settings.vectors.clear(); - /// OL3-TODO - // settings.layerVectors.removeAllFeatures(); if (settings.enable_clustering){ - settings.cluster_array = []; - settings.layerCluster.removeAllFeatures(); + settings.clusterSource.getSource().clear(); } if (!data.features) return; if (data.zoom_need_reload){ settings._zoom_need_reload = data.zoom_need_reload; } + settings._revision += 1; for (var i = 0; i < data.features.length; i++) { var feature = data.features[i]; if (feature.geometry.type == 'Point'){ - methods.addMarker(feature); + var iconFeature = methods.addMarker(feature); } else if (feature.geometry.type == 'Polygon') { methods.addPolygon(feature); } else if (feature.geometry.type == 'MultiPolygon') { @@ -1111,11 +1208,6 @@ function transform(obj) { //OL3 methods.addMultiLine(feature); } } - if (settings.enable_clustering){ - settings.layerCluster.addFeatures( - settings.cluster_array); - methods.cleanCluster(); - } // var extent = settings.sourceDbFeatures.getExtent(); // settings.map.getView().fit(extent, settings.map.getSize()); // settings.map.resetLayersZIndex(); @@ -1393,9 +1485,13 @@ function transform(obj) { } iconFeature.setStyle(iconStyle); + iconFeature.setId(mark.properties.key); settings.dbFeatures.push(iconFeature); + if (settings.enable_clustering){ + settings.clusterSource.getSource().addFeature(iconFeature); + } - return; + return iconFeature; //OL3 hover /* |