The City of Kings Mountain, with a population of just over 11,000 residents, has been experiencing development pressures more commonly seen in much larger communities.
To improve zoning code enforcement, the City implemented a mobile-based solution using Esri’s ArcGIS Online ecosystem. Survey123 was used for field data collection, while ArcGIS Dashboards provided a centralized view of active violations and enforcement activity. Zoning officers can now capture location information, violation details, and photos directly from the field using mobile devices.
By moving to a connected GIS workflow, the City improved response times, reduced manual effort, and increased visibility into ongoing cases and compliance activity.
As development activity increased, the City of Kings Mountain needed a more reliable way to manage zoning enforcement across departments and field staff. The existing process depended on paper records, spreadsheets, phone calls, and informal tracking methods. This made it difficult to keep information consistent or maintain a clear view of what was happening in the field.
Violation details were often recorded in multiple places, and it was not always easy to connect photos, inspection notes, and follow-up actions to the same case. Tracking unresolved violations or checking compliance timelines required manual effort, which slowed down response times and created gaps in visibility for supervisors.
Field staff also had limited access to historical context while on site. Understanding whether a property had prior violations or whether a case was still open often required returning to the office or checking separate records after inspections were completed.
As the volume of inspections grew, these limitations made it harder to prioritize follow-ups, monitor overdue cases, and maintain a consistent enforcement process across the city.
We built a mobile-first workflow using Survey123 to standardize how zoning violations are collected in the field.
Key features include:
This ensures every violation is recorded consistently and can be submitted directly from the field without returning to the office.
All submitted violations are published to ArcGIS Online and displayed through a centralized web map.
Key features include:
This creates a reliable, always-updated source of truth for zoning enforcement data.
To reduce manual tracking and improve visibility, ArcGIS Dashboard is used to provide a live operational view of zoning enforcement activity.
Key features include:
This gives staff and supervisors immediate visibility into what needs attention without relying on manual reporting and keeps dashboards lightweight while improving real-time decision-making.
Flowchart
The City already had an investment in Esri’s ArcGIS platform, which allowed the solution to be built without introducing new systems or additional infrastructure.
Survey123 was selected because it provides a simple, structured way to collect accurate field data. It works both online and offline, which supports inspections in all areas of the City while ensuring consistent capture of photos, locations, and inspection details.
ArcGIS Dashboard was used to bring all enforcement activity into a single, real-time view. This gave staff and leadership immediate visibility into enforcement activity without relying exclusively on manual reports. Within the dashboard, Arcade expressions were used to calculate key information from live data. This added a layer of intelligence to the dashboard, reducing manual tracking and ensuring information stays current as new cases are submitted.
Since implementing the new workflow, the City of Kings Mountain has significantly improved how zoning violations are managed from the field to the office. What was once a manual, multi-step process is now handled through a connected, real-time system that improves speed, visibility, and coordination across teams.
What once took days to compile and track can now be reviewed in minutes. Staff no longer rely on memory, paper notes, or disconnected spreadsheets, as all enforcement data is consistently up to date and centrally available.
"The Esri ecosystem has allowed us to input complaints both in and out of the office and generate base reports, eliminating the need to create reports from scratch or copy previous ones. This system has enabled our department to broaden its efforts in enforcing the City's regulations, even with just one enforcement officer."
Jaylon M. Smallwood
Zoning Administrator, City of Kings Mountain
We have compiled some nifty Arcade examples that you could try in your Dashboards next
Data expressions can be used to create dynamic fields that update in real time based on simple business logic.
This example calculates how many days have passed since the last inspection and assigns a status depending on whether action is needed.
// Pull only required fields, no geometry for better performancevar myFeatureSet = FeatureSetByPortalItem(Portal("https://your-portal-url.com/"), "your-item-id", 0, ["AssetID", "Status", "LastInspectionDate"], false)// Store processed output featuresvar features = []// Loop through each recordfor (var f in myFeatureSet)// Days since last inspectionvar daysSince = DateDiff(Today(), f.LastInspectionDate, "days")// Set default statusvar inspectionStatus = ""// Closed records stay closedif (f.Status == "Closed") {inspectionStatus = "Closed"}// Recently inspected within 14 dayselse if (!IsEmpty(f.LastInspectionDate) && daysSince <= 14) {inspectionStatus = "Inspected"}// Open records needing inspectionelse if (f.Status == "Open" && (IsEmpty(f.LastInspectionDate) || daysSince > 14)) {inspectionStatus = "Inspection Needed"}// Build output recordPush(features, {attributes: {AssetID: f.AssetID,DaysSinceInspection: daysSince,InspectionStatus: inspectionStatus}})}// Return final FeatureSetreturn FeatureSet({fields: [{ name: "AssetID", type: "esriFieldTypeString" },{ name: "DaysSinceInspection", type: "esriFieldTypeInteger" },{ name: "InspectionStatus", type: "esriFieldTypeString" }],features: features})
Data expressions can also be used to create custom groupings that go beyond what is available directly in the dashboard. By combining multiple fields, you can easily summarize data in a more meaningful way.
This example groups records by their status and an existing incident category field.
// Pull required fields, no geometryvar myFeatureSet = FeatureSetByPortalItem(Portal("https://your-portal-url.com/"), "your-item-id", 0, ["Status", "IncidentCategory"], false)// Prepare outputvar features = []// Loop through recordsfor (var f in myFeatureSet) {// Build simplified datasetPush(features, {attributes: {Status: f.Status,IncidentCategory: f.IncidentCategory,Count: 1}})}// Create FeatureSetvar fs = FeatureSet({fields: [{ name: "Status", type: "esriFieldTypeString" },{ name: "IncidentCategory", type: "esriFieldTypeString" },{ name: "Count", type: "esriFieldTypeInteger" }],features: features})// Group by multiple fieldsreturn GroupBy(fs,["Status", "IncidentCategory"],[{ name: "Total", expression: "Count", statistic: "SUM" }]
)
Data expressions can also be used to control how data is visually represented inside dashboard elements. This allows you to highlight important records directly within lists or tables using conditional formatting.
For example, you can change text colors based on the inspection status to quickly draw attention to records that need action.
// Get status value from the current data pointvar Status = $datapoint.InspectionStatus// Set text color based on statusvar txtColor = When(Status == "Closed", "#008000",Status == "Inspected", "#002fff",Status == "Inspection Needed", "#cf0808","#000000")// Return styling properties for the dashboard elementreturn {textColor: txtColor,backgroundColor: "",separatorColor: "",selectionColor: "",selectionTextColor: "#0c5885"}
For those looking to explore Arcade data expressions and dashboard workflows further, the following resources are a good starting point: