首页 > 解决方案 > ArcGIS API for JavaScript,Web 应用程序中的 geoJSON 图层过滤器?

问题描述

我正在使用 ArcGIS API for JavaScript 制作 3D 地球仪,总体而言,它运行良好。但是,我在处理 GeoJSON 文件时遇到了一个挑战。

我向地球添加了一个 GeoJSON 图层,它基本上包含有关世界各地几个有趣的地质特征的信息。我为每个位置添加了一个弹出窗口和一个符号。然而,所有这些位置都属于不同的类别,例如珊瑚礁、火山、矿床等等。我想添加某种过滤器,以便用户可以选择他们想在这个地球上探索的类别。

对于 GeoJSON 层,这是否可能,如果是,我该如何实现它?如果有人可以在正确的方向上给我一个轻推,或者就可能的事情提供一些建议,我将非常感激。

或者,不同类别的不同符号和图例也可以。我找到了有关它如何与常规要素图层一起使用的信息。尽管如此,我还是找不到关于如何在 GeoJSON 图层上应用它的教程。

这是我的第一个编码项目,非常感谢所有帮助。

标签: javascriptfilteringgeojsonarcgisarcgis-js-api

解决方案


如果您使用的是 GeoJSON 源,那么您将不得不使用客户端中的数据,这意味着您在检索源时获得的功能。

GeoJSONViewLayer在您的情况下,要过滤或查询功能,您可以使用图层(对象)的视图图层。

这是一本很好的读物,可以了解它是什么以及如何使用服务器(远程)或客户端(本地)数据,ArcGIS Docs - Query/Filter

无论如何,我给你做了一个简单的例子来掌握,

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <title>GeoJSONLayer</title>

    <style>
        html,
        body,
        #viewDiv {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }

        #controls {
            width: 500px;
        }

        #outerContainer {
            padding: 15px;
            width: 500px;
        }
    </style>

    <link rel="stylesheet" href="https://js.arcgis.com/4.16/esri/themes/light/main.css" />
    <script src="https://js.arcgis.com/4.16/"></script>

    <script>
        require([
            "esri/Map",
            "esri/layers/GeoJSONLayer",
            "esri/views/MapView",
            "esri/widgets/Expand",
            "esri/widgets/HistogramRangeSlider",
            "esri/smartMapping/statistics/histogram",
            "esri/core/promiseUtils"
        ], function (
            Map,
            GeoJSONLayer,
            MapView,
            Expand,
            HistogramRangeSlider,
            histogram,
            promiseUtils
        ) {
            // layer set up
            const url = "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson";
            const template = {
                title: "Earthquake Info",
                content: "Magnitude {mag} {type} hit {place} on {time}",
                fieldInfos: [
                    {
                        fieldName: 'time',
                        format: {
                            dateFormat: 'short-date-short-time'
                        }
                    }
                ]
            };
            const renderer = {
                type: "simple",
                field: "mag",
                symbol: {
                    type: "simple-marker",
                    color: "rgba(225, 125, 0, 0.5)",
                    outline: {
                        color: "rgba(225, 125, 0, 0.5)"
                    }
                },
                visualVariables: [{
                    type: "size",
                    field: "mag",
                    stops: [
                        { value: 1, size: "1px" },
                        { value: 2, size: "2px" },
                        { value: 3, size: "4px" },
                        { value: 4, size: "8px" },
                        { value: 5, size: "16px" },
                        { value: 6, size: "32px" },
                        { value: 7, size: "64px" }
                    ]
                }]
            };
            const layer = new GeoJSONLayer({
                url: url,
                copyright: "USGS Earthquakes",
                popupTemplate: template,
                renderer: renderer
            });
            // map and view set up
            const map = new Map({
                basemap: "gray",
                layers: [layer]
            });
            const view = new MapView({
                container: "viewDiv",
                center: [10, 10],
                zoom: 3,
                map: map
            });
            view.whenLayerView(layer).then(layerView => {
                
                // filter logic
                const today = new Date(Date.now());
                const breaks = [
                    new Date(today.getFullYear(), today.getMonth(), 1),
                    new Date(today.getFullYear(), today.getMonth(), 7),
                    new Date(today.getFullYear(), today.getMonth(), 14),
                    new Date(today.getFullYear(), today.getMonth(), 21),
                    new Date(today.getFullYear(), today.getMonth() + 1, 0),
                ]
                const weeks = [true, true, true, true];
                const condition = document.getElementById("conditionSpan");
                const inputs = document.querySelectorAll("input[type='checkbox']");
                const updateCondition = _ => {
                    const conditions = [];
                    for (let i = 0; i < 4; i++) {
                        weeks[i] = inputs[i].checked;
                    }
                }
                const updateConditionText = _ => {
                    const conditions = [];
                    for (let i = 0; i < 4; i++) {
                        if (weeks[i]) {
                            conditions.push(
                                `(updated >= ${breaks[i].toDateString()} AND updated <= ${breaks[i + 1].toDateString()})`
                            )
                        }
                    }
                    condition.innerText = conditions.join(" OR ");
                };
                const updateLayer = _ => {
                    const conditions = [];
                    for (let i = 0; i < 4; i++) {
                        if (weeks[i]) {
                            conditions.push(
                                `(updated >= ${breaks[i].getTime()} AND updated <= ${breaks[i + 1].getTime()})`
                            )
                        }
                    }
                    layerView.filter = { where: conditions.length === 0 ? "false" : conditions.join(" OR ") };
                }
                inputs.forEach(input => input.addEventListener("click", _ => {
                    updateCondition();
                    updateConditionText();
                    updateLayer();
                }));
                updateCondition();
                updateConditionText();
            });
        });
    </script>
</head>

<body>
    <div class="esri-widget">
        <h3>Filter Month Earthquakes By Week</h3>
        <input id="week1" type="checkbox" value="1" checked><label for="week1">First Week</label>
        <input id="week2" type="checkbox" value="2" checked><label for="week2">Second Week</label>
        <input id="week3" type="checkbox" value="3" checked><label for="week3">Third Week</label>
        <input id="week4" type="checkbox" value="4" checked><label for="week4">Last Week</label>
        <p>Condition: <span id="conditionSpan"></span></p>
    </div>
    <div id="viewDiv"></div>
</body>

</html>


推荐阅读