You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

248 lines
7.7 KiB

const turf = {
area: require('@turf/area').default,
length: require('@turf/length').default
}
const tabs = require('modulekit-tabs')
const formatUnits = require('./formatUnits')
const displayBlock = require('./displayBlock')
require('./GeoInfo.css')
function heading (value) {
return [ 'N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N' ][Math.round(value / 45)]
}
register_hook('init', function () {
let tab = new tabs.Tab({
id: 'search',
weight: -1
})
tab.content.classList.add('geo-info')
global.tabs.add(tab)
updateTabHeader(tab.header)
tab.header.title = lang('geoinfo:header')
let crosshairIcon = L.icon({
iconUrl: 'img/crosshair.png',
iconSize: [21, 21],
iconAnchor: [10, 10],
})
let crosshair = new L.marker([0,0], {
icon: crosshairIcon,
clickable:false,
pane: "crosshair800"
})
global.map.createPane('crosshair800')
global.map.getPane('crosshair800').style.zIndex = 800
global.map.getPane('crosshair800').style.pointerEvents = 'none'
let domZoom = document.createElement('div')
domZoom.className = 'zoom'
domZoom.title = lang('geoinfo:zoom')
tab.content.appendChild(domZoom)
let domBBoxNW = document.createElement('div')
domBBoxNW.className = 'bbox-nw-corner'
domBBoxNW.title = lang('geoinfo:nw-corner')
tab.content.appendChild(domBBoxNW)
let domCenter = document.createElement('div')
domCenter.className = 'bbox-center'
domCenter.title = lang('geoinfo:center')
tab.content.appendChild(domCenter)
let domBBoxSE = document.createElement('div')
domBBoxSE.className = 'bbox-se-corner'
domBBoxSE.title = lang('geoinfo:se-corner')
tab.content.appendChild(domBBoxSE)
let domMouse = document.createElement('div')
domMouse.className = 'mouse empty'
domMouse.title = lang('geoinfo:mouse')
tab.content.appendChild(domMouse)
let domLocation = document.createElement('div')
domLocation.title = lang('geoinfo:location')
domLocation.className = 'location empty'
tab.content.appendChild(domLocation)
function getPrecision () {
let zoom = global.map.getZoom()
return zoom > 16 ? 5
: zoom > 8 ? 4
: zoom > 4 ? 3
: zoom > 2 ? 2
: zoom > 1 ? 1
: 0
}
function updateMapView () {
crosshair.setLatLng(global.map.getCenter())
let scale = formatUnits.distance(global.map.getMetersPerPixel())
let scale2 = formatUnits.area(Math.pow(global.map.getMetersPerPixel(), 2))
let precision = getPrecision()
domZoom.innerHTML = '<span class="value">z' +
Math.round(global.map.getZoom()) + ', ' +
scale + '/px, ' +
scale2 + '/px²' +
'</span>'
let bounds = map.getBounds()
domBBoxNW.innerHTML = '<span class="value">' + formatUnits.coord(bounds.getNorthWest().wrap(), { precision }) + '</span>'
domCenter.innerHTML = '<span class="value">' + formatUnits.coord(bounds.getCenter().wrap(), { precision }) + '</span>'
domBBoxSE.innerHTML = '<span class="value">' + formatUnits.coord(bounds.getSouthEast().wrap(), { precision }) + '</span>'
}
let lastMouseEvent
function updateMouse (e) {
if (!e) {
e = lastMouseEvent
}
if (e) {
let precision = getPrecision()
domMouse.innerHTML = '<span class="value">' + formatUnits.coord(e.latlng.wrap(), { precision }) + '</span>'
domMouse.classList.remove('empty')
} else {
removeMouse()
}
lastMouseEvent = e
}
function removeMouse () {
lastMouseEvent = null
domMouse.innerHTML = ''
domMouse.classList.add('empty')
}
let lastLocation
function updateLocation (e) {
if (e) {
lastLocation = e
} else {
e = lastLocation
}
if (e) {
domLocation.innerHTML = '<span class="value">' + formatUnits.coord(e.latlng.wrap(), { precision: 5 }) +
(typeof e.accuracy !== 'undefined' ? (global.options.formatUnitsCoordSpacer || ', ') + '± ' + formatUnits.distance(e.accuracy.toFixed(0)) : '') + '<br/>' +
(typeof e.altitude !== 'undefined' ? '<i class="fas fa-mountain"></i> ' + formatUnits.height(e.altitude) + (typeof e.altitudeAccuracy !== 'undefined' ? ' ± ' + formatUnits.distance(e.altitudeAccuracy) : '') + ' ' : '') +
(typeof e.speed !== 'undefined' ? '<i class="fas fa-tachometer-alt"></i> ' + formatUnits.speed(e.speed) + ' ' : '') +
(typeof e.heading !== 'undefined' ? '<i class="fas fa-compass"></i> ' + lang('heading:' + heading(e.heading)) + ' (' + e.heading.toFixed(0) + '°)' : '') +
'</span>'
domLocation.classList.remove('empty')
}
}
function saveLocation (e) {
lastLocation = e
}
global.map.on('move', () => {
updateTabHeader(tab.header)
})
global.map.on('locationfound', saveLocation)
tab.on('select', () => {
crosshair.addTo(global.map)
updateMapView()
updateLocation()
global.map.on('move', updateMapView)
global.map.on('mousemove', updateMouse)
global.map.on('mouseout', removeMouse)
global.map.off('locationfound', saveLocation)
global.map.on('locationfound', updateLocation)
})
tab.on('unselect', () => {
crosshair.removeFrom(global.map)
global.map.off('move', updateMapView)
global.map.off('mousemove', updateMouse)
global.map.off('mouseout', removeMouse)
global.map.off('locationfound', updateLocation)
global.map.on('locationfound', saveLocation)
})
register_hook('format-units-refresh', updateMapView)
register_hook('format-units-refresh', updateMouse)
register_hook('format-units-refresh', removeMouse)
register_hook('format-units-refresh', updateLocation)
})
let showDetailsCurrent
register_hook('show-details', (data, category, dom, callback) => {
let div = document.createElement('div')
div.className = 'geo-info'
displayBlock({
dom,
title: lang('geoinfo:header'),
content: div,
order: 5,
})
showDetailsCurrent = [ data, category, div ]
geoInfoShowDetails.apply(this, showDetailsCurrent)
callback()
})
register_hook('format-units-refresh', () => {
if (showDetailsCurrent) {
showDetailsCurrent[2].innerHTML = ''
geoInfoShowDetails.apply(this, showDetailsCurrent)
}
})
function geoInfoShowDetails (data, category, div) {
let ob = data.object
let result = ''
let geojson = ob.GeoJSON()
let area = turf.area(geojson)
let length = turf.length(geojson) * 1000
if (area !== 0 || length !== 0) {
result += '<div class="object-shape">' +
'<span class="value">' +
lang('geoinfo:length') + ': ' + formatUnits.distance(length) +
(area === 0 ? '' : ', ' + lang('geoinfo:area') + ': ' + formatUnits.area(area)) +
'</span></div>'
}
if (ob.bounds.minlat !== ob.bounds.maxlat || ob.bounds.minlon !== ob.bounds.maxlon) {
result += '<div class="object-nw-corner" title="' + lang('geoinfo:nw-corner') + '"><span class="value">' + formatUnits.coord({ lat: ob.bounds.minlat, lng: ob.bounds.maxlon }) + '</span></div>'
}
result += '<div class="object-center" title="' + lang('geoinfo:centroid') + '"><span class="value">' + formatUnits.coord({ lat: ob.center.lat, lng: ob.center.lon }) + '</span></div>'
if (ob.bounds.minlat !== ob.bounds.maxlat || ob.bounds.minlon !== ob.bounds.maxlon) {
result += '<div class="object-se-corner" title="' + lang('geoinfo:se-corner') + '"><span class="value">' + formatUnits.coord({ lat: ob.bounds.maxlat, lng: ob.bounds.minlon }) + '</span></div>'
}
div.innerHTML = result
}
function updateTabHeader (header) {
if (!global.map._loaded) {
return
}
let center = global.map.getCenter().wrap()
if (center.lng < -35) {
header.innerHTML = '<i class="fas fa-globe-americas"></i>'
} else if (center.lng > 80) {
header.innerHTML = '<i class="fas fa-globe-asia"></i>'
} else if (center.lat < 30) {
header.innerHTML = '<i class="fas fa-globe-africa"></i>'
} else {
header.innerHTML = '<i class="fas fa-globe-europe"></i>'
}
}