Thursday, January 19, 2023

Compile fanvanzh's 3dtiles in Linux

Working for fanvanzh's 3dtiles Linux compilation for days. Some items for reminding everybody how wants to do the same thing.

liwei0705 did a good move in making fanvanzh's 3dtiles converter works. But if you are using a new version of OSG and GDAL, pay attention to the following summarised reminders when building your own version of "_3dtile"

  • Delete 3dtiles/bin, it is for windows only
  • Compile your own OpenSceneGraph
    • Copy OpenSceneGraph /lib to 3dtiles
    • Copy OpenSceneGraph /include/* to 3dtiles/src/osg/*
  • If not compile OpenSceneGraph on your own, you can install "openscenegraph" and "libopenscenegraph-dev" instead
    • Delete /lib in 3dtiles (the /lib is for self-compiled OSG, GDAL actually)
    • Delete 3dtiles/src/osg/ (no need to provide OSG header, use the one in libopenscenegraphi-dev)
    • Install gdal-bin, libgdal-dev
      • rm -rf 3dtiles/src/gdal (we will use libraries and header by gdal-bin and libgdal-dev)

    • Source file: src/tileset.cpp
      • Hide up #ifdef _WIN32, turn on "epsg_convert" and "wkt_convert"
      • Comment out GDAL_DATA: 
        • // CPLSetConfigOption("GDAL_DATA", path);

    • For epsg_convert( )
      • Don't use importFromEPSG(), use:
        • // For 2326 Input (Hard code the input SRS) (Ref)
        • inRs.importFromProj4("+proj=tmerc +lat_0=22.3121333333333 +lon_0=114.178555555556 +k=1 +x_0=836694.05 +y_0=819069.8 +ellps=intl +towgs84=-162.619,-276.959,-161.764,-0.067753,2.243648,1.158828,-1.094246 +units=m +no_defs +type=crs");
        • // for 4326 Output (Hard code the output SRS) (Ref)
        • outRs.importFromProj4("+proj=longlat +datum=WGS84 +no_defs +type=crs");

    • Source file: src/earcut.hpp
      • Add header files
        • #include <stdexcept>
        • #include <limits>

    • Source file: build.rs
      • In linux bulid config, add:
        • println!("cargo:rustc-link-lib=gdal");

    • When running the ./target/release/_3dtile
      • export LD_LIBRARY_PATH=./lib

    • Side notes, if you use "cargo run" for debugging and when to rebuild the project when some CPP files are modified, add the following in linux build config (build.rs): (reference)
      • println!("cargo:rerun-if-changed=./src/tileset.cpp");


    Thursday, August 11, 2022

    Setup autostart services in Linux with SELinux


    1) Create your start / stop script in a predefined directory (e.g. /development/service-script/ )

    • /development/service-script/start-cmd
    • /development/service-script/stop-cmd

    2) Allow SELinux to execute binaries in the predefined directory /development/service-script/ (!! important for SELinux)

        chcon -R -t bin_t /development/service-script/


    3) Create abc.service in /etc/systemd/system/

        # Systemd unit file for ABC service

        [Unit]
     
        Description=ABC service
        After=syslog.target network.target

        [Service]
        Type=forking

        ExecStart=/development/service-script/start-cmd
        ExecStop=/development/service-script/stop-cmd

        User=service_owner
        Group=service_owner
        UMask=0007
        RestartSec=10
        Restart=always

        [Install]
        WantedBy=multi-user.target


    4) Reload systemd

        systemctl daemon-reload

    5) Start ABC service

        systemctl start abc


    6) If ABC service is working, then we can enabled it for autostart

        systemctl enable abc



    Wednesday, August 10, 2022

    NO_PUBKEY when updating QGIS in Linux / Ubuntu (2022)

    Update the key file (qgis-archive.gpg) by:


    wget  -qO  -  https://qgis.org/downloads/qgis-2022.gpg.key  |  gpg  --no-default-keyring  --keyring  gnupg-ring:/etc/apt/trusted.gpg.d/qgis-archive.gpg  --import


    The NO_PUBKEY error message will be gone for 'apt update'


    Sunday, June 5, 2022

    Separated dock for multiple workspace in Ubuntu

    Separated dock for multiple workspace in Ubuntu, set the following to be true:

    gsettings set org.gnome.shell.extensions.dash-to-dock isolate-workspaces true

    Sunday, May 29, 2022

    Skip basic authentication headers before passing a request to proxypass target host

    This can be done via "RequestHeader unset Authorization" 


    <Location "/some_path">

        Require all granted

        ProxyPass https://target-host

        RequestHeader unset Authorization

    </Location>


    Reference: 1, 2

    Monday, January 24, 2022

    Extract PDF content (from CHP) with Python

    import re

    import sys

    import urllib.request

    import pdfplumber

    import pandas as pd



    if (len(sys.argv) < 2):

        print("\n\nSyntax: python extract_pdf.py date_string (e.g. 20220124) \n\n")

        exit()


    def main():    

        date_string  = sys.argv[1] # e.g. 20220124

        pdf_file_name = f"ctn_{date_string}.pdf" # PDF from CHP: https://www.chp.gov.hk/files/pdf/ctn_20220124.pdf

        #download_pdf( pdf_file_name )

        extract_pdf( pdf_file_name )



    def extract_pdf( pdf_file_name ):

        with pdfplumber.open( f"./pdf/{pdf_file_name}" ) as pdf:

            for page in pdf.pages:

                #print(page)

                for table in page.extract_tables():

                    df = pd.DataFrame(table[1:], columns=table[0])

                    for index, row in df.iterrows():

                        if (isinstance(row[0], str) and len(row[0])>0):

                            rowid = row[0].replace(".","")

                            title = row[1].split("\n")

                            for i in range(0,len(title)):                            

                                if (re.search(u'[\u4e00-\u9fff]', title[i]) is None):

                                    title[i] = ""

                            print(rowid, "".join(title))


    def download_pdf ( pdf_file_name ) :

        pdfFile = urllib.request.urlopen(f"https://www.chp.gov.hk/files/pdf/{pdf_file_name}")

        file = open(f"./pdf/{pdf_file_name}", "wb")

        file.write(pdfFile.read())

        file.close()



    main()

    Display cx_oracle error indicating which rows are affected

    cursor.executemany("SQL EXEC STATEMENT", data, batcherrors=True)

    for error in cursor.getbatcherrors():

        print("Error", error.message, "at row offset", error.offset) 



    Sunday, January 23, 2022

    Calculate the viewing location in Cesium

     Here I summarise two approach for calculating the viewing location in Cesium viewer:


    Method 1 (using Camera.computeViewRectangle() method) 


    var projection = new Cesium.WebMercatorProjection();

    var rect = new Cesium.Rectangle()

    viewer.camera.computeViewRectangle(projection.ellipsoid, rect)


    let rect_x = (rect.east - rect.west)/2 + rect.west;

    let rect_y = (rect.north - rect.south)/2 + rect.south;


    var rect_lon = Cesium.Math.toDegrees(rect_y);

    var rect_lat = Cesium.Math.toDegrees(rect_x);


    console.log(rect_lat, rect_lon)


    Note: The computeViewRectangle( ) could be very large when the view pitch is very flat, resulting in a very far point being calculated.


    Method 2 (using Camera.computeViewRectangle() method) 


    var cc = document.getElementById("cesiumContainer");

    var screenCenterPt = new Cesium.Cartesian2(cc.offsetWidth/2, cc.offsetHeight/2);

    var pick = viewer.scene.globe.pick(viewer.camera.getPickRay(screenCenterPt), viewer.scene);

    if (pick) {

      var geoPt = viewer.scene.globe.ellipsoid.cartesianToCartographic(pick);

      var point = [geoPt.longitude/ Math.PI * 180, geoPt.latitude/ Math.PI * 180];

      

      var rect_lon = point[0];

      var rect_lat = point[1];

      

      console.log(rect_lat, rect_lon);

    }


    Note: It uses screen center to calculate the point, seems to be more useful.

    Thursday, January 6, 2022

    DOS batch file: Expand * into list of filenames in command line

    expand-wildcard.bat

    @echo off

    setlocal EnableDelayedExpansion


    set params=command

    for %%a in ("%~1") do (

        set params=!params! %%a

    )


    echo %params%

    %params%

     

    Then, running the following command:

    C:\>expand-wildcard filename*


    Will be executed as following:

    C:\>command filename1 filename2 filename3 filename4 ..

    CSP on Apache

    To add CSP to root if sort of funny. The following will NOT work for most cases !!     <LocationMatch "^/$">        Header s...