Client-provided vector data
Vector data (geometry and attribute values) is typically retrieved from distant sources through HTTP requests, by fetching files such as MVT or GeoJSON. There are however two ways through which the client can directly provide data to Horizon: in-memory and client vector sources.
Using a custom asset URL
A third way is available, using a custom asset request. We will not go into details about how this works here, as it is just a way of serving files (such as MVT or GeoJSON) though the message queue instead of HTTP requests, and is orthogonal to vector data.
For example imagine using a tiled provider with an URL such as
client:my-vector-dataset/{z}/{x}/{y}, and using this information to serve or generate some GeoJSON data client-side.
In-memory vector source
Markers
Go to gallery demo
In-memory vector source layers, and the associated provider, offer a way to store persistent vector data inside the Horizon instance. Along with the definition of the layers, the client pushes the vector data, which can then be used by vector data layers.
The layer declares which attributes it has values for, which attributes constitute the feature ID, as well as data for any number of features. Each feature can have a geometry and values for every attribute of the layer. When a vector data layer wishes to pull data from an in-memory vector source layer, it has to use the same definition of a feature ID.
Whatever its bounding box and max zoom level are, a vector data layer can pull data from an in-memory vector source layer. If the vector data layer requests data at tile coordinates for which the in-memory vector source layer does not contain features, the vector data layer receives an empty tile.
Feature coordinates
Three types of geometries are available: points, polylines, and polygons. They all use the same API for setting their coordinates: the coords array. The client is expected to fill this array by chaining X, Y, and Z coordinates for each invididual vertex of the feature, and chaining the vertices themselves.
The coords array is filled like this:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | … |
|---|---|---|---|---|---|---|---|
| vertex 0, X | vertex 0, Y | vertex 0, Z | vertex 1, X | vertex 1, Y | vertex 1, Z | vertex 2, X | … |
If the last vertex does not have three coordinates, it is ignored.
Points
Point features only use the first vertex of the array. The following vertices, if they exist, are ignored.
Polylines
Polylines are generated by joining all the vertices in the order they are declared, if the linestring_sizes array is empty.
If the linestring_sizes array is not empty, then we are working with a multi-polyline: for each number in that array, a polyline of that size is generated using the next vertices from the coords array (starting from the first).
In this example, each vertex is labeled with its position in the coords array. The first polyline has two vertices, and the second has three. So in this case the linestring_sizes array must contain [2, 3].
If you need a polyline that makes a loop without having to declare the first and last points as equal, use a polygon instead.
Polygons
Polygons are more complex, as they can be multi-polygon, composed of an outer linestring, and a collection of smaller, inner linestrings that define holes in the outer one. Just like the other geometry types, they only use a single coords array, but it is complemented by the linestring_sizes array.
Each linestring is a polygon, defined by a list of vertices that form a closed loop. The last vertex is automatically joined to the first one. (So there is no need to repeat any vertex.)
The coords array must contain all the vertices for the outer polygon, in anticlockwise order, followed by the vertices for the first hole, in clockwise order, followed by the vertices for the second hode, also in clockwise order, and so on.
The linestring_sizes array indicates how many vertices comprises each linestring, in the same order as in the coords array.
In this example, each vertex is labeled with its position in the coords array. The outer linestring has four vertices, the first inner linestring has five, and the last one has three. So in this case the linestring_sizes array must contain [4, 5, 3].
Client vector data
Live data
Go to gallery demo
CSV data & histogram
Go to gallery demo
A VectorDataSource with a provider_type of CLIENT_VECTOR_DATA_PROVIDER enables Horizon to pull data from the client. When such a source is used, Horizon uses the message queue to signal that it needs data from the client, sending a VectorDataRequestMessage.
It is the client’s responsibility to listen for such messages, and respond to those requests with the necessary data using the ProvideVectorData method of ClientDataService.
Data can be requested either by tile coordinates or feature IDs: this is determined by the access field of ClientVectorDataProviderParams.
Responding to a vector data request
The contents of the request message determine the contents that should be included in the response.
The vector_data_layer_id and vector_data_source_index fields identify the vector data source responsible for initiating the request, as there can be multiple sources using a client provider.
The selection union determines the features that require data:
- With an
ACCESS_BY_TILE,tile_selectioncontains the coordinates of the tile for which feature data is required. Thefeaturesarray of the response must include one entry per feature geometry in the tile (IDs can be duplicated between multiple geometries).
Tile coordinates
Horizon uses the XYZ tiling scheme for vector tile coordinates. It is the same one that is used by multiple raster tile providers, such as OpenStreetMap.
- With an
ACCESS_BY_FEATURE_ID,feature_id_selectioncontains an array of feature IDs. Thefeaturesarray of the response must include one entry per feature ID. If the source is the primary source, or if it does not use feature IDs to join its results with the primary source, it is important that results be returned in the same order as the feature IDs in the request, including potential duplicates.
If the response has an incorrect number of features, an error is reported in the logs, and the data is not used. If the data is joined to another source, no feature IDs are used, and the order of the feature is incorrect, Horizon will have no way to tell, so the features will not get their intended data.
The response includes the request ticket for identification purposes, an array of ClientFeatures, and an attribution string. Each feature can include attribute values and/or geometry.
-
Each feature must contain as many attribute values as there are IDs in the request’s
attribute_idsfield. The values must be in the same order as the IDs, including potential duplicates. -
Geometry should be included if the request’s
expects_geometryfield istrue. If geometry is included when not requested, it is ignored.
Geometry format
The geometry has the same format as the one used for in-memory vector sources, which is described above. However, the coordinates of the geometry must be in the Web Mercator (EPSG:3857) projection.
If the client is unable to fulfill the request, it can signal this by setting the error field to true. If any data is included in the same message, the data is ignored.
The response must be sent using the ProvideVectorData method of the ClientDataService, including the request’s ticket in the message to allow Horizon to identify to which request belongs this reponse.