summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commita6600ae9cf270460b3b6e37b4f95081405d2f9a8 (patch)
treed0d4bd81ea4d241d14c104aa1f3980a4c258c525
parent8c1c06e773bd71ded8a553af035859c897b40864 (diff)
downloadChimè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.js176
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
});