<commit_before># -*- coding: utf-8 -*-
import json
import math
import numpy as np
from flask import make_response

from py3dtiles.feature_table import (FeatureTableHeader, FeatureTableBody, FeatureTable)
from py3dtiles.tile import TileBody, TileHeader, Tile

from .utils import (
    read_uncompressed_patch, boundingbox_to_polygon, list_from_str, patch_nbpoints_unc
)
from .conf import Config
from .database import Session

LOD_MIN = 0
LOD_MAX = 5
LOD_LEN = LOD_MAX + 1 - LOD_MIN


def ThreeDTilesInfo(table, column):

    session = Session(table, column)
    # bounding box
    box = session.boundingbox

    # number of points for the first patch
    npoints = session.approx_row_count * session.patch_size

    # srs
    srs = session.srs

    # build json
    return {
        "bounds": [box['xmin'], box['ymin'], box['zmin'],
                   box['xmax'], box['ymax'], box['zmax']],
        "numPoints": npoints,
        "srs": srs
    }


def ThreeDTilesRead(table, column, bounds, lod):

    session = Session(table, column)
    # offsets = [round(off, 2) for off in list_from_str(offsets)]
    box = list_from_str(bounds)
    # requested = [scales, offsets]
    stored_patches = session.lopocstable.filter_stored_output()
    schema = stored_patches['point_schema']
    pcid = stored_patches['pcid']
    # scales = [scale] * 3
    scales = stored_patches['scales']
    offsets = stored_patches['offsets']

    [tile, npoints] = get_points(session, box, lod, offsets, pcid, scales, schema)

    if Config.DEBUG:
        tile.sync()
        print("NPOINTS: ", npoints)

    # build flask response
    response = make_response(tile.to_array().tostring())
    response.headers['content-type'] = 'application/octet-stream'
    return response


# FIXME: change pdt type in case of quantized values
cdt = np.dtype([('Red', np.uint8), ('Green', np.uint8), ('Blue', np.uint8)])
pdt = np.dtype([('X', np.float32), ('Y', np.float32), ('Z', np.float32)])


def get_points(session, box, lod, offsets, pcid, scales, schema):
    sql = sql_query(session, box, pcid, lod)
    if Config.DEBUG:
        print(sql)

    pcpatch_wkb = session.query(sql)[0][0]
    points, npoints = read_uncompressed_patch(pcpatch_wkb, schema)

    if max(points['Red']) > 255:
        # normalize
        rgb_reduced = np.c_[points['Red'] % 255, points['Green'] % 255, points['Blue'] % 255]
        rgb = np.array(np.core.records.fromarrays(rgb_reduced.T, dtype=cdt))
    else:
        rgb = points[['Red', 'Green', 'Blue']].astype(cdt)

    quantized_points_r = np.c_[
        points['X'] * scales[0],
        points['Y'] * scales[1],
        points['Z'] * scales[2]
    ]
<commit_msg>don't crash if no RGB in data<commit_after># -*- coding: utf-8 -*-
import json
import math

import numpy as np
from flask import make_response

from py3dtiles.feature_table import (FeatureTableHeader, FeatureTableBody, FeatureTable)
from py3dtiles.tile import TileBody, TileHeader, Tile

from .utils import (
    read_uncompressed_patch, boundingbox_to_polygon, list_from_str, patch_nbpoints_unc
)
from .conf import Config
from .database import Session

LOD_MIN = 0
LOD_MAX = 5
LOD_LEN = LOD_MAX + 1 - LOD_MIN


def ThreeDTilesInfo(table, column):

    session = Session(table, column)
    # bounding box
    box = session.boundingbox

    # number of points for the first patch
    npoints = session.approx_row_count * session.patch_size

    # srs
    srs = session.srs

    # build json
    return {
        "bounds": [box['xmin'], box['ymin'], box['zmin'],
                   box['xmax'], box['ymax'], box['zmax']],
        "numPoints": npoints,
        "srs": srs
    }


def ThreeDTilesRead(table, column, bounds, lod):

    session = Session(table, column)
    # offsets = [round(off, 2) for off in list_from_str(offsets)]
    box = list_from_str(bounds)
    # requested = [scales, offsets]
    stored_patches = session.lopocstable.filter_stored_output()
    schema = stored_patches['point_schema']
    pcid = stored_patches['pcid']
    # scales = [scale] * 3
    scales = stored_patches['scales']
    offsets = stored_patches['offsets']

    [tile, npoints] = get_points(session, box, lod, offsets, pcid, scales, schema)

    if Config.DEBUG:
        tile.sync()
        print("NPOINTS: ", npoints)

    # build flask response
    response = make_response(tile.to_array().tostring())
    response.headers['content-type'] = 'application/octet-stream'
    return response


# FIXME: change pdt type in case of quantized values
cdt = np.dtype([('Red', np.uint8), ('Green', np.uint8), ('Blue', np.uint8)])
pdt = np.dtype([('X', np.float32), ('Y', np.float32), ('Z', np.float32)])


def get_points(session, box, lod, offsets, pcid, scales, schema):
    sql = sql_query(session, box, pcid, lod)
    if Config.DEBUG:
        print(sql)

    pcpatch_wkb = session.query(sql)[0][0]
    points, npoints = read_uncompressed_patch(pcpatch_wkb, schema)

    if 'Red' in points:
        if max(points['Red']) > 255:
            # normalize
            rgb_reduced = np.c_[points['Red'] % 255, points['Green'] % 255, points['Blue'] % 255]
            rgb = np.array(np.core.records.fromarrays(rgb_reduced.T, dtype=cdt))
        else:
            rgb = points[['Red', 'Green', 'Blue']].astype(cdt)
    else:
        # No colors
        # FIXME: compute color gradient based on elevation or use classification
        rgb_reduced = np.c_[
            np.array([0] * npoints),
            np.array([0] * npoints),
            np.array([0] * npoints)
        ]
        rgb = np.array(np.core.records.fromarrays(rgb_reduced.T, dtype=cdt))

    quantized_points_r = np.c_[
        points['X'] * scales[0],
        points['Y'] * scales[1],
        points['Z'] * scales[2]
    ]

{'fraction_non_alphanumeric': 0.13691931540342298, 'fraction_numerical': 0.01239958085923856, 'mean_word_length': 3.201760821716801, 'pattern_counts': {'":': 6, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5071634', 'n_tokens_mistral': 2006, 'n_tokens_neox': 1898, 'n_words': 464}