Layer Components

Layers are the foundation for displaying different types of data on your map. Svelte OpenLayers provides components for raster tiles, vector data, and more.

Layer.Tile

Displays raster tile data from various sources like OpenStreetMap, satellite imagery, or custom tile servers.

Basic Usage

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

<Map.Root>
	<Map.View center={[0, 0]} zoom={2} />
	<Layer.Tile source="osm" />
</Map.Root>

Props

PropTypeDefaultDescription
source'osm' | 'xyz' | Source'osm'Tile source configuration
urlstringundefinedURL for XYZ source
opacitynumber1Layer opacity (0-1)
visiblebooleantrueLayer visibility
zIndexnumberundefinedLayer stacking order
minZoomnumberundefinedMinimum zoom level
maxZoomnumberundefinedMaximum zoom level
preloadnumber0Preload tiles
layerTileLayer | nullnullBindable layer instance (read-only)
attributionsstring | string[]undefinedLayer attributions
crossOriginstring | nullundefinedCross-origin setting

Built-in Sources

<!-- OpenStreetMap -->
<Layer.Tile source="osm" />

<!-- Custom XYZ source -->
<Layer.Tile
	source="xyz"
	url="https://{a - c}.tile.example.com/{z}/{x}/{y}.png"
	attributions="© Example"
/>

<!-- Using OpenLayers source directly -->
<Layer.Tile source={customTileSource} />

Note: Currently only ‘osm’ and ‘xyz’ string sources are supported. For other sources like satellite imagery, you’ll need to create OpenLayers source instances directly.

Layer.Vector

Displays vector data like points, lines, and polygons using Canvas rendering. Container for Feature components. For high-performance rendering of large datasets, consider using LayerWebGL.

Basic Usage

<Map.Root>
	<Map.View />
	<Layer.Tile source="osm" />
	<Layer.Vector>
		<Feature.Point coordinates={[0, 0]} />
		<Feature.LineString
			coordinates={[
				[0, 0],
				[10, 10]
			]}
		/>
	</Layer.Vector>
</Map.Root>

Props

PropTypeDefaultDescription
opacitynumber1Layer opacity (0-1)
visiblebooleantrueLayer visibility
zIndexnumberundefinedLayer stacking order
minZoomnumberundefinedMinimum zoom level
maxZoomnumberundefinedMaximum zoom level
styleStyleLikeundefinedDefault style for features
updateWhileAnimatingbooleanfalseUpdate during animations
updateWhileInteractingbooleanfalseUpdate during interactions
renderBuffernumber100Render buffer in pixels
layerVectorLayer | nullnullBindable layer instance (read-only)
sourceVectorSource | nullnullBindable source instance (read-only)

Layer.WebGL

High-performance WebGL vector layer for rendering large datasets with hardware acceleration. Uses expression-based styling for dynamic, data-driven visualizations.

Basic Usage

<Map.Root>
	<Map.View />
	<Layer.Tile source="osm" />
	<LayerWebGL
		style={{
			'circle-radius': 8,
			'circle-fill-color': '#ff0000',
			'circle-stroke-color': '#000000',
			'circle-stroke-width': 1
		}}
	>
		<!-- Features are added programmatically via the source -->
	</LayerWebGL>
</Map.Root>

Props

PropTypeDefaultDescription
opacitynumber1Layer opacity (0-1)
visiblebooleantrueLayer visibility
zIndexnumberundefinedLayer stacking order
minZoomnumberundefinedMinimum zoom level
maxZoomnumberundefinedMaximum zoom level
styleFlatStyleLikeundefinedWebGL-compatible style definition
variablesStyleVariablesundefinedVariables for dynamic styling
disableHitDetectionbooleanfalseDisable feature hit detection
layerWebGLVectorLayer | nullnullBindable layer instance (read-only)
sourceVectorSource | nullnullBindable source instance (read-only)

WebGL Styling

LayerWebGL uses OpenLayers’ flat style system with expression-based styling for dynamic visualizations:

Basic Styles

<!-- Simple circle style -->
<LayerWebGL
	style={{
		'circle-radius': 6,
		'circle-fill-color': '#4338ca',
		'circle-opacity': 0.8
	}}
/>

<!-- Icon style -->
<LayerWebGL
	style={{
		'icon-src': '/path/to/icon.png',
		'icon-width': 16,
		'icon-height': 16,
		'icon-color': '#ff0000'
	}}
/>

<!-- Triangle/polygon shapes -->
<LayerWebGL
	style={{
		'shape-points': 3,
		'shape-radius': 10,
		'shape-fill-color': '#10b981',
		'shape-rotate-with-view': true
	}}
/>

Expression-Based Styling

WebGL styles support expressions for data-driven visualization:

<LayerWebGL
	style={{
		// Size based on feature property
		'circle-radius': [
			'interpolate',
			['linear'],
			['get', 'population'],
			0, 4,
			1000000, 20
		],
		// Color based on feature property
		'circle-fill-color': [
			'case',
			['>', ['get', 'temperature'], 30], '#ff4444',
			['>', ['get', 'temperature'], 20], '#ffaa00',
			'#4444ff'
		],
		// Opacity based on zoom level
		'circle-opacity': [
			'interpolate',
			['linear'],
			['zoom'],
			5, 0.3,
			15, 0.9
		]
	}}
/>

Animation Support

WebGL layers support time-based animations:

<script>
	import { onMount } from 'svelte';

	let webglLayer;

	// Start animation loop
	onMount(() => {
		const animate = () => {
			if (webglLayer?.getMapInternal) {
				const map = webglLayer.getMapInternal();
				if (map) {
					map.render();
				}
			}
			requestAnimationFrame(animate);
		};
		animate();
	});
</script>

<LayerWebGL
	bind:layer={webglLayer}
	style={{
		'shape-rotation': ['*', ['time'], 0.01],  // Rotate over time
		'shape-points': 4,
		'shape-radius': 8,
		'shape-fill-color': '#ff6600'
	}}
/>

Performance Considerations

  • Use for large datasets: WebGL layers excel with thousands of features
  • Expression complexity: Keep expressions simple for better performance
  • Hit detection: Disable with disableHitDetection={true} for purely visual layers
  • Memory management: WebGL contexts are properly cleaned up on component destroy

Common Expression Functions

FunctionDescriptionExample
getGet feature property['get', 'population']
interpolateInterpolate between values['interpolate', ['linear'], input, ...]
caseConditional styling['case', condition, value1, value2]
matchMatch specific values['match', input, value1, result1, ...]
zoomCurrent zoom level['zoom']
timeCurrent time for animations['time']
*, +, -Mathematical operations['*', ['get', 'size'], 2]

Coming Soon: Additional layer types including Layer.VectorTile and Layer.Image are planned for future releases.