Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions components/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ export { default as GeocoderControl } from './maplibre/GeocoderControl/GeocoderC
export { default as NavigationControl } from './maplibre/NavigationControl/NavigationControl.svelte';
export { default as ScaleControl } from './maplibre/ScaleControl/ScaleControl.svelte';
export { default as VectorLayer } from './maplibre/VectorLayer/VectorLayer.svelte';
export { default as HillshadeLayer } from './maplibre/HillshadeLayer/HillshadeLayer.svelte';
export { default as VectorTileSource } from './maplibre/VectorTileSource/VectorTileSource.svelte';
export { default as RasterDEMSource } from './maplibre/RasterDEMSource/RasterDEMSource.svelte';
export { default as GeoJSONSource } from './maplibre/GeoJSONSource/GeoJSONSource.svelte';
export { default as ArrowSource } from './maplibre/ArrowSource/ArrowSource.svelte';
export { default as MapSource } from './maplibre/Source/MapSource.svelte';
Expand Down
5 changes: 3 additions & 2 deletions components/src/maplibre/ArrowSource/ArrowSource.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@

const { id, arrows = [], attribution = '' }: ArrowSourceProps = $props();

const ars: JsonArrow[] = arrows.map((a) => {
const ars: JsonArrow[] = $derived(arrows.map((a) => {
return {
width: a.width || 10,
points: quadraticToPoints(a.a, a.b, a.c),
headScale: a.headScale
};
});
}));

const arrowsToJson = (arrows: JsonArrow[] = []) => {
if (!map) return { type: 'FeatureCollection', features: [] } as GeoJSON.GeoJSON;
Expand Down Expand Up @@ -83,6 +83,7 @@
};

let sourceSpec: GeoJSONSourceSpecification = $state({
// svelte-ignore state_referenced_locally
attribution,
type: 'geojson',
promoteId: 'id',
Expand Down
13 changes: 4 additions & 9 deletions components/src/maplibre/GeoJSONSource/GeoJSONSource.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@
// See: https://maplibre.org/maplibre-gl-js/docs/API/classes/GeoJSONSource/
import { type GeoJSONSourceSpecification } from 'maplibre-gl';
import MapSource from '../Source/MapSource.svelte';
import type { SourceProps } from '../types';

interface GeoJSONSourceProps {
id: string;
interface GeoJSONSourceProps extends Omit<SourceProps, "children"> {
/**
* GeoJSON object or URL
*/
data: GeoJSON.GeoJSON | string;
/**
* Attribution string for your data, usually rendered using an `<AttributionControl>`
*/
attribution?: string;
maxZoom?: number;
/**
* Use a field from the feature data for IDs. Must coerce to integer.
*/
Expand All @@ -35,15 +30,15 @@
generateId = false
}: GeoJSONSourceProps = $props();

const sourceSpec: GeoJSONSourceSpecification = {
const sourceSpec: GeoJSONSourceSpecification = $derived({
type: 'geojson',
maxzoom: maxZoom,
attribution,
promoteId,
generateId,
lineMetrics,
data
};
});
</script>

<MapSource {id} {sourceSpec} />
13 changes: 13 additions & 0 deletions components/src/maplibre/HillshadeLayer/HillshadeLayer.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

import { Meta } from '@storybook/addon-docs/blocks';
import { Story, Primary, Controls, Stories } from '@storybook/addon-docs/blocks';
import * as HillshadeLayerStories from './HillshadeLayer.stories.svelte';

<Meta of={HillshadeLayerStories} />

# HillshadeLayer

Experimental hilshade layer. Uses a `raster-dem` source to render real-time raster hillshading.

<Stories />
<Controls />
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<script module lang="ts">
import { defineMeta } from '@storybook/addon-svelte-csf';

import Map from '../Map/Map.svelte';
import HillshadeLayer from './HillshadeLayer.svelte';
import AttributionControl from '../AttributionControl/AttributionControl.svelte';
import DesignTokens from '../../DesignTokens/DesignTokens.svelte';

import { SWRDataLabLight } from '../MapStyle';
import RasterDEMSource from '../RasterDEMSource/RasterDEMSource.svelte';

const { Story } = defineMeta({
title: 'Maplibre/Layer/HillshadeLayer',
component: HillshadeLayer,
tags: ["experimental"]
});
</script>

<Story asChild name="Default">
<DesignTokens theme="light">
<div class="container">
<Map showDebug={true} style={SWRDataLabLight()}>
<RasterDEMSource id='dem' url="https://tiles.datenhub.net/tiles/elevation/tiles.json">
<HillshadeLayer sourceId="dem" id="test"
paint={{
'hillshade-method': 'standard',
'hillshade-illumination-direction': 315,
'hillshade-shadow-color': '#000000',
'hillshade-highlight-color': '#FFFFFF',
'hillshade-accent-color': '#000000',
'hillshade-exaggeration': 0.5
}}
/>
</RasterDEMSource>
<AttributionControl position="bottom-left" />
</Map>
</div>
</DesignTokens>
</Story>

<style>
.container {
width: 100%;
height: 600px;
}
</style>
51 changes: 51 additions & 0 deletions components/src/maplibre/HillshadeLayer/HillshadeLayer.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<script lang="ts">
import { type AddLayerObject } from 'maplibre-gl';

import { getMapContext } from '../context.svelte.js';
import { onDestroy } from 'svelte';

interface HillshadeLayerProps extends Omit<
maplibregl.HillshadeLayerSpecification,
'id' | 'source' | 'source-layer' | 'type'
> {
id: string;
sourceId: string;
sourceLayer?: string;
placeBelow?: string;
visible?: boolean;
minZoom?: number;
maxZoom?: number;
}
const {
id,
sourceId,
sourceLayer,
placeBelow,
paint,
layout,
minZoom = 0,
maxZoom = 24,
}: HillshadeLayerProps = $props();

const ctx = getMapContext();

const layerSpec = $derived({
id,
type: "hillshade",
source: sourceId,
'source-layer': sourceLayer || '',
layout: layout ?? {},
paint: paint ?? {},
minzoom: minZoom,
maxzoom: maxZoom
}) as AddLayerObject;

$effect(() => {
ctx.waitForStyleLoaded((m) => {
ctx.addLayer(layerSpec, placeBelow);
});
});
onDestroy(() => {
if (ctx.map && ctx.map.getLayer(id)) ctx.map.removeLayer(id);
});
</script>
2 changes: 2 additions & 0 deletions components/src/maplibre/HillshadeLayer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import HillshadeLayer from './HillshadeLayer.svelte';
export default HillshadeLayer;
38 changes: 38 additions & 0 deletions components/src/maplibre/RasterDEMSource/RasterDEMSource.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<script lang="ts">
import { type PromoteIdSpecification, type RasterDEMSourceSpecification, } from 'maplibre-gl';

import MapSource from '../Source/MapSource.svelte';
import type { SourceProps } from '../types';
import fetchTileJSON from '../fetchTileJson';

interface RasterDEMSourceProps extends SourceProps {
url?: string;
tiles?: string[];
promoteId?: PromoteIdSpecification;
}

const {
minZoom,
maxZoom,
id,
url,
tiles,
attribution,
promoteId,
children
}: RasterDEMSourceProps = $props();

let tileJsonData = $derived(url ? await fetchTileJSON(url) : {});

const sourceSpec: RasterDEMSourceSpecification = $derived({
type: 'raster-dem',
tileSize: 256,
tiles: tiles || tileJsonData.tiles || [],
maxzoom: maxZoom || tileJsonData.maxZoom || 24,
minzoom: minZoom || tileJsonData.minZoom || 0,
attribution: attribution || tileJsonData.attribution || '',
promoteId
});
</script>

<MapSource {id} {sourceSpec} {children} />
2 changes: 2 additions & 0 deletions components/src/maplibre/RasterDEMSource/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import RasterDEMSource from './RasterDEMSource.svelte';
export default RasterDEMSource;
4 changes: 2 additions & 2 deletions components/src/maplibre/Source/MapSource.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script lang="ts">
import { onDestroy, onMount, type Snippet } from 'svelte';
import { type Map, type SourceSpecification } from 'maplibre-gl';
import { type GeoJSONSourceSpecification, type Map, type RasterDEMSourceSpecification, type VectorSourceSpecification } from 'maplibre-gl';
import { getMapContext } from '../context.svelte.js';

interface MapSourceProps {
id: string;
source?: maplibregl.VectorTileSource | maplibregl.GeoJSONSource;
sourceSpec: SourceSpecification;
sourceSpec: VectorSourceSpecification | GeoJSONSourceSpecification | RasterDEMSourceSpecification;
onLoad?: (map: Map, url?: string, data?: string) => undefined;
children?: Snippet;
}
Expand Down
15 changes: 3 additions & 12 deletions components/src/maplibre/VectorTileSource/VectorTileSource.svelte
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
<script lang="ts">
import { type PromoteIdSpecification, type VectorSourceSpecification } from 'maplibre-gl';
import type { TileJsonData } from './types';

import MapSource from '../Source/MapSource.svelte';
import fetchTileJSON from './fetchTileJson';
import type { Snippet } from 'svelte';
import fetchTileJSON from '../fetchTileJson';
import type { SourceProps } from '../types';

interface VectorTileSourceProps {
id: string;
interface VectorTileSourceProps extends SourceProps{
url?: string;
tiles?: string[];
minZoom?: number;
maxZoom?: number;
/**
* Attribution string for your data, usually rendered using an `<AttributionControl/>`
*/
attribution?: string;
promoteId?: PromoteIdSpecification;
children?: Snippet;
}

const {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type TileJsonData } from './types';
import { type TileJsonData } from './VectorTileSource/types';

// Workaround for https://github.com/versatiles-org/versatiles-rs/issues/184
// Drop when/if this lands: https://github.com/maplibre/maplibre-gl-js/issues/182
Expand Down
13 changes: 13 additions & 0 deletions components/src/maplibre/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {
FillLayerSpecification,
LineLayerSpecification
} from 'maplibre-gl';
import type { Snippet } from 'svelte';

export type Layer =
| LineLayerSpecification
Expand Down Expand Up @@ -40,3 +41,15 @@ export interface Location {
zoom: number;
pitch?: number;
}

export interface SourceProps {
id: string;
minZoom?: number;
maxZoom?: number;
/**
* Attribution string for your data, usually rendered using an `<AttributionControl/>`
*/
attribution?: string;
children?: Snippet;

}
Loading