Skip to content

Instantly share code, notes, and snippets.

@hohonuuli
Created June 1, 2022 20:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hohonuuli/88532909b7f85cd1000245df4634748f to your computer and use it in GitHub Desktop.
Save hohonuuli/88532909b7f85cd1000245df4634748f to your computer and use it in GitHub Desktop.
<template>
<div class="map-box" id="maptest"></div>
</template>
<script>
import Vue from 'vue'
// If you need to reference 'L', such as in 'L.icon', then be sure to
// explicitly import 'leaflet' into your component
import L from 'leaflet'
import 'leaflet/dist/leaflet.css';
import 'leaflet-providers'
import { mapState } from "vuex";
import regionsApi from '@/assets/fathomnet-regions'
import ImageThumbnail from "@/components/ImageThumbnail";
function hslaString({ hue, saturation, luminosity, alpha }) {
return `hsla(${hue}, ${saturation}%, ${luminosity}%, ${alpha})`;
}
function colorByDepth(depthMeters) {
const MAX_DEPTH = 3000
const color = {
hue: 180,
saturation: 100,
luminosity: (1 - (depthMeters / MAX_DEPTH)) * 100,
alpha: 1,
}
return hslaString(color)
}
function namedColorByDepth(depthMeters) {
let color
if (depthMeters > 2000) {
color = "var(--color-benthos-blue)"
} else if (depthMeters > 1000) {
color = "var(--color-ultramarine-blue)"
} else if (depthMeters > 500) {
color = "var(--color-bay-blue)"
} else if (depthMeters > 250) {
color = "var(--color-photic-green)"
} else {
color = "var(--color-seafoam-green)"
}
return color
}
function boxColorFromString(string) {
let accumulatedCharCodes = 0;
for (let index = 0; index < string.length; index++) {
accumulatedCharCodes += string.charCodeAt(index);
}
return {
hue: accumulatedCharCodes % 360,
saturation: 100,
luminosity: 85
};
}
export default {
name: 'SearchResultsMap',
components: {
ImageThumbnail,
},
computed: mapState({
geoImages: (state) => state.fathomnet.geoImages,
region: (state) => state.fathomnet.selectedRegion
}),
data: () => ({
map: null,
tileLayer: null,
layerGroup: null,
renderer: null,
}),
methods: {
redraw() {
if (this.layerGroup) {
this.layerGroup.clearLayers()
}
// Zoom to region if one is defined
let bounds = this.region ? this.region: regionsApi.regions.get('Monterey Bay')
let viewBounds = [[bounds.minLatitude, bounds.minLongitude], [bounds.maxLatitude, bounds.maxLongitude]]
if (this.geoImages && this.geoImages.length > 0) {
this.geoImages.forEach((g, i) => {
if (g.latitude && g.longitude) {
// const color = colorByDepth(g.depthMeters)
// const color = namedColorByDepth(g.depthMeters)
// const color = boxColorFromString(this.concept)
// const color = "hsla(180, 100%, 65%, 1)"
const color = "var(--color-snapper-red)"
const marker = L.circleMarker([g.latitude, g.longitude], {radius: 5, color})
marker.addTo(this.layerGroup)
marker.bindPopup(`<div style="width: 100px; height: 100px; display: flex; align-items: center; justify-content: center;">Loading…</div>`)
}
})
if (!this.region) {
let latitudes = this.geoImages.map(g => g.latitude).filter(v => v !== undefined)
let longitudes = this.geoImages.map(g => g.longitude).filter(v => v !== undefined)
let minLat = Math.min(...latitudes)
let minLon = Math.min(...longitudes)
let maxLat = Math.max(...latitudes)
let maxLon = Math.max(...longitudes)
if (!Number.isNaN(minLat)
&& !Number.isNaN(minLon)
&& !Number.isNaN(maxLat)
&& !Number.isNaN(maxLon)) {
viewBounds = [[minLat, minLon], [maxLat, minLon]]
}
}
}
this.map.fitBounds(viewBounds)
if (this.requestedLatitude && this.requestedLongitude) {
// this.map.panTo(new L.LatLng(requestedLatitude, requestedLongitude));
this.map.setView([this.requestedLatitude, this.requestedLongitude], 10);
}
},
zoomIn() {
this.map.setZoom(this.map.getZoom() + 1)
},
zoomOut() {
this.map.setZoom(this.map.getZoom() - 1)
},
},
mounted() {
// let mapboxLayerUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoiaG9ob251dWxpIiwiYSI6ImNrZ3dvbm0yYTBjOXIyd3F0dXpyODhnNGYifQ.sLLqr7nPh0C1zKxRP3fyJA'
// let openStreetmapUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'
// let openStreetmapDeUrl = 'https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png'
this.requestedLatitude = this.$route.query.latitude
this.requestedLongitude = this.$route.query.longitude
var mymap = L.map(
'maptest',
{ zoomControl: false }
).setView([36.8, -122.0], 13);
this.tileLayer = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri',
maxZoom: 13
});
// this.tileLayer = L.tileLayer(openStreetmapDeUrl, {
// 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: 'your.mapbox.access.token'
// })
this.tileLayer.addTo(mymap)
this.layerGroup = L.layerGroup()
this.layerGroup.addTo(mymap)
this.renderer = L.canvas({padding: 0.5})
// L.control.zoom({ position:'bottomright' }).addTo(mymap)
this.map = mymap
if (this.geoImages) {
this.redraw()
}
// KUDOS: https://gis.stackexchange.com/questions/112866/leaflet-how-can-i-update-content-of-popup-by-jquery
this.map.on('popupopen', e => {
setTimeout(() => {
// console.log({latlong: e.popup.getLatLng()})
// SHIM: Find the target geoimage using latitude and longitude of the popup
const { lat, lng } = e.popup.getLatLng();
const matches = this.geoImages.filter(geoimage =>
geoimage.latitude === lat && geoimage.longitude === lng
)
if (matches.length > 0) {
const geoImage = matches[0]
// console.log({geoImage})
// https://forum.vuejs.org/t/how-can-i-get-rendered-html-code-of-vue-component/19421/2
const thumbnail = new Vue({
...ImageThumbnail,
parent: this,
propsData: { geoImage }
})
// console.log({thumbnail})
// listen to events emitted from the component
thumbnail.$on('IMAGE_LOAD', (value) => {
// console.log({el: thumbnail.$el})
e.popup.setContent(thumbnail.$el)
})
thumbnail.$mount()
}
}, 1)
})
},
watch: {
geoImages: function() {
this.requestedLatitude = null
this.requestedLongitude = null
this.redraw()
},
interfaceState: function() {
// https://stackoverflow.com/questions/24412325/resizing-a-leaflet-map-on-container-resize
this.map.invalidateSize();
},
zoomLevel: function() {
// https://leafletjs.com/examples/zoom-levels/
this.map.setZoom(this.zoomLevel);
},
},
props: {
interfaceState: String,
zoomLevel: Number,
},
};
</script>
<style scoped>
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment