summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chimere/static/chimere/css/styles.css8
-rw-r--r--chimere/static/chimere/img/center.pngbin0 -> 846 bytes
-rw-r--r--chimere/static/chimere/js/clustering.js278
-rw-r--r--chimere/static/chimere/js/jquery.chimere.js106
-rw-r--r--chimere/static/ol3-contextmenu/ol3-contextmenu.min.css8
-rw-r--r--chimere/static/ol3-contextmenu/ol3-contextmenu.min.js8
-rw-r--r--chimere/templates/chimere/blocks/head_chimere.html22
-rw-r--r--chimere/templates/chimere/detail.html3
-rw-r--r--chimere/templatetags/chimere_tags.py6
-rw-r--r--chimere/widgets.py58
-rw-r--r--chimere_example_project/settings.py10
11 files changed, 136 insertions, 371 deletions
diff --git a/chimere/static/chimere/css/styles.css b/chimere/static/chimere/css/styles.css
index 1084ae5..9c7ec62 100644
--- a/chimere/static/chimere/css/styles.css
+++ b/chimere/static/chimere/css/styles.css
@@ -1798,3 +1798,11 @@ span#permalink, .navbar-nav .lbl, #areas-div label, #permalink, #simple_button,
right:50px !important;
top:10px !important;
}
+
+.ol-ctx-menu-container{
+ font-size: 15px;
+}
+
+.ol-ctx-menu-container li.ol-ctx-menu-separator hr{
+ margin: 5px;
+}
diff --git a/chimere/static/chimere/img/center.png b/chimere/static/chimere/img/center.png
new file mode 100644
index 0000000..fad2f26
--- /dev/null
+++ b/chimere/static/chimere/img/center.png
Binary files differ
diff --git a/chimere/static/chimere/js/clustering.js b/chimere/static/chimere/js/clustering.js
deleted file mode 100644
index b3a142c..0000000
--- a/chimere/static/chimere/js/clustering.js
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- Add a recluster to Cluster class.
- probably part of OpenLayers 2.13
-*/
-
-
-OpenLayers.Strategy.Cluster = OpenLayers.Class(OpenLayers.Strategy, {
-
- /**
- * APIProperty: distance
- * {Integer} Pixel distance between features that should be considered a
- * single cluster. Default is 20 pixels.
- */
- distance: 20,
-
- /**
- * APIProperty: threshold
- * {Integer} Optional threshold below which original features will be
- * added to the layer instead of clusters. For example, a threshold
- * of 3 would mean that any time there are 2 or fewer features in
- * a cluster, those features will be added directly to the layer instead
- * of a cluster representing those features. Default is null (which is
- * equivalent to 1 - meaning that clusters may contain just one feature).
- */
- threshold: null,
-
- /**
- * Property: features
- * {Array(<OpenLayers.Feature.Vector>)} Cached features.
- */
- features: null,
-
- /**
- * Property: clusters
- * {Array(<OpenLayers.Feature.Vector>)} Calculated clusters.
- */
- clusters: null,
-
- /**
- * Property: clustering
- * {Boolean} The strategy is currently clustering features.
- */
- clustering: false,
-
- /**
- * Property: resolution
- * {Float} The resolution (map units per pixel) of the current cluster set.
- */
- resolution: null,
-
- /**
- * Constructor: OpenLayers.Strategy.Cluster
- * Create a new clustering strategy.
- *
- * Parameters:
- * options - {Object} Optional object whose properties will be set on the
- * instance.
- */
-
- /**
- * APIMethod: activate
- * Activate the strategy. Register any listeners, do appropriate setup.
- *
- * Returns:
- * {Boolean} The strategy was successfully activated.
- */
- activate: function() {
- var activated = OpenLayers.Strategy.prototype.activate.call(this);
- if(activated) {
- this.layer.events.on({
- "beforefeaturesadded": this.cacheFeatures,
- "moveend": this.cluster,
- scope: this
- });
- }
- return activated;
- },
-
- /**
- * APIMethod: deactivate
- * Deactivate the strategy. Unregister any listeners, do appropriate
- * tear-down.
- *
- * Returns:
- * {Boolean} The strategy was successfully deactivated.
- */
- deactivate: function() {
- var deactivated = OpenLayers.Strategy.prototype.deactivate.call(this);
- if(deactivated) {
- this.clearCache();
- this.layer.events.un({
- "beforefeaturesadded": this.cacheFeatures,
- "moveend": this.cluster,
- scope: this
- });
- }
- return deactivated;
- },
-
- /**
- * Method: cacheFeatures
- * Cache features before they are added to the layer.
- *
- * Parameters:
- * event - {Object} The event that this was listening for. This will come
- * with a batch of features to be clustered.
- *
- * Returns:
- * {Boolean} False to stop features from being added to the layer.
- */
- cacheFeatures: function(event) {
- var propagate = true;
- if(!this.clustering) {
- this.clearCache();
- this.features = event.features;
- this.cluster();
- propagate = false;
- }
- return propagate;
- },
-
- /**
- * Method: clearCache
- * Clear out the cached features.
- */
- clearCache: function() {
- this.features = null;
- },
-
- /**
- * Method: cluster
- * Cluster features based on some threshold distance.
- *
- * Parameters:
- * event - {Object} The event received when cluster is called as a
- * result of a moveend event.
- */
- cluster: function(event) {
- if((!event || event.zoomChanged || (event && event.recluster)) && this.features) {
- var resolution = this.layer.map.getResolution();
- if(resolution != this.resolution || !this.clustersExist() || (event && event.recluster)) {
- this.resolution = resolution;
- var clusters = [];
- var feature, clustered, cluster;
- for(var i=0; i<this.features.length; ++i) {
- feature = this.features[i];
- if(feature.geometry) {
- clustered = false;
- for(var j=clusters.length-1; j>=0; --j) {
- cluster = clusters[j];
- if(this.shouldCluster(cluster, feature)) {
- this.addToCluster(cluster, feature);
- clustered = true;
- break;
- }
- }
- if(!clustered) {
- clusters.push(this.createCluster(this.features[i]));
- }
- }
- }
- this.layer.removeAllFeatures();
- if(clusters.length > 0) {
- if(this.threshold > 1) {
- var clone = clusters.slice();
- clusters = [];
- var candidate;
- for(var i=0, len=clone.length; i<len; ++i) {
- candidate = clone[i];
- if(candidate.attributes.count < this.threshold) {
- Array.prototype.push.apply(clusters, candidate.cluster);
- } else {
- clusters.push(candidate);
- }
- }
- }
- this.clustering = true;
- // A legitimate feature addition could occur during this
- // addFeatures call. For clustering to behave well, features
- // should be removed from a layer before requesting a new batch.
- this.layer.addFeatures(clusters);
- this.clustering = false;
- }
- this.clusters = clusters;
- }
- }
- },
-
- /**
- * Method: recluster
- * User-callable function to recluster features
- * Useful for instances where a clustering attribute (distance, threshold, ...)
- * has changed
- */
- recluster: function(){
- var event={"recluster":true};
- this.cluster(event);
- },
-
- /**
- * Method: clustersExist
- * Determine whether calculated clusters are already on the layer.
- *
- * Returns:
- * {Boolean} The calculated clusters are already on the layer.
- */
- clustersExist: function() {
- var exist = false;
- if(this.clusters && this.clusters.length > 0 &&
- this.clusters.length == this.layer.features.length) {
- exist = true;
- for(var i=0; i<this.clusters.length; ++i) {
- if(this.clusters[i] != this.layer.features[i]) {
- exist = false;
- break;
- }
- }
- }
- return exist;
- },
-
- /**
- * Method: shouldCluster
- * Determine whether to include a feature in a given cluster.
- *
- * Parameters:
- * cluster - {<OpenLayers.Feature.Vector>} A cluster.
- * feature - {<OpenLayers.Feature.Vector>} A feature.
- *
- * Returns:
- * {Boolean} The feature should be included in the cluster.
- */
- shouldCluster: function(cluster, feature) {
- var cc = cluster.geometry.getBounds().getCenterLonLat();
- var fc = feature.geometry.getBounds().getCenterLonLat();
- var distance = (
- Math.sqrt(
- Math.pow((cc.lon - fc.lon), 2) + Math.pow((cc.lat - fc.lat), 2)
- ) / this.resolution
- );
- return (distance <= this.distance);
- },
-
- /**
- * Method: addToCluster
- * Add a feature to a cluster.
- *
- * Parameters:
- * cluster - {<OpenLayers.Feature.Vector>} A cluster.
- * feature - {<OpenLayers.Feature.Vector>} A feature.
- */
- addToCluster: function(cluster, feature) {
- cluster.cluster.push(feature);
- cluster.attributes.count += 1;
- },
-
- /**
- * Method: createCluster
- * Given a feature, create a cluster.
- *
- * Parameters:
- * feature - {<OpenLayers.Feature.Vector>}
- *
- * Returns:
- * {<OpenLayers.Feature.Vector>} A cluster.
- */
- createCluster: function(feature) {
- var center = feature.geometry.getBounds().getCenterLonLat();
- var cluster = new OpenLayers.Feature.Vector(
- new OpenLayers.Geometry.Point(center.lon, center.lat),
- {count: 1}
- );
- cluster.cluster = [feature];
- return cluster;
- },
-
- CLASS_NAME: "OpenLayers.Strategy.Cluster"
-});
diff --git a/chimere/static/chimere/js/jquery.chimere.js b/chimere/static/chimere/js/jquery.chimere.js
index 9b0f386..0ffb14f 100644
--- a/chimere/static/chimere/js/jquery.chimere.js
+++ b/chimere/static/chimere/js/jquery.chimere.js
@@ -18,6 +18,23 @@ See the file COPYING for details.
var extra_url;
+var labels = {
+ 'center_map': "Center map here",
+ 'zoom_in': "Zoom in",
+ 'zoom_out': "Zoom out"
+};
+
+if (typeof language != 'undefined'){
+ if (language == 'fr'){
+ labels = {
+ 'center_map': "Centrer la carte ici",
+ 'zoom_in': "Zoom avant",
+ 'zoom_out': "Zoom arrière"
+ };
+
+ }
+}
+
// Create a simple layer switcher
var default_map_lbl = '';
@@ -214,7 +231,6 @@ function transform(obj) {
},
current_feature: null, // To store the active POI
current_control: null, // To store the current control
- current_popup: null, // To store the current POI popup displayed
current_category: null, // To store the current category clicked in list
current_routes_features: [], // To store the current routes find by routing
itinerary_step_number:0, // current step number
@@ -358,6 +374,32 @@ function transform(obj) {
}
});
+ // manage context menu
+
+ var contextmenu = new ContextMenu({
+ width: 170,
+ default_items: false,
+ items: [
+ {
+ text: labels['center_map'],
+ callback: methods.mapCenter,
+ icon: STATIC_URL + 'chimere/img/center.png'
+ },
+ '-',
+ {
+ text: labels['zoom_in'],
+ classname: 'ol-ctx-menu-zoom-in ol-ctx-menu-icon',
+ callback: methods.zoomIn
+ },
+ {
+ text: labels['zoom_out'],
+ classname: 'ol-ctx-menu-zoom-out ol-ctx-menu-icon',
+ callback: methods.zoomOut
+ }
+ ]
+ });
+ settings.map.addControl(contextmenu);
+
/* Manage permalink */
/* OL3-deprecated permalink
if (!settings.edition){
@@ -516,9 +558,8 @@ function transform(obj) {
settings.current_feature = feature;
if (!settings.edition){
if (methods._is_popuphovering()) return;
+ $(settings.popup_item).popover('destroy');
if (feature) {
- $(settings.popup_item).popover('destroy');
-
// zoom on aggregated
var key = feature.get('key');
if (key && key.length > 3 && key.substring(0, 3) == 'agg' &&
@@ -530,15 +571,11 @@ function transform(obj) {
}
return
}
-
if (key && key.length > 6 && key.substring(0, 7) == 'cluster'){
feature = methods.clickOnCluster(feature);
} else {
methods.openPopup(feature);
}
- } else {
- settings.current_popup = null;
- $(settings.popup_item).popover('destroy');
}
}
});
@@ -1035,7 +1072,6 @@ function transform(obj) {
return feature;
},
openPopup: function(feature, offset_x, offset_y, alt_coordinates){
- settings.current_popup = feature.getId();
if (!offset_x){
offset_x = feature.get('popup_offset_x');
if (!offset_x) offset_x = 0;
@@ -1159,20 +1195,42 @@ function transform(obj) {
// init the context menu
zoomIn: function(){
- methods.mapCenter();
- settings.map.zoomIn();
+ v = settings.map.getView();
+ var zoom_level = v.getZoom() + 1;
+ if (zoom_level >= settings.maxZoom){
+ return;
+ }
+ var zoom = ol.animation.zoom({
+ duration: settings.animation_duration,
+ resolution: v.getResolution()
+ });
+ settings.map.beforeRender(zoom);
+ v.setZoom(zoom_level);
},
// zoom out from the map menu
zoomOut: function(){
- methods.mapCenter();
- settings.map.zoomOut();
+ v = settings.map.getView();
+ var zoom_level = v.getZoom() - 1;
+ if (zoom_level <= settings.minZoom){
+ return;
+ }
+ var zoom = ol.animation.zoom({
+ duration: settings.animation_duration,
+ resolution: v.getResolution()
+ });
+ settings.map.beforeRender(zoom);
+ v.setZoom(zoom_level);
},
// center from the map menu
- mapCenter: function(){
- $('#chimere_map_menu').hide();
- settings.map.setCenter(settings.current_position);
+ mapCenter: function(obj){
+ var pan = ol.animation.pan({
+ duration: settings.animation_duration,
+ source: settings.map.getView().getCenter()
+ });
+ settings.map.beforeRender(pan);
+ settings.map.getView().setCenter(obj.coordinate);
},
// center from the lon lat
@@ -1226,24 +1284,6 @@ function transform(obj) {
}
},
*/
- /*
- * Display menu on the map
- */
- displayMapMenu: function(e) {
- if (methods.hidePopup(e)) return;
- if ($('#chimere_map_menu').is(":visible")){
- $('#chimere_map_menu').hide();
- } else{
- methods.setCurrentPosition(
- settings.map.getLonLatFromViewPortPx(e.xy));
- var offsetX = e.pageX;
- var offsetY = e.pageY;
- $('#chimere_map_menu').show('fast');
- $('#chimere_map_menu').css('display', 'block');
- $('#chimere_map_menu').css('top', offsetY);
- $('#chimere_map_menu').css('left', offsetX);
- }
- },
loadMarker: function(object_id) {
var uri = extra_url + "get-marker/" + object_id;
$.ajax({url: uri,
diff --git a/chimere/static/ol3-contextmenu/ol3-contextmenu.min.css b/chimere/static/ol3-contextmenu/ol3-contextmenu.min.css
new file mode 100644
index 0000000..c1c1c53
--- /dev/null
+++ b/chimere/static/ol3-contextmenu/ol3-contextmenu.min.css
@@ -0,0 +1,8 @@
+/**
+ * Custom Context Menu for Openlayers 3
+ * https://github.com/jonataswalker/ol3-contextmenu
+ * Version: v2.2.4
+ * Built: 2016-09-01T19:04:10-03:00
+ */
+
+.ol-ctx-menu-container{position:absolute;padding:10px;list-style:none;background:#fff;color:#222;font-size:13px;border-radius:5px;box-shadow:rgba(0,0,0,.2) 3px 3px 5px;box-sizing:border-box}.ol-ctx-menu-container a,.ol-ctx-menu-container abbr,.ol-ctx-menu-container acronym,.ol-ctx-menu-container address,.ol-ctx-menu-container applet,.ol-ctx-menu-container article,.ol-ctx-menu-container aside,.ol-ctx-menu-container audio,.ol-ctx-menu-container b,.ol-ctx-menu-container big,.ol-ctx-menu-container blockquote,.ol-ctx-menu-container canvas,.ol-ctx-menu-container caption,.ol-ctx-menu-container center,.ol-ctx-menu-container cite,.ol-ctx-menu-container code,.ol-ctx-menu-container dd,.ol-ctx-menu-container del,.ol-ctx-menu-container details,.ol-ctx-menu-container dfn,.ol-ctx-menu-container div,.ol-ctx-menu-container dl,.ol-ctx-menu-container dt,.ol-ctx-menu-container em,.ol-ctx-menu-container embed,.ol-ctx-menu-container fieldset,.ol-ctx-menu-container figcaption,.ol-ctx-menu-container figure,.ol-ctx-menu-container footer,.ol-ctx-menu-container form,.ol-ctx-menu-container h1,.ol-ctx-menu-container h2,.ol-ctx-menu-container h3,.ol-ctx-menu-container h4,.ol-ctx-menu-container h5,.ol-ctx-menu-container h6,.ol-ctx-menu-container header,.ol-ctx-menu-container hgroup,.ol-ctx-menu-container i,.ol-ctx-menu-container iframe,.ol-ctx-menu-container img,.ol-ctx-menu-container ins,.ol-ctx-menu-container kbd,.ol-ctx-menu-container label,.ol-ctx-menu-container legend,.ol-ctx-menu-container li,.ol-ctx-menu-container mark,.ol-ctx-menu-container menu,.ol-ctx-menu-container nav,.ol-ctx-menu-container object,.ol-ctx-menu-container ol,.ol-ctx-menu-container output,.ol-ctx-menu-container p,.ol-ctx-menu-container pre,.ol-ctx-menu-container q,.ol-ctx-menu-container ruby,.ol-ctx-menu-container s,.ol-ctx-menu-container samp,.ol-ctx-menu-container section,.ol-ctx-menu-container small,.ol-ctx-menu-container span,.ol-ctx-menu-container strike,.ol-ctx-menu-container strong,.ol-ctx-menu-container sub,.ol-ctx-menu-container summary,.ol-ctx-menu-container sup,.ol-ctx-menu-container table,.ol-ctx-menu-container tbody,.ol-ctx-menu-container td,.ol-ctx-menu-container tfoot,.ol-ctx-menu-container th,.ol-ctx-menu-container thead,.ol-ctx-menu-container time,.ol-ctx-menu-container tr,.ol-ctx-menu-container tt,.ol-ctx-menu-container u,.ol-ctx-menu-container ul,.ol-ctx-menu-container var,.ol-ctx-menu-container video{margin:0;padding:0;border:0;font:inherit;font-size:100%;vertical-align:baseline}.ol-ctx-menu-container table{border-collapse:collapse;border-spacing:0}.ol-ctx-menu-container caption,.ol-ctx-menu-container td,.ol-ctx-menu-container th{text-align:left;font-weight:400;vertical-align:middle}.ol-ctx-menu-container blockquote,.ol-ctx-menu-container q{quotes:none}.ol-ctx-menu-container blockquote:after,.ol-ctx-menu-container blockquote:before,.ol-ctx-menu-container q:after,.ol-ctx-menu-container q:before{content:"";content:none}.ol-ctx-menu-container a img{border:none}.ol-ctx-menu-container *,.ol-ctx-menu-container ::after,.ol-ctx-menu-container ::before{box-sizing:inherit}.ol-ctx-menu-container.ol-ctx-menu-hidden{opacity:0;visibility:hidden;-webkit-transition:visibility 0s linear .3s,opacity .3s;transition:visibility 0s linear .3s,opacity .3s}.ol-ctx-menu-container li{position:relative;line-height:20px;padding:2px 5px}.ol-ctx-menu-container li:not(.ol-ctx-menu-separator):hover{cursor:pointer;background-color:#333;color:#eee}.ol-ctx-menu-container li.ol-ctx-menu-submenu ul{border:1px solid #eee;top:0;opacity:0;visibility:hidden;-webkit-transition:visibility 0s linear .3s,opacity .3s;transition:visibility 0s linear .3s,opacity .3s}.ol-ctx-menu-container li.ol-ctx-menu-submenu:hover ul{opacity:1;visibility:visible;-webkit-transition-delay:0s;transition-delay:0s}.ol-ctx-menu-container li.ol-ctx-menu-submenu::after{position:absolute;top:7px;right:10px;content:"";display:inline-block;width:.6em;height:.6em;border-right:.3em solid #222;border-top:.3em solid #222;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ol-ctx-menu-container li.ol-ctx-menu-submenu:hover::after{border-color:#eee}.ol-ctx-menu-container li.ol-ctx-menu-separator{padding:0}.ol-ctx-menu-container li.ol-ctx-menu-separator hr{border:0;height:1px;background-image:-webkit-linear-gradient(right,transparent,rgba(0,0,0,.75),transparent);background-image:linear-gradient(to left,transparent,rgba(0,0,0,.75),transparent)}.ol-ctx-menu-icon{text-indent:20px;background-size:20px auto;background-repeat:no-repeat;background-position:left center}.ol-ctx-menu-zoom-in{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABaUlEQVQ4T72U7VHCQBCGn90GtAMuNGCswFiBWIFQgWMFxg6wArECsQKhArEBiB1Qwa1zgQn5IAYcxv13k71n3919L8KJQ07M47+BzgG9TRfZ/JBuWhS6BJFHRJICYrZGZIz3z5Ct2+B7gG6I6kt+wewdkQVwjtkAkR5mC8yu26A1oItR/cTsOweQBdgutD8G7jGm2PJ2n8oqUKIpIjd4HxTM8gvaT/F+AlmWnyWaIXKF95eNguFzTYFhNsdWu9kFgFlaFMANUH3D8wDLoLgSTSD2il8NCe2ZXQBxWDGwxmyUzzOMBZ7wy7Qb2K0wQfXjMOBuhlFpZtNty5sFaTQBuTusZdymeqs1SpYKcO9HkE3KbTd9WFijMHJQ5hBNEAYNq5Qd0dhyke0GiE4QzjqfW23mHT8Hl4DG4Lce3FPE7AtbBSdsbNqpoJLgYkRnNeUV+xwJDHTnUEkxHGbhBXUs5TjJjew/KPy94g+NRaIVRYmMXwAAAABJRU5ErkJggg==)}.ol-ctx-menu-container li:hover.ol-ctx-menu-zoom-in{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABc0lEQVQ4T71U21ECQRDsJgGdvQDECMQIxAjECMQILCPwzAAjECIQI0AiEDPQAPaWCBhrcKHuCUcV5f7dY3v6tUscefHIePhfwBBCF8CZqRCReRs1tQxDCH1VfQLQz4EsSY4AvIjIsgm8AhhCGKrqa9zwrqoLAKckB5HtguR1E2gBMITQU9VPAD8GICIGtl3e+xHJBwBT59xtHcsCYJZlUwA3kcGHbfDep51OZywi3/acZZm9vyJ5WR5o38uACmDunNt6ZwAkUxFZDwghDFT1jeSjiJinhVUBVNVJkiTDKO8CQA+AsbNQ7s1Ps0VVn5MkSfcCtmBoDZi1Bdx4eJ7zbBolrwPy3o9J3rWSHPs3A1BbjVKlYBaIyDgvu9LDXDU2RTZmXVW1oKyLxRD+OrkOrJLy5mVM0iaftDhuhVbsvBzMglzKUNW6IV/OOWtCM8MmVvEkmbwt83LaB19fdgOtVquUZJeknaDdobTwbOcvBzPcN/AXH1DFFWP7u9oAAAAASUVORK5CYII=)}.ol-ctx-menu-zoom-out{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABU0lEQVQ4T72U7VECMRRFz3sNaAdkacC1AtcKxApcKnCsQOwAK3CtQKxAqEBsANYOqCDPyTIC+8WCw5jfybn33dxEOPGSE/P4b6BzQG89RT47ZJoWhy5B5BGRZAMxWyEyxvtnyFdt8AagS1F9KQ6YvSMyB84xGyDSw2yO2XUbtAJ0MaqfmH0XAPIA2y7tj4F7jAm2uG1yWQZKNEHkBu+Dg2njWBJNEbnC+8uaIFRuWfuG2QxbbrOrUd0A1Tc8D7AIjkur7DAAsVf8MiWMZ3ZR2m02LPIMscATfjHqBnY7TFD9OAy4zTCCPG/MUKMM5O6wkXFr9dZq7FQqqHk/hDzbFa73cFONTZFDdRyiCcKg5rrSiLaXkiI6RjjrfG6VzDs+B5eAxuDXeYpmNRGzL2wZ/wof+du4GNFpBVqqz5HA4MM5VEYYDrOs+1I6Q9u/4Q8O9wN/AGgWjBVqQjjgAAAAAElFTkSuQmCC)}.ol-ctx-menu-container li:hover.ol-ctx-menu-zoom-out{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABYklEQVQ4T72U4VHCQBCF36tA91KAWIFYgViBWIFYgWMFYgdYgVCBWAFSgdiBFpAsFWSdxcDkQoBkhnF/ZjbfvX377ogjF4/Mw/8CVbUD4MynEJF5k2lqFapqz8yeAPRKkCXJEYAXEVnugm8BVXVgZq/FD+9mtgBwSrJfqF2QvN4FjYCq2jWzTwA/DhARh20qTdMRyQcA0xDCbZ3KCJhl2RTATaHgo+6HLMv8+xXJy+qB3l8FGoB5CKHsXcRV1b6ZvZF8FBH3NKotoJlNkiQZFONdlLtJ3rufbouZPSdJMjwIbKDQEzBrClx7eC4i33Uepmk6JnnXaOQifzMAtdGoRApugYiMI1uqKkrRWAfZo9MxM1+UZzFewl8mN4nYdVM83L7BkwbXLUrF3sfBLQDQBbDy08x8vOohXyEE71lVq9emuEk+3gZa3XYroCvwFyjP8yHJDsnxwaU08GxvS2uFhw78BbzWrxXgMbsHAAAAAElFTkSuQmCC)} \ No newline at end of file
diff --git a/chimere/static/ol3-contextmenu/ol3-contextmenu.min.js b/chimere/static/ol3-contextmenu/ol3-contextmenu.min.js
new file mode 100644
index 0000000..e2f1855
--- /dev/null
+++ b/chimere/static/ol3-contextmenu/ol3-contextmenu.min.js
@@ -0,0 +1,8 @@
+/**
+ * Custom Context Menu for Openlayers 3
+ * https://github.com/jonataswalker/ol3-contextmenu
+ * Version: v2.2.4
+ * Built: 2016-09-01T19:04:10-03:00
+ */
+
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.ContextMenu=t()}(this,function(){"use strict";var e="ol-ctx-menu",t="-container",n="-separator",i="-submenu",s="-hidden",o="-icon",a="-zoom-in",r="-zoom-out",l="ol-unselectable",c={isNumeric:function(e){return/^\d+$/.test(e)},classRegex:function(e){return new RegExp("(^|\\s+) "+e+" (\\s+|$)")},addClass:function(e,t,n){var i=this;if(Array.isArray(e))return void e.forEach(function(e){i.addClass(e,t)});for(var s=Array.isArray(t)?t:t.split(/\s+/),o=s.length;o--;)i.hasClass(e,s[o])||i._addClass(e,s[o],n)},_addClass:function(e,t,n){var i=this;e.classList?e.classList.add(t):e.className=(e.className+" "+t).trim(),n&&this.isNumeric(n)&&window.setTimeout(function(){i._removeClass(e,t)},n)},removeClass:function(e,t,n){var i=this;if(Array.isArray(e))return void e.forEach(function(e){i.removeClass(e,t,n)});for(var s=Array.isArray(t)?t:t.split(/\s+/),o=s.length;o--;)i.hasClass(e,s[o])&&i._removeClass(e,s[o],n)},_removeClass:function(e,t,n){var i=this;e.classList?e.classList.remove(t):e.className=e.className.replace(this.classRegex(t)," ").trim(),n&&this.isNumeric(n)&&window.setTimeout(function(){i._addClass(e,t)},n)},hasClass:function(e,t){return e.classList?e.classList.contains(t):this.classRegex(t).test(e.className)},toggleClass:function(e,t){var n=this;return Array.isArray(e)?void e.forEach(function(e){n.toggleClass(e,t)}):void(e.classList?e.classList.toggle(t):this.hasClass(e,t)?this._removeClass(e,t):this._addClass(e,t))},$:function(e){return e="#"===e[0]?e.substr(1,e.length):e,document.getElementById(e)},isElement:function(e){return"HTMLElement"in window?!!e&&e instanceof HTMLElement:!!e&&"object"==typeof e&&1===e.nodeType&&!!e.nodeName},find:function(e,t,n){void 0===t&&(t=window.document);var i=/^(#?[\w-]+|\.[\w-.]+)$/,s=/\./g,o=Array.prototype.slice,a=[];if(i.test(e))switch(e[0]){case"#":a=[this.$(e.substr(1))];break;case".":a=o.call(t.getElementsByClassName(e.substr(1).replace(s," ")));break;default:a=o.call(t.getElementsByTagName(e))}else a=o.call(t.querySelectorAll(e));return n?a:a[0]},getAllChildren:function(e,t){return[].slice.call(e.getElementsByTagName(t))},isEmpty:function(e){return!e||0===e.length},emptyArray:function(e){for(;e.length;)e.pop()},removeAllChildren:function(e){for(;e.firstChild;)e.removeChild(e.firstChild)},mergeOptions:function(e,t){var n={};for(var i in e)n[i]=e[i];for(var s in t)n[s]=t[s];return n},createFragment:function(e){var t=document.createDocumentFragment(),n=document.createElement("div");for(n.innerHTML=e;n.firstChild;)t.appendChild(n.firstChild);return t},contains:function(e,t){return!!~t.indexOf(e)},isDefAndNotNull:function(e){return null!=e},assertEqual:function(e,t,n){if(e!=t)throw new Error(n+" mismatch: "+e+" != "+t)},assert:function(e,t){if(void 0===t&&(t="Assertion failed"),!e){if("undefined"!=typeof Error)throw new Error(t);throw t}}},u={BEFOREOPEN:"beforeopen",OPEN:"open",CLOSE:"close",ADD_MENU_ENTRY:"add-menu-entry"},d={width:150,default_items:!0},h=[{text:"Zoom In",classname:[e+a,e+o].join(" "),callback:function(e,t){var n=t.getView(),i=ol.animation.pan({duration:1e3,source:n.getCenter()}),s=ol.animation.zoom({duration:1e3,resolution:n.getResolution()});t.beforeRender(i,s),n.setCenter(e.coordinate),n.setZoom(+n.getZoom()+1)}},{text:"Zoom Out",classname:[e+r,e+o].join(" "),callback:function(e,t){var n=t.getView(),i=ol.animation.pan({duration:1e3,source:n.getCenter()}),s=ol.animation.zoom({duration:1e3,resolution:n.getResolution()});t.beforeRender(i,s),n.setCenter(e.coordinate),n.setZoom(+n.getZoom()-1)}}],m=function(e){return this.Base=e,this.map=void 0,this.map_element=void 0,this.coordinate_clicked=void 0,this.pixel_clicked=void 0,this.counter=0,this.lineHeight=0,this.items={},this.submenu={left:this.Base.options.width-15+"px",last_left:""},this.event_handler=this.handleEvent.bind(this),this};m.prototype.init=function(e){this.map=e,this.map_element=e.getTargetElement(),this.setListeners(),this.Base.constructor.Html.createMenu(),this.lineHeight=this.getItemsLength()>0?this.Base.container.offsetHeight/this.getItemsLength():this.Base.constructor.Html.cloneAndGetLineHeight()},m.prototype.getItemsLength=function(){var e=this,t=0;return Object.keys(this.items).forEach(function(n){e.items[n].submenu||e.items[n].separator||t++}),t},m.prototype.getPixelClicked=function(){return this.pixel_clicked},m.prototype.getCoordinateClicked=function(){return this.coordinate_clicked},m.prototype.positionContainer=function(t){var n=this,o=this.map.getSize(),a=o[0],r=o[1],l=r-t[1],u=a-t[0],d={w:this.Base.container.offsetWidth,h:Math.round(this.lineHeight*this.getItemsLength())},h=c.find("li."+e+i+">ul",this.Base.container,!0);u>=d.w?(this.Base.container.style.right="auto",this.Base.container.style.left=t[0]+5+"px"):(this.Base.container.style.left="auto",this.Base.container.style.right="15px"),l>=d.h?(this.Base.container.style.bottom="auto",this.Base.container.style.top=t[1]-10+"px"):(this.Base.container.style.top="auto",this.Base.container.style.bottom=0),c.removeClass(this.Base.container,e+s),h.length&&(u<2*d.w?this.submenu.last_left="-"+d.w+"px":this.submenu.last_left=this.submenu.left,h.forEach(function(e){e.style.left=n.submenu.last_left}))},m.prototype.openMenu=function(e,t){this.positionContainer(e),this.Base.dispatchEvent({type:u.OPEN,pixel:e,coordinate:t})},m.prototype.closeMenu=function(){c.addClass(this.Base.container,e+s),this.Base.dispatchEvent({type:u.CLOSE})},m.prototype.getNextItemIndex=function(){return++this.counter},m.prototype.setListeners=function(){this.map_element.addEventListener("contextmenu",this.event_handler,!1)},m.prototype.removeListeners=function(){this.map_element.removeEventListener("contextmenu",this.event_handler,!1)},m.prototype.handleEvent=function(e){var t=this;t.coordinate_clicked=this.map.getEventCoordinate(e),t.pixel_clicked=this.map.getEventPixel(e),t.Base.dispatchEvent({type:u.BEFOREOPEN,pixel:t.pixel_clicked,coordinate:t.coordinate_clicked}),t.Base.disabled||(e.stopPropagation(),e.preventDefault(),t.openMenu(t.pixel_clicked,t.coordinate_clicked),e.target.addEventListener("mousedown",{handleEvent:function(n){t.closeMenu(),e.target.removeEventListener(n.type,this,!1)}},!1))},m.prototype.setItemListener=function(e,t){var n=this;e&&"function"==typeof this.items[t].callback&&!function(i){e.addEventListener("click",function(e){e.preventDefault();var s={coordinate:n.getCoordinateClicked(),data:n.items[t].data||null};n.closeMenu(),i.call(void 0,s,n.map)},!1)}(this.items[t].callback)};var p=function(e){return this.Base=e,this.Base.container=this.container=this.createContainer(),this};p.prototype.createContainer=function(){var n=document.createElement("ul");return n.className=[e+t,e+s,l].join(" "),n.style.width=parseInt(this.Base.options.width,10)+"px",n},p.prototype.createMenu=function(){var e=this.Base.options,t=[];return"items"in e?t=e.default_items?e.items.concat(h):e.items:e.default_items&&(t=h),0!==t.length&&void t.forEach(this.addMenuEntry,this)},p.prototype.addMenuEntry=function(n){var s=this,o=this.Base.constructor.Internal,a=o.getNextItemIndex(),r=e+i;if(n.items&&Array.isArray(n.items)){n.classname=n.classname||"",c.contains(r,n.classname)||(n.classname=n.classname.length>0?" "+r:r);var l=this.generateHtmlAndPublish(this.container,n,a),u=document.createElement("ul");u.className=e+t,u.style.left=o.submenu.last_left||o.submenu.left,u.style.width=this.Base.options.width+"px",l.appendChild(u),n.items.forEach(function(e){s.generateHtmlAndPublish(u,e,o.getNextItemIndex(),!0)})}else this.generateHtmlAndPublish(this.container,n,a)},p.prototype.generateHtmlAndPublish=function(t,i,s,a){var r,l,u,d=!1,h=this.Base.constructor.Internal;return"string"==typeof i&&"-"==i.trim()?(r=['<li id="index',s,'" class="',e,n,'"><hr></li>'].join(""),l=c.createFragment(r),u=[].slice.call(l.childNodes,0)[0],t.appendChild(l),d=!0):(i.classname=i.classname||"",r="<span>"+i.text+"</span>",l=c.createFragment(r),u=document.createElement("li"),i.icon&&(""===i.classname?i.classname=e+o:i.classname.indexOf(e+o)===-1&&(i.classname+=" "+e+o),u.setAttribute("style","background-image:url("+i.icon+")")),u.id="index"+s,u.className=i.classname,u.appendChild(l),t.appendChild(u)),h.items[s]={id:s,submenu:a||0,separator:d,callback:i.callback,data:i.data||null},h.setItemListener(u,s),u},p.prototype.removeMenuEntry=function(e){var t=c.find("#index"+e,this.container);t&&this.container.removeChild(t),delete this.Base.constructor.Internal.items[e]},p.prototype.cloneAndGetLineHeight=function(){var e=this.container.cloneNode(),t=c.createFragment("<span>Foo</span>"),n=c.createFragment("<span>Foo</span>"),i=document.createElement("li"),s=document.createElement("li");i.appendChild(t),s.appendChild(n),e.appendChild(i),e.appendChild(s),this.container.parentNode.appendChild(e);var o=e.offsetHeight/2;return this.container.parentNode.removeChild(e),o};var f=function(e){function t(n){void 0===n&&(n={}),c.assert("object"==typeof n,"@param `opt_options` should be object type!"),this.options=c.mergeOptions(d,n),this.disabled=!1,t.Internal=new m(this),t.Html=new p(this),e.call(this,{element:this.container})}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.clear=function(){Object.keys(t.Internal.items).forEach(function(e){t.Html.removeMenuEntry(e)})},t.prototype.close=function(){t.Internal.closeMenu()},t.prototype.enable=function(){this.disabled=!1},t.prototype.disable=function(){this.disabled=!0},t.prototype.getDefaultItems=function(){return h},t.prototype.extend=function(e){c.assert(Array.isArray(e),"@param `arr` should be an Array."),e.forEach(this.push,this)},t.prototype.pop=function(){var e=Object.keys(t.Internal.items);t.Html.removeMenuEntry(e[e.length-1])},t.prototype.push=function(e){c.assert(c.isDefAndNotNull(e),"@param `item` must be informed."),t.Html.addMenuEntry(e,t.Internal.getNextItemIndex())},t.prototype.shift=function(){t.Html.removeMenuEntry(Object.keys(t.Internal.items)[0])},t.prototype.setMap=function(e){ol.control.Control.prototype.setMap.call(this,e),e?t.Internal.init(e):t.Internal.removeListeners()},t}(ol.control.Control);return f});
diff --git a/chimere/templates/chimere/blocks/head_chimere.html b/chimere/templates/chimere/blocks/head_chimere.html
index 0554f4c..dbb7053 100644
--- a/chimere/templates/chimere/blocks/head_chimere.html
+++ b/chimere/templates/chimere/blocks/head_chimere.html
@@ -1,23 +1,13 @@
-{% if not is_edit %}{% for css_url in MAP_CSS_URLS %}
-<link rel="stylesheet" href="{{ css_url }}" />{% endfor %}
-{% for js_url in MAP_JS_URLS %}
-<script src="{{ js_url }}" type="text/javascript"></script>{% endfor %}
-{% endif %}
-{% if routing %}<script src="{{ STATIC_URL }}chimere/js/routing-widget.js" type="text/javascript"></script>{% endif %}
-{% if enable_clustering %}<script src="{{ STATIC_URL }}chimere/js/clustering.js" type="text/javascript"></script>{% endif %}
-<script src="{{ STATIC_URL }}chimere/js/jquery.chimere.js" type="text/javascript"></script>
+<link rel="stylesheet" href="{{ STATIC_URL }}ol3/ol.css" />
+<link rel="stylesheet" href="{{ STATIC_URL }}ol3-contextmenu/ol3-contextmenu.min.css" />
+<script src="{{ STATIC_URL }}ol3/ol.js" type="text/javascript"></script>
<script type="text/javascript">
/* Global variables */
var STATIC_URL = static_url = "{{ STATIC_URL }}";
var MEDIA_URL = media_path = "{{ MEDIA_URL }}";
var extra_url = "{{ EXTRA_URL }}";
-</script>
-<script src="{{ STATIC_URL }}chimere/js/utils.js" type="text/javascript"></script>
-<script src="{{ STATIC_URL }}chimere/js/base.js" type="text/javascript"></script>
-<script type="text/javascript">
var DEFAULT_ZOOM = {{ DEFAULT_ZOOM }};
var EPSG_DISPLAY_PROJECTION = 'EPSG:{{ EPSG_DISPLAY_PROJECTION }}';
- //OL3-deprecated: OpenLayers.ImgPath = '{{ STATIC_URL }}chimere/img/';
var EPSG_PROJECTION = epsg_projection = 'EPSG:{{ EPSG_PROJECTION }}';
var CENTER_LONLAT = centerLonLat = ol.proj.transform(
[{{DEFAULT_CENTER.0|safe}}, {{DEFAULT_CENTER.1|safe}}],
@@ -25,4 +15,10 @@
var restricted_extent;
{% if area_name %}var area_name = '{{ area_name }}';{% endif %}
var get_share_url = '{% url chimere:get-share-url %}';
+ var language = "{{LANGUAGE}}";
</script>
+<script src="{{ STATIC_URL }}ol3-contextmenu/ol3-contextmenu.min.js" type="text/javascript"></script>
+{% if routing %}<script src="{{ STATIC_URL }}chimere/js/routing-widget.js" type="text/javascript"></script>{% endif %}
+<script src="{{ STATIC_URL }}chimere/js/jquery.chimere.js" type="text/javascript"></script>
+<script src="{{ STATIC_URL }}chimere/js/utils.js" type="text/javascript"></script>
+<script src="{{ STATIC_URL }}chimere/js/base.js" type="text/javascript"></script>
diff --git a/chimere/templates/chimere/detail.html b/chimere/templates/chimere/detail.html
index 2898810..41a4ba3 100644
--- a/chimere/templates/chimere/detail.html
+++ b/chimere/templates/chimere/detail.html
@@ -141,12 +141,13 @@ $(document).ready(function(){
$('a[data-toggle="pill"]').on('shown.bs.tab', function (e) {
manage_tab_opening(e);
})
-
+{% comment %}
// $('div.media-player').jmeEmbedControls();
$("a[rel^='prettyPhoto']").prettyPhoto({
show_title: false,
social_tools: ''
});
+{% endcomment %}
});
</script>
diff --git a/chimere/templatetags/chimere_tags.py b/chimere/templatetags/chimere_tags.py
index 713f70d..e0dc32b 100644
--- a/chimere/templatetags/chimere_tags.py
+++ b/chimere/templatetags/chimere_tags.py
@@ -155,6 +155,8 @@ def head_chimere(context):
is_edit = action_selected and action_selected[0] == "contribute"
context_data = {
"is_edit": is_edit,
+ "LANGUAGE": settings.LANGUAGE_CODE.split('-')[0]
+ if settings.LANGUAGE_CODE else 'en',
"STATIC_URL": settings.STATIC_URL,
"MEDIA_URL": settings.MEDIA_URL,
"DYNAMIC_CATEGORIES": 'true' if area and area.dynamic_categories
@@ -165,16 +167,12 @@ def head_chimere(context):
"DEFAULT_CENTER": settings.CHIMERE_DEFAULT_CENTER,
"DEFAULT_ZOOM": settings.CHIMERE_DEFAULT_ZOOM,
"MAP_LAYER": settings.CHIMERE_DEFAULT_MAP_LAYER,
- "MAP_CSS_URLS": settings.MAP_CSS_URLS,
'MOBILE': context['MOBILE'],
'routing':
settings.CHIMERE_ENABLE_ROUTING
if hasattr(settings, 'CHIMERE_ENABLE_ROUTING') else False,
'enable_clustering': settings.CHIMERE_ENABLE_CLUSTERING,
}
- context_data['MAP_JS_URLS'] = settings.MAP_JS_URLS
- if context['MOBILE']:
- context_data['MAP_JS_URLS'] = settings.MAP_MOBILE_JS_URLS
return context_data
diff --git a/chimere/widgets.py b/chimere/widgets.py
index b4bbee6..465ec7f 100644
--- a/chimere/widgets.py
+++ b/chimere/widgets.py
@@ -38,6 +38,22 @@ from django.template.loader import render_to_string
import re
+BASE_CSS = {
+ "all": ("{}ol3/ol.css".format(settings.STATIC_URL),
+ "{}chimere/css/forms.css".format(settings.STATIC_URL))
+}
+
+BASE_JS = tuple(
+ ["{}ol3/ol.js".format(settings.STATIC_URL)] +
+ list(settings.JQUERY_JS_URLS) +
+ ["{}chimere/js/jquery.chimere.js".format(settings.STATIC_URL)])
+
+AREA_JS = tuple(
+ ["{}ol3/ol.js".format(settings.STATIC_URL)] +
+ ["{}chimere/js/edit_area.js".format(settings.STATIC_URL) +
+ "{}chimere/js/base.js".format(settings.STATIC_URL)])
+
+
def getMapJS(area_name=''):
'''Variable initialization for drawing the map
'''
@@ -355,12 +371,8 @@ class PointChooserWidget(forms.TextInput):
Manage the edition of point on a map
"""
class Media:
- css = {
- "all": settings.MAP_CSS_URLS +
- ["%schimere/css/forms.css" % settings.STATIC_URL]
- }
- js = settings.MAP_JS_URLS + list(settings.JQUERY_JS_URLS) + \
- ["%schimere/js/jquery.chimere.js" % settings.STATIC_URL]
+ css = BASE_CSS
+ js = BASE_JS
def render(self, name, value, attrs=None, area_name='', initialized=True):
'''
@@ -446,12 +458,8 @@ class RouteChooserWidget(forms.TextInput):
Manage the edition of route on a map
"""
class Media:
- css = {
- "all": settings.MAP_CSS_URLS +
- ["%schimere/css/forms.css" % settings.STATIC_URL]
- }
- js = settings.MAP_JS_URLS + list(settings.JQUERY_JS_URLS) + \
- ["%schimere/js/jquery.chimere.js" % settings.STATIC_URL]
+ css = BASE_CSS
+ js = BASE_JS
def render(self, name, value, attrs=None, area_name='', routefile_id=None,
initialized=True):
@@ -499,13 +507,8 @@ class AreaWidget(forms.TextInput):
Manage the edition of an area on the map
"""
class Media:
- css = {
- "all": settings.MAP_CSS_URLS +
- ["%schimere/css/forms.css" % settings.STATIC_URL]
- }
- js = settings.MAP_JS_URLS + [
- "%schimere/js/edit_area.js" % settings.STATIC_URL,
- "%schimere/js/base.js" % settings.STATIC_URL]
+ css = BASE_CSS
+ js = AREA_JS
def get_bounding_box_from_value(self, value):
'''
@@ -596,12 +599,8 @@ class PolygonChooserWidget(forms.TextInput):
Manage the edition of polygon on a map
"""
class Media:
- css = {
- "all": settings.MAP_CSS_URLS +
- ["%schimere/css/forms.css" % settings.STATIC_URL]
- }
- js = settings.MAP_JS_URLS + list(settings.JQUERY_JS_URLS) + \
- ["%schimere/js/jquery.chimere.js" % settings.STATIC_URL]
+ css = BASE_CSS
+ js = BASE_JS
def render(self, name, value, attrs=None, area_name='', initialized=True):
val = ''
@@ -652,13 +651,8 @@ class ImportFiltrWidget(AreaWidget):
Manage the edition of the import source field
"""
class Media:
- css = {
- "all": settings.MAP_CSS_URLS +
- ["%schimere/css/forms.css" % settings.STATIC_URL]
- }
- js = settings.MAP_JS_URLS + [
- "%schimere/js/edit_area.js" % settings.STATIC_URL,
- "%schimere/js/base.js" % settings.STATIC_URL]
+ css = BASE_CSS
+ js = AREA_JS
def render(self, name, value, attrs=None):
"""
diff --git a/chimere_example_project/settings.py b/chimere_example_project/settings.py
index 5386185..260905a 100644
--- a/chimere_example_project/settings.py
+++ b/chimere_example_project/settings.py
@@ -344,16 +344,6 @@ if 'CHIMERE_SHARE_NETWORKS' not in globals():
STATIC_URL + 'chimere/img/twitter.png'),
)
-if 'MAP_CSS_URLS' not in globals():
- global MAP_CSS_URLS
- MAP_CSS_URLS = [STATIC_URL + "ol3/ol.css"]
-
-if 'MAP_JS_URLS' not in globals():
- global MAP_JS_URLS
- if DEBUG:
- MAP_JS_URLS = [STATIC_URL + "ol3/ol-debug.js"]
- else:
- MAP_JS_URLS = [STATIC_URL + "ol3/ol.js"]
if 'OSM_MOBILE_JS_URLS' not in globals():
global OSM_MOBILE_URLS
OSM_JS_MOBILE_URLS = [