diff options
| author | Étienne Loks <etienne.loks@peacefrogs.net> | 2013-03-16 12:00:45 +0100 |
|---|---|---|
| committer | Étienne Loks <etienne.loks@peacefrogs.net> | 2013-03-16 12:00:45 +0100 |
| commit | 24b244f358c05645e1dd11266fe1db3c1da03a52 (patch) | |
| tree | c6f3d6d784e5186bebcbe22e47d2eb0fd7efe05e /chimere/static | |
| parent | 8ff3c1b6f1e7f41a3dfb373ea5bceb9f116603b9 (diff) | |
| parent | 8f854e8ca5c816ab58aacc04b4c360dba3de83ee (diff) | |
| download | Chimère-24b244f358c05645e1dd11266fe1db3c1da03a52.tar.bz2 Chimère-24b244f358c05645e1dd11266fe1db3c1da03a52.zip | |
Merge branch 'saclay'
Conflicts:
chimere/migrations/0029_auto__add_field_marker_modified_since_import__add_field_marker_not_for.py
chimere/migrations/0029_auto__add_propertymodelchoice.py
chimere/migrations/0030_auto__add_field_importer_default_name.py
chimere/migrations/0031_auto__add_field_subcategory_dated.py
chimere/migrations/0031_auto__chg_field_picturefile_width__chg_field_picturefile_height.py
chimere/migrations/0032_auto__add_field_subcategory_submission.py
chimere/migrations/0033_auto__add_field_importer_source_file.py
chimere/migrations/0034_auto__add_field_importer_origin__add_field_importer_license__add_field.py
chimere/migrations/0035_area_permissions.py
chimere/migrations/0035_auto__add_field_marker_modified_since_import__add_field_marker_not_for.py
chimere/migrations/0036_auto.py
chimere/migrations/0036_auto__add_field_importer_default_name.py
chimere/migrations/0037_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py
chimere/migrations/0038_auto__chg_field_picturefile_width__chg_field_picturefile_height.py
chimere/migrations/0039_auto__add_multimediaextension__chg_field_multimediafile_multimedia_typ.py
chimere/migrations/0040_remove_excluded_status.py
chimere/migrations/0041_auto__add_field_importer_overwrite.py
chimere/migrations/0041_auto__add_field_importer_source_file.py
chimere/migrations/0042_auto__add_field_importer_origin__add_field_importer_license__add_field.py
chimere/migrations/0042_fix_rights.py
chimere/migrations/0043_area_permissions.py
chimere/migrations/0043_auto__add_field_importer_get_description.py
chimere/migrations/0044_auto.py
chimere/migrations/0044_auto__add_field_importer_default_description.py
chimere/migrations/0046_auto__del_field_subcategory_routing_available.py
chimere/migrations/0047_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py
chimere/migrations/0049_auto__chg_field_multimediafile_multimedia_type.py
chimere/migrations/0050_remove_excluded_status.py
chimere/migrations/0051_auto__add_field_importer_overwrite.py
chimere/migrations/0054_fix_rights.py
chimere/old_migrations/v2.0/0029_auto__add_field_marker_modified_since_import__add_field_marker_not_for.py
chimere/old_migrations/v2.0/0030_auto__add_field_importer_default_name.py
chimere/old_migrations/v2.0/0031_auto__chg_field_picturefile_width__chg_field_picturefile_height.py
chimere/old_migrations/v2.0/0032_auto__add_field_subcategory_submission.py
chimere/old_migrations/v2.0/0033_auto__add_field_importer_source_file.py
chimere/old_migrations/v2.0/0034_auto__add_field_importer_origin__add_field_importer_license__add_field.py
chimere/old_migrations/v2.0/0035_area_permissions.py
chimere/old_migrations/v2.0/0036_auto.py
chimere/old_migrations/v2.0/0037_auto__add_unique_area_order__add_field_importer_associate_marker_to_wa.py
chimere/old_migrations/v2.0/0038_osm_import_filtr.py
chimere/old_migrations/v2.0/0039_auto__add_multimediaextension__chg_field_multimediafile_multimedia_typ.py
chimere/old_migrations/v2.0/0040_remove_excluded_status.py
chimere/old_migrations/v2.0/0041_auto__add_field_importer_overwrite.py
chimere/old_migrations/v2.0/0042_fix_rights.py
chimere/old_migrations/v2.0/0043_auto__add_field_importer_get_description.py
chimere/old_migrations/v2.0/0044_auto__add_field_importer_default_description.py
Diffstat (limited to 'chimere/static')
23 files changed, 1631 insertions, 81 deletions
diff --git a/chimere/static/chimere/css/admin.css b/chimere/static/chimere/css/admin.css new file mode 100644 index 0000000..931d139 --- /dev/null +++ b/chimere/static/chimere/css/admin.css @@ -0,0 +1,6 @@ +.vTextField{ + width:150px; +} +.vLargeTextField{ + width:200px; +} diff --git a/chimere/static/chimere/css/print.css b/chimere/static/chimere/css/print.css new file mode 100644 index 0000000..8dda0b8 --- /dev/null +++ b/chimere/static/chimere/css/print.css @@ -0,0 +1,40 @@ +#topbar, .no-titlebar-simple.ui-dialog, +#zoombar, #zoomin, #zoomout, #slidebar, +#pandown, #panup, #panright, #panleft, +div#footer p.map-footer{ + display:none; +} + +#main-map{ + z-index:10; + top:0; + bottom:0; + height:605pt; + max-height:605pt; + width:1200pt; + right:50%; + border:none; +} + +#panel #chimere_itinerary_panel{ + width:870pt; + bottom:auto; + left:auto; + right:auto; + top:605pt; + position:absolute; + z-index:1000; +} + +#sidebar div#panel{ + width:900pt; + border:none; + overflow:visible; +} + +#chimere_start_label, +#chimere_end_label{ + width:auto; + overflow:auto; +} + diff --git a/chimere/static/chimere/css/styles.css b/chimere/static/chimere/css/styles.css index c30d259..41502c2 100644 --- a/chimere/static/chimere/css/styles.css +++ b/chimere/static/chimere/css/styles.css @@ -15,7 +15,8 @@ a, a:link, a:visited, legend, h2, h3, th, .action li, .action li a, .action li li a, #no-js-message, -#footer a, #footer a:link, #footer a:visited, .ui-widget-header{ +#footer a, #footer a:link, #footer a:visited, .ui-widget-header, +#chimere_itinerary td.l{ color:#fff; } @@ -25,11 +26,23 @@ h2, h3, th, .action li, .action li a, color:#333; } +.nominatim-widget, .disabled{ + color:#aaa; +} + +#chimere_total_label td.l{ + color:#000; +} + /* background-color definition */ body, h2, h3, th, .ui-widget-header, -.action li.selected, #no-js-message{ +#layer_selection h4, +.action li.selected, #no-js-message, +#content .olControlLayerSwitcher .layersDiv, +#content .olControlLayerSwitcher span, +#chimere_itinerary td.l{ background-color:#449506; } @@ -38,10 +51,12 @@ body, h2, h3, th, } fieldset, .action li, #content, -#map-footer, #panel, #areas, +#layer_selection #layer_list, +#map-footer, #panel, #chimere_itinerary_panel, #areas, #welcome, #detail, .detail_footer a, #content .olControlLayerSwitcher .layersDiv, #content .olControlLayerSwitcher span, +#chimere_total_label td.l, #main-map, .window{ background-color:#FFF; } @@ -58,12 +73,14 @@ div.warning, .errorlist{ border:1px solid #54c200; } +#layer_selection h4, +#layer_selection #layer_list, #areas, #detail, #main-map, div.warning, #content, .action li.selected, #content .olControlLayerSwitcher .layersDiv, -#panel, #map-footer, +#panel, #map-footer, #chimere_itinerary_panel, #utils-div{ border:1px solid #327e04; } @@ -92,7 +109,7 @@ h2, #action li, .detail_footer{ fieldset, #content, #panel, #areas, #welcome, #detail, -#category_detail, div.warning{ +#category_description, div.warning{ -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; @@ -143,7 +160,6 @@ h3{ h4, caption{ font-weight:normal; - font-style:italic; margin:0; text-align:left; } @@ -164,6 +180,10 @@ fieldset{ margin-top:8px; } +.hidden{ + display:none; +} + .ui-dialog-buttonset{ text-align:center; } @@ -182,7 +202,7 @@ fieldset{ } #topbar{ - z-index:0; + z-index:10; } ul.action{ @@ -314,6 +334,7 @@ ul.share{ list-style-type:none; margin:0; padding:0; + display:inline; } ul.share li{ @@ -332,6 +353,10 @@ ul.share li{ height:22px; } +.share .share-icon img{ + width:74px; +} + .detail_footer{ text-align:center; position:absolute; @@ -356,8 +381,6 @@ ul.share li{ #main-map{ position:absolute; - margin:0px; - padding:0px; height:93%; margin:0; padding:0; @@ -388,6 +411,45 @@ ul.share li{ z-index:0; } +#layer_selection{ + position:absolute; + z-index:100; + top:80px; + left:200px; +} + +#layer_selection h4, +#layer_selection #layer_list li{ + padding:2px 5px; +} + +#layer_selection h4{ + font-weight:normal; + border-width:1px; + border-style:solid; + width:140px; + text-align:center; +} + +#layer_selection h4:hover{ + cursor:pointer; +} + +#layer_selection ul{ + display:block; +} + +#layer_selection ul#layer_list{ + width:150px; + display:none; + list-style:none; + margin:0; + padding:0; + border-width:1px; + border-style:solid; + border-top:none; +} + .news h3{ padding:0px; margin:0; @@ -410,12 +472,110 @@ ul.share li{ top:50px; right:18px; width:300px; - bottom:44px; + max-height:300px; overflow:auto; padding:0.5em; padding-top:0; } +#chimere_itinerary_panel, +#chimere_itinerary{ + display:none; +} + +#chimere_itinerary_panel label{ + color:#000; +} + +#chimere_itinerary_panel p +{ + margin:0.5em; +} + +#total_label_div{ + margin:5px 0; +} + +.itinerary_label{ + font-size:0.9em; + padding-top:0.5em; + font-style:italic; +} + +.itinerary_label .label{ + font-style:normal; + font-weight:bold; + padding:3px 8px; +} + + +#chimere_itinerary_content{ + overflow:auto; + height:190px; + margin-top:10px; +} + +#chimere_itinerary_content span.l{ + padding:5px; + width:60px; +} + +#chimere_itinerary_content span.j{ + font-style:italic; +} + +#chimere_itinerary_content .number{ + font-weight:bold; +} + +#chimere_itinerary_content span.t, +#chimere_itinerary_content span.b +{ + text-transform: lowercase; +} + +#chimere_map_menu{ + z-index:4; + display:none; + position:absolute; + padding:0.5em; + background-color:#fff; + border:1px solid #bbb; + -webkit-border-radius: 0 8px 8px 8px; + -moz-border-radius: 0 8px 8px 8px; + border-radius: 0 8px 8px 8px; +} + +#map_menu_clear{ + display:none; +} + +#map_menu_zoomin{ + border-top:1px solid #999; +} + +#chimere_map_menu ul, #chimere_map_menu li{ + padding:0.2em; + margin:0; + list-style:none; +} + +#chimere_map_menu li:hover{ + cursor:pointer; + background-color:#ccc; +} + +.nominatim-label{ + display:block; + font-size:0.9em; + font-weight:bold; + height:2.8em; +} + +.nominatim-widget{ + font-style:italic; +} + .simple #panel{ top:5px; bottom:auto; @@ -494,6 +654,11 @@ ul.subcategories label img{ height:20px; } +li.main_category > span:hover, +li.main_category label:hover{ + cursor:pointer; +} + #categories li#display_submited{ font-variant:normal; } @@ -546,11 +711,10 @@ p.warning{ } -#welcome_button, -#simple_button, +a#welcome_button, +a#routing_button, #permalink{ display: block; - text-align:center; margin:0.3em; padding:0.2em; width:100%; @@ -605,6 +769,40 @@ table.inline-table td input[type=file]{ margin-right: auto; } +.alert-box .ui-dialog-titlebar { + display:none; +} + +ul#multimedia_list_content{ + padding:0; + margin:0; + list-style-type:none; +} + +ul#multimedia_list_content li{ + padding:0.5em 5px 0.5em 35px; + margin:0; + display:block; + list-style-type:none; + border-bottom:1px solid; +} + +ul#multimedia_list_content li img{ + display:block; + float:right; +} + +ul#multimedia_list_content li.picture{ + background-image:url("../img/img_logo.png"); + background-position:4px center; + background-repeat:no-repeat; +} + +ul#multimedia_list_content li.multimedia{ + background-image:url("../img/film_logo.png"); + background-position:6px center; + background-repeat:no-repeat; +} #waiting{ /* Fixed position to provide the vertical offset */ position:fixed; @@ -803,6 +1001,26 @@ div.pp_default .pp_expand{ SimplePanZoom */ +#main_map.olMap{ + z-index:0; +} + +#marker_hover{ + display:none; + position:absolute; + z-index:5; + background-image: url('../img/bottom-arrow.png'); + background-repeat: no-repeat; + background-position: center bottom; +} + +#marker_hover_content{ + margin-bottom:6px; + background-color:#fff; + border:1px solid #000; + padding:0.1em 0.5em; +} + .olControlSimplePanZoom { top: 10px; right: 10px; diff --git a/chimere/static/chimere/img/bottom-arrow.png b/chimere/static/chimere/img/bottom-arrow.png Binary files differnew file mode 100644 index 0000000..7393ffe --- /dev/null +++ b/chimere/static/chimere/img/bottom-arrow.png diff --git a/chimere/static/chimere/img/close.png b/chimere/static/chimere/img/close.png Binary files differnew file mode 100644 index 0000000..f9e8d04 --- /dev/null +++ b/chimere/static/chimere/img/close.png diff --git a/chimere/static/chimere/img/empty.png b/chimere/static/chimere/img/empty.png Binary files differnew file mode 100644 index 0000000..1ad1e19 --- /dev/null +++ b/chimere/static/chimere/img/empty.png diff --git a/chimere/static/chimere/img/feed.png b/chimere/static/chimere/img/feed.png Binary files differnew file mode 100644 index 0000000..19d2246 --- /dev/null +++ b/chimere/static/chimere/img/feed.png diff --git a/chimere/static/chimere/img/film_logo.png b/chimere/static/chimere/img/film_logo.png Binary files differnew file mode 100644 index 0000000..1ccdc2e --- /dev/null +++ b/chimere/static/chimere/img/film_logo.png diff --git a/chimere/static/chimere/img/flag-finish.png b/chimere/static/chimere/img/flag-finish.png Binary files differnew file mode 100644 index 0000000..04bfa1d --- /dev/null +++ b/chimere/static/chimere/img/flag-finish.png diff --git a/chimere/static/chimere/img/flag-start.png b/chimere/static/chimere/img/flag-start.png Binary files differnew file mode 100644 index 0000000..c93f2a3 --- /dev/null +++ b/chimere/static/chimere/img/flag-start.png diff --git a/chimere/static/chimere/img/flag-step.png b/chimere/static/chimere/img/flag-step.png Binary files differnew file mode 100644 index 0000000..5556c94 --- /dev/null +++ b/chimere/static/chimere/img/flag-step.png diff --git a/chimere/static/chimere/img/images_licences b/chimere/static/chimere/img/images_licences index 0e732fc..d6d2773 100644 --- a/chimere/static/chimere/img/images_licences +++ b/chimere/static/chimere/img/images_licences @@ -1,5 +1,5 @@ -* Upload image credit +* Upload image credit (upload.png) * Farm-Fresh layer gps.png in Farm-Fresh Web Icons Author: FatCow Web Hosting @@ -16,17 +16,26 @@ Author: The Tango! Desktop Project Licence: Public domain Url: http://commons.wikimedia.org/wiki/File:Internet-web-browser.svg -* Drawing image credit +* Drawing image credit (drawing.png) * Icons from the Tango! project set. Author: The Tango! Desktop Project Licence: Public domain Url: http://commons.wikimedia.org/wiki/File:Edit-find-replace.svg -Url 2: http://commons.wikimedia.org/wiki/File:Internet-web-browser.svg + http://commons.wikimedia.org/wiki/File:Internet-web-browser.svg + https://commons.wikimedia.org/wiki/File:Document-print.svg -* Quaver image credit +* Quaver image credit (8thNote.png) * An 8th-note. Author: Sbrools Licence: Public domain Url: https://commons.wikimedia.org/wiki/File:8thNote.svg + +* Flags image credit (flag-start.png, flag-step.png, flag-finish.png) + +Author: FatCow Web Hosting +Licence: Creative Commons Attribution 3.0 United States license +Url: https://upload.wikimedia.org/wikipedia/commons/c/cb/Farm-Fresh_flag_1.png + https://upload.wikimedia.org/wikipedia/commons/8/81/Farm-Fresh_flag_blue.png + https://upload.wikimedia.org/wikipedia/commons/6/64/Farm-Fresh_flag_finish.png diff --git a/chimere/static/chimere/img/img_logo.png b/chimere/static/chimere/img/img_logo.png Binary files differnew file mode 100644 index 0000000..b487506 --- /dev/null +++ b/chimere/static/chimere/img/img_logo.png diff --git a/chimere/static/chimere/img/marker-cluster.png b/chimere/static/chimere/img/marker-cluster.png Binary files differnew file mode 100644 index 0000000..73b4146 --- /dev/null +++ b/chimere/static/chimere/img/marker-cluster.png diff --git a/chimere/static/chimere/img/printer.png b/chimere/static/chimere/img/printer.png Binary files differnew file mode 100644 index 0000000..5a5dbaf --- /dev/null +++ b/chimere/static/chimere/img/printer.png diff --git a/chimere/static/chimere/img/share-icon.png b/chimere/static/chimere/img/share-icon.png Binary files differnew file mode 100644 index 0000000..f21b76e --- /dev/null +++ b/chimere/static/chimere/img/share-icon.png diff --git a/chimere/static/chimere/img/share-icon.xcf b/chimere/static/chimere/img/share-icon.xcf Binary files differnew file mode 100644 index 0000000..d149768 --- /dev/null +++ b/chimere/static/chimere/img/share-icon.xcf diff --git a/chimere/static/chimere/js/base.js b/chimere/static/chimere/js/base.js index e76fe76..ba2ffc2 100644 --- a/chimere/static/chimere/js/base.js +++ b/chimere/static/chimere/js/base.js @@ -107,3 +107,36 @@ function zoomToCurrentExtent(map){ map.zoomToExtent(extent, true); return true; } + +/* interface */ +function share_link_update(){ + $('.share_link').click(function(){ + if (this.share_initialized){ + return false; + } + this.share_initialized = true; + var href = $(this).attr('href'); + var url = get_share_url; + var classes = $(this).attr('class').split(' '); + prefix = 'share_id_'; + var share_id; + for (idx=0;idx<classes.length;idx++){ + if(classes[idx].substring(0, prefix.length) == prefix){ + var share_id = classes[idx].substring(prefix.length); + } + } + var params = $('#permalink a').attr('href').split('/'); + url += share_id + params[params.length-1]; + $.ajax({url: url, + dataType: "html", + success: function (url) { + window.open(url); + return false; + }, + error: function(){ + return false; + } + }); + return false; + }); +} diff --git a/chimere/static/chimere/js/clustering.js b/chimere/static/chimere/js/clustering.js new file mode 100644 index 0000000..b3a142c --- /dev/null +++ b/chimere/static/chimere/js/clustering.js @@ -0,0 +1,278 @@ +/* + 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 6675dcd..104e527 100644 --- a/chimere/static/chimere/js/jquery.chimere.js +++ b/chimere/static/chimere/js/jquery.chimere.js @@ -68,6 +68,11 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { lat: null, lon: null, simple: false, + routing_start_lat: null, + routing_start_lon: null, + routing_end_lat: null, + routing_end_lon: null, + routing_steps_lonlat: null, // Provide this function to make a custom click event on the marker on_marker_click: null, // Provide this function to override the feature detail display @@ -75,24 +80,44 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { // Provide this function for overriding the getSubcategories default get_subcategories_fx: null, hide_popup_fx: null, + // if leave to false every click on the map hide the pop-up + explicit_popup_hide: false, controls:[new OpenLayers.Control.Navigation(), - new OpenLayers.Control.SimplePanZoom(), + new OpenLayers.Control.PanPanel(), + new OpenLayers.Control.ZoomPanel(), new OpenLayers.Control.ScaleLine()], + popupClass: OpenLayers.Popup.FramedCloud, + popupContentFull: false, // if true the detail is inside the popup + category_accordion: true, // category opening behave like an accordion maxResolution: 156543.0399, units: 'm', projection: new OpenLayers.Projection('EPSG:4326'), - theme:null, + theme: null, + enable_clustering: true, + routing: false, // enable routing management + routing_panel_open: function(){ + $('#chimere_itinerary_panel').dialog('open'); + }, 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_route_feature: null, // To store the current route find by routing + itinerary_step_number:0, // current step number icon_offset: new OpenLayers.Pixel(0, 0), edition: false, // edition mode edition_type_is_route: false, // route or POI edition default_icon: new OpenLayers.Icon( 'http://www.openlayers.org/dev/img/marker-green.png', new OpenLayers.Size(21, 25), - new OpenLayers.Pixel(-(21/2), -25)) + new OpenLayers.Pixel(-(21/2), -25)), + cluster_icon: null, + marker_hover_id:'marker_hover', + marker_hover_content_id:'marker_hover_content', + marker_hover_offset: null, + icon_start: null, + icon_step: null, + icon_end: null }; var settings = {}; /* @@ -104,6 +129,31 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { */ init: function ( options ) { /* Manage parameters */ + // not staticaly in default because of STATIC_URL init + if (defaults.cluster_icon == null && typeof STATIC_URL != 'undefined'){ + defaults.cluster_icon = new OpenLayers.Icon( + STATIC_URL+'chimere/img/marker-cluster.png', + new OpenLayers.Size(36, 39), + new OpenLayers.Pixel(-(36/2), -(39/2))); + } + if (defaults.icon_start == null && typeof STATIC_URL != 'undefined'){ + defaults.icon_start = new OpenLayers.Icon( + STATIC_URL + "chimere/img/flag-start.png", + new OpenLayers.Size(32, 32), + new OpenLayers.Pixel(0, -32)); + } + if (defaults.icon_step == null && typeof STATIC_URL != 'undefined'){ + defaults.icon_step = new OpenLayers.Icon( + STATIC_URL + "chimere/img/flag-step.png", + new OpenLayers.Size(32, 32), + new OpenLayers.Pixel(0, -32)); + } + if (defaults.icon_end == null && typeof STATIC_URL != 'undefined'){ + defaults.icon_end = new OpenLayers.Icon( + STATIC_URL + "chimere/img/flag-finish.png", + new OpenLayers.Size(32, 32), + new OpenLayers.Pixel(0, -32)); + } settings = $.extend({}, defaults); if ( options ) $.extend(settings, options); var map_element = $(this).get(0); @@ -120,6 +170,8 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { map_options['restrictedExtent'] = settings.restricted_extent; } + settings.current_position = null; + /* Create map object */ settings.map = map = new OpenLayers.Map(map_element, map_options); @@ -145,8 +197,29 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { // Make specific params params.checked_categories = settings.checked_categories; params.display_submited = settings.display_submited; - if(settings.current_feature){ + if(settings.current_feature) params.current_feature = settings.current_feature.pk; + if (settings.routing_start){ + lonlat = settings.routing_start.lonlat.clone().transform( + EPSG_PROJECTION, EPSG_DISPLAY_PROJECTION); + params.routing_start_lon = lonlat.lon; + params.routing_start_lat = lonlat.lat; + } + if (settings.routing_end){ + lonlat = settings.routing_end.lonlat.clone().transform( + EPSG_PROJECTION, EPSG_DISPLAY_PROJECTION); + params.routing_end_lon = lonlat.lon; + params.routing_end_lat = lonlat.lat; + } + if (settings.routing_steps){ + var steps = []; + for (var i = 0; i < settings.routing_steps.length; i++){ + lonlat = settings.routing_steps[i].lonlat.clone( + ).transform(EPSG_PROJECTION, + EPSG_DISPLAY_PROJECTION); + steps.push([lonlat.lon, lonlat.lat]); + } + params.routing_steps = steps; } return params; } @@ -171,6 +244,26 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { } settings.map.setBaseLayer( settings.map_layers[settings.selected_map_layer]); + + /* manage the context menu */ + $('#map_menu_zoomin').bind("click", methods.zoomIn); + $('#map_menu_zoomout').bind("click", methods.zoomOut); + $('#map_menu_center').bind("click", methods.mapCenter); + /* manage the routing */ + if (settings.routing){ + settings.routing_start = null; + settings.routing_steps = new Array(); + settings.routing_end = null; + $('#map_menu_from').bind("click", methods.routingFrom); + $('#map_menu_step').bind("click", methods.routingAddStep); + $('#map_menu_to').bind("click", methods.routingTo); + $('#map_menu_clear').bind("click", methods.routingClear); + settings.layerRoute = new OpenLayers.Layer.Vector("Route Layer"); + settings.map.addLayer(settings.layerRoute); + settings.layerRouteMarker = new OpenLayers.Layer.Markers( + 'Route markers'); + settings.map.addLayer(settings.layerRouteMarker); + } /* Vectors layer */ settings.layerVectors = new OpenLayers.Layer.Vector("Vector Layer"); settings.map.addLayer(settings.layerVectors); @@ -181,10 +274,94 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { settings.map.addControl(new OpenLayers.Control.ModifyFeature( settings.layerVectors, {clickout:false, toggle:false})); } + + if (settings.enable_clustering){ + var style = new OpenLayers.Style({ + graphicTitle: "${name}", + externalGraphic: "${icon}", + graphicWidth: "${width}", + graphicHeight: "${height}", + graphicXOffset: "${offsetx}", + graphicYOffset: "${offsety}", + graphicOpacity: 1, + label: "${label}", + labelYOffset: "2", + fontSize:'1.3em' + }, { + context: { + name: function(feature) { + if(feature.cluster) { + feature.attributes.width = settings.cluster_icon.size.w; + feature.attributes.height = settings.cluster_icon.size.h; + feature.attributes.offsetx = settings.cluster_icon.offset.x; + feature.attributes.offsety = settings.cluster_icon.offset.y; + } else{ + var marker = feature.attributes.marker + feature.attributes.width = marker.icon.size.w; + feature.attributes.height = marker.icon.size.h; + feature.attributes.offsetx = settings.icon_offset.x; + feature.attributes.offsety = settings.icon_offset.y; + } + return feature.attributes.name; + }, + label: function(feature) { + // clustered features count or blank if feature is not a cluster + return feature.cluster ? feature.cluster.length : ""; + }, + icon: function(feature) { + if (feature.cluster){ + return settings.cluster_icon.url; + } else { + return STATIC_URL + 'chimere/img/empty.png'; + } + }, + width: function(feature) { return feature.attributes.width; }, + height: function(feature) { return feature.attributes.height; }, + offsetx: function(feature) { return feature.attributes.offsetx; }, + offsety: function(feature) { return feature.attributes.offsety; } + }}); + + + /* Cluster layer */ + settings.clustering = new OpenLayers.Strategy.Cluster({ + distance: 10, + threshold: 2}); + settings.layerCluster = new OpenLayers.Layer.Vector("Cluster layer", + {styleMap: new OpenLayers.StyleMap({'default': style}), + strategies: [settings.clustering]}); + settings.map.addLayer(settings.layerCluster); + + var highlightCtrl = new OpenLayers.Control.SelectFeature( + settings.layerCluster, { + hover: true, + highlightOnly: true, + eventListeners: { + featurehighlighted: function(e) { + if(e.feature.attributes.marker) + e.feature.attributes.marker.events.triggerEvent('mouseover'); + }, + featureunhighlighted: function(e) { + if(e.feature.attributes.marker) + e.feature.attributes.marker.events.triggerEvent('mouseout'); + } + } + }); + + var selectCtrl = new OpenLayers.Control.SelectFeature( + settings.layerCluster,{ + onSelect: methods.zoomOnCluster + }); + + settings.map.addControl(highlightCtrl); + settings.map.addControl(selectCtrl); + + highlightCtrl.activate(); + selectCtrl.activate(); + } + /* Markers layer */ settings.layerMarkers = new OpenLayers.Layer.Markers('POIs'); settings.map.addLayer(settings.layerMarkers); - settings.layerMarkers.setOpacity(0.8); if (settings.dynamic_categories){ settings.map.events.register('moveend', settings.map, @@ -209,15 +386,16 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { } if (!settings.edition){ + if (settings.enable_clustering){ + settings.map.events.register('zoomend', null, + methods.cleanCluster); + } methods.loadCategories(); methods.loadGeoObjects(); - // Hide popUp when clicking on map - settings.map.events.register('click', settings.map, - methods.hidePopup); + methods.activateContextMenu() } else { if (!settings.edition_type_is_route){ - map.events.register('click', settings.map, - methods.setMarker); + methods.activateMarkerEdit(); } else { settings.layerVectors.events.register('featuremodified', settings.layerVectors, helpers.updateRouteForm); @@ -225,9 +403,139 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { settings.layerVectors, helpers.featureRouteCreated); } } + if (settings.routing_start_lon && settings.routing_start_lat){ + settings.current_position = new OpenLayers.LonLat( + settings.routing_start_lon, settings.routing_start_lat + ).transform(EPSG_DISPLAY_PROJECTION, EPSG_PROJECTION); + methods.routingFrom(); + } + if (settings.routing_end_lon && settings.routing_end_lat){ + settings.current_position = new OpenLayers.LonLat( + settings.routing_end_lon, settings.routing_end_lat + ).transform(EPSG_DISPLAY_PROJECTION, EPSG_PROJECTION); + methods.routingTo(); + } + if (settings.routing_steps_lonlat){ + for (var i = 0; i < settings.routing_steps_lonlat.length/2; i++) { + lon = settings.routing_steps_lonlat[i*2]; + lat = settings.routing_steps_lonlat[i*2+1]; + settings.current_position = new OpenLayers.LonLat(lon, lat + ).transform(EPSG_DISPLAY_PROJECTION, EPSG_PROJECTION); + methods.routingAddStep(); + } + } + methods.preload_images(); }, // end of init + /* Preload icons */ + preload_images: function(){ + if (typeof extra_url == 'undefined') return; + var uri = extra_url + "getAllCategories/"; + $.ajax({url: uri, + dataType: "json", + success: function (data) { + if (!data.categories){return} + for(var idx=0; idx<data.categories.length; idx++){ + new Image().src = data.categories[idx].icon.url; + if(data.categories[idx].icon_hover){ + new Image().src = + data.categories[idx].icon_hover.url; + } + } + }, + error: function (data) { + // fail silently + } + }); + }, + + activateContextMenu: function(){ + settings.edition_type_is_route = false; + settings.map.events.unregister('click', settings.map, + methods.setMarker); + settings.map.events.register('click', settings.map, + methods.displayMapMenu); + }, + + activateRouteEdit: function(){ + settings.edition_type_is_route = true; + settings.map.events.unregister('click', settings.map, + methods.setMarker); + settings.map.events.register('click', settings.map, + methods.displayMapMenu); + }, + + activateMarkerEdit: function(){ + settings.edition_type_is_route = false; + if ($('#chimere_map_menu').length){ + $('#chimere_map_menu').hide(); + } + if (settings.current_popup != null) { + settings.current_popup.hide(); + } + settings.map.events.unregister('click', settings.map, + methods.displayMapMenu); + settings.map.events.register('click', settings.map, + methods.setMarker); + }, + // change map_layer + changeMapLayer: function(map_idx){ + settings.map.setBaseLayer(settings.map_layers[map_idx]); + }, + + // init the context menu + zoomIn: function(){ + methods.mapCenter(); + settings.map.zoomIn(); + }, + + // zoom out from the map menu + zoomOut: function(){ + methods.mapCenter(); + settings.map.zoomOut(); + }, + + // center from the map menu + mapCenter: function(){ + $('#chimere_map_menu').hide(); + settings.map.setCenter(settings.current_position); + }, + + // set current position + setCurrentPosition: function(lonlat){ + settings.current_position = lonlat; + }, + zoomOnCluster: function(feature){ + if(!feature.cluster) // if not cluster + { + feature.attributes.marker.events.triggerEvent('click'); + feature.attributes.marker.events.triggerEvent('mouseover'); + feature.attributes.marker.events.triggerEvent('mouseout'); + } else { + methods.zoomIn(); + settings.map.setCenter( + feature.geometry.getBounds().getCenterLonLat()); + } + }, /* + * 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); + } + }, + /* * Load markers and route from DB */ loadGeoObjects: function () { @@ -237,30 +545,44 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { if (!ids) ids = '0'; var uri = extra_url + "getGeoObjects/" + ids; if (settings.display_submited) uri += "/A_S"; - $.ajax({url: uri, + $.ajax({url: uri, dataType: "json", success: function (data) { settings.layerMarkers.clearMarkers(); settings.layerVectors.removeAllFeatures(); + if (settings.enable_clustering){ + settings.cluster_array = []; + settings.layerCluster.removeAllFeatures(); + } for (var i = 0; i < data.features.length; i++) { var feature = data.features[i]; if (feature.geometry.type == 'Point'){ methods.addMarker(feature); } else if (feature.geometry.type == 'LineString') { methods.addRoute(feature); + } else if (feature.geometry.type == 'MultiLineString') { + methods.addMultiLine(feature); } } + if (settings.enable_clustering){ + settings.layerCluster.addFeatures( + settings.cluster_array); + methods.cleanCluster(); + } + settings.map.resetLayersZIndex(); }, - error: function (data) { + error: function (data, textStatus, errorThrown) { settings.layerMarkers.clearMarkers(); settings.layerVectors.removeAllFeatures(); + if (settings.enable_clustering){ + settings.layerCluster.removeAllFeatures(); + } }, complete: function () { if($('#waiting').length){$('#waiting').hide();} } }); }, - /* * Update the categories div in ajax */ @@ -276,9 +598,11 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { uri += "getAvailableCategories/"; var params = {"current_extent": current_extent} if (settings.display_submited) params["status"] = "A_S"; - $.ajax({url: uri, - data: params, + $.ajax({url: uri, + data: params, + cache: false, success: function (data) { + $('#categories').empty(); $('#categories').html(data); _init_categories(); _reCheckCategories(); @@ -295,7 +619,13 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { category_element.parent().find("li input").attr("checked", val); } var _toggle_categories = function (subcategory_element) { - var parent = subcategory_element.parent().parent().parent(); + var parent = subcategory_element.closest('ul'); + var parent_label = parent.parent().find("> span"); + if (parent.find('input[type=checkbox]:checked').length){ + parent_label.addClass('category-selected'); + } else { + parent_label.removeClass('category-selected'); + } var master_check = parent.find("> input"); if (parent.find('.subcategories input[type=checkbox]').length == parent.find('.subcategories input[type=checkbox]:checked').length){ @@ -303,32 +633,66 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { } else { master_check.removeAttr('checked'); } + + if($('#action-categories').length){ + if ($('#categories input[type=checkbox]:checked').length){ + $('#action-categories').addClass('category-selected'); + } else { + $('#action-categories').removeClass('category-selected'); + } + } return master_check; }; var _init_categories = function () { /* * Add event listener in categories DOM elements */ - $('#categories #ul_categories > li > input').bind("click", function () { - methods.hidePopup(); + $('#categories #ul_categories > li > input').bind("click", + function (e) { + methods.hidePopup(e); _toggle_subcategories($(this)); methods.loadGeoObjects(); settings.permalink.updateLink(); }); - $('.subcategories li input').bind("click", function () { - methods.hidePopup(); + $('.subcategories li input').bind("click", function (e) { + var c_name = $(this).attr('name'); + c_name = c_name.substr(c_name.lastIndexOf("_")+1); + if($(this).is(':checked')){ + methods.subcategory_detail(c_name); + } + var par = $(this).parent(); + if ($(this).attr('checked')){ + par.addClass('selected'); + } else { + par.removeClass('selected'); + } + methods.hidePopup(e); methods.loadGeoObjects(); _toggle_categories($(this)); settings.permalink.updateLink(); + if ($('#layer_cat_'+c_name).length){ + $('#layer_cat_'+c_name).prop("checked", + this.checked); + } }); $('#display_submited_check').bind("click", function () { methods.loadGeoObjects(); settings.permalink.updateLink(); }); // Zoom to category - $(".zoom_to_category").bind("click", function (e) {var id = this.id.substr(this.id.lastIndexOf("_")+1); helpers.zoom_to_category(id);}); - $(".zoom_to_subcategory").bind("click", function (e) {var id = this.id.substr(this.id.lastIndexOf("_")+1); helpers.zoom_to_subcategories([id]);}); - $(".toggle_category").bind("click", function (e) {var id = this.id.substr(this.id.lastIndexOf("_")+1); methods.toggle_category(id); }); + $(".zoom_to_category").bind("click", function (e) { + var id = this.id.substr(this.id.lastIndexOf("_")+1); + helpers.zoom_to_category(id); + }); + $(".zoom_to_subcategory").bind("click", function (e) { + var id = this.id.substr(this.id.lastIndexOf("_")+1); + helpers.zoom_to_subcategories([id]); + }); + $(".toggle_category").parent().bind("click", function (e) { + var item = $(this).children('.toggle_category'); + var id = item.attr('id').substr(item.attr('id').lastIndexOf("_")+1); + methods.toggle_category(id); + }); } var _reCheckCategories = function (){ /* recheck categories on init or when a redraw occurs */ @@ -351,6 +715,37 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { } }, /* + * Hide clusterized markers + */ + cleanCluster: function (){ + if (settings.map.getZoom() === 18) { + // Don't cluster at this level. No matter what. + settings.clustering.threshold = 1000; + } else { + settings.clustering.threshold = 2; + } + //settings.layerCluster.refresh({force:true}); + settings.clustering.recluster(); + var hidden_feature_idx = []; + if (settings.map.getZoom() != 18) { + for(var idx=0; idx<settings.layerCluster.features.length; idx++){ + if(settings.layerCluster.features[idx].cluster){ + for(var c=0;c < settings.layerCluster.features[idx].cluster.length; c++) { + hidden_feature_idx.push( + settings.layerCluster.features[idx].cluster[c].attributes.pk); + } + } + } + } + for(j=0; j<settings.layerMarkers.markers.length;j++){ + if(hidden_feature_idx.indexOf(settings.layerMarkers.markers[j].pk) > -1){ + settings.layerMarkers.markers[j].display(false); + } else { + settings.layerMarkers.markers[j].display(true); + } + } + }, + /* * Put a marker on the map */ addMarker: function (mark) { @@ -362,24 +757,37 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { var lon = mark.geometry.coordinates[0]; var size = new OpenLayers.Size(mark.properties.icon_width, mark.properties.icon_height); - var iconclone = new OpenLayers.Icon(MEDIA_URL + mark.properties.icon_path, - size, settings.icon_offset); + var icon_url = MEDIA_URL + mark.properties.icon_path; + var icon_hover_url = ''; + if (mark.properties.icon_hover_path){ + var icon_hover_url = MEDIA_URL + mark.properties.icon_hover_path; + } + var iconclone = new OpenLayers.Icon(icon_url, size, + settings.icon_offset); + var feature = new OpenLayers.Feature(settings.layerMarkers, - new OpenLayers.LonLat(lon, lat).transform(EPSG_DISPLAY_PROJECTION, - EPSG_PROJECTION), + new OpenLayers.LonLat(lon, lat).transform( + EPSG_DISPLAY_PROJECTION, + EPSG_PROJECTION), {icon:iconclone}); feature.pk = mark.properties.pk; - feature.popupClass = OpenLayers.Popup.FramedCloud; + feature.popupClass = settings.popupClass; feature.data.popupContentHTML = "<div class='cloud'>"; - feature.data.popupContentHTML += mark.properties.name; + if (!settings.popupContentFull) { + feature.data.popupContentHTML += mark.properties.name; + } feature.data.popupContentHTML += "</div>"; feature.data.overflow = 'hidden'; var marker = feature.createMarker(); + marker.pk = feature.pk; + marker.icon_url = icon_url; + marker.icon_hover_url = icon_hover_url; + marker.category_name = mark.properties.category_name; /* manage markers events */ var _popup = function() { /* show the popup */ if (settings.current_popup != null) { - settings.current_popup.hide(); + settings.current_popup.hide(); } if (feature.popup == null) { feature.popup = feature.createPopup(); @@ -389,42 +797,101 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { } settings.current_popup = feature.popup; /* hide on click on the cloud */ - settings.current_popup.groupDiv.onclick = methods.hidePopup; + if (!settings.explicit_popup_hide){ + settings.current_popup.groupDiv.onclick = methods.hidePopup; + } settings.permalink.updateLink(); } + var _repan_popup = function(){ + /* re-pan manually */ + + // no clean way to detect if all the element are ready + // lack of better... + setTimeout( + function(){ + settings.current_popup.panIntoView(); + }, 1000); + } + var markerClick = function (evt) { settings.current_feature = feature; + methods.setCurrentPosition(feature.lonlat); if ( settings.on_marker_click ) { settings.on_marker_click(evt, mark, settings); } else { + methods.center_on_feature(); + $('#chimere_map_menu').hide(); // Default popup if (feature.popup && feature.popup.visible()) { if (settings.current_popup == feature.popup) { feature.popup.hide(); if (!settings.simple){ - $('#panel').removeClass('panel-minified'); $('#detail').hide(); } } else { settings.current_popup.hide(); _popup(); methods.display_feature_detail(feature.pk); + _repan_popup(); } } else { _popup(); methods.display_feature_detail(feature.pk); + _repan_popup(); } } OpenLayers.Event.stop(evt); }; var markerOver = function (evt) { document.body.style.cursor='pointer'; + if (settings.current_feature && settings.current_feature.popup + && settings.current_feature.popup.visible()) return; + var marker = evt.object; + if (marker.icon_hover_url){ + marker.setUrl(marker.icon_hover_url); + } + px = settings.map.getPixelFromLonLat(marker.lonlat); + marker_hover = $('#'+settings.marker_hover_id); + marker_hover_content = $('#'+settings.marker_hover_content_id); + marker_hover_content.html(marker.category_name); + var map_position = $(settings.map.div).offset(); + + var width = marker_hover.width(); + width += parseInt(marker_hover.css("padding-left"), 10) + + parseInt(marker_hover.css("padding-right"), 10) + + parseInt(marker_hover.css("margin-left"), 10) + + parseInt(marker_hover.css("margin-right"), 10) + + parseInt(marker_hover.css("borderLeftWidth"), 10) + + parseInt(marker_hover.css("borderRightWidth"), 10); + var pos_x = px.x + map_position.left + - width/2 + 1; + if (settings.marker_hover_offset) + pos_x += settings.marker_hover_offset.x; + $('#'+settings.marker_hover_id).css('left', pos_x); + var height = marker_hover.height(); + height += parseInt(marker_hover.css("padding-top"), 10) + + parseInt(marker_hover.css("padding-bottom"), 10) + + parseInt(marker_hover.css("margin-top"), 10) + + parseInt(marker_hover.css("margin-bottom"), 10) + + parseInt(marker_hover.css("borderBottomWidth"), 10) + + parseInt(marker_hover.css("borderTopWidth"), 10); + var pos_y = px.y + map_position.top + - height - marker.icon.size.h; + if (settings.marker_hover_offset) + pos_y += settings.marker_hover_offset.y; + $('#'+settings.marker_hover_id).css('top', pos_y); + $('#'+settings.marker_hover_id).show(); OpenLayers.Event.stop(evt); }; var markerOut = function (evt) { document.body.style.cursor='auto'; + var marker = evt.object; + if (marker.icon_hover_url){ + marker.setUrl(marker.icon_url); + } + $('#'+settings.marker_hover_id).hide(); OpenLayers.Event.stop(evt); }; marker.events.register('click', feature, markerClick); @@ -433,13 +900,29 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { settings.layerMarkers.addMarker(marker); /* show the item when designed in the permalink */ if (settings.display_feature == feature.pk){ + settings.current_feature = feature; _popup(feature); methods.display_feature_detail(feature.pk); if (!settings.display_route){ settings.map.setCenter(feature.lonlat, 16); - methods.loadCategories(); + _repan_popup(); } + settings.display_feature = null; + //methods.loadCategories(); + } + + if (settings.enable_clustering){ + // manage cluster layer + var point = new OpenLayers.Geometry.Point(lon, lat).transform( + EPSG_DISPLAY_PROJECTION, + EPSG_PROJECTION); + var feat = new OpenLayers.Feature.Vector(point); + feat.attributes = { icon: MEDIA_URL + mark.properties.icon_path, + name: "", label:"", pk:mark.properties.pk, + marker:marker}; + settings.cluster_array.push(feat); } + return feature; }, @@ -459,7 +942,7 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { settings.current_feature = new OpenLayers.Feature.Vector(); var style = OpenLayers.Util.extend({}, - OpenLayers.Feature.Vector.style['default']); + OpenLayers.Feature.Vector.style['default']); style.strokeColor = route.properties.color; style.strokeWidth = 3; settings.current_feature.style = style; @@ -471,6 +954,307 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { methods.loadCategories(); } }, + /* + * Put a multiline on the map + */ + addMultiLine: function(feature) { + var gformat = new OpenLayers.Format.GeoJSON(); + var feats = gformat.read(feature); + var style = OpenLayers.Util.extend({}, + OpenLayers.Feature.Vector.style['default']); + style.strokeColor = feature.properties.color; + style.strokeWidth = 2; + feats[0].style = style; + feats[0].geometry = feats[0].geometry.transform( + EPSG_DISPLAY_PROJECTION, + settings.map.getProjectionObject()); + settings.layerVectors.addFeatures(feats); + }, + routingInputChange: function(nominatim_id){ + $('#map_menu_clear').show(); + switch(nominatim_id){ + case 'nominatim_start': + settings.routing_start = new OpenLayers.Marker( + new OpenLayers.LonLat( + $('#'+nominatim_id+'_lon').val(), + $('#'+nominatim_id+'_lat').val() + ).transform(EPSG_DISPLAY_PROJECTION, + settings.map.getProjectionObject()), + settings.icon_start); + settings.layerRouteMarker.addMarker(settings.routing_start); + break; + case 'nominatim_end': + settings.routing_end = new OpenLayers.Marker( + new OpenLayers.LonLat( + $('#'+nominatim_id+'_lon').val(), + $('#'+nominatim_id+'_lat').val() + ).transform(EPSG_DISPLAY_PROJECTION, + settings.map.getProjectionObject()), + settings.icon_end); + settings.layerRouteMarker.addMarker(settings.routing_end); + break; + default: + settings.routing_steps.push(new OpenLayers.Marker( + new OpenLayers.LonLat( + $('#'+nominatim_id+'_lon').val(), + $('#'+nominatim_id+'_lat').val() + ).transform(EPSG_DISPLAY_PROJECTION, + settings.map.getProjectionObject()), + settings.icon_step.clone())); + settings.layerRouteMarker.addMarker( + settings.routing_steps[settings.routing_steps.length-1]); + break; + } + if (settings.routing_end && settings.routing_start + && $('#search_routing').length) { + $('#search_routing').button('enable'); + } + }, + + redrawRoutingIcons: function(){ + settings.layerRouteMarker.clearMarkers(); + settings.layerRouteMarker.addMarker(settings.routing_start); + settings.layerRouteMarker.addMarker(settings.routing_end); + for (var k=0;k<settings.routing_steps.length;k++){ + settings.layerRouteMarker.addMarker(settings.routing_steps[k]); + } + }, + + // set the start point for routing + routingFrom: function(){ + $('#chimere_map_menu').hide(); + settings.routing_panel_open(); + $('#map_menu_clear').show(); + settings.routing_start = new OpenLayers.Marker( + settings.current_position.clone(), + settings.icon_start); + settings.layerRouteMarker.addMarker(settings.routing_start); + if (nominatim_url){ + helpers.updateNominatimName(settings.current_position.clone() + .transform(settings.map.getProjectionObject(), + EPSG_DISPLAY_PROJECTION), + 'start_label'); + } + if (settings.routing_end) methods.route(); + }, + // add a step point for routing + routingAddStep: function(){ + $('#chimere_map_menu').hide(); + settings.routing_panel_open(); + $('#map_menu_clear').show(); + settings.routing_steps.push(new OpenLayers.Marker( + settings.current_position.clone(), + settings.icon_step.clone())); + settings.layerRouteMarker.addMarker( + settings.routing_steps[settings.routing_steps.length-1]); + + if (nominatim_url){ + var current_itinerary_number = methods.add_step_fx(); + helpers.updateNominatimName(settings.current_position.clone() + .transform(settings.map.getProjectionObject(), + EPSG_DISPLAY_PROJECTION), + 'step_'+current_itinerary_number+'_label'); + } + if (settings.routing_end && settings.routing_start) methods.route(); + }, + + // add a step on the interface + add_step_fx: function (){ + settings.itinerary_step_number += 1; + var cloned = $("#id_start_div").clone(); + var c_id = 'step_' + settings.itinerary_step_number; + cloned.attr('id', 'id_'+c_id+'_div'); + cloned.children('label').html(step_label).addClass('step_label'); + cloned.children("#nominatim_start_label").attr('id', c_id+'_label' + ).html(''); + cloned.children('label.nominatim-label').attr('for', "" + ).removeClass('step_label'); + var id_suffixes = ['_lat', '_lon', '']; + for (idx=0;idx < id_suffixes.length;idx+=1){ + var suffix = id_suffixes[idx]; + val = c_id + suffix; + cloned.children("#nominatim_start"+suffix).attr('id', val + ).attr('name', val); + } + if (settings.itinerary_step_number == 1){ + $("#nominatim_end_label").after(cloned); + } else { + $("#step_"+(settings.itinerary_step_number-1)+"_label" + ).after(cloned); + } + $('#' + c_id).val(default_nominatim_lbl); + $('#' + c_id).click(function(){ + $('#'+c_id).val(''); + }); + $(".nominatim-widget").autocomplete(nominatim_widget_options); + return settings.itinerary_step_number; + }, + + // set the finish point for routing + routingTo: function(){ + $('#chimere_map_menu').hide(); + settings.routing_panel_open(); + $('#map_menu_clear').show(); + settings.routing_end = new OpenLayers.Marker( + settings.current_position.clone(), + settings.icon_end); + settings.layerRouteMarker.addMarker(settings.routing_end); + if (nominatim_url){ + helpers.updateNominatimName(settings.current_position.clone() + .transform(settings.map.getProjectionObject(), + EPSG_DISPLAY_PROJECTION), + 'end_label'); + } + if (settings.routing_start) methods.route(); + }, + + // clear the current itinerary + routingClear: function(){ + $('#nominatim_start_lon').val(''); + $('#nominatim_start_lat').val(''); + $('#nominatim_start_label').html(''); + $('#chimere_start_label').html(''); + $('#nominatim_end_lon').val(''); + $('#nominatim_end_lat').val(''); + $('#nominatim_end_label').html(''); + $('#chimere_end_label').html(''); + $('.nominatim-widget').val(default_nominatim_lbl); + $('#chimere_map_menu').hide(); + $('#map_menu_clear').hide(); + $('#chimere_itinerary').hide(); + $('#chimere_itinerary_form').show(); + $('div[id^="id_step_"]').remove(); + if($('#search_routing').length) $('#search_routing').button('disable'); + settings.layerRoute.removeAllFeatures(); + settings.layerRouteMarker.clearMarkers(); + settings.routing_start = null; + settings.routing_end = null; + settings.routing_steps = new Array(); + settings.current_itinerary_number = 0; + settings.current_route_feature = null; + settings.permalink.updateLink(); + }, + // display a route + route: function(){ + if($('#search_routing').length) $('#search_routing').button('enable'); + if (!settings.routing_start || !settings.routing_end){ + return; + } + var steps = [settings.routing_start.lonlat.clone()] + for (var i = 0; i < settings.routing_steps.length; i++) { + steps.push(settings.routing_steps[i].lonlat.clone()); + } + steps.push(settings.routing_end.lonlat.clone()); + // create the appropriate URL + var uri = extra_url + "route/" + var transport = $('input[name=transport]:checked').val(); + if(transport){ + uri += transport + "/" + } + var speed = $('#id_speed option:selected').val(); + if(!speed){ + var speed = $('input[name=speed]:checked').val(); + } + if(speed){ + uri += speed.split('_')[1] + "/" + } + for (var i = 0; i < steps.length; i++) { + var step = steps[i].transform( + settings.map.getProjectionObject(), + EPSG_DISPLAY_PROJECTION); + if (i > 0){ + uri += '_'; + } + uri += step.lon + '_' + step.lat; + } + settings.permalink.updateLink(); + $.ajax({url: uri, + dataType: "json", + success: function (data) { + settings.layerRoute.removeAllFeatures(); + methods.redrawRoutingIcons(); + methods.hideMessage(); + if (!data.features.length){ + methods.displayMessage(routing_fail_message); + return; + } + for (var i = 0; i < data.features.length; i++) { + var feat = data.features[i]; + if(feat.type == 'LineString'){ + settings.current_route_feature = + methods.putRoute(feat); + } else { + var lonlat = new OpenLayers.LonLat( + feat.geometry.coordinates[0], + feat.geometry.coordinates[1]); + lonlat.transform(EPSG_DISPLAY_PROJECTION, + settings.map.getProjectionObject()); + var icon_height = feat.properties.icon_height; + var icon_width = feat.properties.icon_width; + var marker = new OpenLayers.Marker(lonlat, + new OpenLayers.Icon( + feat.properties.icon_path, + new OpenLayers.Size(icon_width, + icon_height), + new OpenLayers.Pixel( + -(icon_width/2), + -icon_height)) + ); + settings.layerRouteMarker.addMarker(marker); + } + } + if (data.message) methods.displayMessage(data.message); + settings.map.zoomToExtent( + settings.layerRoute.getDataExtent()); + settings.map.zoomOut(); + $('#id_transport_it').find('span' + ).removeClass('selected'); + $('#id_transport_it_'+data.properties.transport + ).addClass('selected'); + $('#chimere_total_label').html( + data.properties.total); + $('#chimere_itinerary_content').html( + data.properties.description); + $('#chimere_itinerary').show(); + if(!settings.edition_type_is_route){ + $('#chimere_itinerary_form').hide(); + settings.routing_panel_open(); + } else { + methods.updateRoutingInput(); + } + }, + error: function (jqXHR, textStatus, errorThrown) { + methods.redrawRoutingIcons(); + methods.hideMessage(); + console.log(errorThrown); + console.log(textStatus); + settings.layerRoute.removeAllFeatures(); + methods.displayMessage(routing_fail_message); + } + }); + + }, + /* + Put a route on the map + */ + putRoute: function(polyline) { + var point_array = new Array(); + for (i=0; i<polyline.coordinates.length; i++){ + var point = new OpenLayers.Geometry.Point(polyline.coordinates[i][0], + polyline.coordinates[i][1]); + point_array.push(point); + } + var linestring = new OpenLayers.Geometry.LineString(point_array); + linestring.transform(EPSG_DISPLAY_PROJECTION, settings.map.getProjectionObject()); + current_route = new OpenLayers.Feature.Vector(); + var style = OpenLayers.Util.extend({}, + OpenLayers.Feature.Vector.style['default']); + style.strokeWidth = 3; + current_route.style = style; + current_route.geometry = linestring; + settings.layerRoute.addFeatures([current_route]); + return current_route; + }, display_feature_detail: function (pk) { /* * update current detail panel with an AJAX request @@ -480,25 +1264,34 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { uri += "getDetail/" + pk; var params = {} if (settings.simple) { params["simple"] = 1; } - $.ajax({url: uri, - data: params, + $.ajax({url: uri, + data: params, + dataType: "html", success: function (data) { - if ( settings.display_feature_detail_fx ) { - // Custom function ? - settings.display_feature_detail_fx(data, settings); + if ( settings.display_feature_detail_fx ) { + // Custom function ? + settings.display_feature_detail_fx(data, settings); + } + else { + if (!settings.popupContentFull) { + $('#detail').html(data).show(); } else { - if (!settings.simple) { - $('#panel').addClass('panel-minified'); - $('#detail').html(data).show(); - } - else { - settings.current_popup.setContentHTML("<div class='cloud'>" + data + "</div>"); - } + settings.current_popup.setContentHTML("<div class='cloud'>" + data + "</div>"); } } + } }); }, + displayMessage: function(message){ + if (!$('#chimere_message').length) return; + $('#chimere_message').html(message); + $('#chimere_message').dialog('open'); + }, + hideMessage: function(message){ + if (!$('#chimere_message').length) return; + $('#chimere_message').dialog('close'); + }, center_on_feature: function(feature) { var f = get_or_set(feature, settings.current_feature); if (f) @@ -520,28 +1313,64 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { var uri = extra_url + "getDescriptionDetail/" + category_id; $.ajax({url:uri, success: function (data) { - $("#category_detail").html(data).dialog(); - $("#category_detail").dialog( "option", "title", + $("#category_description").html(data).dialog(); + $("#category_description").dialog( "option", "title", $("#category_title").html()); } }); }, + /* + * Load the subcategory description if available + */ + subcategory_detail: function(category_id){ + var uri = extra_url + "getCategory/" + category_id; + + $.ajax({url: uri, + dataType: "json", + success: function (data) { + if (!data.description){return} + $('#category_description').html(data.description); + $("#category_description").dialog("option", "title", + data.name); + $('#category_description').dialog('open'); + }, + error: function (data) { + // fail silently + } + }); + }, toggle_category: function (id) { // TODO make this id DOM element customisable // Check if element is currently visible or not var was_visible = $("#maincategory_" + id).is(":visible"); // Close all categories - $("#categories ul.subcategories").hide(); + var category_plus = STATIC_URL + "chimere/img/plus.png"; + var category_minus = STATIC_URL + "chimere/img/minus.png"; + if (settings.category_accordion){ + $("#categories ul.subcategories").hide(); + $("#categories img.toggle_category").attr("src", category_plus); + $("#categories .main_category").addClass("toggle_plus"); + $("#categories .main_category").removeClass("toggle_minus"); + } // Put a minus image - $("#categories img.toggle_category").attr("src", STATIC_URL + "chimere/img/plus.png"); if (!was_visible) { // Show the subcategories $("#maincategory_" + id).toggle(); + $("#maincategory_" + id).parent().addClass("toggle_minus"); + $("#maincategory_" + id).parent().removeClass("toggle_plus"); // Put a plus image - $("#maincategory_img_" + id).attr("src", STATIC_URL + "chimere/img/minus.png"); + $("#maincategory_img_" + id).attr("src", category_minus); settings.current_category = id; } + if (!settings.category_accordion && was_visible) + { + $("#maincategory_" + id).toggle(); + $("#maincategory_" + id).parent().addClass("toggle_plus"); + $("#maincategory_" + id).parent().removeClass("toggle_minus"); + // Put a minus image + $("#maincategory_img_" + id).attr("src", category_plus); + } }, zoomToCurrentExtent: function(){ /* zoom to current extent */ @@ -573,17 +1402,13 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { }, /* put the marker on the map and update latitude and longitude fields */ putEditMarker: function (lonlat, zoom){ - if (settings.current_feature) { - settings.layerMarkers.removeMarker(settings.current_feature); + if (settings.current_edit_feature) { + settings.layerMarkers.removeMarker(settings.current_edit_feature); } - settings.current_feature = new OpenLayers.Marker(lonlat.clone(), + settings.current_edit_feature = new OpenLayers.Marker(lonlat.clone(), settings.default_icon); - settings.layerMarkers.addMarker(settings.current_feature); - lonlat = lonlat.clone().transform(settings.map.getProjectionObject(), - EPSG_DISPLAY_PROJECTION); - $('#id_point').val('POINT(' + lonlat.lon + ' ' + lonlat.lat + ')'); - $('#live_latitude').val(lonlat.lat); - $('#live_longitude').val(lonlat.lon); + settings.layerMarkers.addMarker(settings.current_edit_feature); + methods.updateMarkerInput(); /* zoom to the point */ if (zoom){ var bounds = settings.layerMarkers.getDataExtent(); @@ -591,6 +1416,28 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { } return; }, + updateMarkerInput: function(){ + if (!settings.current_edit_feature) { + return; + } + lonlat = settings.current_edit_feature.lonlat.clone().transform( + settings.map.getProjectionObject(), + EPSG_DISPLAY_PROJECTION); + $('#id_point').val('POINT(' + lonlat.lon + ' ' + lonlat.lat + ')'); + if($('#live_latitude').length){ + $('#live_latitude').val(lonlat.lat); + $('#live_longitude').val(lonlat.lon); + } + + }, + updateRoutingInput: function(){ + if (!settings.current_route_feature) { + return; + } + var current_geo = settings.current_route_feature.geometry.clone(); + current_geo.transform(EPSG_PROJECTION, EPSG_DISPLAY_PROJECTION); + jQuery('#id_route').val(current_geo); + }, activateCurrentControl: function(){ if (settings.current_control){ settings.current_control.activate(); @@ -646,19 +1493,25 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { if (bounds) settings.map.zoomToExtent(bounds); }, hidePopup: function (evt) { + $('#'+settings.marker_hover_id).hide(); if (settings.hide_popup_fx) { settings.hide_popup_fx(evt, settings) } else { // Default behaviour if (settings.current_popup) { - settings.current_popup.hide(); if (!settings.simple){ - $('#panel').removeClass('panel-minified'); $('#detail').hide(); } + if (settings.current_popup.visible()){ + settings.current_popup.hide(); + if(evt) + settings.map.events.triggerEvent('click', evt); + return true; + } } } + return false; }, saveExtent: function(){ var extent_key = 'MAP_EXTENT'; @@ -794,8 +1647,23 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { if (vertices){ jQuery('#id_point').val(vertices); } + }, + updateNominatimName:function(lonlat, response_id){ + $.ajax({ + url: nominatim_url.substring(0, nominatim_url.length-6) + 'reverse', + data: { + format: "json", + lat:lonlat.lat, + lon:lonlat.lon + }, + dataType:'json', + success: function (vals) { + $('#'+response_id).html(vals.display_name); + $('#nominatim_'+response_id).html(vals.display_name); + $('#chimere_'+response_id).html(vals.display_name); + } + }); } - }; // End of helpers $.fn.chimere = function (thing) { @@ -822,7 +1690,6 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, { else { $.error( 'Method ' + thing + ' does not exist on jQuery.chimere' ); } - return this; }; })( jQuery ); diff --git a/chimere/static/chimere/js/nominatim-widget.js b/chimere/static/chimere/js/nominatim-widget.js new file mode 100644 index 0000000..99f7034 --- /dev/null +++ b/chimere/static/chimere/js/nominatim-widget.js @@ -0,0 +1,46 @@ +var default_nominatim_lbl = ''; +var nominatim_widget_options = { + source: function (request, response) { + $.ajax({ + url: nominatim_url, + data: { + format: "json", + q: request.term, + }, + dataType:'json', + success: function ( data ) { + response ( $.map(data, function(item) { + return { + label: item.display_name, + value: item.display_name, + lat: item.lat, + lon: item.lon + } + })); + + } + }) + }, + minLength: 6, + delay: 1000, + select: function ( event, ui ) { + $('#'+$(this).attr('id')+'_lat').val(ui.item.lat); + $('#'+$(this).attr('id')+'_lon').val(ui.item.lon); + $('#'+$(this).attr('id')+'_label').html(ui.item.label); + $('#chimere_'+$(this).attr('id').substring(10)+'_label').html( + ui.item.label); + $('#'+$(this).attr('id')).val(default_nominatim_lbl); + jQuery("#map").chimere("routingInputChange", $(this).attr('id')); + return false; + }, + open: function() { + $( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" ); + }, + close: function() { + $( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" ); + } +} + +$(function(){ + $(".nominatim-widget").autocomplete(nominatim_widget_options); +}); diff --git a/chimere/static/chimere/js/routing-widget.js b/chimere/static/chimere/js/routing-widget.js new file mode 100644 index 0000000..34ca46c --- /dev/null +++ b/chimere/static/chimere/js/routing-widget.js @@ -0,0 +1,47 @@ +var step_label = "Step"; +var add_step = null; + +$(document).ready(function() { + var itinerary_step_number = 0; + $("#add_step_link").click(function(){ + $('#main-map').chimere('add_step_fx'); + return false; + }); + $('#search_routing').button({'disabled':true}); + $('#routing_button').click(function(){ + $('#chimere_itinerary_panel').dialog('open'); + }); + $('#chimere_itinerary_modify').click(function(){ + $('#chimere_itinerary').hide(); + $('#chimere_itinerary_form').show(); + }); + $('#chimere_itinerary_new').click(function(){ + $('#map').chimere('routingClear'); + }); + $('#search_routing').click(function(){ + $('#map').chimere('route'); + }); + + var detached_speeds = Array(); + function filter_speed(transport){ + $("#id_speed_div").show(); + for (i=0;i<detached_speeds.length;i+=1){ + $("#id_speed_div ul").append(detached_speeds[i]); + } + detached_speeds = Array(); + $("#id_speed_div input[type=radio]").each(function(){ + if(!$(this).val().match(transport) && $(this).val()){ + detached_speeds.push($(this).parent().parent().detach()); + } + }); + $('#id_speed_div').val(''); + if($("#id_speed_div input[type=radio]").length == 1){ + $("#id_speed_div").hide(); + } + } + $('#id_transport label').click(function(){ + checked_item = $("#"+$(this).attr('for')); + filter_speed(checked_item.val()); + }); + filter_speed($('#id_transport :checked').val()); +}); diff --git a/chimere/static/chimere/js/utils.js b/chimere/static/chimere/js/utils.js index 80ab91a..460e843 100644 --- a/chimere/static/chimere/js/utils.js +++ b/chimere/static/chimere/js/utils.js @@ -236,6 +236,12 @@ function has_index(index, arr) { function get_or_set(v, d){ return typeof v === "undefined" ? d : v;} +/* email validity */ +function isValidEmailAddress(emailAddress) { + var pattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i); + return pattern.test(emailAddress); +}; + /* remove multiple, leading or trailing spaces */ function trim(s) { s = s.replace(/(^\s*)|(\s*$)/gi,""); |
