blacklight-maps 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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>