kopia lustrzana https://github.com/paraboul/mapchecking
Porównaj commity
4 Commity
912620e44d
...
1b8e97ed82
Autor | SHA1 | Data |
---|---|---|
Anthony Catel | 1b8e97ed82 | |
Anthony Catel | 018168af8d | |
Anthony Catel | ba573ed2fd | |
Anthony Catel | 633033b4d1 |
|
@ -10,6 +10,7 @@
|
|||
"@types/google.maps": "^3.48.3",
|
||||
"@vitejs/plugin-vue": "^2.2.4",
|
||||
"@vueuse/core": "^8.2.0",
|
||||
"fflate": "^0.7.3",
|
||||
"js-base64": "^3.5.2",
|
||||
"tailwindcss": "^3.0.23",
|
||||
"tatween": "^0.2.0",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="w-full h-full">
|
||||
<input ref="pacinput" class="controls" :class="[mapLoaded ? '' : 'hidden']" type="text" placeholder="Search Box">
|
||||
<div class="w-full h-full" id="map"></div>
|
||||
<input ref="pacinput" id="pac-input" class="controls" :class="[mapLoaded ? '' : 'hidden']" type="text" placeholder="Search Box">
|
||||
<div class="w-full h-full" ref="mapel"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
|||
import { Base64 } from 'js-base64'
|
||||
import { onMounted, ref, watch, computed } from 'vue';
|
||||
import { watchDebounced } from '@vueuse/core'
|
||||
|
||||
import { zlibSync, unzlibSync } from 'fflate';
|
||||
|
||||
const DEFAULT_MAP_POSITION = [48.862895, 2.286978, 18]
|
||||
|
||||
|
@ -35,9 +35,10 @@
|
|||
const arrPoly = ref<google.maps.LatLng[]>([])
|
||||
const mapLoaded = ref(false);
|
||||
const pacinput = ref()
|
||||
const mapel = ref()
|
||||
|
||||
let currentMap : google.maps.Map | undefined;
|
||||
let currentPolygon : google.maps.Polygon | undefined;
|
||||
let currentMap : google.maps.Map;
|
||||
let currentPolygon : google.maps.Polygon;
|
||||
|
||||
onMounted(() => {
|
||||
loader.loadCallback(e => {
|
||||
|
@ -46,7 +47,7 @@
|
|||
return;
|
||||
}
|
||||
|
||||
currentMap = new google.maps.Map(document.getElementById("map"), {
|
||||
currentMap = new google.maps.Map(mapel.value, {
|
||||
zoom: mapPosition.value[2],
|
||||
center: {
|
||||
lat: mapPosition.value[0],
|
||||
|
@ -62,20 +63,23 @@
|
|||
searchBox.addListener('places_changed', () => {
|
||||
const places = searchBox.getPlaces();
|
||||
|
||||
if (places.length == 0) {
|
||||
if (!places || places.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const place = places[0];
|
||||
|
||||
currentMap.setCenter(place.geometry.location);
|
||||
if (place.geometry?.location) {
|
||||
currentMap.setCenter(place.geometry.location);
|
||||
}
|
||||
|
||||
currentMap.setZoom(17);
|
||||
|
||||
reset();
|
||||
});
|
||||
|
||||
currentMap.addListener('bounds_changed', function() {
|
||||
searchBox.setBounds(currentMap.getBounds());
|
||||
searchBox.setBounds(currentMap.getBounds()!);
|
||||
});
|
||||
currentMap.addListener('center_changed', mapUpdated);
|
||||
currentMap.addListener('zoom_changed', mapUpdated);
|
||||
|
@ -107,13 +111,21 @@
|
|||
|
||||
["insert_at", "remove_at", "set_at"].forEach(ev => google.maps.event.addListener(poly.getPath(), ev, surfaceUpdated));
|
||||
updatePolygonColor();
|
||||
|
||||
mapLoaded.value = true;
|
||||
});
|
||||
})
|
||||
|
||||
/*
|
||||
Get the polygon color from the density value.
|
||||
This is a simple linear interpolation between
|
||||
green and red on the Hue space.
|
||||
*/
|
||||
const getHue = (val: number) => {
|
||||
const min = 0.1;
|
||||
/*
|
||||
Clamp "max density" because any value
|
||||
above 3.0 should be considered "red"
|
||||
*/
|
||||
const max = 3.0;
|
||||
|
||||
// inv lerp from the density
|
||||
|
@ -138,9 +150,17 @@
|
|||
const pos = currentMap.getCenter();
|
||||
const zoom = currentMap.getZoom();
|
||||
|
||||
if (!pos || !zoom) {
|
||||
return;
|
||||
}
|
||||
|
||||
mapPosition.value = [pos.lat(), pos.lng(), zoom];
|
||||
}
|
||||
|
||||
/*
|
||||
Add a new point to our polygon
|
||||
using the lat/lng position clicked on the map.
|
||||
*/
|
||||
const mapClicked = (ev: any) => {
|
||||
currentPolygon.getPath().push(ev.latLng);
|
||||
}
|
||||
|
@ -148,6 +168,10 @@
|
|||
const surfaceUpdated = () => {
|
||||
arrPoly.value = currentPolygon.getPath().getArray().slice();
|
||||
|
||||
/*
|
||||
Compute the surface area of our polygon.
|
||||
google.maps.geometry.spherical.computeArea() returns the area in square meters
|
||||
*/
|
||||
emits('surfaceUpdate', google.maps.geometry.spherical.computeArea(currentPolygon.getPath()));
|
||||
}
|
||||
|
||||
|
@ -159,23 +183,34 @@
|
|||
updatePolygonColor();
|
||||
}
|
||||
|
||||
/*
|
||||
Deserialize out URL hash
|
||||
*/
|
||||
const loadHash = (hash: string) => {
|
||||
if (hash[0] != 'b') {
|
||||
if (hash[0] != 'b' && hash[0] != 'c') {
|
||||
return loadLegacyHash(hash);
|
||||
}
|
||||
|
||||
const buf = Base64.toUint8Array(hash.substr(1));
|
||||
const isCompressed = hash[0] == 'c';
|
||||
let buf = Base64.toUint8Array(hash.substr(1));
|
||||
|
||||
if (!buf) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isCompressed) {
|
||||
buf = unzlibSync(buf)
|
||||
}
|
||||
|
||||
/* Extract meta data (density, position & zoom) */
|
||||
const meta = new Float32Array(buf.buffer, 0, 4);
|
||||
/* Extract polygon path */
|
||||
const data = new Float32Array(buf.buffer, 4*4);
|
||||
|
||||
currentMap.setCenter({lat: meta[1], lng: meta[2]});
|
||||
currentMap.setZoom(meta[3]);
|
||||
|
||||
const path = [];
|
||||
const path : google.maps.LatLngLiteral[] = [];
|
||||
for (let i = 0; i < data.length; i += 2) {
|
||||
path.push({
|
||||
lat: data[i],
|
||||
|
@ -191,6 +226,11 @@
|
|||
emits('densityChange', meta[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
This is the legacy hash decoder.
|
||||
We keep it around so that original
|
||||
links posted online keep working
|
||||
*/
|
||||
const loadLegacyHash = (hash: string) => {
|
||||
const opt = hash.split(';');
|
||||
const curPosition = opt.pop();
|
||||
|
@ -201,8 +241,8 @@
|
|||
currentMap.setZoom(parseInt(cursetting[2]));
|
||||
}
|
||||
|
||||
const density = parseFloat(opt.pop()) || 1;
|
||||
const path = [];
|
||||
const density = parseFloat(opt.pop() ?? '') || 1;
|
||||
const path : google.maps.LatLngLiteral[] = [];
|
||||
|
||||
for (let i = 0; i < opt.length; i++) {
|
||||
const coord = opt[i].split(',');
|
||||
|
@ -224,6 +264,21 @@
|
|||
currentPolygon.getPath().clear();
|
||||
}
|
||||
|
||||
/*
|
||||
Generate URL hash from various data.
|
||||
|
||||
- density
|
||||
- Map position (center position as lat/lng & zoom value)
|
||||
- Our polygon path as lat/lng points
|
||||
|
||||
The generated buffer is then compressed (if needed) and Base64'd.
|
||||
|
||||
We consider every value to be a float and serialize
|
||||
our data into a binary array with no extra information.
|
||||
|
||||
0 4 8 12 16 ....
|
||||
[density][position lat][position long][zoom][...polygon points]
|
||||
*/
|
||||
const hash = computed(() => {
|
||||
const buf = new Float32Array(arrPoly.value.length*2+4);
|
||||
buf[0] = props.density;
|
||||
|
@ -233,11 +288,27 @@
|
|||
buf[4+i*2] = arrPoly.value[i].lat();
|
||||
buf[4+i*2+1] = arrPoly.value[i].lng();
|
||||
}
|
||||
return 'b' + Base64.fromUint8Array(new Uint8Array(buf.buffer), true);
|
||||
|
||||
let outbuf = new Uint8Array(buf.buffer);
|
||||
const isCompressed = outbuf.byteLength >= 150;
|
||||
|
||||
if (isCompressed) {
|
||||
outbuf = zlibSync(outbuf, { level: 9 });
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
return (isCompressed ? 'c' : 'b') + Base64.fromUint8Array(outbuf, true);
|
||||
})
|
||||
|
||||
watch(() => props.density, () => updatePolygonColor());
|
||||
|
||||
/*
|
||||
Debounce the URL hash update
|
||||
otherwise it would flood the browser history whenever the user
|
||||
moves the polygon around
|
||||
*/
|
||||
watchDebounced(hash,
|
||||
(hashval: string) => emits('hashChange', hashval),
|
||||
{ debounce: 300 })
|
||||
|
|
|
@ -596,6 +596,11 @@ fastq@^1.6.0:
|
|||
dependencies:
|
||||
reusify "^1.0.4"
|
||||
|
||||
fflate@^0.7.3:
|
||||
version "0.7.3"
|
||||
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.7.3.tgz#288b034ff0e9c380eaa2feff48c787b8371b7fa5"
|
||||
integrity sha512-0Zz1jOzJWERhyhsimS54VTqOteCNwRtIlh8isdL0AXLo0g7xNTfTL7oWrkmCnPhZGocKIkWHBistBrrpoNH3aw==
|
||||
|
||||
fill-range@^7.0.1:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
||||
|
|
Ładowanie…
Reference in New Issue