Select to view content in your preferred language

Unable to search a geojsonlayer that is not added to the view when the map loads

742
5
01-19-2022 11:43 AM
Fox71
by
Emerging Contributor

Hello,

I created a geojsonLayers from a local json file. However, the definitionExpression is set to "1=0" so none of the points show when the page loads. The points visibility is triggered by checkboxes in a menu that update the definitionExpression. This works fine.

The problem is that the search UI doesn't search that jsonlayer because none of the points are actually added to the view when the map loads.

Is there a solution to that? Probably a different approach.

A solution I found was to reload the json file in the search source, but then I lose the jsonrender define for the jsonlayer.

Any help appreciated.

Thanks!

Ben

0 Kudos
5 Replies
JeffreyWilkerson
Frequent Contributor

Can you just set it's visible property to 'false' when you create it, and then load it into the View as normal?  Then you can set it's visible property to 'true' when the user clicks on something.

Fox71
by
Emerging Contributor

The problem is that when the user use the checkboxes, this updates the definitionExpression (query) which only shows some points on that layer. At that stage, I think only the points returned by the query are available to the search.

0 Kudos
JeffreyWilkerson
Frequent Contributor

Visibility is separate from the Definition Expression thing.  My point is that you don't need to rely on definition expression to control the layer's visibility.  If you 'load' the layer at the beginning with it turned off, you aren't worrying about it being visible with any defined expression, but when you the user generates an expression you can turn visibility on to display the results. 

Maybe this example will help:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="viewport"
          content="initial-scale=1,maximum-scale=1,user-scalable=no" />
    <title>
        Example resetting a FeatureLayer's Definition Expression with Visibility
    </title>
    <link rel="stylesheet"
          href="https://js.arcgis.com/4.22/esri/themes/dark/main.css" />
    <script src="https://js.arcgis.com/4.22/"></script>

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

        #infoDiv {
            padding: 6px;
            width: 370px;
            height: 97%;
            position: absolute;
            top: 10px;
            right: 10px;
            --calcite-ui-brand: #71C96E;
            --calcite-ui-brand-hover: #67B564;
        }

        #resultsDiv {
            overflow: auto;
            display: none;
        }
    </style>

    <script>
        require([
            "esri/Map",
            "esri/views/MapView",
            "esri/layers/FeatureLayer",
            "esri/Basemap",
            "esri/layers/GeoJSONLayer"
        ], (
            Map,
            MapView,
            FeatureLayer,
            Basemap,
            GeoJSONLayer
        ) =>
            (async () => {
                // dark human geography basemap
                const basemap = new Basemap({
                    portalItem: {
                        id: "4f2e99ba65e34bb8af49733d9778fb8e"
                    }
                });

                // layers
                const layer1 = new FeatureLayer({
                    url: "https://services9.arcgis.com/RHVPKKiFTONKtxq3/ArcGIS/rest/services/NDFD_WindForecast_v1/FeatureServer/0",
                    outFields: ["*"]
                });

                const geojsonLayer = new GeoJSONLayer({
                    url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson",
                    copyright: "USGS Earthquakes",
                    visible: false
                });

                const map = new Map({
                    basemap,
                    layers: [layer1, geojsonLayer]
                });

                const view = new MapView({
                    container: "viewDiv",
                    map: map,
                    center: [-112.4, 33.5],
                    zoom: 3,
                    padding: {
                        right: 380
                    }
                });

                view.when(function () {
                    view.ui.add("buttons", "bottom-right");
                    document.getElementById("btnTest1").addEventListener('click', function () { testDef("Low"); });
                    document.getElementById("btnTest2").addEventListener('click', function () { testDef("High") });
                    document.getElementById("btnOff").addEventListener('click', function () { testDef("Off") });
                });
                
                function testDef(inCheck) {
                    if (inCheck == "Off") {
                        geojsonLayer.visible = false;
                    }
                    else {
                        geojsonLayer.visible = true;
                        var defExp = "mag < 1";
                        if (inCheck == "High") {
                            defExp = "mag > 1";
                        }
                        geojsonLayer.definitionExpression = defExp;
                    }
                }
            })());
    </script>
</head>

<body>
    <div id="viewDiv"></div>
    <div id="buttons">
        <button id="btnTest1">Low Magnitude</button>
        <button id="btnTest2">High Magnitude</button>
        <button id="btnOff">Off</button>
    </div>
</body>
</html>
0 Kudos
Fox71
by
Emerging Contributor

Thanks a lot Jeffrey for the example. 

I was able to update my code to use your approach. But I'm still having the issue of the icon on the search results.

I use a renderer on the jsonlayer to assign different icons to groups of points (the ones toggled by checkboxes). While the search seems to retrieve every points, it doesn't render icons that are define in the renderer of the jsonlayer.

0 Kudos
Fox71
by
Emerging Contributor

Jeffrey, the code doesn't work in this case. If the user start by using a button, the definitionExpression remove all other points and the search only finds what the points included with the definitionExpression. The code only works after the page loads and the user use the search (all points from that layer are just invisible but available to search). Once the user clicks a button, the query limits what available to the search in that jsonlayer.... if I'm not mistaken

0 Kudos