Source CursorPosition
Source CursorPosition
Cette page est générée automatiquement à partir du dépôt local au moment de la génération de la documentation.
Fichiers inclus
packages/common/src/lib/widgets/cursor-position/cursor-position.declaration.tspackages/common/src/lib/widgets/cursor-position/cursor-position.config.tspackages/common/src/lib/widgets/cursor-position/CursorPosition.sveltepackages/common/src/lib/widgets/cursor-position/index.ts
packages/common/src/lib/widgets/cursor-position/cursor-position.declaration.ts
import { widgetFactorySvelte, type WidgetProps } from '$lib/api/managers/widget';import { type CursorPositionConfig, cursorPositionConfigSchema } from './cursor-position.config';import type { WidgetDeclaration } from '$lib/api/managers/widget/widget-declaration';
export const declaration = { factory: () => import('./CursorPosition.svelte').then((CursorPosition) => widgetFactorySvelte(CursorPosition)), schema: () => cursorPositionConfigSchema,} satisfies WidgetDeclaration;
export type CursorPositionProps = WidgetProps<CursorPositionConfig>;packages/common/src/lib/widgets/cursor-position/cursor-position.config.ts
import { defineWidgetConfig } from '$lib/api/managers/configuration';import { inToolbarSchemaFrom } from '$lib/api/managers/configuration/models/widget/widget-in-toolbar.schema';import { i18nDataSchema, i18nSchemaFrom } from '$lib/api/managers/i18n';import { z } from 'zod';
const cursorPositionProjectionOption = z.object({ wkid: z.number(), label: i18nDataSchema, unit: z.string().optional(), precision: z.number().optional(), dms: z.boolean().optional(), xLabel: z.string().optional(), yLabel: z.string().optional(), key: z.string(),});export type CursorPositionProjectionOption = z.infer<typeof cursorPositionProjectionOption>;
export const LAMBERT_2008_OPTION = { label: 'Lambert Belge 2008', wkid: 3812, unit: 'm', key: 'lambert-belge-2008',};
export const cursorPositionConfigSchema = defineWidgetConfig({ inToolbar: inToolbarSchemaFrom(false), active: true, i18n: i18nSchemaFrom({ 'dropdown-label': { fr: 'Coordonnées du pointeur en', nl: 'NL - Coordonnées du pointeur en', }, }), config: z .object({ defaultWkid: z.number().optional(), options: cursorPositionProjectionOption.array().default([ { label: 'Lambert Belge 1972', wkid: 31370, unit: 'm', key: 'lambert-belge-1972', }, LAMBERT_2008_OPTION, { label: 'WGS84 (DD)', wkid: 4326, precision: 5, unit: '°', xLabel: 'Long', yLabel: 'Lat', key: 'wgs84-dd', }, { label: 'WGS84 (DMS)', wkid: 4326, dms: true, xLabel: 'Long', yLabel: 'Lat', key: 'wgs84-dms', }, ]), }) .prefault({}),});
export type CursorPositionConfig = z.infer<typeof cursorPositionConfigSchema>;packages/common/src/lib/widgets/cursor-position/CursorPosition.svelte
<script lang="ts"> import { getI18n } from '$lib/api/managers/i18n'; import { Projections } from '$lib/api/managers/projection'; import { getMapManager } from '$lib/api/map'; import { type CardinalLabels, formatDms, parseDms } from '$lib/api/utils/format.utils'; import { ApiSelect, type ApiSelectItem } from '$lib/components/api-select'; import { onDestroy, tick } from 'svelte'; import { type CursorPositionProjectionOption, LAMBERT_2008_OPTION } from './cursor-position.config'; import type { ApiPoint } from '$lib/api/geometry'; import { cn } from '$lib/components/shadcn/utils'; import type { CursorPositionProps } from './cursor-position.declaration';
type ResultFormat = { x: string; y: string; xLabel: string; yLabel: string; unit: string; };
const { fullConfig }: CursorPositionProps = $props();
const mapManager = getMapManager(); const zoom = mapManager.tools.zoom; const transform = mapManager.tools.transform; const i18n = getI18n(fullConfig.i18n); const defaultWkid = fullConfig.config.defaultWkid; const defaultOption = defaultWkid ? fullConfig.config.options.find((x) => x.wkid === defaultWkid) : fullConfig.config.options[0];
let selectedProjection = $state<CursorPositionProjectionOption>(defaultOption ?? LAMBERT_2008_OPTION); const options: ApiSelectItem<CursorPositionProjectionOption>[] = $derived( fullConfig.config.options.map((o) => ({ value: o, label: i18n.translate(o.label), })), );
$effect(() => { if (selectedProjection) { editMode = false; } });
const isWGS84 = $derived.by(() => { return selectedProjection.wkid === Projections.WGS_1984.wkid; });
const cardinalLabels: CardinalLabels = $derived.by(() => { return { north: i18n('common.cardinal-north'), south: i18n('common.cardinal-south'), west: i18n('common.cardinal-west'), east: i18n('common.cardinal-east'), }; });
let point = $state<ApiPoint | null>(null); let editMode = $state<boolean>(false); let xCoordValue = $state<number | string>(0); let yCoordValue = $state<number | string>(0); let xCoordInput = $state<HTMLInputElement | undefined>(); let yCoordInput = $state<HTMLInputElement | undefined>();
const formated = $derived.by(() => { if (point) { if (!selectedProjection) { return { x: point.x.toFixed(0), y: point.y.toFixed(0), xLabel: 'x', yLabel: 'y', unit: '', } satisfies ResultFormat; }
const projected = transform.transformPoint(point, selectedProjection.wkid);
if (selectedProjection.dms) { return { x: formatDms(projected.x, 'X', cardinalLabels), y: formatDms(projected.y, 'Y', cardinalLabels), xLabel: selectedProjection.xLabel ?? 'Long', yLabel: selectedProjection.yLabel ?? 'Lat', unit: '', } satisfies ResultFormat; }
return { x: projected.x.toFixed(selectedProjection.precision ?? 0), y: projected.y.toFixed(selectedProjection.precision ?? 0), xLabel: selectedProjection.xLabel ?? 'x', yLabel: selectedProjection.yLabel ?? 'y', unit: selectedProjection.unit ?? '', } satisfies ResultFormat; } return null; });
function validate(event: KeyboardEvent) { if (event.key === 'Enter' && formated) { let xCoord: string | number = xCoordValue; let yCoord: string | number = yCoordValue; if (selectedProjection.dms) { const { x, y } = parseDms(`${xCoordValue}`, `${yCoordValue}`); xCoord = x; yCoord = y; } zoom.zoomToPoint({ x: Number(xCoord), y: Number(yCoord), wkid: selectedProjection.wkid, }); editMode = false; } }
function activateEditMode(inputClick: HTMLInputElement | undefined) { editMode = true; if (!formated) return; xCoordValue = formated.x; yCoordValue = formated.y; tick().then(() => inputClick?.focus()); }
const unsub = mapManager.tools.events.on('hover', (p) => (point = p));
onDestroy(() => { unsub(); });</script>
<div class="gv-bg-black/40 gv-text-white gv-flex gv-items-center gv-h-5 gv-gap-1 gv-px-1 gv-py-0.5 gv-text-sm gv-leading-3"> <span>{i18n('dropdown-label')}</span>
<ApiSelect bind:value={selectedProjection} {options} getKey={(p) => p.key} class="gv-h-5 gv-bg-transparent gv-w-[12rem] gv-border-none" contentClass="gv-bg-black/40 gv-text-white" dataTestId="CursorPosition-ProjectionSelect" />
{#if formated} <span> {formated.xLabel} = <input onkeydown={validate} bind:this={xCoordInput} bind:value={xCoordValue} class={cn(editMode ? 'gv-visible' : 'gv-hidden', 'gv-bg-black/50 focus:gv-outline-none gv-m-0')} type={isWGS84 ? 'text' : 'number'} data-test-id="CursorPosition-XInput" /> <button class={cn(editMode ? 'gv-hidden' : 'gv-visible', '')} onclick={() => activateEditMode(xCoordInput)}> {formated.x} </button> <span class="gv-mr-3">{formated.unit}</span> {formated.yLabel} = <input onkeydown={validate} bind:this={yCoordInput} bind:value={yCoordValue} class={cn(editMode ? 'gv-visible' : 'gv-hidden', 'gv-bg-black/50 focus:gv-outline-none gv-m-0')} type={isWGS84 ? 'text' : 'number'} data-test-id="CursorPosition-YInput" /> <button class={cn(editMode ? 'gv-hidden' : 'gv-visible', '')} onclick={() => activateEditMode(yCoordInput)}> {formated.y} </button> {formated.unit} </span> {/if}</div>
<style> input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; } input[type='number'] { -moz-appearance: textfield; }</style>packages/common/src/lib/widgets/cursor-position/index.ts
export * from './cursor-position.config';export * as CursorPosition from './CursorPosition.svelte';export * from './cursor-position.declaration';