选择输入并使用按钮提交后,如何更新地图框不透明度?

问题描述 投票:0回答:1

我可以初始化地图并添加 geojson 多边形。但我无法根据所选选项更新不透明度。我能够检索这些值并计算每个邮政编码的标准化值,但我无法获得反映新值的不透明度。

一切都会返回更新后的 geojson,其中包含基于选择的值。但我无法使用新的不透明度级别更新图层。

我在控制台日志中收到此错误:

(index):181错误:TypeError:map.setPaintProperty不是函数 在(索引):259:21 在Array.forEach() 在 updateMap ((index):216:34) 在(索引):173:17

fetch('https://vizibalmaps.s3.amazonaws.com/2023_zipcode_20mb.json')
            .then(response => response.json())
            .then(data => {
                // Initialize the map
                console.log('GeoJSON Data:', data);
                console.log('GeoJSON Zipcode Type:', typeof data.features[0].properties.ZCTA5CE20);

                const map = new mapboxgl.Map({
                    container: 'map',
                    style: 'mapbox://styles/mapbox/light-v10',
                    center: [-74.5, 40], // Default center coordinates
                    zoom: 4, // Adjust the zoom level
                });

                // Store the fetched data in the global variable
                geojsonData = data;

                map.on('load', function () {
                    map.addSource('polygons', {
                        type: 'geojson',
                        data: geojsonData, // Use the global variable to set the data
                    });

                    map.addLayer({
                        id: 'polygons',
                        type: 'fill',
                        source: 'polygons',
                        paint: {
                            'fill-color': '#FF5733',
                            // 'fill-opacity': 0.3,
                            'fill-outline-color': '#088',
                        },
                    });

            .catch(error => console.error('Error fetching GeoJSON:', error));

 // Function to update the map based on new data
        function normalize(value, min, max) {
            // Map the value from the range [min, max] to [0, 1]
            return (value - min) / (max - min);
        }   

        function getValueFromData(outputData, zipcode) {
            // Find the entry with the matching zipcode
            var entry = outputData.find(entry => entry.zipcode === zipcode);
            // Return the output_value if the entry is found, otherwise return null or handle appropriately
            return entry ? parseInt(entry.output_value) : null;
        }

        function updateMap(data) {

            // Log the data to the console to examine its structure
            // console.log(data);

            // Extract the output data
            var outputData = data.output;

            // Get the min and max values from the data
            var values = outputData.map(entry => parseInt(entry.output_value));
            var minValue = Math.min(...values);
            var maxValue = Math.max(...values);

            // Iterate over the GeoJSON features to calculate normalized opacity based on the value
            geojsonData.features.forEach(feature => {
                // Check if the zipcode property exists in feature.properties
                if (feature.properties.hasOwnProperty('ZCTA5CE20')) {

                    // console.log('GeoJSON Zipcode:', feature.properties.ZCTA5CE20); // check geojson zipcode format
                    // console.log('GeoJSON Zipcode Type:', typeof geojsonData.features[0].properties.ZCTA5CE20);


                    var zipcode = feature.properties.ZCTA5CE20;
                    var value = getValueFromData(outputData, zipcode); // Assuming you have a function to extract the value from the data
                    
                    // console.log('var Zipcode:', zipcode); // check geojson zipcode format
                    // console.log('outputData value:', value);

                    
                    // Check if a value was found for the zipcode
                    if (value !== null) {
                        
                        var normalizedValue = normalize(value, minValue, maxValue);
                        var opacity = normalizedValue;
                        console.log(`Zipcode: ${zipcode}, Output Value: ${value}, normalizedValue: ${normalizedValue}`); // Log the zipcode and corresponding output value
                        feature.properties.opacity = opacity;
                        

                        // Log the variables to the console
                        console.log("Zipcode:", zipcode);
                        console.log("Value:", value);
                        console.log("Normalized Value:", normalizedValue);
                        console.log("Opacity:", opacity);

                    } else {
                        console.log(`No output value found for zipcode: ${zipcode}`);
                    }
                
                } else {
                    console.log('Zipcode property not found for feature:', feature);
                }

                // Optionally, you can set other properties such as color based on the opacity value

                // Update the 'fill-opacity' property of the feature in the map layer

                
                map.setPaintProperty('polygons', 'fill-opacity', opacity);


            });

            // Log the map object to the console
            console.log(map);


            // Update the data source for the 'polygons' layer
            // map.getSource('polygons').setData(geojsonData);
            }






    </script>

</body>
</html>




        
      


java mapbox
1个回答
0
投票

我能够解决它。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Your Web App</title>
    <!-- Include Mapbox GL CSS and JS -->
    <link href="https://api.mapbox.com/mapbox-gl-js/v3.2.0/mapbox-gl.css" rel="stylesheet">
    <script src="https://api.mapbox.com/mapbox-gl-js/v3.2.0/mapbox-gl.js"></script>
    <!-- Your custom styles -->
    <style>
        #map {
            height: 100vh;
            width: 100%;
        }
    </style>
</head>
<body>
    <form action="/" method="post" id="inputForm">
        <label for="output">Output Metric:</label>
        <select name="output_metric_value" id="output">
            <option value="Housing Units">Housing Units</option>
            <option value="Tenure" selected>Tenure</option>
        </select>
        
        <label for="race">Race:</label>
        <select name="race_search_value" id="race">
            <option value="All" selected>All</option>
            <option value="White">White</option>
            <option value="Black or African American">Black or African American</option>
            <option value="American Indian and Alaskan Native">American Indian and Alaskan Native</option>
            <option value="Asian">Asian</option>
            <option value="Native Hawaiian and Other Pacific Islander">Native Hawaiian and Other Pacific Islander</option>
            <option value="Other Race">Other Race</option>
            <option value="2+ Races">2+ Races</option>
        </select>

        <label for="age">Age:</label>
        <select name="age_search_value" id="age">
            <option value="All" selected>All</option>
            <option value="15 to 24 Years Old">15 to 24 Years Old</option>
            <option value="25 to 34 Years Old">25 to 34 Years Old</option>
            <option value="35 to 44 Years Old">35 to 44 Years Old</option>
            <option value="45 to 54 Years Old">45 to 54 Years Old</option>
            <option value="55 to 59 Years Old">55 to 59 Years Old</option>
            <option value="60 to 64 Years Old">60 to 64 Years Old</option>
            <option value="65 to 74 Years Old">65 to 74 Years Old</option>
            <option value="75 to 84 Years Old">75 to 84 Years Old</option>
            <option value="85+ Years Old">85+ Years Old</option>
        </select>

        <label for="marital_status">Marital Status:</label>
        <select name="marital_status_value" id="marital_status">
            <option value="All" selected>All</option>
            <option value="Married Couple">Married Couple</option>
            <option value="No Spouse Present">No Spouse Present</option>
            <option value="No Spouse Present, Male Householder">No Spouse Present, Male Householder</option>
            <option value="No Spouse Present, Female Householder">No Spouse Present, Female Householder</option>
            <option value="Single">Single</option>
            <option value="Single, Male Householder">Single, Male Householder</option>
            <option value="Single, Female Householder">Single, Female Householder</option>
        </select>

        <label for="home_ownership">Home Ownership:</label>
        <select name="home_ownership_value" id="home_ownership">
            <option value="All" selected>All</option>
            <option value="Owner Occupied">Owner Occupied</option>
            <option value="Renter Occupied">Renter Occupied</option>
        </select>

        <input type="button" value="Submit" onclick="submitForm()">
    </form>

    <div id="map"></div>


    <script>
        // Your Mapbox access token
        mapboxgl.accessToken = 'pk.eyJ1IjoidG1jYmV0aDgwIiwiYSI6ImNsdDZndW1rZTBhemIycm9lZWo0eXBlcXQifQ.Fphu4YiYP2eEsky0WIjyuQ';

        var geojsonData;
        var map;

        // Fetch the GeoJSON data once when the page loads
        fetch('https://vizibalmaps.s3.amazonaws.com/2023_zipcode_20mb.json')
            .then(response => response.json())
            .then(data => {
                // Store the fetched data in the global variable
                geojsonData = data;

                // Initialize the map
                map = new mapboxgl.Map({
                    container: 'map',
                    style: 'mapbox://styles/mapbox/light-v10',
                    center: [-74.5, 40], // Default center coordinates
                    zoom: 4, // Adjust the zoom level
                });

                map.on('load', function () {
                    // Add initial layer
                    addLayer('polygons', {
                        'fill-color': '#FF5733',
                        'fill-opacity': 0.3,
                        'fill-outline-color': '#088',
                    });
                });
            })
            .catch(error => console.error('Error fetching GeoJSON:', error));

        // Function to submit the form
        function submitForm() {
            // Get selected values from dropdowns
            var outputMetric = document.getElementById('output').value;
            var race = document.getElementById('race').value;
            var age = document.getElementById('age').value;
            var maritalStatus = document.getElementById('marital_status').value;
            var homeOwnership = document.getElementById('home_ownership').value;
            
            // Make an AJAX request to the server to get updated data
            fetch('/process_data', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    output_metric_value: outputMetric,
                    race_search_value: race,
                    age_search_value: age,
                    marital_status_value: maritalStatus,
                    home_ownership_value: homeOwnership,
                }),
            })
            .then(response => response.json())
            .then(data => {
                // Log the data to the console to see its structure
                console.log('Output Data:', data);

                // Update the map with the new data and get the updated GeoJSON data
                var updatedGeoJSON = updateMap(data);

                // Log the updatedGeoJSON variable to the console
               console.log('Updated GeoJSON:', updatedGeoJSON);

                // Remove the existing layer
                if (map.getLayer('polygons')) {
                    map.removeLayer('polygons');
                }

                // Add a new layer to the map with the updated GeoJSON data
                map.addLayer({
                    id: 'updated-polygons',
                    type: 'fill',
                    source: {
                        type: 'geojson',
                        data: updatedGeoJSON,
                    },
                    paint: {
                        'fill-color': '#FF5733',
                        'fill-opacity': ['get', 'opacity'], // Use data-driven styling to set opacity
                        'fill-outline-color': '#088',
                    },
                });
            })
            .catch(error => console.error('Error:', error));
        }



        function getValueFromData(outputData, zipcode) {
            // Find the entry with the matching zipcode
            var entry = outputData.find(entry => entry.zipcode === zipcode);
            // Return the output_value if the entry is found, otherwise return null or handle appropriately
            return entry ? parseInt(entry.output_value) : null;
        }

        function normalize(value, min, max) {
            // Map the value from the range [min, max] to [0, 1]
            return (value - min) / (max - min);
        }


        // Function to update the map based on new data
        function updateMap(data) {
            // Extract the output data
            var outputData = data.output;

            // Get the min and max values from the data
            var values = outputData.map(entry => parseInt(entry.output_value));
            var minValue = Math.min(...values);
            var maxValue = Math.max(...values);

            // Iterate over the GeoJSON features to calculate normalized opacity based on the value
            geojsonData.features.forEach(feature => {
                // Check if the zipcode property exists in feature.properties
                if (feature.properties.hasOwnProperty('ZCTA5CE20')) {
                    var zipcode = feature.properties.ZCTA5CE20;
                    var value = getValueFromData(outputData, zipcode); // Assuming you have a function to extract the value from the data
                            
                    // Check if a value was found for the zipcode
                    if (value !== null) {
                        var normalizedValue = normalize(value, minValue, maxValue);
                        var opacity = normalizedValue;
                        // Update the opacity value in the GeoJSON data
                        feature.properties.opacity = opacity;
                    } else {
                        console.log(`No output value found for zipcode: ${zipcode}`);
                    }
                } else {
                    console.log('Zipcode property not found for feature:', feature);
                }
            });

            return geojsonData;

            // Log the updatedGeoJSON variable to the console
            console.log('Updated GeoJSON:', geojsonData);

        }


        // Function to add a layer to the map
        function addLayer(sourceId, paint) {
            map.addSource(sourceId, {
                type: 'geojson',
                data: geojsonData,
            });

            map.addLayer({
                id: sourceId,
                type: 'fill',
                source: sourceId,
                paint: paint,
            });
        }
    </script>

</body>
</html>

© www.soinside.com 2019 - 2024. All rights reserved.