/* default variables */ var default_pointer = "/media/images/default-pointer.png"; var marker_cluster = "/media/images/marker-cluster.png"; var view_projection = 'EPSG:3857'; var animation_duration = 250; var cluster_threshold_1 = 8; var cluster_threshold_2 = 25; var map_default_center = 'SRID=4326;POINT (2.4397 46.5528)'; var map_default_zoom = '7'; var min_auto_zoom_on_cluster = 13; /* base layers */ var source_osm = function(options){ return new ol.layer.Tile({ source: new ol.source.OSM() }); }; var default_map_layers = { 'osm': source_osm }; var get_layers = function(layers){ if (!layers){ layers = [{'type': 'osm', 'options': null}]; } var ol_layers = []; for (idx in layers){ var layer_attr = layers[idx]; ol_layers.push( default_map_layers[layer_attr['type']](layer_attr['options']) ); } return ol_layers; }; /* styles */ var get_icon_style = function(feature){ return new ol.style.Style({ image: new ol.style.Icon({ anchor: [17, 50], anchorXUnits: 'pixels', anchorYUnits: 'pixels', size: [35, 50], src: static_path + default_pointer }) }); }; var cluster_get_style = function(feature, resolution){ feature.set('key', 'cluster'); var cluster_features = feature.get('features'); var size = cluster_features.length; feature.set('size', size); var style = _styleCache[size]; if (!style && size == 1){ style = _styleCache[size] = [get_icon_style()]; } else if (!style && size > 1){ var color = size > cluster_threshold_2 ? "192,0,0" : size > cluster_threshold_1 ? "255,128,0" : "0,128,0"; var radius = Math.max(8, Math.min(size * 0.75, 20)); var lbl = size.toString(); style = _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' }) }) }) ]; } return style; } /* clustering */ var _styleCache; var cluster_source; var cluster_layer; var enable_clustering = function(){ // cache for styles _styleCache = {}; // cluster Source cluster_source = new ol.source.Cluster({ distance: 40, source: new ol.source.Vector() }); // animated cluster layer cluster_layer = new ol.layer.Vector({ name: 'Cluster', source: cluster_source, // cluster style style: cluster_get_style }); map.addLayer(cluster_layer); }; var reinit_clustering = function(){ cluster_source.getSource().clear(); _styleCache = {}; }; /* manage clicks */ var current_feature; var animate_in_progress = false; var animate_end = function(){animate_in_progress = false}; var wait_animation_end = function(callback, retry){ if (!retry) retry = 1; setTimeout(function(){ retry += 1 if (retry < 5 && animate_in_progress){ wait_animation_end(callback) } else { callback(); } }, 100); }; var manage_click_on_map = function(e) { var feature = map.forEachFeatureAtPixel( e.pixel, function(feature, layer) { return feature; } ); click_on_feature(feature, e); }; var click_on_feature = function(feature, e){ if (!$(e.target).is($(popup_item)) && !$.contains($(popup_item)[0],e.target) ) { $(popup_item).hide(); } if (typeof feature == 'undefined'){ current_feature = null; return; } current_feature = feature; if (!feature) return; var timeout = 200; setTimeout(function(){ // zoom on aggregated var key = feature.get('key'); if (key && key.length > 6 && key.substring(0, 7) == 'cluster'){ feature = click_on_cluster(feature); } }, timeout); }; var auto_zoom = false; var click_on_cluster = function(feature, zoom_level, duration, nb_zoom, current_nb_items){ if (!duration){ // zoom animation must be slower duration = animation_duration * 2; } if (!nb_zoom) nb_zoom = 0; var props = feature.getProperties(); if (!'features' in props) return feature; if (!auto_zoom || props['features'].length == 1){ return display_cluster_detail(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 = map.getView(); if (!zoom_level) zoom_level = v.getZoom() + 1; // center var new_center = feature.getGeometry().getCoordinates(); // max zoom reached if (zoom_level >= min_auto_zoom_on_cluster){ animate_in_progress = true; v.animate({center: new_center, duration: duration}, animate_end); return display_cluster_detail(feature); } // zoom animate_in_progress = true; v.animate({center: new_center, zoom: zoom_level, duration: duration}, animate_end); nb_zoom += 1; // something wrong stop zoom! if (nb_zoom > v.getMaxZoom()) 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 = map.getPixelFromCoordinate(v.getCenter()); var new_feature; map.forEachFeatureAtPixel( pixel, function(feat, layer){ if (layer == cluster_layer){ new_feature = feat; return true } } ); if (new_feature){ if (zoom_level < min_auto_zoom_on_cluster){ return display_cluster_detail(new_feature); } return click_on_cluster( new_feature, zoom_level + 1, duration, nb_zoom, current_nb_items); } // no more cluster feature here or min auto zoom reach: stop zooming return feature; }, duration + 200); }; /* display info */ var display_cluster_detail = function(cluster){ // console.log("display_cluster_detail"); var features = cluster.getProperties()['features'] var offset_x = 0; var offset_y = -21; if (features.length == 1){ offset_y = -54; } display_items(features, offset_x, offset_y); }; var display_items = function(features, offset_x, offset_y){ wait_animation_end(function() {_display_items(features, offset_x, offset_y)}); }; var open_map_window = function(){ $('.ishtar-map-window').show(); }; var complete_list_label = "complete list..."; var _display_items = function(features, offset_x, offset_y){ // console.log("display_items"); var feature = features[0]; var geom = feature.getGeometry(); var popup_content = "