⚡ Minor optimizations
This commit is contained in:
parent
0b7af7ce99
commit
6703a197fb
@ -3,6 +3,8 @@ import "leaflet.markercluster";
|
|||||||
import "leaflet-contextmenu";
|
import "leaflet-contextmenu";
|
||||||
import { Place } from "../types/poi";
|
import { Place } from "../types/poi";
|
||||||
|
|
||||||
|
export const DEFAULT_TILE_URL =
|
||||||
|
"https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png";
|
||||||
export interface ContextMenuItem {
|
export interface ContextMenuItem {
|
||||||
text: string;
|
text: string;
|
||||||
index?: number;
|
index?: number;
|
||||||
@ -19,41 +21,34 @@ export interface MarkerOptions extends L.MarkerOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function createMap(
|
export function createMap(
|
||||||
contextMenuItems?: ContextMenuItem[],
|
contextMenuItems: ContextMenuItem[] = [],
|
||||||
tilelayer?: string,
|
tilelayer: string = DEFAULT_TILE_URL,
|
||||||
): L.Map {
|
): L.Map {
|
||||||
let southWest = L.latLng(-89.99, -180);
|
const southWest = L.latLng(-89.99, -180);
|
||||||
let northEast = L.latLng(89.99, 180);
|
const northEast = L.latLng(89.99, 180);
|
||||||
let bounds = L.latLngBounds(southWest, northEast);
|
const bounds = L.latLngBounds(southWest, northEast);
|
||||||
|
|
||||||
let _contextMenuItems = contextMenuItems || [];
|
const map = L.map("map", {
|
||||||
let map = L.map("map", {
|
|
||||||
maxBoundsViscosity: 1.0,
|
maxBoundsViscosity: 1.0,
|
||||||
zoomControl: false,
|
zoomControl: false,
|
||||||
contextmenu: true,
|
contextmenu: true,
|
||||||
contextmenuItems: _contextMenuItems,
|
contextmenuItems: contextMenuItems,
|
||||||
} as MapOptions)
|
} as MapOptions)
|
||||||
.setZoom(10)
|
.setZoom(10)
|
||||||
.setMaxBounds(bounds);
|
.setMaxBounds(bounds);
|
||||||
|
|
||||||
L.tileLayer(
|
L.tileLayer(tilelayer, {
|
||||||
tilelayer ||
|
|
||||||
"https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",
|
|
||||||
{
|
|
||||||
maxZoom: 17,
|
maxZoom: 17,
|
||||||
minZoom: 3,
|
minZoom: 3,
|
||||||
attribution:
|
attribution:
|
||||||
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, © <a href="https://carto.com/attributions">CARTO</a>',
|
'© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, © <a href="https://carto.com/attributions">CARTO</a>',
|
||||||
},
|
}).addTo(map);
|
||||||
).addTo(map);
|
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function placeHoverTooltip(place: Place): string {
|
export function placeHoverTooltip(place: Place): string {
|
||||||
let content = `<div class="font-semibold mb-1 truncate" style="font-size:1.1em">${place.name}</div>`;
|
return `<div class="font-semibold mb-1 truncate" style="font-size:1.1em">${place.name}</div><div><span style="color:${place.category.color}; background:${place.category.color}1A;" class="text-xs font-medium px-2.5 py-0.5 rounded">${place.category.name}</span></div>`.trim();
|
||||||
content += `<div><span style="color:${place.category.color}; background:${place.category.color}1A;" class="text-xs font-medium px-2.5 py-0.5 rounded">${place.category.name}</span></div>`;
|
|
||||||
return content;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createClusterGroup(): L.MarkerClusterGroup {
|
export function createClusterGroup(): L.MarkerClusterGroup {
|
||||||
@ -62,7 +57,7 @@ export function createClusterGroup(): L.MarkerClusterGroup {
|
|||||||
disableClusteringAtZoom: 11,
|
disableClusteringAtZoom: 11,
|
||||||
showCoverageOnHover: false,
|
showCoverageOnHover: false,
|
||||||
maxClusterRadius: 50,
|
maxClusterRadius: 50,
|
||||||
iconCreateFunction: function (cluster) {
|
iconCreateFunction: (cluster) => {
|
||||||
const count = cluster.getChildCount();
|
const count = cluster.getChildCount();
|
||||||
return L.divIcon({
|
return L.divIcon({
|
||||||
html: `<div class="custom-cluster">${count}</div>`,
|
html: `<div class="custom-cluster">${count}</div>`,
|
||||||
@ -85,7 +80,7 @@ export function tripDayMarker(item: {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
let touchDevice = "ontouchstart" in window;
|
const touchDevice = "ontouchstart" in window;
|
||||||
if (!touchDevice) {
|
if (!touchDevice) {
|
||||||
marker.bindTooltip(
|
marker.bindTooltip(
|
||||||
`<div class="font-semibold mb-1 truncate text-base">${item.text}</div>`,
|
`<div class="font-semibold mb-1 truncate text-base">${item.text}</div>`,
|
||||||
@ -105,11 +100,9 @@ export function placeToMarker(
|
|||||||
grayscale: boolean = false,
|
grayscale: boolean = false,
|
||||||
gpxInBubble: boolean = false,
|
gpxInBubble: boolean = false,
|
||||||
): L.Marker {
|
): L.Marker {
|
||||||
let marker: L.Marker;
|
const options: Partial<L.MarkerOptions> = {
|
||||||
let options: any = {
|
|
||||||
riseOnHover: true,
|
riseOnHover: true,
|
||||||
title: place.name,
|
title: place.name,
|
||||||
place_id: place.id,
|
|
||||||
alt: "",
|
alt: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -119,6 +112,7 @@ export function placeToMarker(
|
|||||||
|
|
||||||
let markerClasses = "w-full h-full rounded-full bg-center bg-cover bg-white";
|
let markerClasses = "w-full h-full rounded-full bg-center bg-cover bg-white";
|
||||||
if (grayscale) markerClasses += " grayscale";
|
if (grayscale) markerClasses += " grayscale";
|
||||||
|
|
||||||
const iconHtml = `
|
const iconHtml = `
|
||||||
<div class="flex items-center justify-center relative rounded-full marker-anchor size-14 box-border" style="border: 2px solid ${place.category.color};">
|
<div class="flex items-center justify-center relative rounded-full marker-anchor size-14 box-border" style="border: 2px solid ${place.category.color};">
|
||||||
<div class="${markerClasses}" style="background-image: url('${markerImage}');"></div>
|
<div class="${markerClasses}" style="background-image: url('${markerImage}');"></div>
|
||||||
@ -127,17 +121,17 @@ export function placeToMarker(
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const icon = L.divIcon({
|
const icon = L.divIcon({
|
||||||
html: iconHtml,
|
html: iconHtml.trim(),
|
||||||
iconSize: [56, 56],
|
iconSize: [56, 56],
|
||||||
className: "",
|
className: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
marker = new L.Marker([+place.lat, +place.lng], {
|
const marker = new L.Marker([+place.lat, +place.lng], {
|
||||||
...options,
|
...options,
|
||||||
icon,
|
icon,
|
||||||
});
|
});
|
||||||
|
|
||||||
let touchDevice = "ontouchstart" in window;
|
const touchDevice = "ontouchstart" in window;
|
||||||
if (!touchDevice) {
|
if (!touchDevice) {
|
||||||
marker.bindTooltip(placeHoverTooltip(place), {
|
marker.bindTooltip(placeHoverTooltip(place), {
|
||||||
direction: "right",
|
direction: "right",
|
||||||
@ -153,12 +147,13 @@ export function gpxToPolyline(gpx: string): L.Polyline {
|
|||||||
const gpxDoc = parser.parseFromString(gpx, "application/xml");
|
const gpxDoc = parser.parseFromString(gpx, "application/xml");
|
||||||
|
|
||||||
const trkpts = Array.from(gpxDoc.querySelectorAll("trkpt"));
|
const trkpts = Array.from(gpxDoc.querySelectorAll("trkpt"));
|
||||||
const latlngs = trkpts.map((pt) => {
|
const latlngs = trkpts.map(
|
||||||
return [
|
(pt) =>
|
||||||
|
[
|
||||||
parseFloat(pt.getAttribute("lat")!),
|
parseFloat(pt.getAttribute("lat")!),
|
||||||
parseFloat(pt.getAttribute("lon")!),
|
parseFloat(pt.getAttribute("lon")!),
|
||||||
] as [number, number];
|
] as [number, number],
|
||||||
});
|
);
|
||||||
|
|
||||||
return L.polyline(latlngs, { color: "blue" });
|
return L.polyline(latlngs, { color: "blue" });
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user