Identify By Query

98
1
Friday

Identify By Query

This is a ground-up re-design and re-build of my previous Identify Widget. It is designed to act as a replacement for a popup in an auto-opening Sidebar. If you have used the previous version of the Widget here are the major improvements:

  • Identify from all types of layers. (The previous Widget was limited to Feature Layers.)
  • Identify receives the Record Selection Changes Message option, allowing built-in integration with OOTB Widgets.
    • More than just a Customized Search Widget, as in the prior Widget.
  • Works with any type of input geometry.
    • The previous version could only handle points.
  • Built-in draw tools for creating an search area.
  • Faster processing.
  • Capable of identifying hundreds of features at once without significant performance degradation.
  • Sorting options for results.
  • Many appearance options for Builders.
  • Integration of the previously separate Identify Controller Widget.
  • Integration with the Community Draw Widget
  • Built using Components.

It all looks something like this:

JeffreyThompson2_0-1777658447085.png

This re-design was instigated by four issues with the previous Widget. The previous Widget used the Feature Widget from the JavaScript, which is deprecated. It also incorporated some React anti-patterns that would occasionally result in some errors. This design should be much more React friendly. The Search Widget previously packaged to work with the prior version is no longer functional. Finally, the previous design and the standard popup is dependent on hitTest() which is in turn dependent on the LayerView. This dependency makes it so that the layer must be fully loaded before the query can start to find features. It also makes querying non-FeatureLayers more difficult. This Widget avoids hitTest() entirely and directly queries the layers which greatly improves the ultimate speed, or at least perceived speed, of the response.

What can be identified?

For a layer or sublayer to be identifiable by this Widget, it must meet the following criteria:

  • The layer must be visible.
  • The layer must have queries enabled.
  • Popups must be enabled for the layer.
  • The layer must not use scale dependent visibility or the current scale must be in the layer's scale range.
  • The layer must have a popup template or a default popup template.
    • This Widget should respect any popup customization set up on the webmap or REST endpoint.
  • Annotation layers are excluded.

This set of criteria should closely mirror the behavior of the standard popup. And the Widget should check these criteria at the sublayer level, if applicable. These criteria are checked dynamically every time Identify is triggered, so it will stay up-to-the-moment with layer changes.

Note: If you use Group Layers and turn off visibility at the group level, but leave the visibility on at the layer level, the layer will still be identified. Group Layers do not have true sublayers and there is no practical way of testing if a layer is part of a Group Layer that I know of.

It shows me popup info. That's great. How is it presented?

  • The Search Area is shown with a magenta drawing on the map.
    • Users can hide and turn this on/off with the Show Search Graphics Switch.
  • Data is neatly sorted by layer with Tabs.
    • Builder option to not use Tabs for results.
  • If a large number of results are found in a layer, Pagination is used to further organize data.
    • Builder option for how many results before Pagination is used.
      • Set the number really high if you don't want Pagination.
  • Each individual feature is wrapped in a Collapsable Panel for hiding a result.
    • The panels will not be used if only one result is found in a layer or Pagination is set to 1.
  • Each feature has options to Zoom To it, Highlight it or send it to the Draw Widget with Copy To Draw.
    • Builder option to disable Copy To Draw.
    • Highlighting can also be turned on/off at the layer level with Highlight Layer Button or the all feature level with the Highlight All Features Switch.
      • Note: The Experience Builder framework will also trigger its own highlighting that is not controllable by this Widget.
      • Hovering over a result table will also cause the feature to briefly highlight in yellow.
  • Features are default sorted by their proximity to the center of the search area with the distance to center displayed for each feature.
    • User options to sort alphabetically, numerically, or temporally with dropdown menu of appropriate fields.JeffreyThompson2_1-1777660278461.png

       

    • Builder option to disable sorting.
      • This also hides the Highlight Layer Button.
  • Metadata shows the size of the area searched and where it is centered.
    • Builder options for metric or imperial units and XY or Lat/Long.

Important note about distances and areas in this Widget: This Widget uses planer calculations of area and distance. It does not account for the curvature of the Earth. All distances and measurements should be treated as estimates, not accurate measurements. There are two reasons for this:

  1. The functions which account for the curvature of the Earth require working with Promises, which would greatly increase the programming complexity and greatly slow the processing speed.
  2. Over the distances this Widget is designed to work in, the difference in the calculations should be small.

What kind of shapes can I use to Identify with?

Starting in the top row and going left to right the options are:

  • Map Extent - Selects the entire currently visible map extent.
    • Note: This Widget can return an indefinite number of results at a time and it performs well into the hundreds of results. However, somewhere around 500 results the performance dramatically decreases and it will take a long time for results to be returned. Unintuitively, this will also dramatically slow down the next search in the sequence as well.
      • Using this option can easily exceed this threshold, use with caution.
  • Point - This is the default option.
    • A click listener will Identify immediately wherever the map is clicked.
      • The user can turn off this click listener by clicking the Point Button, turning off the Map Click Search Switch, or picking a different draw tool.
    • Builder option to disable this when the Widget loads.
    • By default, the Widget will switch to Point mode after some other shape is used.
      • Turning off Map Click Search will disable this behavior.
        • This is how the Map Click Search Switch and Point Buttons differ. Allowing users to draw a shape without fear of accidentally triggering a Point search.
      • Builders can hide this Switch, if not wanted.
    • Note: Points are not points. They are circles that are really 60-sided polygons. It is practically impossible to use a point to find another point or line feature. This is why the standard hitTest() function uses a 6 pixel buffer around the actual clicked point. This Widget mimics this behavior by using a buffer that is some percentage of the width of the screen.
      • Builder option for controlling the percentage this buffer represents.
      • The default is 0.005. This is a bit larger than the hitTest() standard, but much smaller it becomes very difficult to identify points.
  • Polyline
  • Freehand Polyline
  • Rectangle- First option on second line.
  • Polygon
  • Freehand Polygon
  • Circle - Not a true circle. It's a 60-sided polygon.

How does interactivity with other Widgets work?

  • To trigger this Widget with an OOTB Widget, set up a Record Selected Changes Action in the OOTB Widget.
    • I have tested with Search (Layer Source and Locator Source), List and Query Widgets.
    • Identify can handle Single or Multiple Selection options in the OOTB Widgets.
    • Setting up a Map > Zoom To Action is recommended, but not required.
      • This prevents issues with unexpected identification resulting from scale dependent visibility.
      • Better overall UX.
    • Users have an option to turn off this functionality.
      • Builders have an option to hide this user option.
        • Builders should hide this, if they don't have a Message Action set up.
    • When triggering from an external source, features are slightly altered.
      • Point-type geometries: Point data is given a circular buffer as described above.
      • Polyline-type geometries: It is also very difficult to find points and lines with lines, so polylines are given a 1 unit buffer around the line.
      • Polygon-type geometries: In order to avoid selecting features immediately adjacent to polygons, polygons are given a 1 unit negative buffer. 
  • Interactivity with the Draw Widget
    • To set up interactivity, the features must be enabled in the Settings of both Widgets and the Draw Widget must know the widget id number of the Identify Widget.
    • As noted above, identified features can be copied into the Draw Widget to take advantage of all the Draw Widget tools.
    • Drawings in the Draw Widget can be sent to the Identify Widget as a search area.
      • If a buffer is used in Draw, the buffer will be sent to Identify.
      • Drawings will be processed through the same logic described above.
        • You may want to add an extra unit to your buffers in Draw for better accuracy in Identify.
    • While the Draw Widget is is Drawing Mode, Identify will be disabled.
      • This prevents annoying, accidental triggers of Identify.

Big thank you to @Brian_McLeer for all the work on making this work with Draw. He also improved the highlighting functionality and found several issues/bugs.

What's this Controls Tab for?

This is my version of a Map Layers List. Every operational layer and sublayer that does not have the listMode = 'hide' property is listed in this sub-widget.

  • Sublayers are listed in Collapsable Panels.
  • This list will adapt to map changes.
  • Identifiable layers are labeled in black.
  • Layers that cannot currently be identified are labelled in light grey with a reason why Identify won't work on them.
  • Each layer has four buttons from left to right they are:
    • Identify - Turns on/off identify for this layer.
    • Exclusive Identify
      • Turns on Identify for this layer and turns it off for all other layers.
      • Turning this feature off should reset the identify settings as they were before it was turned on.
    • Visibility - Turns on/off visibility for this layer.
    • Exclusive Visibility - Like the Exclusive Identify, but toggles visibility.
  • There are five additional buttons at the bottom. They are:
    • Reset Identifiability and Visibility to Defaults
      • When a layer is first loaded into the map, this Widget will save its popupEnabled and visibility state. Clicking this button will instantly reset every map layer to its initial states.
    • The other four buttons are intended to be used when only a few layers are supposed to be or not be visible or identifiable. Click one of these then the individual layer buttons.
      • All Layers Identifiable
      • All Layers Visible
      • No Layers Identifiable
      • No Layers VisibleJeffreyThompson2_0-1777667711270.png

         

Recommended Settings

  • Place this Widget inside a Sidebar.
    • Place it immediately after adding the Sidebar and subtract one from this Widget's id number to get the Sidebar widget id number.
    • Use a left or right side dock position with a minimum width of 400px.
    • Turn on the Overlay property.
    • Set the Default State to Collapsed.
  • Map Widget
    • Turn off Enable Popup.
    • Set the Highlight Fill to transparent.
  • Map Layers Widget
    • Turn off the Enable or Disable pop-up option.
      • Use the on/off options in the Control Tab instead.
      • It will start out-of-sync, thinking that all layers have popups disabled.
      • Turning it on and off will cause the standard popup to activate with no way to turn it back off.

Note: This Widget was primarily developed in Experience Builder 1.19. It should work in both 1.19 and 1.20, however, the Draw Widget interactivity requires using 1.20 as the latest version of the Draw Widget is only in 1.20. The final version was only tested in 1.20.

Attachments
Comments
ncramer11
Occasional Contributor

I was just looking for an updated version of this today... and it integrates with Advanced Draw? I wish I could give more than 1 kudos!

Version history
Last update:
Friday
Updated by:
Contributors