From 1655690bc81c79de72150b54f91097022fbc652f Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 24 Apr 2012 14:19:03 +0100 Subject: [PATCH 1/5] [view/map][xs] Fix lat/lon parsing (eg geoms in Greenwich can have lon 0) --- src/view-map.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/view-map.js b/src/view-map.js index 430c89d9..8b63fe15 100644 --- a/src/view-map.js +++ b/src/view-map.js @@ -356,7 +356,7 @@ my.Map = Backbone.View.extend({ // 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: [lon,lat] From 6749e38b07b7b2aa8a037989e10d84fadb3acd69 Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 24 Apr 2012 18:34:36 +0100 Subject: [PATCH 2/5] [view/map,tests] Add tests for the Map view --- test/index.html | 1 + test/view-map.test.js | 129 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 test/view-map.test.js diff --git a/test/index.html b/test/index.html index 8bc78f41..bb721fdd 100644 --- a/test/index.html +++ b/test/index.html @@ -42,6 +42,7 @@ + diff --git a/test/view-map.test.js b/test/view-map.test.js new file mode 100644 index 00000000..430eda86 --- /dev/null +++ b/test/view-map.test.js @@ -0,0 +1,129 @@ +(function ($) { + +module("View - Map"); + +var GeoJSONFixture = { + getDataset: function() { + var fields = [ + {id: 'id'}, + {id: 'x'}, + {id: 'y'}, + {id: 'z'}, + {id: 'geom'} + ]; + var documents = [ + {id: 0, x: 1, y: 2, z: 3, geom: '{"type":"Point","coordinates":[13.40,52.35]}'}, + {id: 1, x: 2, y: 4, z: 6, geom: {type:"Point",coordinates:[13.40,52.35]}}, + {id: 2, x: 3, y: 6, z: 9, geom: {type:"LineString",coordinates:[[100.0, 0.0],[101.0, 1.0]]}} + ]; + var dataset = recline.Backend.createDataset(documents, fields); + return dataset; + } +}; + +test('basics', function () { + var dataset = Fixture.getDataset(); + var view = new recline.View.Map({ + model: dataset + }); + $('.fixtures').append(view.el); + + //Fire query, otherwise the map won't be initialized + dataset.query(); + + assertPresent('.editor',view.el); + + // Check that the Leaflet map was set up + assertPresent('.leaflet-container',view.el); + + ok(view.map instanceof L.Map); + ok(view.features instanceof L.GeoJSON); + + view.remove(); +}); + +test('Lat/Lon geom fields', function () { + var dataset = Fixture.getDataset(); + var view = new recline.View.Map({ + model: dataset + }); + $('.fixtures').append(view.el); + + //Fire query, otherwise the map won't be initialized + dataset.query(); + + // Check that all markers were created + equal(_getFeaturesCount(view.features),6); + + // Delete a document + view.model.currentDocuments.remove(view.model.currentDocuments.get('1')); + equal(_getFeaturesCount(view.features),5); + + // Add a new one + view.model.currentDocuments.add({id: 7, x: 7, y: 14, z: 21, country: 'KX', label: 'seventh', lat:13.23, lon:23.56}), + equal(_getFeaturesCount(view.features),6); + + view.remove(); +}); + +test('GeoJSON geom field', function () { + var dataset = GeoJSONFixture.getDataset(); + var view = new recline.View.Map({ + model: dataset + }); + $('.fixtures').append(view.el); + + //Fire query, otherwise the map won't be initialized + dataset.query(); + + // Check that all features were created + equal(_getFeaturesCount(view.features),3); + + // Delete a document + view.model.currentDocuments.remove(view.model.currentDocuments.get('2')); + equal(_getFeaturesCount(view.features),2); + + // Add it back + view.model.currentDocuments.add({id: 2, x: 3, y: 6, z: 9, geom: {type:"LineString",coordinates:[[100.0, 0.0],[101.0, 1.0]]}}), + equal(_getFeaturesCount(view.features),3); + + view.remove(); +}); + +test('Popup', function () { + var dataset = GeoJSONFixture.getDataset(); + var view = new recline.View.Map({ + model: dataset + }); + $('.fixtures').append(view.el); + + //Fire query, otherwise the map won't be initialized + dataset.query(); + + var marker = view.el.find('.leaflet-marker-icon').first(); + + assertPresent(marker); + + _.values(view.features._layers)[0].fire('click'); + + var popup = view.el.find('.leaflet-popup-content'); + + assertPresent(popup); + + var text = popup.text(); + _.each(view.model.fields.toJSON(),function(field){ + ok((text.indexOf(field.id) !== -1)) + }); + + view.remove(); +}); + +var _getFeaturesCount = function(features){ + var cnt = 0; + features._iterateLayers(function(layer){ + cnt++; + }); + return cnt; +} + +})(this.jQuery); From 3597974469fd8ce1de8e05fda9dde39b458e2584 Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 24 Apr 2012 18:42:52 +0100 Subject: [PATCH 3/5] [view/map] Don't show GeoJSON geometries in the popup as they can be quite big --- src/view-map.js | 4 +++- test/view-map.test.js | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/view-map.js b/src/view-map.js index 8b63fe15..3a86a468 100644 --- a/src/view-map.js +++ b/src/view-map.js @@ -293,7 +293,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}; diff --git a/test/view-map.test.js b/test/view-map.test.js index 430eda86..aa07f9a8 100644 --- a/test/view-map.test.js +++ b/test/view-map.test.js @@ -111,8 +111,11 @@ test('Popup', function () { assertPresent(popup); var text = popup.text(); + ok((text.indexOf('geom') === -1)) _.each(view.model.fields.toJSON(),function(field){ - ok((text.indexOf(field.id) !== -1)) + if (field.id != 'geom'){ + ok((text.indexOf(field.id) !== -1)) + } }); view.remove(); From 653eda6f438be550f2841d83f8cd362fcc9e8681 Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 24 Apr 2012 18:53:19 +0100 Subject: [PATCH 4/5] [view/map][xs] Small fix in the getBounds method (does not work for multi-geometries) --- src/view-map.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/view-map.js b/src/view-map.js index 3a86a468..65cfed0f 100644 --- a/src/view-map.js +++ b/src/view-map.js @@ -448,8 +448,10 @@ my.Map = Backbone.View.extend({ if (layer instanceof L.Marker){ bounds.extend(layer.getLatLng()); } else { - bounds.extend(layer.getBounds().getNorthEast()); - bounds.extend(layer.getBounds().getSouthWest()); + if (layer.getBounds){ + bounds.extend(layer.getBounds().getNorthEast()); + bounds.extend(layer.getBounds().getSouthWest()); + } } }, this); return (typeof bounds.getNorthEast() !== 'undefined') ? bounds : null; From a516fc1deb0ce0a5261ed61f20ad641298a47ca1 Mon Sep 17 00:00:00 2001 From: amercader Date: Tue, 24 Apr 2012 19:06:51 +0100 Subject: [PATCH 5/5] [view/map][s] Listen to changes in the documents and update the map accordingly --- src/view-map.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/view-map.js b/src/view-map.js index 65cfed0f..e6537614 100644 --- a/src/view-map.js +++ b/src/view-map.js @@ -117,6 +117,10 @@ 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')});