0

根据 Svelte 教程中的 Context API 示例,我在 Svelte-Sapper 应用程序中使用 Mapbox。我想使用 Mapbox-Draw 绘制多边形以根据对象的坐标限制搜索对象的区域。我扩展了示例代码以添加绘图功能:

mapbox.js:

import mapbox from 'mapbox-gl';
import mapboxDraw from "@mapbox/mapbox-gl-draw";
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';

mapbox.accessToken = '...';

const key = {};

export { mapbox, mapboxDraw, key };

Map.svelte:

<script>
    import { onMount, setContext } from 'svelte';
    import { mapbox, mapboxDraw, key } from '../routes/_mapbox.js';

    setContext(key, {
        getMap: () => map
    });

    export let lat;
    export let lon;
    export let zoom;

    let container;
    let map;
    let draw;

    onMount(() => {
        const link = document.createElement('link');
        link.rel = 'stylesheet';
        link.href = 'https://unpkg.com/mapbox-gl/dist/mapbox-gl.css';

        link.onload = () => {
            map = new mapbox.Map({
                container,
                style: 'mapbox://styles/mapbox/streets-v10',
                center: [lon, lat],
                zoom
            });
            draw = new mapboxDraw({
                displayControlsDefault: false,
                controls: {
                polygon: true,
                trash: true
                }
            });
            map.addControl(draw, 'top-left');
        };
  
        document.head.appendChild(link);
    });

    ...

</script>

该地图工作正常,并且也在地图上绘制多边形。但是我在 Map-svelte 的父组件中没有成功读取多边形的坐标 - 例如在按钮按下时。我已经尝试了很多东西,但没有任何东西接近。做这个的最好方式是什么?

父组件如下所示:

<script>
    import Map from '../../components/Map.svelte';
    import MapMarker from '../../components/MapMarker.svelte';  
    import { storedCoordinates } from '../stores.js';
    ...
    let coords = $storedCoordinates;
</script>

<div class="col border mt-1 ml-1 mr-1 fullheight scrolldiv" style="padding:0px">
    <Map lat={52.2} lon={5.7} zoom={6.5}>
        {#each coords as coord}
            <MapMarker 
                lat={coord[0][0]} 
                lon={coord[0][1]}
                label='<div style="width:300px; ">
                           {coord[1][0][0]} <a href="items/{coord[1][0][1]}">
                           <b>&nbsp;&gt;&gt;&nbsp;</b></a>
                       </div>'                                      
            />
        {/each}
    </Map>
</div>

坐标('coords')来自 MongoDB 存储中的 api。多边形在地图上围绕其标记的子集绘制。然后通过 api 将多边形的坐标发回以检索该子集的数据。一切正常,除了我找不到读取多边形坐标的方法 - 我用 draw.getAll() 以不同的方式尝试了它,但没有成功......

4

1 回答 1

0

我自己的回答:最终解决方案相当简单(像往常一样:-)。我将绘图中的坐标存储在商店中。然后父组件可以从存储中读取。问题解决了...

Map.svelte:

<script>
    import { onMount, setContext } from 'svelte';
    import { mapbox, mapboxDraw, key } from '../routes/_mapbox.js';
    import { selectedCoords } from '../routes/stores.js';

    setContext(key, {
        getMap: () => map
    });

    export let lat;
    export let lon;
    export let zoom;

    let container;
    let map;
    let draw;

    onMount(() => {
        const link = document.createElement('link');
        link.rel = 'stylesheet';
        link.href = 'https://unpkg.com/mapbox-gl/dist/mapbox-gl.css';

        link.onload = () => {
            map = new mapbox.Map({
                container,
                style: 'mapbox://styles/mapbox/streets-v10',
                center: [lon, lat],
                zoom
            });
            draw = new mapboxDraw({
                displayControlsDefault: false,
                controls: {
                polygon: true,
                trash: true
                }
            });
            map.addControl(draw, 'top-left');
            map.on('draw.create', getCoords);
            map.on('draw.delete', getCoords);
            map.on('draw.update', getCoords);

            function getCoords(e) {
                let data = draw.getAll();
                selectedCoords.set(data['features'][0]['geometry']['coordinates'][0]);
            }
        }; 
        document.head.appendChild(link);

    }); 
</script>


<div bind:this={container}>
    {#if map}
        <slot></slot>
    {/if}
</div>


<style>
    div {
        width: 100%;
        height: 100%;
    }

</style>
于 2021-03-29T08:07:35.880 回答