From 97bfc3f6012027077077ea4a6b5f2f709c76158e Mon Sep 17 00:00:00 2001 From: hellekin Date: Fri, 22 Jan 2021 10:35:07 +0100 Subject: Add markers and popups - Replace MakiMarkers with ExtraMarkers and ForkAwesome - Add HTML popup binding --- app/assets/stylesheets/application/_fonts.scss | 12 ++++ app/helpers/leaflet_helper.rb | 19 ++++-- app/helpers/sections_helper.rb | 15 +---- app/javascript/controllers/map_controller.js | 4 +- app/javascript/controllers/taxonomy_controller.js | 35 +++------- app/javascript/packs/application.js | 3 +- app/views/resources/_popup.html.erb | 10 +++ db/migrate/20210122050635_add_section_icon.rb | 5 ++ db/schema.rb | 3 +- db/seeds.rb | 82 +++++++++++++++++++++++ package.json | 3 +- yarn.lock | 17 +++-- 12 files changed, 152 insertions(+), 56 deletions(-) create mode 100644 app/assets/stylesheets/application/_fonts.scss create mode 100644 app/views/resources/_popup.html.erb create mode 100644 db/migrate/20210122050635_add_section_icon.rb diff --git a/app/assets/stylesheets/application/_fonts.scss b/app/assets/stylesheets/application/_fonts.scss new file mode 100644 index 0000000..2d3565c --- /dev/null +++ b/app/assets/stylesheets/application/_fonts.scss @@ -0,0 +1,12 @@ +/* Override ForkAwesome font path to match Webpack's */ +@fa-font-path: '../media/fonts'; + +/* Align font icon with the marker's head */ +.extra-marker-svg i.fa { + position: absolute; + top: 9px; + font-size: 16px; + left: -2px; + right: 0px; + text-align: center; +} diff --git a/app/helpers/leaflet_helper.rb b/app/helpers/leaflet_helper.rb index 6ca03f3..67820d3 100644 --- a/app/helpers/leaflet_helper.rb +++ b/app/helpers/leaflet_helper.rb @@ -1,11 +1,22 @@ module LeafletHelper - def marker_for(resource, options = {}) - coords = [resource.latitude, resource.longitude] + def json_marker_for(resource, section) + # Style according to requested section + marker = resource.to_geojson + marker['style'] = { + classes: "cat#{section.category_id} sec#{section.id}", + color: section.category.color + } + marker['icon'] = { + name: 'fa-neuter' || section.icon_name || 'fa-circle', + shape: 'penta' # TODO: change shape according to marker state + } + # Render HTML popup + marker['popup'] = popup_for(resource) - "L.marker(#{coords}, #{options}).bindPopup(%s)" % popup_for(resource) + marker.to_json end def popup_for(resource) - render partial: 'resource/popup', locals: { resource: resource } + render partial: 'resources/popup', locals: { resource: resource }, formats: [:html] end end diff --git a/app/helpers/sections_helper.rb b/app/helpers/sections_helper.rb index 8180fee..20f602b 100644 --- a/app/helpers/sections_helper.rb +++ b/app/helpers/sections_helper.rb @@ -1,19 +1,8 @@ module SectionsHelper # Render a section as a GeoJSON FeatureCollection def geojson_feature_collection(section) - out = [] - class_name = { baseVal: "cat#{section.category_id} sec#{section.id}" } - style = { fill: section.category.color } + features = section.resources.map { |res| json_marker_for(res, section) }.join(',') - section.resources.each do |marker| - # Add styling - marker = marker.to_geojson - marker['className'] = class_name - marker['style'] = style - - out << marker.to_json - end - - raw("{ \"type\": \"FeatureCollection\", \"features\": [ #{out.join(',')} ] }") + raw("{ \"type\": \"FeatureCollection\", \"features\": [ #{features} ] }") end end diff --git a/app/javascript/controllers/map_controller.js b/app/javascript/controllers/map_controller.js index 1704da8..9770cf4 100644 --- a/app/javascript/controllers/map_controller.js +++ b/app/javascript/controllers/map_controller.js @@ -17,7 +17,7 @@ import 'leaflet-defaulticon-compatibility' import "leaflet-providers" import "leaflet.markercluster/dist/leaflet.markercluster.js" -import 'leaflet-makimarkers' +import 'leaflet-extra-markers' export default class extends Controller { static targets = [ "container" ] @@ -28,8 +28,6 @@ export default class extends Controller { } connect() { - L.MakiMarkers.accessToken = this.mapBoxAPIToken - var mapbox = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', { attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery Mapbox', maxZoom: 18, diff --git a/app/javascript/controllers/taxonomy_controller.js b/app/javascript/controllers/taxonomy_controller.js index 02b1483..413872b 100644 --- a/app/javascript/controllers/taxonomy_controller.js +++ b/app/javascript/controllers/taxonomy_controller.js @@ -81,30 +81,11 @@ export default class extends Controller { this._mapLayerToggleSection(secId) } - _sectionIconName(secId) { - const names = { - 215: 'campsite', - 216: 'hospital', - 217: 'landmark', - 218: 'shelter', - 219: 'lodging', - 220: 'playground', - 221: 'residential-community', - 222: 'home', - 223: 'residential-community', - 224: 'residential-community', - 225: 'home' - - } - return names[secId] || 'circle' - } - _loadMarkers(secId) { if (this.overlays[secId] == undefined) { - console.log(`loading markers for section ${secId} [${this._sectionIconName(secId)}]...`) + console.log(`loading markers for section ${secId}`) let overlay = L.layerGroup(); let markers = L.markerClusterGroup(); - let iconName = this._sectionIconName(secId); fetch(`/sections/${secId}.json`, { headers: { 'X-CSRF-Token': this._csrfToken() } @@ -115,13 +96,15 @@ export default class extends Controller { pointToLayer: function (feature, latlng) { return L.marker(latlng, { attribution: feature.source, - icon: L.MakiMarkers.icon({ - icon: iconName, - className: feature.className.baseVal, - color: feature.style.fill, - size: 'm' + icon: L.ExtraMarkers.icon({ + icon: feature.icon.name, + extraClasses: feature.style.classes, + markerColor: feature.style.color, + shape: feature.icon.shape, + prefix: 'fa', + svg: true }) - }); + }).bindPopup(feature.popup); }, onEachFeature: (feature, layer) => { layer.on('click', () => this.onClick(layer)) diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index a4b51a8..011c3fe 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -20,5 +20,6 @@ require("@rails/activestorage").start() //= require leaflet.markercluster import "controllers" - +import "fork-awesome/scss/fork-awesome" +import "fork-awesome/fonts/forkawesome-webfont" import 'stylesheets/application' diff --git a/app/views/resources/_popup.html.erb b/app/views/resources/_popup.html.erb new file mode 100644 index 0000000..0841264 --- /dev/null +++ b/app/views/resources/_popup.html.erb @@ -0,0 +1,10 @@ +
+

<%= resource.name %>

+

<%= h resource.summary %>

+ <% unless resource.description.blank? %> +
+

Description

+ <%= m resource.description %> +
+ <% end %> +
diff --git a/db/migrate/20210122050635_add_section_icon.rb b/db/migrate/20210122050635_add_section_icon.rb new file mode 100644 index 0000000..a89c201 --- /dev/null +++ b/db/migrate/20210122050635_add_section_icon.rb @@ -0,0 +1,5 @@ +class AddSectionIcon < ActiveRecord::Migration[6.1] + def change + add_column :sections, :icon_name, :string, limit: 32, default: 'fa-neuter' + end +end diff --git a/db/schema.rb b/db/schema.rb index c97f290..60a2c99 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_01_21_192039) do +ActiveRecord::Schema.define(version: 2021_01_22_050635) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -124,6 +124,7 @@ ActiveRecord::Schema.define(version: 2021_01_21_192039) do t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.integer "dewey_id" + t.string "icon_name", limit: 32, default: "circle" t.index ["category_id"], name: "index_sections_on_category_id" t.index ["dewey_id"], name: "index_sections_on_dewey_id", unique: true end diff --git a/db/seeds.rb b/db/seeds.rb index 6252ebf..60cebe2 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -53,3 +53,85 @@ end if Map.count == 0 Map.create(uuid: "1a42651e-3fe8-4e83-bfcd-f14bb8d0c713", latitude: 50.8503396, longitude: 4.3517103, zoom: 13, taxonomy_id: 1) end + +# TODO: Fix section icons +# This thing below was a start with maki icons but we need more... +# And fork-awesome is missing some as well, so we need to create them. +=begin +if Section.first.icon_name == 'circle' + { + # cat-30 + 148: 'fa-campsite', + 158: 'hospital', + 130: 'landmark-JP', + 198: 'shelter', + 150: 'lodging', + 149: 'playground', + 165: 'residential-community', + 131: 'home', + 168: 'residential-community', + 164: 'residential-community', + 114: 'home', + # cat-31 + 170: 'convenience', + 180: 'sushi', + 155: 'garden', + 135: 'shop', + 115: 'drinking-water', + 154: 'restaurant', + 118: 'restaurant', + 28: 'recycling', + 27: 'garden-center', + 185: 'farm', + 182: 'fast-food', + 123: 'beer', + # cat-32 + 210: 'square', + 156: 'clothing-store', + 46: 'gift', + 144: 'waterfall', + 104: 'clothing-store', + 207: 'toilet', + # cat-33 + 18: 'hospital', + 145: 'doctor', + 157: 'doctor', + 192: 'shelter', + 199: 'defibrillator', + 190: 'shelter', + 143: 'heart', + 208: 'hospital', + 191: 'heart', + # cat-34 + 699: 'shop', + 138: 'logging', + 136: 'recycling', + 50: 'library', + 132: 'garden-center', + 42: 'hardware', + 113: 'building', + 206: 'clothing-store', + 47: 'recycling', + 205: 'recycling', + 120: 'shop', + # cat-35 + 128: 'garden-center', + 121: 'waste-basket', + 116: 'garden', + 133: 'park', + 194: 'natural', + 129: 'picnic-site', + 125: 'recycle', + 127: 'natural', + # cat-36 + 102: 'ranger-station', + 19: 'town', + 17: 'skateboard', + 14: '' + + + }.each do |id, name| + Section.find_by(dewey_id: id).update(icon_name: name) + end +end +=end diff --git a/package.json b/package.json index a597de3..cdf02a1 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,10 @@ "@rails/ujs": "^6.0.0", "@rails/webpacker": "4.3.0", "css-loader": "^5.0.1", + "fork-awesome": "^1.1.7", "leaflet": "^1.7.1", "leaflet-defaulticon-compatibility": "^0.1.1", - "leaflet-makimarkers": "^3.1.0", + "leaflet-extra-markers": "^1.2.1", "leaflet-providers": "^1.11.0", "leaflet.markercluster": "^1.4.1", "normalize.css": "^8.0.1", diff --git a/yarn.lock b/yarn.lock index c25ca0c..fdbce3e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3226,6 +3226,11 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +fork-awesome@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/fork-awesome/-/fork-awesome-1.1.7.tgz#1427da1cac3d1713046ee88427e5fcecb9501d21" + integrity sha512-IHI7XCSXrKfUIWslse8c/PaaVDT1oBaYge+ju40ihL2ooiQeBpTr4wvIXhgTd2NuhntlvX+M5jYHAPTzNlmv0g== + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -4289,12 +4294,10 @@ leaflet-defaulticon-compatibility@^0.1.1: resolved "https://registry.yarnpkg.com/leaflet-defaulticon-compatibility/-/leaflet-defaulticon-compatibility-0.1.1.tgz#ab72257b3da66fb48dab69a10c3824012a15a20a" integrity sha512-vDBFdlUAwjSEGep9ih8kfJilf6yN8V9zTbF5NC/1ZwLeGko3RUQepspPnGCRMFV51dY3Lb3hziboicrFz+rxQA== -leaflet-makimarkers@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leaflet-makimarkers/-/leaflet-makimarkers-3.1.0.tgz#b6cf89b161153bac8746f15726daa27afae6117c" - integrity sha1-ts+JsWEVO6yHRvFXJtqievrmEXw= - dependencies: - leaflet ">=0.5.0" +leaflet-extra-markers@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/leaflet-extra-markers/-/leaflet-extra-markers-1.2.1.tgz#dcea9e0ab3850c4724afa6eda8dda8fa743739fa" + integrity sha512-k3mGGBJg5wr4LY89MyLHcWCol3yNC9qcK1+5os+HjBk09RlxmqsywNSBwmpP1WKnkKCIgofnOFOhdM5GeK0kHQ== leaflet-providers@^1.11.0: version "1.11.0" @@ -4306,7 +4309,7 @@ leaflet.markercluster@^1.4.1: resolved "https://registry.yarnpkg.com/leaflet.markercluster/-/leaflet.markercluster-1.4.1.tgz#b53f2c4f2ca7306ddab1dbb6f1861d5e8aa6c5e5" integrity sha512-ZSEpE/EFApR0bJ1w/dUGwTSUvWlpalKqIzkaYdYB7jaftQA/Y2Jav+eT4CMtEYFj+ZK4mswP13Q2acnPBnhGOw== -leaflet@>=0.5.0, leaflet@^1.7.1: +leaflet@^1.7.1: version "1.7.1" resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.7.1.tgz#10d684916edfe1bf41d688a3b97127c0322a2a19" integrity sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw== -- cgit v1.2.3