blacklight_heatmaps 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +13 -0
- data/README.md +56 -0
- data/Rakefile +13 -0
- data/app/assets/javascripts/blacklight_heatmaps/blacklight_heatmaps.js +10 -0
- data/app/assets/javascripts/blacklight_heatmaps/default.js +6 -0
- data/app/assets/javascripts/blacklight_heatmaps/viewers/index.js +89 -0
- data/app/assets/javascripts/blacklight_heatmaps/viewers/show.js +34 -0
- data/app/assets/stylesheets/blacklight_heatmaps/default.scss +14 -0
- data/app/controllers/blacklight_heatmaps/application_controller.rb +5 -0
- data/app/helpers/blacklight/maps_helper.rb +59 -0
- data/app/models/concerns/blacklight_heatmaps/bounding_box.rb +50 -0
- data/app/models/concerns/blacklight_heatmaps/exceptions.rb +10 -0
- data/app/models/concerns/blacklight_heatmaps/geometry_parser.rb +21 -0
- data/app/models/concerns/blacklight_heatmaps/geometry_solr_document.rb +11 -0
- data/app/models/concerns/blacklight_heatmaps/point.rb +31 -0
- data/app/models/concerns/blacklight_heatmaps/solr_facet_heatmap_behavior.rb +53 -0
- data/app/views/catalog/_document_heatmaps.html.erb +5 -0
- data/app/views/catalog/_show_leaflet_map_default.html.erb +5 -0
- data/app/views/catalog/index.json.jbuilder +10 -0
- data/app/views/layouts/blacklight_heatmaps/application.html.erb +14 -0
- data/config/routes.rb +2 -0
- data/lib/blacklight_heatmaps.rb +7 -0
- data/lib/blacklight_heatmaps/engine.rb +8 -0
- data/lib/blacklight_heatmaps/version.rb +3 -0
- data/lib/generators/blacklight_heatmaps/install_generator.rb +41 -0
- data/lib/generators/blacklight_heatmaps/templates/blacklight_heatmaps.js +1 -0
- data/lib/generators/blacklight_heatmaps/templates/blacklight_heatmaps.scss +3 -0
- data/lib/tasks/blacklight_heatmaps_tasks.rake +25 -0
- data/spec/features/index_page_map_spec.rb +15 -0
- data/spec/features/show_page_map_spec.rb +15 -0
- data/spec/helpers/blacklight/maps_helper_spec.rb +38 -0
- data/spec/models/concerns/blacklight_heatmaps/bounding_box_spec.rb +31 -0
- data/spec/models/concerns/blacklight_heatmaps/geometry_parser_spec.rb +24 -0
- data/spec/models/concerns/blacklight_heatmaps/geometry_solr_document_spec.rb +34 -0
- data/spec/models/concerns/blacklight_heatmaps/point_spec.rb +18 -0
- data/spec/models/concerns/blacklight_heatmaps/solr_facet_heatmap_behavior_spec.rb +67 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +27 -0
- data/spec/views/catalog/_document_heatmaps.html.erb_spec.rb +19 -0
- data/spec/views/catalog/_show_leaflet_map_default.html.erb_spec.rb +32 -0
- metadata +242 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: eb7c89ff10e6644af8ec6c7ac604b50f7b6e9322
|
4
|
+
data.tar.gz: a9b83bde4dcce36145deb45db7f3a523ae994010
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 63b31f0cb11727db4067c3e0cdb4047b54e0b6126a9f2b32a398f228bfffdc63b0aba90efdb4f4956b57c8df55dd8abd1db912b232b1fbb5119d5566eb63763e
|
7
|
+
data.tar.gz: 1b11f4e59a9166fe570f7e93d3f2b1b7c2199b5a95093be250a1d5214506474766e58226937a26b5a324013ea7ee436dee97a171aeb75325fccc724287243596
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2016 The Board of Trustees of the Leland Stanford Junior University
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# BlacklightHeatmaps
|
2
|
+
[](https://travis-ci.org/sul-dlss/blacklight_heatmaps) | [](https://coveralls.io/github/sul-dlss/blacklight_heatmaps?branch=master)
|
3
|
+
|
4
|
+

|
5
|
+
|
6
|
+
## Features
|
7
|
+
- Configurable heatmaps of result sets
|
8
|
+
- Works with center points and bounding box data
|
9
|
+
- Show page map view
|
10
|
+
- Changeout the basemap to any tile layer
|
11
|
+
- _Really_ fast with large data sets
|
12
|
+
- Utilizes Solr's [facet heatmap](https://issues.apache.org/jira/browse/SOLR-7005) feature to provide snappy results. Tested with an index > 10,000,000 records.
|
13
|
+
- Customizable result view template
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'blacklight_heatmaps'
|
21
|
+
```
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
|
25
|
+
```sh
|
26
|
+
bundle install
|
27
|
+
```
|
28
|
+
|
29
|
+
Run the BlacklightMaps installer:
|
30
|
+
|
31
|
+
```sh
|
32
|
+
rails generate blacklight_heatmaps:install
|
33
|
+
```
|
34
|
+
|
35
|
+
## Getting started
|
36
|
+
|
37
|
+
BlacklightHeatmaps expects your data to be indexed as a [Spatial Recursive Prefix Tree](https://cwiki.apache.org/confluence/display/solr/Spatial+Search#SpatialSearch-RPT) type. The plugin currently supports data indexed in formats:
|
38
|
+
|
39
|
+
- `x y` Syntax. example: "-121.631609 36.688128"
|
40
|
+
- CQL ENVELOPE Syntax (`minX, maxX, maxY, minY`). example: "ENVELOPE(122.934585571, 153.987060547, 45.522888184, 20.422889709)"
|
41
|
+
|
42
|
+
Additional formats could be added by extending `BlacklightHeatmaps::GeometryParser`
|
43
|
+
|
44
|
+
## Development
|
45
|
+
|
46
|
+
Run Solr and Blacklight (with BlacklightMaps) for interactive development:
|
47
|
+
|
48
|
+
```sh
|
49
|
+
bundle exec rake blacklight_heatmaps:server
|
50
|
+
```
|
51
|
+
|
52
|
+
Run the test suite
|
53
|
+
|
54
|
+
```sh
|
55
|
+
bundle exec rake ci
|
56
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
Bundler::GemHelper.install_tasks
|
8
|
+
|
9
|
+
load 'tasks/blacklight_heatmaps.rake'
|
10
|
+
|
11
|
+
require 'engine_cart/rake_task'
|
12
|
+
|
13
|
+
task default: :spec
|
@@ -0,0 +1,89 @@
|
|
1
|
+
Blacklight.onLoad(function () {
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
$('[data-index-map]').each(function () {
|
5
|
+
BlacklightHeatmaps.indexView(this, {});
|
6
|
+
});
|
7
|
+
});
|
8
|
+
|
9
|
+
!(function (global) {
|
10
|
+
'use strict';
|
11
|
+
|
12
|
+
var IndexView = L.Class.extend({
|
13
|
+
options: {},
|
14
|
+
|
15
|
+
initialize: function (el, options) {
|
16
|
+
var _this = this;
|
17
|
+
var $el = $(el);
|
18
|
+
var requestUrl = $el.data().searchUrl + '&format=json';
|
19
|
+
var geometryField = $el.data().geometryField;
|
20
|
+
var template = $el.data().sidebarTemplate;
|
21
|
+
var colorRamp = $el.data().colorRamp;
|
22
|
+
|
23
|
+
var map = L.map($el[0].id).setView([0, 0], 1);
|
24
|
+
var basemap = L.tileLayer($el.data().basemap, {
|
25
|
+
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="http://cartodb.com/attributions">CartoDB</a>',
|
26
|
+
}).addTo(map);
|
27
|
+
|
28
|
+
var solrLayer = L.solrHeatmap(requestUrl, {
|
29
|
+
field: geometryField,
|
30
|
+
maxSampleSize: 50,
|
31
|
+
colors: colorRamp,
|
32
|
+
}).addTo(map);
|
33
|
+
|
34
|
+
var sidebar = L.control.sidebar('index-map-sidebar', {
|
35
|
+
position: 'right',
|
36
|
+
});
|
37
|
+
|
38
|
+
map.addControl(sidebar);
|
39
|
+
|
40
|
+
solrLayer.on('click', function (e) {
|
41
|
+
if (!sidebar.isVisible()) {
|
42
|
+
map.setView(e.latlng);
|
43
|
+
} else {
|
44
|
+
var point = map.project(e.latlng);
|
45
|
+
var offset = sidebar.getOffset();
|
46
|
+
var newPoint = L.point(point.x - (offset / 2), point.y);
|
47
|
+
map.setView(map.unproject(newPoint));
|
48
|
+
}
|
49
|
+
|
50
|
+
sidebar.show();
|
51
|
+
});
|
52
|
+
|
53
|
+
solrLayer.on('dataAdded', function (e) {
|
54
|
+
if (e.response && e.response.docs) {
|
55
|
+
var html = '';
|
56
|
+
$.each(e.response.docs, function (i, value) {
|
57
|
+
html += L.Util.template(template, value);
|
58
|
+
});
|
59
|
+
|
60
|
+
sidebar.setContent(html);
|
61
|
+
|
62
|
+
var docCount = e.response.pages.total_count;
|
63
|
+
$('#sortAndPerPage .page_links').html(
|
64
|
+
parseInt(docCount).toLocaleString() + ' ' +
|
65
|
+
_this.pluralize(docCount, 'item') + ' found'
|
66
|
+
);
|
67
|
+
}
|
68
|
+
});
|
69
|
+
|
70
|
+
$(document).on('turbolinks:click', function (e) {
|
71
|
+
e.preventDefault();
|
72
|
+
});
|
73
|
+
},
|
74
|
+
|
75
|
+
pluralize: function (count, word) {
|
76
|
+
switch (count) {
|
77
|
+
case 1:
|
78
|
+
return word;
|
79
|
+
default:
|
80
|
+
return word + 's';
|
81
|
+
}
|
82
|
+
},
|
83
|
+
});
|
84
|
+
|
85
|
+
global.BlacklightHeatmaps.IndexView = IndexView;
|
86
|
+
global.BlacklightHeatmaps.indexView = function (el, options) {
|
87
|
+
return new IndexView(el, options);
|
88
|
+
};
|
89
|
+
})(this);
|
@@ -0,0 +1,34 @@
|
|
1
|
+
Blacklight.onLoad(function () {
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
$('[data-show-map]').each(function () {
|
5
|
+
BlacklightHeatmaps.showView(this);
|
6
|
+
});
|
7
|
+
});
|
8
|
+
|
9
|
+
!(function (global) {
|
10
|
+
'use strict';
|
11
|
+
|
12
|
+
var ShowView = L.Class.extend({
|
13
|
+
options: {},
|
14
|
+
|
15
|
+
initialize: function (el, options) {
|
16
|
+
var $el = $(el);
|
17
|
+
var features = $el.data().features;
|
18
|
+
|
19
|
+
var map = L.map($el[0].id).setView([0, 0], 1);
|
20
|
+
var basemap = L.tileLayer($el.data().basemap, {
|
21
|
+
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="http://cartodb.com/attributions">CartoDB</a>',
|
22
|
+
}).addTo(map);
|
23
|
+
|
24
|
+
var features = L.geoJson(features).addTo(map);
|
25
|
+
|
26
|
+
map.fitBounds(features.getBounds());
|
27
|
+
},
|
28
|
+
});
|
29
|
+
|
30
|
+
global.BlacklightHeatmaps.ShowView = ShowView;
|
31
|
+
global.BlacklightHeatmaps.showView = function (el, options) {
|
32
|
+
return new ShowView(el, options);
|
33
|
+
};
|
34
|
+
})(this);
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Blacklight
|
2
|
+
module MapsHelper
|
3
|
+
##
|
4
|
+
# Creates a div with needed attributes, used to display the index map
|
5
|
+
# @return String
|
6
|
+
def index_map_div
|
7
|
+
content_tag(
|
8
|
+
:div,
|
9
|
+
nil,
|
10
|
+
class: 'blacklight-heatmaps-index-map',
|
11
|
+
id: 'index-map',
|
12
|
+
data: index_map_data_attributes
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# The Leaflet template used for constructing the sidebar documents.
|
18
|
+
# Variables from returned docs should be keys within curly braces
|
19
|
+
# e.g. {title_display}
|
20
|
+
# @return String
|
21
|
+
def sidebar_template
|
22
|
+
<<-HTMLTEMPLATE
|
23
|
+
<div class='media'>
|
24
|
+
<div class='media-body'>
|
25
|
+
<h3 class='media-heading'>
|
26
|
+
<a href=\"#{document_path}\"}>
|
27
|
+
{#{blacklight_config.index.title_field}}
|
28
|
+
</a>
|
29
|
+
</h3>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
HTMLTEMPLATE
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
##
|
38
|
+
# Document path used for creating client side links to documents from a
|
39
|
+
# template
|
40
|
+
# @return String
|
41
|
+
def document_path
|
42
|
+
"#{search_catalog_path}/{#{blacklight_config.document_unique_id_param}}"
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Data attributes used in displaying the index map
|
47
|
+
# @return Hash
|
48
|
+
def index_map_data_attributes
|
49
|
+
{
|
50
|
+
index_map: true,
|
51
|
+
basemap: blacklight_config.basemap,
|
52
|
+
search_url: request.url,
|
53
|
+
geometry_field: blacklight_config.geometry_field,
|
54
|
+
sidebar_template: sidebar_template,
|
55
|
+
color_ramp: blacklight_config.view.heatmaps.color_ramp
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module BlacklightHeatmaps
|
2
|
+
##
|
3
|
+
# Used for creating and parsing bounding boxes from CQL Envelope syntax
|
4
|
+
class BoundingBox
|
5
|
+
##
|
6
|
+
# @param [String, Integer, Float] west
|
7
|
+
# @param [String, Integer, Float] south
|
8
|
+
# @param [String, Integer, Float] east
|
9
|
+
# @param [String, Integer, Float] north
|
10
|
+
def initialize(west, south, east, north)
|
11
|
+
@west = west.to_f
|
12
|
+
@south = south.to_f
|
13
|
+
@east = east.to_f
|
14
|
+
@north = north.to_f
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Returns a bounding box in ENVELOPE syntax
|
19
|
+
# @return [String]
|
20
|
+
def to_envelope
|
21
|
+
"ENVELOPE(#{west}, #{east}, #{north}, #{south})"
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# @return String
|
26
|
+
def to_geojson
|
27
|
+
{
|
28
|
+
type: 'Polygon',
|
29
|
+
coordinates: [
|
30
|
+
[
|
31
|
+
[west, south],
|
32
|
+
[west, north],
|
33
|
+
[east, north],
|
34
|
+
[east, south],
|
35
|
+
[west, south]
|
36
|
+
]
|
37
|
+
]
|
38
|
+
}.to_json
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.from_envelope(envelope)
|
42
|
+
envelope = envelope[/.*ENVELOPE\(([^\)]*)/,1].split(',')
|
43
|
+
new(envelope[0], envelope[3], envelope[1], envelope[2])
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_reader :west, :south, :east, :north
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module BlacklightHeatmaps
|
2
|
+
module Exceptions
|
3
|
+
class UnknownSpatialDataType < StandardError
|
4
|
+
def message
|
5
|
+
'BlacklightHeatmaps does not know how to parse that type of spatial data. '\
|
6
|
+
'Please try using the CQL ENVELOPE or X Y syntax.'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module BlacklightHeatmaps
|
2
|
+
##
|
3
|
+
# Parser that tries to understand the type of geospatial data stored in a
|
4
|
+
# String and sends that to the correct parsing class.
|
5
|
+
class GeometryParser
|
6
|
+
##
|
7
|
+
# Utility method for determing the type of spatial data stored in a string
|
8
|
+
# field
|
9
|
+
# @param String
|
10
|
+
def self.parse(geometry)
|
11
|
+
case geometry
|
12
|
+
when /^ENVELOPE\(.*\)$/
|
13
|
+
BlacklightHeatmaps::BoundingBox.from_envelope(geometry)
|
14
|
+
when /^(\-?\d+(\.\d+)?) \w*(\-?\d+(\.\d+)?)$/
|
15
|
+
BlacklightHeatmaps::Point.from_lng_lat(geometry)
|
16
|
+
else
|
17
|
+
raise BlacklightHeatmaps::Exceptions::UnknownSpatialDataType
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module BlacklightHeatmaps
|
2
|
+
##
|
3
|
+
# Provides methods to convert Solr geometry strings
|
4
|
+
module GeometrySolrDocument
|
5
|
+
def to_geojson(blacklight_config = nil)
|
6
|
+
return unless blacklight_config.try(:geometry_field) && fetch(blacklight_config.geometry_field, nil)
|
7
|
+
BlacklightHeatmaps::GeometryParser
|
8
|
+
.parse(fetch(blacklight_config.geometry_field)).to_geojson
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module BlacklightHeatmaps
|
2
|
+
##
|
3
|
+
# A geometry class to characterize points. Can be longitude and latitude.
|
4
|
+
class Point
|
5
|
+
def initialize(x, y)
|
6
|
+
@x = x.to_f
|
7
|
+
@y = y.to_f
|
8
|
+
end
|
9
|
+
|
10
|
+
##
|
11
|
+
# @return String
|
12
|
+
def to_geojson
|
13
|
+
{
|
14
|
+
type: 'Point',
|
15
|
+
coordinates: [
|
16
|
+
x, y
|
17
|
+
]
|
18
|
+
}.to_json
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# @param String
|
23
|
+
def self.from_lng_lat(lng_lat)
|
24
|
+
new(*lng_lat.split(' '))
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :x, :y
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module BlacklightHeatmaps
|
2
|
+
##
|
3
|
+
# Extends itself into a consuming application's SearchBuilder and adds
|
4
|
+
# relevancy, spatial search, and heatmap functionality.
|
5
|
+
module SolrFacetHeatmapBehavior
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
self.default_processor_chain += [:add_solr_facet_heatmap]
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Add Solr spatial heatmap parameters to Solr request
|
14
|
+
def add_solr_facet_heatmap(solr_parameters = {})
|
15
|
+
if blacklight_params[:bbox]
|
16
|
+
solr_parameters['facet.heatmap'] = geometry_field
|
17
|
+
solr_parameters['facet.heatmap.geom'] = bbox_as_range
|
18
|
+
solr_parameters[:bq] ||= []
|
19
|
+
solr_parameters[:bq] << "#{geometry_field}:\"IsWithin(#{bbox_as_envelope})\""
|
20
|
+
solr_parameters[:fq] ||= []
|
21
|
+
solr_parameters[:fq] << "#{geometry_field}:\"Intersects(#{bbox_as_envelope})\""
|
22
|
+
end
|
23
|
+
solr_parameters
|
24
|
+
end
|
25
|
+
|
26
|
+
def geometry_field
|
27
|
+
blacklight_config.geometry_field
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# `bbox` parameter is in format "west,south,east,north"
|
32
|
+
# @return Array
|
33
|
+
def bbox
|
34
|
+
blacklight_params[:bbox].split(',')
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Returned in CQL Envelope syntax
|
39
|
+
# https://cwiki.apache.org/confluence/display/solr/Spatial+Search
|
40
|
+
# @return String
|
41
|
+
def bbox_as_envelope
|
42
|
+
BlacklightHeatmaps::BoundingBox.new(*bbox).to_envelope
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Returned in rectangle-range syntax ["-180 -90" TO "180 90"]
|
47
|
+
# https://cwiki.apache.org/confluence/display/solr/Spatial+Search
|
48
|
+
# @return String
|
49
|
+
def bbox_as_range
|
50
|
+
"[\"#{bbox[0]} #{bbox[1]}\" TO \"#{bbox[2]} #{bbox[3]}\"]"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<% features = document.to_geojson(blacklight_config) %>
|
2
|
+
|
3
|
+
<% unless features.nil? %>
|
4
|
+
<%= content_tag(:div, nil, class: 'blacklight-heatmaps-show-map', id: "map-#{document.id}", data: {show_map: true, features: features, basemap: blacklight_config.basemap}) %>
|
5
|
+
<% end %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
##
|
2
|
+
# Overrides default index.json.jbuilder from Blacklight by adding the
|
3
|
+
# `facet_heatmaps` key/value
|
4
|
+
|
5
|
+
json.response do
|
6
|
+
json.docs @presenter.documents
|
7
|
+
json.facets @presenter.search_facets_as_json
|
8
|
+
json.facet_heatmaps @response['facet_counts']['facet_heatmaps']
|
9
|
+
json.pages @presenter.pagination_info
|
10
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>BlacklightHeatmaps</title>
|
5
|
+
<%= stylesheet_link_tag "blacklight_heatmaps/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "blacklight_heatmaps/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module BlacklightHeatmaps
|
4
|
+
class Install < Rails::Generators::Base
|
5
|
+
def add_gems
|
6
|
+
gem 'blacklight_heatmaps'
|
7
|
+
end
|
8
|
+
|
9
|
+
source_root File.expand_path('../templates', __FILE__)
|
10
|
+
|
11
|
+
def assets
|
12
|
+
copy_file 'blacklight_heatmaps.scss', 'app/assets/stylesheets/blacklight_heatmaps.scss'
|
13
|
+
copy_file 'blacklight_heatmaps.js', 'app/assets/javascripts/blacklight_heatmaps.js'
|
14
|
+
end
|
15
|
+
|
16
|
+
def configuration
|
17
|
+
inject_into_file 'app/controllers/catalog_controller.rb', after: 'configure_blacklight do |config|' do
|
18
|
+
"\n # BlacklightHeatmaps configuration values" \
|
19
|
+
"\n config.geometry_field = :geo_srpt" \
|
20
|
+
"\n config.basemap = 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png'" \
|
21
|
+
"\n config.show.partials.insert(1, :show_leaflet_map)" \
|
22
|
+
"\n config.view.heatmaps.partials = []" \
|
23
|
+
"\n #Heatmap color ramp. For best results, use http://colorbrewer2.org or http://tristen.ca/hcl-picker/#/hlc/5/1" \
|
24
|
+
"\n config.view.heatmaps.color_ramp = ['#ffffcc', '#a1dab4', '#41b6c4', '#2c7fb8', '#253494']" \
|
25
|
+
"\n"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_model_mixin
|
30
|
+
inject_into_file 'app/models/solr_document.rb', after: 'include Blacklight::Solr::Document' do
|
31
|
+
"\n include BlacklightHeatmaps::GeometrySolrDocument\n"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def inject_search_builder
|
36
|
+
inject_into_file 'app/models/search_builder.rb', after: /include Blacklight::Solr::SearchBuilderBehavior.*$/ do
|
37
|
+
"\n include BlacklightHeatmaps::SolrFacetHeatmapBehavior\n"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
//= require blacklight_heatmaps/default
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Tasks shared with the consuming application
|
2
|
+
namespace :blacklight_heatmaps do
|
3
|
+
namespace :index do
|
4
|
+
desc 'Put sample data into Solr'
|
5
|
+
task :seed, [:datafile] => [:environment] do |_t, args|
|
6
|
+
args.with_defaults(datafile: 'sample_solr_documents')
|
7
|
+
fn = File.join(BlacklightHeatmaps::Engine.root, 'solr', args[:datafile] + '.yml')
|
8
|
+
puts "Indexing sample data from #{fn}"
|
9
|
+
docs = YAML.load(File.open(fn))
|
10
|
+
conn = Blacklight.default_index.connection
|
11
|
+
conn.add docs
|
12
|
+
conn.commit
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Fetch random data from WhosOnFirst gazetteer and index into Solr'
|
16
|
+
task :seed_random, [:n] => [:environment] do |_t, args|
|
17
|
+
args.with_defaults(n: 10)
|
18
|
+
puts "Indexing #{args[:n]} random data records"
|
19
|
+
docs = YAML.load(`bundle exec ruby #{File.join(BlacklightHeatmaps::Engine.root, 'scripts', 'sample_whosonfirst.rb')} #{args[:n]}`)
|
20
|
+
conn = Blacklight.default_index.connection
|
21
|
+
conn.add docs
|
22
|
+
conn.commit
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
feature 'Index page map', js: true do
|
4
|
+
it 'renders a leaflet map' do
|
5
|
+
visit search_catalog_path(q: 'strong', view: 'heatmaps')
|
6
|
+
expect(page).to have_css '.leaflet-map-pane'
|
7
|
+
# Zoomed to world
|
8
|
+
expect(page).to have_css 'img[src="http://a.basemaps.cartocdn.com/light_all/1/0/0.png"]'
|
9
|
+
expect(page).to have_css '#index-map-sidebar', visible: false
|
10
|
+
page.find('svg g path').click
|
11
|
+
expect(page).to have_css '#index-map-sidebar', visible: true
|
12
|
+
expect(page)
|
13
|
+
.to have_css 'h3.media-heading a', text: '"Strong Medicine speaks"'
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
feature 'Show map map', js: true do
|
4
|
+
it 'renders a leaflet map' do
|
5
|
+
visit solr_document_path '43037890'
|
6
|
+
expect(page).to have_css '.leaflet-map-pane'
|
7
|
+
# Zoomed to Kazakhstan
|
8
|
+
expect(page).to have_css 'img[src="http://b.basemaps.cartocdn.com/light_all/4/11/5.png"]'
|
9
|
+
expect(page).to have_css 'svg g path'
|
10
|
+
end
|
11
|
+
it 'renders a point type' do
|
12
|
+
visit solr_document_path '34860108'
|
13
|
+
expect(page).to have_css '.leaflet-marker-icon'
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Blacklight::MapsHelper do
|
4
|
+
let(:blacklight_config) do
|
5
|
+
Blacklight::Configuration.new(
|
6
|
+
basemap: 'http://www.example.com/{z}/{x}/{y}.png',
|
7
|
+
geometry_field: 'geo_srpt',
|
8
|
+
index: Blacklight::OpenStructWithHashAccess.new(
|
9
|
+
title_field: 'title_display'
|
10
|
+
)
|
11
|
+
)
|
12
|
+
end
|
13
|
+
before do
|
14
|
+
allow(helper).to receive_messages(blacklight_config: blacklight_config)
|
15
|
+
end
|
16
|
+
describe '#index_map_div' do
|
17
|
+
it 'renders html with the required elements/attributes' do
|
18
|
+
expect(helper.index_map_div)
|
19
|
+
.to have_css '#index-map.blacklight-heatmaps-index-map'
|
20
|
+
expect(helper.index_map_div)
|
21
|
+
.to have_css '[data-index-map="true"]'
|
22
|
+
expect(helper.index_map_div)
|
23
|
+
.to have_css '[data-search-url="http://test.host"]'
|
24
|
+
expect(helper.index_map_div)
|
25
|
+
.to have_css '[data-geometry-field="geo_srpt"]'
|
26
|
+
expect(helper.index_map_div)
|
27
|
+
.to have_css '[data-basemap="http://www.example.com/{z}/{x}/{y}.png"]'
|
28
|
+
expect(helper.index_map_div).to have_css '[data-sidebar-template]'
|
29
|
+
expect(helper.index_map_div).to have_css '[data-color-ramp]'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
describe '#sidebar_template' do
|
33
|
+
it 'renders html template used in sidebar' do
|
34
|
+
expect(helper.sidebar_template)
|
35
|
+
.to have_css '.media .media-body h3.media-heading a', text: '{title_display}'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BlacklightHeatmaps::BoundingBox do
|
4
|
+
describe '#initialize' do
|
5
|
+
it 'handles multiple input types as arguments' do
|
6
|
+
expect(described_class.new('1', '1', '1', '1')).to be_an described_class
|
7
|
+
expect(described_class.new(1, 2, 3, 3)).to be_an described_class
|
8
|
+
expect(described_class.new(1.1, 2.1, 3.1, 3.1)).to be_an described_class
|
9
|
+
end
|
10
|
+
end
|
11
|
+
describe '#to_envelope' do
|
12
|
+
let(:example_box) { described_class.new(-160, -80, 120, 70) }
|
13
|
+
it 'creates an envelope syntax version of the bounding box' do
|
14
|
+
expect(example_box.to_envelope).to eq 'ENVELOPE(-160.0, 120.0, 70.0, -80.0)'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
describe '#to_geojson' do
|
18
|
+
let(:example_box) { described_class.new(-160, -80, 120, 70) }
|
19
|
+
it 'creates a geoJSON string' do
|
20
|
+
expect(example_box.to_geojson).to eq '{"type":"Polygon","coordinates":[[[-160.0,-80.0],[-160.0,70.0],[120.0,70.0],[120.0,-80.0],[-160.0,-80.0]]]}'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
describe '#from_rectangle' do
|
24
|
+
let(:envelope) { 'ENVELOPE(-160.0, 120.0, 70.0, -80.0)' }
|
25
|
+
let(:example_box) { described_class.from_envelope(envelope) }
|
26
|
+
it 'parses and creates a Geoblacklight::BoundingBox from a Solr lat-lon' do
|
27
|
+
expect(example_box).to be_an described_class
|
28
|
+
expect(example_box.to_envelope).to eq envelope
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BlacklightHeatmaps::GeometryParser do
|
4
|
+
describe '.parse' do
|
5
|
+
context 'when parsing a CQL ENVELOPE' do
|
6
|
+
it 'returns a BlacklightHeatmaps::BoundingBox' do
|
7
|
+
expect(described_class.parse('ENVELOPE(1,2,4,3)'))
|
8
|
+
.to be_an BlacklightHeatmaps::BoundingBox
|
9
|
+
end
|
10
|
+
end
|
11
|
+
context 'when parsing an X Y coordinate' do
|
12
|
+
it 'returns a BlacklightHeatmaps::Point' do
|
13
|
+
expect(described_class.parse('-180 90')).to be_an BlacklightHeatmaps::Point
|
14
|
+
end
|
15
|
+
end
|
16
|
+
context 'when parsing an unknown type' do
|
17
|
+
it 'raises an exception' do
|
18
|
+
expect do
|
19
|
+
described_class.parse('123,23 32,123')
|
20
|
+
end.to raise_error(BlacklightHeatmaps::Exceptions::UnknownSpatialDataType)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BlacklightHeatmaps::GeometrySolrDocument do
|
4
|
+
subject { SolrDocument.new(fields).to_geojson(blacklight_config) }
|
5
|
+
|
6
|
+
context 'when configured' do
|
7
|
+
let(:fields) { { some_field: 'ENVELOPE(1,2,4,3)' } }
|
8
|
+
let(:blacklight_config) { double('BlacklightConfig', geometry_field: :some_field) }
|
9
|
+
it 'returns the data from the document as geoJSON' do
|
10
|
+
expect(subject).to eq '{"type":"Polygon","coordinates":[[[1.0,3.0],[1.0,4.0],[2.0,4.0],[2.0,3.0],[1.0,3.0]]]}'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
context 'when not configured' do
|
14
|
+
let(:fields) { { some_field: 'ENVELOPE(1,2,4,3)' } }
|
15
|
+
let(:blacklight_config) { double('BlacklightConfig') }
|
16
|
+
it 'returns nil' do
|
17
|
+
expect(subject).to be_nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
context 'when the document has the field' do
|
21
|
+
let(:fields) { { some_field: 'ENVELOPE(1,2,4,3)' } }
|
22
|
+
let(:blacklight_config) { double('BlacklightConfig', geometry_field: :some_field) }
|
23
|
+
it 'returns the data from the document as geoJSON' do
|
24
|
+
expect(subject).to eq '{"type":"Polygon","coordinates":[[[1.0,3.0],[1.0,4.0],[2.0,4.0],[2.0,3.0],[1.0,3.0]]]}'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
context 'when the document does not have the field' do
|
28
|
+
let(:fields) { { some_other_field: 'ENVELOPE(1,2,4,3)' } }
|
29
|
+
let(:blacklight_config) { double('BlacklightConfig', geometry_field: :some_field) }
|
30
|
+
it 'returns nil' do
|
31
|
+
expect(subject).to be_nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BlacklightHeatmaps::Point do
|
4
|
+
describe '#to_geojson' do
|
5
|
+
it 'creates geojson from the point' do
|
6
|
+
expect(described_class.new(-180, 90).to_geojson)
|
7
|
+
.to eq '{"type":"Point","coordinates":[-180.0,90.0]}'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
describe '.from_lng_lat' do
|
11
|
+
subject { described_class.from_lng_lat('-180 90') }
|
12
|
+
it 'instantiates an instance from a lng lat string' do
|
13
|
+
expect(subject).to be_an described_class
|
14
|
+
expect(subject.to_geojson)
|
15
|
+
.to eq '{"type":"Point","coordinates":[-180.0,90.0]}'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe BlacklightHeatmaps::SolrFacetHeatmapBehavior do
|
4
|
+
let(:blacklight_config) { CatalogController.blacklight_config.deep_copy }
|
5
|
+
let(:context) { CatalogController.new }
|
6
|
+
|
7
|
+
before do
|
8
|
+
allow(context).to receive(:blacklight_config).and_return(blacklight_config)
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:search_builder_class) do
|
12
|
+
Class.new(Blacklight::SearchBuilder) do
|
13
|
+
include Blacklight::Solr::SearchBuilderBehavior
|
14
|
+
include BlacklightHeatmaps::SolrFacetHeatmapBehavior
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:search_builder) { search_builder_class.new(context) }
|
19
|
+
|
20
|
+
describe '#add_solr_facet_heatmap' do
|
21
|
+
let(:solr_params) { { fq: [filter: 'stuff'], bq: [boost: 'stuff'] } }
|
22
|
+
context 'when bbox is not present' do
|
23
|
+
subject { search_builder }
|
24
|
+
it 'does not modify the solr parameters' do
|
25
|
+
expect(subject.add_solr_facet_heatmap(solr_params)).to eq solr_params
|
26
|
+
end
|
27
|
+
end
|
28
|
+
context 'when a bbox is present' do
|
29
|
+
subject { search_builder.with(bbox: '1,2,4,3') }
|
30
|
+
it 'leaves solr params in place and adds new params' do
|
31
|
+
expect(subject.add_solr_facet_heatmap(solr_params)['facet.heatmap'])
|
32
|
+
.to eq :geo_srpt
|
33
|
+
expect(subject.add_solr_facet_heatmap(solr_params)['facet.heatmap.geom'])
|
34
|
+
.to eq '["1 2" TO "4 3"]'
|
35
|
+
expect(subject.add_solr_facet_heatmap(solr_params)[:bq])
|
36
|
+
.to include(boost: 'stuff')
|
37
|
+
expect(subject.add_solr_facet_heatmap(solr_params)[:bq])
|
38
|
+
.to include('geo_srpt:"IsWithin(ENVELOPE(1.0, 4.0, 3.0, 2.0))"')
|
39
|
+
expect(subject.add_solr_facet_heatmap(solr_params)[:fq])
|
40
|
+
.to include(filter: 'stuff')
|
41
|
+
expect(subject.add_solr_facet_heatmap(solr_params)[:fq])
|
42
|
+
.to include('geo_srpt:"Intersects(ENVELOPE(1.0, 4.0, 3.0, 2.0))"')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#bbox' do
|
48
|
+
subject { search_builder.with(bbox: '1,2,4,3') }
|
49
|
+
it 'returns the bbox parameter split on ,' do
|
50
|
+
expect(subject.bbox).to match_array %w(1 2 4 3)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#bbox_as_envelope' do
|
55
|
+
subject { search_builder.with(bbox: '1,2,4,3') }
|
56
|
+
it 'returns the bbox parameter in envelope syntax' do
|
57
|
+
expect(subject.bbox_as_envelope).to eq 'ENVELOPE(1.0, 4.0, 3.0, 2.0)'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#bbox_as_range' do
|
62
|
+
subject { search_builder.with(bbox: '1,2,4,3') }
|
63
|
+
it 'returns the bbox parameter in rectangle-range syntax' do
|
64
|
+
expect(subject.bbox_as_range).to eq '["1 2" TO "4 3"]'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
ENV['RAILS_ENV'] ||= 'test'
|
2
|
+
|
3
|
+
if ENV['COVERAGE'] || ENV['CI']
|
4
|
+
require 'simplecov'
|
5
|
+
require 'coveralls'
|
6
|
+
|
7
|
+
SimpleCov.formatter = Coveralls::SimpleCov::Formatter
|
8
|
+
SimpleCov.start do
|
9
|
+
add_filter '/spec/'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'engine_cart'
|
14
|
+
EngineCart.load_application!
|
15
|
+
|
16
|
+
require 'rspec/rails'
|
17
|
+
|
18
|
+
require 'capybara/poltergeist'
|
19
|
+
Capybara.javascript_driver = :poltergeist
|
20
|
+
|
21
|
+
require 'blacklight'
|
22
|
+
require 'blacklight_heatmaps'
|
23
|
+
|
24
|
+
RSpec.configure do |c|
|
25
|
+
c.infer_spec_type_from_file_location!
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
class TestAppGenerator < Rails::Generators::Base
|
4
|
+
source_root './spec/test_app_templates'
|
5
|
+
|
6
|
+
def add_gems
|
7
|
+
gem 'blacklight', '~> 6.0'
|
8
|
+
|
9
|
+
Bundler.with_clean_env do
|
10
|
+
run 'bundle install'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def run_blacklight_generator
|
15
|
+
say_status('warning', 'GENERATING BL', :yellow)
|
16
|
+
|
17
|
+
generate 'blacklight:install', '--devise'
|
18
|
+
end
|
19
|
+
|
20
|
+
# if you need to generate any additional configuration
|
21
|
+
# into the test app, this generator will be run immediately
|
22
|
+
# after setting up the application
|
23
|
+
|
24
|
+
def install_engine
|
25
|
+
generate 'blacklight_heatmaps:install'
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'catalog/_document_heatmaps.html.erb' do
|
4
|
+
let(:blacklight_config) { Blacklight::Configuration.new }
|
5
|
+
before do
|
6
|
+
allow(view).to receive(:index_map_div)
|
7
|
+
.and_return '<div id="index-map"></div>'.html_safe
|
8
|
+
end
|
9
|
+
it 'renders a div with needed elements' do
|
10
|
+
blacklight_config.configure do |config|
|
11
|
+
config.geometry_field = :geo_srpt
|
12
|
+
end
|
13
|
+
render partial: 'catalog/document_heatmaps',
|
14
|
+
locals: { blacklight_config: blacklight_config }
|
15
|
+
expect(rendered).to have_css '.blacklight-heatmaps-index-map-container'
|
16
|
+
expect(rendered).to have_css '#index-map'
|
17
|
+
expect(rendered).to have_css '#index-map-sidebar'
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'catalog/_show_leaflet_map_default.html.erb' do
|
4
|
+
let(:document) do
|
5
|
+
SolrDocument.new(geo_srpt: 'ENVELOPE(1,2,4,3)', id: 'abc123')
|
6
|
+
end
|
7
|
+
let(:blacklight_config) { Blacklight::Configuration.new }
|
8
|
+
before do
|
9
|
+
allow(view).to receive(:document).and_return(document)
|
10
|
+
end
|
11
|
+
context 'when geojson is available' do
|
12
|
+
it 'should render the leaflet container' do
|
13
|
+
blacklight_config.configure do |config|
|
14
|
+
config.geometry_field = :geo_srpt
|
15
|
+
end
|
16
|
+
render partial: 'catalog/show_leaflet_map_default',
|
17
|
+
locals: { document: document, blacklight_config: blacklight_config }
|
18
|
+
expect(rendered).to have_css '.blacklight-heatmaps-show-map'
|
19
|
+
expect(rendered).to have_css '#map-abc123'
|
20
|
+
expect(rendered).to have_css '[data-basemap]'
|
21
|
+
expect(rendered).to have_css '[data-show-map]'
|
22
|
+
expect(rendered).to have_css '[data-features]'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
context 'when geojson is not available' do
|
26
|
+
it 'renders nothing' do
|
27
|
+
render partial: 'catalog/show_leaflet_map_default',
|
28
|
+
locals: { document: document, blacklight_config: blacklight_config }
|
29
|
+
expect(rendered).to eq "\n"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: blacklight_heatmaps
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jack Reed
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-07-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.2.6
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.2.6
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: blacklight
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '6.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '6.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: leaflet-rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: leaflet-sidebar-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.1.9
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.1.9
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sqlite3
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-rails
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.4'
|
90
|
+
- - "<"
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '4'
|
93
|
+
type: :development
|
94
|
+
prerelease: false
|
95
|
+
version_requirements: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '3.4'
|
100
|
+
- - "<"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '4'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: engine_cart
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.8'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - "~>"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0.8'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: solr_wrapper
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: capybara
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: poltergeist
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
description: Search and view Blacklight resources on a map.
|
160
|
+
email:
|
161
|
+
- phillipjreed@gmail.com
|
162
|
+
executables: []
|
163
|
+
extensions: []
|
164
|
+
extra_rdoc_files: []
|
165
|
+
files:
|
166
|
+
- LICENSE.txt
|
167
|
+
- README.md
|
168
|
+
- Rakefile
|
169
|
+
- app/assets/javascripts/blacklight_heatmaps/blacklight_heatmaps.js
|
170
|
+
- app/assets/javascripts/blacklight_heatmaps/default.js
|
171
|
+
- app/assets/javascripts/blacklight_heatmaps/viewers/index.js
|
172
|
+
- app/assets/javascripts/blacklight_heatmaps/viewers/show.js
|
173
|
+
- app/assets/stylesheets/blacklight_heatmaps/default.scss
|
174
|
+
- app/controllers/blacklight_heatmaps/application_controller.rb
|
175
|
+
- app/helpers/blacklight/maps_helper.rb
|
176
|
+
- app/models/concerns/blacklight_heatmaps/bounding_box.rb
|
177
|
+
- app/models/concerns/blacklight_heatmaps/exceptions.rb
|
178
|
+
- app/models/concerns/blacklight_heatmaps/geometry_parser.rb
|
179
|
+
- app/models/concerns/blacklight_heatmaps/geometry_solr_document.rb
|
180
|
+
- app/models/concerns/blacklight_heatmaps/point.rb
|
181
|
+
- app/models/concerns/blacklight_heatmaps/solr_facet_heatmap_behavior.rb
|
182
|
+
- app/views/catalog/_document_heatmaps.html.erb
|
183
|
+
- app/views/catalog/_show_leaflet_map_default.html.erb
|
184
|
+
- app/views/catalog/index.json.jbuilder
|
185
|
+
- app/views/layouts/blacklight_heatmaps/application.html.erb
|
186
|
+
- config/routes.rb
|
187
|
+
- lib/blacklight_heatmaps.rb
|
188
|
+
- lib/blacklight_heatmaps/engine.rb
|
189
|
+
- lib/blacklight_heatmaps/version.rb
|
190
|
+
- lib/generators/blacklight_heatmaps/install_generator.rb
|
191
|
+
- lib/generators/blacklight_heatmaps/templates/blacklight_heatmaps.js
|
192
|
+
- lib/generators/blacklight_heatmaps/templates/blacklight_heatmaps.scss
|
193
|
+
- lib/tasks/blacklight_heatmaps_tasks.rake
|
194
|
+
- spec/features/index_page_map_spec.rb
|
195
|
+
- spec/features/show_page_map_spec.rb
|
196
|
+
- spec/helpers/blacklight/maps_helper_spec.rb
|
197
|
+
- spec/models/concerns/blacklight_heatmaps/bounding_box_spec.rb
|
198
|
+
- spec/models/concerns/blacklight_heatmaps/geometry_parser_spec.rb
|
199
|
+
- spec/models/concerns/blacklight_heatmaps/geometry_solr_document_spec.rb
|
200
|
+
- spec/models/concerns/blacklight_heatmaps/point_spec.rb
|
201
|
+
- spec/models/concerns/blacklight_heatmaps/solr_facet_heatmap_behavior_spec.rb
|
202
|
+
- spec/spec_helper.rb
|
203
|
+
- spec/test_app_templates/lib/generators/test_app_generator.rb
|
204
|
+
- spec/views/catalog/_document_heatmaps.html.erb_spec.rb
|
205
|
+
- spec/views/catalog/_show_leaflet_map_default.html.erb_spec.rb
|
206
|
+
homepage: https://github.com/sul-dlss/blacklight_heatmaps
|
207
|
+
licenses:
|
208
|
+
- Apache
|
209
|
+
metadata: {}
|
210
|
+
post_install_message:
|
211
|
+
rdoc_options: []
|
212
|
+
require_paths:
|
213
|
+
- lib
|
214
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
215
|
+
requirements:
|
216
|
+
- - ">="
|
217
|
+
- !ruby/object:Gem::Version
|
218
|
+
version: '0'
|
219
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
220
|
+
requirements:
|
221
|
+
- - ">="
|
222
|
+
- !ruby/object:Gem::Version
|
223
|
+
version: '0'
|
224
|
+
requirements: []
|
225
|
+
rubyforge_project:
|
226
|
+
rubygems_version: 2.4.5.1
|
227
|
+
signing_key:
|
228
|
+
specification_version: 4
|
229
|
+
summary: Search and view Blacklight resources on a map.
|
230
|
+
test_files:
|
231
|
+
- spec/features/index_page_map_spec.rb
|
232
|
+
- spec/features/show_page_map_spec.rb
|
233
|
+
- spec/helpers/blacklight/maps_helper_spec.rb
|
234
|
+
- spec/models/concerns/blacklight_heatmaps/bounding_box_spec.rb
|
235
|
+
- spec/models/concerns/blacklight_heatmaps/geometry_parser_spec.rb
|
236
|
+
- spec/models/concerns/blacklight_heatmaps/geometry_solr_document_spec.rb
|
237
|
+
- spec/models/concerns/blacklight_heatmaps/point_spec.rb
|
238
|
+
- spec/models/concerns/blacklight_heatmaps/solr_facet_heatmap_behavior_spec.rb
|
239
|
+
- spec/spec_helper.rb
|
240
|
+
- spec/test_app_templates/lib/generators/test_app_generator.rb
|
241
|
+
- spec/views/catalog/_document_heatmaps.html.erb_spec.rb
|
242
|
+
- spec/views/catalog/_show_leaflet_map_default.html.erb_spec.rb
|