【问题标题】:ArcGIS API for JavaScript, Filter for geoJSON Layer in web app?ArcGIS API for JavaScript,Web 应用程序中的 geoJSON 图层过滤器?
【发布时间】:2021-07-17 19:31:10
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: javascript filtering geojson arcgis arcgis-js-api


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2016-11-23
      • 1970-01-01
      • 2016-02-05
      • 2014-01-24
      • 1970-01-01
      • 2011-04-07
      • 2015-07-22
      • 2017-06-04
      • 2012-05-14
      相关资源
      最近更新 更多