From 4f675cb6aa232622355c0d679e5b0a3f99e7a0c7 Mon Sep 17 00:00:00 2001 From: amercader Date: Wed, 25 Apr 2012 12:50:58 +0100 Subject: [PATCH] [build] Build library --- recline.js | 107 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 87 insertions(+), 20 deletions(-) diff --git a/recline.js b/recline.js index 391296aa..c1f91852 100644 --- a/recline.js +++ b/recline.js @@ -1404,7 +1404,7 @@ this.recline.View = this.recline.View || {}; // //
 //   {
-//     // geomField if specified will be used in preference to lat/lon 
+//     // geomField if specified will be used in preference to lat/lon
 //     geomField: {id of field containing geometry in the dataset}
 //     lonField: {id of field containing longitude in the dataset}
 //     latField: {id of field containing latitude in the dataset}
@@ -1462,6 +1462,11 @@ my.Map = Backbone.View.extend({
       
\ \
\ +
\ + \ +
\ \ \ \ @@ -1479,7 +1484,8 @@ my.Map = Backbone.View.extend({ // Define here events for UI elements events: { 'click .editor-update-map': 'onEditorSubmit', - 'change .editor-field-type': 'onFieldTypeChange' + 'change .editor-field-type': 'onFieldTypeChange', + 'change #editor-auto-zoom': 'onAutoZoomChange' }, initialize: function(options) { @@ -1498,15 +1504,27 @@ my.Map = Backbone.View.extend({ // Listen to changes in the documents this.model.currentDocuments.bind('add', function(doc){self.redraw('add',doc)}); + this.model.currentDocuments.bind('change', function(doc){ + self.redraw('remove',doc); + self.redraw('add',doc); + }); this.model.currentDocuments.bind('remove', function(doc){self.redraw('remove',doc)}); this.model.currentDocuments.bind('reset', function(){self.redraw('reset')}); - // If the div was hidden, Leaflet needs to recalculate some sizes - // to display properly this.bind('view:show',function(){ - if (self.map) { - self.map.invalidateSize(); + // If the div was hidden, Leaflet needs to recalculate some sizes + // to display properly + if (self.map){ + self.map.invalidateSize(); + if (self._zoomPending && self.autoZoom) { + self._zoomToFeatures(); + self._zoomPending = false; } + } + self.visible = true; + }); + this.bind('view:hide',function(){ + self.visible = false; }); var stateData = _.extend({ @@ -1518,6 +1536,7 @@ my.Map = Backbone.View.extend({ ); this.state = new recline.Model.ObjectState(stateData); + this.autoZoom = true; this.mapReady = false; this.render(); }, @@ -1583,6 +1602,13 @@ my.Map = Backbone.View.extend({ this.features.clearLayers(); this._add(this.model.currentDocuments.models); } + if (action != 'reset' && this.autoZoom){ + if (this.visible){ + this._zoomToFeatures(); + } else { + this._zoomPending = true; + } + } } }, @@ -1629,6 +1655,10 @@ my.Map = Backbone.View.extend({ } }, + onAutoZoomChange: function(e){ + this.autoZoom = !this.autoZoom; + }, + // Private: Add one or n features to the map // // For each document passed, a GeoJSON geometry will be extracted and added @@ -1656,7 +1686,9 @@ my.Map = Backbone.View.extend({ // TODO: mustache? html = '' for (key in doc.attributes){ - html += '
' + key + ': '+ doc.attributes[key] + '
' + if (!(self.state.get('geomField') && key == self.state.get('geomField'))){ + html += '
' + key + ': '+ doc.attributes[key] + '
'; + } } feature.properties = {popupContent: html}; @@ -1707,19 +1739,22 @@ my.Map = Backbone.View.extend({ _getGeometryFromDocument: function(doc){ if (this.geomReady){ if (this.state.get('geomField')){ - // We assume that the contents of the field are a valid GeoJSON object - return doc.attributes[this.state.get('geomField')]; + var value = doc.get(this.state.get('geomField')); + if (typeof(value) === 'string'){ + // We have a GeoJSON string representation + return $.parseJSON(value); + } else { + // We assume that the contents of the field are a valid GeoJSON object + return value; + } } else if (this.state.get('lonField') && this.state.get('latField')){ // We'll create a GeoJSON like point object from the two lat/lon fields var lon = doc.get(this.state.get('lonField')); var lat = doc.get(this.state.get('latField')); - if (lon && lat) { + if (!isNaN(parseFloat(lon)) && !isNaN(parseFloat(lat))) { return { type: 'Point', - coordinates: [ - doc.attributes[this.state.get('lonField')], - doc.attributes[this.state.get('latField')] - ] + coordinates: [lon,lat] }; } } @@ -1761,6 +1796,18 @@ my.Map = Backbone.View.extend({ return null; }, + // Private: Zoom to map to current features extent if any, or to the full + // extent if none. + // + _zoomToFeatures: function(){ + var bounds = this.features.getBounds(); + if (bounds){ + this.map.fitBounds(bounds); + } else { + this.map.setView(new L.LatLng(0, 0), 2); + } + }, + // Private: Sets up the Leaflet map control and the features layer. // // The map uses a base layer from [MapQuest](http://www.mapquest.com) based @@ -1785,6 +1832,24 @@ my.Map = Backbone.View.extend({ } }); + + // This will be available in the next Leaflet stable release. + // In the meantime we add it manually to our layer. + this.features.getBounds = function(){ + var bounds = new L.LatLngBounds(); + this._iterateLayers(function (layer) { + if (layer instanceof L.Marker){ + bounds.extend(layer.getLatLng()); + } else { + if (layer.getBounds){ + bounds.extend(layer.getBounds().getNorthEast()); + bounds.extend(layer.getBounds().getSouthWest()); + } + } + }, this); + return (typeof bounds.getNorthEast() !== 'undefined') ? bounds : null; + } + this.map.addLayer(this.features); this.map.setView(new L.LatLng(0, 0), 2); @@ -3404,7 +3469,9 @@ this.recline.Backend = this.recline.Backend || {}; var options = options || {}; var trm = options.trim; var separator = options.separator || ','; - + var delimiter = options.delimiter || '"'; + + var cur = '', // The character we are currently processing. inQuote = false, fieldQuoted = false, @@ -3451,8 +3518,8 @@ this.recline.Backend = this.recline.Backend || {}; field = ''; fieldQuoted = false; } else { - // If it's not a ", add it to the field buffer - if (cur !== '"') { + // If it's not a delimiter, add it to the field buffer + if (cur !== delimiter) { field += cur; } else { if (!inQuote) { @@ -3460,9 +3527,9 @@ this.recline.Backend = this.recline.Backend || {}; inQuote = true; fieldQuoted = true; } else { - // Next char is ", this is an escaped " - if (s.charAt(i + 1) === '"') { - field += '"'; + // Next char is delimiter, this is an escaped delimiter + if (s.charAt(i + 1) === delimiter) { + field += delimiter; // Skip the next char i += 1; } else {