Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction to Point Tiler

Avatar for nokonoko1203 nokonoko1203
September 02, 2026
42

Introduction to Point Tiler

Avatar for nokonoko1203

nokonoko1203

September 02, 2026

More Decks by nokonoko1203

Transcript

  1. OPENING 01 / 20 Introduction to Point Tiler A tool

    and techniques for converting large point clouds into 3D Tiles Point Cloud 3D Tiles 1.1 Rust CLI Satoru Nishio / MIERUNE Inc. / @nokonoko1203
  2. A BOU T M E 02 / 20 Satoru Nishio

    (@nokonoko_1203) Engineering Manager at MIERUNE Inc. GIS & web development. 3D WebGIS Point Cloud AWS Community Builder (AI Engineering) PLATEAU ADVOCATE / Cesium Certified Developer X: twitter.com/nokonoko_1203 LinkedIn: linkedin.com/in/satoru-nishio
  3. R EA LI T Y 03 / 20 In theory

    3 steps — in reality, several problems ① Pick a tool › ② Point it at your files 01 Points land in the wrong place 02 Distributed data is too big 03 Memory dies mid-conversion 04 Output is heavy too › ③ Run it — in theory JP plane rectangular CRS has X and Y swapped Ships as plain LAS. e.g. Expo site ≈ 940GB City-scale data does not fit in RAM 1000s of files, tens of GB. Each failure = half a day If conversion is fast and stable, trial and error works
  4. POINT TILER 04 / 20 LAS/LAZ/CSV → 3D Tiles 1.1(GLB)

    Rust CLI, MIT license One CLI command → automate it with cron / CI curl -sSf .../install.sh | bash Linux / macOS via script · Windows: .exe from GitHub Releases
  5. BEN CHMA RK Benchmark Input Osaka Expo site point cloud

    — ≈ 940GB of LAS Time ≈ 3 hours Compare In the past, converting a 260GB point cloud took about 7 hours ※ This is the out-of-memory external sort path (mechanism in ③ Memory) 05 / 20
  6. COMMA N D The command = today's agenda 4 option

    groups — one answer per trap from the previous slide. ptiler --input /path/to/data/*.laz \ --output /path/to/output \ --input-epsg 6677 --output-epsg 4979 \ # ① CRS & input --min 15 --max 18 \ # ② tile design --max-memory-mb 8192 --threads 8 \ # ③ memory & threads --quantize --meshopt --gzip-compress # ④ compression 06 / 20
  7. ① INPUT — LAS AND LAZ 07 / 20 LAS

    or LAZ — Point Tiler reads both as they are LAS— big, common › Point Tiler LAZ— small, handy — Point cloud data is often shared as LAS. LAS files are big. — LAZ is the packed form of LAS. Same points, much smaller. Handy for storing and sharing. — Point Tiler reads both. No need to unpack LAZ first.
  8. ① LAZ INT ERN A LS 08 / 20 Inside

    LAZ: chunks of 50,000 points Header metadata › Chunk #1 › Chunk #2 50k points — Point Tiler unpacks one chunk at a time — Only one chunk is in memory — nothing is written back as LAS › Chunk #N … › Chunk table offsets
  9. ① CRS TRAP → PROJ 09 / 20 The CRS

    trap: explicit EPSG codes + PROJ JP plane rectangular CRS (EPSG:6669–6687) X = north, Y = east — the opposite of math Mixing them up throws NO error — points appear rotated 90° or in the wrong place Fix 1 Fix 2 You give input and output EPSG codes — no guessing The math is done by PROJ — the standard GIS library
  10. ② LOD BASICS 10 / 20 LOD = geometricError; "zoom

    level" is just a ruler LOD switches by geometricError (roughness in meters), not by zoom level min / max use 2D-style zoom as a simple ruler z15 z18 geometricError geometricError ≈ 64m ≈ 8m
  11. ② QU ADTREE 11 / 20 Generate from detailed →

    coarse All points → max zoom — Source points are read only once — Upper levels get lighter › merge 4 children, decimate › … › min zoom
  12. ② DECIMATION 12 / 20 Decimation: voxels proportional to geometricError

    Voxel size follows geometricError One rule for all zooms — coarser zoom, bigger voxel — Keep 1 real point per voxel — the one closest to the center Start from the defaults (z15–18) → close views too thin? max +1 Output is for display — for survey-grade accuracy, use LAS/LAZ or COPC
  13. ③ M EM ORY B UD GET 13 / 20

    Just declare: "this machine may use 8GB" --max-memory-mb 8192 estimated size × 5 ≤ limit › All in memory estimated size × 5 > limit › External sort estimated size = point count × record length (from file headers) Why ×5: real memory use is several times the raw points
  14. ③ EX TERNAL SORT 14 / 20 External sort: the

    basic idea An old, well-known way to sort data that does not fit in memory 1 2 Sort small pieces, write each piece to disk Merge all sorted files → whole dataset sorted Tiling = points of the same tile come together = sorting
  15. ③ READ → SORTED FILES 15 / 20 Read with

    a queue → files sorted by tile ID Reader threads 1 point = › Tile ID Bounded queue XYZ coords › Sort by tile ID RGB color Tile IDs follow a Hilbert curve — close tiles → close IDs › Write to disk = 38 bytes fixed
  16. ③ SHA RD + M ER GE 16 / 20

    Shard = one min-zoom cell; merge inside it shard Merge sorted files › Tile done → thin, write › GLB out Shard done → temp files deleted right away Temp disk ≈ 1.2–1.5× the LAS size
  17. ③ I /O + P AR A LL E L

    I SM 17 / 20 Disk speed matters — each stage runs in its own way Files are written and read back many times → use a fast local drive Read + transform Shard merge Aggregation + GLB Threads + a queue One shard at a time In parallel with Rayon
  18. ④ QU ANTIZE 18 / 20 Compression stage 1 —

    quantize: 16 → 12 bytes per point 16B/pt Normal f32 ×3 RGB 12B/pt (−25%) --quantize u16 ×3 · RGB Tile-local coords have a small range → 16-bit is fine Required glTF extension — old viewers cannot open it. CesiumJS OK since 1.97 (2022) · ·
  19. ④ MESHOPT + GZIP 19 / 20 Stages 2 &

    3 — meshopt and gzip ① Quantize ② meshopt ③ gzip Data representation Binary compression Transport compression .glb files hold gzip bytes → server must send Content-Encoding: gzip The 3 stages are independent — when in doubt, turn them all on
  20. WR A P UP / FIN Takeaways — and where

    to find Point Tiler 01 Read the compressed input directly 02 Ask for the CRS — never guess 03 Let the user set a memory limit; switch paths automatically github.com/MIERUNE/point-tiler(MIT) For CityGML buildings → 3D Tiles: PLATEAU GIS Converter Issues / PRs welcome — thank you! 20 / 20