maps
This commit is contained in:
parent
fa7c623002
commit
ea6f7934ec
|
|
@ -19,7 +19,7 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
leaflet-map,
|
folk-map,
|
||||||
geo-wiki {
|
geo-wiki {
|
||||||
display: block;
|
display: block;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
@ -38,34 +38,27 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<fc-geometry x="25" y="100" width="400" height="200">
|
<fc-geometry x="25" y="100" width="400" height="200">
|
||||||
<leaflet-map coordinates="52.09, 5.12" zoom="13"></leaflet-map>
|
<folk-map coordinates="52.09, 5.12" zoom="13"></folk-map>
|
||||||
</fc-geometry>
|
</fc-geometry>
|
||||||
|
|
||||||
<fc-geometry x="50" y="550" width="400" height="250">
|
<fc-geometry x="50" y="550" width="400" height="250">
|
||||||
<leaflet-map
|
<folk-map coordinates="51.50404120260676, -0.14007568359375003" zoom="13"></folk-map>
|
||||||
coordinates="51.50404120260676, -0.14007568359375003"
|
|
||||||
zoom="13"
|
|
||||||
></leaflet-map>
|
|
||||||
</fc-geometry>
|
</fc-geometry>
|
||||||
|
|
||||||
<fc-geometry x="500" y="400" width="500" height="300">
|
<fc-geometry x="500" y="400" width="500" height="300">
|
||||||
<geo-wiki
|
<geo-wiki coordinates="51.50404120260676, -0.14007568359375003"></geo-wiki>
|
||||||
coordinates="51.50404120260676, -0.14007568359375003"
|
|
||||||
></geo-wiki>
|
|
||||||
</fc-geometry>
|
</fc-geometry>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
|
import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
|
||||||
import { LeafletMap } from '../src/maps';
|
import { FolkMap } from '../src/maps';
|
||||||
|
|
||||||
FolkGeometry.register();
|
FolkGeometry.register();
|
||||||
LeafletMap.register();
|
FolkMap.register();
|
||||||
|
|
||||||
function collisionDetection(rect1, rect2) {
|
function collisionDetection(rect1, rect2) {
|
||||||
return (
|
return (
|
||||||
rect1.left < rect2.right &&
|
rect1.left < rect2.right && rect1.right > rect2.left && rect1.top < rect2.bottom && rect1.bottom > rect2.top
|
||||||
rect1.right > rect2.left &&
|
|
||||||
rect1.top < rect2.bottom &&
|
|
||||||
rect1.bottom > rect2.top
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,12 +74,7 @@
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const proximityMap = new Map(
|
const proximityMap = new Map(Array.from(document.querySelectorAll('fc-geometry')).map((el) => [el, new Set()]));
|
||||||
Array.from(document.querySelectorAll('fc-geometry')).map((el) => [
|
|
||||||
el,
|
|
||||||
new Set(),
|
|
||||||
])
|
|
||||||
);
|
|
||||||
|
|
||||||
function handleProximity(e) {
|
function handleProximity(e) {
|
||||||
proximityMap.forEach((set, el) => {
|
proximityMap.forEach((set, el) => {
|
||||||
|
|
@ -124,7 +112,7 @@
|
||||||
proximityMap.get(e.target.parentElement)?.forEach((el) => {
|
proximityMap.get(e.target.parentElement)?.forEach((el) => {
|
||||||
const content = el.firstElementChild;
|
const content = el.firstElementChild;
|
||||||
if (content instanceof GeoWiki) {
|
if (content instanceof GeoWiki) {
|
||||||
const { lat, lng } = e.detail;
|
const { lat, lng } = e.target.coordinates;
|
||||||
content.coordinates = [lat, lng];
|
content.coordinates = [lat, lng];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -152,9 +140,7 @@
|
||||||
|
|
||||||
attributeChangedCallback(name, oldValue, newValue) {
|
attributeChangedCallback(name, oldValue, newValue) {
|
||||||
if (name === 'coordinates') {
|
if (name === 'coordinates') {
|
||||||
this.#coordinates = newValue
|
this.#coordinates = newValue.split(',').map((str) => Number(str)) || [0, 0];
|
||||||
.split(',')
|
|
||||||
.map((str) => Number(str)) || [0, 0];
|
|
||||||
this.searchWiki(this.#coordinates);
|
this.searchWiki(this.#coordinates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -170,9 +156,7 @@
|
||||||
origin: '*',
|
origin: '*',
|
||||||
});
|
});
|
||||||
// https://www.mediawiki.org/wiki/API:Geosearch
|
// https://www.mediawiki.org/wiki/API:Geosearch
|
||||||
this.#results = await fetch(
|
this.#results = await fetch(`https://en.wikipedia.org/w/api.php?${params}`)
|
||||||
`https://en.wikipedia.org/w/api.php?${params}`
|
|
||||||
)
|
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => data?.query?.geosearch ?? []);
|
.then((data) => data?.query?.geosearch ?? []);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
"preview": "vite build demo && vite preview demo"
|
"preview": "vite build demo && vite preview demo"
|
||||||
},
|
},
|
||||||
"imports": {
|
"imports": {
|
||||||
|
"@types/leaflet": "npm:@types/leaflet@^1.9.14",
|
||||||
"perfect-arrows": "npm:perfect-arrows@^0.3.7",
|
"perfect-arrows": "npm:perfect-arrows@^0.3.7",
|
||||||
"perfect-freehand": "npm:perfect-freehand@^1.2.2",
|
"perfect-freehand": "npm:perfect-freehand@^1.2.2",
|
||||||
"leaflet": "npm:leaflet@^1.9.4",
|
"leaflet": "npm:leaflet@^1.9.4",
|
||||||
|
|
|
||||||
11
deno.lock
11
deno.lock
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"version": "4",
|
"version": "4",
|
||||||
"specifiers": {
|
"specifiers": {
|
||||||
|
"npm:@types/leaflet@^1.9.14": "1.9.14",
|
||||||
"npm:leaflet@^1.9.4": "1.9.4",
|
"npm:leaflet@^1.9.4": "1.9.4",
|
||||||
"npm:perfect-arrows@~0.3.7": "0.3.7",
|
"npm:perfect-arrows@~0.3.7": "0.3.7",
|
||||||
"npm:perfect-freehand@^1.2.2": "1.2.2",
|
"npm:perfect-freehand@^1.2.2": "1.2.2",
|
||||||
|
|
@ -134,6 +135,15 @@
|
||||||
"@types/estree@1.0.6": {
|
"@types/estree@1.0.6": {
|
||||||
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
|
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
|
||||||
},
|
},
|
||||||
|
"@types/geojson@7946.0.14": {
|
||||||
|
"integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg=="
|
||||||
|
},
|
||||||
|
"@types/leaflet@1.9.14": {
|
||||||
|
"integrity": "sha512-sx2q6MDJaajwhKeVgPSvqXd8rhNJSTA3tMidQGduZn9S6WBYxDkCpSpV5xXEmSg7Cgdk/5vJGhVF1kMYLzauBg==",
|
||||||
|
"dependencies": [
|
||||||
|
"@types/geojson"
|
||||||
|
]
|
||||||
|
},
|
||||||
"esbuild@0.21.5": {
|
"esbuild@0.21.5": {
|
||||||
"integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
|
"integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
|
|
@ -228,6 +238,7 @@
|
||||||
},
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"dependencies": [
|
"dependencies": [
|
||||||
|
"npm:@types/leaflet@^1.9.14",
|
||||||
"npm:leaflet@^1.9.4",
|
"npm:leaflet@^1.9.4",
|
||||||
"npm:perfect-arrows@~0.3.7",
|
"npm:perfect-arrows@~0.3.7",
|
||||||
"npm:perfect-freehand@^1.2.2",
|
"npm:perfect-freehand@^1.2.2",
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,8 @@
|
||||||
import {
|
import { LatLng, LatLngExpression, LeafletEvent, map, Map, tileLayer } from 'leaflet';
|
||||||
LatLng,
|
|
||||||
LatLngExpression,
|
|
||||||
LeafletEvent,
|
|
||||||
map,
|
|
||||||
Map,
|
|
||||||
tileLayer,
|
|
||||||
} from "leaflet";
|
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
// Vite specific import :(
|
// Vite specific import :(
|
||||||
import css from "leaflet/dist/leaflet.css?inline";
|
import css from 'leaflet/dist/leaflet.css?inline';
|
||||||
const styles = new CSSStyleSheet();
|
const styles = new CSSStyleSheet();
|
||||||
styles.replaceSync(`${css}
|
styles.replaceSync(`${css}
|
||||||
:host {
|
:host {
|
||||||
|
|
@ -22,54 +15,69 @@ styles.replaceSync(`${css}
|
||||||
}
|
}
|
||||||
`);
|
`);
|
||||||
|
|
||||||
export class RecenterEvent extends CustomEvent<LatLng> {
|
export class RecenterEvent extends Event {
|
||||||
constructor(detail: LatLng) {
|
constructor() {
|
||||||
super("recenter", { detail, bubbles: true });
|
super('recenter', { bubbles: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LeafletMap extends HTMLElement {
|
export class FolkMap extends HTMLElement {
|
||||||
static tagName = "leaflet-map";
|
static tagName = 'folk-map';
|
||||||
|
|
||||||
static register() {
|
static register() {
|
||||||
customElements.define(this.tagName, this);
|
customElements.define(this.tagName, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
#container = document.createElement("div");
|
#container = document.createElement('div');
|
||||||
#map!: Map;
|
#map!: Map;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.handleEvent = this.handleEvent.bind(this);
|
this.handleEvent = this.handleEvent.bind(this);
|
||||||
const shadow = this.attachShadow({ mode: "open" });
|
|
||||||
|
const shadow = this.attachShadow({ mode: 'open' });
|
||||||
shadow.adoptedStyleSheets.push(styles);
|
shadow.adoptedStyleSheets.push(styles);
|
||||||
shadow.appendChild(this.#container);
|
shadow.appendChild(this.#container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get coordinates() {
|
||||||
|
return this.#map.getCenter();
|
||||||
|
}
|
||||||
|
set coordinates(coordinates) {
|
||||||
|
this.#map.setView(coordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
get zoom() {
|
||||||
|
return this.#map.getZoom();
|
||||||
|
}
|
||||||
|
set zoom(zoom) {
|
||||||
|
this.#map.setZoom(zoom);
|
||||||
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
this.#map = map(this.#container);
|
this.#map = map(this.#container);
|
||||||
this.#map.addLayer(
|
this.#map.addLayer(
|
||||||
tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||||
maxZoom: 19,
|
maxZoom: 19,
|
||||||
attribution:
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
||||||
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const coordinates = (this.getAttribute("coordinates")
|
|
||||||
?.split(",")
|
|
||||||
.map((str) => Number(str)) || [0, 0]) as LatLngExpression;
|
|
||||||
const zoom = Number(this.getAttribute("zoom") || 13);
|
|
||||||
this.#map.setView(coordinates, zoom);
|
|
||||||
|
|
||||||
this.#map.on("zoom", this.handleEvent);
|
this.#map.on('zoom', this.handleEvent);
|
||||||
this.#map.on("moveend", this.handleEvent);
|
this.#map.on('moveend', this.handleEvent);
|
||||||
|
|
||||||
|
this.#map.setView(
|
||||||
|
(this.getAttribute('coordinates') || '0, 0').split(',').map(Number) as LatLngExpression,
|
||||||
|
Number(this.getAttribute('zoom') || 13)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEvent(event: LeafletEvent) {
|
handleEvent(event: LeafletEvent) {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case "zoom":
|
case 'zoom':
|
||||||
case "moveend": {
|
case 'moveend': {
|
||||||
this.dispatchEvent(new RecenterEvent(this.#map.getCenter()));
|
this.dispatchEvent(new RecenterEvent());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue