blacklight_heatmaps 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/sul-dlss/blacklight_heatmaps.svg?branch=master)](https://travis-ci.org/sul-dlss/blacklight_heatmaps) | [![Coverage Status](https://coveralls.io/repos/github/sul-dlss/blacklight_heatmaps/badge.svg?branch=master)](https://coveralls.io/github/sul-dlss/blacklight_heatmaps?branch=master)
|
3
|
+
|
4
|
+
![blacklight_heatmap](https://cloud.githubusercontent.com/assets/1656824/16598401/d0538fce-42cb-11e6-86f8-81fd37ab2abe.gif)
|
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
|