cluster markers to handle larger datasets
This commit is contained in:
@@ -53,12 +53,22 @@ my.Map = Backbone.View.extend({
|
|||||||
geomField: null,
|
geomField: null,
|
||||||
lonField: null,
|
lonField: null,
|
||||||
latField: null,
|
latField: null,
|
||||||
autoZoom: true
|
autoZoom: true,
|
||||||
|
cluster: true
|
||||||
},
|
},
|
||||||
options.state
|
options.state
|
||||||
);
|
);
|
||||||
this.state = new recline.Model.ObjectState(stateData);
|
this.state = new recline.Model.ObjectState(stateData);
|
||||||
|
|
||||||
|
this._clusterOptions = {
|
||||||
|
zoomToBoundsOnClick: true,
|
||||||
|
//disableClusteringAtZoom: 10,
|
||||||
|
maxClusterRadius: 80,
|
||||||
|
singleMarkerMode: false,
|
||||||
|
skipDuplicateAddTesting: true,
|
||||||
|
animateAddingMarkers: false
|
||||||
|
};
|
||||||
|
|
||||||
// Listen to changes in the fields
|
// Listen to changes in the fields
|
||||||
this.model.fields.bind('change', function() {
|
this.model.fields.bind('change', function() {
|
||||||
self._setupGeometryField();
|
self._setupGeometryField();
|
||||||
@@ -146,8 +156,11 @@ my.Map = Backbone.View.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this._geomReady() && this.mapReady){
|
if (this._geomReady() && this.mapReady){
|
||||||
if (action == 'reset' || action == 'refresh'){
|
if (action == 'refresh' || action == 'reset') {
|
||||||
this.features.clearLayers();
|
this.features.clearLayers();
|
||||||
|
// recreate cluster group because of issues with clearLayer
|
||||||
|
this.map.removeLayer(this.markers);
|
||||||
|
this.markers = new L.MarkerClusterGroup(this._clusterOptions);
|
||||||
this._add(this.model.records.models);
|
this._add(this.model.records.models);
|
||||||
} else if (action == 'add' && doc){
|
} else if (action == 'add' && doc){
|
||||||
this._add(doc);
|
this._add(doc);
|
||||||
@@ -161,6 +174,13 @@ my.Map = Backbone.View.extend({
|
|||||||
this._zoomPending = true;
|
this._zoomPending = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.map.removeLayer(this.features);
|
||||||
|
this.map.removeLayer(this.markers);
|
||||||
|
if (this.state.get('cluster')) {
|
||||||
|
this.map.addLayer(this.markers);
|
||||||
|
} else {
|
||||||
|
this.map.addLayer(this.features);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -198,6 +218,9 @@ my.Map = Backbone.View.extend({
|
|||||||
|
|
||||||
if (!(docs instanceof Array)) docs = [docs];
|
if (!(docs instanceof Array)) docs = [docs];
|
||||||
|
|
||||||
|
// removing ad re-adding the layer enables faster bulk loading
|
||||||
|
self.map.removeLayer(self.markers);
|
||||||
|
|
||||||
var count = 0;
|
var count = 0;
|
||||||
var wrongSoFar = 0;
|
var wrongSoFar = 0;
|
||||||
_.every(docs, function(doc){
|
_.every(docs, function(doc){
|
||||||
@@ -236,9 +259,11 @@ my.Map = Backbone.View.extend({
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.map.addLayer(self.markers);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Private: Remove one or n features to the map
|
// Private: Remove one or n features from the map
|
||||||
//
|
//
|
||||||
_remove: function(docs){
|
_remove: function(docs){
|
||||||
|
|
||||||
@@ -347,7 +372,7 @@ my.Map = Backbone.View.extend({
|
|||||||
//
|
//
|
||||||
_zoomToFeatures: function(){
|
_zoomToFeatures: function(){
|
||||||
var bounds = this.features.getBounds();
|
var bounds = this.features.getBounds();
|
||||||
if (bounds.getNorthEast()){
|
if (bounds && bounds.getNorthEast() && bounds.getSouthWest()){
|
||||||
this.map.fitBounds(bounds);
|
this.map.fitBounds(bounds);
|
||||||
} else {
|
} else {
|
||||||
this.map.setView([0, 0], 2);
|
this.map.setView([0, 0], 2);
|
||||||
@@ -360,15 +385,27 @@ my.Map = Backbone.View.extend({
|
|||||||
// on [OpenStreetMap](http://openstreetmap.org).
|
// on [OpenStreetMap](http://openstreetmap.org).
|
||||||
//
|
//
|
||||||
_setupMap: function(){
|
_setupMap: function(){
|
||||||
|
var self = this;
|
||||||
this.map = new L.Map(this.$map.get(0));
|
this.map = new L.Map(this.$map.get(0));
|
||||||
|
|
||||||
var mapUrl = "http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png";
|
var mapUrl = "http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png";
|
||||||
var osmAttribution = 'Map data © 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 osmAttribution = 'Map data © 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'});
|
var bg = new L.TileLayer(mapUrl, {maxZoom: 18, attribution: osmAttribution ,subdomains: '1234'}).addTo(this.map);
|
||||||
this.map.addLayer(bg);
|
|
||||||
|
|
||||||
this.features = new L.GeoJSON();
|
this.markers = new L.MarkerClusterGroup(this._clusterOptions);
|
||||||
this.map.addLayer(this.features);
|
|
||||||
|
m = this.map;
|
||||||
|
l = this.markers;
|
||||||
|
|
||||||
|
this.features = new L.GeoJSON(null,{
|
||||||
|
pointToLayer: function (feature, latlng) {
|
||||||
|
var marker = new L.marker(latlng);
|
||||||
|
self.markers.addLayer(marker);
|
||||||
|
return marker;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//this.map.addLayer(this.features);
|
||||||
|
//this.map.addLayer(this.markers);
|
||||||
|
|
||||||
this.map.setView([0, 0], 2);
|
this.map.setView([0, 0], 2);
|
||||||
|
|
||||||
@@ -441,19 +478,23 @@ my.MapMenu = Backbone.View.extend({
|
|||||||
</div> \
|
</div> \
|
||||||
<div class="editor-options" > \
|
<div class="editor-options" > \
|
||||||
<label class="checkbox"> \
|
<label class="checkbox"> \
|
||||||
<input type="checkbox" id="editor-auto-zoom" checked="checked" /> \
|
<input type="checkbox" id="editor-auto-zoom" value="autozoom" checked="checked" /> \
|
||||||
Auto zoom to features</label> \
|
Auto zoom to features</label> \
|
||||||
|
<label class="checkbox"> \
|
||||||
|
<input type="checkbox" id="editor-cluster" value="cluster" checked="checked" /> \
|
||||||
|
Cluster markers</label> \
|
||||||
</div> \
|
</div> \
|
||||||
<input type="hidden" class="editor-id" value="map-1" /> \
|
<input type="hidden" class="editor-id" value="map-1" /> \
|
||||||
</div> \
|
</div> \
|
||||||
</form> \
|
</form> \
|
||||||
',
|
',
|
||||||
|
|
||||||
// Define here events for UI elements
|
// Define here events for UI elements
|
||||||
events: {
|
events: {
|
||||||
'click .editor-update-map': 'onEditorSubmit',
|
'click .editor-update-map': 'onEditorSubmit',
|
||||||
'change .editor-field-type': 'onFieldTypeChange',
|
'change .editor-field-type': 'onFieldTypeChange',
|
||||||
'click #editor-auto-zoom': 'onAutoZoomChange'
|
'click #editor-auto-zoom': 'onAutoZoomChange',
|
||||||
|
'click #editor-cluster': 'onClusteringChange'
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function(options) {
|
initialize: function(options) {
|
||||||
@@ -486,10 +527,14 @@ my.MapMenu = Backbone.View.extend({
|
|||||||
}
|
}
|
||||||
if (this.state.get('autoZoom')) {
|
if (this.state.get('autoZoom')) {
|
||||||
this.el.find('#editor-auto-zoom').attr('checked', 'checked');
|
this.el.find('#editor-auto-zoom').attr('checked', 'checked');
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
this.el.find('#editor-auto-zoom').removeAttr('checked');
|
this.el.find('#editor-auto-zoom').removeAttr('checked');
|
||||||
}
|
}
|
||||||
|
if (this.state.get('cluster')) {
|
||||||
|
this.el.find('#editor-cluster').attr('checked', 'checked');
|
||||||
|
} else {
|
||||||
|
this.el.find('#editor-cluster').removeAttr('checked');
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -540,6 +585,10 @@ my.MapMenu = Backbone.View.extend({
|
|||||||
this.state.set({autoZoom: !this.state.get('autoZoom')});
|
this.state.set({autoZoom: !this.state.get('autoZoom')});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onClusteringChange: function(e){
|
||||||
|
this.state.set({cluster: !this.state.get('cluster')});
|
||||||
|
},
|
||||||
|
|
||||||
// Private: Helper function to select an option from a select list
|
// Private: Helper function to select an option from a select list
|
||||||
//
|
//
|
||||||
_selectOption: function(id,value){
|
_selectOption: function(id,value){
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
<script type="text/javascript" src="../vendor/mustache/0.5.0-dev/mustache.js"></script>
|
<script type="text/javascript" src="../vendor/mustache/0.5.0-dev/mustache.js"></script>
|
||||||
<script type="text/javascript" src="../vendor/bootstrap/2.0.2/bootstrap.js"></script>
|
<script type="text/javascript" src="../vendor/bootstrap/2.0.2/bootstrap.js"></script>
|
||||||
<script type="text/javascript" src="../vendor/leaflet/0.4.4/leaflet-src.js"></script>
|
<script type="text/javascript" src="../vendor/leaflet/0.4.4/leaflet-src.js"></script>
|
||||||
|
<script type="text/javascript" src="../vendor/leaflet.markercluster/leaflet.markercluster.js"></script>
|
||||||
<script type="text/javascript" src="../vendor/slickgrid/2.0.1/jquery-ui-1.8.16.custom.min.js"></script>
|
<script type="text/javascript" src="../vendor/slickgrid/2.0.1/jquery-ui-1.8.16.custom.min.js"></script>
|
||||||
<script type="text/javascript" src="../vendor/slickgrid/2.0.1/jquery.event.drag-2.0.min.js"></script>
|
<script type="text/javascript" src="../vendor/slickgrid/2.0.1/jquery.event.drag-2.0.min.js"></script>
|
||||||
<script type="text/javascript" src="../vendor/slickgrid/2.0.1/slick.grid.min.js"></script>
|
<script type="text/javascript" src="../vendor/slickgrid/2.0.1/slick.grid.min.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user