คอมไพล์ PROJ 9.6.0 สำหรับแอนดรอยด์ แก้ปัญหาเพิ่มขนาด page size 16KB ตามกฎใหม่ของกูเกิ้ล

ตอนนี้เป็นตอนต่อ ของบทความที่แล้ว

ถ้าใครพัฒนาแอพลง Google play store จะเห็นข้อความของกูเกิ้ลส่งมาใน inbox ให้แก้ไขแอพโดยที่แก้ขนาดของ page size จากเดิม 4KB ที่ใช้มานานแล้วให้เป็น 16KB กูเกิ้ลแจ้งว่าจะให้แอพจะเร็วขึ้น เนื่องจากแอพผมไม่ได้ต้องการความเร็วในการคำนวณเหมือนพวกแอพเกมส์การแก้ปัญหาด้วย page size นี้คงไม่ได้ช่วยอะไร

กูเกิ้ลปรับกฎนี้ กำหนดเวลาให้ 1 พย. 2025 นี้ ผมก็เลยใช้เวลาว่างแก้ไข สำหรับในตัวแอพเองการบิวท์ต้องใช้ Android studio อยู่แล้วเบื้องหลัง จึงไม่ต้องทำอะไร เพียงแต่แอพผมมีการใช้ไลบรารี native ภายนอกอยู่สองไลบรารีคือ PROJ (libproj.so), Sqlite3 (libsqlite3.so) ผมต้องมาแก้ไขที่ตัวนี้

แอพทดสอบ “SurveyStar QuickTM”

และแอพที่จะมานำเสนอการแก้ไข page size ที่ต้องการขนาด 16 KB ก็คือ SurveyStar Quick TM ของผมนั่นเอง แอพนี้เป็นแอพฟรี ไม่มีการ subscription หน้าที่ของแอพคือให้ผู้ใช้กำหนดเส้นโครงแผนที่แบบ LDP (Low Distortion Projection) หรือบางท่านอาจจะติดปากว่า TM

ที่จริง TM เป็นเส้นโครงแผนที่ Transverse Mercator หรือหนึ่งในสามเส้นโครงแผนที่ที่นิยมนำมาใช้ทำ LDP อีกสองเส้นโครงแผนที่คือ LCC (Lambert Conic Conformal) และ OM (Oblique Mercator) พอกำหนดค่าพารามิเตอร์ของ LDP อย่างง่ายแล้วสามารถคำนวณค่าพิกัดกับ UTM ได้ทันที

การทดสอบ Page size

ผมไม่ค่อยแน่ใจว่า libproj.so และ libsqlite3.so ที่นำมาใช้ในแอพ จะมี page size เท่ากับ 16 KB หรือไม่ การทดสอบทำได้หลายวิธี

วิธีแรกคือใช้ทูลส์ “APK Analyzer” ที่ติดมากับ Android Studio โดยที่แนะนำโดยกูเกิ้ล แต่ผมพบว่าแสดงผลไม่ถูกต้องนัก วิธีใช้งานเปิดเมนู Run > APK Analyzer แล้วเลิกไฟล์ APK ของแอพเรา จะมีช่องคอลัมน์แสดง Alignment ผมดูตัวเลขพบว่า libproj.so และ libsqlite3.so มีขนาด 16KB ทั้งคู่เหมือนจะได้ข้อกำหนดแต่ผมก็ไม่แน่ใจเพราะสองไลบรารีนี้คอมไพล์ไว้นานแล้ว น่าจะร่วมๆ 4 ปี

วิธีที่สองใช้ llvm-objdump เนื่องจากผมใช้ลีนุกซ์ ใช้คำสั่ง sudo apt install llvm จะได้ llvm-objdump มาด้วย แต่เนื่องจาก llvm-objdump ต้องใช้กับไฟล์ไลบรารีโดยตรง ไม่ได้ตรวจที่ไฟล์ APK ผมจึงใช้คำสั่งกับไฟล์ *.so ผลที่ได้ตามคาดคือตัวเลข 2**12 ไม่ผ่าน กูเกิ้ลบอกไว้ว่าตัวเลข ที่ได้เช่น 2**12 และ 2**13 จะไม่ผ่าน ต้องเป็นตัวเลข 2**14 ขึ้นไปเท่านั้น

pbrobo@pbrobo-ThinkPad-P52:.../main/jniLibs/arm64-v8a$ llvm-objdump -p libsqlite3.so | grep LOAD
    LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**12
    LOAD off    0x000000000003e814 vaddr 0x000000000003f814 paddr 0x000000000003f814 align 2**12
    LOAD off    0x00000000001719f0 vaddr 0x00000000001739f0 paddr 0x00000000001739f0 align 2**12
    LOAD off    0x00000000001744e8 vaddr 0x00000000001774e8 paddr 0x00000000001774e8 align 2**12
pbrobo@pbrobo-ThinkPad-P52:.../main/jniLibs/arm64-v8a$ llvm-objdump -p libproj.so | grep LOAD
    LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**12
    LOAD off    0x00000000003f7dd0 vaddr 0x00000000003f8dd0 paddr 0x00000000003f8dd0 align 2**12
    LOAD off    0x000000000041ad80 vaddr 0x000000000041cd80 paddr 0x000000000041cd80 align 2**12
pbrobo@pbrobo-ThinkPad-P52:.../main/jniLibs/arm64-v8a$ 

วิธีที่สาม โดยการใช้สคริปต์ดาวน์โหลดได้ที่ check_elf_alignment.sh เมื่อดาวน์โหลดมาแล้วอย่าลืมใช้คำสั่ง chmod +x check_elf_alignmnet.sh เพื่อให้กลายเป็นไฟล์ที่รันได้ จากนั้นทำการเช็คไฟล์ APK วิธีการใช้สคริปต์นี้ผมเห็นว่าแสดงผลได้ละเอียดเพราะจะแสดงไลบรารีในแอพนั้นที่ใช้มาทั้งหมด

pbrobo@pbrobo-ThinkPad-P52:~/scripts$ ./check_elf_alignment.sh /media/pbrobo/backupData/sourcecodes/dart_flutter/surveystar_quick_tm_branch_4/build/app/outputs/flutter-apk/app-debug.apk

Recursively analyzing /media/pbrobo/backupData/sourcecodes/dart_flutter/surveystar_quick_tm_branch_4/build/app/outputs/flutter-apk/app-debug.apk

NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher.
  You can install the latest build-tools by running the below command
  and updating your $PATH:

    sdkmanager "build-tools;35.0.0-rc3"

=== ELF alignment ===
/tmp/app-debug_out_NDws1/lib/arm64-v8a/libsqlite3.so: UNALIGNED (2**12)
/tmp/app-debug_out_NDws1/lib/arm64-v8a/libproj.so: UNALIGNED (2**12)
/tmp/app-debug_out_NDws1/lib/x86_64/libsqlite3.so: UNALIGNED (2**12)
/tmp/app-debug_out_NDws1/lib/x86_64/libproj.so: UNALIGNED (2**12)
/tmp/app-debug_out_NDws1/lib/x86_64/libflutter.so: ALIGNED (2**16)
/tmp/app-debug_out_NDws1/lib/x86/libsqlite3.so: UNALIGNED (2**12)
/tmp/app-debug_out_NDws1/lib/x86/libproj.so: UNALIGNED (2**12)
/tmp/app-debug_out_NDws1/lib/x86/libflutter.so: ALIGNED (2**16)
Found 6 unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).
=====================
pbrobo@pbrobo-ThinkPad-P52:~/scripts$ 

ตอนนี้ชัดเจนแล้วว่าไลบรารี libproj.so และ libsqlite3.so ไม่ผ่านเกณฑ์ (2**12)

คอมไพล์ PROJ 9.6.0

ต่อไปจะเป็นการคอมไพล์ libproj และ libsqlite3 โดยกลับไปใช้สคริปต์เก่า แต่ครั้งนี้จะไม่คอมไพล์เป็น armeabi-v7a และ X86 ที่เป็น 32 บิต คงไม่ได้ใช้กันอีกแล้ว ผมได้ตัดสินใจถอนการสนับสนุน ไม่มีการบิวท์ไปกับแอพรุ่นใหม่ ผมได้ดัดแปลงสคริปต์เก่า โดยตัด ccache (cache compiler) เนื่องจากสร้างความยุ่งยากให้ผม จากนั้นผมใส่ URL ของไฟล์ที่จะดาวน์โหลดเช่น PROJ ที่ปัจจุบันเป็นรุ่น 9.6.0 ไว้ในไฟล์สครปต์

และใช้ทูลส์ตัวใหม่คือ Cmake รุ่น 4.0.2 และ Android NDK รุ่น r28b ส่วนตัว Sqlite3 ผมเลือกใช้รุ่นเก่า รุ่น 3430100 รุ่นในขณะที่เขียนบทความคือ 3490200 เนื่องจากพบปัญหา ถ้าใช่รุ่นใหม่ เมื่อตอนรันแอพ libproj.so จะฟ้องว่าหาไลบรารี libsqlite3.so ไม่เจอ error แจ้งว่าไม่พบไฟล์ libsqlite3.so ที่ไดเรคทอรี “tmp/install/lib” ซึ่งเป็นปลายทางที่ผมคอนไพล์ไปเก็บไว้ อิหยังอะ งงจัดแต่ไม่มีเวลาตามแกะมากนัก อีกอย่าง libproj ใช้ libsqlite3 แค่อ่านเขียนไฟล์ proj.db ก็ไม่น่าจะมีอะไร

สคริปต์สำหรับคอมไพล์

ต่อไปมาดูสคริปต์ จะมีไฟล์ buildproj4_v8a.sh สำหรับคอมไพล์ไปใช้ในเครื่องแอนดรอยด์จริงๆ เมื่อผู้ใช้ติดตั้งแล้ว ส่วน buildproj4_x86_64.sh สำหรับคอมไพล์ใช้สำหรับอีมูเลเตอร์สำหรับผู้พัฒนาซึ่งก็หมายถึงผมเอง เริ่มจาก buildproj4_x86_64.sh

#!/bin/sh
### buildproj4_x86_64.sh ###

set -e

apt-get update -y

# pkg-config sqlite3 for proj compilation
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
    wget unzip ccache curl ca-certificates \
    pkg-config make binutils sqlite3 \
    automake

cd "$WORK_DIR"


# We need a recent cmake for recent NDK versions
wget -q https://github.com/Kitware/CMake/releases/download/v4.0.2/cmake-4.0.2-linux-x86_64.tar.gz
rm -rf cmake-4.0.2-linux-x86_64
tar xzf cmake-4.0.2-linux-x86_64.tar.gz
export PATH=$PWD/cmake-4.0.2-linux-x86_64/bin:$PATH

# Download Android NDK
wget -q https://dl.google.com/android/repository/android-ndk-r28b-linux.zip
rm -rf android-ndk-r28b
unzip -q android-ndk-r28b-linux.zip

export ANDROID_NDK=$PWD/android-ndk-r28b
export NDK_TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64


rm -rf /tmp/install

# build sqlite3
wget -q https://sqlite.org/2023/sqlite-autoconf-3430100.tar.gz
rm -rf sqlite-autoconf-3430100
tar xzf sqlite-autoconf-3430100.tar.gz
cd sqlite-autoconf-3430100
CC="$NDK_TOOLCHAIN/bin/x86_64-linux-android24-clang" ./configure \
  --prefix=/tmp/install --host=x86_64-linux-android24
make -j3
make install
cd ..

# Build proj
wget -q https://download.osgeo.org/proj/proj-9.6.0.tar.gz
rm -rf proj-9.6.0
tar xzf proj-9.6.0.tar.gz
cd proj-9.6.0
mkdir build
cd build
# See later comment in GDAL build section about MAKE_FIND_ROOT_PATH_MODE_INCLUDE, CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
cmake .. \
  -DUSE_CCACHE=ON \
  -DENABLE_TIFF=OFF -DENABLE_CURL=OFF -DBUILD_APPS=OFF -DBUILD_TESTING=OFF \
  -DCMAKE_INSTALL_PREFIX=/tmp/install \
  -DCMAKE_SYSTEM_NAME=Android \
  -DCMAKE_ANDROID_NDK=$ANDROID_NDK \
  -DCMAKE_ANDROID_ARCH_ABI=x86_64 \
  -DCMAKE_SYSTEM_VERSION=24 \
  "-DCMAKE_PREFIX_PATH=/tmp/install;$NDK_TOOLCHAIN/sysroot/usr/" \
  -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER \
  -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER \
  -DEXE_SQLITE3=/usr/bin/sqlite3
make -j3
make install
cd ../..

# Build GDAL, will be failed!!!! Becasue I don't use GDAL it is OK for me.
rm -rf build_android_cmake
mkdir build_android_cmake
cd build_android_cmake

# PKG_CONFIG_LIBDIR, CMAKE_FIND_ROOT_PATH_MODE_INCLUDE, CMAKE_FIND_ROOT_PATH_MODE_LIBRARY, CMAKE_FIND_USE_CMAKE_SYSTEM_PATH
# are needed because we don't install dependencies (PROJ, SQLite3) in the NDK sysroot
# This is definitely not the most idiomatic way of proceeding...
PKG_CONFIG_LIBDIR=/tmp/install/lib/pkgconfig cmake .. \
 -DUSE_CCACHE=ON \
 -DCMAKE_INSTALL_PREFIX=/tmp/install \
 -DCMAKE_SYSTEM_NAME=Android \
 -DCMAKE_ANDROID_NDK=$ANDROID_NDK \
 -DCMAKE_ANDROID_ARCH_ABI=x86_64 \
 -DCMAKE_SYSTEM_VERSION=24 \
 "-DCMAKE_PREFIX_PATH=/tmp/install;$NDK_TOOLCHAIN/sysroot/usr/" \
 -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER \
 -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER \
 -DCMAKE_FIND_USE_CMAKE_SYSTEM_PATH=NO \
 -DSFCGAL_CONFIG=disabled \
 -DHDF5_C_COMPILER_EXECUTABLE=disabled \
 -DHDF5_CXX_COMPILER_EXECUTABLE=disabled
make -j3
make install
cd ..

และ buildproj4_v8a.sh

#!/bin/sh
### buildproj4_v8a.sh ###

set -e
apt-get update -y

# pkg-config sqlite3 for proj compilation
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
    wget unzip ccache curl ca-certificates \
    pkg-config make binutils sqlite3 \
    automake

cd "$WORK_DIR"

# We need a recent cmake for recent NDK versions
wget -q https://github.com/Kitware/CMake/releases/download/v4.0.2/cmake-4.0.2-linux-x86_64.tar.gz
tar xzf cmake-4.0.2-linux-x86_64.tar.gz
rm -rf cmake-4.0.2-linux-x86_64
export PATH=$PWD/cmake-4.0.2-linux-x86_64/bin:$PATH

# Download Android NDK
wget -q https://dl.google.com/android/repository/android-ndk-r28b-linux.zip
rm -rf android-ndk-r28b
unzip -q android-ndk-r28b-linux.zip

export ANDROID_NDK=$PWD/android-ndk-r28b
export NDK_TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64


rm -rf /tmp/install
# build sqlite3
wget -q https://sqlite.org/2023/sqlite-autoconf-3430100.tar.gz
rm -rf sqlite-autoconf-3430100
tar xzf sqlite-autoconf-3430100.tar.gz
cd sqlite-autoconf-3430100
CC="$NDK_TOOLCHAIN/bin/aarch64-linux-android24-clang" ./configure \
  --prefix=/tmp/install --host=aarch64-linux-android24
make -j3
make install
cd ..

# Build proj
wget -q https://download.osgeo.org/proj/proj-9.6.0.tar.gz
rm -rf proj-9.6.0
tar xzf proj-9.6.0.tar.gz
cd proj-9.6.0
mkdir build
cd build
# See later comment in GDAL build section about MAKE_FIND_ROOT_PATH_MODE_INCLUDE, CMAKE_FIND_ROOT_PATH_MODE_LIBRARY
cmake .. \
  -DUSE_CCACHE=ON \
  -DENABLE_TIFF=OFF -DENABLE_CURL=OFF -DBUILD_APPS=OFF -DBUILD_TESTING=OFF \
  -DCMAKE_INSTALL_PREFIX=/tmp/install \
  -DCMAKE_SYSTEM_NAME=Android \
  -DCMAKE_ANDROID_NDK=$ANDROID_NDK \
  -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \
  -DCMAKE_SYSTEM_VERSION=24 \
  "-DCMAKE_PREFIX_PATH=/tmp/install;$NDK_TOOLCHAIN/sysroot/usr/" \
  -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER \
  -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER \
  -DEXE_SQLITE3=/usr/bin/sqlite3
make -j3
make install
cd ../..

# Build GDAL, it will be failed!!!!!! I don't use GDAL so this is OK.
rm -rf build_android_cmake
mkdir build_android_cmake
cd build_android_cmake

# PKG_CONFIG_LIBDIR, CMAKE_FIND_ROOT_PATH_MODE_INCLUDE, CMAKE_FIND_ROOT_PATH_MODE_LIBRARY, CMAKE_FIND_USE_CMAKE_SYSTEM_PATH
# are needed because we don't install dependencies (PROJ, SQLite3) in the NDK sysroot
# This is definitely not the most idiomatic way of proceeding...
PKG_CONFIG_LIBDIR=/tmp/install/lib/pkgconfig cmake .. \
 -DUSE_CCACHE=ON \
 -DCMAKE_INSTALL_PREFIX=/tmp/install \
 -DCMAKE_SYSTEM_NAME=Android \
 -DCMAKE_ANDROID_NDK=$ANDROID_NDK \
 -DCMAKE_ANDROID_ARCH_ABI=arm64-v8a \
 -DCMAKE_SYSTEM_VERSION=24 \
 "-DCMAKE_PREFIX_PATH=/tmp/install;$NDK_TOOLCHAIN/sysroot/usr/" \
 -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER \
 -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER \
 -DCMAKE_FIND_USE_CMAKE_SYSTEM_PATH=NO \
 -DSFCGAL_CONFIG=disabled \
 -DHDF5_C_COMPILER_EXECUTABLE=disabled \
 -DHDF5_CXX_COMPILER_EXECUTABLE=disabled
make -j3
make install
cd ..

วิธีการใช้งาน สร้างไดเรคทอรีเปล่าๆสำหรับไฟล์สองคริปต์นี้ แล้ว copy ไฟล์นี้ไปใส่ เปิด terminal มาทำการรันดังคำสั่งถัดไป

pbrobo@pbrobo-ThinkPad-P52:~/buildProj4$ sudo ./buildproj4_v8a.sh
pbrobo@pbrobo-ThinkPad-P52:~/buildProj4$ sudo ./buildproj4_x86_64.sh

เมื่อรันสคริปต์แต่ละครั้งจะมี error เกิดขึ้นตอนท้ายๆ เพราะสคริปต์พยายามสร้างไลบรารีสำหรับ GDAL ซึ่งสคริปต์นี้ผมเอามาจากท่านอื่นแต่ไม่ได้ลบในส่วนนี้ออก

CMake Error: The source directory "/home/pbrobo/buildProj4" does not appear to contain CMakeLists.txt.
Specify --help for usage, or press the help button on the CMake GUI.

การทดสอบไลบรารีก่อนนำไปใช้งาน

ผลลัพธ์คือไลบรารี libproj.so และ libsqilte3.so จะถูกจัดเก็บชั่วคราวที่ไดเรคทอรี “/tmp/install” ต่อไปจะทดสอบว่าสองไลบรารีนี้จะผ่านข้อกำหนดกูเกิ้ลหรือไม่ ผมจะทำการทดสอบด้วยคำสั่ง llvm-objdump ได้ผลลัพธ์ 2**14 ซึ่งผ่าน

pbrobo@pbrobo-ThinkPad-P52:/tmp/install/lib$ llvm-objdump -p libproj.so | grep LOAD
    LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**14
    LOAD off    0x000000000043ca10 vaddr 0x0000000000440a10 paddr 0x0000000000440a10 align 2**14
    LOAD off    0x00000000004607c0 vaddr 0x00000000004687c0 paddr 0x00000000004687c0 align 2**14
pbrobo@pbrobo-ThinkPad-P52:/tmp/install/lib$ llvm-objdump -p libsqlite3.so | grep LOAD
    LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**14
    LOAD off    0x000000000003e0ec vaddr 0x00000000000420ec paddr 0x00000000000420ec align 2**14
    LOAD off    0x0000000000170a90 vaddr 0x0000000000178a90 paddr 0x0000000000178a90 align 2**14
    LOAD off    0x0000000000173560 vaddr 0x000000000017f560 paddr 0x000000000017f560 align 2**14
pbrobo@pbrobo-ThinkPad-P52:/tmp/install/lib$ 

แค่นี้ก็เพียงพอจะนำไปใช้งานได้ จากนั้นทำการคัดลอกไฟล์ที่ได้ไปใช้งาน

และผมยัง copy สองไดเรคทอรีคือ share และ include ไปด้วย

การนำไลบรารีที่คอมไพล์แล้วไปใช้งาน

สำหรับปลายทางที่ผมเอาไปใช้ในโครงการที่พัฒนาด้วยภาษาดาร์ท (Dart) ขึ้น UI ด้วย Flutter พัฒนาใน VS Code ผมมี package ชื่อ proj4 แล้วเอาไฟล์ที่ได้ไปใส่ให้ถูกที่ดังรูป ไม่งั้นแอพจะหาไลบรารีไม่เจอ

ทดสอบ APK

ผมบิวท์แอพด้วยคำสั่ง flutter build apk เพื่อเอาไฟล์ apk มาทดสอบด้วยสคริปต์ check_elf_alignment.sh ได้ผลดังนี้

pbrobo@pbrobo-ThinkPad-P52:~/scripts$ ./check_elf_alignment.sh /media/pbrobo/Dev/dev/dart/surveystar_quick_tm_branch_5/build/app/outputs/flutter-apk/app-release.apk

Recursively analyzing /media/pbrobo/Dev/dev/dart/surveystar_quick_tm_branch_5/build/app/outputs/flutter-apk/app-release.apk

NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher.
  You can install the latest build-tools by running the below command
  and updating your $PATH:

    sdkmanager "build-tools;35.0.0-rc3"

=== ELF alignment ===
/tmp/app-release_out_Z2WF3/lib/arm64-v8a/libapp.so: ALIGNED (2**16)
/tmp/app-release_out_Z2WF3/lib/arm64-v8a/libsqlite3.so: ALIGNED (2**14)
/tmp/app-release_out_Z2WF3/lib/arm64-v8a/libdatastore_shared_counter.so: ALIGNED (2**14)
/tmp/app-release_out_Z2WF3/lib/arm64-v8a/libproj.so: ALIGNED (2**14)
/tmp/app-release_out_Z2WF3/lib/arm64-v8a/libflutter.so: ALIGNED (2**16)
/tmp/app-release_out_Z2WF3/lib/x86_64/libapp.so: ALIGNED (2**16)
/tmp/app-release_out_Z2WF3/lib/x86_64/libsqlite3.so: ALIGNED (2**14)
/tmp/app-release_out_Z2WF3/lib/x86_64/libdatastore_shared_counter.so: ALIGNED (2**14)
/tmp/app-release_out_Z2WF3/lib/x86_64/libproj.so: ALIGNED (2**14)
/tmp/app-release_out_Z2WF3/lib/x86_64/libflutter.so: ALIGNED (2**16)
ELF Verification Successful
=====================
pbrobo@pbrobo-ThinkPad-P52:~/scripts$ 

จะเห็นว่าไฟล์ไลรารี libproj.so และ libsqlite3.so ในไดเรคทอรี lib/arm64-v8a/ และ lib/x86_64 นั้นผ่านแล้ว (2**14) แสดงว่าผ่านข้อกำหนดของกูเกิ้ลแล้ว

ในบรรณพิภพนี้คงหาไลบรารีไหนที่จะมาวัดกับ PROJ ตัวต่อตัวได้เนื่องจากพัฒนามายาวนานหลายสิบปีที่อาศัยคนระดับหัวกะทิมาช่วยกันพัฒนาและยังเปิดซอร์สอีก ส่งผลให้โปรแกรมเปิดซอร์สอื่นๆเช่น QGIS ที่นำไลบรารีไปใช้ในการแปลงระบบพิกัดต่างๆทั้งโลก การแปลงรูปจากระบบพิกัดหนึ่งไปอีกพิกัดหนึ่งก็เช่นเดียวกันถึงแม้ส่วนนี้จะใช้ไลบรารี GDAL แต่ GDAL ก็ใช้ PROJ อยู่ดี

ทำให้นักพัฒนาเช่น QGIS ไม่ต้องมาเสียเวลากับเรื่องนี้เพราะว่า PROJ จัดการให้หมด ทำให้ QGIS เป็นโปรแกรมเปิดซอร์สที่ผมยังใช้อยู่ในปัจจุบัน และก็ดีมากๆ ตัวอย่างสามารถเปิดรูป orthophoto ขนาด 32 GB ได้แบบสบายๆ จะเปิดแบบไดรว์ส่วนตัวหรือจะเปิดผ่านไดรว์ NAS ก็ไม่เกี่ยง ถ้าเอาไฟล์ขนาดนี้มาเปิดในโปรแกรม CAD ไม่ว่าค่ายไหน เดี้ยงทันที จอดไม่ต้องแจวกันเลย

Rust & PROJ

เนื่องจากผมใช้ภาษา Rust ก่อนหน้านี้ผมลองไลบรารีหรือเครท (crate) Geodesy แต่พบว่าไปไม่สุดซอย จำใจต้องกลับมาหาเพื่อนเก่า PROJ เหมือนเดิม ถึงแม้จะมีคนสร้าง crate ชื่อ “proj” และ “proj-sys” มาให้ก็ตาม แต่การ config เพื่อคอมไพล์ไลบรารีมาใช้กับ Rust บน Desktop PC ไม่ได้ตรงไปตรงมา คือหาเอกสารอ่านได้น้อย ผมลองผิดลองถูกอยู่นานพอสมควร

ตอนหน้าอาจจะมาว่าด้วยเรื่องการคอมไพล์ PROJ เพื่อใช้กับ Rust และอนาคตอาจจะยาวไปถึงขั้นเอาไปใช้บนแอนดรอยด์กับ Rust ผ่านแพลตฟอร์มเช่น Dioxus หรืออาจจะเป็น Slint ก็เป็นได้ โปรดติดตามกันตอนหน้าครับ

Leave a Reply

Your email address will not be published. Required fields are marked *