ArcGIS API for JavaScript,过滤网络应用程序中的 geoJSON 图层?

ArcGIS API for JavaScript, Filter for geoJSON Layer in web app?

我正在使用 ArcGIS API 为 JavaScript 制作 3D 地球仪,总的来说,效果很好。但是,我在处理 GeoJSON 文件时遇到了一个挑战。

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

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

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

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

如果您使用的是 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>