преобразование ply в postgis, скрипт работает, но объем неверен - PullRequest
1 голос
/ 22 марта 2019

Я пытаюсь преобразовать слой в многогранник, хранящийся в postgis.В этом примере у меня есть куб от 0,0,0 до 1,1,1, скрипт ниже вводит геометрию в postgis, это не проблема, однако я иду вычислять объем и выдает следующую ошибку:

запрос:

SELECT ST_Volume(st_geomfromtext) FROM public.test3

ошибка:

ERROR:  PolyhedralSurface is invalid : inconsistent orientation of PolyhedralSurface detected at edge 1 (4-3) of polygon 11 : POLYHEDRALSURFACE(((1/1 1/1 0/1,1/1 0/1 0/1,0/1 0/1 0/1,1/1 1/1 0/1)),((1/1 0/1 0/1,1/1 0/1 1/1,0/1 0/1 0/1,1/1 0/1 0/1)),((1/1 0/1 0/1,1
SQL state: XX000

Объект является кубом от 0,0,0 до 1,1,1, здесь он какмассив вершин и треугольников.

вершин:

array([[ 1.,  1., -0.],
       [ 1.,  0., -0.],
       [ 0.,  0., -0.],
       [ 0.,  1., -0.],
       [ 1.,  1.,  1.],
       [ 0.,  1.,  1.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  1.],
       [ 1.,  1., -0.],
       [ 1.,  1.,  1.],
       [ 1.,  0.,  1.],
       [ 1.,  0., -0.],
       [ 1.,  0., -0.],
       [ 1.,  0.,  1.],
       [ 0.,  0.,  1.],
       [ 0.,  0., -0.],
       [ 0.,  0., -0.],
       [ 0.,  0.,  1.],
       [ 0.,  1.,  1.],
       [ 0.,  1., -0.],
       [ 1.,  1.,  1.],
       [ 1.,  1., -0.],
       [ 0.,  1., -0.],
       [ 0.,  1.,  1.]])

Треугольники определены как:

array([[ 0,  1,  2],
       [ 0,  2,  3],
       [ 4,  5,  6],
       [ 4,  6,  7],
       [ 8,  9, 10],
       [ 8, 10, 11],
       [12, 13, 14],
       [12, 14, 15],
       [16, 17, 18],
       [16, 18, 19],
       [20, 21, 22],
       [20, 22, 23]], dtype=int32)

Я собрал этот скрипт преобразования, чтобы взять слой и добавитьэто к postgis:

import numpy as np
from open3d import *
import psycopg2

import dbconfig

def connect_db():
    global connection
    connection = psycopg2.connect(host=dbconfig.DATABASE_CONFIG['host'],
                                  user=dbconfig.DATABASE_CONFIG['user'],
                                  password=dbconfig.DATABASE_CONFIG['password'],
                                  dbname=dbconfig.DATABASE_CONFIG['dbname'])
    return connection
# mesh = read_triangle_mesh('C:/Users/garyn/PycharmProjects/pointcloudprocessor/tmp/contexts/99.526/396.ply')

mesh = read_triangle_mesh('C:/Users/garyn/PycharmProjects/pointcloudprocessor/tmp/contexts/cube3.ply')
verts = mesh.vertices
verts = np.asarray(verts)
tri = mesh.triangles
tri = np.asarray(tri)

data = ''
header = ("'POLYHEDRALSURFACE(")
for i in range(len(tri)):
# for i in range(0,2):
    x1 = (tri[i][0]) # 3
    y1 = (tri[i][1]) # 44
    z1 = (tri[i][2]) # 1
    x_coords1 = verts[x1][0]
    y_coords1 = verts[y1][0]
    z_coords1 = verts[z1][0]
    x_coords2 = verts[x1][1]
    y_coords2 = verts[y1][1]
    z_coords2 = verts[z1][1]
    x_coords3 = verts[x1][2]
    y_coords3 = verts[y1][2]
    z_coords3 = verts[z1][2]

    data += "((%s %s %s, %s %s %s, %s %s %s, %s %s %s))," % \
        (x_coords1, y_coords1, z_coords1, \
        x_coords2, y_coords2, z_coords2, \
        x_coords3, y_coords3, z_coords3, \
        x_coords1, y_coords1, z_coords1)
data = data[:-1]

projection = ")',32635)"
create_stmt = "CREATE TABLE test3 AS "
select_stmt = "SELECT ST_GeomFromText("
polyhedron = header + data + projection
query = create_stmt + select_stmt + polyhedron

conn = connect_db()
cur = conn.cursor()
cur.execute(query)
conn.commit()
cur.close()
conn.close()

Что приводит к:

CREATE TABLE test3 AS 
   SELECT ST_GeomFromText('POLYHEDRALSURFACE(((1.0 1.0 0.0, 1.0 0.0 0.0, -0.0 -0.0 -0.0, 1.0 1.0 0.0)),((1.0 0.0 0.0, 1.0 0.0 1.0, -0.0 -0.0 -0.0, 1.0 0.0 0.0)),((1.0 0.0 0.0, 1.0 1.0 0.0, 1.0 1.0 1.0, 1.0 0.0 0.0)),((1.0 0.0 1.0, 1.0 0.0 0.0, 1.0 1.0 1.0, 1.0 0.0 1.0)),((1.0 1.0 1.0, 1.0 1.0 0.0, -0.0 1.0 1.0, 1.0 1.0 1.0)),((1.0 1.0 1.0, 1.0 0.0 0.0, -0.0 1.0 -0.0, 1.0 1.0 1.0)),((1.0 1.0 0.0, 0.0 0.0 0.0, -0.0 1.0 1.0, 1.0 1.0 0.0)),((1.0 0.0 0.0, 0.0 0.0 0.0, -0.0 1.0 -0.0, 1.0 0.0 0.0)),((0.0 0.0 0.0, 0.0 0.0 1.0, -0.0 1.0 1.0, 0.0 0.0 0.0)),((0.0 0.0 0.0, 0.0 1.0 1.0, -0.0 1.0 -0.0, 0.0 0.0 0.0)),((1.0 1.0 0.0, 1.0 1.0 1.0, 1.0 -0.0 -0.0, 1.0 1.0 0.0)),((1.0 0.0 0.0, 1.0 1.0 1.0, 1.0 -0.0 1.0, 1.0 0.0 0.0)))',32635)

Мне это выглядит нормально, и postgis принимает его как многогранную поверхность, но как мне убедиться, что куб построенправильно?PS и постгис 3D зрители там, я делаю это вслепую.

1 Ответ

0 голосов
/ 22 марта 2019

Я решил, у меня был неправильный порядок, вот правильный порядок.

data = ''
header = ("'POLYHEDRALSURFACE(")
for i in range(len(tri)):
# for i in range(0,2):
    x1 = (tri[i][0]) # 3
    y1 = (tri[i][1]) # 44
    z1 = (tri[i][2]) # 1
    coords1 = verts[x1][0]
    coords2 = verts[x1][1]
    coords3 = verts[x1][2]

    coords4 = verts[y1][0]
    coords5 = verts[y1][1]
    coords6 = verts[y1][2]

    coords7 = verts[z1][0]
    coords8 = verts[z1][1]
    coords9 = verts[z1][2]

    data += "((%s %s %s, %s %s %s, %s %s %s, %s %s %s))," % \
        (
        coords1, coords2, coords3,
        coords4, coords5, coords6,
        coords7, coords8, coords9,
        coords1, coords2, coords3
        )
data = data[:-1]
...