This document will demonstrate how you can use GeoEvent to update a street’s plow status from an AVL feed. Sample data is provided, and the steps can be completed with GeoEvent 10.9.1 or later, and ArcGIS Pro 2.x or later. The services referenced in the below workflow will be published to ArcGIS Enterprise as hosted feature services, but they can also be published to ArcGIS Online.
Data Preparation
The SnowPlowStatus.gdb contains a SnowRoutes feature class. This was created from a small sample of street centerlines.

Streets will vary in size. When a plow truck is traversing down the street, it may only be plowing one side of the street. If the AVL information is accurate, the street centerlines can be buffered twice, once on each side of the street, to give finer granularity. The SnowRoutes feature class was created by:
- Buffering (i.e. 20 ft) the street centerlines on the Right side with Flat end type. Ex:

- Buffering (i.e. 20 ft) the street centerlines on the Left side with Flat end type
- Merging the results to a single feature class
New fields are added to the SnowRoutes feature class and Editor Tracking has been enabled:

Field Name | Field Type | Description |
PlowStatus | TEXT | Field to indicate whether the street is ‘Plowed’ or ‘Not Plowed’ |
ID | LONG | Unique ID for each street segment. If there originally was a unique ID, these are now duplicated from buffering the street segments. This new ID field is calculated from the OBJECTID field. This will be used for the Geofences |
EnterDate | DATE | Field to record date/time when a vehicle enters the street |
ExitDate | DATE | Field to record date/time when a vehicle exits the street |
Publish Snow Routes Service
1. Add the SnowRoutes feature class to a map in ArcGIS Pro
2. Open the Apply Symbology From Layer tool to apply the Snow Routes.lyrx
3. Specify Value field for Type
4. Specify Plow Status for Source Field and Target Field, then execute the tool


5. Publish the Snow Routes feature class as an editable feature service. In this workflow, the service is published as a hosted feature service
Configure GeoEvent
Import GeoFences
The Snow Routes will be imported as Geofences. One thing to note is that Geofences are stored in memory. If you have several thousand street segments make sure you have enough RAM on your server to accommodate the geofences. ArcGIS GeoEvent Server runs in a Java Virtual Machine (JVM) instance. The out-of-the-box default configuration allocates only 4 GB of your server's available RAM to this JVM. It may be necessary to increase this, especially if you have many geofences. See the following help document on how to do this.
- Log into GeoEvent Manager and navigate to Site > Geofences
- Click Import and select the Snow Routes previously published
- For Category Field manually enter snowroutes
- For Name Field click the dropdown and select id
- Specify 3857 for the WKID
- Specify the Query Definition as 1=1 and click Import

Result:

Configure Input
The GeoEvent Simulator will be used to send AVL locations from the SnowPlowAVL.csv to a Receive Text from a TCP Socket input. The SnowPlowAVL.csv contains 5 fields:
Field Name | Description |
vin | VIN number of the snow plow vehicle |
longitude | Longitude of the snow plow location |
latitude | Latitude of the snow plow location |
plow | Indicates whether the plow is up or down |
heading | Direction vehicle is traveling |
1. In GeoEvent Manager > Site, click on GeoEvent Definitions
2. Click New and specify a name (i.e. Snow Plows AVL)
3. Create a GeoEvent Definition with the below fields/tags:

4. In GeoEvent Manger, add a Receive Text from a TCP Socket input
5. Create the input with the following parameters and click Save

6. Start the Input
7. On the GeoEvent Server, go to Start > ArcGIS > GeoEvent Simulator
8. Click the option to connect at the top right:

9. Click the folder and browse to the SnowPlowAVL.csv
10. Check the option to Skip the First 1 Lines and click Load

11. Send an event by clicking on the Step arrow and check GeoEvent Manager to make sure the input has increased by 1

Write the AVL Data to a Feature Service
1. In GeoEvent Manager, add Update a Feature output
2. Click Publish a Feature
3. Specify a name (SnowPlowLocations) and choose the Snow Plows AVL GeoEvent Definition created previously

4. Click Publish
5. Specify a name for the Output Service (Snow Plow Locations Output) and select vin for the Unique Feature Identifier Field and click Save

6. Start the Output
7. Create a new GeoEvent Service (Snow Plow Locations)
8. Add the Snow Plows AVL tcp-text-in and the Snow Plow Locations Output to the service, connect the two, then click Publish

Create an Output for the Snow Routes Feature Service
An Update a Feature output will be created in GeoEvent to update the Snow Routes feature service
- In GeoEvent Manager, create a new Update a Feature Output called Snow Routes Output
- Select the Snow Routes feature service published previously
- Set the Unique Feature Identifier Field to id and click Save

Create Snow Route GeoEvent Definitions
There will be different iterations of Snow Routes schema used as GeoEvent Definitions. This is to ensure NULL values are not being written to fields when a value for that field is not sent to the Snow Routes Output.
1. Navigate to the Site tab > GeoEvent Definitions in GeoEvent Manager
2. Click on Import
3. Browse to the Snow Routes feature service, specify id and the Unique Identifier Field, and click Import:

4. Edit the Snow Routes GeoEvent Definition so only fields plowstatus, id, enterdate, and exitdate remain:

5. Make a copy of the Snow Routes GeoEvent Definition:

6. Name the GeoEvent Definition Snow Routes Enter and leave only the id and enterdate fields:

7. Make another copy of the Snow Routes GeoEvent Definition. Name the GeoEvent Definition Snow Routes Exit. Leave only the plowstatus, id, and exitdate fields:

8. Make another copy of the Snow Routes GeoEvent Definition. Name the GeoEvent Definition Snow Routes Not Plowed. Leave only the plowstatus and id fields:

Record when the Snow Plow Vehicle Enters a Street
The Snow Routes feature service contains a field enterdate. GeoEvent will be used to update this field with the datetime when the vehicle enters the street. This field will be used later in a calculation to determine how long the snow plow vehicle was plowing a street
1. In GeoEvent Manager, create a new GeoEvent Service called Snow Plows – Enter Street
2. Add the Snow Plows AVL tcp-text-in input
3. Ideally, the AVL feed will contain a metric whether the snow plow is up or down. A filter will be added to only continue processing the event when the snow plow is ‘Down’. Add a Filter to the GeoEvent Service with the following condition and connect to the Input:

4. Add the GeoTagger Processor with the below parameters and connect to the Filter:
Name | Enters GeoTagger |
Geofences | snowroutes/.* |
Spatial Operator | Enter Any |
Geometry Field | GEOMETRY |
Target Field | New Field |
GeoTag Field Name | Enter_GeoTags |
GeoTag Format | Delimited Value |
New GeoEvent Definition Name | Snow Routes Enters GeoTagger |
Include Geofence Category | No |

5. The new GeoEvent Definition specified in the GeoTagger will not be created until it receives an event. To do this, add the Snow Routes Output to the service, but do not connect it to any inputs/processor.
6. Publish the GeoEvent Service and send an event using the GeoEvent Simulator. The count should increase by 1 for the GeoEvent Service. At this point the GeoEvent Definition should be created.
- We want the event to continue only when it enters a geofence, so we’ll add a Filter to filter the data when the Enter_GeoTags field is NOT NULL. Connect this filter to the GeoTagger Processor.

7. Add a Field Mapper Processor with Snow Routes Enters GeoTagger as the Source and Snow Routes Enter as the Target. Map the Enter_GeoTags to id, and $RECEIVED_TIME to enterdate. This will update the Snow Routes feature service with a datetime when a snow plow vehicle enters a road:

8. Connect the Field Mapper to the Filter, and then to the Snow Routes Output:

Update a Street When It Has Been Plowed
1. Make a copy of the Snow Plows – Enter Street GeoEvent Service
2. Name the new GeoEvent Service Snow Plows – Plowed
3. Delete the Field Mapper Processor
4. Edit the GeoTagger Processor and change the following:
Name | Exits GeoTagger |
Spatial Operator | Exit Any |
GeoTag Field Name | Exit_GeoTags |
New GeoEvent Definition Name | Snow Routes Exit GeoTagger |

5. Publish the GeoEvent Service and send an event with the GeoEvent Simulator to create the new GeoEvent Definition:

6. Edit the Filter and change the field to Exit_GeoTags:

7. To eliminate some margin of error, we will be calculating the total time a vehicle has spent within a street with the snow plow down. There may be times when a vehicle is simply making a U-turn, for example, to come back the other direction to begin plowing the other side of the road. In doing so, they have briefly entered/exited another road segment, but these roads should not be updated as Plowed:

Also, the buffered street segments will have overlap at the intersections. Again, these streets should not be updated as Plowed when the vehicle crosses an intersection:

First, we will add a Field Splitter processor. This processor can be downloaded from here. The Field Splitter Processor splits the comma separated value of a string field into separated GeoEvents, thus allowing downstream processing of each value. If a vehicle position is recorded on an area where there is overlapping snow routes, the Exit_GeoTags may include two values if the vehicle is exiting two segments:

These values will be split so each event can be processed. After installing the Field Splitter processor add this to the GeoEvent Service with the following parameters, and connect it to the Filter previously created:
Name | Split GeoTags Field |
Field to Split | Exit_GeoTags |
Field Splitter | , |

Next, we can calculate the total time the vehicle has spent on a road segment using the enterdate and exitdate values. If the total time is less than a particular time (i.e. 5 minutes), this would indicate the vehicle did not fully plow the street and it should not be updated. We need to add the enterdate field to the event. To do this, add the Field Enricher (Feature Service) Processor with the following parameters and connect to the Filter:
Name | Field Enricher |
Service | Snow Routes |
Layer | Snow Routes |
Feature Layer Join Field | id |
Target Fields | New Fields |
Enrichment Fields | enterdate |
New GeoEvent Definition Name | Snow Routes Field Enricher |
GeoEvent Join Field | Exit_GeoTags |

8. Add the Field Calculator Processor with the following parameters, connect to the Field Enricher, and then Publish the GeoEvent Service:
Name | Calculate Total Time |
Expression | currentTime() - toDate(enterdate) |
Target Field | New Field |
New Field Name | total_time |
New Field Type | Long |
New GeoEvent Definition Name | Snow Route Total Plow Time |


9. In the GeoEvent Simulator, click Go to Start

10. Uncheck Continuous Loop and then click Play. Let all the events process so the new GeoEvent Definitions will be created
11. The Snow Route should only be updated as Plowed if the snow plow vehicle has spent more than X minutes on the road segment. Add a Filter Processor to only continue processing the event if the total_time is greater than X minutes. The time will be entered in milliseconds, so 5 minutes would equal 300000. In this example, we’ll be sending the events quickly using the GeoEvent Simulator, so we will specify a very small value of 30 seconds:

12. Add a Field Mapper Processor:
Source GeoEvent Definition | Snow Route Total Plow Time |
Target GeoEvent Definition | Snow Routes Exit |
Note: Starting at GeoEvent 10.9.1 you can enter Field Calculations in the Field Mapper. Below we’re calculating ‘Plowed’ for the plowstatus field.

13. The GeoEvent Service should appear as below:

Configure the Web Map
These steps will show how to configure a web map so you can see the results.
1. Open a new map (Classic or New). Note: The new map viewer at 10.9.1 does not contain the arrow symbology referenced in step 3
2. Add the SnowPlowLocations and Snow Routes feature services to the web map
3. Change the symbology to an arrow symbology and choose to rotate the symbols using the heading field:

4. Delete the Snow Plow Vehicle point if it exists
5. Set the Refresh Interval to 0.1 for both layers
6. Set the GeoEvent Simulator to the beginning, increase the Events Per to 10000 ms, and uncheck Continuous Loop
7. Click Play and view the web map. As the vehicle exits streets, you will see the road change to green indicating it has been plowed. It will only show a street as plowed if it exits the street and it had a duration greater than 30 seconds spent on the street.


Update a Street to Not Plowed
During a severe snow storm that lasts several hours, it may be necessary to mark a street as Not Plowed after a period of time (i.e. 3 hours). GeoEvent can be used to calculate the snow route’s status to Not Plowed.
1. Create a Poll and ArcGIS Server for Features Input
2. Specify the Snow Routes feature service and create a new GeoEvent Definition called Snow Routes FS. For the Refresh Interval, specify a value of your choice (i.e. 5 minutes), click Save and start the input.

3. Create a new GeoEvent Service called Snow Plows – Not Plowed
4. Add the Snow Plow Routes Input
5. Add a Field Calculator to convert the last_edited_date field to a field of type Long, and connect this to the input:
Name | Convert Date |
Expression | toDate(last_edited_date) |
Target Field | New Field |
New Field Name | last_edited_date_LONG |
New Field Type | Long |
New GeoEvent Definition Name | Snow Routes last_edited_date Conversion |

6. Add another Field Calculator to calculate the time to check whether the street’s status should be reset to Not Plowed. In the below example, 3 hours (10800000 milliseconds) are being subtracted from the current datetime. The logic here is if this date is greater than the last_edited_date, the status will be updated to Not Plowed.
Name | Calc Reset Date |
Expression | currentTime() – 10800000 |
Target Field | New Field |
New Field Name | reset_date |
New Field Type | Long |
New GeoEvent Definition Name | Snow Routes Reset Date |

7. Add the Snow Routes Output but do not connect this to any processor. Publish the GeoEvent Service and stop/start the Snow Routes Input so events are received, and the new GeoEvent Definitions are created:

8. Add a Filter to check if the reset_date is greater than the last_edited_date_LONG field:

9. Add a Field Mapper to update the plowstatus field to Not Plowed:
Source GeoEvent Definition | Snow Routes Reset Date |
Target GeoEvent Definition | Snow Routes Not Plowed |

10. The GeoEvent Service should appear as below. Any street that has not been plowed in the past 3 hours will be updated to Not Plowed.
