Author: kanakorn.h

  • Spark #04 – Pyspark connect to MySQL

    ในบทความนี้ จะกล่าวถึง การดึงข้อมูลจาก MySQL ผ่าน JDBC เพื่อนำมาใช้งานใน Spark ด้วยภาษา Python ซึ่งจะใช้ Library Pyspark

    ในขั้นตอนนี้ขอกล่าวเฉพาะวิธีการก่อน (รายละเอียดจะตามมาทีหลัง)

    1. สร้าง SparkSession ตั้งชื่อว่า myspark
      from pyspark.sql import SparkSession
      myspark = SparkSession \
       .builder \
       .appName("Python Spark SQL basic example") \
       .config("spark.some.config.option", "some-value") \
       .getOrCreate()
    2. ติดต่อ MySQL และสร้าง View ชื่อ myuser
      myuser=myspark.read.jdbc(url="jdbc:mysql://mysql/mysql",table="user", properties={
       'user': 'user1', 'password': '123456'}
       )
      myuser.createOrReplaceTempView(name="myuser")
    3. จากนั้นก็จะสามารถ Query ข้อมูลที่เก็บไว้มาใช้งานใน Spark ได้
      myspark.sql(sqlQuery="select user,host from myuser where user='user1'").show()

    ซึ่งต่อจากนี้ จะสามารถใช้ความสามารถของ Spark ซึ่งทำงานด้าน Distributed Computing ได้ดี มาปรับปรุงความเร็วในการ Query ที่ซับซ้อน เช่นการ JOIN ได้ โดยจะกล่าวในบทความต่อๆไป

  • Machine Learning #01 – Python with iris dataset

    ในบทความนี้ จะแนะนำวิธีการสร้างกระบวนการ Machine Learning ด้วย Python โดยใช้ iris dataset ตั้งแต่การโหลดข้อมูล, สร้าง  Model,  Cross Validation, วัด Accuracy และการนำ Model ไปใช้งาน

    เพื่อความสะดวกในการเรียนรู้ เราจะเลือกใช้ Anaconda ซึ่งเป็น Python Data Science Platform ซึ่งจะรวบรวมเครื่องมือ และ Library ที่จำเป็นต่อการพัฒนา โดยสามารถเลือก Download รุ่นที่เหมาะกับระบบปฏบัติการของท่านได้ที่ https://www.anaconda.com/download/

    สามารถ Clone Repository ตัวอย่างทั้งหมดที่กล่าวถึงในบทความนี้ได้จาก https://github.com/nagarindkx/pythonml

    และ แนะนำให้ใช้งาน jupyter-notebook เพื่อสะดวกในการเรียนรู้

    บทความนี้ใช้ Notebook: 01 – SVM with iris dataset.ipynb

     

    เริ่มจาก import dataset “iris” จาก SciKit

    ซึ่งเป็น dataset ตัวอย่างทีดี ในการสร้างระบบ Predict ชนิดของดอกไม้ จากการป้อนค่า ความกว้างและความยาวของกลีบดอก Iris (รายละเอียดอ่านได้จาก https://en.wikipedia.org/wiki/Iris_flower_data_set) ซึ่งเป็นการวัดความกว้าง และ ความยาวของกลีบดอก ของดอก “iris” (sepal width, sepal length, petal width, petal length) ใน 3 Spicy

    Image Source: https://en.wikipedia.org/wiki/Iris_flower_data_set

    ชุด iris dataset นี้ มักจะใช้ในการเริ่มต้นเรียนรู้ กระบวนการสร้าง Machine Learning เพื่อการ Classification โดยในตัวอย่างนี้จะใช้ Support Vector Machine (SVM) โดยเมื่อสร้างและ Train Model เสร็จแล้ว สามารถนำ Model นี้ไปใช้ในการ จำแนก Species ได้ โดยการระบุ ความกว้างและความยาวดังกล่าว แล้วระบบจะตอบมาได้ว่า เป็น Species ใด

    ในการเริ่มต้นนี้ เราจะใช้ iris dataset ที่มาพร้อมกับ SciKit  (sklearn) ซึ่งเป็น Machine Learning Package ในภาษา Python (ซึ่งติดตั้งมาในชุดของ Anaconda เรียบร้อยแล้ว)

    นำเข้าข้อมูล

    from sklearn import datasets
    iris = datasets.load_iris()

    สำรวจข้อมูล

    print(iris.data)
    print(iris.target)
    print(iris.data.shape)
    print(iris.target.shape)

    ใช้งาน SVM (Support Vector Machine)

    สร้าง SVC (Support Vector Classification) เพื่อทำการ Training ด้วยคำสั่ง fit โดยใส่ค่า data และ target ลงไป

    from sklearn import svm
    clf = svm.SVC()
    clf.fit(iris.data, iris.target)
    

    ผลที่ได้คือ

    SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
      decision_function_shape=None, degree=3, gamma='auto', kernel='rbf',
      max_iter=-1, probability=False, random_state=None, shrinking=True,
      tol=0.001, verbose=False)

    ทดลองทำการ Predict

    ด้วยคำสั่ง predict แล้วใส่ Array ข้อมูลลงไป

    print(clf.predict([[ 6.3 , 2.5, 5., 1.9]]))

    ซึ่งระบบจะตอบออกมาเป็น

    [2]

    ต้องการแสดงผลเป็นชื่อของ Target

    ต้องทำในขั้นตอน fit ดังนี้

    clf.fit(iris.data, iris.target_names[ iris.target])
    print(clf.predict([[ 6.3 , 2.5, 5., 1.9]]))

    ผลที่ได้คือ

    ['virginica']

    ทำการ Cross Validation

    โดยแบ่งข้อมูลเป็นสองส่วน คือ ส่วน Train และ Test ทั้ง X และ Y จากนั้น ใช้ Function “fit” ในการ Train

    from sklearn.model_selection import train_test_split
    x_train,x_test,y_train, y_test = train_test_split( iris.data, iris.target, test_size=0.4 , random_state=0)
    
    print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)
    
    clf.fit(x_train, y_train)

    ผลที่ได้คือ

    (90, 4) (60, 4) (90,) (60,)
    SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
    decision_function_shape=None, degree=3, gamma='auto', kernel='rbf', max_iter=-1, probability=False, random_state=None, shrinking=True, tol=0.001, verbose=False)

    ทดสอบความแม่นยำ

    ด้วยการ นำข้อมูลส่วน Test ไปทดสอบใน Model ด้วย Function “score”

    print(clf.score(x_test, y_test))

    ผลที่ได้คือ

    0.95

    นำ Model ที่สร้างเสร็จไปใช้ต่อ

    ใช้กระบวนการ pickle หรือ serialization

    import pickle
    pickle.dump(clf, open("myiris.pickle","wb"))

    ซึ่ง ก็จะได้ไฟล์ “myiris.pickle” สามารถนำไปใช้งานต่อได้

    ในบทความต่อไป จะกล่าวถึง การนำ Model นี้ไปใช้งานผ่าน django REST Framework

  • การใช้ GitHub Command Line #newbie

    Prerequisite

    • ต้องมี GitHub Account ก่อน ทำตามวิธีการนี้ https://help.github.com/articles/signing-up-for-a-new-github-account/
    • สร้าง GitHub Repository บน Web ก่อน  (ในที่นี้ จะสร้าง Repository ชื่อ mynewrepo) ซึ่งจะได้ URL มาเป็น https://github.com/your-username/mynewrepo.git

    สร้าง local repository

    mkdir mynewrepo
    cd mynewrepo
    git init
    git status

    สร้างไฟล์ใหม่

    # สมมุติสร้างไฟล์ใหม่
    echo "Hello World" > mynewfile.txt
    git add .
    git status

    ทำการ Commit

    git commit -m "This is a first Commit"

    สร้าง Connection ระหว่าง Local Folder กับ GitHub Repository

    git remote add origin https://github.com/your-username/mynewrepo.git
    git push -u origin master

    จากนั้น ใส่ Username/Password ของ GitHub Account

    ไปดูผลงานใน Repository “mynewrepo” ที่ https://github.com/your-username/mynewrepo

    เมื่อมีการแก้ไขไฟล์

    echo "Hello New World" >> mynewfile.txt
    git status

    ทำการ เพิ่ม > Commit > Push

    git add .
    git commit -m "This is a second Commit"
    git push -u origin master

    วนไป

     

  • วิธียกเลิก “Keep a local copy as well” บน PSU Webmail

    จากที่เริ่มมีการใช้งาน PSU GSuite (Google Apps for Education – GAFE เดิม) ซึ่งมีเอกสารแนะนำวิธีการใช้งานคือ

    http://gafe.psu.ac.th/support/1/1

    ในช่วงแรก เกรงผู้ใช้จะไม่คุ้นชินกับ Gmail (หึมมมม) ก็เลยแนะนำให้ทำ “Keep a local copy as well” ไว้ด้วย เผื่อว่า ยังสับสน ก็จะได้ดูบน PSU Webmail เดิมได้

    แต่ต่อมา ก็อาจจะลืมไปว่า Redirect ไปแล้ว ก็ยังมีเก็บไว้ในพื้นที่ PSU Webmail อยู่ ไม่ได้เข้ามาลบอีกเลย นานเข้าก็ทำให้พื้นที่เต็ม

    ต่อไปนี้ เป็น วิธียกเลิก “Keep a local copy as well” บน PSU Webmail

    1. Login เข้า PSU Webmail ที่ https://webmail.psu.ac.th
    2. ลบ Email จนได้พื้นที่เป็นสีเขียว
      จาก

      เป็น
    3. คลิก Filters
    4. คลิก Edit ในบรรทัดที่เป็นของ @g.psu.ac.th
    5. คลิก Keep a local copy as well ออก
      จาก

      เป็น
    6. เลื่อนไปล่างสุดของหน้าจอ คลิกปุ่ม Apply Change
    7. เสร็จ จบ
  • ELK #6 วิธีการติดตั้ง ELK และ Geoserver แบบ Docker ให้ทำงานร่วมกัน

    จาก ELK #5 การประยุกต์ใช้ ELK ในงานด้าน GIS และ การสร้าง Web Map Service (WMS) บน Geoserver ก็จะเห็นถึงการนำไปใช้เบื้องต้น

    >> ขอบคุณ คุณนพัส กังวานตระกูล สถานวิจัยสารสนเทศภูมิศาสตร์ทรัพยากรธรรมชาติและสิ่งแวดล้อม ศูนย์ภูมิภาคเทคโนโลยีอวกาศและภูมิสารสนเทศ (ภาคใต้) สำหรับความรู้มากมายครับ <<

     

    ต่อไปนี้ จะเป็นขั้นตอนการติดตั้ง ELK และ Geoserver แบบ Docker โดยผมได้สร้าง Github Repository เอาไว้ ซึ่งได้แก้ไขให้ระบบสามารถเก็บข้อมูลไว้ภายนอก

    Prerequisite

    1. ถ้าเป็น Windows ก็ต้องติดตั้ง Docker Toolbox หรือ Docker for Windows ให้เรียบร้อย
    2. ถ้าเป็น Linux ก็ติดตั้ง docker-ce ให้เรียบร้อย (เรียนรู้เกี่ยวกับ Docker ได้จาก ติดตั้ง docker 17.06.0 CE บน Ubuntu)

    ขั้นตอนการติดตั้ง

    1. สร้าง Folder ชื่อ Docker เอาไว้ในเครื่อง เช่นใน Documents หรือ จะเป็น D:\ หรืออะไรก็แล้วแต่
    2. เปิด Terminal หรือ Docker Quickstart Terminal จากนั้นให้ cd เข้าไปมา Folder “Docker” ที่สร้างไว้
    3. ดึง ELK ลงมา ด้วยคำสั่ง
      git clone https://github.com/deviantony/docker-elk.git
    4. ดึง Geoserver ลงมา ด้วยคำสั่ง (อันนี้ผมทำต่อยอดเค้าอีกทีหนึ่ง ต้นฉบับคือ https://hub.docker.com/r/fiware/gisdataprovider/)
      git clone https://github.com/nagarindkx/geoserver.git
    5. เนื่องจาก ไม่อยากจะไปแก้ไข Git ของต้นฉบับ เราจึงต้องปรับแต่งนิดหน่อยเอง
      ให้แก้ไขไฟล์ docker-elk/docker-compose.yml
      โดยจะเพิ่ม Volume  “data” เพื่อไป mount ส่วนของ data directory ของ Elasticsearch ออกมาจาก Containerแก้ไขจาก

      elasticsearch:
       build: elasticsearch/
       volumes:
       - ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

      เป็น

      elasticsearch:
       build: elasticsearch/
       volumes:
       - ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
       - ./elasticsearch/data:/usr/share/elasticsearch/data
    6. สร้าง docker-elk/elasticsearch/data
      mkdir docker-elk/elasticsearch/data
    7. แก้ไขไฟล์ docker-elk/logstash/pipeline/logstash.conf ตามต้องการ เช่น ใส่ filter
      filter {
       csv {
         separator => ","
         columns => [
      	"cid","name","lname","pid","house","road","diagcode","latitude","longitude","village","tambon","ampur","changwat"
         ]
       }
       if [cid] == "CID" {
         drop { }
       } else {
         # continue processing data
         mutate {
           remove_field => [ "message" ]
         }
         mutate {
           convert => { "longitude" => "float" }
           convert => { "latitude" => "float" }
         }
         mutate {
           rename => {
             "longitude" => "[geoip][location][lon]"
             "latitude" => "[geoip][location][lat]"
           }
         }
       }
      }
    8. จาก Terminal ให้เข้าไปใน docker-elk แล้ว start ด้วยคำสั่ง
      cd docker-elk
      docker-compose up -d
    9. จาก Terminal ให้เข้าไปใน geoserver แล้ว start ด้วยคำสั่ง
      cd ../geoserver
      docker-compose up -d

    ถึงขั้นตอนนี้ ก็จะได้ ELK และ Geoserver ทำงานขึ้นแล้ว

    ELK: http://localhost:5601

    Geoserver: http://localhost:9090/geoserver/web

     

    ขั้นตอนต่อไป จะเป็นการ นำข้อมูลเข้า และ เชื่อ Kibana กับ Geoserver

    วิธีการนำข้อมูลเข้า Elasticsearch

    เนื่องจาก pipeline ของ Logstash กำหนดว่า จะรับข้อมูลทาง TCP Port 5000 จึงใช้วิธี netcat ไฟล์เข้าไป ด้วยคำสั่ง (ตัวอย่างนี้ ใช้ข้อมูลจากไฟล์ sample.csv)

    cat sample.csv | nc localhost 5000

    วิธีการดึง Map จาก Geoserver มาใช้งานใน Kibana

    ทำตามขั้นตอนที่กล่าวไว้ใน การสร้าง Web Map Service (WMS) บน Geoserver ซึ่งจะได้ URL ของ Layer Preview มา ประมาณนี้
    http://localhost:9090/geoserver/test/wms?service=WMS&version=1.1.0&request=GetMap&layers=test:hadyai_vil&styles=&bbox=631866.963048935,748605.6609660918,677997.0295239205,791055.6681053439&width=768&height=706&srs=EPSG:32647&format=application/openlayers

    ทำตามขั้นตอนที่กล่าวไว้ใน ELK #5 การประยุกต์ใช้ ELK ในงานด้าน GIS ในส่วนของ วิธีใส่ Map Server อื่น แล้วเอา URL นี้ไปใส่ และรายละเอียดเกี่ยวกับ Layer, version, format ตามที่กำหนดไว้ ก็จะสามารถเอา Map ที่เราต้องการ พร้อม Shape File มาใช้งานได้

    หวังว่าจะเป็นประโยชน์ครับ

  • วิธีการ Upload ไฟล์ไปบน Google Drive File Stream ด้วย Google Client Library for Python

    Google Drive File Stream จริงๆแล้วก็คือการเปิดให้ PC ทั้ง Windows และ Mac สามารถ Map Drive จาก Google Drive มาเป็น G:\ หรืออะไรทำนองนั้น แต่ปัจจุบัน (September 2017) บน Windows Server ซึ่งใช้ Secure Boot จะไม่สามารถติดตั้ง Client ได้ และ Ubuntu Server ก็ยังไม่มีตัวติดตั้ง ดังนั้น ในภาพของผู้ดูแลระบบ ไม่สามารถใช้ความสามารถนี้ได้ … โดยตรง

    ส่วนใน Windows Desktop ทั่วไปก็จะติดตั้งได้ แม้ว่า จากคำโฆษณา จะบอกว่าผู้ใช้สามารถใช้งานได้ แม้พื้นที่บน Local Drive ไม่เยอะ แต่เอาเข้าจริง ด้วยความสามารถที่จะใช้งาน Offline ได้บ้าง ทำให้ Client ต้อง Cache ไฟล์ที่ใช้งานด้วยเช่นกัน และหาก upload ไฟล์ขนาดใหญ่ จาก Local Drive ไปเก็บใน G:\ ข้างต้น ก็จะทำให้ต้องเสียพื้นที่ในขนาดเท่าๆกันไปด้วย เช่น ใน Local Drive มีไฟล์ที่จะ Backup ขึ้นไป ขนาด 1 GB บน C:\ เมื่อทำการ Copy ไปยัง G:\ ก็จะเสียพื้นที่อีก 1 GB ด้วยเช่นกัน

    ทางออกก็คือ ใช้ความสามารถของ Google Client Library ทำการ Upload ไฟล์ขึ้นไปโดยตรง เท่าที่ทดลองมา จะไม่ได้ Cache บน Local Drive ทำให้สามารถ Upload ไฟล์ขนาดใหญ่ได้ โดยไม่เสียพื้นที่เพิ่มแบบ Client ข้างต้น

    วิธีการใช้งาน Python เพื่อ Upload File ขึ้น Google Drive File Stream

    1. ผมเขียน Code เอาไว้ ชื่อ upload2gdrive.py ไว้บน GitHub (https://github.com/nagarindkx/google) สามารถดึงมาใช้งานได้โดยใช้คำสั่ง
      clone https://github.com/nagarindkx/google.git
      cd google
    2. สร้าง Project, Credential ตาม “ขั้นที่ 1” ในบทความ การใช้งาน Google Drive API ด้วย Google Client Library for Python ซึ่งจะได้ไฟล์ Client Secret File มา ให้แก้ไขชื่อเป็น “client_secret.json” แล้ว นำไปไว้ใน directory “google” ตามข้อ 1
    3. วิธีใช้คำสั่ง
      ดูวิธีใช้

      python upload2gdrive.py --help

      Upload ไฟล์ จาก /backup/bigfile.tar,gz

      python upload2gdrive.py --file /backup/bigfile.tar.gz

      บน Windows ก็สามารถใช้งานได้ ด้วยคำสั่ง

      python upload2gdrive.py --file D:\backup\bigfile.tar.gz

      หากต้องการระบุตำแหน่ง Folder บน Google Drive ที่ต้องการเอาไฟล์ไปไว้ ให้ระบุ Folder ID

      python upload2gdrive.py --file /backup/bigfile.tar.gz ----gdrive-id xxxxxxxbdXVu7icyyyyyy

      หากต้องการระบุ Chunk Size (ปริมาณข้อมูลที่จะแบ่ง Upload เช่น ไฟล์ 1 GB หากกำหนด Chunk Size เป็น 100MB โปรแกรมจะแบ่งข้อมูลเป็น 10 ส่วน — ขนาดที่เล็กที่สุดคือ 1 MB และค่า Default คือ 100 MB)

      python upload2gdrive.py --file /backup/bigfile.tar.gz ----gdrive-id xxxxxxxbdXVu7icyyyyyy --chunk-size 100
    4. ผลการทำงานจะประมาณนี้

      ใน Google Drive ที่กำหนด ก็จะมีไฟล์ปรากฏอยู่

    หวังว่าจะเป็นประโยชน์ครับ

    PS: ในบทความต่อไป จะมาอธิบายว่า เขียนขึ้นมาได้อย่างไร โปรดติดตามชม

  • การใช้งาน Google Drive API ด้วย Google Client Library for Python

    ในบทความนี้ จะแนะนำวิธีการเขียน Python เพื่อติดต่อกับ Google Drive API ทาง Google Client Library ซึ่ง จะใช้ REST v2 [1] เนื่องจาก ใน REST v3 ยังหาทางแสดง Progress ไม่ได้ (หากได้แล้วจะมา Update นะ)

    สิ่งต้องมี

    1. Python 2.6 ขึ้นไป
    2. PIP Package Management Tool
    3. เครื่องต้องต่อ Internet ได้
    4. แน่นอน มี Google Account

    ขั้นที่ 1: เปิดใช้ Drive API

    เปิด URL https://console.cloud.google.com แล้วคลิก Select a project

    จากนั้นคลิกปุ่ม + เพือสร้าง Project

    ตั้งชื่อ Project แล้วคลิก Save

    เลือก Project ที่สร้างขึ้น เลือก API Library ที่ต้องการ ในที่นี้คือ Google Drive API

    แล้วคลิก Enable

    จากนั้น Create Credentials

    เลือกชนิดเป็น OAuth Client ID แล้วกรอกข้อมูลดังนี้

    สร้าง Consent Screen

    เลือก Application Type เป็น Web Application, ระบุ Name (จะแสดงตอนขอ Permission) แล้วตั้งค่า URL ทั้ง 2 อันเป็น http://localhost:8080

     

    และ สุดท้าย คลิก Download

    ก็จะได้ไฟล์ JSON มา ส่งนี้จะเรียกว่า “Client Secret File”  ให้เก็บไฟล์ไว้ใน Directory เดียวกันกับที่ต้องการจะเขียน Python Code โดยสามารถแก้ไขเปลี่ยนชื่อ เช่น ตั้งเป็น client_secret.json

    ขั้นที่ 2: ติดตั้ง Google Client Library

    ติดตั้งด้วย pip ตามคำสั่งต่อไปนี้

    pip install --upgrade google-api-python-client

    ขั้นที่ 3: เขียน Code เพื่อติดต่อ Drive API

    จาก Python Quickstart [1] เป็นการเริ่มต้นที่ดีมาก เราสามารถนำ Code มาเป็นจุดเริ่มต้นได้ โดยตัวอย่างจะทำการติดต่อไปยัง Google Drive แล้ว List รายการของไฟล์ 10 อันดับแรกออกมา

    ตัวอย่างที่ Google ให้มา จะอ้างอิงไปยัง Credentials Path ไปยัง directory “.credentials” ใน “Home Directory” ของผู้ใช้ แต่ในตัวอย่างที่จะแสดงต่อไปนี้ ได้แก้ไขให้ “Client Secret File” อยู่ที่ directory เดียวกับ python file และเมื่อทำการ Authorization แล้วก็จะได้ “Credential File” มาเก็บไว้ที่เดียวกัน

    Code ต้นฉบับ สามารถดูได้จาก https://developers.google.com/drive/v2/web/quickstart/python ในที่นี้จะเปลี่ยนเฉพาะส่วนที่ต้องการข้างต้น และ เขียน Comment เพื่ออธิบายเพิ่มเติมเป็นภาษาไทย (ซึ่งไม่สามารถเขียนลงไปใน Python Code ได้) โดยตั้งชื่อไฟล์ว่า listfile.py

    from __future__ import print_function
    ...
    # การกำหนด SCOPES ต้องสอดคล้องกับบริการที่เราจะใช้งาน
    SCOPES = 'https://www.googleapis.com/auth/drive.metadata.readonly'
    
    # แก้ไข Client Secret File ให้สอดคล้องกับไฟล์ที่ได้จาก ขั้นตอนที่ 1
    CLIENT_SECRET_FILE = 'client_secret.json'
    # แก้ไข Application Name ตามต้องการ
    APPLICATION_NAME = 'Drive API Python Quickstart'
    
    ...
    def get_credentials():
    ...
     # ไม่ใช้
     # home_dir =os.path.expanduser('~')
     
     # เดิม อยู่ใน os.path.join(home_dir, '.credentials')
     # แก้ไขให้อยู่ที่ Current Working Directory เดียวกันเลย
     credential_dir = os.getcwd()
     ...
     # เดิม os.path.join(credential_dir,'drive-python-quickstart.json')
     # ตั้งชื่อ Credential ตามต้องการ 
     credential_path = os.path.join(credential_dir,'drive_credential.json')
    ...
    
    def main():
    ...
     credentials = get_credentials()
     http = credentials.authorize(httplib2.Http())
    
     # ตรงนี้สำคัญ จะต้องเลือกใช้ REST Version ที่ต้องการ
     # ในที่นี้ ใช้ REST v2
     service = discovery.build('drive', 'v2', http=http)
     
     # ส่วนของการเขียน Code
     # ตัวอย่างนี้ เรียกใช้ files().list()
     # โดยตั้งค่า maxResults เป็น 10 ก็คือ เรียกเฉพาะ 10 รายการแรก
     # อ้างอิงจาก https://developers.google.com/drive/v2/reference/files/list
     results = service.files().list(maxResults=10).execute()
    
     # จาก อ้างอิง จะเห็นได้ว่า files().list() นั้น Return หรือ Response
     # items[] ซึ่งมี element เป็น รายการของไฟล์
     items = results.get('items', [])
     
     # ตรวจสอบว่ามีไฟล์หรือไม่
     if not items:
       print('No files found.')
     else:
       # หากมีไฟล์อยู่
       print('Files:')
       # loop เพื่อแสดงไฟล์ที่มีอยู่ ในที่นี้ จะไม่เกิน maxResults ข้างต้น
       for item in items:
         # แสดงฟิลด์ title และ id
         # เพิ่มเติม .encode('utf-8') ด้วย
         print('{0} ({1})'.format(item['title'].encode('utf-8'), item['id']))
    
    if __name__ == '__main__':
     main()

    ขั้นที่ 4: Run

    ตอนนี้ใน Directory จะมีไฟล์

    • client_secrets.json
    • listfile.py

    ใช้คำสั่ง

    python listfile.py

    หากเป็นการ Run ครั้งแรก ซึ่งจะยังไม่มีไฟล์ drive_credential.json โปรแกรมก็จะทำตาม “flow” โดย ถ้า run command line บนเครื่องที่มี X Window ก็จะเปิด Web Page ไปยัง Google เพื่อ Authorization

    และเปิด Web นี้ ให้คลิกเลือก Account ที่จะติดต่อด้วย

    หน้า Consent Screen คืออย่างนี้ คลิกอนุญาต

    ผลที่ได้

    Reference:

    [1] https://developers.google.com/drive/v2/web/quickstart/python

     

  • ELK #5 การประยุกต์ใช้ ELK ในงานด้าน GIS

    คราวนี้ มาดูการประยุกต์ใช้ ELK ในงานด้าน GIS

    ต่อจาก ELK #01 > ELK #02 > ELK #03 > ELK #04 ซึ่งเป็นการติดตั้งทั้งหมด คราวนี้มาดูการประยุกต์ใช้งานกันบ้าง

    โจทย์มีอยู่ว่า มีการไปเก็บข้อมูลในภาคสนาม แล้วมีการบันทึก พิกัดด้วย GPS เป็น Latitude กับ Longitude พร้อมกับค่าบางอย่าง ทั้งหมดถูกเก็บไว้ในฐานข้อมูล MySQL

    การนำข้อมูลเข้า ELK ก็เลย Export ข้อมูลจาก MySQL มาเป็น CSV File ประกอบด้วย

    id,LATITUDE,LONGITUDE,something

    ตัวอย่างข้อมูล มีดังนี้

    id,LATITUDE,LONGITUDE,something
    1,6.97585,100.448963,100
    2,6.975627,100.450841,19
    3,6.973472,100.449196,65
    4,6.973468,100.449104,53
    5,6.973455,100.449135,33
    6,6.973252,100.44888,13
    7,6.985862,100.45292,85
    8,6.993386,100.416214,90
    9,7.005465,100.447984,1

    นำข้อมูลเข้า ELK ผ่านทาง Logstash

    ใน  ELK #2 ได้อธิบายขั้นตอนการติดตั้ง Logstash ไว้แล้วนั้น ต่อไปเป็นการนำข้อมูลชนิด CSV เข้าไปใส่ใน Elasticsearch

    Logstash จะอ่าน “กระบวนการทำงาน” หรือเรียกว่า Pipeline จากไฟล์ Configuration ซึ่งประกอบด้วย 3 ส่วนหลักๆ คือ Input, Filter และ Output

    input {
       stdin { }
    }

    ในส่วน input นี้ จะเป็นการอ่าน STDIN หรือ ทาง Terminal

    filter {
     csv {
       separator => ","
       columns => [
         "id","latitude","longitude","something"
       ]
     }
     if [id] == "id" {
       drop { }
     } else {
       # continue processing data
       mutate {
         remove_field => [ "message" ]
       }
       mutate {
         convert => { "something" => "integer" }
         convert => { "longitude" => "float" }
         convert => { "latitude" => "float" }
       }
       mutate {
         rename => {
           "longitude" => "[geoip][location][lon]"
           "latitude" => "[geoip][location][lat]"
         }
       }
     }
    }

    ในส่วนของ filter นี้ เริ่มจาก เลือกใช้ Filter Plugin ชื่อ “csv” เพื่อจัดการไฟล์ CSV โดยกำหนด “separator” เป็น “,” แล้วกำหนดว่ามีชื่อ Column เป็น “id”,”latitude”,”longitude”,”something”

    จากนั้น ก็ตรวจสอบว่า ถ้าข้อมูลที่อ่านเข้ามา ใน Column “id” มีค่าเป็น “id” (ซึ่งก็คือบรรทัดหัวตารางของไฟล์ csv นั่นเอง) ก้ให้ “drop” ไป

    แต่หากไม่ใช่ ก็ให้ทำดังนี้ (mutate คือการแก้ไข)

    • remove field ชื่อ message (ซึ่งจะปรากฏเป็น Default อยู่ ก็เลยเอาออกเพราะไม่จำเป็น)
    • convert หรือ เปลี่ยน “ชนิด”  ของแต่ละ field เป็นไปตามที่ต้องการ ได้แก่ ให้ something เป็น Integer, latitude และ longitude เป็น float
    • rename จาก latitude เป็น [geoip][location][lat] และ longitude เป็น [geoip][location][lon] ซึ่งตรงนี้สำคัญ เพราะ geoip.location Field ข้อมูลชนิก “geo_point” ซึ่งจำเป็นต่อการนำไปใช้งานเกำหนดตำแหน่งพิกัดบนแผนที่ (เป็น Field ที่สร้างจาก Template พื้นฐานของ Logstash ซึ่งจะไม่กล่าวถึงในบทความนี้)
    output {
     stdout { codec => rubydebug }
     elasticsearch {
       hosts => ["http://your.elastic.host:9200"]
     }
    }

    ในส่วนของ Output จะกำหนดว่า ข้อมูลที่อ่านจาก csv และผ่าน filter ตามที่กล่าวมาข้างต้น จะส่งไปที่ใน จากการกำหนดนี้ บอกว่า จะส่งออกไป

    • stdout คือ การแสดงผลออกมาทาง terminal โดยมีรูปแบบเป็น rubydebug (รูปแบบหนึ่ง)
    • Elasticsearch ซึ่งอยู่ที่ http://your.elastic.host:9200

    จากนั้น Save ไฟล์นี้ แล้วตั้งชื่อว่า gis.conf

    แล้วใช้คำสั่ง

    cat sample1.csv | /usr/share/logstash/bin/logstash -f gis.conf

    การแสดงผลข้อมูลใน Elasticsearch ผ่าน Kibana

    จากบทความก่อนหน้า ได้แสดงวิธีการติดตั้ง Kibana และเชื่อมต่อกับ Elasticsearch แล้ว โดยจะเข้าถึง Kibana ได้ทางเว็บไซต์ http://your.kibana.host:5601

    ในกระบวนการของ Logstash ข้างต้น จะไปสร้าง Elasticsearch Index ชื่อ “logstash-YYYY-MM-DD”, ใน Kibana ก็จะต้องไป คลิกที่ Setting (รูปเฟือง) จากนั้นคลิกที่ Index Pattern โดยให้ไปอ่าน index ซึ่งมีชื่อเป็น Pattern คือ “logstash-*” จากนั้น คลิกปุ่ม Create

    จะได้ผลประมาณนี้

    ต่อไป คลิกที่ Discover ก็จะเห็นข้อมูลเข้ามา

    แสดงข้อมูลในรูปแบบของ Tile Map

    คลิกที่ Visualization > Create a visualization

    เลือก Tile Map

    เลือก Index ที่ต้องการ ในที่นี้คือ logstash-*

    คลิก Geo Coordinates

    จากนั้น คลิก Apply แล้วคลิก Fit Data Bound

    ก็จะได้เฉพาะ พื้นที่ทีมีข้อมุล

    วิธีใส่ Map Server อื่น

    ปัญหาของ Defaul Map Service ที่มากับ Kibana คือ Elastic Map Service นั้น จะจำกัดระดับในการ Zoom จึงต้องหา WMS (Web Map Service) อื่นมาใช้แทน ต้องขอบคุณ คุณนพัส กังวานตระกูล สถานวิจัยสารสนเทศภูมิศาสตร์ทรัพยากรธรรมชาติและสิ่งแวดล้อม ศูนย์ภูมิภาคเทคโนโลยีอวกาศและภูมิสารสนเทศ (ภาคใต้)  สำหรับคำแนะนำในการใช้งาน WMS และระบบ GIS ตลอดมาครับ 🙂

    โดย เราจะใช้ WMS ของ Longdo Map API : http://api.longdo.com/map/doc/
    ข้อมูลการใช้งาน เอามาจาก http://api.longdo.com/map/doc/demo/advance/02-layer.php

    วิธีการตั้งค่าใน Kibana

    คลิกที่ Option > WMS compliant map server
    แล้วกรอกข้อมูล

    URL : https://ms.longdo.com/mapproxy/service
    Layer: bluemarble_terrain
    Version: 1.3.0
    Format: image/png
    Attribute: Longdo API

    จากนั้นคลิก Apply

    จากนั้นให้ Save พร้อมตั้งชื่อ

    ซึ่ง Longdo Map API สามารถ Zoom ได้ละเอียดพอสมควร

    สามารถนำเสนอระบบ GIS ได้บน Website ทันที

    หวังว่าจะเป็นประโยชน์ครับ

  • วิธีทำ Screen Mirror จาก Android ขึ้นมาแสดงบน PC (Ubuntu)

    เนื่องจากเครื่อง Notebook ที่ใช้ ลง Ubuntu 17.04 Desktop จึงนำเสนอวิธีนี้ก่อน

    1. ใน Android ต้องเปิด Developer Options
    2. เปิด USB Debuging
    3. เสียบ Android กับ USB
    4. ที่เครื่อง Ubuntu Desktop ติดตั้งดังนี้
      sudo apt install adb android-tools-adb ffmpeg
    5. ใช้คำสั่งต่อไปนี้ เพื่อดูว่า มี Android มาต่อทาง USB หรือไม่
      lsusb
      ผลที่ได้
    6. ต่อไป ใช้คำสั่งต่อไปนี้ เพื่อดูว่า ADB เห็น Android หรือไม่
      adb shell screenrecord –output-format=h264 – | ffplay
    7. ผลที่ได้คือ หน้าจอ Android จะปรากฏบน PC (Ubuntu)

    Reference:

    1. https://askubuntu.com/questions/213874/how-to-configure-adb-access-for-android-devices