Subversion in Actions I

การทำเวอร์ชั่นเป็นอีกเรื่องที่ผมพึ่งศึกษาครับ ตอนนี้ทำทั้ง software และงานเอกสาร มีประโยชน์ดีเหมือนกันใช้ไปก็ชักติดใจ ยังแอบคิดเหมือนกันว่าทำไมไม่รู้จักกันก่อนหน้านี้เนี้ยะ T-T หลักๆ ที่ใช้คือ Subversion (SVN) ครับ เพราะว่าเอาไปใช้เรื่องานเอกสารกับพี่ในห้อง (ซึ่งไม่ได้มาทาง software) เพราะเห็นว่า plugin มันง่ายดีบน Windows แต่ถ้าเป็นงานส่วนตัว ก็ใช้ Git ง่ายทีเดียว ความจริงอยากเขียน Git แต่คิดว่า Git บน Windows ยังไม่เกิดแน่ๆ เลยขอเป็น SVN ก่อนแล้วกัน ส่วน Git ค่อยมาเก็บตกเอาทีหลัง ไหนๆ วันนี้ก็ฤกษ์ดีแล้ว (เห็นเขาว่ากัน แต่ส่วนตัวเฉยๆ มาก) เลยขอเอาคำสั่งที่คิดว่าน่าจะใช้กันบ่อยๆ มาลงดีกว่า

ส่วนประกอบของ Subversion

ส่วนประกอบเบื่องต้นของ SVN

ส่วนประกอบของ SVN

SVN ประกอบด้วย 2 ส่วนก็คือ ทางฝั่งขวาคือฝั่ง Server หรือศัพท์ทางเทคนิคจะเรียกว่า Subversion Server จะเก็บ Repository ที่เราสร้าง ส่วนในภาพขอเรียกสั้นๆ ว่า Repository เพื่อให้เข้าใจได้ง่ายขึ้น Repository จะเป็นคนจัดการเรื่อง Version ของข้อมูล เก็บบันทึกการเปลี่ยนแปลงทุกอย่างไว้ และทำหน้าที่แจกจ่ายข้อมูลให้กับคนที่เข้ามาใช้งาน ฝั่งซ้ายคือ Client หรือศัพท์ทางเทคนิคจะเรียกว่า Subversion Client จะสื่อสารกับ Repository ผ่านตัวกลางที่เรียกว่า Network โดยอาศัยโปรโตคอลต่างๆ นาๆ แล้วแต่ทาง Repository จะสนับสนุน เช่น svn, svn+ssh, https เป็นต้น

สร้าง Repository

ก่อนอื่นที่จะใช้ SVN คือ ต้องมี Repository ที่เราสามารถไป Checkout ข้อมูลมาได้ ในตัวอย่างที่ผมทำคือ สร้างไฟล์ Repository ในเครื่องตัวเองเลย เพื่อไม่ให้ไปเดือดร้อนชาวบ้านด้วย ใช้คำสั่ง

$ svnadmin create /path/to/repository

หมายเหตุ: /path/to/repository จำเป็นอย่างยิ่งที่ต้องเป็น Absolute Path

เสร็จแล้วจะได้โครงสร้างไดเร็คทอรี่ ที่ทำหน้าที่เป็น Repository ดังภาพ

โครงสร้างภายใน Repository เปล่าที่สร้างขึ้นด้วยคำสั่ง svnadmin

โครงสร้างภายใน Repository เปล่าที่สร้างขึ้นด้วยคำสั่ง svnadmin

Check out

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

  $ pwd
  /Users/sitdh/Desktop/workspace
  $ svn co file:///Users/sitdh/Repository/helloSVNServer
  Checked out revision 0.
  $ ls
  helloSVNServer
  $ cd helloSVNServer/
  $ ls
  • บรรทัดที่ 2 สั่ง Checkout ข้อมูลจาก Repository โดยใช้โปรโตคอล file เพราะว่าทำ Repository ในเครื่องเดียวกัน หาก Repository อยู่ที่อื่นก็ต้องตรวจสอบก่อนกว่าจะใช้โปรโตคอลอะไรสำหรับสื่อสาร หากต้องใส่ชื่อกับรหัสผ่าน ก็ใช้ --username USERNAME และ --password PASSWORD หรือจะใส่ --no-auth-cache เพื่อไมให้เก็บชื่อและรหัสผ่านไว้ก็ได้ครับ จะได้สบายใจ :P ไดเร็คทอรี่นี้จะเรียกว่า Working Copies ครับ
  • บรรทัดที่ 4 เลขตัวสุดท้ายคือ Revision (หรือ version) ใน Repository ที่เป็น 0 เนื่องจาก Repository ของเราสร้างกันสดๆ ร้อนๆ เมื่อครู่นี้เอง ซึ่งตัวเลขนี้จะเพิ่มขึ้นไปเรื่อยๆ เมื่อเราส่งข้อมูลกลับไปยัง Repository (Commit)
  • บรรทัดที่ 8 ลองเข้าไปดูด้านใน Working Copies จะเห็นว่าไม่มีอะไรด้านใน แต่ความจริงแล้วจะมีไฟล์ .svn ซ่อนอยู่ เป็นไฟล์ที่ใช้เก็บข้อมูล index ใน working copies สำคัญมาก ห้ามลบเด็จขาด

เพิ่มและส่งกลับเข้าสู่ Repository (Add + Commit)

เนื่องจากเราไม่ได้เป็นเจ้าของ working copies อย่างแท้จริง และต้องทำงานร่วมกันคนอื่น เลยมีคำแนะนำ (เข้าใจว่าน่าจะเป็น De facto) ให้สร้างไดเร็คทอรี่ขึ้นมาอีก 3 ได้แก่ (เรียงตามการใช้)

  • trunk ใช้เก็บข้อมูลหลักของโปรเจ็คทั้งหมด ภายในนี้จะเก็บข้อมูลที่ถูกตรวจสอบ และยอมรับว่าถูกต้องแล้วจะเรียกว่า baseline
  • branch เก็บข้อมูลส่วนที่แยกออกไปพัฒนาต่างหาก หรือทดลองวิธีการแก้ปัญหาใดอย่างหนึ่ง เพื่อไม่ให้ส่งผลกระทบกับข้อมูลหลักที่อยู่ใน baseline
  • tag ใช้แบ่งข้อมูลออกเป็นหมวดหมู่ใช้งานเหมือนกับ tag ใน Web 2.0

วิธีสร้างง่ายมากครับ คือ สร้างไดเร็คทอรี่ที่ต้องการแล้วค่อยใช้คำสั่ง add ของ svn ทีหลัง หรือใช้คำสั่ง mkdir ของ svn เพื่อสร้างและใส่เข้าไปใน list สำหรับ Commit ไปยัง Repository เลยก็ได้

วิธีที่ 1

$ mkdir trunk; mkdir branch; mkdir tag

$ ls
branch   tag   trunk

$ svn add *
A          branch
A          tag
A          trunk

วิธิที่ 2

$ svn mkdir trunk; svn mkdir branch; svn mkdir tag
A          trunk
A          branch
A          tag

$ ls
branch   tag   trunk

หลังจากนั้นสั่ง commit เพื่อส่งข้อมูลไปให้ Repository ด้วยคำสั่ง

$ svn ci -m "Initialize Repository Structure"
Adding          branch
Adding          tag
Adding          trunk

Committed revision 1.

คำสั่งด้านบนจะส่งข้อมูล หรือ Commit ไปยัง Repository ที่ Checkout มาข้างต้น โดยจะมีข้อความบันทึกประจำรุ่นตามข้อความที่ระบุหลัง -m หรือใช้ --message ก็ได้เช่นกัน บรรทัดที่ 2-4 คือ รายการไฟล์ที่ส่งข้อมูลเข้าไปยัง Repository ส่วนบรรทัดสุดท้ายคือเวอร์ชั่นล่าสุดหลังจากส่งไฟล์เข้าสู่ Repository

ตอนนี้เราได้โครงสร้างสำหรับเก็บข้อมูลเรียบร้อยแล้ว (อย่าลืมนะครับ นี่คือโครงสร้างแนะนำเท่านั้น ไม่จะเป็นต้องสร้างโครงสร้างแบบนี้ก็ใช้ได้ปกติ) ต่อไปคือเริ่มทดลองสร้างโปรเจ็คกันครับ เริ่มด้วยเข้าไปยัง trunk แล้วสร้างไดเร็คทอรี่ และไฟล์ด้านใน [02-04] เสร็จแล้วจะใส่ไฟล์เข้าไปในรายการอัพเดตกับ Repository [07-09] แล้วจึงส่งไฟล์ไปยัง Repository [11-15] ดังนี้

  $ cd trunk
  $ mkdir aloha
  $ cd aloha
  $ touch index.php
  $ cd ..

  $ svn add *
  A          aloha
  A          aloha/index.php

  $ svn ci -m "Create Project"
  Adding          trunk/aloha
  Adding          trunk/aloha/index.php
  Transmitting file data .
  Committed revision 2.

ซึ่งหากมีไฟล์ใหม่เพิ่มขึ้นมาเรื่อยๆ ก็สามารถใช้คำสั่ง snv add ตามด้วย svn ci เพื่อส่งข้อมูลภายใน working copies ไปสู่ repository

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

แนะนำการใช้งานสัญญาอนุญาตเบื้องต้น

การใช้สัญญาอนุญาต” เป็นอีกเรื่องหนึ่งที่อยากเขียนลง blog มานานแล้วเหมือนกัน อย่างแรกก็คือความอยากส่วนตัวล้วนๆ ที่อยากศึกษาว่าแต่ล่ะอย่างที่เคยได้ยินมามันมีอะไรบ้าง เท่าที่รู้ มีเยอะมาก ไม่ว่าจะเป็น Creative Commons, GPL, Apache หรือ MIT แต่จุดประสงค์โดยรวมของสัญญาอนุญาตแต่ละชนิดก็คือต้องการให้เกิดการเผยแพร่และต่อยอดงานผลงานที่มีคนได้ตั้งต้นเอาไว้แล้ว ที่ต่างออกไปก็คือสัญญาอนุญาตแต่ละชนิดก็มีข้อกำหนดเล็กๆ น้อยๆ ต่างกันออกไป ขึ้นอยู่กับคนที่นำมาใช้ว่าต้องการให้ผลงานของตัวเองมีลักษณะการเผยแพร่แบบใด ส่วนปัญหาที่ผมเจอก็คือผมก็ไม่ได้ใช้ซะทุกอย่าง เลยไม่ได้มีเวลามาศึกษาสัญญาอนุญาตพวกนี้ อย่างที่ 2 คือ อยากให้เป็นจุดเริ่มต้นของคนที่จะเข้ามาศึกษาและใช้งานสัญญาอนุญาตที่คิดว่าเหมาะกับผลงานของตัวเองมากที่สุด และอย่างสุดท้ายที่ค่อนข้างสำคัญก็คืออยากให้ผู้ใช้งานเคารพ และตระหนักถึงความพยายามของผู้สร้างสรรค์ชิ้นงานเหล่านั้น เพราะเมื่อผลงานนั้นจะอนุญาตให้เราเอาไปใช้ได้โดยไม่เสียค่าใช้จ่าย แต่ก่อนที่ผลงานเหล่านั้นจะออกมาให้ใช้งานกันได้ ผู้สร้างสรรค์ย่อมต้องเวลาและความพยายามในการสร้างชิ้นงานเหล่านั้นเป็นอย่างมากแน่นอน ดังนั้นก่อนที่จะบอกว่าผลงานนั้นไม่ดี หรือไม่ครอบคลุมการใช้งาน ก็อยากให้ลองใช้งานมันให้จริงจังก่อน ยกตัวอย่างเช่น OpenOffice.org (OO.o) ซึ่งถ้าการใช้งานระดับผมแค่พิมพ์เอกสารนิดหน่อย ยังไม่เคยใช้งานคุณสมบัติหนักๆ บ่อยครั้งเท่าไหร่นัก แต่เท่าที่ใช้งานมา OO.o ก็สามารถใช้งานได้อย่างมีประสิทธิภาพไม่แพ้ MS Office หรือ iWork เลยทีเดียว แต่ถ้าจะให้งานออกมาเหมือนทั้ง 2 โปรแกรมผมว่าไม่ควรหวังครับ

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

ส่วนที่จะเขียนคงเป็นส่วน สัญญาอนุญาตที่ใช้กันบ่อยๆ เช่นที่ยกตัวอย่างในข้างต้นครับ

ข้อมูลเพิ่มเติม
– สัญญาอนุญาตสำหรับโอเพ่นซอร์ส – http://www.opensource.org/licenses/alphabetical

Object Oriented Programming with JavaScript I

ช่วงนี้ได้ใช้ JavaScript แบบจริงๆ จังๆ กับเขาบ้าง เพราะต้องเอาไปต่อกับ REST ในหน้าเพจที่ทำแต่เห็นว่าบางอย่างมันต้องเขียนโค้ดแบบเดิมซ้ำไปซ้ำมาอยู่เรื่อยก็เลยเกิดความคิดไปหาวิธีใช้งานแบบ OOP สำหรับ JavaScript ซะหน่อยดีกว่า เคยอ่านผ่านๆ ตาหลายรอบแล้วเหมือนกันแต่ไม่ค่อยได้เอาจริงเอาจังกับมันซะเท่าไหร่ครับ ตอนนี้งาน JavaScript เข้าจังๆ ก็เลยมีเหตุจำเป็นให้ต้องลอง นอกจากนั้นก็เป็นข้อดีหลายอย่างของการเขียน OO ที่ผมชอบก็คือ Reusable, Inheritance และ Encapsulation แต่ต้องบอกก่อนว่าการเขียนโปรแกรมแบบนี้ไม่ใช่เรื่องแปลกอะไร เพราะมันก็ทำได้ตั้งนานแล้วครับ blog ตอนนี้ก็คงเป็นการเอามะพร้าวห้าวมาขายสวนอีกตามเคยครับ :)

ความจริง เท่าที่ได้อ่านวิธีการเขียนก็คงไม่ใช้ OOP เหมือน Java หรือ PHP เท่าไหร่ เพราะใช้วิธีการแปลกๆ ของ JavaScript มาช่วยแต่ถึงอย่างไรวิธีการนี้ก็ใช้แนวคิดของ OO มาช่วยพัฒนาเลยหยวนๆ ถือว่าเป็น OOP แล้วกันครับ :)

hello, world

...
<script type="text/javascript" charset="utf-8">
	function HelloWorld(msg) {
		var defaultMessage = "HELLO, WORLD!!!";
		this.message = msg || "สวัสดีชาวโลก";

		alert('Let me say');

		this.goodie = function(m) {
			m = m || "?";
			alert(m + " " + good());
		}

		var good = function(m) {
			return "good day";
		}
	}

	function sayHi(m) {
		var hi = new HelloWorld();
		hi.goodie(m);
		hi.goodie(hi.message);
		hi.goodie(hi.defaultMessage);
		hi.good("Goodbye");
	}
</script>

</head>

<body id="index" onload="sayHi('สวัสดี')">
...

ด้านบนก็เป็นตัวงอย่างของการเขียน JavaScript แบบ OO ครับ ในที่นี้ “HelloWorld” จะทำหน้าที่เป็นคลาสจะ ให้ function sayHi เรียกใช้งาน โดยที่แนบตัวแปร message ไปให้ด้วย ใน script นี้จะมี alert message ให้เราเห็นทั้งหมด 4 หน้าต่างครับ ตามนี้เลยครับ แต่ก่อนเริ่มอาจจะต้องอธิบายกันนิดหน่อยเพื่อว่าจะมีคนไม่รู้ เครื่องหมาย “||” นี้ผมไม่รู้ชื่อวิธีเรียกมันอย่างเป็นทางการนะครับ แต่วิธีการทำงานก็คือโปรแกรมจะเปรียบเทียบว่าตัวแปรที่อยู่ด้านซ้ายเป็นค่าว่าง (null) หรือเปล่าถ้าใช้จะนำค่าที่อยู่ด้านซ้ายมาให้โดยอัตโนมัติ

Constructor

Constructor

Constructor


เป็น Constructor ของคลาส HelloWorld คิดง่ายๆ ก็คือ ทุกอย่างที่ไม่ได้ครอบไว้ด้วย function จะเป็น Constructor ของคลาสทั้งหมด

Assign

Assign

Assign


ตัวอย่างของการส่งค่าให้กับฟังก์ชั่น goodie ที่เป็น method ที่อยู่ภายในคลาส HelloWorld

Public Access

Public Variable

Public Access


ตัวอย่างการเข้าถึง Public variable ของคลาส “HelloWorld” สังเกตุได้ที่ตัวแปร “message” ที่อยู่ภายในคลาส “HelloWorld” ด้านบนที่นำหน้าด้วย this มีค่าเหมือนกับการใส่ “public”

Private Access

Private Access

Private Access


เป็นการเข้าถึงตัวแปรที่เป็นระบุไว้ว่าเป็น private ผลที่ได้คือไม่สามารถเข้าถึงได้เห็นได้จากค่าทีไ่ด้ออกมาจะเป็น ‘?’

ส่วนหน้าต่างสุดท้ายจะไม่ปรากฎให้เห็นเนื่องจากฟังก์ชั่น ‘good’ ถูกระบุให้มีชนิดการเข้าถึงแบบ private

นอกจากนี้ยังเขียนให้คลาสสามารถสืบทอดคุณสมบัติกันได้เหมือนภาษา OOP ทั่วไป แต่ยังไงก็ขอติดไว้ตอนหน้าแล้วกันครับ

Live Demo

วิธีทำ “สารบัญ” สำหรับ Pages

“สารบัญ” (Table of Contents – TOC) ถือได้ว่าเป็นอีกเรื่องหนึ่งทำให้ปวดหัวกันได้อีกเรื่องหนึ่ง ช่วงนี้ต้องมีเรื่องให้ทะเลาะกับพวก Word Processing บ่อยๆ ไอ้จะมานั่งจัดเลขหน้าที่ละหน้าก็เคยเจอประสบการณ์อันเลวร้ายช่วงมหาวิทยาลัยมาแล้ว เลยจำฝังใจครับ เลยลองไปหาข้อมูล ได้ความว่า Word Processing ที่เป็นที่รู้จักกันดี [MS Word, OO.o Writer และ Pages] สามารถสร้างสารบัญอัตโนมัติให้เราได้ทุกตัว ส่วนวันนี้จะมาแนะนำ Word Processing ที่อยู่บน OS X ที่ชื่อว่า Pages ครับ

Pages Inspector

Fig.1: Pages Inspector

อย่างแรกให้เปิดหน้าต่าง Inspector ขึ้นมาก่อนเพื่อกำหนดว่าเราจะเอารูปแบบ [Paragraph Style] มาสร้างเป็น สารบัญบ้าง จากรูปให้เลือก Document Inspector -> TOC จะเห็นว่ามี checkbox อยู่ 2 ฝั่งคือซ้าย และขวา ด้านซ้ายจะเป็นส่วนที่บอกว่าจะเอารูปแบบใดมาทำสารบัญ ส่วนด้านขวาจะบอกให้ Pages ใส่เลขหน้าด้วย

Chapter Style

Fig.2: Chapter Style

จากนั้นก็ลงมือเขียนกันเลยครับ โดยต้องจำไว้ว่าเราเลือก Paragraph Style แบบไหน ให้ไปโผล่ที่สารบัญบ้าง ก็ให้เลือกใช้ Paragraph Style ในกับข้อความที่ต้องการ ถ้ากลัวลืมก็เปิดหน้าต่าง Style Drawer เอาไว้ครับ [command + Shift + T]

Insert -> Table of Contents

Fig.3: Insert -> Table of Contents

จากนั้นให้ใส่หน้ากระดาษเปล่าๆ 1 หน้าครับ แล้วเลือกเมนู Insert -> Table of Contents จะได้หน้าสารบัญดังที่เห็นใน Fig. 4 ครับ เนื้อหาภายในจะปรับปรุงอัตโนมัติเมื่อเราเพิ่มหรือเปลี่ยนแปลงเนื้อหา แต่เราก็บังคับให้ Pages ปรับปรุงสารบัญได้โดยกดปุ่ม “Update Now” ใน Fig.1 ครับ

Fig.5: Table of Contents

Fig.4: Table of Contents

อย่างที่บอกครับ ว่า Word Processing ที่เรารู้จักกันสามารถทำ TOC ได้กันหมดแล้ว ศึกษาข้อมูลได้ตามลิงก์ด้านล่างครับ

Introduce to Google Maps :: เตรียมพร้อมก่อนลุย

จาก blog ตอนที่แล้วพูดถึงวิธีเอา Google Maps มาใช้แบบง่ายๆ ให้เป็นเป็นตัวอย่างกันไปแล้ว ตอนนี้ก็อย่างที่ทิ้งท้ายไว้คราวก่อนที่ว่าจะเอาวิธิการกำหนดค่าต่างๆ เพื่อบอกให้กูเกิ้ลส่งข้อมูลที่พร้อมใช้งานให้เราได้มากที่สุด

หลังจากเราสมัครของ key เพื่อใช้ดึงข้อมูลจาก Google Maps เลื่อนลงมาด้านล่างจะเห็นตัวอย่างการดึงโค้ดไปใช้งาน ทั้ง JavaScript, Flash และ HTTP Services

<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=true_or_false&amp;key=ABCDEF" type="text/javascript"></script>

วิธีเรียกใช้งานแบบ JavaScript โดยที่ ABCDEF คือ key ที่กูเกิ้ลให้มา

ถ้าลองเปรียบเทียบตัวอย่างด้านบน และตัวอย่างจาก blog ตอนที่แล้ว จะเห็นได้ว่าโค้ดที่กูเกิ้ลให้มา มี parameters ตัวหนึ่งที่ผมได้ตัดออกไป นั่นคือ sensor ที่จะเป็นพารามิเตอร์ที่บอกให้กูเกิ้ลตรวจสอบว่าเครื่อง Client ที่เรียกเข้ามามี อุปกรณ์ GPS ด้วยหรือไม่ ค่าที่เป็นไปได้คือ true และ false (เป็นค่า default) Continue reading

Introduce to Google Maps :: ภาคปฐมบท

Google Maps เป็นบริการหนึ่งของกูเกิ้ลที่ถึอว่าน่าสนใจ และสามารถนำมาใช้ประโยชน์อย่างเห็นได้ชัดบริการหนึ่งทีเดียว และสามารถนำมาประยุกต์ใช้ได้หลายอย่าง ยกตัวอย่างการใช้งานในบ้านเราเอง อย่างเช่น ใช้ลงประกาศ Event ต่างๆ หรือรายงานสภาพการจราจร ซึ่งนี่ก็เป็นที่เห็นได้ใช้สำหรับการเอา Google Maps มาใช้งาน ในตอนนี้ก็จะขอพูดถึงวิธีการดึงเอาข้อมูลแผนที่จาก Google Maps มาใช้งานกับ ส่วนเรื่อง traffic ไม่ต้องเป็นกังวลครับ เพราะกูเกิ้ลอนุญาตให้เรียกใช้ได้ถึง 500,00 page view ต่อวัน ซึ่งก็เป็นจำนวนที่มากจนเหลือเฟือครับ แต่ถ้าต้องการมากกว่านั้น ก็สามารถส่งอีเมล์ไปขอเพิ่มกับกูเกิ้ลได้ครับ
Continue reading