[#64,view/map] Add source docs and links from home page

This commit is contained in:
amercader
2012-04-11 17:33:17 +01:00
parent a8018c4e18
commit 9080fb8c6b
15 changed files with 3023 additions and 428 deletions

View File

@@ -5,27 +5,29 @@ this.recline.View = this.recline.View || {};
(function($, my) {
// ## Map view for a Dataset using Leaflet mapping library.
//
// This view allows to plot gereferenced documents on a map. The location
// information can be provided either via a field with
// [GeoJSON](http://geojson.org) objects or two fields with latitude and
// longitude coordinates.
//
// Initialization arguments:
//
// * options: initial options. They must contain a model:
//
// {
// model: {recline.Model.Dataset}
// }
//
// * config: (optional) map configuration hash (not yet used)
//
//
my.Map = Backbone.View.extend({
tagName: 'div',
className: 'data-map-container',
latitudeFieldNames: ['lat','latitude'],
longitudeFieldNames: ['lon','longitude'],
geometryFieldNames: ['geom','the_geom','geometry','spatial','location'],
//TODO: In case we want to change the default markers
/*
markerOptions: {
radius: 5,
color: 'grey',
fillColor: 'orange',
weight: 2,
opacity: 1,
fillOpacity: 1
},
*/
template: ' \
<div class="editor"> \
<form class="form-stacked"> \
@@ -81,6 +83,13 @@ my.Map = Backbone.View.extend({
</div> \
',
// These are the default field names that will be used if found.
// If not found, the user will need to define the fields via the editor.
latitudeFieldNames: ['lat','latitude'],
longitudeFieldNames: ['lon','longitude'],
geometryFieldNames: ['geom','the_geom','geometry','spatial','location'],
// Define here events for UI elements
events: {
'click .editor-update-map': 'onEditorSubmit',
'change .editor-field-type': 'onFieldTypeChange'
@@ -91,6 +100,8 @@ my.Map = Backbone.View.extend({
var self = this;
this.el = $(this.el);
// Listen to changes in the fields
this.model.bind('change', function() {
self._setupGeometryField();
});
@@ -99,11 +110,13 @@ my.Map = Backbone.View.extend({
self._setupGeometryField()
self.render()
});
// Listen to changes in the documents
this.model.currentDocuments.bind('add', function(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 is hidden, Leaflet needs to recalculate some sizes
// If the div was hidden, Leaflet needs to recalculate some sizes
// to display properly
this.bind('view:show',function(){
self.map.invalidateSize();
@@ -114,6 +127,9 @@ my.Map = Backbone.View.extend({
this.render();
},
// Public: Adds the necessary elements to the page.
//
// Also sets up the editor fields and the map if necessary.
render: function() {
var self = this;
@@ -123,7 +139,6 @@ my.Map = Backbone.View.extend({
$(this.el).html(htmls);
this.$map = this.el.find('.panel.map');
// Setup editor fields
if (this.geomReady && this.model.fields.length){
if (this._geomFieldName){
this._selectOption('editor-geom-field',this._geomFieldName);
@@ -149,6 +164,15 @@ my.Map = Backbone.View.extend({
return this;
},
// Public: Redraws the features on the map according to the action provided
//
// Actions can be:
//
// * reset: Clear all features
// * add: Add one or n features (documents)
// * remove: Remove one or n features (documents)
// * refresh: Clear existing features and add all current documents
//
redraw: function(action,doc){
var self = this;
@@ -157,24 +181,27 @@ my.Map = Backbone.View.extend({
if (this.geomReady && this.mapReady){
if (action == 'reset'){
// Clear all features
this.features.clearLayers();
} else if (action == 'add' && doc){
// Add one or n features
this._add(doc);
} else if (action == 'remove' && doc){
// Remove one or n features
this._remove(doc);
} else if (action == 'refresh'){
// Clear and rebuild all features
this.features.clearLayers();
this._add(this.model.currentDocuments.models);
}
}
},
/* UI Event handlers */
//
// UI Event handlers
//
// Public: Update map with user options
//
// Right now the only configurable option is what field(s) contains the
// location information.
//
onEditorSubmit: function(e){
e.preventDefault();
if ($('#editor-field-type-geom').attr('checked')){
@@ -191,6 +218,9 @@ my.Map = Backbone.View.extend({
return false;
},
// Public: Shows the relevant select lists depending on the location field
// type selected.
//
onFieldTypeChange: function(e){
if (e.target.value == 'geom'){
$('.editor-field-type-geom').show();
@@ -201,6 +231,14 @@ my.Map = Backbone.View.extend({
}
},
// Private: Add one or n features to the map
//
// For each document passed, a GeoJSON geometry will be extracted and added
// to the features layer. If an exception is thrown, the process will be
// stopped and an error notification shown.
//
// Each feature will have a popup associated with all the document fields.
//
_add: function(doc){
var self = this;
@@ -237,6 +275,8 @@ my.Map = Backbone.View.extend({
});
},
// Private: Remove one or n features to the map
//
_remove: function(doc){
var self = this;
@@ -253,6 +293,8 @@ my.Map = Backbone.View.extend({
},
// Private: Return a GeoJSON geomtry extracted from the document fields
//
_getGeometryFromDocument: function(doc){
if (this.geomReady){
if (this._geomFieldName){
@@ -272,11 +314,13 @@ my.Map = Backbone.View.extend({
}
},
// Private: Check if there is a field with GeoJSON geometries or alternatively,
// two fields with lat/lon values.
//
// If not found, the user can define them via the UI form.
_setupGeometryField: function(){
var geomField, latField, lonField;
// Check if there is a field with GeoJSON geometries or alternatively,
// two fields with lat/lon values
this._geomFieldName = this._checkField(this.geometryFieldNames);
this._latFieldName = this._checkField(this.latitudeFieldNames);
this._lonFieldName = this._checkField(this.longitudeFieldNames);
@@ -284,6 +328,10 @@ my.Map = Backbone.View.extend({
this.geomReady = (this._geomFieldName || (this._latFieldName && this._lonFieldName));
},
// Private: Check if a field in the current model exists in the provided
// list of names.
//
//
_checkField: function(fieldNames){
var field;
var modelFieldNames = this.model.fields.pluck('id');
@@ -296,17 +344,20 @@ my.Map = Backbone.View.extend({
return null;
},
// Private: Sets up the Leaflet map control and the features layer.
//
// The map uses a base layer from [MapQuest](http://www.mapquest.com) based
// on [OpenStreetMap](http://openstreetmap.org).
//
_setupMap: function(){
this.map = new L.Map(this.$map.get(0));
// MapQuest OpenStreetMap base map
var mapUrl = "http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png";
var osmAttribution = 'Map data &copy; 2011 OpenStreetMap contributors, Tiles Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png">';
var bg = new L.TileLayer(mapUrl, {maxZoom: 18, attribution: osmAttribution ,subdomains: '1234'});
this.map.addLayer(bg);
// Layer to hold the features
this.features = new L.GeoJSON();
this.features.on('featureparse', function (e) {
if (e.properties && e.properties.popupContent){
@@ -324,6 +375,8 @@ my.Map = Backbone.View.extend({
this.mapReady = true;
},
// Private: Helper function to select an option from a select list
//
_selectOption: function(id,value){
var options = $('.' + id + ' > select > option');
if (options){