OSCP Spatial Service Discovery
Baseline implementation of the OSCP Spatial Service Discovery APIs. These APIs allow an OSCP client to discover nearby spatial service providers (ex. GeoPose provider, spatial content provider, reality modeling provider). Spatial service records are synchronized in real-time across multiple top-level (ex. country) providers in a peer-to-peer manner through the kappa-osm database for decentralized OpenStreetMap. Discovery is managed via hyperswarm.
The P2P stack is based on components from the Hypercore protocol. kappa-osm builds on kappa-core, which combines multiple append-only logs, hypercores, via multifeed, and adds materialized views. Spatial queries rely on a Bkd tree materialized view, unordered-materialized-bkd.
Authentication/authorization is based on JSON Web Tokens (JWTs) via the OpenID Connect standard. A sample integration with Auth0 is provided.
Tested on Node 14.6.1
git clone https://github.com/OpenArCloud/oscp-spatial-service-discovery
cd oscp-spatial-service-discovery
npm install
Create .env file with required params ex.
KAPPA_CORE_DIR="data"
SWARM_TOPIC_PREFIX="oscpdev_ssd"
AUTH0_ISSUER=https://ssd-oscp.us.auth0.com/
AUTH0_AUDIENCE=https://ssd.oscp.clouspose.io
COUNTRIES="IT,FI,US"
PORT=3000
Start the Spatial Service Discovery service (development)
npm run dev
Start the Spatial Service Discovery service (production)
npm start
http://localhost:3000/swagger/
The query API expects a client to provide a hexagonal coverage area by using an H3 index ex. precision level 8. This avoids exposing the client's specific location. The service then performs a wider scale query at a configurable radius (default: 5km) to the p2p OpenStreetMap backend and returns any coverage polygons that intersect with the client provided H3 hexagon.
Current version: 1.0
The API version can be specified by the HTTP Accept header using a vendor-specific media type as per RFC4288:
application/vnd.oscp+json; version=1.0;
Base version of a Spatial Service Record (expected to evolve):
export interface Property {
type: string;
value: string;
}
export interface Service {
id: string; //provider supplied reference ID
type: string; //type of spatial services provider ex. geopose, spatial-content
title: string;
description?: string;
url: URL;
properties?: Property[]; //loosely specified service properties
}
export interface Ssr {
id: string; //platform generated SSR ID
type: string; //record type, "ssr" is currently the only valid type
services: Service[];
geometry: turf.Polygon; //GeoJSON polygon
altitude?: number;
provider: string; //spatial services provider, populated by platform based on auth
timestamp: number; //platform generated timestamp
active?: boolean; //state of SSR
}
Documents (OSM elements, observations, etc) have a common format within kappa-osm:
{
id: String,
type: String,
lat: String,
lon: String,
tags: Object,
changeset: String,
links: Array<String>,
version: String,
deviceId: String
}
GeoJSON polygons are mapped to OSM closed ways which reference an ordered set of OSM nodes. In addition, the GeoJSON polygons are stored as tags within the OSM ways to avoid the need to iterate through all nodes on reads. An OSM bounding box query returns a way if at least one of the corresponding nodes are covered.
To configure Auth0 as a reference auth service please see Auth0 for SSD.