Skip to content

Commit

Permalink
adds query nearby ability
Browse files Browse the repository at this point in the history
  • Loading branch information
mejackreed committed Aug 10, 2017
1 parent 055aed1 commit d1c9855
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 29 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ Option | Type | Default | Description
`solrRequestHandler` | `String` | `'select'` | Request handler for Solr
`colors` | `Array` | `['#f1eef6', '#d7b5d8', '#df65b0', '#dd1c77', '#980043']` | Colors for heatmap. Array can be of any length.
`maxSampleSize` | `Number` | `Number.MAX_SAFE_INTEGER` | For improved performance, run Jenks classification on only a sample of Solr counts. Default value turns off sampling. Typical value is 400.
`queryAdapter` | 'String' | `default` | A query adapter used to connect to a Solr interface. Useful for querying applications that may proxy through Solr.
`queryAdapter` | `String` | `default` | A query adapter used to connect to a Solr interface. Useful for querying applications that may proxy through Solr.
`queryRadius` | `Number` | 40 | Radius (in pixels) used for querying nearby data

### Events

Expand Down
22 changes: 22 additions & 0 deletions example/example.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var map = L.map('map').setView([0, 0], 1);


var layer = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="http://cartodb.com/attributions">CartoDB</a>'
}).addTo(map);
Expand All @@ -9,6 +10,7 @@ function onEachFeature(feature, layer) {
layer.bindPopup(count);
}


// Create and add a solrHeatmap layer to the map
var solr = L.solrHeatmap('http://127.0.0.1:8983/solr/default-core', {
// Solr field with geospatial data (should be type Spatial Recursive Prefix Tree)
Expand All @@ -28,3 +30,23 @@ solr.on('dataAdded', function(data) {
$('#numDocs').html('Number of docs: ' + docsCount.toLocaleString());
$('#renderTime').html('Render time: ' + solr.renderTime + ' ms');
});


// An example of requestNearby in use with Leaflet click handlers
map.on('click', function (e) {
solr.requestNearby(e.layerPoint);
});
solr.on('click', function (e) {
solr.requestNearby(e.layerPoint);
});

solr.on('nearbyQueried', function(data) {
var rect = L.rectangle(data.bounds);
$('#pointQuery').html('Query returned: ' + data.response.numFound + ' results')
rect.on('add', function() {
setTimeout(function() {
rect.removeFrom(map);
}, 500)
})
rect.addTo(map);
});
1 change: 1 addition & 0 deletions example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<div id='responseTime'></div>
<div id='numDocs'></div>
<div id='renderTime'></div>
<div id='pointQuery'></div>
<script src='../leafletSolrHeatmap.js'></script>
<script src='example.js'></script>
</body>
Expand Down
83 changes: 61 additions & 22 deletions leafletSolrHeatmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ L.SolrHeatmapBaseQueryAdapter = L.Class.extend({
this.layer = layer;
L.setOptions(this, options);
},
ajaxOptions: function() {
/*
* @param bounds optional param for a spatial query
*/
ajaxOptions: function(bounds) {
throw('Not implemented');
},
responseFormatter: function() {
Expand All @@ -20,7 +23,7 @@ L.SolrHeatmapBaseQueryAdapter = L.Class.extend({
*/
L.SolrHeatmapQueryAdapters = {
default: L.SolrHeatmapBaseQueryAdapter.extend({
ajaxOptions: function() {
ajaxOptions: function(bounds) {
return {
url: this._solrQuery(),
dataType: 'JSONP',
Expand All @@ -29,8 +32,8 @@ L.SolrHeatmapQueryAdapters = {
wt: 'json',
facet: true,
'facet.heatmap': this.options.field,
'facet.heatmap.geom': this.layer._mapViewToWkt(),
fq: this.options.field + this.layer._mapViewToEnvelope()
'facet.heatmap.geom': this.layer._mapViewToWkt(bounds),
fq: this.options.field + this.layer._mapViewToEnvelope(bounds)
},
jsonp: 'json.wrf'
};
Expand All @@ -44,12 +47,12 @@ L.SolrHeatmapQueryAdapters = {
}
}),
blacklight: L.SolrHeatmapBaseQueryAdapter.extend({
ajaxOptions: function() {
ajaxOptions: function(bounds) {
return {
url: this.layer._solrUrl,
dataType: 'JSON',
data: {
bbox: this._mapViewToBbox(),
bbox: this._mapViewToBbox(bounds),
format: 'json',
},
jsonp: false
Expand All @@ -59,12 +62,13 @@ L.SolrHeatmapQueryAdapters = {
this.layer.count = data.response.pages.total_count;
return data.response.facet_heatmaps;
},
_mapViewToBbox: function () {
_mapViewToBbox: function (bounds) {
if (this.layer._map === undefined) {
return '-180,-90,180,90';
}

var bounds = this.layer._map.getBounds();
if (bounds === undefined) {
bounds = this._map.getBounds();
}
var wrappedSw = bounds.getSouthWest().wrap();
var wrappedNe = bounds.getNorthEast().wrap();
return [wrappedSw.lng, bounds.getSouth(), wrappedNe.lng, bounds.getNorth()].join(',');
Expand All @@ -81,7 +85,8 @@ L.SolrHeatmap = L.GeoJSON.extend({
type: 'geojsonGrid',
colors: ['#f1eef6', '#d7b5d8', '#df65b0', '#dd1c77', '#980043'],
maxSampleSize: Number.MAX_SAFE_INTEGER, // for Jenks classification
queryAdapter: 'default'
queryAdapter: 'default',
queryRadius: 40, // In pixels, used for nearby query
},

initialize: function(url, options) {
Expand All @@ -90,19 +95,49 @@ L.SolrHeatmap = L.GeoJSON.extend({
_this.queryAdapter = new L.SolrHeatmapQueryAdapters[this.options.queryAdapter](this.options, _this);
_this._solrUrl = url;
_this._layers = {};
_this._getData();
},

onAdd: function (map) {
var _this = this;
// Call the parent function
L.GeoJSON.prototype.onAdd.call(_this, map);
L.GeoJSON.prototype.onAdd.call(this, map);

map.on('moveend', function () {
console.log('moveend')
_this._clearLayers();
_this._getData();
});
map.on('moveend', this._resetLayer, this);
},

onRemove: function(map) {
// Call the parent function
L.GeoJSON.prototype.onRemove.call(this, map);
map.off('moveend', this._resetLayer, this);
},

beforeAdd: function() {
this._getData();
},

_resetLayer: function() {
this._clearLayers();
this._getData();
},

_queryNearby: function(bounds) {
var _this = this;
var startTime = Date.now();
var options = _this.queryAdapter.ajaxOptions(bounds);
options.success = function(data) {
_this.nearbyResponseTime = Date.now() - startTime;
data.bounds = bounds;
_this.fireEvent('nearbyQueried', data);
}
$.ajax(options);
},

requestNearby: function(layerPoint) {
var dist = this.options.queryRadius;
var bounds = L.latLngBounds(
this._map.layerPointToLatLng([layerPoint.x + dist, layerPoint.y + dist]),
this._map.layerPointToLatLng([layerPoint.x - dist, layerPoint.y - dist])
);
this._queryNearby(bounds);
},

_computeHeatmapObject: function(data) {
Expand Down Expand Up @@ -381,21 +416,25 @@ L.SolrHeatmap = L.GeoJSON.extend({
$.ajax(options);
},

_mapViewToEnvelope: function() {
_mapViewToEnvelope: function(bounds) {
if (this._map === undefined) {
return ':"Intersects(ENVELOPE(-180, 180, 90, -90))"';
}
var bounds = this._map.getBounds();
if (bounds === undefined) {
bounds = this._map.getBounds();
}
var wrappedSw = bounds.getSouthWest().wrap();
var wrappedNe = bounds.getNorthEast().wrap();
return ':"Intersects(ENVELOPE(' + wrappedSw.lng + ', ' + wrappedNe.lng + ', ' + bounds.getNorth() + ', ' + bounds.getSouth() + '))"';
},

_mapViewToWkt: function() {
_mapViewToWkt: function(bounds) {
if (this._map === undefined) {
return '["-180 -90" TO "180 90"]';
}
var bounds = this._map.getBounds();
if (bounds === undefined) {
bounds = this._map.getBounds();
}
var wrappedSw = bounds.getSouthWest().wrap();
var wrappedNe = bounds.getNorthEast().wrap();
return '["' + wrappedSw.lng + ' ' + bounds.getSouth() + '" TO "' + wrappedNe.lng + ' ' + bounds.getNorth() + '"]';
Expand Down
14 changes: 8 additions & 6 deletions test/leafletSolrHeatmap_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,18 @@ describe('L.SolrHeatmap', function() {
});

describe('adds a SolrHeatmap layer', function() {
var solrLayer = L.solrHeatmap('http://127.0.0.1:8983/solr/default-core', {
field: 'geo_srpt',
type: 'geojsonGrid'
});
var solrLayer;

it('with heatmap polygons on map', function(done) {
map.addLayer(solrLayer);
solrLayer = L.solrHeatmap('http://127.0.0.1:8983/solr/default-core', {
field: 'geo_srpt',
type: 'geojsonGrid'
})//.addTo(map);
solrLayer.on('dataAdded', function() {
expect(Object.keys(solrLayer._layers).length).toBe(52);
done();
})
});
map.addLayer(solrLayer);
});
});
});
Expand Down

0 comments on commit d1c9855

Please sign in to comment.