A primary focus of my day job is managing utility datasets for a small municipality. I am currently in the process of taking a simple database of lines and points and turning it into a true utility network. One of the benefits of having this new seamless database is to perform network traces. This is possible using a variety of desktop and server tools including geometric networks in ArcGIS Desktop, the ArcGIS Utility Network Management extension for ArcGIS Server/Enterprise, pgRouting, and via various QGIS plugins. However, the utility field crews and managers only have access to our web maps, so I wondered if I could program a Mapbox GL JS plugin to do some simple network tracing directly in the browser. Fortunately in my case the entire database is less than 3MB, so all the data can be loaded into the browser via GeoJSON. This data can then be visualized and analyzed using client-side libraries, in this instance Mapbox GL and Turf JS.
My first attempt at network tracing involved looping through all the linear features and checking for equal upstream and downstream asset IDs assigned to each feature. This seemed like a common sense approach, but it would mean these IDs would need to be calculated for each feature beforehand. This did work, but I wanted to find a way to eliminate the need to calculate these IDs and focus solely on the geometry. I found the answer in the Turf JS API.
The basic idea became quit simple: find all the connected lines to an origin point using
turf.booleanPointOnLine() and then use these resulting lines to seed the network trace. By iterating over this method the tool could return the entire network.
In the first iteration I focused solely on identifying all the intersecting lines of the origin point to test the
turf.booleanPointOnLine() method. I ran into some issues with the points and lines not being coincident, possibly due to rounding of extremely long decimal places. I decided to borrow the method used by the geojson-equality package and limit the coordinate check to six decimals using
.toFixed(6). The coordinates could also be trimmed before adding them to the browser using QGIS, in NodeJS using geojson-precision, or with the command-line mapshaper tool.
To trace the upstream network simply click on a point.