Skip to content

Commit

Permalink
Merge pull request #1 from sul-dlss/setup
Browse files Browse the repository at this point in the history
Initial commits of blacklight-maps gem 0.0.1
  • Loading branch information
mejackreed committed Mar 12, 2014
2 parents 3905cf5 + c0607ca commit af2a381
Show file tree
Hide file tree
Showing 25 changed files with 483 additions and 69 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ test/tmp
test/version_tmp
tmp
spec/internal
jetty
jetty
.DS_Store
11 changes: 5 additions & 6 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
source 'https://rubygems.org'

gem 'leaflet-rails'

gem 'leaflet-markercluster-rails', git: 'https://github.com/mejackreed/leaflet-markercluster-rails.git'

gem 'leaflet-sidebar-rails', '0.0.0', git: 'https://github.com/mejackreed/leaflet-sidebar-rails.git'

# Specify your gem's dependencies in blacklight-maps.gemspec
gemspec

gem 'simplecov', require: false
gem 'coveralls', require: false

gem 'engine_cart', git: 'https://github.com/cbeer/engine_cart'


file = File.expand_path("Gemfile", ENV['ENGINE_CART_DESTINATION'] || ENV['RAILS_ROOT'] || File.expand_path("../spec/internal", __FILE__))
if File.exists?(file)
puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
Expand Down
56 changes: 54 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Blacklight::Maps

TODO: Write a gem description
[![Build Status](https://travis-ci.org/sul-dlss/blacklight-maps.png?branch=master)](https://travis-ci.org/sul-dlss/blacklight-maps)

Provides a map view for Blacklight search results.

![Screen shot](docs/map-view.png)
![Screen shot](docs/map-sidebar.png)

## Installation

Expand All @@ -18,7 +23,54 @@ Or install it yourself as:

## Usage

TODO: Write usage instructions here
Blacklight-Maps adds a map view capability for a results set that contains geospatial coordinates (latitude/longitude).

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.

A document requires the following field:
```
placename_coords:
- China|35.86166|104.195397
- Tibet|29.646923|91.117212
- India|20.593684|78.96288
```

Note: We are looking at implementing support for additional fields.

### Configuration

#### Required
Blacklight-Maps expects you to provide:

- a field to map the placename coordinates (`placename_coords` in the example above)

#### Optional

- the maxZoom [property of the map](http://leafletjs.com/reference.html#map-maxzoom)
- a [tileLayer url](http://leafletjs.com/reference.html#tilelayer-l.tilelayer) to change the basemap
- an [attribution string](http://leafletjs.com/reference.html#tilelayer-attribution) to describe the basemap layer


All of these options can easily be configured in `CatalogController.rb` in the `config` block.

```
...
configure_blacklight do |config|
## Default parameters to send to solr for all search-like requests. See also SolrHelper#solr_search_params
config.default_solr_params = {
:qt => 'search',
:rows => 10,
:fl => '*'
}
## Default values
config.view.maps.placename_coords_field = "placename_coords"
config.view.maps.tileurl = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
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>'
...
```


## Contributing

Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,4 @@ namespace :blacklight_maps do
cp("#{f}", 'jetty/solr/blacklight-core/conf/', :verbose => true)
end
end
end
end
7 changes: 6 additions & 1 deletion app/assets/javascripts/blacklight-maps.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// for Blacklight.onLoad:
//= require blacklight/core

//= require leaflet
//= require leaflet.markercluster
//= require L.Control.Sidebar
//= require L.Control.Sidebar

//= require_tree './blacklight-maps'
141 changes: 141 additions & 0 deletions app/assets/javascripts/blacklight-maps/blacklight-maps-browse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
var map, sidebar;

Blacklight.onLoad(function() {

// Stop doing stuff if the map div isn't there
if ($("#blacklight-map").length === 0){
return;
}

// Get the configuration options from the data-attributes
$.extend(Blacklight.mapOptions, $("#blacklight-map").data());

map = L.map('blacklight-map').setView([0,0], 2);
L.tileLayer(Blacklight.mapOptions.tileurl, {
attribution: Blacklight.mapOptions.mapattribution,
maxZoom: Blacklight.mapOptions.maxzoom
}).addTo(map);

// Sets up leaflet-sidebar
sidebar = L.control.sidebar('blacklight-map-sidebar', {
position: 'right',
autoPan: false
});

// Adds leaflet-sidebar control to map (object)
map.addControl(sidebar);

// Create a marker cluster object and set options
markers = new L.MarkerClusterGroup({
showCoverageOnHover: false,
spiderfyOnMaxZoom: false,
singleMarkerMode: true,
animateAddingMarkers: true
});

geoJsonLayer = L.geoJson(geojson_docs, {
onEachFeature: function(feature, layer){
layer.defaultOptions.title = feature.properties.placename;
layer.on('click', function(e){
if (sidebar.isVisible()){
sidebar.hide();
}
var placenames = {};
placenames[feature.properties.placename] = [feature.properties.html];
offsetMap(e);
$('#blacklight-map-sidebar').html(buildList(placenames));
sidebar.show();
});
}
});

// Add GeoJSON layer to marker cluster object
markers.addLayer(geoJsonLayer);

// Add marker cluster object to map
map.addLayer(markers);

// Listeners for marker cluster clicks
markers.on('clusterclick', function(e){

//hide sidebar if it is visible
if (sidebar.isVisible()){
sidebar.hide();
}

//if map is at the lowest zoom level
if (map.getZoom() === Blacklight.mapOptions.maxzoom){

var placenames = generatePlacenamesObject(e.layer._markers);


offsetMap(e);

//Update sidebar div with new html
$('#blacklight-map-sidebar').html(buildList(placenames));

//Show the sidebar!
sidebar.show();
}
});

//Add click listener to map
map.on('click', function(e){

//hide the sidebar if it is visible
if (sidebar.isVisible()){
sidebar.hide();
}
});

//drag listener on map
map.on('drag', function(e){

//hide the sidebar if it is visible
if (sidebar.isVisible()){
sidebar.hide();
}
});

});

Blacklight.mapOptions = {
tileurl : 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
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>'
};

function buildList(placenames){
var html = "";
$.each(placenames, function(i,val){
html += "<h2>" + i + "</h2>";
html += "<ul class='sidebar-list'>";
$.each(val, function(j, val2){
html += val2;
});
html += "</ul>";
});
return html;
}

// Generates placenames object
function generatePlacenamesObject(markers){
var placenames = {};
$.each(markers, function(i,val){
if (!(val.feature.properties.placename in placenames)){
placenames[val.feature.properties.placename] = [];
}
placenames[val.feature.properties.placename].push(val.feature.properties.html);
});
return placenames;
}

// Move the map so that it centers the clicked cluster TODO account for various size screens
function offsetMap(e){
mapWidth = $('#blacklight-map').width();
mapHeight = $('#blacklight-map').height();
if (!e.latlng.equals(map.getCenter())){
map.panBy([(e.originalEvent.layerX - (mapWidth/4)), (e.originalEvent.layerY - (mapHeight/2))]);
}else{
map.panBy([(mapWidth/4), 0]);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
/* Master manifest file for engine, so local app can require
* this one file, but get all our files -- and local app
* require does not need to change if we change file list.
*
*= require 'leaflet.markercluster'
*= require 'leaflet.markercluster.default'
*= require 'L.Control.Sidebar'
*/
23 changes: 20 additions & 3 deletions app/assets/stylesheets/blacklight_maps/default.css.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
#documents.map {
/*
*= require leaflet
*= require leaflet.markercluster
*= require leaflet.markercluster.default
*= require L.Control.Sidebar.css
*/

.view-icon-maps {
&:before { content: "\e135"; }
}

.view-icon-maps {
&:before { content: "\e062"; }
#blacklight-map{
height: 550px;
}

.sidebar-thumb{
height: 64px;
width: 64px;
}

.sidebar-list{
padding-left: 0;
list-style: none;
}
36 changes: 36 additions & 0 deletions app/helpers/blacklight_maps_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module BlacklightMapsHelper

def show_map_div
data_attributes = {
:maxzoom => blacklight_config.view.maps.maxzoom,
:tileurl => blacklight_config.view.maps.tileurl

}

content_tag(:div, "", id: "blacklight-map",
data: data_attributes
)
end

def serialize_geojson
geojson_docs = {type: "FeatureCollection", features: []}
@response.docs.each_with_index do |doc, counter|
if doc[blacklight_config.view.maps.placename_coord_field]
doc[blacklight_config.view.maps.placename_coord_field].each do |loc|
values = loc.split('|')
feature = {type: "Feature", geometry: {type: "Point",
coordinates: [values[2].to_f, values[1].to_f]},
properties: {placename: values[0],
html: render_leaflet_sidebar_partial(doc)}}
geojson_docs[:features].push feature
end
end
end
return geojson_docs.to_json
end

def render_leaflet_sidebar_partial(doc)
render partial: 'catalog/index_maps', locals: {document: SolrDocument.new(doc)}
end

end
6 changes: 4 additions & 2 deletions app/views/catalog/_document_maps.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<% # container for all documents in index view -%>
<% # container for all documents in map view -%>
<div id="documents" class="map">
<!-- map goes here -->
<%= show_map_div() %>
<div id="blacklight-map-sidebar"></div>
<%= javascript_tag "var geojson_docs = #{serialize_geojson}" %>
</div>
9 changes: 9 additions & 0 deletions app/views/catalog/_index_maps.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<% # the way each document will be viewed in the sidebar list -%>
<li class='media'>
<%= render_thumbnail_tag document, {class: 'sidebar-thumb media-object'}, {class: 'pull-left'} %>
<div class='media-body'>
<h4 class='media-heading'>
<%= link_to_document document, :label=>document_show_link_field(document) %>
</h4>
</div>
</li>
3 changes: 3 additions & 0 deletions blacklight-maps.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ Gem::Specification.new do |spec|
spec.add_dependency "rails"
spec.add_dependency "blacklight", ">= 5.1.0"
spec.add_dependency "bootstrap-sass", "~> 3.0"
spec.add_dependency "leaflet-rails"
spec.add_dependency "leaflet-markercluster-rails"
spec.add_dependency "leaflet-sidebar-rails", "~> 0.0.2"

spec.add_development_dependency "bundler", "~> 1.5"
spec.add_development_dependency "rake"
Expand Down
Binary file added docs/map-sidebar.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/map-view.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 15 additions & 1 deletion lib/blacklight/maps/engine.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
require 'blacklight'
require 'leaflet-rails'
require 'leaflet-markercluster-rails'
require 'leaflet-sidebar-rails'


module Blacklight
module Maps
class Engine < Rails::Engine
Blacklight::Configuration.default_values[:view].maps.lat_lng_field = "zzz_pt"

# Set some default configurations
Blacklight::Configuration.default_values[:view].maps.placename_coord_field = "placename_coords"
Blacklight::Configuration.default_values[:view].maps.tileurl = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
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>'
Blacklight::Configuration.default_values[:view].maps.maxzoom = 8

# Add our helpers
initializer 'blacklight-maps.helpers' do |app|
ActionView::Base.send :include, BlacklightMapsHelper
end

# This makes our rake tasks visible.
rake_tasks do
Expand Down

0 comments on commit af2a381

Please sign in to comment.