Use map.fitBounds in MapBox to continuously adjust the map view to show only the visible features on the map

In my map, there are various features with IDs stored in an array called featureIds.

Within my application, I have a button that can toggle the visibility of certain features.

To address this toggling behavior, I am developing a JavaScript function named reCenter(). This function adjusts the map view to fit the bounds of only the visible features.

function reCenter() {

// initialize new array for visible features 
var visibleFeatures = [];

// identify and add visible features to the new array
    for (var i = 0; i < featureIds.length; i++) {

        if (map.getLayoutProperty(featureIds[i], "visibility") == "visible") {

            visibleFeatures.push(map.queryRenderedFeatures(featureIds[i]));
        }

    }

    // set up array to store coordinates
    var coordinates = [];


    // gather coordinates for each visible feature and add them to the array    
    for (var j = 0; j < visibleFeatures.length; j++) {

        coordinates.push(coord.geometry.coordinates);

    }

    // adjust map view as described here: https://docs.mapbox.com/mapbox-gl-js/example/zoomto-linestring/
    var bounds = coordinates.reduce(function (bounds, coord) {
        return bounds.extend(coord);
    }, new mapboxgl.LngLatBounds(coordinates[0], coordinates[0]));

    map.fitBounds(bounds, {
        padding: 20
    });
}

Despite following the instructions at https://docs.mapbox.com/mapbox-gl-js/example/zoomto-linestring/, I encounter the error: TypeError: this._sw is undefined

What is the most effective way to dynamically retrieve all coordinates of visible features and pass them into map.fitBounds()?

Answer №1

Combine all your unique attributes to form a full FeatureCollection. Utilize the bbox feature from Turf.js to extract the boundaries of the FeatureCollection. This is my method:

const features = [
    {
         type: 'Feature',
         geometry: {
             type: 'Polygon',
             coordinates: [
                 [your_feature_s_coordinates],
                 [...],
             ]
         }
     },
     {another feature}
 ]

 const FeatureCollection = {
     type: "FeatureCollection",
     features: features
 };

 map.fitBounds(bbox(toWgs84(FeatureCollection)));

Answer №2

Check out Turf.js: a fantastic open-source JavaScript library designed for spatial analysis.

One of its handy features is the bbox method, which can be found here.

This method takes a set of features and automatically calculates the bounding box for you, allowing you to set it as fitBounds.

If you're looking for more information on similar functions, there's a related question previously asked about Mapbox GL JS getBounds()/fitBounds() here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The window.load() function seems to be malfunctioning as the event is not being triggered. There are no error

I'm struggling with getting the window.load() event to trigger on this specific website. The issue arose last night and despite there being no visible js or php errors, pinpointing the root cause has proven to be quite challenging. In syrp.home.main ...

List of coordinates extracted from PolylineMeasure plugin in the React Leaflet library

I have 3 different scripts: 1. PolylineMeasure.jsx import { MapControl, withLeaflet } from "react-leaflet"; import * as L from "leaflet"; class PolylineMeasure extends MapControl { createLeafletElement() { return L.control.poly ...

RetrieveByUserIdentifier as a callback method (express)

Can you help me refactor the code below to use a callback function instead? I want to ensure that the Req and Res logic is handled separately. Userservice.js function getByUserId(req, res, next) { let userIDD = req.body.userID; User.findOne({ use ...

Navigating the jQuery Search Form: Redirecting to Pages within your Website

After successfully creating my first Javascript search form with an Autocomplete Script, I am facing a challenge. I want to enable users to press "enter" after searching for a product and get redirected to the corresponding product URL page. The operation ...

"Unfortunately, the JavaScript external function failed to function properly, but miraculously the inline function

Struggling to create a fullscreen image modal on the web? I was able to get it working fine when embedding the script directly into my HTML file, but as soon as I moved it to an external JS file, things fell apart. I've double-checked all the variable ...

Is there a way for my component to function seamlessly within another component without the need for redundant code?

Is there a way to avoid repeating code when using my component inside another component? For example, in the file NextPage.js, the <LogoutButton/> component does not perform its function. How can I ensure that the <LogoutButton/> behaves the s ...

``I am having trouble getting the Bootstrap carousel to start

I am having trouble getting the Bootstrap Carousel to function as expected. Despite including all the necessary code, such as initializing the carousel in jQuery.ready, the images are stacking on top of each other with navigation arrows below them instea ...

Issue with window resize directive not functioning as expected

I have recently crafted a personalized directive in AngularJS. Here's the code snippet: var esscom = angular.module('esscom',['ngMaterial' ,'ngMessages','ui.bootstrap','ui.router']); esscom.directiv ...

Customizing CoreUI column names in Vue

I am working with an array of item objects for a table. For example: [{ name: 'Sam', age: 24 }] Instead of using the default column names like age, I want to set custom field names. For instance, I want to display the column as Id instead of age ...

Issue occurred in module.js:341 while attempting to include android platform to ionic using command line

For my hybrid app development using the Ionic framework, I made sure to install all required dependencies like node.js and cordova. Following their Getting started guide, I reached step 3 which instructs running this command within the app directory: > ...

Capturing HTML form values and storing them in my JavaScript data object

I have a JS object with preset data as shown below in the variable var json. I am trying to create a simple HTML web form where I want the user inputs to be added as a new data set within my initial JS object. Here is the initial JS object data. The submi ...

Exploring the concept of Promises through the lens of recursion

I am dealing with a MongoDB collection that looks like this [ { "classId": "1", "name": "Input", "definition": [ { "property": [ { "classId": "12", "name": "One" }, { ...

Steps to create a clickable button wrapper label in React

Contained within the components below: <CheckboxGroupLabel htmlFor={option.label}> <FormCheckbox onClick={() => onChange} key={option.label} defaultChecked={defaultChecked} {...rest} /> {option.value} ...

Issue with Vuetify v-alert not appearing after updating reactive property

I am trying to set up a conditional rendering for a v-alert if the login response code is 401 Unauthorized. Here is how I have defined the alert: <v-alert v-if="this.show" type="error">Invalid email and/or password.</v-alert> Within the data ...

What is the process for accessing someone's birthday information using the Facebook API?

Working on integrating Facebook login and successfully retrieving user details such as first_name, email, etc. However, encountering an issue with fetching the birthday information. When attempting to call for birthday using the code snippet below, no data ...

ERROR_UNSUPPORTED_ESM_URL_SCHEME - issue with next-sitemap plugin

I have a project utilizing next-sitemap with Node.js version v14.11.0. next-sitemap.config.js module.exports = { siteUrl: 'https://*****.com', generateRobotsTxt: true, robotsTxtOptions: { additionalSitemaps: [ 'htt ...

Receiving the most recent data in a protractor examination as a text string

My goal is to fetch an input value for a specific operation in protractor. I am attempting to make an ajax request using protractor and need to assign a unique value (referred to as groupCode) to a JSON object that will be sent to the server. Initially, I ...

Incorporating a self-invoking anonymous function to enhance Sir Trevor within an AngularJS framework while also making use of

I recently started working with AngularJS and I have an App where I am using the Sir Trevor content editor. I want to add some custom blocks to the editor by extending it, but I am having trouble accessing angular services within my extension code. The ext ...

Tips for maximizing the benefits of debounce/throttle and having a truly dynamic experience

Attempting to implement a similar concept in Vue: props(){ debouncing: {type: Number, default: 0} }, methods: { clicked: _.debounce(function() { this.$emit('click'); }, this.debouncing), } Unfortunately, the code breaks when ...

What could be causing the issue of PHP not receiving this multidimensional array through Ajax?

Having an issue with receiving a multidimensional array in PHP after posting it from JS using Ajax: $.ajax({ type: 'post', url: 'external_submit.php', dataType: "json", data: { edit_rfid_changes_submit ...