blacklight-maps 0.5.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +99 -0
  4. data/.solr_wrapper.yml +7 -0
  5. data/.travis.yml +19 -16
  6. data/Gemfile +40 -7
  7. data/README.md +13 -12
  8. data/Rakefile +35 -32
  9. data/app/assets/images/blacklight/maps.svg +1 -0
  10. data/app/assets/javascripts/blacklight-maps.js +1 -4
  11. data/app/assets/javascripts/blacklight-maps/blacklight-maps-browse.js +7 -8
  12. data/app/assets/stylesheets/blacklight_maps/blacklight-maps.scss +1 -2
  13. data/app/assets/stylesheets/blacklight_maps/default.scss +7 -10
  14. data/app/helpers/blacklight/blacklight_maps_helper_behavior.rb +81 -86
  15. data/app/helpers/blacklight_maps_helper.rb +2 -0
  16. data/app/views/catalog/_show_maplet_default.html.erb +8 -9
  17. data/app/views/catalog/map.html.erb +2 -2
  18. data/blacklight-maps.gemspec +27 -26
  19. data/config/locales/blacklight-maps-zh.yml +7 -7
  20. data/config/locales/blacklight-maps.ar.yml +21 -0
  21. data/config/locales/blacklight-maps.de.yml +21 -0
  22. data/config/locales/blacklight-maps.en.yml +1 -1
  23. data/config/locales/blacklight-maps.es.yml +21 -0
  24. data/config/locales/blacklight-maps.fr.yml +8 -8
  25. data/config/locales/blacklight-maps.hu.yml +21 -0
  26. data/config/locales/blacklight-maps.it.yml +8 -8
  27. data/config/locales/blacklight-maps.nl.yml +21 -0
  28. data/config/locales/blacklight-maps.pt-BR.yml +21 -0
  29. data/config/locales/blacklight-maps.sq.yml +21 -0
  30. data/config/routes.rb +3 -2
  31. data/lib/blacklight/maps.rb +8 -2
  32. data/lib/blacklight/maps/controller.rb +27 -0
  33. data/lib/blacklight/maps/engine.rb +12 -13
  34. data/lib/blacklight/maps/export.rb +112 -93
  35. data/lib/blacklight/maps/geometry.rb +30 -18
  36. data/lib/blacklight/maps/maps_search_builder.rb +4 -3
  37. data/lib/blacklight/maps/render_constraints_override.rb +63 -29
  38. data/lib/blacklight/maps/version.rb +3 -1
  39. data/lib/generators/blacklight_maps/install_generator.rb +38 -31
  40. data/lib/generators/blacklight_maps/templates/search_history_controller.rb +2 -0
  41. data/{solr_conf → lib/generators/blacklight_maps/templates/solr}/conf/schema.xml +0 -0
  42. data/{solr_conf → lib/generators/blacklight_maps/templates/solr}/conf/solrconfig.xml +0 -0
  43. data/lib/railties/blacklight_maps.rake +10 -7
  44. data/spec/controllers/catalog_controller_spec.rb +20 -10
  45. data/spec/fixtures/sample_solr_documents.yml +909 -906
  46. data/spec/helpers/blacklight_maps_helper_spec.rb +60 -108
  47. data/spec/lib/blacklight/maps/export_spec.rb +109 -143
  48. data/spec/lib/blacklight/maps/geometry_spec.rb +34 -21
  49. data/spec/lib/blacklight/maps/maps_search_builder_spec.rb +17 -21
  50. data/spec/lib/blacklight/maps/render_constraints_override_spec.rb +42 -69
  51. data/spec/spec_helper.rb +19 -21
  52. data/spec/system/index_view_spec.rb +127 -0
  53. data/spec/system/initial_view_spec.rb +28 -0
  54. data/spec/system/map_view_spec.rb +50 -0
  55. data/spec/system/show_view_maplet_spec.rb +78 -0
  56. data/spec/test_app_templates/lib/generators/test_app_generator.rb +6 -21
  57. data/vendor/assets/images/layers-2x.png +0 -0
  58. data/vendor/assets/images/layers.png +0 -0
  59. data/vendor/assets/images/marker-icon-2x.png +0 -0
  60. data/vendor/assets/images/marker-icon.png +0 -0
  61. data/vendor/assets/images/marker-shadow.png +0 -0
  62. data/vendor/assets/javascripts/leaflet.js.erb +13922 -0
  63. data/vendor/assets/javascripts/leaflet.markercluster.js +3 -0
  64. data/vendor/assets/stylesheets/MarkerCluster.Default.css +60 -0
  65. data/vendor/assets/stylesheets/MarkerCluster.css +14 -0
  66. data/vendor/assets/stylesheets/leaflet.css +635 -0
  67. metadata +86 -91
  68. data/config/jetty.yml +0 -7
  69. data/lib/blacklight/maps/controller_override.rb +0 -20
  70. data/lib/generators/blacklight_maps/templates/saved_searches_controller.rb +0 -5
  71. data/spec/features/initial_view_spec.rb +0 -21
  72. data/spec/features/maps_spec.rb +0 -202
  73. data/spec/features/show_view_maplet_spec.rb +0 -93
  74. data/spec/test_app_templates/Gemfile.extra +0 -5
@@ -0,0 +1,21 @@
1
+ nl:
2
+ blacklight:
3
+
4
+ maps:
5
+ interactions:
6
+ bbox_search: 'Bekijk items die kruisen met dit selectiekader'
7
+ placename_search: 'Bekijk items van deze locatie'
8
+ item: 'item'
9
+ point_search: 'Bekijk items van deze locatie'
10
+ search_ctrl_cue: 'Zoek naar alle items in het huidige kaartvenster'
11
+ title: 'Kaart'
12
+ leader_html: "Klik op een markering om naar items op die locatie te zoeken of gebruik de 🔍 knop om te zoeken naar alle items in het huidige kaartvenster."
13
+
14
+ search:
15
+ filters:
16
+ coordinates:
17
+ bbox: 'Begrenzende doos'
18
+ point: 'Coördinaten'
19
+ view:
20
+ maps: 'Kaart'
21
+
@@ -0,0 +1,21 @@
1
+ pt-BR:
2
+ blacklight:
3
+
4
+ maps:
5
+ interactions:
6
+ bbox_search: 'Exibir itens que se cruzam com esta caixa delimitadora'
7
+ placename_search: 'Ver itens deste local'
8
+ item: 'item'
9
+ point_search: 'Ver itens deste local'
10
+ search_ctrl_cue: 'Pesquise todos os itens na janela atual do mapa'
11
+ title: 'Mapa'
12
+ leader_html: "Clique em um marcador para procurar itens desse local ou use o 🔍 para procurar todos os itens na janela atual do mapa."
13
+
14
+ search:
15
+ filters:
16
+ coordinates:
17
+ bbox: 'Caixa delimitadora'
18
+ point: 'Coordenadas'
19
+ view:
20
+ maps: 'Mapa'
21
+
@@ -0,0 +1,21 @@
1
+ sq:
2
+ blacklight:
3
+
4
+ maps:
5
+ interactions:
6
+ bbox_search: 'Shikoni artikujt që kryqëzohen me këtë kuti kufizuese'
7
+ placename_search: 'Shikoni artikujt nga ky vendndodhje'
8
+ item: 'artikull'
9
+ point_search: 'Shikoni artikujt nga ky vendndodhje'
10
+ search_ctrl_cue: 'Kërkoni për të gjithë artikujt brenda dritares aktuale të hartës'
11
+ title: 'Hartë'
12
+ leader_html: "Klikoni në një shënues për të kërkuar artikuj nga ai vend, ose përdorni 🔍 butoni për të kërkuar të gjitha artikujt brenda dritares aktuale të hartës."
13
+
14
+ search:
15
+ filters:
16
+ coordinates:
17
+ bbox: 'Kuti kufizuese'
18
+ point: 'Koordinon'
19
+ view:
20
+ maps: 'Hartë'
21
+
@@ -1,4 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Rails.application.routes.draw do
2
- get 'map', :to => 'catalog#map', :as => 'map'
4
+ get 'map', to: 'catalog#map', as: 'map'
3
5
  end
4
-
@@ -1,13 +1,19 @@
1
- require "blacklight/maps/version"
1
+ # frozen_string_literal: true
2
+
3
+ require 'blacklight/maps/version'
2
4
 
3
5
  module Blacklight
4
6
  module Maps
5
- require 'blacklight/maps/controller_override'
7
+ require 'blacklight/maps/controller'
6
8
  require 'blacklight/maps/render_constraints_override'
7
9
  require 'blacklight/maps/engine'
8
10
  require 'blacklight/maps/export'
9
11
  require 'blacklight/maps/geometry'
10
12
  require 'blacklight/maps/maps_search_builder'
11
13
 
14
+ # returns the full path to the blacklight plugin installation
15
+ def self.root
16
+ @root ||= File.expand_path(File.dirname(File.dirname(File.dirname(__FILE__))))
17
+ end
12
18
  end
13
19
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BlacklightMaps
4
+ module Controller
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ helper BlacklightMaps::RenderConstraintsOverride
9
+ end
10
+
11
+ def map
12
+ (@response, @document_list) = search_service.search_results
13
+ params[:view] = 'maps'
14
+ respond_to do |format|
15
+ format.html
16
+ end
17
+ end
18
+
19
+ ##
20
+ # BlacklightMaps override: update to look for spatial query params
21
+ # Check if any search parameters have been set
22
+ # @return [Boolean]
23
+ def has_search_parameters?
24
+ params[:coordinates].present? || super
25
+ end
26
+ end
27
+ end
@@ -1,29 +1,28 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'blacklight'
2
- require 'leaflet-rails'
3
- require 'leaflet-markercluster-rails'
4
4
 
5
5
  module Blacklight
6
6
  module Maps
7
7
  class Engine < Rails::Engine
8
-
9
8
  # Set some default configurations
10
- initializer 'blacklight-maps.default_config' do |app|
11
- Blacklight::Configuration.default_values[:view].maps.geojson_field = "geojson"
12
- Blacklight::Configuration.default_values[:view].maps.placename_property = "placename"
13
- Blacklight::Configuration.default_values[:view].maps.coordinates_field = "coordinates"
14
- Blacklight::Configuration.default_values[:view].maps.search_mode = "placename" # or 'coordinates'
9
+ initializer 'blacklight-maps.default_config' do |_app|
10
+ Blacklight::Configuration.default_values[:view].maps.geojson_field = 'geojson_ssim'
11
+ Blacklight::Configuration.default_values[:view].maps.placename_property = 'placename'
12
+ Blacklight::Configuration.default_values[:view].maps.coordinates_field = 'coordinates_srpt'
13
+ Blacklight::Configuration.default_values[:view].maps.search_mode = 'placename' # or 'coordinates'
15
14
  Blacklight::Configuration.default_values[:view].maps.spatial_query_dist = 0.5
16
- Blacklight::Configuration.default_values[:view].maps.placename_field = "placename_field"
17
- Blacklight::Configuration.default_values[:view].maps.coordinates_facet_field = "coordinates_facet_field"
18
- Blacklight::Configuration.default_values[:view].maps.facet_mode = "geojson" # or 'coordinates'
19
- Blacklight::Configuration.default_values[:view].maps.tileurl = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
15
+ Blacklight::Configuration.default_values[:view].maps.placename_field = 'subject_geo_ssim'
16
+ Blacklight::Configuration.default_values[:view].maps.coordinates_facet_field = 'coordinates_ssim'
17
+ Blacklight::Configuration.default_values[:view].maps.facet_mode = 'geojson' # or 'coordinates'
18
+ Blacklight::Configuration.default_values[:view].maps.tileurl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
20
19
  Blacklight::Configuration.default_values[:view].maps.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>'
21
20
  Blacklight::Configuration.default_values[:view].maps.maxzoom = 18
22
21
  Blacklight::Configuration.default_values[:view].maps.show_initial_zoom = 5
23
22
  end
24
23
 
25
24
  # Add our helpers
26
- initializer 'blacklight-maps.helpers' do |app|
25
+ initializer 'blacklight-maps.helpers' do |_app|
27
26
  ActionView::Base.send :include, BlacklightMapsHelper
28
27
  end
29
28
 
@@ -1,5 +1,6 @@
1
- module BlacklightMaps
1
+ # frozen_string_literal: true
2
2
 
3
+ module BlacklightMaps
3
4
  # This class provides the ability to export a response document to GeoJSON.
4
5
  # The export is formated as a GeoJSON FeatureCollection, where the features
5
6
  # consist of an array of Point features. For more on the GeoJSON
@@ -8,146 +9,164 @@ module BlacklightMaps
8
9
  class GeojsonExport
9
10
  include BlacklightMaps
10
11
 
11
- # controller is a Blacklight CatalogController object passed by a helper
12
- # action is the controller action
13
- # response_docs is passed by a helper, and is either:
12
+ # @param controller [CatalogController]
13
+ # @param action [Symbol] the controller action
14
+ # @param response_docs [Array || SolrDocument] either:
14
15
  # - index view, map view: an array of facet values
15
16
  # - show view: the document object
16
- # options is an optional hash of possible configuration options
17
- def initialize(controller, action, response_docs, options={})
17
+ # @param options [Hash] optional hash of configuration options
18
+ def initialize(controller, action, response_docs, options = {})
18
19
  @controller = controller
19
20
  @action = action
20
21
  @response_docs = response_docs
21
22
  @options = options
23
+ @features = []
22
24
  end
23
25
 
24
- # build the GeoJSON FeatureCollection
26
+ # builds the GeoJSON FeatureCollection
25
27
  def to_geojson
26
- geojson_docs = { type: 'FeatureCollection',
27
- features: build_geojson_features }
28
- geojson_docs.to_json
28
+ { type: 'FeatureCollection', features: build_geojson_features }.to_json
29
29
  end
30
30
 
31
31
  private
32
32
 
33
- def blacklight_maps_config
33
+ def maps_config
34
34
  @controller.blacklight_config.view.maps
35
35
  end
36
36
 
37
37
  def geojson_field
38
- blacklight_maps_config.geojson_field
38
+ maps_config.geojson_field
39
39
  end
40
40
 
41
41
  def coordinates_field
42
- blacklight_maps_config.coordinates_field
42
+ maps_config.coordinates_field
43
43
  end
44
44
 
45
- def search_mode
46
- blacklight_maps_config.search_mode
45
+ def build_geojson_features
46
+ if @action == :index || @action == :map
47
+ build_index_features
48
+ elsif @action == :show
49
+ build_show_features
50
+ end
51
+ @features
47
52
  end
48
53
 
49
- def facet_mode
50
- blacklight_maps_config.facet_mode
54
+ # build GeoJSON features array for index and map views
55
+ def build_index_features
56
+ @response_docs.each do |geofacet|
57
+ @features << if maps_config.facet_mode == 'coordinates'
58
+ build_feature_from_coords(geofacet.value, geofacet.hits)
59
+ else
60
+ build_feature_from_geojson(geofacet.value, geofacet.hits)
61
+ end
62
+ end
51
63
  end
52
64
 
53
- def placename_property
54
- blacklight_maps_config.placename_property
65
+ # build GeoJSON features array for show view
66
+ def build_show_features
67
+ doc = @response_docs
68
+ return unless doc[geojson_field] || doc[coordinates_field]
69
+
70
+ if doc[geojson_field]
71
+ build_features_from_geojson(doc[geojson_field])
72
+ elsif doc[coordinates_field]
73
+ build_features_from_coords(doc[coordinates_field])
74
+ end
55
75
  end
56
76
 
57
- # build GeoJSON features array
58
- # determine how to build GeoJSON feature based on config and controller#action
59
- def build_geojson_features
60
- features = []
61
- case @action
62
- when "index", "map"
63
- @response_docs.each do |geofacet|
64
- if facet_mode == "coordinates"
65
- features.push(build_feature_from_coords(geofacet.value, geofacet.hits))
66
- else
67
- features.push(build_feature_from_geojson(geofacet.value, geofacet.hits))
68
- end
69
- end
70
- when "show"
71
- doc = @response_docs
72
- return unless doc[geojson_field] || doc[coordinates_field]
73
- if doc[geojson_field]
74
- doc[geojson_field].uniq.each do |loc|
75
- features.push(build_feature_from_geojson(loc))
76
- end
77
- elsif doc[coordinates_field]
78
- doc[coordinates_field].uniq.each do |coords|
79
- features.push(build_feature_from_coords(coords))
80
- end
81
- end
77
+ def build_features_from_geojson(geojson_field_values)
78
+ return unless geojson_field_values
79
+
80
+ geojson_field_values.uniq.each do |loc|
81
+ @features << build_feature_from_geojson(loc)
82
82
  end
83
- features
84
83
  end
85
84
 
86
- # build blacklight-maps GeoJSON feature from GeoJSON-formatted data
85
+ def build_features_from_coords(coordinates_field_values)
86
+ return unless coordinates_field_values
87
+
88
+ coordinates_field_values.uniq.each do |coords|
89
+ @features << build_feature_from_coords(coords)
90
+ end
91
+ end
92
+
93
+ # build GeoJSON feature from incoming GeoJSON data
87
94
  # turn bboxes into points for index view so we don't get weird mix of boxes and markers
95
+ # @param loc [Hash]
96
+ # @param hits [Integer]
88
97
  def build_feature_from_geojson(loc, hits = nil)
89
- geojson_hash = JSON.parse(loc).deep_symbolize_keys
90
- if @action != "show" && geojson_hash[:bbox]
91
- geojson_hash[:geometry][:coordinates] = Geometry::Point.new(Geometry::BoundingBox.new(geojson_hash[:bbox]).find_center).normalize_for_search
92
- geojson_hash[:geometry][:type] = "Point"
93
- geojson_hash.delete(:bbox)
98
+ geojson = JSON.parse(loc).deep_symbolize_keys
99
+ if @action != :show && geojson[:bbox]
100
+ bbox = Geometry::BoundingBox.new(geojson[:bbox])
101
+ geojson[:geometry][:coordinates] = Geometry::Point.new(bbox.find_center).normalize_for_search
102
+ geojson[:geometry][:type] = 'Point'
103
+ geojson.delete(:bbox)
94
104
  end
95
- geojson_hash[:properties] ||= {}
96
- geojson_hash[:properties][:hits] = hits.to_i if hits
97
- geojson_hash[:properties][:popup] = render_leaflet_popup_content(geojson_hash, hits)
98
- geojson_hash
105
+ geojson[:properties] ||= {}
106
+ geojson[:properties][:hits] = hits.to_i if hits
107
+ geojson[:properties][:popup] = render_leaflet_popup_content(geojson, hits)
108
+ geojson
99
109
  end
100
110
 
101
- # build blacklight-maps GeoJSON feature from coordinate data
111
+ # build GeoJSON feature from incoming raw coordinate data
102
112
  # turn bboxes into points for index view so we don't get weird mix of boxes and markers
113
+ # @param coords [String]
114
+ # @param hits [Integer]
103
115
  def build_feature_from_coords(coords, hits = nil)
104
- geojson_hash = {type: "Feature", geometry: {}, properties: {}}
105
- if coords.scan(/[\s]/).length == 3 # bbox
106
- if @action != "show"
107
- geojson_hash[:geometry][:type] = "Point"
108
- geojson_hash[:geometry][:coordinates] = Geometry::Point.new(Geometry::BoundingBox.from_lon_lat_string(coords).find_center).normalize_for_search
109
- else
110
- coords_array = coords.split(' ').map { |v| v.to_f }
111
- geojson_hash[:bbox] = coords_array
112
- geojson_hash[:geometry][:type] = "Polygon"
113
- geojson_hash[:geometry][:coordinates] = [[[coords_array[0],coords_array[1]],
114
- [coords_array[2],coords_array[1]],
115
- [coords_array[2],coords_array[3]],
116
- [coords_array[0],coords_array[3]],
117
- [coords_array[0],coords_array[1]]]]
118
- end
119
- elsif coords.match(/^[-]?[\d]*[\.]?[\d]*[ ,][-]?[\d]*[\.]?[\d]*$/) # point
120
- geojson_hash[:geometry][:type] = "Point"
121
- if coords.match(/,/)
122
- coords_array = coords.split(',').reverse
123
- else
124
- coords_array = coords.split(' ')
125
- end
126
- geojson_hash[:geometry][:coordinates] = coords_array.map { |v| v.to_f }
116
+ geojson = { type: 'Feature', properties: {} }
117
+ if coords =~ /ENVELOPE/ # bbox
118
+ geojson.merge!(build_bbox_feature_from_coords(coords))
119
+ elsif coords =~ /^[-]?[\d]*[\.]?[\d]*[ ,][-]?[\d]*[\.]?[\d]*$/ # point
120
+ geojson[:geometry] = build_point_geometry(coords)
127
121
  else
128
122
  Rails.logger.error("This coordinate format is not yet supported: '#{coords}'")
129
123
  end
130
- geojson_hash[:properties] = { popup: render_leaflet_popup_content(geojson_hash, hits) } if geojson_hash[:geometry][:coordinates]
131
- geojson_hash[:properties][:hits] = hits.to_i if hits
132
- geojson_hash
124
+ geojson[:properties] = { popup: render_leaflet_popup_content(geojson, hits) } if geojson[:geometry][:coordinates]
125
+ geojson[:properties][:hits] = hits.to_i if hits
126
+ geojson
127
+ end
128
+
129
+ # @param coords [String]
130
+ def build_bbox_feature_from_coords(coords)
131
+ geojson = { geometry: {} }
132
+ bbox = Geometry::BoundingBox.from_wkt_envelope(coords)
133
+ if @action != :show
134
+ geojson[:geometry][:type] = 'Point'
135
+ geojson[:geometry][:coordinates] = Geometry::Point.new(bbox.find_center).normalize_for_search
136
+ else
137
+ coords_array = bbox.to_a
138
+ geojson[:bbox] = coords_array
139
+ geojson[:geometry][:type] = 'Polygon'
140
+ geojson[:geometry][:coordinates] = bbox.geojson_geometry_array
141
+ end
142
+ geojson
143
+ end
144
+
145
+ # @param coords [String]
146
+ def build_point_geometry(coords)
147
+ geometry = { type: 'Point' }
148
+ coords_array = coords =~ /,/ ? coords.split(',').reverse : coords.split(' ')
149
+ geometry[:coordinates] = coords_array.map(&:to_f)
150
+ geometry
133
151
  end
134
152
 
135
- # Render to string the partial for each individual doc.
153
+ # Render to string the partial for each individual feature.
136
154
  # For placename searching, render catalog/map_placename_search partial,
137
- # full geojson hash is passed to the partial for easier local customization
155
+ # pass the full geojson hash to the partial for easier local customization
138
156
  # For coordinate searches (or features with only coordinate data),
139
157
  # render catalog/map_coordinate_search partial
140
- def render_leaflet_popup_content(geojson_hash, hits=nil)
141
- if search_mode == 'placename' && geojson_hash[:properties][placename_property.to_sym]
142
- @controller.render_to_string partial: 'catalog/map_placename_search',
143
- locals: { geojson_hash: geojson_hash, hits: hits }
158
+ # @param geojson [Hash]
159
+ # @param hits [Integer]
160
+ def render_leaflet_popup_content(geojson, hits = nil)
161
+ if maps_config.search_mode == 'placename' &&
162
+ geojson[:properties][maps_config.placename_property.to_sym]
163
+ partial = 'catalog/map_placename_search'
164
+ locals = { geojson_hash: geojson, hits: hits }
144
165
  else
145
- @controller.render_to_string partial: 'catalog/map_spatial_search',
146
- locals: { coordinates: geojson_hash[:bbox].presence || geojson_hash[:geometry][:coordinates],
147
- hits: hits }
166
+ partial = 'catalog/map_spatial_search'
167
+ locals = { coordinates: geojson[:bbox].presence || geojson[:geometry][:coordinates], hits: hits }
148
168
  end
169
+ @controller.render_to_string(partial: partial, locals: locals)
149
170
  end
150
-
151
171
  end
152
-
153
172
  end
@@ -1,15 +1,14 @@
1
- module BlacklightMaps
1
+ # frozen_string_literal: true
2
2
 
3
+ module BlacklightMaps
3
4
  # Parent class of geospatial objects used in BlacklightMaps
4
5
  class Geometry
5
-
6
6
  # This class contains Bounding Box objects and methods for interacting with
7
7
  # them.
8
8
  class BoundingBox
9
-
10
9
  # points is an array containing longitude and latitude values which
11
10
  # relate to the southwest and northeast points of a bounding box
12
- # [west, south, east, north] ([swlng, swlat, nelng, nelat]).
11
+ # [west, south, east, north] ([minX, minY, maxX, maxY]).
13
12
  def initialize(points)
14
13
  @west = points[0].to_f
15
14
  @south = points[1].to_f
@@ -17,15 +16,24 @@ module BlacklightMaps
17
16
  @north = points[3].to_f
18
17
  end
19
18
 
19
+ def geojson_geometry_array
20
+ [
21
+ [
22
+ [@west, @south],
23
+ [@east, @south],
24
+ [@east, @north],
25
+ [@west, @north],
26
+ [@west, @south]
27
+ ]
28
+ ]
29
+ end
30
+
20
31
  # Returns an array [lng, lat] which is the centerpoint of a BoundingBox.
21
32
  def find_center
22
33
  center = []
23
34
  center[0] = (@west + @east) / 2
24
35
  center[1] = (@south + @north) / 2
25
-
26
- # Handle bounding boxes that cross the dateline
27
- center[0] -= 180 if @west > @east
28
-
36
+ center[0] -= 180 if @west > @east # handle bboxes that cross the dateline
29
37
  center
30
38
  end
31
39
 
@@ -34,11 +42,21 @@ module BlacklightMaps
34
42
  def self.from_lon_lat_string(points)
35
43
  new(points.split(' '))
36
44
  end
45
+
46
+ # Creates a new bounding box from from a Solr WKT Envelope string
47
+ # "ENVELOPE(34.26, 35.89, 33.33, 29.47)" (minX, maxX, maxY, minY)
48
+ def self.from_wkt_envelope(envelope)
49
+ coords = envelope.gsub(/[[A-Z]\(\)]/, '')&.split(', ')
50
+ new([coords[0], coords[3], coords[1], coords[2]])
51
+ end
52
+
53
+ def to_a
54
+ [@west, @south, @east, @north]
55
+ end
37
56
  end
38
57
 
39
58
  # This class contains Point objects and methods for working with them
40
59
  class Point
41
-
42
60
  # points is an array corresponding to the longitude and latitude values
43
61
  # [long, lat]
44
62
  def initialize(points)
@@ -49,13 +67,9 @@ module BlacklightMaps
49
67
  # returns a string that can be used as the value of solr_parameters[:pt]
50
68
  # normalizes any long values >180 or <-180
51
69
  def normalize_for_search
52
- case
53
- when @long > 180
54
- @long -= 360
55
- when @long < -180
56
- @long += 360
57
- end
58
- [@long,@lat]
70
+ @long -= 360 if @long > 180
71
+ @long += 360 if @long < -180
72
+ [@long, @lat]
59
73
  end
60
74
 
61
75
  # Creates a new point from from a coordinate string
@@ -63,8 +77,6 @@ module BlacklightMaps
63
77
  def self.from_lat_lon_string(points)
64
78
  new(points.split(',').reverse)
65
79
  end
66
-
67
80
  end
68
-
69
81
  end
70
82
  end