Step-by-Step: Importing Files into LumiDB Using the API

Step-by-Step: Importing Files into LumiDB Using the API

This post shows you how to import reality capture files into a LumiDB table, by walking through our simple import API.

Published on


Do not index
Do not index
At LumiDB, we’re building a database for reality capture data that makes handling big point cloud datasets easy, accessible and fun. Request access to the alpha version to try it out!
A while ago, I wrote about LumiDB’s simple Runtime API. But it wouldn’t be much of a database unless you could put some data into it. This post shows you how to import a bunch of .laz files into a LumiDB table, by walking through our equally simple import API.
The import process involves the following steps:
  1. (Generate presigned URLs for input files)
  1. Create a manifest
  1. Call the import API
  1. Poll for import status
  1. Query imported data (optional)

Prerequisites

You’ll need:
  • An API key with import privileges.
  • Input files (e.g. .laz) either directly available via HTTP GET, or in S3 for generating pre-signed URLs

Step 1: Generate Presigned URLs

Each input file must be accessible to LumiDB via an HTTP(S) URL. If using AWS S3, we recommend you generate presigned URLs. For example, you can use the AWS CLI to do this:
aws s3 presign s3://your-bucket-name/path/to/file.laz --expires-in 3600

Step 2: Create a Manifest

The manifest is a JSON object describing the import. Here's an example:
{
  "table_name": "example_dataset",
  "table_proj": "EPSG:3879",
  "inputs": [
    {
      "src": "https://example.com/path/to/fileA.laz?AWSAccessKeyId=...",
      "date": "2021-02-03",
      "proj": "EPSG:3879",
      "license": "Example License"
    },
    {
      "src": "https://example.com/path/to/fileB.laz?AWSAccessKeyId=...",
      "date": "2021-06-22",
      "proj": "EPSG:3879",
      "license": "Example License"
    }
  ]
}
The table_proj field defines the coordinate reference system for the table. Each individual file also has a respective proj field defining the input projection of the file. Each file's data will be converted into the table's native projection. Both fields accept either an EPSG code or a PROJ string. This means that you can combine input files from different projections into the same table. It makes sense to choose the table’s native projection so that it matches the projection in which you typically want the queries to return the data, to avoid the conversion overhead during queries.
In a manifest, the table_name, table_proj and each input file's src and proj fields are mandatory. In addition, each input file can have arbitrary user-defined metadata properties, which will be available through the query API after import, and can be utilized by LumiDB's metadata queries. In the example above, we define date and license, but the user may as well define capture_weekday, producer or anything else.

Step 3: Launch the Import Process

The heavy lifting is done by the /api/tables/import HTTP endpoint. Send a POST request to the endpoint with the manifest:
curl -X POST https://lumidb.example.com/api/tables/import \
  -H "Authorization: apikey YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d @manifest.json
The response will contain a table_version ID which is then used to poll the import progress:
{
    "table_version": "123e4567-e89b-12d3-a456-426614174000"
}

Step 4: Poll for Import Status

To check the progress of the import, poll the /api/tables/import_status/{table_version} endpoint:
curl https://lumidb.example.com/api/tables/import_status/123e4567-e89b-12d3-a456-426614174000 \
  -H "Authorization: apikey YOUR_API_KEY"
The response will be one of the following:
{ "status": "queued" }
{ "status": "processing", "progress": 42.0 }
{ "status": "ready" }
{ "status": "failed", "error_msg": "..." }
Where progress is a percentage between 0 and 100. You can poll every few seconds until the status is either ready or failed.

Step 5: Query the Imported Data

Once the table is ready, you can proceed to query it, e.g. using the NPM library:
// Query points from a table
const response = await lumidb.query({
    tableName: tables[0].tableName,
    queryBoundary: {
        Polygon: [
            // polygon boundary
            [
                [
                    [2777342, 8438905],
                    [2777342, 8439315],
                    [2777573, 8439315],
                    [2777573, 8438905],
                    [2777342, 8438905],
                ],
            ],
            // optional z range
            [0, 100],
        ],
    },
    queryProj: "EPSG:3857",
    maxPoints: 5_000_000,
    maxDensity: 10.0,
    sourceFileFilter: null, // see below
    classFilter: null,
    outputType: "threejs", // or "laz" for exporting to other software
});
NOTE: If you re-imported a table, that is, launched the import using an existing table name, the previous version of the table will be available for queries until the new import process is ready, after which the table name pointer will be atomically changed to point to the newly imported version.

It’s that simple! If you’d like to get your hands on an API key and try it out for yourself, sign up for LumiDB Alpha! LumiDB is currently in alpha and available for early adopters!
 

Written by

Jasin Bushnaief
Jasin Bushnaief

CTO, Co-founder