Groovy Week 2020: Sorting complex objects for Transport Networks
In our fifth and final installment of the 2020 Groovy Week, we will address a type of dataset that is often complex and has specific issues that need to be solved - a transport network, for which we want to create topologically correct link sequences. Like in the previous Groovy Week posts, note that this article assumes you have working knowledge of hale studio and know the terminology.
Friday's Script: Sorting complex objects for Transport Network Link Sequences (Thorsten)
Most of the time, the order in which properties are written to a feature doesn't really matter. However, in some cases the correct order is very important, e.g. for link sequence features that are common in INSPIRE transport Network data sets.
In this post, we will thus examine how we can use sorting in a Groovy Script to ensure that we get the correct order of references to a set of RoadLink
features. In this data set, there was no single simple property that could be used to determine the correct sequence, but rather a combination of sequence and linear referencing properties that would need to be used.
The context in which this script is used is in a Groovy Script (greedy) property-level function, with a Merge type-level function. The Merge function acts like a Group By
in SQL - it creates groups of features based on shared properties. In this data set, we merge on the ROUTE_ID
property, a foreign key that indicates to which RoadLinkSequence
a RoadLink
should belong. In such a Merge case, each source property may be available many times. A greedy Groovy function will take all these instances of source properties and provide them as a list to the script. You will notice, that when accessing the source feature's properties, we are using only lists.
To perform the actual sorting, the script builds a sortable composite key as a single string, and inserts these keys into a TreeMap
. A TreeMap
is sorted according to the natural ordering of its keys, so when using simple strings, we do not need to come up with our own sorting or comparator approach.
Building a working composite key was the main challenge here - we kept getting key collisions for various reasons, but in the end, the approach below produced the correct order and was free of any collisions.
Towards the end of the script, the keys and RoadLink
IDs are stored in the sortedEdgeIDMap
, over whose sorted value set we then iterate to emit the target DirectedLink
properties in the correct order.
You can download the script snippet and import them in hale studio as a Groovy snippet by going to File -> Import -> Groovy Snippet. Please note that some scripts use protected functions, so you might need to Lift Groovy Restrictions to execute the script. Make sure you replace the placeholder attribute names with your own attribute names.
Happy transforming!