wip polycurves

This commit is contained in:
Valentyne Stigloher 2024-05-27 16:34:50 +02:00
parent 9bf136d151
commit 717c5339fb
4 changed files with 123 additions and 4 deletions

1
assets/shapes.json Normal file
View File

@ -0,0 +1 @@
[[[43.1, -2.3], [42.1, 2.9], [43.8, 7.4], [45.9, 7], [46.4, 6], [47.5, 7.6], [49, 8.2], [49.5, 6.1], [51.1, 2.5], [49.8, 0.6], [49.6, -1.9], [48.6, -1.5], [48.9, -3.3], [48.5, -4.9], [47.9, -4.6], [46.4, -0.9]], [[54.1, 13.9], [50.3, 15.6], [49.4, 18.9], [49.2, 22.7], [50.4, 24.5], [52.3, 23.2], [54.5, 23.9], [54.5, 18.7], [55.1, 18.2]], [[59, 11.2], [56.5, 12.8], [55.4, 13.1], [55.4, 14.2], [56.1, 14.6], [56.1, 16.1], [58.6, 16.9], [59.8, 19.1], [60.7, 17.4], [63.1, 18.4], [64.5, 21.6], [65.7, 24.1], [68.3, 23.1], [69.1, 20.3], [68.3, 19.8], [68.5, 18], [64.1, 13.9], [63.6, 12.3], [61, 12.5]], [[59.5, 26.6], [59.6, 24.5], [58.6, 22.7], [58, 25], [57.6, 26.3], [57.6, 27.9], [58.5, 27.7], [59.8, 28.4]], [[50.1, -5.4], [50.6, 1.9], [53, 2], [52.9, 0.4], [54.3, 0], [55.6, -1.8], [57.7, -1.7], [57.7, -3.6], [59.9, -1.4], [58.6, -6.2], [57.4, -7.8], [55.6, -6.6], [54.4, -10.1], [51.6, -10.5], [51.2, -9.7], [52.1, -6.5], [50.5, -5.8]], [[39.6, -7], [37.1, -7.3], [37, -8.3], [37, -9], [38.5, -8.9], [38.6, -9.4], [41.8, -9], [41.9, -7.9], [41.8, -6.4], [41.6, -6.1]], [[38.8, 10.5], [35.4, -1.9], [31.9, -1.2], [28.1, -9.1], [18.3, 3.4], [23.2, 11.9], [19.3, 23.9], [22.2, 36.9], [10.1, 43.7], [19.3, 55.6], [22.4, 55.7], [24.3, 51.7], [28.6, 48.2], [32, 39.2], [29.7, 35]], [[46.6, 11], [46.2, 15.6], [47.6, 16.7], [48.6, 17.3], [49, 15.3], [48.8, 13.8], [49.4, 12.7], [50.6, 12.2], [50.7, 15.2], [52.7, 14.2], [54.7, 14.2], [54.4, 11.7], [55.1, 8.1], [53.9, 6.8], [52.1, 7.2], [50.9, 5.9], [49.3, 6.6], [47.6, 7.5], [47.2, 8.9]], [], [[37.1, -7.5], [35.7, -5.7], [36.6, -2.3], [38.6, 0.4], [40.4, -0.4], [42.2, 4.7], [42.7, -0.5], [43.8, -2.6], [43.8, -11.2], [42.2, -7.9], [42.1, -5.4]], [[43.8, 28.8], [45.3, 29.8], [45.3, 28.4], [48.3, 26.9], [48, 25], [48, 23.1], [46.1, 20.6], [44.3, 22.5], [43.5, 24.9]], [[52.3, 32.8], [51.4, 30.4], [51.6, 24], [50.8, 24.4], [48.6, 22.2], [48.1, 23.1], [48.3, 27.6], [46.4, 30], [45.7, 29], [45.3, 30], [46.3, 31.8], [46, 33.6], [45.3, 32.5], [44.4, 33.5], [45.1, 36.7], [47.1, 38.4], [49.6, 40.2], [51.1, 35.4]], [[58.1, 11], [61.5, 12.1], [63.2, 12], [64.1, 13.5], [64.6, 13.7], [68.1, 17.1], [69.3, 21.4], [68.7, 23.1], [68.6, 25], [69.9, 26.4], [69.7, 29.2], [68.9, 28.7], [69.7, 30.9], [70.4, 31], [71.2, 26], [69.9, 18.2], [67.8, 12.6], [67.8, 14.3], [63.6, 9.2], [62, 4.7], [58.6, 5], [58, 6.9]], [[41.4, 35.7], [42.7, 31.9], [39.3, 29.8], [31.5, 34.6], [31.1, 35.6]], [[53.5, 6.7], [53.2, 4.9], [51.5, 3.5], [51.3, 5.7], [52.2, 6.8]], [[18.3, 56]]]

View File

@ -1,18 +1,23 @@
<template>
<div id="map" :class="isDark ? 'dark' : ''"></div>
<div>
<div id="map" :class="isDark ? 'dark' : ''"></div>
{{ JSON.stringify(polygons) }}
</div>
</template>
<script lang="ts">
import dark from '../plugins/dark.ts';
import walsLanguages from '~/assets/languages.csv';
import polygons from '~/assets/shapes.json';
import locales from '../locale/locales.ts';
import { clearUrl } from '~/src/helpers.ts';
import type { LocaleDescription } from '../locale/locales.ts';
import type { GridLayerOptions } from 'leaflet/index.d.ts';
import type { GridLayerOptions, LatLng } from 'leaflet/index.d.ts';
const MOBILE_BREAKPOINT = 992;
const localesByWalsCode = locales.reduce((acc, language) => {
if (language.walsCode && language.published) {
acc[language.walsCode] = language;
@ -30,23 +35,88 @@ declare module 'leaflet' {
}
export default dark.extend({
data() {
return {
inputCurve: null as any,
curve: null as any,
controls: [],
polygons,
};
},
watch: {
polygons() {
this.update();
},
},
methods: {
update() {
const inputPath = [];
const polygonPath = [];
for (const polygon of this.polygons) {
if (polygon.length >= 1) {
inputPath.push('M', polygon[0]);
}
for (let i = 1; i < polygon.length; i++) {
inputPath.push('L', polygon[i]);
}
inputPath.push('Z');
const middleOf = (a: [number, number], b: [number, number]) => {
return [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2];
};
if (polygon.length >= 3) {
polygonPath.push('M', middleOf(polygon[0], polygon[1]));
polygonPath.push('Q', polygon[1], middleOf(polygon[1], polygon[2]));
for (let i = 2; i < polygon.length - 1; i++) {
polygonPath.push('T', middleOf(polygon[i], polygon[i + 1]));
}
polygonPath.push('T', middleOf(polygon[polygon.length - 1], polygon[0]));
polygonPath.push('T', middleOf(polygon[0], polygon[1]));
}
}
// this.inputCurve.setPath(inputPath);
this.curve.setPath(polygonPath);
},
},
async mounted() {
const { default: L } = await import('leaflet');
await import ('@elfalem/leaflet-curve');
await this.$loadScript(
'tinyworldmap',
'https://tinyworldmap.com/dist/v3/tiny-world-borders.js',
);
const toPoint = (latlng: LatLng): [number, number] => {
return [Math.round(latlng.lat * 10) / 10, Math.round(latlng.lng * 10) / 10];
};
const map = L.map('map', {
attributionControl: false,
worldCopyJump: true,
center: window.innerWidth < MOBILE_BREAKPOINT ? [45, 15] : [40, 65],
zoom: 3,
center: [50, 12.8],
zoom: 5,
minZoom: 2,
maxZoom: 5,
maxBounds: [[-75, Number.NEGATIVE_INFINITY], [85, Number.POSITIVE_INFINITY]],
});
map.addEventListener('click', (event) => {
this.polygons[this.polygons.length - 1].push(toPoint(event.latlng));
});
window.addEventListener('keydown', (event) => {
switch (event.key) {
case 'Enter':
this.polygons.push([]);
return false;
case 'Backspace':
this.polygons[this.polygons.length - 1].pop();
event.preventDefault();
return false;
}
});
L.control.attribution({ position: 'bottomright' })
.addAttribution('&copy; <a href="https://doi.org/10.5281/zenodo.7385533" target="_blank" title="Dryer, Matthew S. & Haspelmath, Martin (eds.) 2013. The World Atlas of Language Structures Online. Leipzig: Max Planck Institute for Evolutionary Anthropology.">WALS</a>')
.addAttribution('<a href="https://wals.info" target="_blank">wals.info</a>')
@ -70,6 +140,32 @@ export default dark.extend({
},
}).addTo(map);
this.inputCurve = L.curve([], {
color: '#ffffff',
opacity: 0.5,
}).addTo(map);
this.curve = L.curve([], {
color: '#971064',
fill: true,
fillColor: '#c71585',
fillOpacity: 0.5,
fillRule: 'nonzero',
}).addTo(map);
/* for (let i = 0; i < this.polygons.length; i++) {
for (let j = 0; j < this.polygons[i].length; j++) {
const marker = L.marker(this.polygons[i][j], {
icon: L.divIcon({ className: 'fas fa-circle' }),
draggable: true,
}).addTo(map);
marker.on('drag', () => {
polygons[i][j] = toPoint(marker.getLatLng());
this.update();
});
}
}*/
for (const walsLanguage of walsLanguages) {
if (!localesByWalsCode.hasOwnProperty(walsLanguage.id)) {
continue;
@ -89,6 +185,7 @@ export default dark.extend({
});
}
}
this.update();
},
});
</script>
@ -114,5 +211,6 @@ export default dark.extend({
.leaflet-container {
font: inherit;
cursor: crosshair;
}
</style>

View File

@ -16,6 +16,7 @@
"dependencies": {
"@aws-sdk/client-polly": "^3.525.0",
"@aws-sdk/client-s3": "^3.525.0",
"@elfalem/leaflet-curve": "^0.9.2",
"@floating-ui/dom": "^1.6.3",
"@nuxtjs/axios": "^5.13.6",
"@nuxtjs/pwa": "3.3.5",

19
pnpm-lock.yaml generated
View File

@ -11,6 +11,9 @@ dependencies:
'@aws-sdk/client-s3':
specifier: ^3.525.0
version: 3.536.0
'@elfalem/leaflet-curve':
specifier: ^0.9.2
version: 0.9.2(leaflet@1.9.4)
'@floating-ui/dom':
specifier: ^1.6.3
version: 1.6.3
@ -2872,6 +2875,16 @@ packages:
engines: {node: '>=10.0.0'}
dev: false
/@elfalem/leaflet-curve@0.9.2(leaflet@1.9.4):
resolution: {integrity: sha512-vHhJZvkTHHQsOeEPRnTYpKjmWZ7DEKVJ7rHh1xeksTi/maoxK3dCd6o59LoT3Uk6kNIvmzwrOFMHN3T+WfsbwA==}
peerDependencies:
leaflet: ^1.1.0
dependencies:
leaflet: 1.9.4
optionalDependencies:
'@tweenjs/tween.js': 17.6.0
dev: false
/@eslint-community/eslint-utils@4.4.0(eslint@8.55.0):
resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@ -4677,6 +4690,12 @@ packages:
/@tsconfig/node16@1.0.4:
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
/@tweenjs/tween.js@17.6.0:
resolution: {integrity: sha512-utSXj0WHi4qr/iyfFHGMJBaL+ixQ2N7BAmx1R5g8jBqykJfjBUQ0hKWwXf767hbALC3zOoOIofKYSDWu5n04JQ==}
requiresBuild: true
dev: false
optional: true
/@types/autoprefixer@10.2.0(postcss@8.4.38):
resolution: {integrity: sha512-ClU0uw3HhUra890K4xcf2IQxD6w0WOjPIaKb8jrRXYPHvvUW1P5dGufPlDtTo5gtWPWH+4L6tSBAoAKVf93uBQ==}
deprecated: This is a stub types definition. autoprefixer provides its own type definitions, so you do not need this installed.