Skip to content

Commit b695822

Browse files
committed
Add ArcGIS webmap popup configurator with reusable Arcade expression; update project index
1 parent 58af890 commit b695822

6 files changed

Lines changed: 854 additions & 0 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ A collection of Python scripts and utilities for GIS automation, primarily focus
1010
| [arcgis-locator-rebuilder](./arcgis-locator-rebuilder) | Scheduled rebuilds of composite geocoding locators via the ArcGIS Server Admin REST API, with safe service stop/rebuild/restart orchestration and guaranteed service restart on failure. |
1111
| [arcgis-network-dataset-rebuilder](./arcgis-network-dataset-rebuilder) | End-to-end network dataset maintenance for routing: refresh sources from production, populate network attributes and hierarchy-penalized travel times, rebuild the network, and compress the geodatabase. |
1212
| [arcgis-replica-auditor](./arcgis-replica-auditor) | Replica health system: audits feature service sync replicas across multiple enterprise geodatabases, unregisters replicas older than a rolling age threshold, and ships with a single-file HTML dashboard visualizing owners, sync status, and source databases. |
13+
| [arcgis-webmap-popups](./arcgis-webmap-popups) | Applies one consistent, accessible Arcade popup to every feature layer in a MapServer group layer, driven from a single reusable expression file. Auto-formats dates, domains, currency, phones, emails, and links with WCAG-conscious HTML. |
1314

1415
More utilities will be added over time.
1516

‎arcgis-webmap-popups/.gitignore‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Credentials - never commit
2+
secrets.py
3+
4+
# Runtime artifacts
5+
*.log
6+
__pycache__/
7+
*.pyc

‎arcgis-webmap-popups/README.md‎

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# ArcGIS Webmap Popup Configurator
2+
3+
Applies one consistent, accessible Arcade popup to every feature layer inside a MapServer group layer in an ArcGIS Enterprise or ArcGIS Online web map — without hand-configuring each sublayer in Map Viewer.
4+
5+
Built and battle-tested by the City of Grand Junction GIS Division.
6+
7+
## The problem this solves
8+
9+
When you add a MapServer to a web map, its sublayers often show up by numeric ID with no popup configured. Setting up popups by hand across many layers — and many web maps — is tedious, and the configurations drift out of sync over time. This script drives every layer from a single Arcade expression, so they all get the same well-formatted, accessible popup, and updating the expression updates everything on the next run.
10+
11+
## What it does
12+
13+
1. Connects to your portal and loads the web map JSON
14+
2. Finds the target group layer (searching nested groups recursively) and reads the real sublayer names from the MapServer REST endpoint
15+
3. Rebuilds the group's `layers` array, enabling a popup on every feature sublayer and disabling it on group sublayers
16+
4. Applies one shared Arcade expression (see below) to each feature sublayer
17+
5. Optionally applies the same popup to one top-level feature layer sitting beside the group (e.g. a `Parcels` layer)
18+
6. Saves the web map in a single update call, so either all changes land or none do
19+
20+
## The Arcade expression
21+
22+
`arcade_popup.js` is a generic, accessible field-listing popup. For each feature it renders every non-excluded field as `Label: value`, one per line, and auto-formats:
23+
24+
- **Dates** → `MM/DD/YYYY`
25+
- **Coded domain values** → the description, not the raw code (resolved before any type detection)
26+
- **Booleans** → True/False or Yes/No (with alias hints for 1/0 fields like `IsActive`)
27+
- **Currency** → `$#,###.##`, with anti-hints so measurement aliases like "Square Feet" are never mistaken for money because "fee" is a substring of "feet"
28+
- **Phone numbers** → `(xxx) xxx-xxxx` as `tel:` links, detected by digit count + punctuation + alias hints, with anti-hints to reject IDs, coordinates, and measurements that happen to have 10 digits
29+
- **Emails** → `mailto:` links
30+
- **Hyperlinks** → absolute `http(s)://` values become links automatically
31+
32+
It produces WCAG-conscious HTML: semantic `<strong>` labels, descriptive link accessible-names via `title` attributes, `(opens in new window)` announcements with `rel="noopener noreferrer"`, and trimmed whitespace so blank fields don't render empty rows.
33+
34+
The expression needs **no editing** to work. Two things you may want to customize are clearly marked at the top of the file:
35+
36+
1. `fieldsToExclude` — system/internal field names to hide
37+
2. The **DOCUMENT LINK SETTINGS** block — if your data stores relative document paths (like `docs/permit123.pdf`) that should become links against your own document server, set `ENABLE_DOC_LINKS = true` and `DOC_BASE_URL`. Off by default; absolute URLs are always linked regardless.
38+
39+
Because the Arcade lives in its own file, you can edit and version it independently, and reuse it in Map Viewer or Experience Builder directly.
40+
41+
## Requirements
42+
43+
- Python 3.7+ with the ArcGIS API for Python (`arcgis`) and `requests` — both included with ArcGIS Pro
44+
- A portal account with rights to edit the target web map
45+
- The target layer must be a MapServer group layer in the web map
46+
47+
## Setup
48+
49+
1. Clone the repo
50+
2. Copy `secrets.example.py` to `secrets.py` and set your portal password (`secrets.py` is gitignored)
51+
3. Edit the CONFIGURATION block at the top of `update_webmap_popups.py`:
52+
- `PORTAL_URL`, `WEBMAP_ITEM_ID`, `USERNAME`
53+
- `TARGET_GROUP_LAYER` — the name of the MapServer group layer to process
54+
- `TOP_LEVEL_LAYER` — optional single top-level layer to also configure, or `None`
55+
4. Run it from an ArcGIS Pro Python environment:
56+
57+
```
58+
python update_webmap_popups.py
59+
```
60+
61+
5. Check `webmap_popup_update.log` for a per-layer report
62+
63+
## Running across many web maps
64+
65+
The City of Grand Junction GIS Division runs this across ten web maps (internal and external). The simplest approach is one copy of the config block per map, or a small driver script that imports the functions and loops over a list of `(item_id, group_layer)` pairs. Keeping the Arcade in `arcade_popup.js` means all maps share one expression — edit it once, rerun, and every popup updates.
66+
67+
## Notes and gotchas
68+
69+
- Uses `disablePopup: false` rather than `popupEnabled: true` — the former is what current Map Viewer and Experience Builder honor reliably
70+
- The Arcade uses plain structural HTML (no inline colors); Map Viewer and Experience Builder popup themes override inline color styles on `<strong>`/`<a>`, so colored text renders inconsistently and is best left to the theme
71+
- Group sublayers (those with `subLayerIds`) get popups disabled since they have no features of their own
72+
- If the target group layer or the optional top-level layer isn't found, the script logs the available layer names to help you correct the configuration
73+
74+
## License
75+
76+
Apache License 2.0

0 commit comments

Comments
 (0)