Map Components

Map components provide the foundation for all mapping functionality. The View component controls the viewport and provides context, while the Map component renders the map container.

View

The View component controls the map’s viewport including center, zoom, rotation, and projection. It wraps the Map component and provides context for all child components.

Basic Usage

<script>
	import { Map, Layer, View } from 'svelte-openlayers';
</script>

<View center={[0, 0]} zoom={2}>
	<Map class="h-96 w-full">
		<Layer.Tile source="osm" />
	</Map>
</View>

Props

PropTypeDefaultDescription
center[number, number][0, 0]View center coordinates (bindable)
zoomnumber5Zoom level (bindable)
projectionProjectionLike'EPSG:3857'Map projection
minZoomnumber0Minimum zoom level
maxZoomnumber28Maximum zoom level
rotationnumber0View rotation in radians (bindable)
extentnumber[]undefinedConstraining extent
bboxExtentnullCurrent view extent (bindable)
constrainRotationboolean | numbertrueConstrain rotation
enableRotationbooleantrueEnable rotation
viewView | nullnullBindable OpenLayers View instance
onCenterChange(center: Coordinate) => voidundefinedCenter change callback
onZoomChange(zoom: number | undefined) => voidundefinedZoom change callback
onRotationChange(rotation: number) => voidundefinedRotation change callback
onMoveEnd(evt: any) => voidundefinedMove end event callback

Reactive Binding Example

<script>
	import { Map, Layer, View } from 'svelte-openlayers';
	import { transform } from 'ol/proj';

	let center = $state([0, 0]);
	let zoom = $state(2);

	const transformedCoordinates = $derived(transform(center, 'EPSG:3857', 'EPSG:4326'));
</script>

<View bind:center bind:zoom>
	<Map class="h-96 w-full">
		<Layer.Tile source="osm" />
	</Map>
</View>

<div>
	Center: [{transformedCoordinates[0].toFixed(2)}, {transformedCoordinates[1].toFixed(2)}]
	Zoom: {zoom.toFixed(1)}
</div>

Sharing a View Across Multiple Maps

You can share a single view across multiple Map components in two ways:

Option 1: View wrapping Maps

The View component can wrap multiple Map components. Each Map receives the view from context automatically:

<script>
	import { Map, Layer, View } from 'svelte-openlayers';

	let center = $state([0, 0]);
	let zoom = $state(2);
</script>

<View bind:center bind:zoom>
	<div class="grid grid-cols-2 gap-4">
		<Map>
			<Layer.Tile source="osm" />
		</Map>
		<Map>
			<Layer.Tile source="xyz" url="..." />
		</Map>
	</div>
</View>

Option 2: View outside Maps

Alternatively, the View can be defined separately (without children) and the view instance passed to each Map:

<script>
	import { Map, Layer, View } from 'svelte-openlayers';
	import type { View as OLView } from 'ol';

	let view: OLView | null = $state(null);
	let center = $state([0, 0]);
	let zoom = $state(2);
</script>

<!-- View defined separately -->
<View bind:center bind:zoom bind:view />

<div class="grid grid-cols-2 gap-4">
	<Map {view}>
		<Layer.Tile source="osm" />
	</Map>
	<Map {view}>
		<Layer.Tile source="xyz" url="..." />
	</Map>
</div>

Both patterns synchronize pan, zoom, and rotation across all maps sharing the view.

Map

The main map container that creates the OpenLayers map instance. It must be placed inside a View component (or receive a view prop directly).

Basic Usage

<script>
	import { Map, Layer, View } from 'svelte-openlayers';
</script>

<View center={[-74.0, 40.7]} zoom={10}>
	<Map class="h-96 w-full">
		<Layer.Tile source="osm" />
	</Map>
</View>

Props

PropTypeDefaultDescription
classstringundefinedCSS classes for the map container
viewViewundefinedOpenLayers View instance (optional)
controlsControlOptions{}Default controls configuration
interactionsInteractionOptions{}Default interactions configuration
pixelRationumberundefinedDevice pixel ratio
keyboardEventTargetHTMLElement | DocumentundefinedKeyboard event target
maxTilesLoadingnumber16Maximum tiles loading simultaneously
moveTolerancenumber1Move tolerance in pixels
exclusiveHoverbooleantrueWhen enabled, only one feature is hovered at a time across all layers
mapMap | nullnullBindable OpenLayers Map instance

Events

Map supports comprehensive event handling for map interactions. All events receive the appropriate OpenLayers event object.

MapBrowserEvent Handlers

Handle pointer and mouse interactions with the map:

<View center={[0, 0]} zoom={2}>
	<Map
		click={handleClick}
		pointermove={handlePointerMove}
		pointerdown={handlePointerDown}
	>
		<Layer.Tile source="osm" />
	</Map>
</View>
Event HandlerTypeDescription
click(evt: MapBrowserEvent) => voidClick event
dblclick(evt: MapBrowserEvent) => voidDouble click event
pointerdrag(evt: MapBrowserEvent) => voidPointer drag event
pointermove(evt: MapBrowserEvent) => voidPointer move event
pointerdown(evt: MapBrowserEvent) => voidPointer down event
pointerup(evt: MapBrowserEvent) => voidPointer up event
pointerover(evt: MapBrowserEvent) => voidPointer over event
pointerout(evt: MapBrowserEvent) => voidPointer out event
pointerenter(evt: MapBrowserEvent) => voidPointer enter event
pointerleave(evt: MapBrowserEvent) => voidPointer leave event
pointercancel(evt: MapBrowserEvent) => voidPointer cancel event

MapEvent Handlers

Handle map lifecycle and navigation events:

<View center={[0, 0]} zoom={2}>
	<Map
		movestart={handleMoveStart}
		moveend={handleMoveEnd}
		loadend={handleLoadEnd}
	>
		<Layer.Tile source="osm" />
	</Map>
</View>
Event HandlerTypeDescription
postrender(evt: MapEvent) => voidAfter map rendering
movestart(evt: MapEvent) => voidMap movement starts
moveend(evt: MapEvent) => voidMap movement ends
loadstart(evt: MapEvent) => voidMap loading starts
loadend(evt: MapEvent) => voidMap loading ends

RenderEvent Handlers

Handle rendering lifecycle events:

<View center={[0, 0]} zoom={2}>
	<Map
		precompose={handlePreCompose}
		postcompose={handlePostCompose}
		rendercomplete={handleRenderComplete}
	>
		<Layer.Tile source="osm" />
	</Map>
</View>
Event HandlerTypeDescription
precompose(evt: RenderEvent) => voidBefore layer composition
postcompose(evt: RenderEvent) => voidAfter layer composition
rendercomplete(evt: RenderEvent) => voidRendering complete

Event Usage Examples

<script>
	import { Map, Layer, View } from 'svelte-openlayers';

	function handleClick(evt) {
		const coordinate = evt.coordinate;
		console.log('Clicked at:', coordinate);
	}

	function handlePointerMove(evt) {
		// Update cursor or highlight features
		const pixel = evt.pixel;
		// Check for features at pixel
	}

	function handleMoveEnd(evt) {
		const map = evt.target;
		const view = map.getView();
		const center = view.getCenter();
		const zoom = view.getZoom();
		console.log('New view:', { center, zoom });
	}
</script>

<View center={[0, 0]} zoom={2}>
	<Map
		click={handleClick}
		pointermove={handlePointerMove}
		moveend={handleMoveEnd}
	>
		<Layer.Tile source="osm" />
		<!-- layers and other components -->
	</Map>
</View>

Built-in Controls

Map includes built-in controls that can be configured via the controls prop.

Control Configuration

<View center={[0, 0]} zoom={2}>
	<Map controls={{ zoom: true, attribution: true, rotate: false }}>
		<Layer.Tile source="osm" />
	</Map>
</View>