Quick Start

2025-02-13
No Rating

This document uses the workflow of a reconstruction algorithm task as an example. You can refer to the API documentation for relevant interface calls.

Get AK/SK

After logging into the Developer Websiteopen in new window, navigate to the DJI TerraAPI Consoleopen in new window. Submit an application and wait for the backend review. Once approved, the DJI TerraAPI Console will display your AK/SK(App Key, Secret Key) information. The following image is an example of how AK/SK information is displayed.

Figure. DJI TerraAPI AK/SK Information

Get Token

When developers send requests from local devices to the server, they need to authenticate using AK/SK of the DJI TerraAPI. During this process, developers should use the HMAC Signature Algorithmopen in new window to add a signature to their request messages.

Below is an example of obtaining a token. Please replace with your own AK/SK as required.

#!/bin/bash

DJI_APP_KEY="{your AK}"
DJI_SECRET_KEY="{your SK}"
URI=/terra-rescon-be/v2/store/obtain_token
HTTP_METHOD=POST
payload=$(
	cat <<EOF
EOF
)


function calculate_signature() {
	content="$1"
	signature=$(echo -n -e "${content}" | openssl dgst -sha256 -hmac "${DJI_SECRET_KEY}" -binary | openssl enc -base64 -A)
	echo ${signature}
}

HOST=https://openapi-us.dji.com

url=${HOST}${URI}
x_date=$(date -u +"%a, %d %b %Y %H:%M:%S GMT")
lower_method=$(echo "${HTTP_METHOD}" | tr '[:upper:]' '[:lower:]')
digest=$(echo -n "${payload}" | openssl dgst -sha256 -binary | base64)
request_signature=$(calculate_signature "date: ${x_date}\n@request-target: ${lower_method} ${URI}\ndigest: SHA-256=${digest}")
curl -X ${HTTP_METHOD} ${url} \
	-H "Date: ${x_date}" \
	-H "Digest: SHA-256=${digest}" \
	-H "Authorization: hmac username=\"${DJI_APP_KEY}\", algorithm=\"hmac-sha256\", headers=\"date @request-target digest\", signature=\"${request_signature}\"" \
	-H 'Content-Type: application/json;charset=UTF-8' \
	-d "$payload" -v

Explanation of Return Results:

  • accessKeyIDsecretAccessKeysessionTokenregioncloudBucketNamestorePathcallbackParam will be used in the SDK examples.
  • If the token expires, please obtain a new token and restart the upload and task.

Preparing Resources

For 2D, 3D, and LiDAR reconstruction tasks, developers can prepare resources as one of the follows:

  1. Use your own resources and store them locally.
  2. Download and unzip the sample resources provided on the official website. Example path structures are D:\data\Two-Dimension-2D and D:\data\Three-Dimension-3D. These two compressed files contain not only the original resources but also the reconstruction result files. In this process, you only need to upload the original resources. That is, in the material upload code example, set the local_folder variable to D:\data\Two-Dimension-2D\5cm-2D-orthomosaic-53pic or D:\data\Three-Dimension-3D\3cm-3D-orthomosaic-70pic.

Installing the Storage Service AWS SDK boto3 Library

Please install the AWS SDK boto3 library first, for uploading materials to the DJI Terra bucket on AWS S3. For detailed instructions, refer to the official documentationopen in new window.

Python SDK installation command: pip install boto3

Upload Resources with AWS Boto3 SDK

Configure the token, store path, and local_folder. The token and store path refer to the information in the "Get Token" step. "Local Folder Path" is the location where the resources you wish to upload are stored. When the script is executed and "uploaded" appears in the printout, it indicates that the upload is successful.

Note: The uploaded_files.json file will be used in the interface associated with binding files.

Example of uploading resources:

# -*- coding: utf-8 -*-
import os

import boto3

# Configure AWS visit information
access_key_id = '{your access id}'
secret_access_key = '{your access key}'
token = '{your token}'
bucket_name = 'vg-terra-be-dev'
region_name = 'us-east-1'
store_path = '{store path}/{fileName}'

store_root_path = store_path[:store_path.rfind('/{fileName}')]

# Create S3 client server
s3_client = boto3.client('s3', aws_access_key_id=access_key_id,
                         aws_secret_access_key=secret_access_key,
                         aws_session_token=token,
                         region_name=region_name)

# Local folder path
local_folder = r"./Three-Dimension-3D\3cm-3D-orthomosaic-70pic"

# Iterate through local folder
uploaded_files = []
for root, dirs, files in os.walk(local_folder):
    for file_name in files:
        # Create local file path
        local_file_path = os.path.join(root, file_name)

        relative_path = os.path.relpath(os.path.join(root, file_name), local_folder)
        oss_file_path = os.path.join(store_root_path, relative_path).replace("\\", "/")

        # Upload files
        with open(local_file_path, "rb") as data:
            print(f"Uploadedxx: {local_file_path} -> s3://{bucket_name}/{oss_file_path}")
            put_result = s3_client.put_object(Bucket=bucket_name, Key=oss_file_path, Body=data)
            etag = put_result['ETag'].strip('"')
            print(f"Uploaded: {local_file_path} -> s3://{bucket_name}/{oss_file_path}, etag:{etag}")
			container_file_path = relative_path.replace("\\", "/")
            uploaded_files.append({"name": container_file_path, "etag": etag, "checksum": etag})

if uploaded_files:
    import json
    with open("./uploaded_files.json", "w") as f:
        json.dump(uploaded_files, f)

Create Resource

Please replace DJI_APP_KEY and DJI_SECRET_KEY with your own AK/SK. The resource uuid in the return value will be used in the subsequent steps.

#!/bin/bash

DJI_APP_KEY="{your AK}"
DJI_SECRET_KEY="{your SK}"
URI=/terra-rescon-be/v2/resources
HTTP_METHOD=POST

payload=$(
	cat <<EOF
{"name": "test_resource", "type": "map"}
EOF
)

function calculate_signature() {
	content="$1"
	signature=$(echo -n -e "${content}" | openssl dgst -sha256 -hmac "${DJI_SECRET_KEY}" -binary | openssl enc -base64 -A)
	echo ${signature}
}

HOST=https://openapi-us.dji.com

url=${HOST}${URI}
x_date=$(date -u +"%a, %d %b %Y %H:%M:%S GMT")
lower_method=$(echo "${HTTP_METHOD}" | tr '[:upper:]' '[:lower:]')
digest=$(echo -n "${payload}" | openssl dgst -sha256 -binary | base64)
request_signature=$(calculate_signature "date: ${x_date}\n@request-target: ${lower_method} ${URI}\ndigest: SHA-256=${digest}")

curl -X ${HTTP_METHOD} ${url} \
	-H "Date: ${x_date}" \
	-H "Digest: SHA-256=${digest}" \
	-H "Authorization: hmac username=\"${DJI_APP_KEY}\", algorithm=\"hmac-sha256\", headers=\"date @request-target digest\", signature=\"${request_signature}\"" \
	-H 'Content-Type: application/json;charset=UTF-8' \
	-d "$payload" -v

Bind Batch Files

Please replace dji_app_key and dji_secret_key with your own AK/SK. Replace resource_uuid with the return value from the resources creation step. Replace callbackParam with the return value from the Token acquisition step.

Python example for binding files:

import base64
import hashlib
import hmac
import json
import time

import requests

dji_app_key = "{your app key}"
dji_secret_key = b"{your secret key}"
uri = "/terra-rescon-be/v2/store/upload_callback"
resource_uuid = "{your created resource uuid}"
callback_param = "{callbackParam from token}"

host = "https://openapi-us.dji.com"
url = host + uri
method = "POST"


def bind_batch_files(files):
    payload = {
        "resourceUUID": resource_uuid,
        "callbackParam": callback_param,
        "files": files,
    }

    digest = (
        lambda x: base64.b64encode(hashlib.sha256(x.encode("utf-8")).digest()).decode(
            "utf-8"
        )
    )(json.dumps(payload))

    gmt_time = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(time.time()))
    signing_string = f"date: {gmt_time}\n@request-target: {method.lower()} {uri}\ndigest: SHA-256={digest}"
    signature = (
        lambda secret, x: base64.b64encode(
            hmac.new(secret, x.encode("utf-8"), hashlib.sha256).digest()
        ).decode("utf-8")
    )(dji_secret_key, signing_string)

    headers = {
        "Content-Type": "application/json",
        "Date": gmt_time,
        "Digest": f"SHA-256={digest}",
        "Authorization": f'hmac username="{dji_app_key}", algorithm="hmac-sha256", headers="date @request-target digest", signature="{signature}"',
    }

    r = requests.post(url, json=payload, headers=headers)
    print(r.request.headers)
    print(r.content)
    print(r.headers)


if __name__ == "__main__":
    with open("./uploaded_files.json", "r") as f:
        uploaded_files = json.load(f)

    mini_batch = []
    for item in uploaded_files:
        mini_batch.append(item)
        if len(mini_batch) >= 50:
            bind_batch_files(mini_batch)
            mini_batch = []

    if mini_batch:
        bind_batch_files(mini_batch)

Create a Job

Please replace with your own AK/SK. The job uuid in the return value will be used in the subsequent steps.

#!/bin/bash

DJI_APP_KEY="{your AK}"
DJI_SECRET_KEY="{your SK}"
URI=/terra-rescon-be/v2/jobs
HTTP_METHOD=POST

payload=$(
	cat <<EOF
{"name": "test_name"}
EOF
)


function calculate_signature() {
	content="$1"
	signature=$(echo -n -e "${content}" | openssl dgst -sha256 -hmac "${DJI_SECRET_KEY}" -binary | openssl enc -base64 -A)
	echo ${signature}
}

HOST=https://openapi-us.dji.com

url=${HOST}${URI}
x_date=$(date -u +"%a, %d %b %Y %H:%M:%S GMT")
lower_method=$(echo "${HTTP_METHOD}" | tr '[:upper:]' '[:lower:]')
digest=$(echo -n "${payload}" | openssl dgst -sha256 -binary | base64)
request_signature=$(calculate_signature "date: ${x_date}\n@request-target: ${lower_method} ${URI}\ndigest: SHA-256=${digest}")

curl -X ${HTTP_METHOD} ${url} \
	-H "Date: ${x_date}" \
	-H "Digest: SHA-256=${digest}" \
	-H "Authorization: hmac username=\"${DJI_APP_KEY}\", algorithm=\"hmac-sha256\", headers=\"date @request-target digest\", signature=\"${request_signature}\"" \
	-H 'Content-Type: application/json;charset=UTF-8' \
	-d "$payload" -v

Start Job

Start 2D job

Please fill in the AK/SK, job uuid, and resource uuid.

#!/bin/bash

DJI_APP_KEY="{your AK}"
DJI_SECRET_KEY="{your SK}"
URI=/terra-rescon-be/v2/jobs/{your uuid}/start
HTTP_METHOD=POST

payload=$(
	cat <<EOF
{"type": 14, "resourceUuid": "{uuid from create resource}", "parameters": "{\"parameter\":{\"map_mode\":1,\"quality_level\":1,\"output_geo_desc\":{\"cs_type\":\"GEO_CS\",\"geo_cs\":\"EPSG:32650\",\"geo_cs_wkt\":\"\",\"override_vertical_cs\":\"\"}}}"}
EOF
)

function calculate_signature() {
	content="$1"
	signature=$(echo -n -e "${content}" | openssl dgst -sha256 -hmac "${DJI_SECRET_KEY}" -binary | openssl enc -base64 -A)
	echo ${signature}
}

HOST=https://openapi-us.dji.com

url=${HOST}${URI}
x_date=$(date -u +"%a, %d %b %Y %H:%M:%S GMT")
lower_method=$(echo "${HTTP_METHOD}" | tr '[:upper:]' '[:lower:]')
digest=$(echo -n "${payload}" | openssl dgst -sha256 -binary | base64)
request_signature=$(calculate_signature "date: ${x_date}\n@request-target: ${lower_method} ${URI}\ndigest: SHA-256=${digest}")

curl -X ${HTTP_METHOD} ${url} \
	-H "Date: ${x_date}" \
	-H "Digest: SHA-256=${digest}" \
	-H "Authorization: hmac username=\"${DJI_APP_KEY}\", algorithm=\"hmac-sha256\", headers=\"date @request-target digest\", signature=\"${request_signature}\"" \
	-H 'Content-Type: application/json;charset=UTF-8' \
	-d "$payload" -v

Start 3D Job

Please fill in the AK/SK, job uuid, and resource uuid.

#!/bin/bash

DJI_APP_KEY="{your AK}"
DJI_SECRET_KEY="{your SK}"
URI=/terra-rescon-be/v2/jobs/{uuid from create job}/start
HTTP_METHOD=POST

payload=$(
    cat <<EOF
{"type": 15, "resourceUUID": "{uuid from create resource}", "parameters": "{\"parameter\":{\"output_mesh\":true,\"generate_obj\":true,\"generate_b3dm\":true,\"generate_osgb\":true}}"}
EOF
)

function calculate_signature() {
	content="$1"
	signature=$(echo -n -e "${content}" | openssl dgst -sha256 -hmac "${DJI_SECRET_KEY}" -binary | openssl enc -base64 -A)
	echo ${signature}
}

HOST=https://openapi-us.dji.com

url=${HOST}${URI}
x_date=$(date -u +"%a, %d %b %Y %H:%M:%S GMT")
lower_method=$(echo "${HTTP_METHOD}" | tr '[:upper:]' '[:lower:]')
digest=$(echo -n "${payload}" | openssl dgst -sha256 -binary | base64)
request_signature=$(calculate_signature "date: ${x_date}\n@request-target: ${lower_method} ${URI}\ndigest: SHA-256=${digest}")

curl -X ${HTTP_METHOD} ${url} \
	-H "Date: ${x_date}" \
	-H "Digest: SHA-256=${digest}" \
	-H "Authorization: hmac username=\"${DJI_APP_KEY}\", algorithm=\"hmac-sha256\", headers=\"date @request-target digest\", signature=\"${request_signature}\"" \
	-H 'Content-Type: application/json;charset=UTF-8' \
	-d "$payload" -v

Start LiDAR Job

Please fill in the AK/SK, job uuid, resource uuid, and path. For path, please refer to the parameter explanation for lidar_files in the algorithm parameter explanation.

#!/bin/bash

DJI_APP_KEY="{your AK}"
DJI_SECRET_KEY="{your SK}"
URI=/terra-rescon-be/v2/jobs/{uuid from create job}/start
HTTP_METHOD=POST

payload=$(
	cat <<EOF
	{"type": 13, "resourceUuid": "{uuid from create resource}",  "parameters": "{\"parameter\":{\"sample_distance\":0.2,\"output_pointcloud\":true,\"generate_pnts\":true,\"generate_las\":true,\"output_geo_desc\":{\"cs_type\":\"GEO_CS\",\"geo_cs\":\"EPSG:32649\",\"geo_cs_wkt\":\"\",\"override_vertical_cs\":\"\"}}}"}
EOF
)

function calculate_signature() {
	content="$1"
	signature=$(echo -n -e "${content}" | openssl dgst -sha256 -hmac "${DJI_SECRET_KEY}" -binary | openssl enc -base64 -A)
	echo ${signature}
}

HOST=https://openapi-us.dji.com

url=${HOST}${URI}
x_date=$(date -u +"%a, %d %b %Y %H:%M:%S GMT")
lower_method=$(echo "${HTTP_METHOD}" | tr '[:upper:]' '[:lower:]')
digest=$(echo -n "${payload}" | openssl dgst -sha256 -binary | base64)
request_signature=$(calculate_signature "date: ${x_date}\n@request-target: ${lower_method} ${URI}\ndigest: SHA-256=${digest}")

curl -X ${HTTP_METHOD} ${url} \
	-H "Date: ${x_date}" \
	-H "Digest: SHA-256=${digest}" \
	-H "Authorization: hmac username=\"${DJI_APP_KEY}\", algorithm=\"hmac-sha256\", headers=\"date @request-target digest\", signature=\"${request_signature}\"" \
	-H 'Content-Type: application/json;charset=UTF-8' \
	-d "$payload" -v

Check Job Status

After starting a task, you can inquire about the job status.

#!/bin/bash

DJI_APP_KEY="{your AK}"
DJI_SECRET_KEY="{your SK}"
URI=/terra-rescon-be/v2/jobs/{uuid from create job}
HTTP_METHOD=GET

function calculate_signature() {
	content="$1"
	signature=$(echo -n -e "${content}" | openssl dgst -sha256 -hmac "${DJI_SECRET_KEY}" -binary | openssl enc -base64 -A)
	echo ${signature}
}

HOST=https://openapi-us.dji.com

url=${HOST}${URI}
x_date=$(date -u +"%a, %d %b %Y %H:%M:%S GMT")
lower_method=$(echo "${HTTP_METHOD}" | tr '[:upper:]' '[:lower:]')
digest=$(echo -n "${payload}" | openssl dgst -sha256 -binary | base64)
request_signature=$(calculate_signature "date: ${x_date}\n@request-target: ${lower_method} ${URI}\ndigest: SHA-256=${digest}")

curl -X ${HTTP_METHOD} ${url} \
	-H "Date: ${x_date}" \
	-H "Digest: SHA-256=${digest}" \
	-H "Authorization: hmac username=\"${DJI_APP_KEY}\", algorithm=\"hmac-sha256\", headers=\"date @request-target digest\", signature=\"${request_signature}\"" \
	-H 'Content-Type: application/json;charset=UTF-8'

Download Computation Results

Once the job is completed, you can download the computation results.

  1. Obtain the outputResourceUuid returned by querying the job status.
  2. Get the file uuid by querying the resource (alternatively, you can obtain the file pagination information by querying the file interface and using the resource uuid as a condition).
  3. Download by using the uuid of the file.

Follow the steps below on how to download by querying the resource:

  1. Get the list of file uuids

Please replace with the outputResourceUuid from querying the job status.

#!/bin/bash

DJI_APP_KEY="{your AK}"
DJI_SECRET_KEY="{your SK}"
URI=/terra-rescon-be/v2/resources/{uuid form check job status}
HTTP_METHOD=GET

function calculate_signature() {
	content="$1"
	signature=$(echo -n -e "${content}" | openssl dgst -sha256 -hmac "${DJI_SECRET_KEY}" -binary | openssl enc -base64 -A)
	echo ${signature}
}

HOST=https://openapi-us.dji.com

url=${HOST}${URI}
x_date=$(date -u +"%a, %d %b %Y %H:%M:%S GMT")
lower_method=$(echo "${HTTP_METHOD}" | tr '[:upper:]' '[:lower:]')
digest=$(echo -n "${payload}" | openssl dgst -sha256 -binary | base64)
request_signature=$(calculate_signature "date: ${x_date}\n@request-target: ${lower_method} ${URI}\ndigest: SHA-256=${digest}")

curl -X ${HTTP_METHOD} ${url} \
	-H "Date: ${x_date}" \
	-H "Digest: SHA-256=${digest}" \
	-H "Authorization: hmac username=\"${DJI_APP_KEY}\", algorithm=\"hmac-sha256\", headers=\"date @request-target digest\", signature=\"${request_signature}\"" \
	-H 'Content-Type: application/json;charset=UTF-8'
  1. Get File Information

After completing the previous step, a list of file uuids will be returned.

#!/bin/bash

DJI_APP_KEY="{your AK}"
DJI_SECRET_KEY="{your SK}"
URI=/terra-rescon-be/v2/files/{file uuid}
HTTP_METHOD=GET

function calculate_signature() {
	content="$1"
	signature=$(echo -n -e "${content}" | openssl dgst -sha256 -hmac "${DJI_SECRET_KEY}" -binary | openssl enc -base64 -A)
	echo ${signature}
}

HOST=https://openapi-us.dji.com

url=${HOST}${URI}
x_date=$(date -u +"%a, %d %b %Y %H:%M:%S GMT")
lower_method=$(echo "${HTTP_METHOD}" | tr '[:upper:]' '[:lower:]')
digest=$(echo -n "${payload}" | openssl dgst -sha256 -binary | base64)
request_signature=$(calculate_signature "date: ${x_date}\n@request-target: ${lower_method} ${URI}\ndigest: SHA-256=${digest}")

curl -X ${HTTP_METHOD} ${url} \
	-H "Date: ${x_date}" \
	-H "Digest: SHA-256=${digest}" \
	-H "Authorization: hmac username=\"${DJI_APP_KEY}\", algorithm=\"hmac-sha256\", headers=\"date @request-target digest\", signature=\"${request_signature}\"" \
	-H 'Content-Type: application/json;charset=UTF-8'
  1. Download using the URL provided in the file information.

Import Output Files into DJI Terra

In the reconstruction parameter settings for output files, set the 'pc_dir_structure' parameter to True (See the Algorithm Parameter Introduction for details). The output directory for reconstruction files will be consistent with the DJI Terra reconstruction results output directory. The root directory structure for various types of tasks is as follows:

# Directory Structure of 2D Reconstruction Results
    Root Directory of Results/
    ├── AT
    ├── map
    ├── images
    ├── mission.json
# Directory Structure of 3D Reconstruction Results 
    Root Directory of Results/
    ├── AT
    ├── models
    ├── images
    ├── mission.json
# Directory Structure of LiDAR Reconstruction Results
    Root Directory of Results/
    ├── AT
    ├── lidars
    ├── mission.json

Compress the output files in the above directory structure into a ZIP file and then import the file into DJI Terra for viewing. If the directory structure of the downloaded files is inconsistent with the above, adjustments are required in order to import the files into DJI Terra for viewing.