diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-09-30 20:43:14 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-09-30 20:43:14 +0200 |
commit | a6600ae9cf270460b3b6e37b4f95081405d2f9a8 (patch) | |
tree | d0d4bd81ea4d241d14c104aa1f3980a4c258c525 | |
parent | 8c1c06e773bd71ded8a553af035859c897b40864 (diff) | |
download | Chimère-a6600ae9cf270460b3b6e37b4f95081405d2f9a8.tar.bz2 Chimère-a6600ae9cf270460b3b6e37b4f95081405d2f9a8.zip |
JS ol3: multiple zoom on click when the cluster is not exploded - display list for the cluster when at max zoom
-rw-r--r-- | chimere/static/chimere/js/jquery.chimere.js | 176 |
1 files changed, 140 insertions, 36 deletions
diff --git a/chimere/static/chimere/js/jquery.chimere.js b/chimere/static/chimere/js/jquery.chimere.js index 7771b7f..c76267e 100644 --- a/chimere/static/chimere/js/jquery.chimere.js +++ b/chimere/static/chimere/js/jquery.chimere.js @@ -74,6 +74,12 @@ var LayerSwitcher = function(options){ }; // LayerSwitcher +function _zoom_to_resolution(zoom, proj_name){ + var proj = ol.proj.get(proj_name); + var maxResolution = ol.extent.getWidth(proj.getExtent()) / 256; + return maxResolution / Math.pow(2, zoom); +} + function _geoportail_layer(key, layer, name, max_zoom, image_format, style, baselayer){ var resolutions = []; @@ -135,7 +141,7 @@ function transform(obj) { 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 + src : MEDIA_URL+'chimere/img/marker-cluster.png', //still need something even if it's invisible opacity : 0 }) }); @@ -198,7 +204,8 @@ var invisibleStyleIcon = new ol.style.Style({ popupClass: null, popupContentFull: false, // if true the detail is inside the popup category_accordion: true, // category opening behave like an accordion - maxResolution: 156543.0399, + minZoom: null, + maxZoom: 18, units: 'm', projection: new ol.proj.get('EPSG:900913'), theme: null, @@ -314,12 +321,16 @@ var invisibleStyleIcon = new ol.style.Style({ var map_element = $(this).attr('id'); var view_options = { - maxResolution: settings.maxResolution, - // OL3-deprecated: units: settings.units, projection: settings.projection, center: CENTER_LONLAT, - zoom: DEFAULT_ZOOM + zoom: DEFAULT_ZOOM, + maxZoom: settings.maxZoom }; + + if (settings.minZoom){ + view_options['minZoom'] = settings.minZoom; + } + /* OL3-deprecated if (settings.restricted_extent){ settings.restricted_extent.transform(EPSG_DISPLAY_PROJECTION, @@ -524,37 +535,9 @@ var invisibleStyleIcon = new ol.style.Style({ } if (key && key.length > 6 && key.substring(0, 7) == 'cluster'){ - var v = settings.map.getView(); - var pan = ol.animation.pan( - {duration: 500, source: v.getCenter()}) - var zoom = ol.animation.zoom( - {duration: 500, resolution: v.getResolution()}) - settings.map.beforeRender(pan, zoom); - v.setZoom(v.getZoom() + 1); - v.setCenter(feature.getGeometry().getCoordinates()); + feature = methods.clickOnCluster(feature); } else { - var geom = feature.getGeometry(); - if (geom.getType() == 'Point'){ - settings.popup.setPosition(geom.getCoordinates()); - settings.popup.setOffset([feature.get('popup_offset_x'), - -feature.get('popup_offset_y')]); - } else if (geom.getType() == 'Polygon'){ - settings.popup.setPosition(geom.getInteriorPoint().getCoordinates()); - settings.popup.setOffset([0, 0]); - } else if (geom.getType() == 'LineString'){ - settings.popup.setPosition(geom.getCoordinateAt(0.5)); - settings.popup.setOffset([0, 0]); - } else if (geom.getType() == 'MultipleLineString'){ - settings.popup.setPosition(geom.getLineString(0).getCoordinatesAt(0.5)); - settings.popup.setOffset([0, 0]); - } - $(settings.popup_item).popover({ - 'placement': 'top', - 'html': true, - 'content': feature.get('name') - }); - $(settings.popup_item).popover('show'); - methods.display_feature_detail(key); + methods.openPopup(feature); } } else { $(settings.popup_item).popover('destroy'); @@ -999,6 +982,125 @@ var invisibleStyleIcon = new ol.style.Style({ settings.map.addLayer(settings.clusterLayer); }, + clickOnCluster: function(feature, zoom_level, duration, nb_zoom, + current_nb_items){ + if (!duration) duration = 500; + if (!nb_zoom) nb_zoom = 0; + + var props = feature.getProperties(); + if (!'features' in props) return feature; + if (!current_nb_items){ + current_nb_items = props['features'].length; + } else if(current_nb_items != props['features'].length) { + // stop zooming there less item in the cluster + return feature; + } + + var v = settings.map.getView(); + if (!zoom_level) zoom_level = v.getZoom() + 1; + + // animation + var pan = ol.animation.pan( + {duration: duration, source: v.getCenter()}) + var zoom = ol.animation.zoom( + {duration: duration, resolution: v.getResolution()}) + settings.map.beforeRender(pan, zoom); + + // center + v.setCenter(feature.getGeometry().getCoordinates()); + + // max zoom reached + if (zoom_level >= settings.maxZoom){ + return methods.displayClusterDetail(feature); + } + + // zoom + v.setZoom(zoom_level); + + nb_zoom += 1; + // something wrong stop zoom! + if (nb_zoom > settings.maxZoom) return feature; + // wait for the animation to finish before rezoom + return setTimeout( + function(){ + // our cluster must be at the center (if it exists after zoom) + var pixel = settings.map.getPixelFromCoordinate(v.getCenter()); + var new_feature; + settings.map.forEachFeatureAtPixel( + pixel, function(feat, layer){ + if (layer == settings.clusterLayer){ + new_feature = feat; + return true + } + } + ); + if (new_feature){ + return methods.clickOnCluster( + new_feature, zoom_level + 1, duration, nb_zoom, + current_nb_items); + } + // no more cluster feature here: stop zooming + return feature; + }, duration); + }, + displayClusterDetail: function(feature){ + var feats = feature.getProperties()['features']; + var content = "<div class='dialog-content'><ul>"; + for (idx in feats){ + var props = feats[idx].getProperties(); + content += "<li><img src="+MEDIA_URL+props.icon_path+">" + + "<span class='cluster_list' id='cluster_list_"+idx+"'>" + + props.name + "</span></li>"; + } + content += "</ul></div>"; + $('#cluster_list').html(content); + $('#cluster_list').dialog('open'); +/* + $("#cluster_list").on("dialogclose", methods.cleanCluster); + settings.map.setCenter( + feature.geometry.getBounds().getCenterLonLat()); + // register after the display + settings.clustered_feature = feature.cluster; +*/ + jQuery(".cluster_list").click( + function(e){ + $('#cluster_list').dialog('close'); + var splitted = $(this).attr('id').split('_'); + var index = splitted[splitted.length-1]; + feat = feats[parseInt(index)] + methods.openPopup(feat); + //.attributes.marker; + //m.events.triggerEvent('click'); + e.stopPropagation(); + return false; + }); + return feature; + }, + openPopup: function(feature){ + var geom = feature.getGeometry(); + if (geom.getType() == 'Point'){ + settings.popup.setPosition(geom.getCoordinates()); + settings.popup.setOffset([feature.get('popup_offset_x'), + -feature.get('popup_offset_y')]); + } else if (geom.getType() == 'Polygon'){ + settings.popup.setPosition(geom.getInteriorPoint().getCoordinates()); + settings.popup.setOffset([0, 0]); + } else if (geom.getType() == 'LineString'){ + settings.popup.setPosition(geom.getCoordinateAt(0.5)); + settings.popup.setOffset([0, 0]); + } else if (geom.getType() == 'MultipleLineString'){ + settings.popup.setPosition(geom.getLineString(0).getCoordinatesAt(0.5)); + settings.popup.setOffset([0, 0]); + } + $(settings.popup_item).popover({ + 'placement': 'top', + 'html': true, + 'content': feature.get('name') + }); + $(settings.popup_item).popover('show'); + methods.display_feature_detail(feature.get('key')); + }, + /* end of new ol3 */ /* Preload icons */ preload_images: function(){ if (typeof extra_url == 'undefined') return; @@ -1102,6 +1204,7 @@ var invisibleStyleIcon = new ol.style.Style({ addLayer: function(layer){ settings.map.addLayer(layer); }, + /* zoomOnCluster: function(feature){ if(!feature.cluster) // if not cluster { @@ -1136,7 +1239,7 @@ var invisibleStyleIcon = new ol.style.Style({ }); } }, - + */ /* * Display menu on the map */ @@ -1469,6 +1572,7 @@ var invisibleStyleIcon = new ol.style.Style({ name: mark.properties.name, pk: mark.properties.pk, key: mark.properties.key, + icon_path: mark.properties.icon_path, popup_offset_x: mark.properties.icon_popup_offset_x, popup_offset_y: mark.properties.icon_popup_offset_y }); |