@watergis/svelte-maplibre-legend

@watergis/svelte-maplibre-legend is a svelte component to make layer legend for maplibre-gl.

Demo

    Usage

    Install the package

    npm i @watergis/svelte-maplibre-legend
    yarn add @watergis/svelte-maplibre-legend
    pnpm i @watergis/svelte-maplibre-legend

    Example

    <script lang="ts">import { onMount } from 'svelte';
    import { Map } from 'maplibre-gl';
    import { MenuControl } from '@watergis/svelte-maplibre-menu';
    import { LegendPanel, LegendHeader } from '@watergis/svelte-maplibre-legend';
    let mapContainer;
    // create maplibre.Map object
    let map = new Map();
    let onlyRendered = true;
    let onlyRelative = true;
    let enableLayerOrder = false;
    let enableEditing = true;
    let relativeLayers = {
        pipeline: 'Pipeline',
        pipeline_annotation: 'Pipeline Label',
        meter: 'Water Meter',
        'flow meter': 'Flow Meter',
        valve: 'Valve',
        firehydrant: 'Fire Hydrant',
        washout: 'Washout',
        tank: 'Tank',
        tank_annotation: 'Tank Label',
        wtp: 'WTP',
        wtp_annotation: 'WTP Label',
        intake: 'Intake',
        intake_annotation: 'Intake Label',
        parcels: 'Parcels',
        parcels_annotation: 'Parcels Label',
        village: 'Village',
        village_annotation: 'Village Label',
        dma: 'DMA',
        'dma-annotation': 'DMA Label',
        'contour-line': 'Countour',
        'contour-label': 'Contour Label',
        hillshade: 'Hillshade',
        sewer_connection: 'Households (Sewer)',
        sewer_commercial: 'Commecial (Sewer)',
        sewer_institution: 'Institution (Sewer)',
        sewer_public_toilet: 'Public Toilet (Sewer)',
        manhole: 'Manhole',
        sewer_pipeline: 'Sewer pipeline',
        sewer_treatment_plant: 'Wastewater treatment plant'
    };
    onMount(async () => {
        map = new Map({
            container: mapContainer,
            style: 'https://narwassco.github.io/mapbox-stylefiles/unvt/style.json'
        });
    });
    </script>
    
    <MenuControl bind:map position={'top-right'} bind:isMenuShown>
    	<div slot="sidebar" class="primary-container">
    		<div class="legend-header">
    			<LegendHeader
    				bind:onlyRendered
    				bind:onlyRelative
    				bind:enableLayerOrder
    				bind:enableEditing
    				isLayerOrderShown={true}
    			/>
    		</div>
    		<div class="legend-content" style="height:{menuHeight - 56}px">
    			<LegendPanel
    				bind:map
    				bind:onlyRendered
    				bind:onlyRelative
    				{relativeLayers}
    				bind:enableLayerOrder
    				bind:enableEditing
    				disableVisibleButton={false}
    			/>
    		</div>
    	</div>
    	<div slot="map">
    		<div class="map" bind:this={mapContainer} />
    	</div>
    </MenuControl>
    
    <style lang="scss">@import 'maplibre-gl/dist/maplibre-gl.css';
    .map {
      width: 100%;
      height: 100%;
      z-index: 1;
    }
    
    .primary-container {
      display: flex;
      flex-direction: column;
      position: relative;
    }
    .primary-container .legend-header {
      padding-left: 0.5rem;
      padding-top: 0.5rem;
      padding-bottom: 0.5rem;
    }
    .primary-container .legend-content {
      overflow-x: hidden;
      overflow-y: auto;
      height: calc(100vh - 56px);
      width: 100%;
    }</style>

    In case style.json is changed

    When you changed map style.json, please fire style:change event like the following source code. this legend panel watch this event and will recreate legend with new style.json.

    map.on('style:change')