blacklight-maps 0.0.1 → 0.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e35e471feb601eeeec9355dc1cc7e31d158f03bb
4
- data.tar.gz: 8be5024c30a03decfb0e15563f79117606be1fec
3
+ metadata.gz: f5cede804f84631bbe7ec2c80370c8f0cbf88c31
4
+ data.tar.gz: 853cd08e29850b439c5d7773c48118b835216d28
5
5
  SHA512:
6
- metadata.gz: b019eae752da2b6cc576a759b09abb1d7799748c82603b0d13f20990f592e0ad51b35785abb6dda9370d5cbbd477c506ee26db9f73ae2cfa8aa7380ea584c707
7
- data.tar.gz: a999abc043657b6f52ae34f1ce6d5479491b49812e2fa87b93257a3173de069a4e237d09e4cfb53869849d939803554842a918aec59e78c182d94be3d02f787b
6
+ metadata.gz: 4181770fa39430c201156ab3b9d83cffc0208a58c530e6209fea4d5f4ce56b3e52d04ee7a49059be6cd84ae65208589afdc00f6e80de51a082652b1f8d33cb9e
7
+ data.tar.gz: defd9c711b0f083449e952726548532d078b639c822fc606ab4fd3d79f3eaf3abeb5658a022a52041dca3981a2363eecfbb284dcaaa37f534e89d27b5057a0d7
data/.travis.yml CHANGED
@@ -15,4 +15,8 @@ notifications:
15
15
  env:
16
16
  global:
17
17
  - JRUBY_OPTS="-J-Xms512m -J-Xmx1024m"
18
- - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
18
+ - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
19
+
20
+ matrix:
21
+ allow_failures:
22
+ - rvm: jruby-19mode
data/Gemfile CHANGED
@@ -6,11 +6,19 @@ gemspec
6
6
  gem 'simplecov', require: false
7
7
  gem 'coveralls', require: false
8
8
 
9
- gem 'engine_cart', git: 'https://github.com/cbeer/engine_cart'
9
+ # If we don't specify 2.11.0 we'll end up with sprockets 2.12.0 in the main
10
+ # Gemfile.lock but since sass-rails gets generated (rails new) into the test app
11
+ # it'll want sprockets 2.11.0 and we'll have a conflict
12
+ gem 'sprockets', '2.11.0'
13
+
14
+ # # If we don't specify 3.2.15 we'll end up with sass 3.3.2 in the main
15
+ # # Gemfile.lock but since sass-rails gets generated (rails new) into the test app
16
+ # # it'll want sass 3.2.0 and we'll have a conflict
17
+ gem 'sass', '~> 3.2.0'
10
18
 
11
19
 
12
20
  file = File.expand_path("Gemfile", ENV['ENGINE_CART_DESTINATION'] || ENV['RAILS_ROOT'] || File.expand_path("../spec/internal", __FILE__))
13
21
  if File.exists?(file)
14
22
  puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
15
23
  instance_eval File.read(file)
16
- end
24
+ end
data/README.md CHANGED
@@ -25,14 +25,20 @@ Or install it yourself as:
25
25
 
26
26
  Blacklight-Maps adds a map view capability for a results set that contains geospatial coordinates (latitude/longitude).
27
27
 
28
- For now, Blacklight-Maps requires that your SOLR index includes a field containing placenames with latitude and longitude coordinates delimited by `|`. This field can be multivalued.
28
+ For now, Blacklight-Maps requires that your Solr index include one of the following two types of fields:
29
29
 
30
- A document requires the following field:
30
+ 1. A `location_rpt` field that contains a bounding box for the document. For more on `location_rpt` see [Solr help](https://cwiki.apache.org/confluence/display/solr/Spatial+Search). This field can be multivalued.
31
+ ```
32
+ place_bbox: 44.0318907 25.0594286 63.3333366 39.7816755
33
+ # minX minY maxX maxY
34
+ ```
35
+
36
+ 2. A field containing placenames with latitude and longitude coordinates delimited by `-|-`. The delimiter can be configured in `app/controllers/catalog_controller.rb`. This field can be multivalued.
31
37
  ```
32
38
  placename_coords:
33
- - China|35.86166|104.195397
34
- - Tibet|29.646923|91.117212
35
- - India|20.593684|78.96288
39
+ - China-|-35.86166-|-104.195397
40
+ - Tibet-|-29.646923-|-91.117212
41
+ - India-|-20.593684-|-78.96288
36
42
  ```
37
43
 
38
44
  Note: We are looking at implementing support for additional fields.
@@ -42,14 +48,15 @@ Note: We are looking at implementing support for additional fields.
42
48
  #### Required
43
49
  Blacklight-Maps expects you to provide:
44
50
 
45
- - a field to map the placename coordinates (`placename_coords` in the example above)
51
+ - the type of location field you are using, `placename_coord` or `bbox` (`bbox` is default)
52
+ - a field to map the placename coordinates or bbox field
46
53
 
47
54
  #### Optional
48
55
 
49
56
  - the maxZoom [property of the map](http://leafletjs.com/reference.html#map-maxzoom)
50
57
  - a [tileLayer url](http://leafletjs.com/reference.html#tilelayer-l.tilelayer) to change the basemap
51
58
  - an [attribution string](http://leafletjs.com/reference.html#tilelayer-attribution) to describe the basemap layer
52
-
59
+ - a custom delimiter field (used to delimit placename_coord values)
53
60
 
54
61
  All of these options can easily be configured in `CatalogController.rb` in the `config` block.
55
62
 
@@ -57,16 +64,19 @@ All of these options can easily be configured in `CatalogController.rb` in the `
57
64
  ...
58
65
  configure_blacklight do |config|
59
66
  ## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params
60
- config.default_solr_params = {
67
+ config.default_solr_params = {
61
68
  :qt => 'search',
62
69
  :rows => 10,
63
70
  :fl => '*'
64
71
  }
65
72
 
66
73
  ## Default values
67
- config.view.maps.placename_coords_field = "placename_coords"
74
+ config.view.maps.type = "bbox" # also accepts 'placename_coord' to use the placename coordinate type
75
+ config.view.maps.bbox_field = "place_bbox"
76
+ config.view.maps.placename_coord_field = "placename_coords"
68
77
  config.view.maps.tileurl = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
69
78
  config.view.maps.attribution = 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'
79
+ config.view.maps.placename_coord_delimiter = '-|-'
70
80
  ...
71
81
 
72
82
  ```
@@ -1,141 +1,152 @@
1
- var map, sidebar;
1
+ ;(function( $ ) {
2
+
3
+ $.fn.blacklight_leaflet_map = function(geojson_docs, arg_opts) {
4
+ var map, sidebar, markers, geoJsonLayer, currentLayer;
5
+
6
+ // Configure default options and those passed via the constructor options
7
+ var options = $.extend({
8
+ tileurl : 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
9
+ mapattribution : 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
10
+ sidebar: 'blacklight-map-sidebar'
11
+ }, arg_opts );
12
+
13
+ // Extend options from data-attributes
14
+ $.extend(options, this.data());
15
+
16
+ // Display the map
17
+ this.each(function() {
18
+ options.id = this.id;
19
+
20
+ // Setup Leaflet map
21
+ map = L.map(this.id).setView([0,0], 2);
22
+ L.tileLayer(options.tileurl, {
23
+ attribution: options.mapattribution,
24
+ maxZoom: options.maxzoom
25
+ }).addTo(map);
26
+
27
+ // Initialize sidebar
28
+ sidebar = L.control.sidebar(options.sidebar, {
29
+ position: 'right',
30
+ autoPan: false
31
+ });
2
32
 
3
- Blacklight.onLoad(function() {
33
+ // Adds leaflet-sidebar control to map
34
+ map.addControl(sidebar);
4
35
 
5
- // Stop doing stuff if the map div isn't there
6
- if ($("#blacklight-map").length === 0){
7
- return;
8
- }
9
-
10
- // Get the configuration options from the data-attributes
11
- $.extend(Blacklight.mapOptions, $("#blacklight-map").data());
12
-
13
- map = L.map('blacklight-map').setView([0,0], 2);
14
- L.tileLayer(Blacklight.mapOptions.tileurl, {
15
- attribution: Blacklight.mapOptions.mapattribution,
16
- maxZoom: Blacklight.mapOptions.maxzoom
17
- }).addTo(map);
18
-
19
- // Sets up leaflet-sidebar
20
- sidebar = L.control.sidebar('blacklight-map-sidebar', {
21
- position: 'right',
22
- autoPan: false
23
- });
24
-
25
- // Adds leaflet-sidebar control to map (object)
26
- map.addControl(sidebar);
27
-
28
- // Create a marker cluster object and set options
29
- markers = new L.MarkerClusterGroup({
30
- showCoverageOnHover: false,
31
- spiderfyOnMaxZoom: false,
32
- singleMarkerMode: true,
33
- animateAddingMarkers: true
34
- });
35
-
36
- geoJsonLayer = L.geoJson(geojson_docs, {
37
- onEachFeature: function(feature, layer){
38
- layer.defaultOptions.title = feature.properties.placename;
39
- layer.on('click', function(e){
40
- if (sidebar.isVisible()){
41
- sidebar.hide();
36
+ // Create a marker cluster object and set options
37
+ markers = new L.MarkerClusterGroup({
38
+ showCoverageOnHover: false,
39
+ spiderfyOnMaxZoom: false,
40
+ singleMarkerMode: true,
41
+ animateAddingMarkers: true
42
+ });
43
+
44
+ geoJsonLayer = L.geoJson(geojson_docs, {
45
+ onEachFeature: function(feature, layer){
46
+ layer.defaultOptions.title = getMapTitle(options.type, feature.properties.name);
47
+ layer.on('click', function(e){
48
+ var placenames = {};
49
+ placenames[layer.defaultOptions.title] = [feature.properties.html];
50
+ setupSidebarDisplay(e,placenames);
51
+ });
42
52
  }
43
- var placenames = {};
44
- placenames[feature.properties.placename] = [feature.properties.html];
45
- offsetMap(e);
46
- $('#blacklight-map-sidebar').html(buildList(placenames));
47
- sidebar.show();
48
53
  });
49
- }
50
- });
51
54
 
52
- // Add GeoJSON layer to marker cluster object
53
- markers.addLayer(geoJsonLayer);
55
+ // Add GeoJSON layer to marker cluster object
56
+ markers.addLayer(geoJsonLayer);
54
57
 
55
- // Add marker cluster object to map
56
- map.addLayer(markers);
58
+ // Add marker cluster object to map
59
+ map.addLayer(markers);
57
60
 
58
- // Listeners for marker cluster clicks
59
- markers.on('clusterclick', function(e){
60
-
61
- //hide sidebar if it is visible
62
- if (sidebar.isVisible()){
63
- sidebar.hide();
64
- }
61
+ // Listeners for marker cluster clicks
62
+ markers.on('clusterclick', function(e){
63
+ hideSidebar();
65
64
 
66
- //if map is at the lowest zoom level
67
- if (map.getZoom() === Blacklight.mapOptions.maxzoom){
65
+ //if map is at the lowest zoom level
66
+ if (map.getZoom() === options.maxzoom){
68
67
 
69
- var placenames = generatePlacenamesObject(e.layer._markers);
70
-
68
+ var placenames = generatePlacenamesObject(e.layer.getAllChildMarkers());
69
+ setupSidebarDisplay(e,placenames);
70
+ }
71
+ });
72
+
73
+ //Add click listener to map
74
+ map.on('click drag', hideSidebar);
75
+
76
+ });
71
77
 
78
+ function setupSidebarDisplay(e, placenames){
79
+ hideSidebar();
72
80
  offsetMap(e);
81
+ if (currentLayer !== e.layer || !("layer" in e)){
82
+ // Update sidebar div with new html
83
+ $('#' + options.sidebar).html(buildList(placenames));
73
84
 
74
- //Update sidebar div with new html
75
- $('#blacklight-map-sidebar').html(buildList(placenames));
85
+ // Scroll sidebar div to top
86
+ $('#' + options.sidebar).scrollTop(0);
87
+ currentLayer = e.layer;
88
+ }
76
89
 
77
- //Show the sidebar!
90
+ // Show the sidebar
78
91
  sidebar.show();
92
+
79
93
  }
80
- });
81
94
 
82
- //Add click listener to map
83
- map.on('click', function(e){
95
+ // Hides sidebar if it is visible
96
+ function hideSidebar(){
97
+ if (sidebar.isVisible()){
98
+ sidebar.hide();
99
+ }
100
+ }
84
101
 
85
- //hide the sidebar if it is visible
86
- if (sidebar.isVisible()){
87
- sidebar.hide();
102
+ // Build the list
103
+ function buildList(placenames){
104
+ var html = "";
105
+ $.each(placenames, function(i,val){
106
+ html += "<h2>" + i + "</h2>";
107
+ html += "<ul class='sidebar-list'>";
108
+ $.each(val, function(j, val2){
109
+ html += val2;
110
+ });
111
+ html += "</ul>";
112
+ });
113
+ return html;
88
114
  }
89
- });
90
115
 
91
- //drag listener on map
92
- map.on('drag', function(e){
116
+ // Generates placenames object
117
+ function generatePlacenamesObject(markers){
118
+ var placenames = {};
119
+ $.each(markers, function(i,val){
120
+ if (!(val.defaultOptions.title in placenames)){
121
+ placenames[val.defaultOptions.title] = [];
122
+ }
123
+ placenames[val.defaultOptions.title].push(val.feature.properties.html);
124
+ });
125
+ return placenames;
126
+ }
93
127
 
94
- //hide the sidebar if it is visible
95
- if (sidebar.isVisible()){
96
- sidebar.hide();
128
+ // Move the map so that it centers the clicked cluster TODO account for various size screens
129
+ function offsetMap(e){
130
+ var mapWidth = $('#' + options.id).width();
131
+ var mapHeight = $('#' + options.id).height();
132
+ if (!e.latlng.equals(map.getCenter())){
133
+ map.panBy([(e.originalEvent.layerX - (mapWidth/4)), (e.originalEvent.layerY - (mapHeight/2))]);
134
+ }else{
135
+ map.panBy([(mapWidth/4), 0]);
136
+ }
97
137
  }
98
- });
99
-
100
- });
101
-
102
- Blacklight.mapOptions = {
103
- tileurl : 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
104
- mapattribution : 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'
105
- };
106
-
107
- function buildList(placenames){
108
- var html = "";
109
- $.each(placenames, function(i,val){
110
- html += "<h2>" + i + "</h2>";
111
- html += "<ul class='sidebar-list'>";
112
- $.each(val, function(j, val2){
113
- html += val2;
114
- });
115
- html += "</ul>";
116
- });
117
- return html;
118
- }
119
-
120
- // Generates placenames object
121
- function generatePlacenamesObject(markers){
122
- var placenames = {};
123
- $.each(markers, function(i,val){
124
- if (!(val.feature.properties.placename in placenames)){
125
- placenames[val.feature.properties.placename] = [];
138
+
139
+ };
140
+
141
+ function getMapTitle(type, featureName){
142
+ switch(type){
143
+ case 'bbox':
144
+ return 'Results';
145
+ case 'placename_coord':
146
+ return featureName;
147
+ default:
148
+ return 'Results';
126
149
  }
127
- placenames[val.feature.properties.placename].push(val.feature.properties.html);
128
- });
129
- return placenames;
130
- }
131
-
132
- // Move the map so that it centers the clicked cluster TODO account for various size screens
133
- function offsetMap(e){
134
- mapWidth = $('#blacklight-map').width();
135
- mapHeight = $('#blacklight-map').height();
136
- if (!e.latlng.equals(map.getCenter())){
137
- map.panBy([(e.originalEvent.layerX - (mapWidth/4)), (e.originalEvent.layerY - (mapHeight/2))]);
138
- }else{
139
- map.panBy([(mapWidth/4), 0]);
140
150
  }
141
- }
151
+
152
+ }( jQuery ));
@@ -1,36 +1,26 @@
1
+ # Helper methods used for Blacklight Maps
1
2
  module BlacklightMapsHelper
2
-
3
- def show_map_div
4
- data_attributes = {
5
- :maxzoom => blacklight_config.view.maps.maxzoom,
6
- :tileurl => blacklight_config.view.maps.tileurl
7
-
8
- }
3
+ # @param [String] id the html id
4
+ # @param [Hash] tag_options options to put on the tag
5
+ def blacklight_map_tag id, tag_options = {}, &block
6
+ default_data = {
7
+ maxzoom: blacklight_config.view.maps.maxzoom,
8
+ tileurl: blacklight_config.view.maps.tileurl,
9
+ type: blacklight_config.view.maps.type,
10
+ mapattribution: blacklight_config.view.maps.mapattribution
11
+ }
9
12
 
10
- content_tag(:div, "", id: "blacklight-map",
11
- data: data_attributes
12
- )
13
+ options = {id: id, data: default_data}.deep_merge(tag_options)
14
+ if block_given?
15
+ content_tag(:div, options, &block)
16
+ else
17
+ tag(:div, options)
13
18
  end
19
+ end
14
20
 
15
- def serialize_geojson
16
- geojson_docs = {type: "FeatureCollection", features: []}
17
- @response.docs.each_with_index do |doc, counter|
18
- if doc[blacklight_config.view.maps.placename_coord_field]
19
- doc[blacklight_config.view.maps.placename_coord_field].each do |loc|
20
- values = loc.split('|')
21
- feature = {type: "Feature", geometry: {type: "Point",
22
- coordinates: [values[2].to_f, values[1].to_f]},
23
- properties: {placename: values[0],
24
- html: render_leaflet_sidebar_partial(doc)}}
25
- geojson_docs[:features].push feature
26
- end
27
- end
28
- end
29
- return geojson_docs.to_json
30
- end
31
-
32
- def render_leaflet_sidebar_partial(doc)
33
- render partial: 'catalog/index_maps', locals: {document: SolrDocument.new(doc)}
34
- end
35
-
36
- end
21
+ def serialize_geojson
22
+ export = BlacklightMaps::GeojsonExport.new(controller,
23
+ @response.docs)
24
+ export.to_geojson
25
+ end
26
+ end
@@ -1,6 +1,6 @@
1
1
  <% # container for all documents in map view -%>
2
2
  <div id="documents" class="map">
3
- <%= show_map_div() %>
3
+ <%= blacklight_map_tag('blacklight-map') %>
4
4
  <div id="blacklight-map-sidebar"></div>
5
- <%= javascript_tag "var geojson_docs = #{serialize_geojson}" %>
6
- </div>
5
+ <%= javascript_tag "$('#blacklight-map').blacklight_leaflet_map(#{serialize_geojson});" %>
6
+ </div>