วันเสาร์ที่ 26 กุมภาพันธ์ พ.ศ. 2554

สร้างเลเซอร์สแกนเนอร์สำหรับการรังวัด จากเลเซอร์ในงานอุตสาหกรรม

เลเซอร์สำหรับการรังวัดเพื่อการรังวัดทำแผนที่ สร้างแบบจำลองอาคาร สร้างแบบจลองโรงงานสามมิติ จะเป็นชนิดตั้งพื้นที่เรียกว่า Terrestrial Laser Scanner (TLS) ระยะรังวัดไปได้ไกลสัก 25-600 เมตร ความถี่สัก 50,000-400,000 เฮิร์ต
สำหรับระบบที่ติดรถได้ที่เรียกว่า Vehicular Laser Scanner (VLS) ก็จะมีคุณสมบัติเพิ่มคือกันน้ำ กันสะเทือน
ในอีกแนวคิด low-cost คือสร้างเลเซอร์สแกนเนอร์สำหรับการรังวัด จากเลเซอร์ในงานอุตสาหกรรม นักวิจัยสร้างหุ่นยนตร์ หรือ รถยนตร์ไร้ค้นบังคับ นิยมใช้ไลดาร์ราคาถูก ระยะสั้น 10-80 เมตร ความถี่ <10,000 เฮิร์ต ระบบพวกนี้ได้ Hokuyo UTM-30LX, Sick LMS-291 และล่าสุด Sick มีโปรดักส์ใหม่ LMS 100 Series ที่เล็กน้ำหนักเบา 1.1 กิโล ระยะ 10-50 เมตร ราคา 3059 ปอนด์ ได้มั้ง หรือ 1/10 เครื่องระบบใหญ่เป็นอย่างน้อย

ดังนั้นจึงมีนักวิจัยสนใจที่จะนำมาประกอบกัน1, 2 หรือ 3 เครื่อง หรืออาจจะมากว่า แล้วทำการ calibrate หา intrinsic parameter ซะแล้วให้หมุนได้ 1-2 เฮิร์ต การนำเครื่องมือมาตั้งบนแทนให้หมุนได้ต้องการอุปกรณ์มาตราฐานทางไฟฟ้าเครื่องกลชิ้นหนึ่งที่เรียกว่า "slip-ring" เพื่อให้สายไฟและสัญญาณ ผ่านจากแท่นตั้งพื่้นหรือติดรถไปสู่แกนหมุนทีติดกับเลเซอร์ได้
ลองดูผลงานของ Fraunhofer Institute จากประเทศเยอรมัน ชนิด 2 เครื่อง http://www.3d-scanner.net/

ระบบที่ 1 ประกอบขึ้นจาก Hokuyo UTM-30LX เพียงตัวเดียว



ระบบที่ 2 ประกอบด้วย Sick LMS_291 จำนวน 2 ตัว ภาพจาก www.3d-scanner.net


และล่าสุด ระบบที่ 3 ประกอบด้วย Sick LMS-151 จำนวน 3 ตัว ทำให้ด้วยความถี่ 80,000 เฮิร์ต ใกล้ 100 kHZ!
เข้าใจว่าเป็นความร่วมมือ Informatik Institut , University of Friburg, Germany กับ Robot Group ของ Oxford Univerisyt, UK
http://europa.informatik.uni-freiburg.de/files/SheehanHarrisonNewman_ISER2010.pdf

PostgreSQL กับ วันเดือนปี ของไทย ( Date Time and Thai Localization for PostgreSQL/PostGIS)

ในการพัฒนาฐานข้อมูล เช่น PostgreSQL/PostGIS หากต้องการจัดเก็บวันเวลา ควรใช้เวลาสากล เช่น timestamp with time zone แต่เวลาแสดงผล ต้องเป็นแบบไทยๆ ผมมีฟังก์ชันช่วยงานดังนี้
ชื่อวันของสัปดาห์ ชื่อเดือน ปีพศ ให้ใช้ฟังก์ชัน PS_Day(), PS_Month(), PS_Year()

----------------------------------------------------------------------

-- Function: "PS_Day"(timestamp with time zone, boolean)

-- DROP FUNCTION "PS_Day"(timestamp with time zone, boolean);

CREATE OR REPLACE FUNCTION "PS_Day"(datetime timestamp with time zone, thai_lang boolean)
RETURNS text AS
$BODY$
DECLARE
a_text text;
BEGIN
IF thai_lang = TRUE THEN
a_text := to_char( datetime , 'TMDay' ); -- TM Translation Mode
ELSE
a_text := to_char( datetime , 'Day' );
END IF;
RETURN a_text;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION "PS_Day"(timestamp with time zone, boolean) OWNER TO postgres;
COMMENT ON FUNCTION "PS_Day"(timestamp with time zone, boolean) IS 'return THAI or english day of week';

------------------------------------------------------------------------

-- Function: "PS_Month"(timestamp with time zone, boolean)

-- DROP FUNCTION "PS_Month"(timestamp with time zone, boolean);

CREATE OR REPLACE FUNCTION "PS_Month"(datetime timestamp with time zone, thai_lang boolean)
RETURNS text AS
$BODY$
DECLARE
a_text text;
BEGIN
IF thai_lang = TRUE THEN
a_text := to_char( datetime , 'TMMonth' ); -- TM Translation Mode
ELSE
a_text := to_char( datetime , 'Month' );
END IF;
RETURN a_text;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION "PS_Month"(timestamp with time zone, boolean) OWNER TO postgres;
COMMENT ON FUNCTION "PS_Month"(timestamp with time zone, boolean) IS 'return THAI or english month';

-----------------------------------------------------------------------------

-- Function: "PS_Year"(timestamp with time zone, boolean)

-- DROP FUNCTION "PS_Year"(timestamp with time zone, boolean);

CREATE OR REPLACE FUNCTION "PS_Year"(datetime timestamp with time zone, thai_lang boolean)
RETURNS text AS
$BODY$DECLARE
year_int integer;
BEGIN
IF thai_lang = TRUE THEN
year_int := (EXTRACT(YEAR FROM datetime))::int+543 ;
ELSE
year_int := (EXTRACT(YEAR FROM datetime))::int ;
END IF;
RETURN CAST(year_int AS text);
END;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION "PS_Year"(timestamp with time zone, boolean) OWNER TO postgres;
COMMENT ON FUNCTION "PS_Year"(timestamp with time zone, boolean) IS 'return BE or AD from ''timesptamp''';

------------------------------------------------------------------------

ปล. ผม copy & paste รู้สึกว่ามัน indent ไม่ค่อยดี แต่โปรแกรมสั้น ไปเคาะเอาเองแล้วกันนะครับ
ลองดูนะครับ หากมีปัญหา เมลย์ถึงแล้วกันจะส่ง dump ไฟล์ไปให้
อ้อ อีกอย่าง ตอน CREATE DATABASE อย่าลืมระบุ
CREATE DATABASE "Your_DB_Name"
WITH OWNER = postgres
ENCODING = 'UTF8'
....
LC_COLLATE = 'Thai_Thailand.874'
LC_CTYPE = 'Thai_Thailand.874'
...
ครับ

วันพุธที่ 23 กุมภาพันธ์ พ.ศ. 2554

VGI หัวข้อใหม่ วิชาใหม่ ในวงการศึกษา

Volunteer Geographic Information (VGI) ภูมิสารสารสนเทศด้วยอาสาสมัคร หรือ ภูมิสารสนเทศแบบร่วมด้วยช่วยกัน เป็นแนวทางการยกระดับเครื่องมือในการสร้าง ประกอบ และเผยแพร่ภูมิสารสนเทศโดยอาสาสมัครปัจเจกบุคคล

Professor Goodchild ศาสตราจารย์ด้วย GIS ได้เขียนบทความเป็นเรื่องราว เป็นเชื้อให้วงการศึกษา กำลังมองว่าจะเป็นวิชาใหม่อีกหนึ่งวิชา เป็นหัวขอวิจัย หรือแม้กระทั่ง Loughborough ในอังกฤษคิดเป็นหัวข้อวิทยานิพนธ์ ป เอก แล้วด้วย

รู้จักกับ Professor Goodchild ได้ที่

http://www.geog.ucsb.edu/~good/Goodchild-CV.html
Goodchild 2007
M.F. Goodchild (2007) Citizens as sensors: the world of volunteered geography. GeoJournal 69(4): 211-221. [441]

จัดเก็บไฟล์ภาพ "ปิรามิดภายนอก" หรือ "ปิรามิดภายใน" ดี

ในกลุ่มวิจัยผม หลายปีก่อนมีนักวิจัยทำงาน mapserver / map service ปัญหาที่พบบ่อย คือตัดสินใจว่า จะนำไฟล์แผนที่ภาพขนาดใหญ่ในรูปแบบ GeoTIFF ติดตั้งเข้าในระบบเซอฟร์แวอร์ อย่างไรดี เพื่อให้เรียกดู การย่อขยายทำได้เร็ว
ปกติเรามี 2 แนวทาง
1) "ปิรามิดภายใน" นำ GeoTIFF มาสร้าง image pyramid ด้วย gdal_addo "gdal add overlay" ข้อดีคือจัดการง่าย มีไฟล์ GeoTIFF หนึ่งไฟล์เช่นเดิม แม้ว่าขนาดไฟล์จะเพิ่ม 33% ก็ยินดีรับไปใช้อย่างยิ่ง
2) "ปิรามิดภายนอก" นำ GeoTIFF มาสร้างปิรามิดหลายชั้น แต่ละชั้นคือไฟล์ GeoTIFF ใหม่ วิธีนี้จะได้ไฟล์ geotiff เล็ก แล้วจัดโครงสร้างใน mapfile (UMN Mapserver) คุมด้วย scale min/max

ที่คาใจคือแบบใหนเร็วกว่า และโปรแกรมประยุกต์ผ่านเวปประเภทให้บริการแผนที่ภาพ เราให้ความสำคัญกับความเร็วเป็นเรื่องแรก
แล้วคำถามนี้ประทุขึ้น ผมเชื่อสะสมหลายๆค่ายทั่วโลก จนร้อนถึงศาสดา Frank Warmerdam ได้รับการเรียกร้องจากผู้ใช้และการสนับสนุนจาก MapGears และ USACE ให้ตรวจสอบและปรับปรุง ซึ่ง Frank อธิบายให้พวกเราฟังว่า โดยโลจิก เราน่าจะเห็นการอ่าน "ปิรามิดภายใน" น่าจะเร็วกว่า การอ่าน "ปิรามิดภายนอก" ที่ต้องวิ่งไปเปิดภายหลายไฟล์ อีกทั้งตัดสิ้นใจเงื่อนใขสเกล แต่ในความเป็นจริงปัจจุบัน "ปิรามิดภายใน" กลับประสิทธิภาพต่ำกว่าถึง 3 เท่า ตามกราฟ


หลังจากนี้น่าจะสบายใจได้ Frank ได้แก้ใข และสร้างกลับเข้าไปที่ไลบรารี่พื้นฐานคือ libtiff ในเร็ววัน
สรุป หลังจาก libtiff ใหม่ ซอฟต์แวร์ ทุกตัวที่ใช้ ความสามารถทั้งสองแบบนี้ได้ ก็จะทำงานได้เร็วพอๆกัน
อ่านกูรู ว่าเขาค้นหาปัญหาและแก้ใขอย่างไร เต็มๆได้ที่
http://fwarmerdam.blogspot.com/2011/02/mapserver-tiff-overview-performance.html

อนี่งจะเห็นว่ากรณี Super Overlay ของ GoogleEarth ใช้ ปิรามิดภายนอก + ไทล ร่วมกัน เช่น gdal2tiles ทำให้

วันจันทร์ที่ 21 กุมภาพันธ์ พ.ศ. 2554

ตัวอย่าง PL/SQL แปลงพื้นที่ให้เป็น ไร่-งาน-วา

มาหัดเขียน Procudure Language สำหรับไว้แปลงพื้นที่ จากมาตราเมตริก ตารางเมตร ให้แสดงผลเป็น มาตราไทย
อย่างง่าย ผู้ใช้ป้อนค่าพื้นที่ใน หน่วยไร่ เช่น ISO/SF SQL ST_Area( the_geom ) สำหรับ geometry object ที่มี SRID ยูทีเอ็ม โซน 47/47 ที่มีรหัส epsg:32647, 32648 หรือจะใช้ geography object ก็สดวกมาก จัดเป็นเป็นพิกัดภูมิศาสตร์ (ยีออเดติกส์) แต่ให้ผลพื้นที่จาก ST_Area ( geography_type) หน่วยเป็นตารางเมตร โดยตรง

---------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION "PS_Area_Thai"(area float) RETURNS text AS $$
DECLARE
rai int;
ngan int;
wa float;
str_area text;
BEGIN
-- !!!For sake of floating point round-up --
-- !!!THIS PROGRAM IS NOT PERFECT! --
-- !!! THIS IS NOT A PRODUCTION CODE --
rai := floor( area/1600. );
ngan := floor( area/400. - 4.*(rai::float) );
wa := (area/4.) - (rai::float)*400. - (ngan::float)*100.;
RAISE NOTICE 'area % ->rai % ngan % wa %', area, rai,ngan,wa;
str_area := to_char(rai,'999999999') || '-' || to_char(ngan,'9') || '-' || to_char(wa::real,'999D9') ;
return str_area;
END;
$$ LANGUAGE plpgsql;
---------------------------------------------------------------------------

ตัวโครงสร้างโปรแกรมโอเคนะครับ แต่ให้ระวังเรื่องการปัดเศษ เช่น ท่านอาจพบกรณี
ตัวอย่างเช่น พื้นที่ 1.99999969 ไร่
เมื่อคำนวนเป็น ไร่ งาน วา จะได้ 1 ไร่ 3 งาน 99.99987654 ตารางวา
แต่หากต้องการให้ หน่วยวา แสดงผลทศนิยมสัก 1 ตำแหน่ง
อัลกอริธึมในฟังก์ชันข้างต้นจะแสดง "1-3-100.0" หรือ 1 ไร่ 3 งาน 100.0 ตร.ว
ซึ่งคงนำไปแสดงผลใช้งานยังไม่ได้ มนุษย์ก็จะโทษว่าคอมพิวเตอร์ทำงานผิดแน่ๆ
ซึ่งจะต้องแก้ใขต่อไป ไว้จะเล่าให้ฟังต่อครับ

วันเสาร์ที่ 19 กุมภาพันธ์ พ.ศ. 2554

สรุป 2010 Android โตขึ้น 888.8% เทียบจากปีที่แล้ว

บริษัทวิเคราะห์ตลาดระดับโลก Gartner สรุปการตลาดของสมาร์ทโฟน สรุปยอดเมื่อ กุมภาพันธ์ 2011 ปรากฏว่า Android โตขึ้น 888.8% เทียบจากปีที่แล้ว และเขยิบขึ้นเป็นอันดับ 2 ซะแล้ว

จาก PressRelease: Gartner Says Worldwide Mobile Device Sales to End Users Reached 1.6 Billion Units in 2010; Smartphone Sales Grew 72 Percent in 2010
โดยภาพรวมแล้วยอดขาย Mobile Device เพิ่มทุกเจ้าสูงถึง 31.8% แต่คิดเฉพาะ smart phone ปรากฏว่าโตซะ 72.1% แต่สัดส่วนการตลาดปรับตัวไปมาระหว่างค่ายและเทคโนโลยีค่อนข้าง ผมมองว่าปี สองปีหน้าจะเป็นช่วงรอยต่อ วัดดวงระหว่าง IOS กับ Android
อ้อ อีกอย่าง ปีนี้ต้นไป Android tablet 7 นิ้ว และ 10 นิ้ว ยังเปิดตัวแข่งกันไม่หยุด ส่วน Apple ก็กินบุญเก่า ปั้มและข่าย IPhone4 และ IPAD ด้วยต้นทุนต่ำสุดโดยการขุดดินมาแปรเป็นทางคำ ผลิตรุ่นเดียว โมเดลเดียว สองสีขาว ดำ ก็พอแล้ว แล้วยังโกร่งราคมได้อีกหลายพันบาทในตลาดมือถือบ้านเรา...
ถ้าอยากดูยอดขายรายยี่ห้อ Gartner ก็มีให้ดูตามนี้ครับ

วันจันทร์ที่ 14 กุมภาพันธ์ พ.ศ. 2554

การฝังลายน้ำลงในไฟล์ภาพขนาดใหญ่

การฝังลายน้ำ (watermark) ลงในเนื้อภาพเพื่อวัตถุประสงค์ต่างๆ เช่นการแสดงสิทธิการใช้งาน การให้ข้อมูลข่าวสารที่แน่ใจว่าผู้ใช้งานภาพจะต้องอ่านเป็นต้น หากภาพเล็กก็สามารถใช้ซอฟต์แวร์ image editor เปิดภาพแล้วพิมพ์ข้อความลงไปแล้วสั่งจัดเก็บ แต่หากเป็นภาพขนาดใหญ่เช่น ภาพจากกล้องถ่ายภาพทางอากาศ ภาพจากดาวเทียมสำรวจทรัพยากร เราสามารถใช้ชุดซอฟต์แวร์ฟรี เช่น FWTool/GDAL/OGR และ ImageMagick(convert,composite) ทำไดัดังตัวอย่างนี้

ตัวอย่างข้างต้นทำได้โดยใช้ Batch File ต่อไปนี้
=================================================
@echo on
::
:: to pre-process RTSD-DMC
:: D:\GeoData\Chula-DMC>gdalenhance -ot Byte -equalize test_dmc.tif dmc_0682.tif
::
SET "DMC_IMAGE_NAME=dmc_0682"
::SET "DMC_IMAGE_NAME=dmc_0683"
::SET "DMC_IMAGE_NAME=dmc_0684"
SET "DMC_EXT=.tif"
SET "DMC_LIC_SUFFIX=_SV_LIC.tif"
::
::SET DEBUG=True
SET DEBUG=False
if "%DEBUG%" == "false" (
SET "DMC_IMAGE=dmc_small.tif"
SET "IMAGE_SIZE=768x1382"
SET "DMC_LIC_IMG=dmc_small_SV_LIC.tif"
) ELSE (
SET "DMC_IMAGE=%DMC_IMAGE_NAME%%DMC_EXT%"
SET "IMAGE_SIZE=7680x13824"
SET "DMC_LIC_IMG=%DMC_IMAGE_NAME%%DMC_LIC_SUFFIX%"
)
echo License-embedded Image named %DMC_LIC_IMG%
::
::
SET IM_CONVERT=d:\Programs\ImageMagick-6.6.5-10\convert.exe
SET IM_COMPOSITE=d:\Programs\ImageMagick-6.6.5-10\composite.exe
SET LICENSE_IMAGE=license.tif
::
::
echo Starting processing at:
time /T
::
%IM_CONVERT% -font C:\Windows\Fonts\angsa.ttf -size %IMAGE_SIZE% -gravity center label:@license_dmc_utf8.txt %LICENSE_IMAGE%
::openev %LICENSE_IMAGE%
::
%IM_COMPOSITE% -dissolve 50 -gravity center %LICENSE_IMAGE% %DMC_IMAGE% %DMC_LIC_IMG%
::openev %DMC_LIC_IMG%
::
ECHO End of processing at
time /T
::
===================================================
สำหรับข้อความที่จะฝังลงไป โดยเฉพาะหากเป็นภาษาไทย อาจจัดเก็บไว้ใน
text file ก่อน โดย encoding ต้องเป็น UTF-8 จึงจะใช้ได้ ใน
ตัวอย่างข้างต้น ผู้เขียนจัดเตรียมข้อความที่ยืดยาวไว้ในไฟล์ชื่อ license_dmc_utf8.txt

ซอฟต์แวร์คำนวนงานรังวัดยีออเดติกส์

การรังวัดยีออเดติกส์สามารถนำเข้ามูลการรังวัดผสมผสานได้หลากหลาย เช่น จากการรังวัดเส้นฐานในสามมิติในการรับสัญญาณจีพีเอส (GPS baseline measurement) การวัดทิศทางและระยะทางด้วยกล้องโทตอลสเตชั่น (Totalstation) การรังวัดค่าต่างระด้บด้วยกล้องระดับและสต๊าฟอินวาร์(Level with Invar staff) อีกทั้งการรังวัดที่ซับซ้อนที่ต้องการติดตามตรวจสอบสิ่งก่อสร้างขนาดใหญ่ เช่น สะพาน เขื่อน ในกรณีนี้ต้องการซอฟต์แวร์คำนวนงานรังวัดยีออเดติกส์ ที่รองรับข้อมูลรังวัดที่เป็น "ค่าสังเกตุ" หลายหลายคุณภาพ อีกทั้งสามารถเลือกจำลองแบบ เพื่อเปรียบเทียบค่าพิกัดเมื่อเวลาเปลี่ยนไปเช่น การรังวัดตรวจสอบการบิดเบี้ยวของสิ่งปลูกสร้าง (deformation analysis for large structure)
ในการนี้จำเป็นต้องมีซอฟต์วแวร์ช่วยคำนวน ซอฟต์แวร์ที่เป็นเปิดรหัสได้แก่
Gama - Geodesy and Mapping ,
เป็น OpenSource , พัฒนาด้วย GNU-gcc-g++, ข้อมูลนำเข้าเป็น XML ทันสมัย สดวก
JAG3D - Java Graticule 3D
พัฒนาด้วย JAVA , มี GUI และ graphic visualization ครบ, ข้อมูลนำเข้าเป็น Text ง่ายๆ
Xdesy (freeware!)
เป็น freeware แต่แจกมานาน ดูเหมือนได้รับความนิยมพอสมควร
ในภาพเป็นต้วอย่างการประมวลผลการรังวัดตรวจสอบการบิดเบี้ยวของเขื่อน


ท่านมีตัวเลือกถึง 3 ตัวครับ

วันศุกร์ที่ 11 กุมภาพันธ์ พ.ศ. 2554

เมือต้องอ่าน EXIF จาก Geotagged Photo

กล้องที่มี GPS ในตัวก็เติบโตตามลำดับ อีกทั้งยังเข็มทิศแม่เหล็กชนิดอิเล็คทรอนิกส์สำหรับบอกทิศทางด้วย เช่น SONY DSC-HX5V

การมีพิกัดและทิศทาง อาจนำไปใช้ในการแสดงตำแหน่งภาพและทิศทางในแผนที่ หรือ แทรกภาพเฟรม ไปอยู่บนภาพพาโนรามา
Exif จะบรรจุข้อมูลพิกัดและทิศทาง ดิบๆดังนี้
-----------------Exif Tags------------------------
0 (2, 2, 0, 0)
1 N
2 ((13, 1), (43, 1), (2154, 1000))
3 E
4 ((100, 1), (30, 1), (49889, 1000))
5 0
6 (123, 10)
7 ((9, 1), (40, 1), (16000, 1000))
9 A
10 3
12 K
13 (2, 10)
14 T
15 (32118, 100)
16 M
17 (27925, 100)
18 WGS-84
29 2010:11:18
30 0
----------------------------------------
ค่าสำคัญๆ คำนวนได้จาก
2) Latitude =13+43/60+2154/1000/3600. องศา
หรือ 13-43-02.154 องศา ลิปดา ฟิลิปดา
4)Longitude = 100/1.+30/60 + 16000/1000/3600. องศา
หรือ 100-30-16.000 องศา ลิปดา ฟิลิปดา
6) Altitude = 123/10. เมตร
หรือ 1.23 เมตร
17) ImgDirection = 27925/100.
หรือ 279.25 องศา