The Map application supports Ontology objects with geospatial data attached.
Point geometries can be specified using the geohash
property type. The contents of a geohash
property should be a string of either:
[latitude],[longitude]
: For example, 57.64911,10.40744
. Coordinates must use the WGS 84 CRS (standard latitude and longitude).u4pruydqqvj
. Geohashes will be converted into points, using the bottom-left corner of the Geohash rectangle.Objects with geohash
properties are indexed for geospatial search.
A circle geometry can be specified on an object type by selecting a Radius property in the Geospatial section of the object type's Capabilities tab. The radius property can be any numeric property measured in meters.
The circle geometry is only rendered on the map, not indexed for searching. If you need objects to be geospatially searchable based on a circle geometry, you will need to approximate a circle using a polygon.
Polygon and line geometries can be specified using the geoshape
property type. The contents of a geoshape
property must be a GeoJSON Geometry string meeting the following requirements:
geoshape
property type; use the geohash
property type for Point geometries.This is an example of valid GeoJSON for a geoshape
property:
Copied!1
{ "type": "LineString", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ] }
Objects with geoshape
properties are indexed for geospatial search.
Objects can include string properties containing H3 cell IDs from the H3 geospatial indexing system ↗. These will render as relevant hexagons on the map.
To specify that a string property contains H3 cell IDs, select that property under H3 cell in the Geospatial section of the object type's Capabilities tab.
The H3 hexagon is only rendered on the Map, not indexed for searching. If you need objects to be geospatially searchable based on a H3 hexagon, you will need to convert the H3 cell IDs into GeoJSON Polygons and include them in a geoshape
property as described above.
An object can have georectified images attached, such as a satellite photo, aerial imagery, or a scan of a physical map. Two properties are required for the georectified image:
String
property containing the URL of the image to render. Supported image file extensions include .png
, .jpg
, .jpeg
, .gif
, .webp
, .bmp
, .ico
, and .svg
. The ID of the image URL property is used to configure the image bounds property.geoshape
property containing a GeoJSON Polygon of a quadrilateral representing the georectified bounds of the image. The polygon must specify its vertices in clockwise order, beginning with the bottom left corner.
geo
bounds.<image URL property ID>
where <image URL property ID>
is the ID of the image URL property.image_url
then the typeclass would be: Kind: geo
, Value: bounds.image_url
Objects with georectified images are indexed for geospatial search, as with all geoshape
properties.
Georeferenced raster imagery can also be displayed in tiles by uploading GeoTIFF imagery in a (.tiff
, .tif
) to a media set. From there, object types with a media reference property can be added to the map and only the visible portions of the imagery will be loaded as the user pans or zooms around the Map.
Objects can have numeric time series properties representing an object's latitude and longitude over time, allowing users to see the path the object traveled over time as well as its location at any point in time.
To configure the track for the object type, select the Track Latitude and Track Longitude properties in the Geospatial section of the object type's Capabilities tab. Both properties must be numeric time series properties representing the object's location over time. See Time series setup for more information.
Users can perform temporal and geotemporal analysis in the Map for geospatial objects with time series data and/or time series properties.
Events are Ontology objects that occur at a point or period of time. Object types can be configured as events by specifying Event start time and Event end time timestamp properties in the Event section of the object type's Capabilities tab.
If event objects are added to the Map, they can be configured to only display when current (that is, when the selected timestamp is within the event period).
If objects on the map have event objects linked to them, the event objects can be added to the Series panel for temporal analysis, and current event count indicators can be added to object labels. For example, a road
object could be represented as lines on the map, and a road
object may have linked traffic accident
events; a user could then use the indicators to see traffic event counts for each road at any point in time.
For this to be possible, the event object type must be configured with an Event intent indicating the severity of the event in the Event section of the object type's Capabilities tab.
Search Arounds are link-based searches that allow users to explore related objects.
A user can Search Around from any geospatial object to any geospatial objects it is linked to. See Create a link type for more information.
The Map application can run two-step Search Arounds, where a geospatial object is linked to another geospatial object via an intermediary object (which could be non-geospatial).
Factory
object and a Supplier
object might be related via a Supply Contract
object; when a Search Around is run, the Map will show an arc from factory to supplier, where the arc represents the supply contract.Customer
object might be linked to a Distribution Center
object via a Delivery
event - in this case, the delivery events will be shown as circles traveling along the arc. The position of the circle will be interpolated along the arc based on the event start and end time as well as the currently selected timestamp.There are two methods for configuring objects to be used for link merged Search Arounds:
To designate an intermediary object type to always link merge, turn on Link merge always in the Search Around section of the intermediary object type's Capabilities tab. This means that the object type itself will never appear in the Search Around list, but its transitive links will.
For example, if the intermediary object type is Delivery
, and the object types on either side are Distribution Center
and Customer
, then when a Distribution Center
is selected to Search Around on, Delivery
will not show up in the list, but Customer (via Delivery)
will. See below for an example:
To designate specific link traversals to be link merged, specify both the Incoming links to merge and Outgoing links to merge in the Search Around section of the intermediary object type's Capabilities tab.
For example, if you want to be able to perform a Search Around from a Supplier
object type to a Distribution Center
object type via a Delivery
object type, you would configure the Delivery
object type as the intermediary by selecting the Delivery <-> Supplier
link as Incoming links to merge and the Delivery <-> Distribution Center
link as Outgoing links to merge. Now, when a Supplier
is selected to Search Around on, Distribution Centers (via Delivery)
will appear as an option in the list.
If you want both link traversal directions to appear in the Search Around list (for example, for both Suppliers
to have Distribution Centers (via Delivery)
and also Distribution Centers
to have Suppliers (via Delivery)
), you will need to configure those links as both Incoming links to merge and Outgoing links to merge.
You can create powerful Search Arounds by writing Search Around functions. See Search Around functions for more details.
Functions can be used to create derived properties on objects. These can be displayed in the Selection panel and used to color objects on the map.
Any function that takes in an array of objects and returns a FunctionsMap
from object to a primitive can be used as a derived property. For example:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
import { Function, FunctionsMap, Double } from "@foundry/functions-api"; import { ExampleDataRoute } from "@foundry/ontology-api"; export class DerivedPropertyFunctions { @Function() public async flightCancellationPercentage(routes: ExampleDataRoute[]): Promise<FunctionsMap<ExampleDataRoute, Double>> { const routeMap = new FunctionsMap<ExampleDataRoute, Double>(); const allFlights = await Promise.all(routes.map(route => route.flights.allAsync())); for (let i = 0; i < routes.length; i++) { const route = routes[i]; const flights = allFlights[i]; const cancelledFlights = flights.filter(flight => flight.cancelled); const cancellationPercentage = (cancelledFlights.length / flights.length) * 100; routeMap.set(route, cancellationPercentage); } return routeMap; } }