aboutsummaryrefslogtreecommitdiff
path: root/app/javascript
diff options
context:
space:
mode:
authorhellekin <hellekin@cepheide.org>2021-01-22 05:32:15 +0100
committerhellekin <hellekin@cepheide.org>2021-01-22 05:32:15 +0100
commitb54a8458d5029b3494165b7430e21b3ae34ecc0c (patch)
tree32ea6fc6b8774f672325fec52f0ffc97229a9568 /app/javascript
parent1c1aead78192982e221179de6688b944e5b01bf6 (diff)
downloadincommon-map-b54a8458d5029b3494165b7430e21b3ae34ecc0c.tar.gz
Upgrade Rails and add StimulusJS support
Diffstat (limited to 'app/javascript')
-rw-r--r--app/javascript/controllers/map_controller.js59
-rw-r--r--app/javascript/controllers/taxonomy_controller.js112
-rw-r--r--app/javascript/packs/application.js6
3 files changed, 160 insertions, 17 deletions
diff --git a/app/javascript/controllers/map_controller.js b/app/javascript/controllers/map_controller.js
index 30c1361..1704da8 100644
--- a/app/javascript/controllers/map_controller.js
+++ b/app/javascript/controllers/map_controller.js
@@ -7,32 +7,65 @@
//
import { Controller } from "stimulus"
-import "leaflet/dist/leaflet.css"
-import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.webpack.css'; // Re-uses images from ~leaflet package
-import L from "leaflet"
+import 'leaflet/dist/leaflet.css'
+// Re-uses images from ~leaflet package
+import 'leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.webpack.css'
+
+import * as L from 'leaflet'
+import 'leaflet-defaulticon-compatibility'
+import "leaflet-providers"
+import "leaflet.markercluster/dist/leaflet.markercluster.js"
+
+import 'leaflet-makimarkers'
export default class extends Controller {
static targets = [ "container" ]
initialize() {
-
+ console.log("Map controller initialized.")
+ this.mapBoxAPIToken = 'pk.eyJ1IjoibmVtYWVsIiwiYSI6ImNrZzBrYjBudTB3bnMyenFmNWtrN3h3bmMifQ.Rkeyhm-9iIQOV7NAMA5LaA'
}
connect() {
- this.map = L.map(this.containerTarget, {
- zoomDelta: 0.5,
- zoomSnap: 0.5,
- }).setView(this._coordinates(), this._zoom());
+ L.MakiMarkers.accessToken = this.mapBoxAPIToken
- L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
+ var mapbox = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
- accessToken: 'pk.eyJ1IjoibmVtYWVsIiwiYSI6ImNrZzBrYjBudTB3bnMyenFmNWtrN3h3bmMifQ.Rkeyhm-9iIQOV7NAMA5LaA'
- }).addTo(this.map);
+ accessToken: this.mapBoxAPIToken
+ })
+
+ var stamen_tr = L.tileLayer.provider('Stamen.Toner')
+ var stamen_wc = L.tileLayer.provider('Stamen.Watercolor')
+ var tiles_osm = L.tileLayer.provider('OpenStreetMap.Mapnik')
+ var tiles_sat = L.tileLayer.provider('Esri.WorldImagery')
+
+ const tilemaps = {
+ 'osm': tiles_osm,
+ 'mapbox': mapbox,
+ 'watercolor': stamen_wc,
+ 'greyscale': stamen_tr,
+ 'satellite': tiles_sat
+ }
+
+ const overlays = {}
+
+ this.map = L.map(this.containerTarget, {
+ zoomDelta: 0.5,
+ zoomSnap: 0.5,
+ layers: [ tiles_osm ],
+ }).setView(this._coordinates(), this._zoom());
+
+ L.control.layers(tilemaps, overlays).addTo(this.map)
+
+ L.DomEvent.on(window, 'hashchange', this.doSomethingCool);
+
+ // Allow calling the mapController from elsewhere.
+ this.element[this.identifier] = this
}
disconnect() {
@@ -40,6 +73,10 @@ export default class extends Controller {
console.log('Map controller disconnected.')
}
+ doSomethingCool() {
+ console.log(window.location.hash)
+ }
+
_coordinates() {
return [this.data.get('latitude'), this.data.get('longitude')];
}
diff --git a/app/javascript/controllers/taxonomy_controller.js b/app/javascript/controllers/taxonomy_controller.js
index 16d57fa..02b1483 100644
--- a/app/javascript/controllers/taxonomy_controller.js
+++ b/app/javascript/controllers/taxonomy_controller.js
@@ -9,15 +9,18 @@
import { Controller } from "stimulus"
export default class extends Controller {
- static targets = [ "category", "deploy", "filter", "section", "toggle" ]
+ static targets = [ "category", "deploy", "filter", "layers", "section", "toggle" ]
initialize() {
console.log("Taxonomy controller initialized.")
+
+ this.overlays = {}
+ this.sectionsOnMap = []
}
connect() {
console.log("Taxonomy controller connected.")
-
+ this.taxonomy_uuid = this.data.get('uuid')
if (this.hasFilterTarget) {
let url = `/taxonomies/${this.data.get('uuid')}/filter.js`
console.log(`loading url = ${url}`)
@@ -29,10 +32,19 @@ export default class extends Controller {
} else {
console.log("Taxonomy filter is missing")
}
+
+ // Access the map
+ if (this.map = document.querySelector('#map').parentElement.map.map) {
+ console.log("Taxonomy Controller connected to this.map")
+ } else {
+ console.log("Taxonomy Controller could not load map!")
+ }
}
+
deploy() {
console.log(`deploying taxonomy ${this.data.get('uuid')}`);
+
fetch(`/taxonomies/${this.data.get('uuid')}.js`)
.then(response => response.text())
.then(html => this.deployTarget.innerHTML = html);
@@ -45,12 +57,100 @@ export default class extends Controller {
}
category(event) {
- let catId = event.target.dataset.taxonomyCategoryId
- event.target.classList.toggle('active')
+ let catId = (event.target.dataset.taxonomyCategoryId || event.target.parentNode.parentNode.dataset.CategoryId)
+ let secId = event.target.dataset.taxonomySectionId
+ console.log(`Category: ${catId}/${secId}`)
+ var active = event.target.classList.toggle('active')
+ if (active) {
+ console.log('activated')
+ } else {
+ console.log('deactivated')
+ }
+ }
+
+ loadCategory(catId) {
+ document.querySelector(`#category-${catId}`).lastChild.childNodes.forEach(function(li) {
+ this._mapLayerToggleSection(li.dataset.taxonomySectionId)
+ })
}
section(event) {
- let catId = event.target.dataset.taxonomySectionId
- event.target.classList.toggle('active')
+ let secId = event.target.dataset.taxonomySectionId
+ console.log(`Section: ${secId} to be loaded`)
+ this._loadMarkers(secId)
+ 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)}]...`)
+ let overlay = L.layerGroup();
+ let markers = L.markerClusterGroup();
+ let iconName = this._sectionIconName(secId);
+
+ fetch(`/sections/${secId}.json`, {
+ headers: { 'X-CSRF-Token': this._csrfToken() }
+ })
+ .then(response => response.json())
+ .then(data => {
+ L.geoJSON(data, {
+ 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'
+ })
+ });
+ },
+ onEachFeature: (feature, layer) => {
+ layer.on('click', () => this.onClick(layer))
+ layer.addTo(markers)
+ }
+ })
+ })
+ console.log(`cluster counts ${markers.length} markers`)
+ this.overlays[secId] = markers
+ }
+ }
+
+ onClick(layer) {
+ console.log(layer)
+ }
+
+ _mapLayerToggleSection(secId) {
+ if (this.sectionsOnMap.includes(secId)) {
+ console.log(`removing section ${secId} from map`)
+ this.map.removeLayer(this.overlays[secId])
+ this.sectionsOnMap.pop(secId)
+ } else {
+ console.log(`adding section ${secId} to the map`)
+ this.sectionsOnMap.push(secId)
+ this.overlays[secId].addTo(this.map)
+ }
+ }
+
+ _csrfToken() {
+ return document.querySelector('[name=csrf-token]').content
}
}
diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js
index 5e3eec0..a4b51a8 100644
--- a/app/javascript/packs/application.js
+++ b/app/javascript/packs/application.js
@@ -15,4 +15,10 @@ require("@rails/activestorage").start()
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)
+//= require leaflet
+//= require leaflet-defaulticon-compatibility
+//= require leaflet.markercluster
+
import "controllers"
+
+import 'stylesheets/application'