ก้าวไปอีกหนึ่งก้าวกับ XSection Plot

สวมวิญญานใหม่ด้วย PySide2

หลังจากผมคอมไพล์ XSection Plot ใหม่ด้วยสภาวะแวดล้อมพัฒนาของ Qt5 platform ด้วย PySide2 ผมเปลี่ยนลิขสิทธิ์ของโปรแกรมเดิมที่กำกวมออกมาฟรีสมบูรณ์แบบเหมือนกันกับ Surveyor Pocket Tools สามารถนำไปทำซ้ำแจกจ่ายได้ตามอัธยาศัย แต่ห้ามดัดแปลง ห้ามนำไปจำหน่ายหรือให้เช่า

XSection Plot
Copyright (C) Prajuab Riabroy. All Rights Reserved.

XSection Plot is free for use in any environment, including but not necessarily limited to: personal, academic, commercial, government, business, non-profit, and for-profit. "Free" in the preceding sentence means that there is no cost or charge associated with the installation and use of XSection Plot. 
Permission is hereby granted, free of charge, to any person obtaining a copy of this software (the "Software"), to use the Software without restriction, including the rights to use, copy, publish, and distribute the Software, and to permit persons to whom the Software is furnished to do so.

You may not modify, adapt, rent, lease, loan, sell, or create derivative works based upon the Software or any part thereof. 

The above copyright notice and this permission notice shall be included in all copies of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

แก้ไข bugs

นอกจากย้ายโค้ดมาใช้ PySide2 แล้ว ผมเลยถือโอกาสแก้บั๊กเล็กน้อยไปหลายอย่าง เช่น

  • เวลาคลิกขวาเพื่อเรียกเมนูในช่องป้อนข้อมูล โปรแกรมจะ terminate ทันที
  • ใน Section Layout ตรง Horizontal Grid เมื่อปรับ Distance from CL to left ไปแล้ว โปรแกรมไม่จำค่าใหม่
  • อื่นๆอีกเล็กน้อยประมาณสิบกว่าอย่าง

คอมไพล์และสร้างไฟล์ execute binary ด้วย PyInstaller

ตอนนี้โปรแกรมสนับสนุนทั้ง 32 บิตและ 64 บิต ผมใช้ PyCharm เป็นทูลส์ในการพัฒนา และเลือกได้ว่าจะใช้ 32 บิตหรือ 64 บิต เมื่อโปรแกรม stable แล้ว ก็จะสร้าง execute binary file ด้วย PyInstaller ตามสภาวะแวดล้อม ต้องทำสองครั้ง ครั้งแรก 32 บิตและครั้งที่สอง 64 บิต โดยแต่ละครั้งจะได้ไฟล์ exe, pyd, dll รวมถึงไลบรารีของไพทอนที่เราเรียกใช้ และที่สำคัญคือไลบรารีของ PySide2

ทำไฟล์ Setup ด้วย Inno Setup

ไฟล์ที่ได้จาก PyInstaller ทั้งหมด ผมจะนำมาสร้างไฟล์ Setup ด้วย Inno Setup เพื่อนเก่าที่ใช้กันมานมนาน มีดีเพียงพอที่จะสร้างไฟล์ Setup ได้ง่ายๆ มี options ให้เลือกพอสมควร สุดท้ายจะได้ไฟล์ Setup ที่เป็น Execute file ไฟล์เดียวพร้อมจะนำไปอัพโหลดให้ผู้ใช้นำไปใช้งานได้

ทดสอบโปรแกรมด้วยแบบรูปตัดตามยาว

ผมจะลองทดสอบโปรแกรมจากข้อมูล ความจริง XSection Plot คือโปรแกรมสร้างหรือช่วยเขียนรูปตัดตามขวาง แต่ยังพอเอามาประยุกต์ใช้กับ Long Profile ได้ แต่ไฟล์ข้อมูลส่วนใหญ่จะมีข้อมูลเพียงหนึ่ง Section เท่านั้นจะเริ่มจากไฟล์ข้อมูลของ Existing Ground Section ก่อนครับ ข้อมูลดังในกรอบข้างล่าง สามารถ copy ไป paste ในโปรแกรม text file editor เช่น Notepad ได้จากนั้น save ตั้ง extension เป็น gxml (ตัวอย่างผมตั้งชื่อว่า lake-road.gxml)

<root version="1.0">
  <!--Generated by XSection Plot-->
  <!--This data file is Existing ground section-->
  <Header>
    <AppName>XSection Plot</AppName>
    <Developer>Prajuab Riabroy</Developer>
    <Version>4.1.512</Version>
    <SectionType>Ground</SectionType>
    <DateCreated>2017-11-12 19:24:28.634707</DateCreated>
  </Header>
  <ProjectInfo>
    <ProjectName>Cantonment Lake Road</ProjectName>
    <ClientName></ClientName>
    <ContractorName></ContractorName>
    <DrawingTitle></DrawingTitle>
    <DrawnName></DrawnName>
    <ApprovedName></ApprovedName>
    <ClientApprovedName></ClientApprovedName>
    <CheckedName></CheckedName>
    <SurveyorName></SurveyorName>
    <SurveyedDate></SurveyedDate>
    <DrawingNo></DrawingNo>
    <SheetNo></SheetNo>
    <DrawingDate></DrawingDate>
    <Revision></Revision>
    <UseLocaleLanguage>False</UseLocaleLanguage>
    <MapTexts>
      <MapText Label="Client" Locale="เจ้าของโครงการ"/>
      <MapText Label="Contractor" Locale="ผู้รับจ้าง"/>
      <MapText Label="Drawn" Locale="เขียน"/>
      <MapText Label="Design" Locale="ออกแบบ"/>
      <MapText Label="Surveyor" Locale="ผู้สำรวจ"/>
      <MapText Label="Surveyed Date" Locale="วันที่สำรวจ"/>
      <MapText Label="Checked" Locale="ตรวจสอบ"/>
      <MapText Label="Approved" Locale="อนุมัติ"/>
      <MapText Label="Client Approved" Locale="ผู้คุมงานอนุมัติ"/>
      <MapText Label="Drawing No." Locale="แบบเลขที่"/>
      <MapText Label="Plotted Date" Locale="แบบวันที่"/>
      <MapText Label="Project" Locale="โครงการ"/>
      <MapText Label="Drawing Title" Locale="แผนที่แสดง"/>
      <MapText Label="Sheet No." Locale="แบบเลขที่"/>
      <MapText Label="Scale" Locale="มาตราส่วน"/>
      <MapText Label="Vertical" Locale="ทางดิ่ง"/>
      <MapText Label="Horizontal" Locale="ทางราบ"/>
      <MapText Label="Vertical Scale" Locale="มาตราส่วนทางดิ่ง"/>
      <MapText Label="Horizontal Scale" Locale="มาตราส่วนทางราบ"/>
      <MapText Label="Legend" Locale="สัญลักษณ์"/>
      <MapText Label="Note" Locale="หมายเหตุ"/>
      <MapText Label="Geodetic Information" Locale="ข้อมูลระบบพิกัด"/>
      <MapText Label="No." Locale="ครั้งที่"/>
      <MapText Label="Amendments" Locale="ความเห็น"/>
      <MapText Label="By" Locale="โดย"/>
      <MapText Label="Date" Locale="วันที่"/>
      <MapText Label="Revision" Locale="ครั้งที่แก้ไข"/>
    </MapTexts>
  </ProjectInfo>
  <SectionOptions>
    <VerticalScale>500.0</VerticalScale>
    <HorizontalScale>1000.0</HorizontalScale>
    <HozGridSpace>10.0</HozGridSpace>
    <VertGridSpace>2.0</VertGridSpace>
    <GridLineType>0</GridLineType>
    <CalcIntersection>True</CalcIntersection>
    <CalcArea>True</CalcArea>
    <TrimTypical>False</TrimTypical>
    <NumDecimalElev>3</NumDecimalElev>
    <NumDecimalDist>3</NumDecimalDist>
    <UseIntervalText>True</UseIntervalText>
    <IntervalDist>10.0</IntervalDist>
    <PrefixText>MSL</PrefixText>
    <PostfixText>MSL</PostfixText>
    <UsePostPrefix>1</UsePostPrefix>
    <UseOffsetElevFormat>2</UseOffsetElevFormat>
    <CalcPlotAreaCut>True</CalcPlotAreaCut>
    <CalcPlotAreaFill>True</CalcPlotAreaFill>
    <NumVertCLLeft>1</NumVertCLLeft>
    <NumVertCLRight>90</NumVertCLRight>
    <NumHozTopBottom>10</NumHozTopBottom>
    <LeftSideText>LT.</LeftSideText>
    <RightSideText>RT.</RightSideText>
    <StationText>Km.</StationText>
    <SelectedTBlock>2</SelectedTBlock>
    <NumSectionRows>1</NumSectionRows>
    <NumSectionColumns>1</NumSectionColumns>
    <SurveyType>0</SurveyType>
    <PlotTBlock>True</PlotTBlock>
    <SwapLeftAndRight>False</SwapLeftAndRight>
  </SectionOptions>
  <PageSetup>
    <Size>Custom</Size>
    <Width>940.0</Width>
    <Height>200.0</Height>
  </PageSetup>
  <Sections>
    <NumSections>1</NumSections>
    <Section Name="0+000">
      <XPositionOnPaper>47.7</XPositionOnPaper>
      <YPositionOnPaper>11.7</YPositionOnPaper>
      <TopGridElev>14.0</TopGridElev>
      <NumPoints>29</NumPoints>
      <Points>
        <Point Elevation="5.741" Offset="0.0"/>
        <Point Elevation="5.802" Offset="29.5"/>
        <Point Elevation="4.186" Offset="44.5"/>
        <Point Elevation="1.955" Offset="66.778"/>
        <Point Elevation="1.04" Offset="84.5"/>
        <Point Elevation="1.017" Offset="114.5"/>
        <Point Elevation="0.895" Offset="144.5"/>
        <Point Elevation="1.162" Offset="174.5"/>
        <Point Elevation="1.012" Offset="234.5"/>
        <Point Elevation="1.145" Offset="264.5"/>
        <Point Elevation="1.16" Offset="316.642"/>
        <Point Elevation="1.317" Offset="339.5"/>
        <Point Elevation="1.619" Offset="386.947"/>
        <Point Elevation="1.518" Offset="409.5"/>
        <Point Elevation="1.311" Offset="454.5"/>
        <Point Elevation="1.261" Offset="484.5"/>
        <Point Elevation="1.065" Offset="544.5"/>
        <Point Elevation="1.113" Offset="574.5"/>
        <Point Elevation="2.799" Offset="634.5"/>
        <Point Elevation="1.664" Offset="664.5"/>
        <Point Elevation="1.442" Offset="694.5"/>
        <Point Elevation="1.108" Offset="724.5"/>
        <Point Elevation="1.099" Offset="754.5"/>
        <Point Elevation="1.854" Offset="784.5"/>
        <Point Elevation="1.549" Offset="814.5"/>
        <Point Elevation="8.402" Offset="844.5"/>
        <Point Elevation="8.555" Offset="866.792"/>
        <Point Elevation="8.68" Offset="889.5"/>
        <Point Elevation="8.58" Offset="916.9"/>
      </Points>
    </Section>
  </Sections>
</root>

ต่อไปเป็น Typical Section ขนาดเล็กกว่า ผมตั้งชื่อว่า lake-typical.txml

<root version="1.0">
  <!--Generated by XSection Plot-->
  <!--This data file is Typical section-->
  <Header>
    <AppName>XSection Plot</AppName>
    <Developer>Prajuab Riabroy</Developer>
    <Version>4.1.512</Version>
    <SectionType>Typical</SectionType>
    <DateCreated>2017-11-12 18:42:28.929847</DateCreated>
  </Header>
  <Sections>
    <NumSections>1</NumSections>
    <Section Name="">
      <XPositionOnPaper>0.0</XPositionOnPaper>
      <YPositionOnPaper>0.0</YPositionOnPaper>
      <TopGridElev>0.0</TopGridElev>
      <NumPoints>4</NumPoints>
      <Points>
        <Point Elevation="5.0" Offset="36.944"/>
        <Point Elevation="5.0" Offset="695.0"/>
        <Point Elevation="8.4" Offset="845.0"/>
        <Point Elevation="8.44" Offset="900.0"/>
      </Points>
    </Section>
  </Sections>
</root>

เปิดไฟล์ข้อมูลทดสอบบน XSection Plot

จากนั้นนำสองไฟล์มาเปิดด้วย XSection Plot เวลาเปิดไฟล์ให้เลือกรูปแบบของไฟล์ด้วยจะได้เปิดง่าย  มีชื่อ extension ตามลำดับดังนี้ gxml, txml

จะได้ข้อมูลปรากฎขึ้นบนโปรแกรมดังนี้

ตั้งหน้ากระดาษ (Page Setup)

ผมลองเลือกใช้หน้ากระดาษที่ไม่มาตรฐานเพื่อให้ฟิตกับขนาดรูปตัดตามยาว ยาว 940 มม. และกว้าง 200 มม.

ตั้งค่า (Settings)

ผมตั้งสเกลทางราบเป็น 1:1000 และสเกลทางดิ่ง 1:250 อย่างอื่นดูรูปด้านล่าง

จัดวางรูปตัดบนกระดาษ (Section Layout)

จะเห็นกระดาษขนาด 200 มม. x 940 มม. แล้วเลือกพารามิเตอร์ดังรูปด้านล่าง

ดูรูปตัด (Section Viewer)

จะเห็นรูปตัดตามยาวที่ประกอบไปด้วย Existing Ground และ Typical

ลองซูมดู ก็ได้แบบ drawing มาพอถูๆไถๆ ที่สามารถนำไปเขียนเพิ่มเติมได้ในโปรแกรมด้านเขียนแบบทั้งหลายเช่น Autocad, Microstation, Draftsight

Save to DXF

จัดเก็บไฟล์ในรูป Autocad DXF เพื่อสามารถนำไปเปิดในโปรแกรมอื่นได้

เปิดไฟล์แบบรูปตัดตามยาว

ผมใช้ Microstation เปิดแบบรูปตัดตามยาวได้ผลลัพธ์ดังนี้และพร้อมจะนำแบบไปเขียนเพิ่มเติมตามความต้องการ

ครับคงอีกไม่นานก็จะคงจะปล่อยเวอร์ชั่นเสถียรให้สามารถดาวน์โหลดได้ พบกันใหม่ครับ

แนะนำการย้ายโค้ดจาก PyQt5 เป็น PySide2

ย้ายโค้ด XSection Plot

ในขณะนี้ทำงานอยู่ที่บังคลาเทศ โครงการก่อสร้างรถไฟฟ้าที่กรุงธากา มีโอกาสกลับมาพัก ก็พอมีเวลาว่างพยายามย้ายโค้ดของโปรแกรม XSection Plot จากของเดิมที่พัฒนาด้วย PyQt5 ที่ยังติดเรื่องลิขสิทธิ์บางส่วน โดยย้ายมาใช้ PySide2 ที่เปิดกว้างกว่า ความจริงทั้งคู่ใช้เครื่องยนต์ (Engine) เดียวกันคือ Qt5 platform ดังนั้นเมื่อย้ายโค้ดสำเร็จแล้วเวลารันก็หน้าตาเหมือนกันเป๊ะดังรูปด้านล่างที่คอมไพล์ด้วย PySide2

จัดการปลั๊กอิน PySide2

การย้ายโค๊ดใช้เวลาไม่นานนัก ใช้เวลาประมาณ 2 ชั่วโมง เนื่องจากผมเคยย้ายโค้ด Surveyor Pocket Tools ทำให้รู้แนวทางลัดพอสมควร อันดับแรกขอย้อนกลับหน่อย เนื่องจาก PySide2 จะมองหาโฟลเดอร์ลิ๊งค์ไลบรารีของตัวเองชื่อ “plugins” ถ้าไม่เจอจะ error แล้วหยุดทันที ดังนั้นก่อนอื่นควรจะแทรกโค๊ดนี้เข้าไปก่อน เริ่มตั้งแต่ import PySide2 ตามด้วยตรวจสอบว่า PySide2 อยู่ที่โฟลเดอร์ไหนจัดเก็บเข้าตัวแปร dirname จากนั้นค้นหาพาทของ “plugins” ที่อยู่ใต้โฟลเดอร์ dirname ด้วยคำสั่ง os.path.join()

import os
import sys
import PySide2
dirname = os.path.dirname(PySide2.__file__)
plugin_path = os.path.join(dirname, 'plugins', '')
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path
print('plugin_path = ', plugin_path)

ที่เครื่องคอมพิวเตอร์ผม จะปริ๊นท์พาทของ “plugins” ดังนี้

plugin_path =  C:\Miniconda3\envs\py36_64\lib\site-packages\PySide2\plugins\

เพราะว่าผมใช้ Miniconda เป็นตัวจัดการระบบ environment ของ python ผมสร้าง envs ชื่อ “py36_64” เป็น python รุ่น 3.6 แบบ 64 บิต และ PySide2 ก็จะถูกติดตั้งมาอยู่ภายใต้โฟลเดอร์นี้ อีก envs หนึ่งที่สร้างไว้ชื่อ “py36_32” เป็น python รุ่น 3.6 แบบ 32 บิต เมื่อรันโปรแกรมแล้วจะปริ๊นท์พาทมาดังนี้

plugin_path =  C:\Miniconda3\envs\py36_32\lib\site-packages\PySide2\plugins\

วิธีการสร้าง environment สำหรับไพทอนก็กลับไปดูโพสต์เก่าของผมได้ครับ

เปลี่ยนคำ PyQt5 เป็น PySide2

ยังอยู่ในส่วน import ที่โค๊ดเดิมของโปรแกรมผมเรียกใช้ไลบรารีของ PyQt5 ดังนี้

from PyQt5.QtGui import QPixmap, QIcon, QKeySequence, QFont, QIntValidator, QCursor
from PyQt5.QtCore import Qt, pyqtSlot, QSettings, QFileInfo, QSize, QFile
from PyQt5.QtWidgets import QUndoStack, QSplashScreen, QApplication, QMainWindow, QTabWidget, QAction, QStatusBar,\
     QMenu, QWidget, QSizePolicy, QLineEdit, QFileDialog, QMessageBox, QDesktopWidget

เปลี่ยนเป็น

from PySide2.QtGui import QPixmap, QIcon, QKeySequence, QFont, QIntValidator, QCursor
from PySide2.QtCore import Qt, Slot, QSettings, QFileInfo, QSize, QFile
from PySide2.QtWidgets import QUndoStack, QSplashScreen, QApplication, QMainWindow, QTabWidget, QAction, QStatusBar,\
     QMenu, QWidget, QSizePolicy, QLineEdit, QFileDialog, QMessageBox, QDesktopWidget

ส่วนใหญ่เกือบ 99.99% ที่เหมือนกัน ยกเว้น Signal & Slot

Signal and Slot

มีข้อแตกต่างกันเล็กน้อย เช่นเดิมใน PyQt5 เรียกใช้ pyqtSlot, pyqtSignal ให้เปลี่ยนเป็น Slot, Signal ใน PySide2 ครับ
นอกจากส่วน import แล้ว ในโค๊ดเดิมที่ประกาศคลาส โค้ดเดิมผมเรียกใช้ Signal and Slot ดังนี้

class OverlapSection(QObject):
    '''Horizontal &amp; Vertical overlapped.'''
    overlapped = pyqtSignal(str)
 
    def __init__(self):
            QObject.__init__(self)
 
    def emitOverlapSignal(self, message):
        self.overlapped.emit(message)

เปลี่ยนใหม่เป็น

class OverlapSection(QObject):
    '''Horizontal &amp; Vertical overlapped.'''
    overlapped = Signal(str)
 
    def __init__(self):
            QObject.__init__(self)
 
    def emitOverlapSignal(self, message):
        self.overlapped.emit(message)

ติดตั้ง PySide2 จากไฟล์ wheel

ก็ขอแนะอีกนิดว่า PySide2 เวลาติดตั้งให้ใช้แพ๊คเกจแบบ wheel ที่ทางทีมงานได้ทำไว้ดีกว่าครับ ติดตั้งง่ายไม่งอแง ดาวน์โหลดได้ตามลิ๊งค์นี้ จะสังเกตเห็นชื่อไฟล์ประมาณนี้

PySide2-5.6-cp35-cp35m-win32.whl 	 
PySide2-5.6-cp35-cp35m-win_amd64.whl 	 
PySide2-5.6-cp36-cp36m-win32.whl 
PySide2-5.6-cp36-cp36m-win_amd64.whl

จะเห็นว่า PySide2 สนับสนุนทั้งไพทอน 3.5 และ 3.6 และในตอนนี้ Qt5 รุ่น  5.6 สำหรับคำสั่งที่ติดตั้งก็ง่ายๆใช้ pip ตามด้วยชื่อไฟล์ wheel

pip install PySide2-5.6-cp36-cp36m-win_amd64.whl

สรุปแล้วการย้ายโค้ดง่ายๆไม่ลำบากกินแรง แต่ไปกินแรงเข็นครกอีกทีคือตอนสร้างไบนารีไฟล์ด้วย Pyinstaller ความจริง Pyinstaller ถ้าเข้าใจแล้วปรับใช้ได้ไม่ยาก แต่สำหรับมือใหม่บอกตรงๆว่า ถ้าโปรแกรมที่พัฒนาเรียกใช้ไลบรารีมากหลายอันแล้ว เป็นนรกลูกย่อมๆครับ ถ้าไลบรารีตัวไหนมีคนเขียนไฟล์ hook ให้ก็ง่ายหน่อย แต่ถ้าไม่มีต้องออกแรงกันพอสมควร สำหรับ PySide2 ผมจัดการแบบ manual ครับ รู้ว่าตอนโปรแกรมรันมันต้องการอะไร ตอนใช้ Pyinstaller ผมก็จัดการ copy ไฟล์ไปตามต้องการ ถ้ามีโอกาสจะมาเขียนเรื่องการใช้ Pyinstaller อีกสักตอน พบกันตอนหน้าครับ

ปลดพันธนาการ PyQt5 ด้วย PySide2

ตอนนี้ถือว่ามาเล่าสู่กันฟังจากประสบการณ์ เป็นเรื่องโปรแกรมมิ่ง ถ้าไม่สนใจเรื่องโปรแกรมมิ่งก็ผ่านไปได้ครับ

PyQt5 กับลิขสิทธิ์แบบ GPL v3

ผมเขียนไพทอนด้วยการใช้ PyQt5 มาได้สักระยะเวลาหนึ่ง น่าจะสองปีกว่าได้ ยอมรับว่าชอบมากๆ ก็ไม่ได้ระแวดระวังเรื่องกฎหมายลิขสิทธิ์เท่าไหร่นัก ลิขสิทธิ์ของ PyQt5 เป็นแบบ GPL v3 ซึ่งสาระโดยรวมๆสามารถเอาไปใช้ได้สองกรณีคือ พัฒนาโปรแกรมแบบเปิดโค๊ด (open source) และแจกจ่ายฟรีพร้อมโค๊ด กรณีนี้ไม่จำเป็นต้องเสียเงินค่าลิขสิทธิ์ แต่ถ้าเป็นกรณีที่สองคือการพัฒนาโปรแกรมเพื่อการค้าและปิดโค๊ด จะต้องเสียค่าลิขสิทธิ์ประมาณ 500US$ ต่อปี ซึ่งไม่น่าจะมากมายนัก ผมเองเอา PyQt5 มาใช้และแจกจ่ายโปรแกรมของผมให้ฟรีก็จริงแต่ปิดโค๊ด ยังไม่พร้อมที่จะเปิดโค๊ดและจ่ายค่าลิขสิทธิ์เนื่องจากไม่ได้หารายได้จากโปรแกรมที่แจกจ่ายไป

ทางสองแพร่ง

ผมลองมองหาเครื่องมือพัฒนาตัวอื่นๆที่มีลิขสิทธิ์เอื้อแบบปิดโค๊ดแต่ยังสามารถใช้ได้ฟรี ที่อ่านๆมาแล้วอยู่ในใจคือ Kivy Platform

  • Kivy framework Platform รองรับภาษาไพทอน ข้อดีหลายอย่างคือ  cross platform  เขียนโปรแกรมครั้งเดียวสามารถนำไปคอมไพล์ บิวด์ได้บน Linux, Mac OS หรือสามารถพอร์ตลงไปหามือถือ Android, IOS ก็ได้ ที่สำคัญคือเป็นโครงการเปิดโค๊ด มีลิขสิทธิ์แบบ MIT License ซึ่งนอกจากจะเปิดโค๊ดแล้ว ยังอิสระเสรีมาก ซอฟแวร์ที่ใช้ลิขสิทธิ์แบบนี้ ผู้ใช้สามารถเอาไปทำอะไรก็ได้ตั้งแต่ก๊อปปี้ แก้ไข รวม แจกจ่ายหรือกระทั่งนำไปขายก็ได้ สุดท้ายถ้าใช้ Kivy พัฒนาก็ยังสามารถนำโปรแกรมไปทำการค้าได้
  • แต่ปัญหาของผมคือ โปรแกรมที่เขียนมีขนาดค่อนข้างใหญ่แล้ว การพอร์ตจากโค๊ดของ PyQt5 ไปยัง Kivy ไม่ใช่่จะทำได้ง่ายๆ เนื่องจาก Kivy มีรูปแบบ GUI ของตัวเอง ไม่ง่ายครับต้องใช้เวลามาก

PySide2 ผู้มาช่วยชีวิต

ในขณะที่กำลังจะจมน้ำอยู่นั้น นึกถึง PySide รุ่นแรกซึ่งรองรับและใช้ได้แค่ Qt4 ไม่ใช่ Qt5 ที่ผมตกร่องปล่องชิ้นไปแล้ว การจะ downgrade กลับหลังหันไปใช้ Qt4 ผ่าน PySide รุ่นหนึ่งไม่ได้ง่ายต้องรื้อโค๊ดพอสมควร เผลอๆอาจจะยากกว่าการกลับไปขอคืนดีกับแฟนเก่า 🙂 ส่วนเรื่องลิขสิทธิ์เท่าที่ทราบมาคือ PySide ใช้ลิขสิทธิ์แบบ LGPL v2.1 คือสามารถนำไปใช้พัฒนาโปรแกรมสำหรับปิดหรือเปิดโค๊ดได้ ทั้งแจกจ่ายฟรีและขายได้ เพียงแต่ไปเอาไลบรารีตัวไหนที่เป็น LPGL มาใช้จะต้องคงความเป็น LGPL ไว้คือต้องเปิดโค๊ตไลบรารีตัวนั้นไปให้ผู้ใช้ด้วย  ข่าวร้ายของ PySide รุ่นหนึ่งคือโครงการตาย ไม่ขยับมาแล้วสามปีกว่า ผมลองค้นเข้าไปลึกๆ ปรากฎว่าโครงการนี้ตอนแรกๆ ได้มีนักพัฒนาอิสระ fork โครงการมาบน Github กลุ่มเล็กๆต่อมาได้ย้ายและไปพัฒนาต่อเป็นทางการจาก Qt Company เจ้าของ Qt framework ตัวจริงเสียงจริง เหมือนฟ้ามาโปรด แต่ยังไม่แน่ใจว่าโค๊ดเดิม PyQt5 ของผมจะ compatible กับ PySide2 แค่ไหน

ในขณะที่ไม่รู้จะทำอะไรก็เลยไปดาวน์โหลดหยิบเอา PySide ตอนนี้เป็นรุ่น PySide2 ที่กำลังพัฒนาอยู่ เป็นไฟล์ wheel ครับที่ทีมงานได้คอมไพล์และบิวท์มาให้ลองใช้ก่อน รุ่นที่ผมหยิบมาใช้ในขณะนี้ บิวท์นานมาแล้วประมาณหกเดือนกว่า รุ่นล่ากว่านี้ยังไม่มี

PySide2 ใช้ลิขสิทธิ์แบบ LGPL v2 เหมือนกันกับ PySide รุ่นหนึ่ง เมื่อดาวนโหลดมาแล้วก็ติดตั้ง มาลองดูว่าพอไปได้ไหม ผมใช้เวลาว่างๆตอนเลิกงานลองไปหก เจ็ดวัน สำเร็จครับ ส่วนใหญ่ใช้ได้กับโค๊ดเดิม แค่ตอน import ไลบรารีเปลี่ยนแค่หัวจาก PyQt5 มาเป็น PySide2 มีส่วนนิดเดียวผมแก้ไขโค๊ดใหม่ให้เข้ากับ PySide2 แต่น้อยมาก และที่เจออีกหนักอีกหน่อยคือ ระบบรายงานผลการแสดงภาพบนจอมอนิเตอร์คือ Screen ยังไม่เสร็จ ทำให้ผมไม่สามารถตรวจได้ว่าผู้ใช้ใช้จอที่ resolution เท่าไหร่ มี dot pixel  ratio เท่าไหร่ อันนี้สำคัญเพราะว่าจอ HiDPI เช่นจอ 4K ทั้งหลาย ตอนนี้ใช้กันมากแล้ว เมื่อ PySide2 ไม่มีให้ ต้องไปหาโค๊ดมาช่วย ใช้ Windows API ไปพลางๆก่อน พอเสร็จเมื่อไหร่ ค่อยกลับมาใช้โค๊ดของ PySide2 ที่เสร็จแล้วต่อ

ผมพูดได้ว่าตอนนี้โปรแกรมของผม เกือบจะ 99.9% ใช้ของเดิม มาปรับแต่งเองเพียง 0.1% มันง่ายหรือเพราะโปรแกรมผมไม่ได้ใช้เขียนอะไรพิศดารหรือปล่าวเช่นระบบกราฟฟิคที่เลิศหรู แต่เอาละต้องขอบคุณทีมงาน PySide2 มา ณ ที่นี้ด้วยครับ

ข้อจำกัด PySide2 รุ่นพัฒนา

ข้อจำกัดของ PySide2 รุ่นพัฒนายังมีอยู่มากครับ บางครั้งผมรันโปรแกรมผ่านบรรทัดที่ผิด ไม่มีการนับแปดครับ โดนน๊อคกลางอากาศค้างไปดื้อๆ ก็น่าจะอีกสักพักครับ ที่ทีมงานของ Qt จะบิวท์มาให้ใช้กันใหม่ เพราะของเก่าผ่านมาหกเดือนกว่าแล้ว ตัวใหม่น่าจะเสถียรกว่า ดีกว่า

แปลงเป็นไฟล์ Execute ให้รันได้ นรกของโปรแกรมเมอร์ไพทอน

ปกติผมใช้ PyInstaller  สำหรับแปลงโค๊ดไพทอนเป็น execute file (exe) ที่สามารถนำไปรันได้ ทั้งที่ข้อดีของไพทอนคือเขียนง่าย อ่านง่าย ทรงพลัง และไลบรารีที่มีให้เลือกให้ใช้มากมายมหาศาล แต่เป็นที่รู้กันว่างานแปลงไฟล์จากโค๊ดไปเป็นไฟล์ exe ที่รันใช้งานได้ มันเป็นงานสุดหินสุดโหด ตอนผมเริ่มต้นใหม่ๆ ผมก็ไม่รู้ว่าไลบรารีตัวไหน ต้องการขนเอาไฟล์อะไรไปบ้างเพื่อให้สามารถรันได้ บางตัวขนกันไปเป็นโฟลเดอร์ คือแบบเรือพ่วงลากกันไปเป็นพวงๆ ตอนหลังมารู้ว่า มีไฟล์ hooks ที่ PyInstaller  อ่านมาเพื่อตัดสินใจว่าจะขนอะไรไปให้ โฟลเดอร์ไหน ก็ง่ายขึ้น ไฟล์ hooks ส่วนใหญ่มากับ PyInstaller  ถ้าไม่มีก็ไปค้นหาดาวน์โหลดมาได้

ตอนนี้ PySide2 ยังมีนักพัฒนาเอาไปใช้ในวงจำกัดอยู่ จึงไม่มีไฟล์ hooks ปล่อยมา นรกกลับมาเริ่มต้นกับผมอีกครั้ง ต้องลองทดสอบว่า PySide2 เอาอะไรไปใช้บ้าง ตอนนี้ขณะเขียนบทความนี้ ยังไม่สำเร็จครับ กำลังลองผิดลองถูก ไม่เป็นไรชีวิตย่อมมีหนทางเสมอ ผมใช้เวลาในวันอาทิตย์เกือบค่อนวันก็สำเร็จ สามารถนำไฟล์ exe ไปรันได้ตามปกติ สาเหตุที่ไม่ผ่านในตอนแรก ตัว PyInstaller มีปัญหากับโมดูลระบบชื่อ requests ต้องเอา requests รุ่นที่ไม่มีปัญหากันมาใส่แทน

เมื่อไฟล์ exe รันแล้วไม่ติดขัด ก็จะเป็นขั้นตอนต่อไปคือใช้โปรแกรมจำพวก installer มาใช้เช่น Inno Setup ขวัญใจมหาชนเจ้าประจำผมใช้อยู่ ขั้นตอนนี้ง่ายครับ เตรียมไฟล์ exe ให้พร้อม ไฟล์ไลบรารีทั้งหลาย โฟลเดอร์ที่จำเป็นต้องใช้ จากนั้นทำการ build ก็ได้โปรแกรมติดตั้ง ที่สามารถนำไปติดตั้งใช้งานได้

ดาวน์โหลด (Download)

ไปดาวน์โหลดโปรแกรมรุ่นที่บิวท์ด้วย PySide2  เป็นรุ่น V0.70 build 513 ได้แล้วที่หน้า Download ใครที่ใช้รุ่นก่อนหน้านี้ขอความกรุณาช่วย uninstall และมาดาวน์โหลดรุ่นใหม่ไปใช้ด้วย

python_2017-04-22_18-37-32
Surveyor Pocket Tools ในฉบับของ PySide2 เหมือนเดิมเพราะ engine คือตัว Qt framework เดียวกัน
python_2017-04-22_18-49-45

ตัวอย่างหน้าตาของ Transform Coordinates

ความเป็นมาของ Qt framework

เล่าเรื่อง PyQt5 vs. PySide2 ผู้อ่านบางท่านอาจจะงง ถีงที่มาที่ไป PyQt และ PySide คือเครื่องมือสำหรับพัฒนาโปรแกรมประยุกต์ ที่มีพื้นฐานมาจาก Qt framework ที่พัฒนาด้วย C++ ผู้สร้าง Qt คือบริษัท Trolltech บริษัทเล็กๆนอรเวย์ จากนั้นถูกซื้อไปในปี 2008 โดยโนเกีย (Nokia) ยักษ์ใหญ่ในตอนนั้นจากฟินแลนด์ (ย้อนหลังไป 15-25 ปีที่แล้ว คงไม่มีใครไม่รู้จักโนเกียเพราะเป็นเจ้าพ่อแห่งวงการมือถือ ยุคก่อน IPhone OS และ Android) ทำให้ลิขสิทธิ์ของ Qt ตกมาอยู่กับโนเกีย และโนเกียพยายามจะพัฒนาให้ Qt สามารถใช้กับมือถือได้ (แต่ก็ไม่ทัน ไอโอเอสและแอนดรอยด์ จนแพ้สงครามนี้ในที่สุด) ช่วงที่ Qt อยู่กับโนเกีย ในขณะนั้น Riverbank Computing บริษัทจากอังกฤษได้พัฒนา PyQt  แต่ตอนหลังมีปัญหากัน เพราะ Riverbank ไม่ยอมเปลี่่ยนลิขสิทธิ์ของ PyQt ที่ใช้แบบ GPL ส่วน Qt ใช้ลิขสิทธิ์แบบ LGPL ซึ่งยืดหยุ่นกว่า โนเกียก็ได้พัฒนา PySide ขึ้นมาเพื่อให้มีลิขสิทธิ์แบบเดียวกันกับ Qt แต่สถาณการณ์ของโนเกียตอนนั้นกำลังย่ำแย่มากๆ เพราะมือถือจากไอโอเอสของแอปเปิ้ลกับแอนด์ดรอยของกูเกิ้ลได้ครองตลาดเบ็ดเสร็จแล้ว

ในปี 2011 โนเกียขาย Qt ให้บริษัท Digia จากฟินแลนด์ หลังจากนั้นฉากสุดท้ายแล้วก็เป็นที่ทราบกันดีว่าโนเกียถูกซื้อเสนอซื้อโดยไมโครซอฟท์ในปี 2013 เฉพาะส่วนที่เกี่ยวกับมือถือสมาร์ทโฟนจบการดีลการซื้อขายในปี 2014 และจบตำนานโนเกียในที่สุด สะท้อนของสัจธรรมที่ว่าในโลกนี้ไม่มีอะไรเที่ยงแท้แน่นอน หลังจาก Digia ได้ Qt ไปในปี 2014 ได้ก่อตั้งบริษัท Qt Company และเป็นผู้พัฒนา Qt จนถึงปัจจุบัน และตามที่ผมกล่าวมาแล้ว Qt Company ได้ดึงโครงการ PySide มาสานต่อเป็นโครงการ PySide2 ซึ่งถ้าเปิดใช้เป็นทางการเมื่อไหร่ ผมก็เป็นคนหนึ่งที่ตั้งหน้าตั้งตารอคอย

โครงการในอนาคต

ก็เป็นโครงการที่วาดฝันครับ คือพอร์ตโปรแกรม Surveyor Pocket Tools ลงบนมือถือด้วย Kivy framework คงแยกแต่ละ tool ไปเป็นแต่ละ app ซึ่งก็มีฟรีบ้างขายบ้าง ก็เป็นเรื่องอนาคตไม่ได้ตั้งความหวังอะไรมากมาย ปัจจุบันคือพัฒนาและปรับปรุงโปรแกรมทั้งหลายบน Desktop ให้ใช้งานกันต่อไป และยังยืนยันว่าฟรีเหมือนเดิม และความคิดก็ยังเหมือนเดิมครับ “โลกนี้จะน่าอยู่ ถ้าทุกคนแบ่งปัน ถ้อยทีถ้อยอาศัยกัน

ทิ้งท้ายกันนิดหนึ่งจากหัวข้อ “ปลดพันธนาการ” ก็ดูจะโหดร้ายไป ตั้งให้น่าสนใจแค่นั้นครับ PyQt5 นั้นเป็นเครื่องมือพัฒนาโปรแกรมที่ดีมาก มี document ให้อ่านเยอะแยะ ติดขัดตรงไหน Stackoverflow ช่วยได้ สำหรับคนใช้เครื่องมือเพื่อการค้า ก็อุดหนุนซื้อกันไป แต่ถ้าพัฒนาโปรแกรมแบบเปิดโค๊ดก็ตัวนี้เลย ไม่ผิดหวัง สำหรับผมขอเลือก PySide2 ด้วยเหตุผลที่กล่าวมาข้างต้นทั้งหมด พบกันตอนต่อไปครับ

Surveyor Pocket Tools โปรแกรมรวมเครื่องมือฉบับกระเป๋าสำหรับช่างสำรวจ (แจกฟรี) – ตอนที่ 1

ความเป็นมา

  • ปกติผมเป็นคนชอบพกเครื่องมือสารพัดประโยชน์เช่นมีดพับในกระเป๋ากางเกง เพราะสะดวกรวมทุกสิ่งทุกอย่างทั้งไขควง มีด กรรไกร ตะไบ ที่เปิดขวด ยี่ห้อที่ชอบได้แก่  Leatherman, Victorinox เมื่อสองปีที่แล้วไปโมซัมบิค อาฟริกา ท่านศุลกากรที่นั่นเปิดกระเป๋าเดินทางเพื่อตรวจก่อนออกจากสนามบิน  แอบสอย Victorinox ของผมไปหน้าตาเฉย เสียดายครับเพราะใช้มาหลายสิบปี แต่ก็อโหสิกรรมให้ท่านผู้นั้นไปแล้ว โปรแกรมที่จะแนะนำก็คล้ายกับมีดพับสารพัดประโยชน์แบบเดียวกัน
  • ที่ใช้บ่อยสำหรับคนที่ทำงานสนามคือโปรแกรมแปลงพิกัดค่ากริดยูทีเอ็ม (UTM) แปลงไป  แลตติจูด/ลองจิจูด (Geographic)  หรือกลับกัน ส่วนใหญ่จะเปิดคำนวณผ่านออนไลน์ ได้ค่ามาแล้ว บางทีก็ copy มาวางที่่  google earth หรือ google map  เพื่อปักหมุดให้รู้ว่าจุดตัวนั้นอยู่ตรงไหน หลายขั้นตอนบางครั้งรู้สึกรำคาญ
  • ไปๆมาๆ เขียนใช้เองดีกว่า ตรงใจที่สุด ป้อนค่าพิกัดเสร็จก็คลิกแปลงพิกัดทันที เสร็จแล้วก็ปักหมุดลงใน google maps ทันที

spt_intro

  • สิ่งที่ตั้งใจไว้ก็คือจะเขียนโปรแกรมคำนวณย่อยเล็กๆเอามารวมกัน ที่ใช้บ่อยในงานสนาม ตอนนี้โปรแกรมยังเป็นแค่รุ่น 0.35 รุ่นทดลองใช้ ยังมีอีกหลายอย่างที่จะใส่เพิ่มเข้ามาอีกในรุ่นหน้า ตอนนี้เอาแค่นี้ก่อน

ใครคือผู้ใช้งานโปรแกรม

  • ดูจากชื่อโปรแกรมเหมือนกับเอาไว้ให้ ช่างสำรวจใช้อย่างเดียว แต่ไม่ใช่ครับ ใครก็เอาไปใช้ได้ เพราะโปรแกรมผมได้พยายามออกแบบให้ใช้งานได้ง่ายๆ

ดาวน์โหลดและติดตั้ง

  • ดูลิ๊งค์ด้านขวามือ “ดาวน์โหลด (Download)” มองหาโปรแกรม Surveyor Pocket Tools จะมีรุ่นและ build ปกติดูที่ build เป็นหลัก เนื่องจากโปรแกรมนี้อยู่ในระหว่างพัฒนาตัวเลข build จะเพิ่มขึ้นเรื่อยๆ

 

  • คลิกเพื่อดาวน์โหลด เสร็จแล้วแตกไฟล์ zip ออกมาจะได้ไฟล์ .exe พร้อมทำการติดตั้ง เมื่อติดตั้งแล้วจะเห็นไอคอนรูปกล้องเซอร์เวย์

icon_sptเริ่มใช้งาน

  • เมื่อเปิดโปรแกรมมาจะเห็นหน้าตาดังรูปด้านล่าง แต่ละไอคอนจะมีโปรแกรมย่อยๆให้ใช้งาน

intro-surveyor-pokcet-tools

  • มาดูกันว่าแต่ละโปรแกรมย่อยทำอะไรได้บ้าง เรียงเลยครับจากบนลงล่าง

โปรแกรมแปลงพิกัดกริดยูทีเอ็ม (UTM – Geo Converter)

  • สำหรับแปลงพิกัดกริด UTM ได้แก่ค่า Northing(N), Easting(E) ไปค่าพิกัดภูมิศาสตร์ Latitude, Longitude  ในที่นี้จะแปลงค่าพิกัดบนรูปทรงรี WGS84 เท่านั้น แต่สามารถแปลงจากพิกัดภูมิศาสตร์ไปค่าพิกัดกริดยูทีเอ็ม เมื่อดับเบิ้ลคลิกที่ไอคอนจะเห็นหน้าต่างโปรแกรมแปลงพิกัดเล็กๆแสดงออกมาด้านขวา มีช่องพิกัดให้กรอกช่องด้านซ้ายหรือด้านขวา

spt_utm2geo-01

  • ช่องด้านซ้ายมือผู้อ่านจะเป็นช่องให้ป้อนค่าพิกัดกริดยูทีเอ็ม มีช่อง Point Name คือป้อนชื่อจุด และเรียงลงมาคือป้อนค่า N, E สุดท้ายต้องบอกโซนด้วยครับเพราะระบบกริดยูทีเอ็มมีหลายโซนทั้งโลก ค่าพิกัดอาจซ้ำกันถ้าไม่ระบุโซนจะไม่รู้เลยว่าอยู่ที่ไหน
  • ผมจะลองแปลงพิกัดจากกริดยูทีเอ็มไปหาค่าพิกัดภูมิศาสตร์ โดยที่จุดหรือหมุดมีค่าพิกัดดังนี้ ชื่อหมุด “006 -031” ค่า N = 1598702.276 ค่า E=707105.198 Zone No. = UTM Zone 47N ดังรูปด้านล่าง

spt_utm2geo-03

  • จากนั้นคลิกที่ไอคอนรูปลูกศรเพื่อแปลงค่าพิกัดจะเห็นค่าพิกัดแปลงไปเป็นค่าพิกัดภูมิศาสตร์ดังรูปด้านบน ล่างขวาจะเห็นรูปแบบที่จะแสดงมุมได้สามอย่างคือแบบทศนิยม แบบแยกองศา ลิปดา ฟิลิปดา (DD°MM’SS.SSSS”) และแบบที่สามคือองศา ทศนิยมของลิปดา (DD°MM.MMMM’)

spt_utm2geo-04

  • กรณีค่าแลตติจูดเป็นค่าบวกคืออยูเหนือเส้นศูนย์สูตร จะมีคำว่า “N” เป็น suffix ไปแปะไว้ด้านหลัง ถ้าอยู่ต่ำกว่าเส้นศูนย์สูตรจะใข้คำว่า “S”  เช่นเดียวกันกับค่าลองจิจูดถ้าค่าเป็นบวกจะใช้คำว่า “E” ย่อมาจาก East แปะด้านหลัง ถ้าค่าเป็นลบจะใช้คำ “W” ย่อมาจาก West  แปะไว้ด้านหลัง
  • ลองเปลี่ยนรูปแบบมุมเป็น DD°MM.MMMM’

spt_utm2geo-05

ปักหมุดบน Google Maps

  •   ต่อไปจะปักหมุดบน google maps กระบวนการนี้ต้องออนไลน์นะครับ  คลิกที่ไอคอนด้านล่างตามรูป โปรแกรมจะเรียก  web browser ที่ใช้งานมาแสดง

spt_utm2geo-06

  • รูปด้านล่างแสดง google maps พร้อมหมุดที่ปักแล้ว สะดวกดีครับ ดูตรง address bar จะเห็นว่าเรียกไฟล์จากเครื่องที่ติดตั้งโปรแกรมใช้งานอยู่ดูเหมือนจะออฟไลน์ แต่ไม่ใช่ครับ ยังออนไลน์สามารถซูมเข้าออกได้ปกติ

gm_006031

ปักหมุดบน Google Earth

  • มาลองปักหมุดบน google earth ดูกัน เครื่องที่ใช้ต้องติดตั้ง google earth ด้วยนะครับ คลิกที่ไอคอนดังรูปด้านล่าง

spt_utm2geo-07

  • โปรแกรมจะถามชื่อไฟล์เพื่อจัดเก็บไว้ เผื่อกรณีต้องการใช้ภายหลัง แล้วจะสวิชต์เข้าโปรแกรม google earth ทันที จะเห็นหมุดสีเหลืองปักกลางรูป

googleearth01

  • มาลองแปลงค่าพิกัดภูมิศาสตร์ไปเป็นค่าพิกัดกริดยูทีเอ็ม ทีนี้จะลองรูปแบบมุมเป็นทศนิยมดีกรี ผมป้อนค่าพิกัดที่อยู่ที่โมซัมบิค อาฟริกาที่เคยไปทำงานอยู่ดังรูป คลิกไอคอนเพื่อแปลงพิกัด

spt_utm2geo-08

  • จะเห็นว่าโปรแกรมจะแปลงพิกัดให้พร้อมทั้งคำนวณ UTM Zone ให้ได้ถูกต้อง จุดนี้อยู่ในประเทศโมซัมบิค ทวีปอาฟริกาอยู่ใต้เส้นศูนย์สูตรและยูทีเอ็มโซนคือ  UTM Zone 37S

spt_utm2geo-10

  • ลองปักหมุดบน google earth

googleearth02

จัดเก็บข้อมูลจุดที่ใช้งานเข้าฐานข้อมูล

  • เนื่องจากเป็นโปรแกรมขนาดเล็กๆ ไม่ได้ตั้งใจจะออกแบบให้อ่านเขียนไฟล์ข้อมูลได้เป็นเรื่องเป็นราว ผมจึงทำฐานข้อมูลขนาดเล็กๆ สามารถเก็บจุดที่ใช้งานได้ เผื่อต้องการเรียกนำมาใช้งานได้อีก ก็สามารถลากจากตารางฐานข้อมูลเข้าช่องป้อนตัวเลข
  • ต้องการจัดเก็บก็คลิกที่ไอคอนรูปหมุดที่มีเครื่องหมายบวก โปรแกรมจะถามคอนเฟิร์มอีกทีตอบ “OK”

spt_utm2geo-11

  • จากนั้นโปรแกรมจะเปิดตารางข้อมูล ตรวจสอบว่าข้อมูลเข้าไปเรียบร้อยแล้วดังรูป ส่วนจุดอื่นๆที่ปรากฎในตารางผมได้เพิ่มมาก่อนหน้านี้แล้ว

spt_utm2geo-12

วิธีใช้งานตารางข้อมูลกริดยูทีเอ็ม

  •  ในตอนนี้ผมจัดทำตาราง (Table) เก็บค่าพิกัดที่เป็นกริดแยกกับตารางที่เก็บค่าพิกัดภูมิศาสตร์ แต่อยู่ในฐานข้อมูลเดียวกัน มาดูวิธีใช้งาน คลิกที่ไอคอนดังรูป

spt_utm2geo_opentable-01

  • จะเห็นตารางข้อมูลขึ้นมา ตอนนี้จะใช้งาน ต้องการค่าพิกัดตัวไหนก็ใช้เมาส์เลื่อนสกรอลบาร์ไปได้ ถ้าคลิกที่ปุ่ม “First” จะไปที่ตัวแรก ถ้าคลิกที่ “Last”  จะไปที่ตัวสุดท้าย ถ้าต้องการลบก็คลิกที่ “Delete”
  • ตอนนี้สมมุติว่าผมต้องการค่าพิกัด “AC-01-GPS” มาใช้งาน คลิกเมาส์ที่ค่าพิกัดตัวนี้แล้วลากไปวางที่ช่อง UTM ดังรูป

spt_utm2geo_draganddrop-01

  • จะได้ค่าพิกัดจากตารางข้อมูลมาปรากฎในช่อง UTM ดังรูป แปลงพิกัดก็คลิกที่รูปลูกศรขวาได้เลย

spt_utm2geo_draganddrop-02

  • ลองลากค่าพิกัดกริดยูทีเอ็มจากตารางข้อมูลไปที่ช่อง Geographic เพื่อแปลงพิกัด

spt_utm2geo_draganddrop-03

  • โปรแกรมจะเตือนว่าผู้ใช้ต้องการแปลงพิกัด

spt_utm2geo_draganddrop-04

  • คลิก “OK” จะได้ผลลัพธ์

spt_utm2geo_draganddrop-05

วิธีการใช้ตารางข้อมูลค่าพิกัดภูมิศาสตร์

  • จากที่กล่าวไปแล้วตารางข้อมูล (table) มีสองแบบ ที่นี้มาลองใช้ตารางค่าพิกัดภูมิศาสตร์ดูบ้าง ตอนนี้จะจัดเก็บจุด “006-053” เข้าตารางข้อมูล คลิกที่ไอคอนรูปหมุดดังรูป

spt_ge2utm_draganddrop-02

  • จะเห็นตารางข้อมูลขึ้นมา และค่าพิกัดถูกจัดเก็บเข้าไปเรียบร้อยดังรูปด้านล่าง จะเห็นตารางข้อมูลสองตารางที่ลากขยับหน้าต่างเรียงกันใหม่

spt_geo_table

  • ลองคลิกไอคอนลูกศรไปทางซ้ายเพื่อแปลงพิกัดจากพิกัดภูมิศาสตร์ไปหาพิกัดกริดยูทีเอ็ม จะได้ค่าเดิมก่อนหน้านี้

โปรแกรมแปลงพิกัดข้ามพื้นหลักฐาน (Transform Coordinates)

  • โปรแกรมที่แล้วสำหรับแปลงพิกัดบนพื้นหลักฐาน WGS84 เท่านั้น แต่ถ้าต้องการแปลงข้ามพื้นหลักฐาน (datum) จะทำยังไง โปรแกรมที่สองที่ผมเขียนขึ้นมาเพื่อตอบโจทย์นี้ แต่เนื่องจาก datum และเส้นโครงแผนที่ (Map Projection) ในโลกนี้มันมีมากมายมหาศาลต่างประเทศต่างใช้หลากหลายกันไป สำหรับประเทศไทยมีสองพื้นหลักฐานที่ใช้กันคือ WGS84 และ Indian 1975 เส้นโครงแผนที่ของบ้านเราใช้ UTM
  • จากโปรแกรมหลักเมื่อคลิกโปรแกรมที่สอง จะเห็นหน้าตาแบบนี้  ด้านซ้ายเป็นระบบพิกัด ที่สามารถเลือกพิ้นหลักฐานและเส้นโครงแผนที่ได้ ด้านขวาก็เช่นเดียวกันสามารถเลือกได้อิสระ

surveyor-pocket-tools_2016-10-27_07-30-03

การป้อนรูปแบบของมุม

  • การป้อนมุมสำหรับโปรแกรมชุดนี้ ค่อนข้างต้องเป๊ะครับ ผมจะอธิบายให้พอเข้าใจ ถึงที่มาที่ไป ในทางโปรแกรมมิ่งผมใช้ที่เขาเรียกว่า Regular Express คอยสอดส่องว่าผู้ใช้กำลังป้อนอะไรเข้ามา ตรงไหนเป็นตัวเลข 0-9 ตัวไหนเป็นสัญลักษณ์เช่นองศา ° ลิปดา ‘ ฟิลิปดา ” หรือตรงไหนเป็นตัวอักษร d, N, S, E, W และต้องไม่มีช่องว่าง
  • รูปแบบ DD MM SS.SSSS เช่น 14°36’44.21988″N ต้องไม่มีช่องว่างและต้องป้อนสัญลักษณ์ให้ครบทั้งสาม แต่สัญลักษณ์องศาให้ใช้ตัว d แทนได้เช่น 14d36’44.21988″N 
  • โปรแกรมแก้ไขเรื่องป้อนมุม ดูที่  build 375 ขึ้นไป การป้อนมุมมีช่องว่างได้ครับ 14°36’44.21988″N สามารถป้อนแบบนี้ได้ 14d 36′ 44.21988″ N ถ้าป้อนไปแล้วผิดให้เอาเคอร์เซอร์มาไว้ที่ท้ายสุดแล้วกด backspace ไปเรื่อยๆ ดูโปรแกรมว่า build เท่าไหร่เปิดดูที่ About ครับ

surveyor-pocket-tools_2016-11-14_13-58-54

  • ก่อนจะมาว่ากันต่อคงต้องยกยอดไปตอนที่ 2 ครับ

เครดิตและโปรแกรมมิ่ง

  • โปรแกรมนี้สำเร็จมาใช้งานไม่ได้เลย ถ้าไม่มีไลบรารีภาษาไพธอน (Python) ที่แจกให้ใช้ฟรีเหล่านี้ ผมขอยกเครดิตความดีให้
    • PyProj โดย Jeff Whitaker ที่พัฒนามาจาก Proj.4 ช่วยให้งานคำนวณแปลงพิกัดข้ามพื้นหลักฐานอันุยุ่งยากกลายเป็นเรื่องง่าย
    • GeographicLib โดย Charles F. F. Karney ช่วยในการคำนวณระยะทางสั้นที่สุดบนอิลลิปซอยด์โดยวิธี Geodesic distance
    • SimpleKML โดย Kyle Lancaster ช่วยในการปักหมุดลงใน Google Earth
    • gmplot โดย Michael Woods ช่วยในการปักหมุดลง Google Maps
    • EGM96 เป็นโค้ดภาษาซี ผมแปลงเป็นภาษาไพธอนเพื่อคำนวณ Geoid Separation ด้วยโมเดล EGM96
    • EGM2008  เป็นโค้ดภาษาซี โค้ดดั้งเดิมอยู่ในโครงการ Geotrans เช่นกันผมแปลงเป็นภาษาไพธอน เพื่อนำมาคำนวณหา Geoid Separation ด้วยโมเดล EGM2008 แบบ 2.5′ x 2.5′
  • โปรแกรมพัฒนาด้วย Python 3.5 กราฟฟิค User Interface ด้วย PyQt5 ตอนนี้รุ่น 5.5.7 สภาพแวดล้อมในการพัฒนาโปรแกรมไพธอนใช้ Eric Python IDE ดีมากจนไม่เคยคิดจะกลับไปใช้ตัวอื่นอีกเลย
  • พบกันตอนใหม่ครับ

สิ้นสุดการรอคอย XSection Plot รุ่น 4.10 มาแล้ว ตอนที่ 3 (จบ)

10.การจัดเรียงรูปตัดบนกระดาษเขียนแบบ (Page Layout)

  • การจัดเรียงรูปตัด เลือกทูลบาร์และคลิกที่ “Page layout” ได้ดังรูป

page_layout_toolbar

  • ความยาวของรูปตัดแต่ละรูปตัด ความกว้างในแนวดิ่ง มาตราส่วน จะมีผลต่อขนาดของรูปตัดแต่ละรูป ที่่จะวางบนกระดาษเขียนแบบ  การจัดเรียงรูปตัดให้เหมาะสม ผู้ใช้สามารถเลือกจำนวนรูปตัดในแนวดิ่ง จำนวนรูปตัดในแนวนอน ลองตั้งค่าตามรูปด้านล่าง เนื่องจากข้อมูลที่เรากำลังทดลองใช้งานอยู่มี 4 รูปตัดและความกว้างของรูปตัดประมาณ 1300 เมตร จึงยาวจรดกระดาษซ้ายขวา จำนวนรูปตัดในแนวดิ่งจึงเลือกเป็น 1 ส่วนจำนวนรูปตัดในแนวนอนเลือกเป็น 4

page_layout_1

  • มาดูตั้งค่าให้กริดทางราบ จัดระยะราบจาก CL (ค่าที่ X = 0) ไปด้านซ้าย ตั้งไว้ 700 เมตร เผื่อยาวเกินกว่าข้อมูลไว้นิดหนึ่งไม่ให้รูปตัดไปชน ด้านขวาตั้งไว้ 650 เมตร ส่วนระยะราบของกริดแต่ละช่อง(grid spacing) เลือกไว้ 10 เมตร

page_layout_2

  • มาดูการตั้งกริดทางดิ่ง ผมตั้งไว้ 21 เมตร ระยะของช่องกริดทางดิ่ง (มาตราส่วน 1:200) 1 เมตร ดูรูปกราฟฟิคที่ลากลูกศรเชื่อมโยงด้านล่างเพื่อความเข้าใจ และตั้งระยะของช่องกริดทางดิ่ง 1 เมตร

page_layout_3

  • เวลาเปลี่ยนค่า ต้องกปุ่ม “Apply” เพื่อโปรแกรมจะได้จัดวางรูปตัดให้ใหม่ ถ้ารูปตัดทับซ้อนกันโปรแกรมจะเตือนให้ทราบ ผมเตรียมไอคอนบนทูลบาร์ด้านบน เพื่อ  copy ค่าพิกัดของรูปตัดเมื่อเทียบกับค่าพิกัดของกระดาษ มุมล่างซ้าย x,y = 0,0 หน่วยเป็น ซม.ครับ เมื่อคลิกที่ไอคอน โปรแกรมจะคัดลอกค่าพิกัดลงไปตารางข้อมูล จากนั้นคลิก “OK” เพื่อปิดหน้าต่างไดอะล็อก

page_layout_coors

  • บันทึกไฟล์ข้อมูลลงดิสค์ ให้เรียบร้อย

11.แสดงรูปตัดตามขวาง (Section Viewer)

  • ในที่สุดก็มาดูรูปตัดที่เราตั้งค่าไว้ ว่าตรงตามที่ต้องการหรือไม่ ที่ทูลบาร์ คลิก “Section Viewer”

section_viewer_toolbar

  • จะเห็นรูปตัดตามขวางแสดงผลมาให้ดูแต่ละ section ซึ่งจะเริ่มจาก section แรกก่อน ดังรูปด้านล่าง การขยาย ย่อ แผนที่ทำได้โดยการ scroll เมาส์ปุ่มกลางครับง่ายๆ ส่วนการเลื่อนแผนที่คลิกกดปุ่มกลางของเมาส์แล้วลาก

section_viewer_elements

  • ค่าที่เราตั้งค่าสำหรับรูปตัดไว้ก่อนหน้านี้ เช่นค่าระดับกริดเส้นบน (Top grid elevation) หรือไม่รูปแบบการเขียนตัวเลข จะส่งผลต่อรูปตัด พิจารณาดูรูปด้านล่างที่แสดงเส้นลูกศรเชื่อมโยง

section_viewer_shown_topgrid_int

  • ส่วนค่าอื่นๆเช่นตั้งค่าให้คำนวณหาพื้นที่ดินตัด (cut) หรือดินถม (fill) หรือหาจุดตัดระหว่าง typical  และเส้นดินเดิม

section_viewer_shown_calcarea_interval

  • สังเกตรูปตัดด้านบนจะเห็นว่าตัวรูปตัดตกจากเส้นกริดลงมาด้านล่างเนื่องจากค่าระดับกริดเส้นบนใส่ค่ามากไป จากที่โปรแกรมคำนวณมาให้ ลองกลับไปตั้งค่าใหม่จาก 6 เมตร เป็น 4 เมตร จะเห็นว่ารูปตัดเลื่อนขึ้นไปอยู่ในกริด แต่เส้น existing ground ล้นกริดด้านบนไปแทน ซึ่งสามารถ trim ออกได้ในโปรแกรมด้าน CAD ในภายหลัง

section_viewer_shown_new_topgrid_elev

  • นอกจากนี้เมื่อเลื่อนเมาส์ไปยังพื้นที่ดินตัดหรือดินถม โปรแกรมจะแสดงผล interactive ตรงพื้นที่รูปตัดจะสว่างขึ้นช่วยให้ผู้ใช้เห็นพื้นที่ได้ชัดเจน

section_viewer_interactive

  • ลองคลิกที่ลูกศรเพื่อขยับไปดูรูปตัดถัดไป เสร็จแล้วจะออกจากการแสดงผลก็คลิกที่ไอคอน รูปประตู

section_viewer_next_prev12.บันทึกไฟล์ Autocad DXF (Save to DXF)

  • เมื่อตั้งค่ารูปตัดทั้งหลายจนเป็นที่พอใจ กระบวนการสุดท้ายที่ต้องการคือ แผนที่แสดงรูปตัดตามขวาง ที่สามารถส่งงานกันได้ ซึ่งจะใช้โปรแกรมอะไรด้าน CAD ความสามารถโปรแกรมเหล่านี้คือสามารถอ่านเขียนไฟล์ฟอร์แม็ต dxf ได้เพราะเจ้าของคือ Autodesk เปิดเป็นสาธารณะ ที่ทูลบาร์เลือกคลิก “Save to DXF

save_to_dxf_toolbar

  • โปรแกรมจะแสดงไดอะล็อก คลิกที่รูปไอคอนรูปดิสเก็ตเพื่อเลือกโฟลเดอร์ที่จะจัดเก็บตลอดทั้งป้อนชื่อไฟล์ทึ่จะบันทึกเป็น dxf ดังรูป

save_to_dxf_inputfile

  • เมื่อเสร็จสิ้นโปรแกรมจะขึ้น message box ว่าจัดเก็บเรียบร้อย คลิก “OK” และ “Close” เพื่อปิด

save_to_dxf_ready

13.เปิดไฟล์ด้วยโปรแกรมด้าน CAD

  • โปรแกรมด้าน CAD ขนาดเล็กๆ เขียนแบบ 2มิติ ใช้งานได้ฟรีขอแนะนำ Draftsight ดาวน์โหลด ติดตั้งแล้วลงทะเบียนก็พร้อมใช้งาน ใช้งานง่ายสะดวกครับ (ยังมีรุ่นเสียตังค์ซื้อด้วย ถ้าต้องการ) ลองเปิดไฟล์ dxf ที่บันทึกเก็บไว้จะเห็นผลงานออกมาดังรูป

draftsight2d-first

  • จะเห็นว่าตัว hatch สำหรับพื้นที่ดินตัด ดินถม ทึบสนิท ทั้งๆที่ผมตั้ง scale ของแฮ็ทช์ไว้ 1.0 ปัญหาไม่ใช่ของ Draftsight แต่มาจากไฟล์ dxf ซึ่งผมคิดว่าน่าจะเป็นไลบรารีเขียน dxf ที่ผมใช้งานอยู่คือ ezdxf แต่ไม่เป็นไรวิธีแก้กลับคือไปคลิกเลือก hatch ทุก section ที่ property มองหา scale เจอแล้วจะเห็นตัวเลข 1.000 ป้อนค่าใหม่เป็น 10.000 (หรืออะไรก็ได้) จากนั้นป้อนกลับไปค่าเดิมอีกครั้งเป็น 1.000 เหมือนเดิม จะเห็น hatch เปลี่ยนเป็นโปร่งขึ้น
  • ปัญหา hatch นี้เปิดใน Autocad ก็เป็นครับ

 

draftsight2d-hatch_ok

  • ผมลองเปิดข้อมูลเก่าที่ Titleblock เป็นภาษาไทย ลองดูก็ใช้ได้บน Draftsight สำหรับ Draftsight แบบสองมิติ อ่านดูในเน็ตเห็นว่ารุ่นนี้ฟรี (แต่ต้องลงทะเบียน ซึ่งง่ายๆ ถามไม่กี่คำถาม) แต่ก็ไม่แน่ใจว่าฟรีไปตลอดหรือไม่ ซึ่งก็น่าใช้งานมากครับถ้าฟรีตลอด สำหรับท่านที่ใช้งานแคด ที่ไม่ได้มีงานสามมิติเข้ามาเกี่ยวข้อง ดีกว่าไปละเมิดลิขสิทธิ์

draftsight2d_thai_ok

สรุป

  • โปรแกรมนี้ใช้เวลาพัฒนาประมาณ 2 ปีกว่าๆ แต่ไม่ได้ต่อเนื่องนะครับ เนื่องจากเขียนเป็นงานอดิเรก ไม่มีความกดดันอะไร ถือว่าเป็นการศึกษาด้านโปรแกรมมิ่งในตัวโดยเฉพาะ python เขียนสนุก กระชับ ทรงพลัง มีแง่บางอย่างที่นึกไม่ถึงว่าภาษาสามารถทำได้ และที่สำคัญมีไลบรารีหรือโมดูลให้ใช้มากมาย ส่วนใหญ่ฟรี เมื่อมารวมกับ Qt framework ที่เก่งอยู่แล้ว โปรแกรมที่เขียนออกมาแล้วจึงดูเป็นมืออาชีพพอสมควร แต่ก็แจ้งเตือนก่อนว่าโปรแกรม XSection Plot รุ่นนี้ยังมีบั๊กอยู่บ้าง ถ้าพบก็แจ้งมาได้ที่ blog นี้
  • เกือบลืมบอกไป โปรแกรมนี้สนับสนุนจอ 4K เรียบร้อยแล้ว ไม่มีปัญหาเรื่องไอคอนเล็ก ตัวหนังสือเล็ก

xsectionplot_about

  • ก่อนจากกันก็ขอบอกว่าโปรแกรมทุกโปรแกรมที่ผมพัฒนาขึ้นมายังคง concept เหมือนเดิมคือให้ใช้ฟรี และสำหรับช่างสำรวจและช่างโยธา เหมือนเดิมครับ

สิ้นสุดการรอคอย XSection Plot รุ่น 4.10 มาแล้ว ตอนที่ 2

6.เปิดไฟล์ข้อมูล (Open file)

  • ขั้นตอนต่อไปจะมาเปิดไฟล์ข้อมูล เริ่มจากไฟล์ Typical section ที่จัดเก็บไว้ใน Documents ขั้นตอนตามรูปด้านล่าง ขั้นตอนที่ 3 เลือกประเภทของไฟล์เป็น .txml โปรแกรมจะอ่านข้อมูล และแสดงผลบนตารางในแท็บ “Typical section”

open_typical_section_file

  • ต่อไปเช่นเดียวกันเปิดไฟล์ Existing Ground section

open_ground_section_file

7.ป้อนข้อมูลโครงการ

  • ตอนนี้ข้อมูลของเราที่ได้จาก import  จาก text file มีแต่รูปตัดในตารางเท่านั้น เราจะทำการบันทึกข้อมูลโครงการของงาน นอกจากบันทึกเพื่อจำแล้วยังสามารถนำไปเขียนเป็น Titleblock ใน Autocad คลิกที่ Toolbar ดังรูปด้านล่างedit_titleblock
  • จะเห็นหน้าต่างไดอะล็อกให้ป้อนข้อมูล ถ้ามีข้อมูลอะไรให้ลบออกหมด เนื่องจากโปรแกรมจะบันทึกสถานะครั้งสุดท้ายที่ใช้เอาไว้set_project_info_procedure
  • ป้อนข้อมูลโครงการเข้าไป (ข้อมูลมาจากการสำรวจจริง แต่ชื่อโครงการ บริษัท ชื่อคน สมมุติหมด)

set_project_info_filled

เลือกภาษาให้  Titleblock

  • ที่ผมเตรียมไว้ให้มีภาษาไทยกับอังกฤษเท่านั้น ถ้าต้องการใช้ภาษาไทยก็คลิกตามรูป

set_project_info_locale

8.ตั้งขนาดกระดาษสำหรับเขียนแบบ (Page Setup)

  • สำหรับงานเขียนแบบใน Autocad แล้วขนาดกระดาษที่เราใช้มักจะเป็นขนาดกระดาษมาตรฐานได้แก่ A4, A3, A2, A1 และ A0 ขึ้นอยู่กับขนาด printer หรือ plotter ที่ใช้ด้วย ที่ทูลบาร์หลักคลิกที่ “Page Setup”

page_setup_toolbar

  • จะมีหน้าต่างไดอะล๊อกให้เลือกตั้งขนาดกระดาษ (ขนาดกระดาษกำหนดโดยผู้ใช้  Custom Paper Size โปรแกรมตอนนี้ยังไม่ support) เลือก A1 ดังรูป

page_setup

9.ตั้งค่ารูปตัด (Cross-section settings)

  • รูปแบบรูปตัดเช่นการเลือกมาตราส่วนทางราบและทางดิ่งให้ตรงกับความต้องการ การจัดรูปแบบตัวอักษร ค่า x,y (offset/elevation) หรือการตั้งจำนวนทศนิยม สามารถตั้งค่าได้ที่นี่ จากทูลบาร์หลักเลือก “Xsection Settings” ดังรูป

section_settings_toolbarตั้งค่าทั่วไป

  • จะเห็นหน้าต่างไดอะล็อก มีแท็บทั้งหมด 4 แท็บ แยกค่าที่จะตั้งเป็นสัดส่วน มาดูหน้าแรกสำหรับตั้งค่ารูปตัดทั่วๆไป

section_settings_page1_desc

  • ข้อสังเกตรูปตัดจะเห็นว่าใช้มาตราส่วนทางราบ 1 : 2000 คิดง่ายๆ ในแผนที่วัดได้ 1 มม. = ระยะจริงในสนามได้ 2 เมตร หรือในแผนที่วัดได 1 ซม. เท่ากับระยะจริงในสนาม 20 เมตร ขนาดกระดาษ A1 594 x 871 มม. แต่ขนาดที่ปริ๊นท์ได้เท่ากับ 517 x 817 มม. ถ้าวางกระดาษในแนวนอน (landscape) ความยาวคร่าวๆคือ 800 มม. สามารถเขียนแบบรูปตัดตามขวางได้เท่ากับระยะในสนาม = 2 x 800 เมตร = 1600 เมตร
  • ถ้ากลับไปดูข้อมูลในตารางจะเห็นว่าจากซ้ายไปขวาประมาณ 1300 เมตร ซึ่งกระดาษ A1 และมาตราส่วนนี้สามารถเขียนแบบได้โดยที่ไม่ล้นกระดาษ

ตั้งค่ารูปแบบตารางแสดงตัวเลข offset/elevation

  • จากหน้าต่างไดอะล็อก คลิกที่แท็บที่ 2 เลือกรูปแบบแสดงตัวเลข  offset/elevation  จาก 3 รูปแบบที่มีรูปตัวอย่างแสดงไว้ให้เห็นง่ายๆ ที่นี้ผมเลือก  Type 3 ดังรูปด้านล่าง

section_settings_page2_desc

ตั้งค่าตัวหนังสือคำหน้า/ตามหลัง ค่าระดับ datum

  •  ที่หน้าต่างไดอะล็อกคลิกที่แท็บตัวที่ 3 “Grid datum postfix/prefix” เลือกแบบที่สาม เขียนตัวหนังสือ CD (Chard Datum)  ตามหลังค่าระดับ 0.0  บางครั้งงานทางทะเลจะระบุว่าค่า 0.0 เมตร อิงอยู่กับอะไรเช่นน้ำทะเลปานกลาง (MSL) หรือ Chart Datum (CD)

section_settings_page3_desc

 ตั้งค่าระดับเส้นกริด

  • เป็นการตั้งค่าระดับเส้นกริดตัวบนสุด ปรับได้ตามต้องการเพื่อให้รูปตัดอยู่กลางๆรูปตัด จะได้ดูง่าย ไม่อึดอัด

section_settings_page4_desc

  • แต่ก็สามารถเลือกตั้งได้อัตโนมัติโดยโปรแกรม ดูรูปด้านล่างประกอบ เมื่อเสร็จสิ้นการตั้งค่ารูปตัด สามารถคลิกปุ่ม “OK” เพื่อออกจากไดอะล็อก

section_settings_page4_auto

  • ต่อไปบันทึกข้อมูลลงไฟล์ ที่เราแก้ไขตั้งค่ารูปตัด โปรแกรมจะเก็บค่าทั้งหลายเอาไว้ในไฟล์ Existing ground section รวมทั้งข้อมูล offset/elevation ในตารางทุก  section
  • ก่อนจะทำอะไรต่อ ให้คลิกรูปดิสค์เก็ตที่ทูลบาร์ เพื่อบันทึกข้อมูลลงดิสค์ โลกสวยด้วยมือเราครับ

เปิดดูไฟล์ข้อมูล

  • ลองเปิดไฟล์ข้อมูลด้วยโปรแกรมเช่น  Notepad, Notepad++  จะเห็นข้อมูลดังข้างล่าง (คลิกที่สี่เหลี่ยมลิ๊งค์ด้านล่าง เพื่อขยายออกมา)

[sourcecode language=”xml” collapse=”true” title=”ไฟล์ข้อมูล Existing ground section”]
<root version=”1.0″>
<!–Generated by XSection Plot–>
<!–This data file is Existing ground section–>
<Header>
<AppName>XSection Plot</AppName>
<Developer>Prajuab Riabroy</Developer>
<Version>4.1.512</Version>
<SectionType>Ground</SectionType>
<DateCreated>2016-08-15 21:09:30.751163</DateCreated>
</Header>
<ProjectInfo>
<ProjectName>Macuzy International Port</ProjectName>
<ClientName>MX Port Authority</ClientName>
<ContractorName>East West Construction &amp; Engineering</ContractorName>
<DrawingTitle>X-Section of Approach Channel</DrawingTitle>
<DrawnName>Sergio Motezia</DrawnName>
<ApprovedName>Prati Wisas</ApprovedName>
<ClientApprovedName>Mario P. Tenes</ClientApprovedName>
<CheckedName>Antonio Molibzo</CheckedName>
<SurveyorName>Suras Malcom</SurveyorName>
<SurveyedDate>1-7/03/2016</SurveyedDate>
<DrawingNo>2017-MZ-001-PLN-020</DrawingNo>
<SheetNo>1 / 50</SheetNo>
<DrawingDate>1-7/03/2016</DrawingDate>
<Revision></Revision>
<UseLocaleLanguage>False</UseLocaleLanguage>
<MapTexts>
<MapText Label=”Client” Locale=”เจ้าของโครงการ”/>
<MapText Label=”Contractor” Locale=”ผู้รับจ้าง”/>
<MapText Label=”Drawn” Locale=”เขียน”/>
<MapText Label=”Design” Locale=”ออกแบบ”/>
<MapText Label=”Surveyor” Locale=”ผู้สำรวจ”/>
<MapText Label=”Surveyed Date” Locale=”วันที่สำรวจ”/>
<MapText Label=”Checked” Locale=”ตรวจสอบ”/>
<MapText Label=”Approved” Locale=”อนุมัติ”/>
<MapText Label=”Client Approved” Locale=”ผู้คุมงานอนุมัติ”/>
<MapText Label=”Drawing No.” Locale=”แบบเลขที่”/>
<MapText Label=”Plotted Date” Locale=”แบบวันที่”/>
<MapText Label=”Project” Locale=”โครงการ”/>
<MapText Label=”Drawing Title” Locale=”แผนที่แสดง”/>
<MapText Label=”Sheet No.” Locale=”แบบเลขที่”/>
<MapText Label=”Scale” Locale=”มาตราส่วน”/>
<MapText Label=”Vertical” Locale=”ทางดิ่ง”/>
<MapText Label=”Horizontal” Locale=”ทางราบ”/>
<MapText Label=”Vertical Scale” Locale=”มาตราส่วนทางดิ่ง”/>
<MapText Label=”Horizontal Scale” Locale=”มาตราส่วนทางราบ”/>
<MapText Label=”Legend” Locale=”สัญลักษณ์”/>
<MapText Label=”Note” Locale=”หมายเหตุ”/>
<MapText Label=”Geodetic Information” Locale=”ข้อมูลระบบพิกัด”/>
<MapText Label=”No.” Locale=”ครั้งที่”/>
<MapText Label=”Amendments” Locale=”ความเห็น”/>
<MapText Label=”By” Locale=”โดย”/>
<MapText Label=”Date” Locale=”วันที่”/>
<MapText Label=”Revision” Locale=”ครั้งที่แก้ไข”/>
</MapTexts>
</ProjectInfo>
<SectionOptions>
<VerticalScale>200.0</VerticalScale>
<HorizontalScale>2000.0</HorizontalScale>
<HozGridSpace>10.0</HozGridSpace>
<VertGridSpace>1.0</VertGridSpace>
<GridLineType>0</GridLineType>
<CalcIntersection>True</CalcIntersection>
<CalcArea>True</CalcArea>
<TrimTypical>False</TrimTypical>
<NumDecimalElev>3</NumDecimalElev>
<NumDecimalDist>3</NumDecimalDist>
<UseIntervalText>True</UseIntervalText>
<IntervalDist>20.0</IntervalDist>
<PrefixText></PrefixText>
<PostfixText>CD</PostfixText>
<UsePostPrefix>0</UsePostPrefix>
<UseOffsetElevFormat>2</UseOffsetElevFormat>
<CalcPlotAreaCut>True</CalcPlotAreaCut>
<CalcPlotAreaFill>True</CalcPlotAreaFill>
<NumVertCLLeft>70</NumVertCLLeft>
<NumVertCLRight>65</NumVertCLRight>
<NumHozTopBottom>21</NumHozTopBottom>
<LeftSideText>LT.</LeftSideText>
<RightSideText>RT.</RightSideText>
<StationText>Km.</StationText>
<SelectedTBlock>2</SelectedTBlock>
<NumSectionRows>4</NumSectionRows>
<NumSectionColumns>1</NumSectionColumns>
<SurveyType>0</SurveyType>
<PlotTBlock>True</PlotTBlock>
<SwapLeftAndRight>False</SwapLeftAndRight>
</SectionOptions>
<PageSetup>
<Size>A1</Size>
<Width>817</Width>
<Height>570</Height>
</PageSetup>
<Sections>
<NumSections>4</NumSections>
<Section Name=”-0+078″>
<XPositionOnPaper>0.0</XPositionOnPaper>
<YPositionOnPaper>0.0</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>94</NumPoints>
<Points>
<Point Elevation=”5.696″ Offset=”-600.0″/>
<Point Elevation=”5.693″ Offset=”-596.305″/>
<Point Elevation=”5.337″ Offset=”-587.506″/>
<Point Elevation=”2.271″ Offset=”-526.489″/>
<Point Elevation=”0.579″ Offset=”-507.151″/>
<Point Elevation=”-1.19″ Offset=”-490.954″/>
<Point Elevation=”-2.314″ Offset=”-471.14″/>
<Point Elevation=”-2.766″ Offset=”-462.616″/>
<Point Elevation=”-2.875″ Offset=”-457.815″/>
<Point Elevation=”-3.6″ Offset=”-434.419″/>
<Point Elevation=”-4.104″ Offset=”-414.736″/>
<Point Elevation=”-4.128″ Offset=”-406.659″/>
<Point Elevation=”-4.356″ Offset=”-380.964″/>
<Point Elevation=”-4.382″ Offset=”-376.491″/>
<Point Elevation=”-4.406″ Offset=”-375.215″/>
<Point Elevation=”-4.989″ Offset=”-349.559″/>
<Point Elevation=”-5.161″ Offset=”-338.86″/>
<Point Elevation=”-5.347″ Offset=”-322.669″/>
<Point Elevation=”-5.812″ Offset=”-302.883″/>
<Point Elevation=”-5.942″ Offset=”-297.584″/>
<Point Elevation=”-6.148″ Offset=”-283.939″/>
<Point Elevation=”-6.342″ Offset=”-272.05″/>
<Point Elevation=”-6.387″ Offset=”-267.862″/>
<Point Elevation=”-6.733″ Offset=”-246.07″/>
<Point Elevation=”-7.111″ Offset=”-231.836″/>
<Point Elevation=”-7.372″ Offset=”-217.745″/>
<Point Elevation=”-7.824″ Offset=”-194.494″/>
<Point Elevation=”-7.882″ Offset=”-191.371″/>
<Point Elevation=”-7.834″ Offset=”-183.933″/>
<Point Elevation=”-7.668″ Offset=”-165.389″/>
<Point Elevation=”-8.54″ Offset=”-139.979″/>
<Point Elevation=”-8.98″ Offset=”-123.408″/>
<Point Elevation=”-9.255″ Offset=”-115.989″/>
<Point Elevation=”-9.487″ Offset=”-93.719″/>
<Point Elevation=”-9.566″ Offset=”-88.009″/>
<Point Elevation=”-9.732″ Offset=”-85.635″/>
<Point Elevation=”-11.591″ Offset=”-57.803″/>
<Point Elevation=”-11.779″ Offset=”-43.322″/>
<Point Elevation=”-11.967″ Offset=”-27.782″/>
<Point Elevation=”-11.928″ Offset=”-5.492″/>
<Point Elevation=”-11.967″ Offset=”-1.247″/>
<Point Elevation=”-12.16″ Offset=”11.274″/>
<Point Elevation=”-12.318″ Offset=”20.29″/>
<Point Elevation=”-12.301″ Offset=”22.958″/>
<Point Elevation=”-12.249″ Offset=”39.553″/>
<Point Elevation=”-12.303″ Offset=”48.517″/>
<Point Elevation=”-12.25″ Offset=”59.398″/>
<Point Elevation=”-12.081″ Offset=”76.972″/>
<Point Elevation=”-12.057″ Offset=”79.758″/>
<Point Elevation=”-12.02″ Offset=”83.034″/>
<Point Elevation=”-11.703″ Offset=”98.323″/>
<Point Elevation=”-11.569″ Offset=”104.196″/>
<Point Elevation=”-11.562″ Offset=”105.697″/>
<Point Elevation=”-11.365″ Offset=”116.141″/>
<Point Elevation=”-11.25″ Offset=”117.347″/>
<Point Elevation=”-10.732″ Offset=”135.54″/>
<Point Elevation=”-10.625″ Offset=”146.227″/>
<Point Elevation=”-10.077″ Offset=”158.793″/>
<Point Elevation=”-8.681″ Offset=”177.76″/>
<Point Elevation=”-8.592″ Offset=”181.044″/>
<Point Elevation=”-8.401″ Offset=”194.035″/>
<Point Elevation=”-8.271″ Offset=”203.535″/>
<Point Elevation=”-7.923″ Offset=”213.249″/>
<Point Elevation=”-7.728″ Offset=”217.373″/>
<Point Elevation=”-7.095″ Offset=”235.24″/>
<Point Elevation=”-6.982″ Offset=”241.693″/>
<Point Elevation=”-6.682″ Offset=”247.206″/>
<Point Elevation=”-6.075″ Offset=”256.627″/>
<Point Elevation=”-5.455″ Offset=”278.481″/>
<Point Elevation=”-5.337″ Offset=”282.26″/>
<Point Elevation=”-5.042″ Offset=”294.845″/>
<Point Elevation=”-5.019″ Offset=”295.988″/>
<Point Elevation=”-4.347″ Offset=”321.161″/>
<Point Elevation=”-4.189″ Offset=”329.073″/>
<Point Elevation=”-3.808″ Offset=”348.654″/>
<Point Elevation=”-3.664″ Offset=”355.277″/>
<Point Elevation=”-3.317″ Offset=”372.887″/>
<Point Elevation=”-3.154″ Offset=”382.261″/>
<Point Elevation=”-2.776″ Offset=”410.279″/>
<Point Elevation=”-2.765″ Offset=”410.995″/>
<Point Elevation=”-2.704″ Offset=”413.887″/>
<Point Elevation=”-2.197″ Offset=”439.138″/>
<Point Elevation=”-1.967″ Offset=”448.435″/>
<Point Elevation=”-1.716″ Offset=”464.705″/>
<Point Elevation=”-1.481″ Offset=”485.302″/>
<Point Elevation=”-1.403″ Offset=”489.714″/>
<Point Elevation=”-1.251″ Offset=”498.925″/>
<Point Elevation=”-0.928″ Offset=”517.874″/>
<Point Elevation=”-0.799″ Offset=”529.258″/>
<Point Elevation=”-0.604″ Offset=”548.73″/>
<Point Elevation=”-1.169″ Offset=”576.146″/>
<Point Elevation=”-1.18″ Offset=”579.205″/>
<Point Elevation=”-1.305″ Offset=”585.252″/>
<Point Elevation=”-1.468″ Offset=”600.0″/>
</Points>
</Section>
<Section Name=”0+172″>
<XPositionOnPaper>0.0</XPositionOnPaper>
<YPositionOnPaper>0.0</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>104</NumPoints>
<Points>
<Point Elevation=”4.21″ Offset=”-600.0″/>
<Point Elevation=”3.865″ Offset=”-590.197″/>
<Point Elevation=”3.192″ Offset=”-572.372″/>
<Point Elevation=”1.492″ Offset=”-534.461″/>
<Point Elevation=”-1.278″ Offset=”-510.761″/>
<Point Elevation=”-1.773″ Offset=”-506.708″/>
<Point Elevation=”-2.262″ Offset=”-496.208″/>
<Point Elevation=”-3.027″ Offset=”-480.587″/>
<Point Elevation=”-3.26″ Offset=”-473.089″/>
<Point Elevation=”-4.034″ Offset=”-454.61″/>
<Point Elevation=”-4.281″ Offset=”-430.868″/>
<Point Elevation=”-4.355″ Offset=”-425.789″/>
<Point Elevation=”-4.35″ Offset=”-412.009″/>
<Point Elevation=”-4.367″ Offset=”-398.744″/>
<Point Elevation=”-4.437″ Offset=”-394.505″/>
<Point Elevation=”-4.911″ Offset=”-371.013″/>
<Point Elevation=”-5.369″ Offset=”-344.896″/>
<Point Elevation=”-5.909″ Offset=”-321.896″/>
<Point Elevation=”-5.972″ Offset=”-318.479″/>
<Point Elevation=”-6.203″ Offset=”-307.947″/>
<Point Elevation=”-6.559″ Offset=”-290.298″/>
<Point Elevation=”-6.742″ Offset=”-282.919″/>
<Point Elevation=”-7.278″ Offset=”-261.654″/>
<Point Elevation=”-7.19″ Offset=”-241.456″/>
<Point Elevation=”-7.206″ Offset=”-234.351″/>
<Point Elevation=”-7.744″ Offset=”-212.894″/>
<Point Elevation=”-7.972″ Offset=”-205.898″/>
<Point Elevation=”-8.011″ Offset=”-204.056″/>
<Point Elevation=”-8.937″ Offset=”-181.613″/>
<Point Elevation=”-9.613″ Offset=”-169.45″/>
<Point Elevation=”-10.568″ Offset=”-155.252″/>
<Point Elevation=”-11.306″ Offset=”-139.728″/>
<Point Elevation=”-11.435″ Offset=”-136.455″/>
<Point Elevation=”-11.67″ Offset=”-122.543″/>
<Point Elevation=”-11.836″ Offset=”-115.516″/>
<Point Elevation=”-11.845″ Offset=”-113.826″/>
<Point Elevation=”-12.223″ Offset=”-102.969″/>
<Point Elevation=”-12.219″ Offset=”-100.525″/>
<Point Elevation=”-12.572″ Offset=”-83.796″/>
<Point Elevation=”-12.666″ Offset=”-73.185″/>
<Point Elevation=”-12.605″ Offset=”-61.703″/>
<Point Elevation=”-12.379″ Offset=”-44.437″/>
<Point Elevation=”-12.45″ Offset=”-41.849″/>
<Point Elevation=”-12.273″ Offset=”-20.661″/>
<Point Elevation=”-12.271″ Offset=”-15.995″/>
<Point Elevation=”-12.279″ Offset=”-14.536″/>
<Point Elevation=”-12.193″ Offset=”7.86″/>
<Point Elevation=”-12.049″ Offset=”12.127″/>
<Point Elevation=”-11.97″ Offset=”26.792″/>
<Point Elevation=”-11.482″ Offset=”39.803″/>
<Point Elevation=”-11.428″ Offset=”47.755″/>
<Point Elevation=”-11.244″ Offset=”53.548″/>
<Point Elevation=”-10.805″ Offset=”70.223″/>
<Point Elevation=”-10.718″ Offset=”74.57″/>
<Point Elevation=”-10.702″ Offset=”75.913″/>
<Point Elevation=”-10.087″ Offset=”96.66″/>
<Point Elevation=”-9.799″ Offset=”103.819″/>
<Point Elevation=”-9.63″ Offset=”112.183″/>
<Point Elevation=”-9.234″ Offset=”126.254″/>
<Point Elevation=”-8.999″ Offset=”137.384″/>
<Point Elevation=”-8.476″ Offset=”159.55″/>
<Point Elevation=”-8.445″ Offset=”160.778″/>
<Point Elevation=”-8.271″ Offset=”164.407″/>
<Point Elevation=”-7.259″ Offset=”184.045″/>
<Point Elevation=”-7.127″ Offset=”189.256″/>
<Point Elevation=”-6.92″ Offset=”198.448″/>
<Point Elevation=”-6.48″ Offset=”207.958″/>
<Point Elevation=”-6.04″ Offset=”221.897″/>
<Point Elevation=”-5.474″ Offset=”242.469″/>
<Point Elevation=”-5.364″ Offset=”247.769″/>
<Point Elevation=”-5.253″ Offset=”251.096″/>
<Point Elevation=”-4.998″ Offset=”265.24″/>
<Point Elevation=”-4.818″ Offset=”275.102″/>
<Point Elevation=”-4.715″ Offset=”277.979″/>
<Point Elevation=”-4.027″ Offset=”298.699″/>
<Point Elevation=”-3.738″ Offset=”309.727″/>
<Point Elevation=”-3.575″ Offset=”322.408″/>
<Point Elevation=”-3.105″ Offset=”340.851″/>
<Point Elevation=”-2.937″ Offset=”346.115″/>
<Point Elevation=”-2.855″ Offset=”359.315″/>
<Point Elevation=”-2.833″ Offset=”366.127″/>
<Point Elevation=”-2.816″ Offset=”367.498″/>
<Point Elevation=”-2.675″ Offset=”385.31″/>
<Point Elevation=”-2.596″ Offset=”391.895″/>
<Point Elevation=”-2.673″ Offset=”406.1″/>
<Point Elevation=”-2.465″ Offset=”418.482″/>
<Point Elevation=”-2.516″ Offset=”427.315″/>
<Point Elevation=”-2.328″ Offset=”445.356″/>
<Point Elevation=”-2.337″ Offset=”446.342″/>
<Point Elevation=”-2.626″ Offset=”452.604″/>
<Point Elevation=”-3.486″ Offset=”470.977″/>
<Point Elevation=”-3.693″ Offset=”476.912″/>
<Point Elevation=”-3.777″ Offset=”496.074″/>
<Point Elevation=”-3.932″ Offset=”501.72″/>
<Point Elevation=”-4.018″ Offset=”513.362″/>
<Point Elevation=”-3.474″ Offset=”529.259″/>
<Point Elevation=”-3.265″ Offset=”532.878″/>
<Point Elevation=”-2.893″ Offset=”543.264″/>
<Point Elevation=”-2.834″ Offset=”544.691″/>
<Point Elevation=”-2.372″ Offset=”551.966″/>
<Point Elevation=”-1.374″ Offset=”568.651″/>
<Point Elevation=”-1.184″ Offset=”572.608″/>
<Point Elevation=”-0.9″ Offset=”589.873″/>
<Point Elevation=”-0.265″ Offset=”600.0″/>
</Points>
</Section>
<Section Name=”0+422″>
<XPositionOnPaper>0.0</XPositionOnPaper>
<YPositionOnPaper>0.0</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>98</NumPoints>
<Points>
<Point Elevation=”2.527″ Offset=”-600.0″/>
<Point Elevation=”1.923″ Offset=”-583.886″/>
<Point Elevation=”1.147″ Offset=”-573.7″/>
<Point Elevation=”0.148″ Offset=”-560.844″/>
<Point Elevation=”-1.561″ Offset=”-534.717″/>
<Point Elevation=”-1.604″ Offset=”-534.134″/>
<Point Elevation=”-2.764″ Offset=”-502.908″/>
<Point Elevation=”-3.147″ Offset=”-490.643″/>
<Point Elevation=”-3.634″ Offset=”-472.527″/>
<Point Elevation=”-4.199″ Offset=”-442.515″/>
<Point Elevation=”-4.26″ Offset=”-440.183″/>
<Point Elevation=”-4.353″ Offset=”-435.493″/>
<Point Elevation=”-4.626″ Offset=”-412.074″/>
<Point Elevation=”-4.836″ Offset=”-400.43″/>
<Point Elevation=”-4.963″ Offset=”-383.964″/>
<Point Elevation=”-5.335″ Offset=”-361.676″/>
<Point Elevation=”-5.378″ Offset=”-357.711″/>
<Point Elevation=”-5.461″ Offset=”-354.483″/>
<Point Elevation=”-5.587″ Offset=”-348.617″/>
<Point Elevation=”-6.599″ Offset=”-306.504″/>
<Point Elevation=”-6.923″ Offset=”-292.309″/>
<Point Elevation=”-7.646″ Offset=”-260.816″/>
<Point Elevation=”-7.665″ Offset=”-260.005″/>
<Point Elevation=”-8.267″ Offset=”-238.897″/>
<Point Elevation=”-9.466″ Offset=”-215.915″/>
<Point Elevation=”-9.939″ Offset=”-205.494″/>
<Point Elevation=”-10.636″ Offset=”-192.184″/>
<Point Elevation=”-11.499″ Offset=”-177.238″/>
<Point Elevation=”-11.845″ Offset=”-170.731″/>
<Point Elevation=”-12.281″ Offset=”-152.944″/>
<Point Elevation=”-12.343″ Offset=”-150.873″/>
<Point Elevation=”-12.345″ Offset=”-150.114″/>
<Point Elevation=”-12.485″ Offset=”-127.286″/>
<Point Elevation=”-12.474″ Offset=”-120.381″/>
<Point Elevation=”-12.427″ Offset=”-111.488″/>
<Point Elevation=”-12.447″ Offset=”-105.883″/>
<Point Elevation=”-12.651″ Offset=”-87.792″/>
<Point Elevation=”-12.622″ Offset=”-78.078″/>
<Point Elevation=”-12.53″ Offset=”-55.591″/>
<Point Elevation=”-12.495″ Offset=”-52.513″/>
<Point Elevation=”-12.115″ Offset=”-31.23″/>
<Point Elevation=”-12.009″ Offset=”-23.783″/>
<Point Elevation=”-11.488″ Offset=”-9.776″/>
<Point Elevation=”-11.236″ Offset=”4.184″/>
<Point Elevation=”-10.416″ Offset=”13.232″/>
<Point Elevation=”-10.641″ Offset=”20.134″/>
<Point Elevation=”-10.28″ Offset=”44.002″/>
<Point Elevation=”-10.292″ Offset=”44.652″/>
<Point Elevation=”-10.289″ Offset=”44.792″/>
<Point Elevation=”-10.828″ Offset=”56.567″/>
<Point Elevation=”-10.797″ Offset=”59.917″/>
<Point Elevation=”-10.401″ Offset=”76.981″/>
<Point Elevation=”-10.186″ Offset=”85.234″/>
<Point Elevation=”-10.076″ Offset=”91.139″/>
<Point Elevation=”-9.671″ Offset=”106.374″/>
<Point Elevation=”-9.556″ Offset=”114.729″/>
<Point Elevation=”-9.018″ Offset=”131.881″/>
<Point Elevation=”-8.96″ Offset=”133.976″/>
<Point Elevation=”-8.938″ Offset=”135.194″/>
<Point Elevation=”-8.59″ Offset=”157.634″/>
<Point Elevation=”-8.516″ Offset=”163.615″/>
<Point Elevation=”-8.379″ Offset=”182.167″/>
<Point Elevation=”-8.093″ Offset=”194.118″/>
<Point Elevation=”-7.878″ Offset=”204.774″/>
<Point Elevation=”-7.548″ Offset=”221.957″/>
<Point Elevation=”-7.482″ Offset=”225.607″/>
<Point Elevation=”-7.519″ Offset=”237.596″/>
<Point Elevation=”-7.537″ Offset=”244.959″/>
<Point Elevation=”-7.524″ Offset=”247.228″/>
<Point Elevation=”-7.202″ Offset=”265.159″/>
<Point Elevation=”-6.937″ Offset=”273.625″/>
<Point Elevation=”-6.791″ Offset=”280.238″/>
<Point Elevation=”-6.674″ Offset=”286.833″/>
<Point Elevation=”-6.486″ Offset=”295.474″/>
<Point Elevation=”-6.408″ Offset=”313.252″/>
<Point Elevation=”-6.365″ Offset=”316.221″/>
<Point Elevation=”-6.294″ Offset=”327.463″/>
<Point Elevation=”-6.2″ Offset=”337.22″/>
<Point Elevation=”-6.207″ Offset=”338.339″/>
<Point Elevation=”-5.867″ Offset=”355.513″/>
<Point Elevation=”-5.65″ Offset=”362.307″/>
<Point Elevation=”-5.567″ Offset=”375.271″/>
<Point Elevation=”-5.433″ Offset=”387.259″/>
<Point Elevation=”-5.152″ Offset=”396.436″/>
<Point Elevation=”-4.378″ Offset=”413.203″/>
<Point Elevation=”-4.146″ Offset=”425.427″/>
<Point Elevation=”-4.099″ Offset=”435.841″/>
<Point Elevation=”-3.993″ Offset=”439.726″/>
<Point Elevation=”-3.418″ Offset=”457.353″/>
<Point Elevation=”-2.943″ Offset=”467.452″/>
<Point Elevation=”-2.548″ Offset=”480.037″/>
<Point Elevation=”-1.52″ Offset=”499.033″/>
<Point Elevation=”-1.085″ Offset=”505.573″/>
<Point Elevation=”-0.707″ Offset=”509.068″/>
<Point Elevation=”-0.564″ Offset=”514.17″/>
<Point Elevation=”1.044″ Offset=”545.131″/>
<Point Elevation=”3.671″ Offset=”586.351″/>
<Point Elevation=”4.257″ Offset=”600.0″/>
</Points>
</Section>
<Section Name=”0+672″>
<XPositionOnPaper>0.0</XPositionOnPaper>
<YPositionOnPaper>0.0</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>101</NumPoints>
<Points>
<Point Elevation=”0.751″ Offset=”-600.0″/>
<Point Elevation=”0.17″ Offset=”-590.282″/>
<Point Elevation=”-0.185″ Offset=”-585.509″/>
<Point Elevation=”-1.698″ Offset=”-564.455″/>
<Point Elevation=”-2.012″ Offset=”-556.049″/>
<Point Elevation=”-2.541″ Offset=”-536.428″/>
<Point Elevation=”-2.738″ Offset=”-526.646″/>
<Point Elevation=”-3.164″ Offset=”-510.314″/>
<Point Elevation=”-3.581″ Offset=”-498.217″/>
<Point Elevation=”-3.967″ Offset=”-482.548″/>
<Point Elevation=”-4.17″ Offset=”-466.638″/>
<Point Elevation=”-4.63″ Offset=”-454.111″/>
<Point Elevation=”-4.885″ Offset=”-437.444″/>
<Point Elevation=”-4.739″ Offset=”-426.605″/>
<Point Elevation=”-4.755″ Offset=”-407.163″/>
<Point Elevation=”-4.887″ Offset=”-399.338″/>
<Point Elevation=”-5.348″ Offset=”-377.159″/>
<Point Elevation=”-5.455″ Offset=”-371.865″/>
<Point Elevation=”-6.085″ Offset=”-345.987″/>
<Point Elevation=”-6.145″ Offset=”-343.34″/>
<Point Elevation=”-6.428″ Offset=”-331.877″/>
<Point Elevation=”-6.448″ Offset=”-330.864″/>
<Point Elevation=”-7.104″ Offset=”-309.854″/>
<Point Elevation=”-7.356″ Offset=”-296.783″/>
<Point Elevation=”-7.378″ Offset=”-295.786″/>
<Point Elevation=”-8.31″ Offset=”-272.558″/>
<Point Elevation=”-9.344″ Offset=”-249.668″/>
<Point Elevation=”-9.524″ Offset=”-246.49″/>
<Point Elevation=”-10.115″ Offset=”-236.3″/>
<Point Elevation=”-10.351″ Offset=”-218.394″/>
<Point Elevation=”-10.714″ Offset=”-213.348″/>
<Point Elevation=”-11.674″ Offset=”-204.751″/>
<Point Elevation=”-11.699″ Offset=”-201.381″/>
<Point Elevation=”-11.744″ Offset=”-193.463″/>
<Point Elevation=”-12.329″ Offset=”-178.033″/>
<Point Elevation=”-12.592″ Offset=”-165.284″/>
<Point Elevation=”-12.777″ Offset=”-155.308″/>
<Point Elevation=”-12.43″ Offset=”-144.408″/>
<Point Elevation=”-12.528″ Offset=”-139.081″/>
<Point Elevation=”-12.669″ Offset=”-133.221″/>
<Point Elevation=”-12.262″ Offset=”-121.876″/>
<Point Elevation=”-12.13″ Offset=”-110.999″/>
<Point Elevation=”-12.286″ Offset=”-98.019″/>
<Point Elevation=”-12.367″ Offset=”-89.578″/>
<Point Elevation=”-11.654″ Offset=”-75.025″/>
<Point Elevation=”-11.598″ Offset=”-71.369″/>
<Point Elevation=”-12.418″ Offset=”-63.45″/>
<Point Elevation=”-12.586″ Offset=”-57.395″/>
<Point Elevation=”-12.029″ Offset=”-40.428″/>
<Point Elevation=”-11.941″ Offset=”-37.225″/>
<Point Elevation=”-12.05″ Offset=”-17.903″/>
<Point Elevation=”-11.919″ Offset=”-14.255″/>
<Point Elevation=”-10.878″ Offset=”5.213″/>
<Point Elevation=”-10.987″ Offset=”7.781″/>
<Point Elevation=”-12.241″ Offset=”17.876″/>
<Point Elevation=”-12.175″ Offset=”19.902″/>
<Point Elevation=”-12.679″ Offset=”37.309″/>
<Point Elevation=”-12.779″ Offset=”41.445″/>
<Point Elevation=”-12.756″ Offset=”41.967″/>
<Point Elevation=”-12.147″ Offset=”62.308″/>
<Point Elevation=”-12.189″ Offset=”63.587″/>
<Point Elevation=”-11.804″ Offset=”83.447″/>
<Point Elevation=”-11.748″ Offset=”85.224″/>
<Point Elevation=”-11.68″ Offset=”105.223″/>
<Point Elevation=”-11.648″ Offset=”107.415″/>
<Point Elevation=”-11.299″ Offset=”124.477″/>
<Point Elevation=”-11.183″ Offset=”129.8″/>
<Point Elevation=”-10.608″ Offset=”145.77″/>
<Point Elevation=”-10.491″ Offset=”152.394″/>
<Point Elevation=”-10.528″ Offset=”156.006″/>
<Point Elevation=”-10.486″ Offset=”170.955″/>
<Point Elevation=”-10.376″ Offset=”180.254″/>
<Point Elevation=”-10.183″ Offset=”192.924″/>
<Point Elevation=”-10.122″ Offset=”198.333″/>
<Point Elevation=”-9.995″ Offset=”209.165″/>
<Point Elevation=”-9.803″ Offset=”220.192″/>
<Point Elevation=”-9.727″ Offset=”230.156″/>
<Point Elevation=”-9.793″ Offset=”235.687″/>
<Point Elevation=”-9.444″ Offset=”249.066″/>
<Point Elevation=”-9.308″ Offset=”258.031″/>
<Point Elevation=”-9.253″ Offset=”261.971″/>
<Point Elevation=”-8.511″ Offset=”283.111″/>
<Point Elevation=”-8.163″ Offset=”289.464″/>
<Point Elevation=”-7.102″ Offset=”307.459″/>
<Point Elevation=”-6.902″ Offset=”312.383″/>
<Point Elevation=”-6.731″ Offset=”322.229″/>
<Point Elevation=”-6.609″ Offset=”326.578″/>
<Point Elevation=”-6.011″ Offset=”346.572″/>
<Point Elevation=”-5.822″ Offset=”350.33″/>
<Point Elevation=”-4.461″ Offset=”371.66″/>
<Point Elevation=”-4.318″ Offset=”373.491″/>
<Point Elevation=”-1.818″ Offset=”396.911″/>
<Point Elevation=”-1.583″ Offset=”398.654″/>
<Point Elevation=”1.249″ Offset=”416.959″/>
<Point Elevation=”1.897″ Offset=”437.491″/>
<Point Elevation=”3.568″ Offset=”467.863″/>
<Point Elevation=”6.567″ Offset=”551.744″/>
<Point Elevation=”6.606″ Offset=”552.895″/>
<Point Elevation=”6.604″ Offset=”553.18″/>
<Point Elevation=”6.591″ Offset=”553.868″/>
<Point Elevation=”5.965″ Offset=”600.0″/>
</Points>
</Section>
</Sections>
</root>

[/sourcecode]

จบตอนที่ 2

  • พบกันตอนหน้า ตอนที่ 3 ครับ

สิ้นสุดการรอคอย XSection Plot รุ่น 4.10 มาแล้ว ตอนที่ 1

ถึงจะล่าช้าแต่ก็มาตามสัญญา

  • โปรแกรมเขียนรูปตัดตามขวาง XSection Plot รุ่นนี้รุ่น 4.10 มาแทนรุ่นเดิม 3.25 ที่ปลดระวางด้วยเนื่องจากอายุมากร่วมสองทศวรรษ แต่ขอแจ้งไว้ก่อนรุ่นนี้ยังเป็นรุ่นทดลองใช้ (beta) นะครับ เพราะยังมีบั๊กอยู่บ้าง แต่โดยรวมใช้งานได้

xsectionplotv410-intro

ความเป็นมาของโปรแกรม

  • อ่านความเป็นมาของโปรแกรมได้อย่างละเอียดที่ => ก้าวต่อไปของโปรแกรมเขียนรูปตัดตามขวาง XSection Plot ในร่างใหม่พัฒนาด้วย Python + Qt
  • และที่ => ก้าวที่ใกล้กับโปรแกรมเขียนรูปตัดตามขวาง XSection Plot รุ่นใหม่
  • ก็ขอเท้าความเป็นมาโปรแกรมสักนิดเผื่อผู้อ่านไม่ได้ติดตามมาก่อน โปรแกรมเขียนรูปตัดตามขวาง XSection Plot รุ่นเดิมพัฒนาด้วย VB อายุอานามเกือบยี่สิบปีแล้วครับ ใช้ได้ดีตอนวินโดส์ XP แต่หลังมาวินโดส์ 7, 8 และวินโดส์ 10 ก็มีปัญหากับการติดตั้งเรื่อยมา เพราะโปรแกรมยังใช้ library ของวินโดส์รุ่นเก่า พอเจอวินโดส์ใหม่หาไลบรารีไม่เจอ ผมเขียนใหม่ด้วยภาษาไพธอน (Python) ใช้ระบบกราฟฟิคเฟรมเวิร์คของ Qt รวมๆเรียกว่า PyQt
  • ขณะที่พัฒนานี้ใช้ Python 3.5 ส่วน Qt ใช้ PyQt รุ่น 5.6 ส่วน Qt เป็นเฟรมเวิร์คที่ใหญ่โตมากๆ อ่านคู่มือไม่ไหว ก็จะเลือกอ่านแต่เท่าที่ใช้ แน่นอนสิ่งที่ทำให้ผมโปรแกรมได้สำเร็จยกเครดิตให้ stackoverflow.com ถ้าไม่มีเวปไซต์ถามและตอบปัญหาการเขียนโปรแกรมนี้ ยังคิดว่าจะเขียนโปรแกรมได้อย่างไร มีปัญหาอะไร เข้าไปค้นหาทีไร ก็เจอคำตอบทุกที จะมีคนที่มีปัญหาแบบเรามาถามก่อนเรา พร้อมมีคนมาตอบให้ ส่วนใหญ่ 99% คำตอบสามารถนำไปใช้งานต่อยอดได้

สาเหตุแห่งความล่าช้า

  • เรื่องความรู้ความเข้าใจภาษาไพธอน อาจจะไม่ใช่ปัญหานักเนื่องจากไพธ่อนเป็นภาษาที่เรียบง่ายแต่ทรงพลัง ปัญหาของผมลำดับแรกคือ Qt Framework ที่เกี่ยวกับกราฟฟิค ศึกษาได้ค่อนข้างช้า ก่อนหน้านี้ไปทุ่มให้กับ wxPython ที่เป็น GUI Framework ที่ใช้ wxWidget ทำให้เสียเวลาไปมาก  พูดอย่างนี้ไม่ใช่ wxPython ไม่ดีนะครับเพียงแต่ส่วนตัวแล้วไม่ชอบ มาเจอ Qt นี่ใช่เลย
  • ความล่าช้าลำดับที่สอง คือไลบรารีที่ผมเอามาเขียนไฟล์ Autocad DXF ใช้ ezdxf เป็นโครงการเปิดซอร์ส ตัวไลบรารีใช้งานง่าย เก่งมาก ผมลองสมมุติว่าถ้าให้ผมเขียนไลบรารีนี้เอง คงไม่มีปัญญาเป็นแน เพราะผู้พัฒนาเข้าใจถ่องแท้มาก ทั้งโครงสร้างของ  DXF ที่รุ่นหลังๆค่อนข้างซับซ้อนพอสมควร ปัญหาของผมอยู่ที่คอมไพล์โปรแกรมเพื่อสร้างไฟล์ execute ที่เป็นไบนารี .exe ตอนแรกใช้ py2exe กลับไม่สามารถรันได้ พอเปิดโปรแกรมใช้งานพอเรียกใช้ไลบรารีนี้จะ crash ทันที ตอนแรกหาสาเหตุไม่เจอ ตอนหลังมาทราบว่ามี่ไฟล์ที่ไลบรารี ezdxf ที่ต้องการใช้ แต่ py2exe ไม่ได้ใส่ไปให้ด้วย คือ py2exe จะสร้างไฟล์ไลบรารีที่โปรแกรมเรียกใช้ทั้งหมดแล้ว zip ไว้ แต่ขาดไฟล์บางไฟล์ของ ezdxf
  • ผมหันมาใช้ pyinstaller คอมไพล์และสร้างไฟล์  .exe สำเร็จเนื่องจาก pyinstaller ใช้วิธีการที่ง่ายกว่าแบบคิดไม่ถึงและก็ยืดหยุ่นมาก ตอนนี้เทใจให้กับ pyinstaller เมื่อได้ไฟล์ execute มาก็ไม่ยากแล้วทำไฟล์ติดตั้ง (setup) ด้วย Inno Setup เจ้าเดิมที่ผมใช้ประจำ เพราะฟรี ใช้งานง่าย

จุดประสงค์ของโปรแกรม

  • เนื่องจากจุดกำเนิดโปรแกรมนี้เริ่มต้นในยุค PC กับวินโดส์ที่กำลังรุ่งเรืองคือวินโดส์ 98 ที่โปรแกรมด้าน Civil/Survey ยังไม่เก่ง การเขียนรูปตัดจึงค่อนข้างจะใช้มือแบบแมนวลคือเน้นป้อนเข้าตาราง ต่อมาเริ่มมีโปรแกรมด้าน Civil/Survey เช่น Land desktop, Terramodel, โปรแกรมตระกูล Microstation เช่น PowerCivil, Inroads ประมาณนี้ หลายๆโปรแกรมสามารถ export รูปตัดเป็น text file ได้ ผมก็พัฒนาโปรแกรมให้สามารถอ่านเข้ามาโปรแกรม XSection Plot เพื่อจัดรูปแบบและสามารถนำไฟล์เข้าโปรแกรมจำพวก CAD ได้
  • ปัจจุบัน Terramodel, Land desktop หยุดพัฒนาไปหลายปี แต่ผู้พัฒนาหันมาพัฒนาตัวใหม่ที่เก่งกว่าเดิมเช่น Trimble Business Center (TBC) ของค่าย Trimble และค่าย Autodesk ก็มี Autodesk Civil3D เป็นโปรดัคเรือธง ผมลองใช้มาหมดแล้วครับ ยอมรับความสามารถเก่งกาจไปไกล แต่ราคาต่อไลเซนต์ก็สูงมากโข ถามกันจริงๆ ถ้าจะซื้อมาใช้แบบไลเซนต์ จะมีผู้ใช้ที่ไม่ใช่องค์กรสักกี่คนที่มีปัญญาซื้อมาใช้งานได้ นี่เป็นปัญหาอย่างหนึ่ง

ดาวน์โหลดและติดตั้ง

  • ดาวน์โหลดได้ที่ XSectionPlotV410b867Setup64.zip หรือดูด้านขวามือตรง ดาวน์โหลด (Download) มองหาลิ๊งค์สำหรับติดตั้งโปรแกรม  “XSection Plot V4.10” ในเบื้องต้นมีเฉพาะรุ่น 64 บิต (สำหรับรุ่น 32 บิต รออีกสักพักครับ) ดาวน์โหลดมาแล้ว ขนาดโปรแกรมไม่ใหญ่ประมาณ 16 MB จากนั้นก็ติดตั้งได้ง่ายๆ ติดตั้งแล้วจะเห็น icon ขึ้นมาบน Desktop ดังรูปด้านล่าง

xsectionplot_icon

พาทัวร์โปรแกรมทดลองใช้งาน

  • ต่อไปผมจะพาลองทดลองใช้โปรแกรมคร่าวๆ พาทัวร์การใช้งานรวดเดียวจบ ผมมีไฟล์ตัวอย่าง ตอนติดตั้งโปรแกรมจะไปอยู่ในโฟลเดอร์ของวินโดส์ C:\Users\ชื่อผู้ใช้\AppData\Roaming\XSection Plot\examples data โฟลเดอร์นี้จะถูกซ่อนอัตโนมัติ ผู้ใช้หน้าใหม่ๆอาจจะหาไม่เจอ กรณีหาไม่เจอผมเตรียมตัวช่วยไว้
  • เปิดโปรแกรมมาครั้งแรกจะเห็นว่าตารางโล่งไม่มีข้อมูล

xsectionplotv410-firstload

1.ที่จัดเก็บข้อมูลตัวอย่าง

  • เปิดเมนู Help เลือกคลิกที่ “Example data”

help_examples_data

  • โปรแกรมจะเปิด windows explorer ของวินโดส์มาให้ มองไปจะเห็นโฟลเดอร์ “examples data”

examples_data_folder

  • จากนั้น double click เข้าไปที่โฟลเดอร์ “example data\mz\import files” จะเห็นไฟล์อยู่สองไฟล์ มาถึงตรงนี้ขอให้คลิกแถบ path ดังรูปแล้วก็ใช้เมาส์คลิกขวาเลือก copy ตอนนี้ path อยู่ในคลิปบอร์ดแล้ว ต่อไปจะใช้โปรแกรม XSection Plot ทำการ import ข้อมูลที่อยู่ในพาทนี้เข้าโปรแกรม

mz_import_files_folder

2.นำข้อมูลดินเดิมเข้าโปรแกรม (Import file)

  • คลิก Import text file ที่ไอคอนตามรูปเพื่อจะนำเข้าไฟล์รูปตัด จะเห็นไดอะล็อกของ Import XSection text file ขึ้นมา คลิกที่ไอคอน Open เพื่อเปิดไฟล์

xtoolbar_import

import_dialog

  • จะเห็นไดอะล็อก “Open X-Section text file” เอาเมาส์ไปคลิกที่แถบพาทดังรูปแล้ว paste กด enter สักครั้งหนึ่งจะเห็นไฟล์ app_ch155m.xsc ที่เก็บไฟล์รูปตัดไว้ จากนั้นคลิกเลือกไฟล์นี้

xfolder_import

  • โปรแกรมจะเปิดไฟล์แล้วอ่านรูปตัดแสดง preview ไฟล์รูปตัด สังเกตว่ารูปแบบค่าปริยายจะเลือก Terramodel Road (4 decimal) คลิก “Next >” เพื่อไปขั้นตอนต่อไป

import_view

3.เลือกรูปตัดให้พอดีกับหน้ากระดาษแบบ

  • เมื่อโปรแกรมอ่านพบรูปตัดแล้วจะนำรูปตัดมาแสดงเป็นลิสต์เพื่อจะให้ผู้ใช้เลือกรูปตัดไปใส่กระดาษแบบตามที่ต้องการ ดูรูปข้างล่าง ข้อสังเกตจะเห็นขั้นตอนที่  3.เลือกปลายทาง ไฟล์นี้เป็นค่าระดับดินเดิมจึงเลือก Copy to Existing Ground section ขั้นตอนที่ 4.copy ไปตารางข้อมูล เป็นอันเรียบร้อย

import_selected

  • ข้อมูลรูปตัดจะถูก  copy ตารางป้อนข้อมูลดินเดิม (Existing Ground Section)

xsectionplot_import_ground

4.นำเข้าข้อมูลไฟล์ Typical Section

  • ต่อไปจะนำข้อมูลดินเดิม Typical section  จาก toolbar เลือกไอคอน “Import text file” เปิดไฟล์ที่โฟลเดอร์เดิม ที่นี้เลือกไฟล์ “design_ch.xsc” คลิก Open โปรแกรมจะเปิดไฟล์มาให้ดูก่อนจากนั้นคลิก “Next >” เพื่อมาเลือกรูปตัด เลือกตามรูปโดยเฉพาะขั้นตอนที่ 3.เลือกปลายทาง เลือก “Copy to Typical section” สุดท้ายคลิกที่ “Copy to >>

import_selected_ts

  • โปรแกรมจะนำข้อมูล Typical มาลงที่ตารางข้อมูล Typical section

typical_after_imported

5.บันทึกไฟล์ข้อมูล (Save file)

  • เมื่อนำข้อมูลเข้ามาแล้ว สิ่งแรกควรจะบันทึกไฟล์ข้อมูลลงดิสค์ คลิกที่ไอคอน “Save” เนื่องจาก Tab มีสองหน้าคือ Typical Section และ Existing Ground Section เวลาจะบันทึกไฟล์ข้อมูลแบบไหนก็ให้คลิกที่แท็บให้ตรงกัน เช่นถ้าต้องการบันทึกไฟล์ข้อมูลของดินเดิมก็ให้คลิกที่แท็บ “Existing Ground Section”

toolbar_save

  • ตอนนี้อยู่แท็บ “Typical Section” เราจะบันทึกไฟล์ข้อมูลนี้ก่อน ผมจะเก็บใน Documents ซึ่ง extension ของไฟล์จะเป็น .txml โดยอัตโนมัต ไฟล์ข้อมูลนี้เป็น xml เปิดดูได้ด้วย Notepad ของวินโดส์ ส่วนรูปแบบฟอร์แมตของไฟล์รุ่นเก่าเป็นไบนารีมีนามสกุล .XST

save_typical_section_file

  • บันทึกไฟล์ดินเดิม (Existing Ground Section) คลิกที่แท็บ “Existing Ground Section” เพื่อสวิตช์มาที่ตารางข้อมูลดินเดิม คลิก “Save” ที่ toolbar ด้านบน เลือกโฟลเดอร์ Documents ป้อนชื่อไฟล์ดังรูปด้านล่าง ไฟล์จะมี extension เป็น .gxml อัตโนมัติsave_existing_ground_section

จบตอนที่ 1 ติดตามต่อตอนที่ 2

  • เมื่อบันทึกข้อมูลรูปตัดลงไฟล์แล้วเราสามารถปิดโปรแกรมได้ โดยที่ไม่ต้องเริ่มต้นใหม่เมื่อเปิดโปรแกรมอีกครั้ง ก็ขอจบตอนที่ 1 ก่อน เพราะจะยาวมากเกินไปติดตามตอนที่ 2 ต่อได้ครับ

 

ก้าวต่อไปของโปรแกรมเขียนรูปตัดตามขวาง XSection Plot ในร่างใหม่พัฒนาด้วย Python + Qt

ลาก่อน XSection Plot รุ่น 3.25

  • โปรแกรมพล็อทรูปตัดตามขวาง XSection Plot เดิมๆนั้นผมเขียนด้วย Visual Basic 6 ใช้มาเป็นสิบๆปีแล้ว บัดนี้ถึงกาลเวลาที่จะต้องฝังในความทรงจำแล้ว เพราะฟอนต์ที่เคยแสดงผลได้ในวินโดส์ XP กลับกลายเป็นตัวประหลาดในวินโดส์ 7/8 ผมเข้าใจว่าฟอนต์ระบบที่เคยอยู่ในวินโดส์ XP น่าจะเป็นระบบแบบด็อทเมทริก น่าจะถูกถอดออกไปแล้วในวินโดส์ 7/8 จึงแสดงผลแบบอักขระประหลาดอย่างที่เห็นxsectionplot_old1
  • กลับมารื้อโค๊ดเดิมๆดูคร่าวๆ จำนวนบรรทัดหลายหมื่นบรรทัดทีเดียว ประกอบด้วยโมดูลและคลาสจำนวนมาก ออกอาการงงๆเหมือนกัน เพราะเขียนไว้นานแล้วภาษานี้ก็ไม่ได้เขียนนานแล้ว แต่ด้วยความง่ายของภาษา VB ใช้เวลาไม่นานก็รื้อฟื้น

แรงจูงใจในการนำมาพัฒนาใหม่

  • บอกตรงๆว่าทนเห็นโปรแกรมที่เคยใช้ได้ดีตอนอยู่วินโดส์ XP แต่มาล้มหายตายจากพอมาอยู่บนวินโดส์ 7/8 ไม่ได้ และความรู้สีกอยากช่วยผู้ที่ใช้งานโปรแกรมนี้ ในรุ่นเก่าแล้วต้องการย้ายงานมาบนวินโดส์ 7/8

เครื่องมือและสภาพแวดล้อมในการพัฒนา

  • ในตอนนี้ผมศึกษา Python อยู่ วิธีเดียวที่จะให้โปรแกรมมิงแตกฉาน คือลงมือเขียนโปรแกรม ก่อนหน้านี้ผมเริ่มเขียนด้วย Python เป็นเวอร์ชัน 2.7.5 แบบ 32 บิต ใช้ graphic user interface (GUI) ของ wxWidgets รวมๆเรียกว่า wxPython ตัวโปรแกรมที่ผมเขียนเป็นโปรแกรมด้าน GIS ใช้ Mapnik เป็นตัว  GIS Map Engine เขียนจนจบโปรแกรมนำมาใช้งานได้ดีพอสมควร  สำหรับผมแล้ว wxPython ก็โอเคในระดับหนึ่ง แต่ความรู้สึกส่วนตัวว่าค่อนข้างติดๆขัดๆไม่ลื่นไหล (ทัศนส่วนตัว)
  • ตอนหลังๆมาลองติดตั้ง Python 3.4 แล้วก็ลง Qt5 เรียกว่า PyQt5 แบบ 64 บิต ลองศึกษา Qt5 ควบคู่ไปด้วย ปรากฎว่าอันนี้ใช่เลย ตามสไตล์ของไพธ่อนครับ สั้น กระชับ ฉับไว ทรงพลัง ผมลงทุนไม่ดูโค๊ดเก่าที่เป็นวิชวลเบสิคเก่า ใช้เวลายามว่างๆ ลงมือเขียนใหม่ เกือบทั้งหมด
  • สภาพแวดล้อมในการพัฒนาใช้ Eclipse (ดั้งเดิมเป็น platform สำหรับพัฒนา Java) ในขณะที่เขียนอยู่เป็นรุน Luna ในส่วน Eclipse ติดตั้ง Plug-ins เพิ่มเติมคือตัว PyDev เพื่อให้สามารถใช้ Python บน Eclipse ได้ ทุกอย่างที่กล่าวมาฟรีหมดครับ

pydev_eclipse

XSection Plot โฉมใหม่ ไฉไลกว่าเดิม

  • มาดูหน้าตาโฉมใหม่ก็เรียบง่ายดังที่เห็น

xsectionplot_new1

xsectionplot_new2

ออกแบบไฟล์ข้อมูลใหม่ เป็น XML

  • ไฟล์ข้อมูลเดิมของ XSection Plot  รุ่นเก่าเป็นไฟล์ไบนารี ข้อเสีย คือมนุษย์อ่านไม่ออก ผู้ใช้ไม่สามารถเปิดไฟล์มาดูได้โดยตรง  ข้อเสียในแง่คนพัฒนาโปรแกรมคือ ขยายเพิ่มเติมข้อมูลลำบาก ก็เลยหันมามอง XML ที่เกิดมานมนานเป็นสิบๆปีแล้ว สนใจลองกดปุ่มบวกข้างล่างดูลักษณะไฟล์ข้อมูล แต่รุ่นจริงอาจจะมีการเปลี่ยนแปลง

[code language=”xml” collapse=”true”]
<root version=”1.0″>
<!–Generated by XSection Plot–>
<!–This data file is Existing ground section–>
<Header>
<AppName>XSection Plot</AppName>
<Developer>Prajuab Riabroy</Developer>
<Version>4.0.512</Version>
<SectionType>Ground</SectionType>
<DateCreated>2014-08-07 16:45:56.517701</DateCreated>
</Header>
<ProjectInfo>
<ProjectName>KohKong Coal-Fired Power Plant</ProjectName>
<ClientName>Harbour Department</ClientName>
<ContractorName>Universal Construction Development PCL.</ContractorName>
<DrawingTitle>Cross Section of Access Channel</DrawingTitle>
<DrawnName>DRS</DrawnName>
<ApprovedName>AS</ApprovedName>
<ClientApprovedName>AD</ClientApprovedName>
<CheckedName>PJ</CheckedName>
<SurveyorName>SK</SurveyorName>
<SurveyedDate>1-7/03/2010</SurveyedDate>
<DrawingNo></DrawingNo>
<SheetNo>1/</SheetNo>
<DrawingDate>1-7/03/2010</DrawingDate>
<Revision></Revision>
<UseLocaleLanguage>False</UseLocaleLanguage>
<MapTexts>
<MapText Label=”Client” Locale=”เจ้าของโครงการ”/>
<MapText Label=”Contractor” Locale=”ผู้รับเหมา”/>
<MapText Label=”Drawn” Locale=”เขียน”/>
<MapText Label=”Design” Locale=”ออกแบบ”/>
<MapText Label=”Surveyor” Locale=”สำรวจ”/>
<MapText Label=”Surveyed date” Locale=”วันที่สำรวจ”/>
<MapText Label=”Checked” Locale=”ตรวจสอบ”/>
<MapText Label=”Approved” Locale=”อนุมัติ”/>
<MapText Label=”Client approved” Locale=”ผู้คุมงานอนุมัติ”/>
<MapText Label=”Drawing No.” Locale=”แบบเลขที่”/>
<MapText Label=”Drawing date” Locale=”แบบวันที่”/>
<MapText Label=”Project title” Locale=”โครงการ”/>
<MapText Label=”Drawing title” Locale=”แผนที่แสดง”/>
<MapText Label=”Sheet No.” Locale=”แบบเลขที่”/>
<MapText Label=”Scale” Locale=”มาตราส่วน”/>
<MapText Label=”Vertical” Locale=”ทางดิ่ง”/>
<MapText Label=”Horizontal” Locale=”ทางราบ”/>
<MapText Label=”Vertical scale” Locale=”มาตราส่วนทางดิ่ง”/>
<MapText Label=”Horizontal scale” Locale=”มาตราส่วนทางราบ”/>
<MapText Label=”Legend” Locale=”สัญลักษณ์”/>
<MapText Label=”Notes” Locale=”หมายเหตุ”/>
<MapText Label=”Geodetic Information” Locale=”ข้อมูลทางยีออเดซี”/>
<MapText Label=”No” Locale=”ครั้งที่”/>
<MapText Label=”Amendments” Locale=”ความเห็น”/>
<MapText Label=”By” Locale=”โดย”/>
<MapText Label=”Date” Locale=”วันที่”/>
<MapText Label=”Revision” Locale=”ครั้งที่แก้ไข”/>
</MapTexts>
</ProjectInfo>
<SectionOptions>
<VerticalScale>250.0</VerticalScale>
<HorizontalScale>2500.0</HorizontalScale>
<HozGridSpace>25.0</HozGridSpace>
<VertGridSpace>2.0</VertGridSpace>
<GridLineType>1</GridLineType>
<CalcIntersection>-1</CalcIntersection>
<CalcArea>-1</CalcArea>
<TrimTypical>0</TrimTypical>
<NumDecimalElev>3</NumDecimalElev>
<NumDecimalDist>3</NumDecimalDist>
<UseIntervalText>-1</UseIntervalText>
<IntervalDist>25.0</IntervalDist>
<PrefixText></PrefixText>
<PostfixText></PostfixText>
<UsePostPrefix>0</UsePostPrefix>
<UseOffsetElevFormat>2</UseOffsetElevFormat>
<CalcPlotAreaCut>0</CalcPlotAreaCut>
<CalcPlotAreaFill>0</CalcPlotAreaFill>
<NumVertCLLeft>18</NumVertCLLeft>
<NumVertCLRight>18</NumVertCLRight>
<NumHozTopBottom>8</NumHozTopBottom>
<LeftSideText>LT.</LeftSideText>
<RightSideText>RT.</RightSideText>
<StationText>Km.</StationText>
<SelectedTBlock>3</SelectedTBlock>
<NumSectionRows>6</NumSectionRows>
<NumSectionColumns>2</NumSectionColumns>
<SurveyType>0</SurveyType>
<PlotTBlock>-1</PlotTBlock>
<SwapLeftAndRight>0</SwapLeftAndRight>
</SectionOptions>
<PageSetup>
<PaperSize>A1</PaperSize>
<PageWidth>-999</PageWidth>
<PaperHeight>-999</PaperHeight>
</PageSetup>
<Sections>
<NumSections>12</NumSections>
<Section Name=”2 + 000″>
<XPositionOnPaper>51.66</XPositionOnPaper>
<YPositionOnPaper>21.18</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>37</NumPoints>
<Points>
<Point Elevation=”-13.75″ Offset=”-450.0″/>
<Point Elevation=”-13.724″ Offset=”-444.229″/>
<Point Elevation=”-13.453″ Offset=”-394.64″/>
<Point Elevation=”-13.708″ Offset=”-357.293″/>
<Point Elevation=”-13.832″ Offset=”-340.678″/>
<Point Elevation=”-13.815″ Offset=”-321.128″/>
<Point Elevation=”-13.812″ Offset=”-303.689″/>
<Point Elevation=”-13.817″ Offset=”-263.4″/>
<Point Elevation=”-13.795″ Offset=”-256.48″/>
<Point Elevation=”-13.774″ Offset=”-237.844″/>
<Point Elevation=”-13.725″ Offset=”-215.868″/>
<Point Elevation=”-13.694″ Offset=”-179.238″/>
<Point Elevation=”-13.694″ Offset=”-146.471″/>
<Point Elevation=”-13.641″ Offset=”-126.792″/>
<Point Elevation=”-13.651″ Offset=”-77.938″/>
<Point Elevation=”-13.577″ Offset=”-68.628″/>
<Point Elevation=”-13.573″ Offset=”-67.035″/>
<Point Elevation=”-13.578″ Offset=”-57.508″/>
<Point Elevation=”-13.545″ Offset=”-14.98″/>
<Point Elevation=”-13.551″ Offset=”-2.388″/>
<Point Elevation=”-13.569″ Offset=”19.95″/>
<Point Elevation=”-13.553″ Offset=”64.032″/>
<Point Elevation=”-13.541″ Offset=”72.772″/>
<Point Elevation=”-13.516″ Offset=”81.096″/>
<Point Elevation=”-13.614″ Offset=”138.343″/>
<Point Elevation=”-13.629″ Offset=”150.271″/>
<Point Elevation=”-13.556″ Offset=”198.013″/>
<Point Elevation=”-13.557″ Offset=”211.934″/>
<Point Elevation=”-13.577″ Offset=”254.983″/>
<Point Elevation=”-13.624″ Offset=”269.121″/>
<Point Elevation=”-13.736″ Offset=”298.975″/>
<Point Elevation=”-13.717″ Offset=”339.278″/>
<Point Elevation=”-13.679″ Offset=”356.86″/>
<Point Elevation=”-13.497″ Offset=”383.249″/>
<Point Elevation=”-13.423″ Offset=”405.804″/>
<Point Elevation=”-13.548″ Offset=”442.413″/>
<Point Elevation=”-13.59″ Offset=”450.0″/>
</Points>
</Section>
<Section Name=”2 + 050″>
<XPositionOnPaper>42.78</XPositionOnPaper>
<YPositionOnPaper>21.18</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>37</NumPoints>
<Points>
<Point Elevation=”-13.587″ Offset=”-450.0″/>
<Point Elevation=”-13.564″ Offset=”-431.93″/>
<Point Elevation=”-13.389″ Offset=”-392.416″/>
<Point Elevation=”-13.59″ Offset=”-363.705″/>
<Point Elevation=”-13.714″ Offset=”-349.243″/>
<Point Elevation=”-13.648″ Offset=”-319.939″/>
<Point Elevation=”-13.613″ Offset=”-305.319″/>
<Point Elevation=”-13.836″ Offset=”-245.696″/>
<Point Elevation=”-13.833″ Offset=”-244.203″/>
<Point Elevation=”-13.656″ Offset=”-200.692″/>
<Point Elevation=”-13.608″ Offset=”-176.25″/>
<Point Elevation=”-13.525″ Offset=”-143.894″/>
<Point Elevation=”-13.552″ Offset=”-129.046″/>
<Point Elevation=”-13.527″ Offset=”-96.253″/>
<Point Elevation=”-13.656″ Offset=”-54.905″/>
<Point Elevation=”-13.654″ Offset=”-53.835″/>
<Point Elevation=”-13.566″ Offset=”-45.158″/>
<Point Elevation=”-13.591″ Offset=”-20.343″/>
<Point Elevation=”-13.567″ Offset=”-0.305″/>
<Point Elevation=”-13.438″ Offset=”26.667″/>
<Point Elevation=”-13.397″ Offset=”59.524″/>
<Point Elevation=”-13.375″ Offset=”70.237″/>
<Point Elevation=”-13.38″ Offset=”77.772″/>
<Point Elevation=”-13.49″ Offset=”115.256″/>
<Point Elevation=”-13.6″ Offset=”156.486″/>
<Point Elevation=”-13.475″ Offset=”180.904″/>
<Point Elevation=”-13.453″ Offset=”188.472″/>
<Point Elevation=”-13.454″ Offset=”203.878″/>
<Point Elevation=”-13.471″ Offset=”256.873″/>
<Point Elevation=”-13.554″ Offset=”276.218″/>
<Point Elevation=”-13.604″ Offset=”294.693″/>
<Point Elevation=”-13.63″ Offset=”328.866″/>
<Point Elevation=”-13.63″ Offset=”355.449″/>
<Point Elevation=”-13.502″ Offset=”374.332″/>
<Point Elevation=”-13.316″ Offset=”406.895″/>
<Point Elevation=”-13.486″ Offset=”441.986″/>
<Point Elevation=”-13.52″ Offset=”450.0″/>
</Points>
</Section>
<Section Name=”2 + 100″>
<XPositionOnPaper>33.89</XPositionOnPaper>
<YPositionOnPaper>21.18</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>38</NumPoints>
<Points>
<Point Elevation=”-13.478″ Offset=”-450.0″/>
<Point Elevation=”-13.468″ Offset=”-424.977″/>
<Point Elevation=”-13.401″ Offset=”-404.422″/>
<Point Elevation=”-13.463″ Offset=”-387.405″/>
<Point Elevation=”-13.633″ Offset=”-344.262″/>
<Point Elevation=”-13.608″ Offset=”-339.036″/>
<Point Elevation=”-13.494″ Offset=”-305.986″/>
<Point Elevation=”-13.552″ Offset=”-274.196″/>
<Point Elevation=”-13.555″ Offset=”-259.655″/>
<Point Elevation=”-13.555″ Offset=”-237.91″/>
<Point Elevation=”-13.486″ Offset=”-192.39″/>
<Point Elevation=”-13.35″ Offset=”-155.4″/>
<Point Elevation=”-13.323″ Offset=”-145.491″/>
<Point Elevation=”-13.288″ Offset=”-86.808″/>
<Point Elevation=”-13.275″ Offset=”-58.314″/>
<Point Elevation=”-13.286″ Offset=”-56.712″/>
<Point Elevation=”-13.511″ Offset=”-44.626″/>
<Point Elevation=”-13.477″ Offset=”-19.724″/>
<Point Elevation=”-13.435″ Offset=”-1.021″/>
<Point Elevation=”-13.385″ Offset=”20.078″/>
<Point Elevation=”-13.354″ Offset=”48.949″/>
<Point Elevation=”-13.322″ Offset=”58.859″/>
<Point Elevation=”-13.309″ Offset=”73.917″/>
<Point Elevation=”-13.431″ Offset=”135.063″/>
<Point Elevation=”-13.512″ Offset=”161.041″/>
<Point Elevation=”-13.36″ Offset=”170.629″/>
<Point Elevation=”-13.285″ Offset=”176.557″/>
<Point Elevation=”-13.303″ Offset=”252.984″/>
<Point Elevation=”-13.309″ Offset=”261.078″/>
<Point Elevation=”-13.349″ Offset=”269.352″/>
<Point Elevation=”-13.442″ Offset=”286.219″/>
<Point Elevation=”-13.451″ Offset=”289.018″/>
<Point Elevation=”-13.454″ Offset=”295.508″/>
<Point Elevation=”-13.381″ Offset=”357.63″/>
<Point Elevation=”-13.291″ Offset=”397.562″/>
<Point Elevation=”-13.265″ Offset=”410.885″/>
<Point Elevation=”-13.291″ Offset=”415.854″/>
<Point Elevation=”-13.436″ Offset=”450.0″/>
</Points>
</Section>
<Section Name=”2 + 150″>
<XPositionOnPaper>25.01</XPositionOnPaper>
<YPositionOnPaper>21.18</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>36</NumPoints>
<Points>
<Point Elevation=”-13.42″ Offset=”-450.0″/>
<Point Elevation=”-13.422″ Offset=”-448.815″/>
<Point Elevation=”-13.36″ Offset=”-407.76″/>
<Point Elevation=”-13.421″ Offset=”-383.018″/>
<Point Elevation=”-13.466″ Offset=”-343.431″/>
<Point Elevation=”-13.477″ Offset=”-330.434″/>
<Point Elevation=”-13.426″ Offset=”-308.725″/>
<Point Elevation=”-13.339″ Offset=”-248.217″/>
<Point Elevation=”-13.318″ Offset=”-227.42″/>
<Point Elevation=”-13.346″ Offset=”-185.203″/>
<Point Elevation=”-13.22″ Offset=”-153.307″/>
<Point Elevation=”-13.204″ Offset=”-149.805″/>
<Point Elevation=”-13.299″ Offset=”-109.743″/>
<Point Elevation=”-13.355″ Offset=”-76.976″/>
<Point Elevation=”-13.291″ Offset=”-70.628″/>
<Point Elevation=”-13.2″ Offset=”-57.454″/>
<Point Elevation=”-13.217″ Offset=”-40.497″/>
<Point Elevation=”-13.27″ Offset=”-5.497″/>
<Point Elevation=”-13.298″ Offset=”42.337″/>
<Point Elevation=”-13.313″ Offset=”57.83″/>
<Point Elevation=”-13.306″ Offset=”58.86″/>
<Point Elevation=”-13.119″ Offset=”66.396″/>
<Point Elevation=”-13.147″ Offset=”99.813″/>
<Point Elevation=”-13.307″ Offset=”160.186″/>
<Point Elevation=”-13.248″ Offset=”169.925″/>
<Point Elevation=”-13.135″ Offset=”176.817″/>
<Point Elevation=”-13.233″ Offset=”220.607″/>
<Point Elevation=”-13.302″ Offset=”256.981″/>
<Point Elevation=”-13.362″ Offset=”268.584″/>
<Point Elevation=”-13.398″ Offset=”285.574″/>
<Point Elevation=”-13.254″ Offset=”344.07″/>
<Point Elevation=”-13.228″ Offset=”357.109″/>
<Point Elevation=”-13.214″ Offset=”363.701″/>
<Point Elevation=”-13.071″ Offset=”408.839″/>
<Point Elevation=”-13.195″ Offset=”427.653″/>
<Point Elevation=”-13.336″ Offset=”450.0″/>
</Points>
</Section>
<Section Name=”2 + 200″>
<XPositionOnPaper>16.13</XPositionOnPaper>
<YPositionOnPaper>21.18</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>34</NumPoints>
<Points>
<Point Elevation=”-13.299″ Offset=”-450.0″/>
<Point Elevation=”-13.244″ Offset=”-436.225″/>
<Point Elevation=”-13.11″ Offset=”-404.037″/>
<Point Elevation=”-13.219″ Offset=”-363.07″/>
<Point Elevation=”-13.268″ Offset=”-346.98″/>
<Point Elevation=”-13.241″ Offset=”-317.712″/>
<Point Elevation=”-13.227″ Offset=”-310.438″/>
<Point Elevation=”-13.238″ Offset=”-280.224″/>
<Point Elevation=”-13.258″ Offset=”-255.553″/>
<Point Elevation=”-13.299″ Offset=”-211.447″/>
<Point Elevation=”-13.297″ Offset=”-203.957″/>
<Point Elevation=”-13.325″ Offset=”-143.444″/>
<Point Elevation=”-13.182″ Offset=”-96.867″/>
<Point Elevation=”-13.167″ Offset=”-71.842″/>
<Point Elevation=”-13.173″ Offset=”-66.961″/>
<Point Elevation=”-13.161″ Offset=”-63.511″/>
<Point Elevation=”-13.105″ Offset=”-25.008″/>
<Point Elevation=”-13.095″ Offset=”-1.821″/>
<Point Elevation=”-13.263″ Offset=”45.687″/>
<Point Elevation=”-13.267″ Offset=”49.066″/>
<Point Elevation=”-13.264″ Offset=”49.467″/>
<Point Elevation=”-13.074″ Offset=”66.884″/>
<Point Elevation=”-13.11″ Offset=”161.015″/>
<Point Elevation=”-13.061″ Offset=”165.896″/>
<Point Elevation=”-13.022″ Offset=”174.39″/>
<Point Elevation=”-13.136″ Offset=”236.021″/>
<Point Elevation=”-13.157″ Offset=”249.355″/>
<Point Elevation=”-13.194″ Offset=”259.713″/>
<Point Elevation=”-13.265″ Offset=”285.85″/>
<Point Elevation=”-13.251″ Offset=”296.83″/>
<Point Elevation=”-13.145″ Offset=”348.582″/>
<Point Elevation=”-13.023″ Offset=”386.699″/>
<Point Elevation=”-12.918″ Offset=”410.555″/>
<Point Elevation=”-13.122″ Offset=”450.0″/>
</Points>
</Section>
<Section Name=”2 + 250″>
<XPositionOnPaper>7.24</XPositionOnPaper>
<YPositionOnPaper>21.18</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>35</NumPoints>
<Points>
<Point Elevation=”-13.141″ Offset=”-450.0″/>
<Point Elevation=”-13.135″ Offset=”-427.089″/>
<Point Elevation=”-13.116″ Offset=”-408.612″/>
<Point Elevation=”-13.158″ Offset=”-378.649″/>
<Point Elevation=”-13.208″ Offset=”-347.778″/>
<Point Elevation=”-13.103″ Offset=”-300.077″/>
<Point Elevation=”-13.082″ Offset=”-258.336″/>
<Point Elevation=”-13.043″ Offset=”-232.005″/>
<Point Elevation=”-13.019″ Offset=”-212.37″/>
<Point Elevation=”-13.039″ Offset=”-193.983″/>
<Point Elevation=”-13.092″ Offset=”-151.651″/>
<Point Elevation=”-13.105″ Offset=”-143.345″/>
<Point Elevation=”-13.093″ Offset=”-121.002″/>
<Point Elevation=”-13.082″ Offset=”-74.012″/>
<Point Elevation=”-13.072″ Offset=”-70.704″/>
<Point Elevation=”-12.939″ Offset=”-61.159″/>
<Point Elevation=”-12.878″ Offset=”-54.908″/>
<Point Elevation=”-13.036″ Offset=”-16.297″/>
<Point Elevation=”-12.959″ Offset=”13.485″/>
<Point Elevation=”-13.014″ Offset=”34.515″/>
<Point Elevation=”-13.016″ Offset=”41.274″/>
<Point Elevation=”-12.881″ Offset=”73.456″/>
<Point Elevation=”-12.997″ Offset=”132.919″/>
<Point Elevation=”-13.083″ Offset=”160.722″/>
<Point Elevation=”-12.971″ Offset=”167.25″/>
<Point Elevation=”-12.897″ Offset=”174.705″/>
<Point Elevation=”-12.973″ Offset=”224.215″/>
<Point Elevation=”-13.039″ Offset=”247.5″/>
<Point Elevation=”-12.997″ Offset=”275.574″/>
<Point Elevation=”-12.965″ Offset=”306.485″/>
<Point Elevation=”-12.954″ Offset=”335.878″/>
<Point Elevation=”-12.932″ Offset=”347.275″/>
<Point Elevation=”-12.763″ Offset=”408.665″/>
<Point Elevation=”-12.844″ Offset=”430.348″/>
<Point Elevation=”-12.93″ Offset=”450.0″/>
</Points>
</Section>
<Section Name=”2 + 300″>
<XPositionOnPaper>51.66</XPositionOnPaper>
<YPositionOnPaper>62.03</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>34</NumPoints>
<Points>
<Point Elevation=”-13.074″ Offset=”-450.0″/>
<Point Elevation=”-12.945″ Offset=”-417.015″/>
<Point Elevation=”-12.941″ Offset=”-415.185″/>
<Point Elevation=”-13.024″ Offset=”-341.605″/>
<Point Elevation=”-13.123″ Offset=”-294.567″/>
<Point Elevation=”-13.107″ Offset=”-279.439″/>
<Point Elevation=”-13.068″ Offset=”-253.199″/>
<Point Elevation=”-13.027″ Offset=”-222.165″/>
<Point Elevation=”-13.007″ Offset=”-210.839″/>
<Point Elevation=”-12.978″ Offset=”-193.209″/>
<Point Elevation=”-12.874″ Offset=”-146.031″/>
<Point Elevation=”-12.947″ Offset=”-112.293″/>
<Point Elevation=”-12.994″ Offset=”-74.731″/>
<Point Elevation=”-12.951″ Offset=”-56.842″/>
<Point Elevation=”-12.941″ Offset=”-51.044″/>
<Point Elevation=”-12.928″ Offset=”-49.349″/>
<Point Elevation=”-12.919″ Offset=”-41.744″/>
<Point Elevation=”-12.857″ Offset=”-17.072″/>
<Point Elevation=”-12.849″ Offset=”-1.213″/>
<Point Elevation=”-12.937″ Offset=”29.996″/>
<Point Elevation=”-12.943″ Offset=”43.79″/>
<Point Elevation=”-12.822″ Offset=”75.413″/>
<Point Elevation=”-12.792″ Offset=”80.941″/>
<Point Elevation=”-12.826″ Offset=”90.04″/>
<Point Elevation=”-13.069″ Offset=”164.519″/>
<Point Elevation=”-12.837″ Offset=”183.079″/>
<Point Elevation=”-12.873″ Offset=”222.341″/>
<Point Elevation=”-12.893″ Offset=”250.522″/>
<Point Elevation=”-12.863″ Offset=”272.959″/>
<Point Elevation=”-12.84″ Offset=”289.627″/>
<Point Elevation=”-12.791″ Offset=”341.037″/>
<Point Elevation=”-12.791″ Offset=”375.553″/>
<Point Elevation=”-12.778″ Offset=”402.959″/>
<Point Elevation=”-12.782″ Offset=”450.0″/>
</Points>
</Section>
<Section Name=”2 + 350″>
<XPositionOnPaper>42.78</XPositionOnPaper>
<YPositionOnPaper>62.03</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>35</NumPoints>
<Points>
<Point Elevation=”-12.783″ Offset=”-450.0″/>
<Point Elevation=”-12.807″ Offset=”-423.664″/>
<Point Elevation=”-12.842″ Offset=”-402.422″/>
<Point Elevation=”-12.834″ Offset=”-393.811″/>
<Point Elevation=”-12.879″ Offset=”-350.323″/>
<Point Elevation=”-12.966″ Offset=”-318.938″/>
<Point Elevation=”-13.011″ Offset=”-304.688″/>
<Point Elevation=”-12.898″ Offset=”-262.751″/>
<Point Elevation=”-12.866″ Offset=”-244.765″/>
<Point Elevation=”-12.876″ Offset=”-206.942″/>
<Point Elevation=”-12.88″ Offset=”-204.564″/>
<Point Elevation=”-12.856″ Offset=”-158.672″/>
<Point Elevation=”-12.786″ Offset=”-141.587″/>
<Point Elevation=”-12.787″ Offset=”-103.149″/>
<Point Elevation=”-12.766″ Offset=”-91.41″/>
<Point Elevation=”-12.779″ Offset=”-82.894″/>
<Point Elevation=”-12.781″ Offset=”-78.804″/>
<Point Elevation=”-12.767″ Offset=”-58.384″/>
<Point Elevation=”-12.765″ Offset=”-39.14″/>
<Point Elevation=”-12.676″ Offset=”-10.552″/>
<Point Elevation=”-12.786″ Offset=”13.725″/>
<Point Elevation=”-12.924″ Offset=”42.861″/>
<Point Elevation=”-12.794″ Offset=”60.497″/>
<Point Elevation=”-12.654″ Offset=”81.948″/>
<Point Elevation=”-12.833″ Offset=”123.769″/>
<Point Elevation=”-12.916″ Offset=”163.182″/>
<Point Elevation=”-12.784″ Offset=”181.207″/>
<Point Elevation=”-12.765″ Offset=”188.92″/>
<Point Elevation=”-12.792″ Offset=”255.693″/>
<Point Elevation=”-12.815″ Offset=”295.177″/>
<Point Elevation=”-12.79″ Offset=”315.292″/>
<Point Elevation=”-12.749″ Offset=”345.204″/>
<Point Elevation=”-12.744″ Offset=”364.207″/>
<Point Elevation=”-12.753″ Offset=”396.564″/>
<Point Elevation=”-12.68″ Offset=”450.0″/>
</Points>
</Section>
<Section Name=”2 + 400″>
<XPositionOnPaper>33.89</XPositionOnPaper>
<YPositionOnPaper>62.03</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>36</NumPoints>
<Points>
<Point Elevation=”-12.776″ Offset=”-450.0″/>
<Point Elevation=”-12.779″ Offset=”-447.698″/>
<Point Elevation=”-12.774″ Offset=”-434.746″/>
<Point Elevation=”-12.716″ Offset=”-414.286″/>
<Point Elevation=”-12.81″ Offset=”-359.948″/>
<Point Elevation=”-12.835″ Offset=”-352.389″/>
<Point Elevation=”-12.834″ Offset=”-346.592″/>
<Point Elevation=”-12.907″ Offset=”-315.681″/>
<Point Elevation=”-12.863″ Offset=”-285.783″/>
<Point Elevation=”-12.746″ Offset=”-240.545″/>
<Point Elevation=”-12.748″ Offset=”-212.21″/>
<Point Elevation=”-12.82″ Offset=”-189.251″/>
<Point Elevation=”-12.715″ Offset=”-173.517″/>
<Point Elevation=”-12.632″ Offset=”-145.846″/>
<Point Elevation=”-12.591″ Offset=”-106.965″/>
<Point Elevation=”-12.571″ Offset=”-91.109″/>
<Point Elevation=”-12.571″ Offset=”-48.284″/>
<Point Elevation=”-12.577″ Offset=”-45.561″/>
<Point Elevation=”-12.599″ Offset=”-14.411″/>
<Point Elevation=”-12.787″ Offset=”15.841″/>
<Point Elevation=”-12.859″ Offset=”44.469″/>
<Point Elevation=”-12.629″ Offset=”73.752″/>
<Point Elevation=”-12.541″ Offset=”85.843″/>
<Point Elevation=”-12.606″ Offset=”127.261″/>
<Point Elevation=”-12.689″ Offset=”164.56″/>
<Point Elevation=”-12.777″ Offset=”188.004″/>
<Point Elevation=”-12.794″ Offset=”194.282″/>
<Point Elevation=”-12.765″ Offset=”220.036″/>
<Point Elevation=”-12.697″ Offset=”257.027″/>
<Point Elevation=”-12.742″ Offset=”298.261″/>
<Point Elevation=”-12.761″ Offset=”308.727″/>
<Point Elevation=”-12.739″ Offset=”317.584″/>
<Point Elevation=”-12.692″ Offset=”346.633″/>
<Point Elevation=”-12.663″ Offset=”389.2″/>
<Point Elevation=”-12.662″ Offset=”396.811″/>
<Point Elevation=”-12.622″ Offset=”450.0″/>
</Points>
</Section>
<Section Name=”2 + 450″>
<XPositionOnPaper>25.01</XPositionOnPaper>
<YPositionOnPaper>62.03</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>35</NumPoints>
<Points>
<Point Elevation=”-12.772″ Offset=”-450.0″/>
<Point Elevation=”-12.779″ Offset=”-447.895″/>
<Point Elevation=”-12.728″ Offset=”-435.359″/>
<Point Elevation=”-12.625″ Offset=”-419.964″/>
<Point Elevation=”-12.671″ Offset=”-361.947″/>
<Point Elevation=”-12.65″ Offset=”-349.652″/>
<Point Elevation=”-12.745″ Offset=”-323.285″/>
<Point Elevation=”-12.881″ Offset=”-302.461″/>
<Point Elevation=”-12.774″ Offset=”-273.658″/>
<Point Elevation=”-12.614″ Offset=”-241.564″/>
<Point Elevation=”-12.923″ Offset=”-198.167″/>
<Point Elevation=”-12.751″ Offset=”-169.044″/>
<Point Elevation=”-12.581″ Offset=”-144.88″/>
<Point Elevation=”-12.616″ Offset=”-115.712″/>
<Point Elevation=”-12.607″ Offset=”-103.85″/>
<Point Elevation=”-12.527″ Offset=”-58.007″/>
<Point Elevation=”-12.522″ Offset=”-49.404″/>
<Point Elevation=”-12.511″ Offset=”-40.605″/>
<Point Elevation=”-12.526″ Offset=”-7.582″/>
<Point Elevation=”-12.637″ Offset=”44.494″/>
<Point Elevation=”-12.638″ Offset=”46.028″/>
<Point Elevation=”-12.336″ Offset=”98.718″/>
<Point Elevation=”-12.345″ Offset=”101.193″/>
<Point Elevation=”-12.764″ Offset=”162.39″/>
<Point Elevation=”-12.66″ Offset=”204.444″/>
<Point Elevation=”-12.627″ Offset=”229.054″/>
<Point Elevation=”-12.548″ Offset=”258.494″/>
<Point Elevation=”-12.644″ Offset=”293.019″/>
<Point Elevation=”-12.669″ Offset=”307.749″/>
<Point Elevation=”-12.618″ Offset=”321.733″/>
<Point Elevation=”-12.477″ Offset=”351.792″/>
<Point Elevation=”-12.529″ Offset=”375.735″/>
<Point Elevation=”-12.545″ Offset=”385.798″/>
<Point Elevation=”-12.574″ Offset=”415.152″/>
<Point Elevation=”-12.621″ Offset=”450.0″/>
</Points>
</Section>
<Section Name=”2 + 500″>
<XPositionOnPaper>16.13</XPositionOnPaper>
<YPositionOnPaper>62.03</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>37</NumPoints>
<Points>
<Point Elevation=”-12.675″ Offset=”-450.0″/>
<Point Elevation=”-12.682″ Offset=”-448.083″/>
<Point Elevation=”-12.672″ Offset=”-428.342″/>
<Point Elevation=”-12.68″ Offset=”-425.205″/>
<Point Elevation=”-12.649″ Offset=”-408.657″/>
<Point Elevation=”-12.507″ Offset=”-340.077″/>
<Point Elevation=”-12.62″ Offset=”-320.546″/>
<Point Elevation=”-12.737″ Offset=”-293.581″/>
<Point Elevation=”-12.521″ Offset=”-251.753″/>
<Point Elevation=”-12.513″ Offset=”-249.937″/>
<Point Elevation=”-12.801″ Offset=”-216.359″/>
<Point Elevation=”-12.653″ Offset=”-174.972″/>
<Point Elevation=”-12.591″ Offset=”-158.425″/>
<Point Elevation=”-12.541″ Offset=”-144.303″/>
<Point Elevation=”-12.614″ Offset=”-115.444″/>
<Point Elevation=”-12.615″ Offset=”-111.726″/>
<Point Elevation=”-12.6″ Offset=”-104.058″/>
<Point Elevation=”-12.415″ Offset=”-42.364″/>
<Point Elevation=”-12.406″ Offset=”-28.724″/>
<Point Elevation=”-12.416″ Offset=”-1.475″/>
<Point Elevation=”-12.36″ Offset=”38.494″/>
<Point Elevation=”-12.353″ Offset=”52.28″/>
<Point Elevation=”-12.321″ Offset=”63.68″/>
<Point Elevation=”-12.198″ Offset=”112.168″/>
<Point Elevation=”-12.383″ Offset=”139.067″/>
<Point Elevation=”-12.577″ Offset=”161.059″/>
<Point Elevation=”-12.541″ Offset=”188.84″/>
<Point Elevation=”-12.454″ Offset=”213.082″/>
<Point Elevation=”-12.385″ Offset=”256.777″/>
<Point Elevation=”-12.375″ Offset=”261.779″/>
<Point Elevation=”-12.415″ Offset=”269.668″/>
<Point Elevation=”-12.639″ Offset=”309.342″/>
<Point Elevation=”-12.483″ Offset=”329.784″/>
<Point Elevation=”-12.337″ Offset=”352.33″/>
<Point Elevation=”-12.37″ Offset=”365.049″/>
<Point Elevation=”-12.507″ Offset=”423.352″/>
<Point Elevation=”-12.597″ Offset=”450.0″/>
</Points>
</Section>
<Section Name=”2 + 550″>
<XPositionOnPaper>7.24</XPositionOnPaper>
<YPositionOnPaper>62.03</YPositionOnPaper>
<TopGridElev>0.0</TopGridElev>
<NumPoints>40</NumPoints>
<Points>
<Point Elevation=”-12.351″ Offset=”-450.0″/>
<Point Elevation=”-12.346″ Offset=”-440.604″/>
<Point Elevation=”-12.456″ Offset=”-420.924″/>
<Point Elevation=”-12.422″ Offset=”-356.665″/>
<Point Elevation=”-12.436″ Offset=”-351.476″/>
<Point Elevation=”-12.433″ Offset=”-348.926″/>
<Point Elevation=”-12.599″ Offset=”-305.043″/>
<Point Elevation=”-12.617″ Offset=”-296.42″/>
<Point Elevation=”-12.516″ Offset=”-254.712″/>
<Point Elevation=”-12.489″ Offset=”-238.476″/>
<Point Elevation=”-12.648″ Offset=”-206.205″/>
<Point Elevation=”-12.563″ Offset=”-187.983″/>
<Point Elevation=”-12.407″ Offset=”-147.195″/>
<Point Elevation=”-12.453″ Offset=”-122.034″/>
<Point Elevation=”-12.46″ Offset=”-116.462″/>
<Point Elevation=”-12.465″ Offset=”-115.775″/>
<Point Elevation=”-12.453″ Offset=”-110.426″/>
<Point Elevation=”-12.39″ Offset=”-62.05″/>
<Point Elevation=”-12.294″ Offset=”-40.738″/>
<Point Elevation=”-12.318″ Offset=”-24.44″/>
<Point Elevation=”-12.277″ Offset=”-5.967″/>
<Point Elevation=”-12.467″ Offset=”31.391″/>
<Point Elevation=”-12.537″ Offset=”53.35″/>
<Point Elevation=”-12.432″ Offset=”77.607″/>
<Point Elevation=”-12.187″ Offset=”125.999″/>
<Point Elevation=”-12.356″ Offset=”151.552″/>
<Point Elevation=”-12.421″ Offset=”160.797″/>
<Point Elevation=”-12.325″ Offset=”199.432″/>
<Point Elevation=”-12.286″ Offset=”218.382″/>
<Point Elevation=”-12.281″ Offset=”225.988″/>
<Point Elevation=”-12.28″ Offset=”255.015″/>
<Point Elevation=”-12.398″ Offset=”283.83″/>
<Point Elevation=”-12.476″ Offset=”305.13″/>
<Point Elevation=”-12.396″ Offset=”329.028″/>
<Point Elevation=”-12.277″ Offset=”354.738″/>
<Point Elevation=”-12.291″ Offset=”372.85″/>
<Point Elevation=”-12.291″ Offset=”400.408″/>
<Point Elevation=”-12.334″ Offset=”421.647″/>
<Point Elevation=”-12.426″ Offset=”448.515″/>
<Point Elevation=”-12.419″ Offset=”450.0″/>
</Points>
</Section>
</Sections>
</root>

[/code]

ระยะเวลาในการพัฒนา

  • เนื่องจากโปรแกรมไม่ได้ถูกพัฒนาในเชิงพานิชย์ และผมใช้เวลาว่างเป็นงานอดิเรก จึงไม่สามารถกำหนดเวลาที่แน่นอนได้ แต่คาดว่าอย่างน้อยอีกสักครึ่งปี ถึงจะได้ยลโฉมกัน ลองไปรันในลีนุกซ์ก็ไม่มีปัญหา ใช้ดีเหมือนบนวินโดส์ แต่ไปลองบนแมค ภาษาไทยกลับเกิดอาการสระลอย ยังหาวิธีแก้ไขไม่ได้ แต่ยังมีเวลาอีกนานครับ