GEOINT App: Using web maps as the spatial ground truth.
Typically, a geospatial analyst starts visualizing operational data having location information on a map. A basemap defines the geographic context and allows us thematic layering of our data. We try to gain new knowledge based on the spatial distribution of the data. A geospatial analyst almost always doesn’t have the time and skills to create high-quality basemaps from raw geographic features. Our task is to analyze the space and time-related information. This is our core competence that we should rely on.
The easiest way to access ready to go basemaps is to use cloud-based map services. As an experienced user of the ArcGIS ecosystem, you appreciate the wealth of information that are available through ArcGIS Online. Quality assured web maps, apps and data can be easily found and used via the Living Atlas of the World. As many other cloud-based resources a web map can be accessed by using an unique url.
For our proof of concept we will use a web map, which contains open data from the Armed Conflict Location & Event Data Project (ACLED). This project collects publicly available political violence and protest events and offers a dataset designed for disaggregated conflict analysis and crisis mapping. The web map can be accessed by using this item.
The Web Map Use Case
Loading a web map can sometimes take a while and should therefore be carried out in the background. ArcGIS Runtime supports the so-called loadable design pattern. Accessing web maps and operational data structured in layers requires the resources to initialize their state asynchronously. The loadable design pattern reflects the behavior that online resources use to load data asynchronously. The pattern also provides a retry mechanism if previous attempts to load have failed so we can properly handle and resolve situations such as network outtakes. Online resources process simultaneous and repeated requests for loading accordingly and also allow a request to be canceled so that we can stop the loading of a resource.
The ACLED events are represented as two feature layers of this web map. Both feature layers represent the events as data records, so called features. One contains the events of the last 14 days and the other all historical events. The events are visualized by a specific unique value and a simple renderer. An event feature has a unique primary key and a point geometry. All features of a feature layer always have the same geometry type and the same spatial reference. This restriction not only has advantages in terms of rendering performance, but also in evaluating the features. It also allows to spatially relate the features to one another in a simple manner.
When querying the features you have to make sure that the corresponding layer is fully loaded first. You get access to the attributes and geometries of every feature. A query can not only filter the resulting feature set, but also define which attributes and whether or not the geometries should be returned.
After investigating a bunch of ACLED items from the Living atlas we took a closer look at one of the items the “Bureau of Conflict and Stabilization Operations” (CSO) published in 2019. The web map was last updated on December 4th in 2019 and can be easily accessed using this item.
If we reuse the examples from Proof of concept — Ramp-up, we just have to replace the default map by using the item. We need to create a new portal item instance using the item’s url and passing this instance into the constructor of the map instance. Compile, run the sample map viewer and after the web map is loaded we should see a ACLED layer showing on top of a dark-gray basemap.
Each SDK uses the language specific best practices for getting the job done. In Java you create and register a listener using the map or layer instance. When developing with C# you do the same, the listener is just called an event handler and you can enjoy the async/await pattern. In Qt you are using the specific signals and define slots for handling the map and layer events.
We defined a simple use case for stressing the map viewer samples. When the map is fully loaded we just register a map view tap listener/handler/slot. By tapping the map view a query is scheduled against the feature layer representing the ACLED events. The returned result is analyzed by using the primary key and the returned geometry of each feature. The map sample viewer defines a generic Hastable/Dictionary/Hash managing all returned features using the ID as key and the feature itself as value. Whenever a new query result is obtained, the feature is only added when the ID is not already known and if the ID is known the geometries of both features are compared using the underlying Geometry Engine implementation of the C++ based runtime core. If the geometry had changed, the old feature is replaced by the new feature. The feature layer contains 13 684 features all having a valid and not empty geometry representation. When analyzing the point geometries by just using their raw coordinates we saw that 6301 unique locations were represented by those features. If we want to know the real spatial distribution of these ACLED events, we would create a spatial grid and classify locations being near to each other as a match.
Let us take a look at the following chart representing the overall memory consumption of all three sample map viewers during startup and on shutdown.
Summary
The Java sample viewer is consuming more memory after executing a bunch of queries and feels a bit laggy under heavy load caused by the queries running in the back when zooming and panning the map. Maybe the JNI interop is responsible for this behavior. The two sample viewers being implemented using .NET and Qt were having a smaller footprint, seem to render the map and query the features a bit faster than the Java implementation.
We were really surprised how easy it was to start developing with Qt. The entry hurdle was quite low and the cautious development of the use case with constant reflection on how the objects should be managed in memory, to the amazement of our team, was rather positive. As part of a technical discussion:
“When defining the map view as parent for the returned features, they won’t be deleted till the app is shutdown. That is a memory leak!
No, it’s not. We need to check any returned feature with the already known ones, so these must be held in memory, that is exactly what we want.”
In fact, these discussions are more important than whatever automatic garbage collection is offering. Because of the low entry hurdle and that mindset we decided to develop the GEOINT App with Qt.
References: