class BlacklightMaps::GeojsonExport

This class provides the ability to export a response document to GeoJSON. The export is formated as a GeoJSON FeatureCollection, where the features consist of an array of Point features. For more on the GeoJSON specification see geojson.org/geojson-spec.html.

Public Class Methods

new(controller, action, response_docs, options = {}) click to toggle source

@param controller [CatalogController] @param action [Symbol] the controller action @param response_docs [Array || SolrDocument] either:

- index view, map view: an array of facet values
- show view: the document object

@param options [Hash] optional hash of configuration options

# File lib/blacklight/maps/export.rb, line 18
def initialize(controller, action, response_docs, options = {})
  @controller = controller
  @action = action
  @response_docs = response_docs
  @options = options
  @features = []
end

Public Instance Methods

to_geojson() click to toggle source

builds the GeoJSON FeatureCollection

# File lib/blacklight/maps/export.rb, line 27
def to_geojson
  { type: 'FeatureCollection', features: build_geojson_features }.to_json
end

Private Instance Methods

build_bbox_feature_from_coords(coords) click to toggle source

@param coords [String]

# File lib/blacklight/maps/export.rb, line 130
def build_bbox_feature_from_coords(coords)
  geojson = { geometry: {} }
  bbox = Geometry::BoundingBox.from_wkt_envelope(coords)
  if @action != :show
    geojson[:geometry][:type] = 'Point'
    geojson[:geometry][:coordinates] = Geometry::Point.new(bbox.find_center).normalize_for_search
  else
    coords_array = bbox.to_a
    geojson[:bbox] = coords_array
    geojson[:geometry][:type] = 'Polygon'
    geojson[:geometry][:coordinates] = bbox.geojson_geometry_array
  end
  geojson
end
build_feature_from_coords(coords, hits = nil) click to toggle source

build GeoJSON feature from incoming raw coordinate data turn bboxes into points for index view so we don't get weird mix of boxes and markers @param coords [String] @param hits [Integer]

# File lib/blacklight/maps/export.rb, line 115
def build_feature_from_coords(coords, hits = nil)
  geojson = { type: 'Feature', properties: {} }
  if coords =~ /ENVELOPE/ # bbox
    geojson.merge!(build_bbox_feature_from_coords(coords))
  elsif coords =~ /^[-]?[\d]*[\.]?[\d]*[ ,][-]?[\d]*[\.]?[\d]*$/ # point
    geojson[:geometry] = build_point_geometry(coords)
  else
    Rails.logger.error("This coordinate format is not yet supported: '#{coords}'")
  end
  geojson[:properties] = { popup: render_leaflet_popup_content(geojson, hits) } if geojson[:geometry][:coordinates]
  geojson[:properties][:hits] = hits.to_i if hits
  geojson
end
build_feature_from_geojson(loc, hits = nil) click to toggle source

build GeoJSON feature from incoming GeoJSON data turn bboxes into points for index view so we don't get weird mix of boxes and markers @param loc [Hash] @param hits [Integer]

# File lib/blacklight/maps/export.rb, line 97
def build_feature_from_geojson(loc, hits = nil)
  geojson = JSON.parse(loc).deep_symbolize_keys
  if @action != :show && geojson[:bbox]
    bbox = Geometry::BoundingBox.new(geojson[:bbox])
    geojson[:geometry][:coordinates] = Geometry::Point.new(bbox.find_center).normalize_for_search
    geojson[:geometry][:type] = 'Point'
    geojson.delete(:bbox)
  end
  geojson[:properties] ||= {}
  geojson[:properties][:hits] = hits.to_i if hits
  geojson[:properties][:popup] = render_leaflet_popup_content(geojson, hits)
  geojson
end
build_features_from_coords(coordinates_field_values) click to toggle source
# File lib/blacklight/maps/export.rb, line 85
def build_features_from_coords(coordinates_field_values)
  return unless coordinates_field_values

  coordinates_field_values.uniq.each do |coords|
    @features << build_feature_from_coords(coords)
  end
end
build_features_from_geojson(geojson_field_values) click to toggle source
# File lib/blacklight/maps/export.rb, line 77
def build_features_from_geojson(geojson_field_values)
  return unless geojson_field_values

  geojson_field_values.uniq.each do |loc|
    @features << build_feature_from_geojson(loc)
  end
end
build_geojson_features() click to toggle source
# File lib/blacklight/maps/export.rb, line 45
def build_geojson_features
  if @action == :index || @action == :map
    build_index_features
  elsif @action == :show
    build_show_features
  end
  @features
end
build_index_features() click to toggle source

build GeoJSON features array for index and map views

# File lib/blacklight/maps/export.rb, line 55
def build_index_features
  @response_docs.each do |geofacet|
    @features << if maps_config.facet_mode == 'coordinates'
                   build_feature_from_coords(geofacet.value, geofacet.hits)
                 else
                   build_feature_from_geojson(geofacet.value, geofacet.hits)
                 end
  end
end
build_point_geometry(coords) click to toggle source

@param coords [String]

# File lib/blacklight/maps/export.rb, line 146
def build_point_geometry(coords)
  geometry = { type: 'Point' }
  coords_array = coords =~ /,/ ? coords.split(',').reverse : coords.split(' ')
  geometry[:coordinates] = coords_array.map(&:to_f)
  geometry
end
build_show_features() click to toggle source

build GeoJSON features array for show view

# File lib/blacklight/maps/export.rb, line 66
def build_show_features
  doc = @response_docs
  return unless doc[geojson_field] || doc[coordinates_field]

  if doc[geojson_field]
    build_features_from_geojson(doc[geojson_field])
  elsif doc[coordinates_field]
    build_features_from_coords(doc[coordinates_field])
  end
end
coordinates_field() click to toggle source
# File lib/blacklight/maps/export.rb, line 41
def coordinates_field
  maps_config.coordinates_field
end
geojson_field() click to toggle source
# File lib/blacklight/maps/export.rb, line 37
def geojson_field
  maps_config.geojson_field
end
maps_config() click to toggle source
# File lib/blacklight/maps/export.rb, line 33
def maps_config
  @controller.blacklight_config.view.maps
end
render_leaflet_popup_content(geojson, hits = nil) click to toggle source

Render to string the partial for each individual feature. For placename searching, render catalog/map_placename_search partial,

pass the full geojson hash to the partial for easier local customization

For coordinate searches (or features with only coordinate data),

render catalog/map_coordinate_search partial

@param geojson [Hash] @param hits [Integer]

# File lib/blacklight/maps/export.rb, line 160
def render_leaflet_popup_content(geojson, hits = nil)
  if maps_config.search_mode == 'placename' &&
     geojson[:properties][maps_config.placename_property.to_sym]
    partial = 'catalog/map_placename_search'
    locals = { geojson_hash: geojson, hits: hits }
  else
    partial = 'catalog/map_spatial_search'
    locals = { coordinates: geojson[:bbox].presence || geojson[:geometry][:coordinates], hits: hits }
  end
  @controller.render_to_string(partial: partial, locals: locals)
end