#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
#*******************************************************************************
#
#  Copyright 2025 RIEGL Laser Measurement Systems
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.
#
#  SPDX-License-Identifier: Apache-2.0
#
#*******************************************************************************
#
"""
rdb-example-01-create-database.py

This example shows how to create a new RDB point cloud database and define
some point attributes.
"""

import riegl.rdb


def example_define_point_attributes(pointcloud):
    """
    This function shows how to define and add new point attributes
    and is used by the example functions below. Please note that there
    is also a shortcut for built-in RIEGL default point attributes
    which we use to define the "riegl.class" attribute at the end of
    this function.
    """

    # Target surface reflectance
    reflectance = riegl.rdb.PointAttribute(pointcloud)
    reflectance.name = "riegl.reflectance"
    reflectance.title = "Reflectance"
    reflectance.description = "Target surface reflectance"
    reflectance.unit_symbol = "dB"
    reflectance.length = 1
    reflectance.resolution = 0.010
    reflectance.minimum_value = -100.000  # minimum,
    reflectance.maximum_value = +100.000  # maximum and
    reflectance.default_value = 0.000  # default in dB
    reflectance.storage_class = riegl.rdb.PointAttribute.StorageClass.CONSTANT
    pointcloud.point_attributes.add(reflectance)

    # Point color
    point_color = riegl.rdb.PointAttribute(pointcloud)
    point_color.name = "riegl.rgba"
    point_color.title = "True Color"
    point_color.description = "Point color acquired by camera"
    point_color.unit_symbol = ""  # has no unit
    point_color.length = 4
    point_color.resolution = 1.000
    point_color.minimum_value = 0.000
    point_color.maximum_value = 255.000
    point_color.default_value = 255.000
    point_color.storage_class = riegl.rdb.PointAttribute.StorageClass.VARIABLE
    pointcloud.point_attributes.add(point_color)

    # Point classification - by using a shortcut for built-in RIEGL attributes:
    pointcloud.point_attributes.add("riegl.class")


def example_a():
    """
    This is a very simple example using default values for most options.
    """
    print("Example A")
    with riegl.rdb.rdb_create("pointcloud.rdbx") as rdb:
        # Before we can modify the database, we must start a transaction
        with riegl.rdb.Transaction(
            rdb,  # point cloud to create transaction for
            "Initialization",  # transaction title
            "Example program v1.0"  # software name
        ) as transaction:
            # Define some additional point attributes
            example_define_point_attributes(rdb)

            # Finally commit transaction
            transaction.commit()

    # Alternative: Create database and initialize it with commonly used point attributes and meta data (empty):
    # with riegl.rdb.rdb_create("pointcloud.rdbx", schema=riegl.rdb.RDB_SCHEMA_RIEGL_RDBX, optionals=True) as rdb:


def example_b():
    """
    This is a more advanced example, very similar to the C++ API example 1.
    """
    print("Example B")

    # New RDB library context
    context = riegl.rdb.Context()

    # New database instance
    rdb = riegl.rdb.Pointcloud(context)

    # Create new point cloud database
    settings = riegl.rdb.CreateSettings(context)

    # Define primary point attribute, usually the point coordinates
    # details see class riegl::rdb::pointcloud::PointAttribute
    settings.primary_attribute.name = "riegl.xyz"
    settings.primary_attribute.title = "XYZ"
    settings.primary_attribute.description = "Cartesian point coordinates"
    settings.primary_attribute.unit_symbol = "m"
    settings.primary_attribute.length = 3
    settings.primary_attribute.resolution = 0.00025
    settings.primary_attribute.minimum_value = -535000.0  # minimum,
    settings.primary_attribute.maximum_value = +535000.0  # maximum and
    settings.primary_attribute.default_value = 0.0  # default in m
    settings.primary_attribute.storage_class = \
        riegl.rdb.PointAttribute.StorageClass.VARIABLE

    # Define database settings
    settings.chunk_size = 50000  # maximum number of points per chunk
    settings.compression_level = 50  # 50% compression rate

    # Finally create new database
    rdb.create("pointcloud.rdbx", settings)

    # Before we can modify the database, we must start a transaction
    with riegl.rdb.Transaction(
        rdb,  # point cloud to create transaction for
        "Initialization",  # transaction title
        "Example program v1.0"  # software name
    ) as transaction:
        # Define some additional point attributes
        example_define_point_attributes(rdb)

        # Finally commit transaction
        transaction.commit()


if __name__ == "__main__":
    example_a()
    example_b()
