点群データはデータ量が多く、手元で動かせるOracle Database 23ai Freeでは、一本の等高線を生成するだけで何時間もかかります。そのため、作業の目的は等高線を生成することではなく、Oracle Databaseで点群データを扱う手順の確認です。
- LasファイルからCSVファイルを生成しました。
- CSVファイルをフラットな点群データとしてデータベースにアップロードしました。
- フラットな点群データをOracle Spatialの点群データ型であるSDO_PC型へ変換しました。
- SDO_PC型のデータから等高線(SDO_GEOMETRY型)を生成しました。
- 生成した等高線をマップ上に表示しました。
- オープンデータのDXF形式の等高線をGDALのogr2ogrを使って表示しました。
Lasファイルの取得
東京都デジタルツイン実現プロジェクトの島しょ地域点群データより、オリジナル(DSM)及びグラウンドデータ(DEM)を開きます。
onbase % unzip 09QC6295.zip
Archive: 09QC6295.zip
inflating: 09QC6295.las
onbase %
LasからCSVファイルへの変換
git clone https://github.com/LAStools/LAStools.git
onbase % git clone https://github.com/LAStools/LAStools.git
Cloning into 'LAStools'...
remote: Enumerating objects: 11261, done.
remote: Counting objects: 100% (1841/1841), done.
remote: Compressing objects: 100% (413/413), done.
remote: Total 11261 (delta 1585), reused 1463 (delta 1428), pack-reused 9420 (from 2)
Receiving objects: 100% (11261/11261), 21.22 MiB | 6.80 MiB/s, done.
Resolving deltas: 100% (8580/8580), done.
onbase %
onbase % cd LAStools
LAStools % ls
bin data lastools.dsw LICENSE.txt
CHANGES.txt example_batch_scripts LAStools.sln readme_logo.jpg
CMakeLists.txt HALL_OF_SHAME.txt LASzip README.md
COPYING.txt LASlib license.html src
LAStools %
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="-Wno-non-pod-varargs -Wno-deprecated-declarations" \
..
make -j"$(sysctl -n hw.ncpu)"
LAStools % mkdir build && cd build
build % cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="-Wno-non-pod-varargs -Wno-deprecated-declarations" \
..
-- The CXX compiler identification is AppleClang 17.0.0.17000319
-- The C compiler identification is AppleClang 17.0.0.17000319
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done (0.4s)
-- Generating done (0.0s)
-- Build files have been written to: /Users/**********/Documents/onbase/LAStools/build
build % make -j"$(sysctl -n hw.ncpu)"
[ 1%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreader.cpp.o
[ 3%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreader_shp.cpp.o
[ 3%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasignore.cpp.o
[ 4%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreader_las.cpp.o
[ 7%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreader_bil.cpp.o
[ 8%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/laswriter.cpp.o
[ 8%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreader_asc.cpp.o
[ 8%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreader_qfit.cpp.o
[ 9%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreader_bin.cpp.o
[ 10%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreadermerged.cpp.o
[ 12%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreader_dtm.cpp.o
[ 13%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreader_ply.cpp.o
[ 13%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreaderbuffered.cpp.o
[ 14%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreaderstored.cpp.o
[ 16%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreaderpipeon.cpp.o
[ 16%] Building CXX object LASlib/src/CMakeFiles/LASlib.dir/lasreader_txt.cpp.o
In file included from /Users/ynakakoshi/Documents/onbase/LAStools/LASlib/src/lasreader.cpp:31:
In file included from /Users/ynakakoshi/Documents/onbase/LAStools/LASlib/inc/lasreader.hpp:55:
In file included from /Users/ynakakoshi/Documents/onbase/LAStools/LASlib/inc/lasdefinitions.hpp:63:
/Users/ynakakoshi/Documents/onbase/LAStools/LASzip/src/laspoint.hpp:303:9: warning: unknown pragma ignored [-Wunknown-pragmas]
303 | #pragma warning(push)
| ^
[中略]
29 warnings generated.
21 warnings generated.
[100%] Linking CXX executable /Users/ynakakoshi/Documents/onbase/LAStools/bin64/lasinfo64
[100%] Built target lasinfo
build %
build % cd ..
LAStools % ls bin64
las2las64 lascopcindex64 lasindex64 lasmerge64 laszip64
las2txt64 lasdiff64 lasinfo64 lasprecision64 txt2las64
LAStools %
これらのコマンドを使用するために、環境変数PATHに含めます。
LAStools % export PATH=$PWD/bin64:$PATH
LAStools %
las2las64 -i 09QC6295_all.las -o 09QC6295.las -keep_class 2 4 12 22
onbase % mv 09QC6295.las 09QC6295_all.las
onbase % las2las64 -i 09QC6295_all.las -o 09QC6295.las -keep_class 2 4 12 22
onbase %
las2txt64を実行し、LasデータをCSVに変換します。parseオプションにxyzirnedcaRGBを指定していますが、今回使用するデータは最初のxyzの3列のみです。
onbase % las2txt64 -i 09QC6295.las -o 09QC6295.csv -parse xyzirnedcaRGB -sep comma
onbase % ls -l 09QC6295.*
-rw-r--r-- 1 ******** staff 161142749 10月 14 12:22 09QC6295.csv
-rw-r--r-- 1 ******** staff 81351793 10月 14 12:18 09QC6295.las
-rw-r--r--@ 1 ******** staff 82706254 10月 14 11:23 09QC6295.zip
onbase %
headコマンドでCSVファイルの先頭データを確認します。ヘッダー行を含まず、parseオプションで指定したデータが、カンマ区切りで列記されています。
onbase % head 09QC6295.csv
-69888.740,-200700.000,0.810,11078,1,1,0,1,2,3,41728,43264,40704
-69749.450,-200999.240,0.930,14406,1,1,0,1,2,-11,41984,40192,35328
-69749.630,-200999.050,1.480,6361,1,1,0,1,2,-11,44288,44032,40192
-69749.360,-200999.090,1.320,9665,1,1,0,1,2,-11,45824,44544,38656
-69751.120,-200997.910,0.880,8949,1,1,0,1,2,-11,44544,44544,40704
-69750.600,-200998.300,1.580,3854,1,1,0,1,2,-11,41728,41984,38912
-69750.340,-200998.390,1.590,3962,1,1,0,1,2,-11,43264,43008,39680
-69750.080,-200998.550,1.830,3112,1,1,0,1,2,-11,45568,45824,40960
-69749.830,-200998.710,2.060,3530,1,1,0,1,2,-11,41984,42240,39168
-69749.560,-200998.790,2.010,3812,1,1,0,1,2,-11,40448,41216,38912
onbase %
CSVをSDO_PC型の点群データとして保存
drop table if exists lidar_points;
create table lidar_points (
x NUMBER, -- X
y NUMBER, -- Y
z NUMBER, -- Z
intensity NUMBER, -- i => Intensity
return_number NUMBER, -- r => Return Number
number_of_returns NUMBER, -- n => Number of Returns
edge_of_flight_line NUMBER, -- e => Flightline Edge
scan_direction_flag NUMBER, -- d => Scan Direction Flag
classification NUMBER, -- c => Classification
scan_angle_rank NUMBER, -- a => Scan Angle Rank
r NUMBER, -- R => Color red (2 bytes [0-65536])
g NUMBER, -- G => Color green (2 bytes [0-65536])
b NUMBER -- B => Color blue (2 bytes [0-65536])
)
nologging;
onbase % sql wksp_apexdev@localhost/freepdb1
SQLcl: 火 10月 14 12:34:48 2025のリリース25.2 Production
Copyright (c) 1982, 2025, Oracle. All rights reserved.
パスワード (**********?) ******
接続先:
Oracle Database 23ai Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.9.0.25.07
SQL> drop table if exists lidar_points;
Table LIDAR_POINTSが削除されました。
SQL> create table lidar_points (
2 x NUMBER, -- X
3 y NUMBER, -- Y
4 z NUMBER, -- Z
5 intensity NUMBER, -- i => Intensity
6 return_number NUMBER, -- r => Return Number
7 number_of_returns NUMBER, -- n => Number of Returns
8 edge_of_flight_line NUMBER, -- e => Flightline Edge
9 scan_direction_flag NUMBER, -- d => Scan Direction Flag
10 classification NUMBER, -- c => Classification
11 scan_angle_rank NUMBER, -- a => Scan Angle Rank
12 r NUMBER, -- R => Color red (2 bytes [0-65536])
13 g NUMBER, -- G => Color green (2 bytes [0-65536])
14 b NUMBER -- B => Color blue (2 bytes [0-65536])
15 )
16* nologging;
Table LIDAR_POINTSは作成されました。
SQL>
set load batch_rows 10000
set loadformat column_names off
SQL> set load batch_rows 10000
SQL> set loadformat column_names off
SQL> load lidar_points 09QC6295.csv
csv
column_names off
delimiter ,
enclosures ""
double off
encoding UTF8
row_limit off
row_terminator default
skip_rows 0
skip_after_names
データを表にロードします WKSP_APEXDEV.LIDAR_POINTS
batch_rows 10000
batches_per_commit 10
clean_names transform
column_size rounded
commit on
date_format
errors 50
map_column_names off
method insert
timestamp_format
timestamptz_format
locale
scan_rows 100
truncate off
unknown_columns_fail on
#INFO 処理された行数: 2,392,691
#INFO エラーのある行数: 0
#INFO 最後にコミットされたバッチで処理された最後の行: 2,392,691
成功: エラーなしで処理されました
SQL>
座標X、YおよびZの最小値と最大値を確認します。座標参照系は、日本測地系2011/平面直角座標系第9系(EPSG:6677)です。
SELECT
MIN(x) as min_x, MAX(x) as max_x,
MIN(y) as min_y, MAX(y) as max_y,
MIN(z) as min_z, MAX(z) as max_z
FROM lidar_points;
SQL> SELECT
2 MIN(x) as min_x, MAX(x) as max_x,
3 MIN(y) as min_y, MAX(y) as max_y,
4 MIN(z) as min_z, MAX(z) as max_z
5* FROM lidar_points;
MIN_X MAX_X MIN_Y MAX_Y MIN_Z MAX_Z
_________ _________ __________ __________ _________ ________
-70000 -69600 -201000 -200700 -12.97 65.08
SQL>
Z方向が-12.97mから65.08mの間にデータがあるので、生成できる等高線もこの間になります。
SQL> @create_point_cloud
Table LIDAR_PC_BASEが削除されました。
Table LIDAR_PC_BASEは作成されました。
Table LIDAR_PC_BLKが削除されました。
Table LIDAR_PC_BLKは作成されました。
Point Cloudオブジェクトが初期化されました
PL/SQLプロシージャが正常に完了しました。
Table LIDAR_INPUT_PCが削除されました。
Table LIDAR_INPUT_PCは作成されました。
Point Cloudの作成が完了しました
PL/SQLプロシージャが正常に完了しました。
SQL>
SELECT
COUNT(*) as block_count,
SUM(num_points) as total_points,
MIN(num_points) as min_points_per_block,
MAX(num_points) as max_points_per_block,
AVG(num_points) as avg_points_per_block
FROM lidar_pc_blk;
SQL> SELECT
2 COUNT(*) as block_count,
3 SUM(num_points) as total_points,
4 MIN(num_points) as min_points_per_block,
5 MAX(num_points) as max_points_per_block,
6 AVG(num_points) as avg_points_per_block
7* FROM lidar_pc_blk;
BLOCK_COUNT TOTAL_POINTS MIN_POINTS_PER_BLOCK MAX_POINTS_PER_BLOCK AVG_POINTS_PER_BLOCK
______________ _______________ _______________________ _______________________ ____________________________________________
240 2392691 6345 10000 9969.545833333333333333333333333333333333
SQL>
drop table if exists contour_lines purge;
create table contour_lines (
contour_id number generated by default as identity primary key,
elevation number,
geom_6677 mdsys.sdo_geometry, -- EPSG:6677
geom_wgs84 mdsys.sdo_geometry, -- EPS_G:4326
geom mdsys.sdo_geometry -- sdo_util.remove_duplicate_vertices
);
SQL> drop table if exists contour_lines purge;
Table CONTOUR_LINESが削除されました。
SQL> create table contour_lines (
2 contour_id number generated by default as identity primary key,
3 elevation number,
4 geom_6677 mdsys.sdo_geometry, -- EPSG:6677
5 geom_wgs84 mdsys.sdo_geometry, -- EPSG:4326
6 geom mdsys.sdo_geometry -- sdo_util.remove_duplicate_vertices
7* );
Table CONTOUR_LINESは作成されました。
SQL>
select elevation, sdo_util.to_wktgeometry(geom_6677) from contour_lines;
SQL> select elevation, sdo_util.to_wktgeometry(geom_6677) from contour_lines;
ELEVATION SDO_UTIL.TO_WKTGEOMETRY(GEOM_6677)
____________ ___________________________________________________________________________________
0 LINESTRING (-69967.3933570539 -200999.5, -69967.5 -200999.350083891, -69969.5 -2
10 LINESTRING (-69893.5 -200905.218388821, -69895.087159423 -200905.5, -69895.5 -20
20 LINESTRING (-9893.5 -200913.191513301, -9894.87498406222 -200913.5, -9895.5 -200
30 LINESTRING (-9895.5 -200919.186358386, -9895.84202419422 -200919.5, -9897.5 -200
40 LINESTRING (-69774.0662795354 -200811.5, -69775.5 -200810.867211666, -69777.5 -2
50 LINESTRING (-9725.5 -200809.466071466, -9727.5 -200808.938161045, -9729.5 -20080
60 LINESTRING (-9767.5 -200881.000708521, -9769.5 -200880.815372578, -9770.44721335
7行が選択されました。
SQL>
update contour_lines set geom_wgs84 =
SDO_CS.MAKE_2D(
SDO_CS.TRANSFORM(
geom_6677,
4326
)
);
commit;
SQL> update contour_lines set geom_wgs84 =
2 SDO_CS.MAKE_2D(
3 SDO_CS.TRANSFORM(
4 geom_6677,
5 4326
6 )
7* );
7行更新しました。
SQL> commit;
コミットが完了しました。
SQL>
select sdo_util.to_geojson(geom_wgs84) from contour_lines;
現状ではORA-13199: GeoJSON supports only a straight lineが発生し、等高線のデータをGeoJSONに変換できません。
SQL> select sdo_util.to_geojson(geom_wgs84) from contour_lines;
次のコマンド行の開始中にエラーが発生しました : 1 -
select sdo_util.to_geojson(geom_wgs84) from contour_lines
コマンド行 : 1 列 : 8 でのエラー
エラー・レポート -
SQLエラー: ORA-13199: GeoJSON supports only a straight line
ORA-06512: "MDSYS.SDO_UTIL", 行9150
ORA-06512: "MDSYS.SDO_UTIL", 行9171
https://docs.oracle.com/error-help/db/ora-13199/13199. 00000 - "%s"
*Cause: This is an internal error.
*Action: Contact Oracle Support Services.
More Details :
https://docs.oracle.com/error-help/db/ora-13199/
https://docs.oracle.com/error-help/db/ora-06512/
SQL>
update contour_lines set geom =
sdo_util.remove_duplicate_vertices(
geom_wgs84,
1e-6
);
commit;
SQL> update contour_lines set geom =
2 sdo_util.remove_duplicate_vertices(
3 geom_wgs84,
4 1e-6
5* );
7行更新しました。
SQL> commit;
コミットが完了しました。
SQL>
APEXアプリケーションの作成
SQL> SELECT
2 MIN(x) as min_x, MAX(x) as max_x,
3 MIN(y) as min_y, MAX(y) as max_y,
4 MIN(z) as min_z, MAX(z) as max_z
5* FROM lidar_points;
MIN_X MAX_X MIN_Y MAX_Y MIN_Z MAX_Z
_________ _________ __________ __________ _________ ________
-70000 -69600 -201000 -200700 -12.97 65.08
SQL>
オープンデータの等高線を表示する
podman run --rm -it -v $PWD:/home/oracle gdal
以下のコマンドを実行します。ファイル09qc6295.dxfに記載されている等高線(1m間隔)が、表CONTOUR_LINES_FULLの列GEOMにSDO_GEOMETRY型で保存されます。
ogr2ogr -f OCI -overwrite \
OCI:wksp_apexdev/********@host.containers.internal/freepdb1 \
09qc6295.dxf \
-oo ENCODING=CP932 \
-nln CONTOUR_LINES_FULL -lco GEOMETRY_NAME=GEOM -lco SRID=4326 -lco DIM=2 \
-s_srs EPSG:6677 \
-t_srs EPSG:4326 \
-skipfailures
bash-5.1$ ogr2ogr -f OCI -overwrite \
OCI:wksp_apexdev/oracle@host.containers.internal/freepdb1 \
09qc6295.dxf \
-oo ENCODING=CP932 \
-nln CONTOUR_LINES_FULL -lco GEOMETRY_NAME=GEOM -lco SRID=4326 -lco DIM=2 \
-s_srs EPSG:6677 \
-t_srs EPSG:4326 \
-skipfailures
bash-5.1$
ogr2ogrの実行結果を、APEXマップにレイヤーを追加して確認します。