MaxBounds and custom asymmetric padding in Mapbox GL

北城以北 提交于 2021-02-11 17:52:51

问题


I have a Mapbox GL JS app, where over a map I display some widgets. To make sure nothing on the map will be hidden by them I've added some padding using map.setPadding(). It's an asymmetric one (left is larger than right in my case). It works as intended for things like fitBounds and animation but I also need to set up maxBounds of the map so the user won't pan out of the desired viewport. Unfortunately that doesn't work well with custom padding. When I draw the bounds and use showPadding I can see that those lines won't align. The problem grows bigger the bigger I make the difference between the paddings.

I was wondering if anybody had similar issues or can lead me to a solution where I can have map clamped to some bounds while still being able to use custom padding like I described above.

Here's an example of the issue: https://jsfiddle.net/1ysrgkcL/45/ Notice how the thick black rectangle doesn't align with the padding lines.


回答1:


I ran into same problem earlier and i fix it using:

  • fitBounds as it add's the amount of padding(in pixels) to the given bounds.
  • requestAnimationFrame: In its callback i received the getBounds and set it as max bounds(trick)

Updated code snippet:

<script>
        mapboxgl.accessToken = 'pk.eyJ1IjoiYnBhY2h1Y2EiLCJhIjoiY2lxbGNwaXdmMDAweGZxbmg5OGx2YWo5aSJ9.zda7KLJF3TH84UU6OhW16w';

        const map = new mapboxgl.Map({
            container: 'map',
            style: 'mapbox://styles/mapbox/streets-v9',
            center: [-73.9774108244587, 40.820698485268366],
            zoom: 11.6
        });

        map.on('load', function () {
            const padding = { left: 300, right: 100, top: 100, bottom: 30 }; //<--- padding

            const bounds = {
                "n": 40.896790957065434,
                "s": 40.76021859203365,
                "e": -73.85756962495667,
                "w": -74.09102645202957
            }
            const maxBounds = [[bounds.w, bounds.s], [bounds.e, bounds.n]];

            //<---- notice here--->
            map.fitBounds(maxBounds, {
                padding, //<--- used here
                linear: true,
                duration: 0
            });

            map.showPadding = true

            //<---- notice here--->
            requestAnimationFrame(() => {
                const getBoundsFromViewport = map.getBounds();
                map.setMaxBounds(getBoundsFromViewport);
            });

            const boundsRect = [
                [bounds.e, bounds.n],
                [bounds.w, bounds.n],
                [bounds.w, bounds.s],
                [bounds.e, bounds.s],
                [bounds.e, bounds.n]
            ]

            map.on('click', (e) => console.log('##', e.lngLat.toArray()))

            map.addLayer({
                'id': 'bounds',
                'type': 'line',
                'source': {
                    'type': 'geojson',
                    'data': {
                        'type': 'Feature',
                        'geometry': {
                            'type': 'LineString',
                            'coordinates': boundsRect
                        }
                    }
                },
                'paint': {
                    'line-color': '#000000',
                    'line-width': 10
                },
                'layout': {}
            });
        });
    </script>

And it will like charm in your case too. Attaching screenshot:

Give it a try!



来源:https://stackoverflow.com/questions/64106412/maxbounds-and-custom-asymmetric-padding-in-mapbox-gl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!