You can create powerful Map Search Arounds for the Map by writing Map Search Around functions. This allows you to write TypeScript functions that are given the selected objects and traverse the Ontology to bring back all the objects that are relevant or useful for the specific analysis being undertaken.
Map Search Around functions return a data structure that can include:
objectRids
: Objects, which will be added to the map.edges
: Edges, which include a source object, a target object, and optionally intermediary objects. The source and target objects will be added to the map with an arc drawn between them, and the intermediary objects will be listed when the arc is selected.measures
: Time Series Measures, which will be added to the Series Panel.Map Search Around functions are developed in a TypeScript functions repository. For more information, see the Functions documentation.
A Map Search Around function must declare a return type of Promise<IMapSearchAroundResults>
. The Map application will discover Search Around functions using the name and structure of their return type, so the return type must be declared exactly as follows:
Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
export interface IMapSearchAroundResults { objectRids?: string[]; edges?: IMapSearchAroundEdge[]; measures?: IMapSearchAroundMeasure[]; } export interface IMapSearchAroundEdge { sourceObjectRid: string; targetObjectRid: string; intermediaryObjectRids?: string[]; } export interface IMapSearchAroundMeasure { objectRids: string[]; measureId: string; }
Map Search Around functions must include one (and only one) object parameter, which can be one of the following:
Copied!1
public exampleSearchAround(object: ExampleObjectType) { ...
Copied!1
public exampleSearchAround(objects: ExampleObjectType[]) { ...
Copied!1
public exampleSearchAround(objectSet: ObjectSet<ExampleObjectType>) { ...
Map Search Around functions can optionally include any number of additional parameters of these scalar types: string
, boolean
, Integer
, Long
, Float
, Double
, LocalDate
, or Timestamp
(see Scalar types for more details). When a user executes a Search Around function with additional parameters, the user will be prompted to enter values for the parameters. For example:
Copied!1
public exampleSearchAround(objectSet: ObjectSet<ExampleObjectType>, stringParameter: string, timestampParameter: Timestamp) { ...
allAsync()
and getAsync()
instead of all()
and get()
when loading objects, and use as few await
statements as possible.This example code contains three Search Around functions, based on the Foundry Reference Project
sample data:
airportsRelatedObjects
: Returns various objects related to a set of airports. Could be used in a map template for airport analysis.nearbyAirports
: Performs a geospatial search to find other airports within a given distance. The function takes an optional distance parameter, allowing the user to provide a distance when executing the function.routesBetweenAirports
: Given a set of airports, returns all routes just between those airports.Copied!1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
import { Distance, Function, Integer, Filters } from "@foundry/functions-api"; import { ObjectSet, Objects, ExampleDataAirport } from "@foundry/ontology-api"; export interface IMapSearchAroundResults { objectRids?: string[]; edges?: IMapSearchAroundEdge[]; measures?: IMapSearchAroundMeasure[]; } export interface IMapSearchAroundEdge { sourceObjectRid: string; targetObjectRid: string; intermediaryObjectRids?: string[]; } export interface IMapSearchAroundMeasure { objectRids: string[]; measureId: string; } export class MapSearchAroundFunctions { /** * Return relevant objects for airports: runways, routes */ @Function() public async airportsRelatedObjects(airportSet: ObjectSet<ExampleDataAirport>): Promise<IMapSearchAroundResults> { const relatedObjects = (await Promise.all([ airportSet.searchAroundExampleDataRunway().allAsync(), airportSet.searchAroundRoutes().allAsync(), ])).flat(); const objectRids = relatedObjects.map(o => o.rid!); return { objectRids, }; } /** * Return all airports within the specific number of kilometres of the selected airport (defaulting to 50) */ @Function() public async nearbyAirports(airport: ExampleDataAirport, distanceKm?: Integer): Promise<IMapSearchAroundResults> { const point = airport.airportLocation; const distance = Distance.ofKilometers(distanceKm ?? 50); if (point === undefined) { return {}; } const nearbyAirports = await Objects.search() .exampleDataAirport() .filter(airportFilter => airportFilter.airportLocation.withinDistanceOf(point, distance)) .allAsync(); const objectRids = nearbyAirports.map(o => o.rid!); return { objectRids, }; } /** * Return only routes that depart from and arrive in the selected airports */ @Function() public async routesBetweenAirports(airportSet: ObjectSet<ExampleDataAirport>): Promise<IMapSearchAroundResults> { const airports = await airportSet.allAsync(); const airportCodes = airports.map(airport => airport.airport); const airportsByCodes = new Map(Array.from(airports, a => [a.airport, a])); const routes = await Objects.search() .exampleDataRoute() .filter(route => Filters.and( route.origin.exactMatch(...airportCodes), route.dest.exactMatch(...airportCodes), )) .allAsync(); const edges = routes.map(route => ({ sourceObjectRid: airportsByCodes.get(route.origin!)!.rid!, targetObjectRid: airportsByCodes.get(route.dest!)!.rid!, intermediaryObjectRids: [route.rid!], })); return { edges }; } }