Random Thoughts on Random Things by Tanomsak
Random header image... Refresh for more!

Tutorial แบบบ้านๆ ตอนที่ 2 – แสดงหมุดจาก database ใน Google Maps

09 Dec 2008

จากคราวก่อนที่เราทดลองใช้ Google Maps API แสดงแผนที่ในหน้าเวปของเราไปแล้ว (อ่าน Tutorial แบบบ้านๆ ตอนที่ 1) คราวนี้มาต่อตอนที่ 2: เพิ่มและแสดงหมุดใน Google Maps กันครับ

ประโยชน์ของการใช้ Google Maps API แสดงแผนที่ก็คือเราสามารถแสดงหมุด จากข้อมูลใน database ของเราเองได้ คราวนี้เราจะทดลองสร้าง interface ให้ปักหมุด จัดค่าพิกัดใน database และนำข้อมูลจาก database กลับมาแสดงครับ

สิ่งที่ต้องเตรียมก่อนเริ่ม

  1. Database server สำหรับเก็บข้อมูลพิกัด (ผมใช้ MySQL v5.0)
  2. Web Server สำหรับประมวลผลและติดต่อ database จะใช้อะไรก็ตามสะดวกครับ (ผมเขียน server side ด้วย Rails ครับ ขอใช้ตัวอย่างเป็น Rails นะครับ)

ขั้นตอนที่ 1 มารู้จักวิธีการแสดงหมุดบนแผนที่ด้วย Google Maps API กันก่อน

หมุดที่แสดงบนแผนที่ Google Maps จะเรียกว่า Marker ครับ โดยการจะแสดงหมุดบนแผนที่นั้น ก็ต้องสร้าง Marker ขึ้นมาก่อน แล้วก็ทำการเพิ่ม Marker ที่สร้างมาลงบนแผนที่ ลองดูจาก script นะครับ

/*บรรทัด 2-3 เป็นการสร้างแผนที่และกำหนดจุดศูนย์กลางแผนที่ เหมือนในตอนที่ 1*/
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

/*บรรทัด 6-7 เป็นการสร้าง Marker โดยกำหนดตำแหน่งของ Marker ไว้ตำแหน่งเดียวกับศูนย์กลางแผนที่*/
var point = new GLatLng(37.4419, -122.1419);
var marker = new GMarker(point);

/*บรรทัด 10 เป็นการเพิ่ม marker ที่เพิ่งสร้างลงในแผนที่*/
map.addOverlay(marker);

ตัวอย่างของ script ข้างบน (view source กันเองนะครับ) เป็นไง ง่ายไหมครับ

ขั้นตอนที่ 2 สร้าง database สำหรับเก็บข้อมูลพิกัด

สร้าง table สำหรับเก็บข้อมูลพิกัด อย่างง่ายๆตาม SQL ข้างล่างครับ โดย field lat กับ lng เก็บทศนิยมแค่ 6 หลักก็พอครับ เนื่องจากถึงเก็บละเอียดกว่านี้ เรา็ก็คงสามารถสังเกตุไม่ออกแม้ว่าจะซูมแผนที่ใกล้ที่สุดแล้วก็ตาม ตัวอย่าง table และตัวอย่างข้อมูลต่อจากนี้ผมขออนุญาตนำมาจาก http://code.google.com/support/bin/answer.py?answer=87134&topic=11364 นะครับ

CREATE TABLE `markers` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 60 ) NOT NULL ,
`address` VARCHAR( 80 ) NOT NULL ,
`lat` FLOAT( 10, 6 ) NOT NULL ,
`lng` FLOAT( 10, 6 ) NOT NULL
) ENGINE = MYISAM ;

ขั้นตอนที่ 3 ใส่่ค่าเริ่มต้นใน database

ใส่ marker ลงใน database เพิ่มค่าเริ่มต้นซักหน่อย เดี๋ยวเราจะลองมาแสดงหมุดจาก database กัน

INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Frankie Johnnie Luigo Too','939 W El Camino Real, Mountain View, CA','37.386339','-122.085823');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Amici\'s East Coast Pizzeria','790 Castro St, Mountain View, CA','37.38714','-122.083235');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Kapp\'s Pizza Bar Grill','191 Castro St, Mountain View, CA','37.393885','-122.078916');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Round Table Pizza: Mountain View','570 N Shoreline Blvd, Mountain View, CA','37.402653','-122.079354');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Sausage Factory Inc','517 Castro St, San Francisco, CA','37.389578','-122.081463');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Tony and Alba\'s Pizza & Pasta','619 Escuela Ave, Mountain View, CA','37.394011','-122.095528');
INSERT INTO `markers` (`name`, `address`, `lat`, `lng`) VALUES ('Oregano\'s Wood-Fired Pizza','4546 El Camino Real, Los Altos, CA','37.401724','-122.114646');

ขั้นตอนที่ 4 ทดลองนำค่าพิกัดจาก database มาแสดงในแผนที่

พอเสร็จขั้นตอนที่ 3 เราก็มี database ที่มีข้อมูลพิกัดแล้ว ตอนนี้เราจะมาแสดงพิกัดจาก database บนแผนที่กันครับ เริ่มต้นง่ายๆที่สุดก็คือทำเป็นแบบ static โดยโหลดค่าพิกัดทั้งหมดที่ต้องการแสดงเข้าไปกับหน้าเพจที่กำลังแสดงเลย แล้วใช้ javascript สร้าง Marker จากค่าพิกัดนั้นๆ แล้วก็ใส่ลงในแผนที่

ขั้นตอนนี้จะต้องเขียนโปรแกรมฝั่ง server side กันละครับ ว่ากันตามสะดวกนะครับใครถนัดภาษาอะไร ตัวอย่างข้างล่างเป็น Ruby on Rails

ส่วน controller query ค่าพิกัดจาก database

def show
@markers = Marker.find(:all, :limit => 5)
end

ส่วน view ไฟล์ show.html.erb

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Maps JavaScript API Example</title>
<script src="http://maps.google.com/maps?file=api&amp;amp;amp;amp;amp;amp;amp;amp;amp;key=ABQIAAAAeNsNnRXUdrpgSw3qfvhz5hRHchrjOSPM-moa2HMmJZw-0fE6VhTsARfVd9x1Dg8TowZALqHIOcO20g"
type="text/javascript"></script>
<script type="text/javascript">

//<![CDATA[

function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

var bounds = new GLatLngBounds();
for (var i = 0; i < markers.length; i++) {
var point = new GLatLng(markers[i]['marker']['lat'],markers[i]['marker']['lng']);
var marker = new GMarker(point);
map.addOverlay(marker);
bounds.extend(point);
}
map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
}
}

//]]>
</script>
</head>
<body onload="load()" onunload="GUnload()">
<div id="map" style="width:500px;height:300px"></div>
<script type="text/javascript">

//<![CDATA[
var markers = <%=@markers.to_json%> ;
//]]>
</script>
</body>
</html>

ตัวอย่างเมื่อเสร็จสมบูรณ์

จุดสำคัญคือ ตรง var markers = <%=@markers.to_json%> เป็นส่วนที่นำค่าพิกัดที่ได้จาก database ส่งไปให้ function load() เพื่อนำไปสร้าง Marker และใส่ในแผนที่ โดย Rails จะ render ออกมาเป็น

var markers = [{"marker": {"lng": -122.083235, "lat": 37.38714}}, {"marker": {"lng": -122.078916, "lat": 37.393885}}, {"marker": {"lng": -122.085823, "lat": 37.386339}}, {"marker": {"lng": -122.079354, "lat": 37.402653 }}, {"marker": {"lng": -122.081463, "lat":37.389578 }}] ;

แล้วเราก็แกะค่าตัวแปล markers เพื่อเอา lat, lng ออกมาสร้าง Marker ครับ

var point = new GLatLng(markers[i]['marker']['lat'],markers[i]['marker']['lng']);

ไม่ยากใช่ไหมครับ แต่ว่าวิธีนี้มีปัญหาอยู่ตรงที่ ถ้าเรามี Marker จำนวนมากๆ เป็นร้อยเป็นพัน จะทำให้หน้า html ของเราใหญ่และโหลดช้า รวมถึงทำให้เปลือง memory ในการที่โหลด Marker จำนวนมากๆด้วยครับ วิธีแก้ก็คือทำการ load ค่าพิกัดและสร้างหมุดแบบ dynamic คือแสดงเพราะส่วนที่มองเห็นในแผนที่เท่านั้น แต่ว่าขอยกไปคราวหน้าละกันครับ

  • หลิว
    ทำไงถึงจะซ่อน markers เอาไว้ก่อนได้คะ พอถึงเวลาค้นหาค่อยเอาขึ้นมาโชว์อ่ะค่ะ

    ขอบคุณค่ะ
  • tanomsak
    ถ้ายังไม่สั่ง map.addOverlay(marker) marker ก็ยังไม่ปรากฎครับ

    แต่ถ้าจะซ่อน marker Google Maps API ก็มี function hide() สำหรับ marker ครับ

    http://code.google.com/intl/th-TH/apis/maps/doc...

    น่าจะเรียกใช้แบบนี้

    var marker = new GMarker(latlng); // สร้างตามปกติ
    map.addOverlay(marker); // วาง marker บนแผนที่
    marker.hide(); // ซ่อน marker
  • หลิว
    อยากทราบว่า google map จะโชว์รูปภาพใน info windows ยังไงคะ เชื่อมกับดาต้าเบสแล้วออกแต่ข้อมูลอ่ะค่ะ รูปภาพไม่โชว์เลย ใช้ sql 2008 อ่ะค่ะ เก็บไฟล์รูปภาพที่ my document

    ขอบคุณค่ะ
  • tanomsak
    ตอน map.openInfoWindow น่ะครับ ต้องใส่เป็น html ไม่ใช้ text ธรรมดาครับ เช่น

    map.openInfoWindow(latlng, "")

    ลองดูนะครับ
  • เขียนเองเลยเหรอครับ..โห..ขอบคุณมากเลยคับ..ที่นำมาแบ่งปันแบบนี้
    ผมติดตามอ่านอยู่นะคับ..เป็นกำลังใจให้คับผม...ตอนแรกๆ ก็งง เหมือนกันครับ..

    แต่ก็กำลังทำความเข้าใจอยู่เหมือนกันครับ..ฮ๋าๆๆ อ
  • โห ละเอียดมากเลยนะครับเนี้ย....ขอบคุณมากๆ เลยนะครับ.. นี่เป็นคนเขียนเองเลยป่าวเนี้ย..เห็น แจงซะ ...ฮ่าๆๆ สุดยอดครับ..ผม
  • tanomsak
    เขียนเองครับ ทดลองเขียนดูครับ แต่เหมือนส่วนใหญ่จะงง :)
  • arcreo
    ขอโทษครับผมยังไม่เข้าใจการติดต่อ database
  • hunt
    ผมก็ยังงงๆเหมือนกันครับ อยากได้โค้ดของ php อ่ะครับ ว่าเขียนดึงข้อมูลยังไง
  • ฺิbig
    อยากเรียนถามคับ ว่าหากต้องการนำภาพถ่ายมาวางในลักษณะ Overlay จำนวนหลายๆภาพต่อๆ กัน และแสดงในลักษณะ Layer หรือ กำหนดให้แสดงตามระดับความสูง หรือแสดงเฉพาะบริเวณที่หน้าจอ ( ไม่จำเป็นต้องโหลดภาพมาทั้งหมด )

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

    เห็นคนที่ติดตามแล้วถ้ารอไม่ไหวลองเข้าไปอ่านใน link ที่พี่เค้าให้ไว้ดูหน่อยดีมั้ยครับ(รู้สึกในตอนที่ 1)
    ผมว่า ศึกษาตาม Google Tutorial มันก็ไม่ยากเกินความพยายามนะครับ
  • tanomsak
    ขอบคุณสำหรับคำชมครับ คุณ Sang

    ถ้ามีเรื่องแนะนำให้เขียนก็แนะนำได้นะครับ หวังว่าจะเจอกันแถวๆบล๊อกนี้บ่อยๆครับ :)
  • nuijang
    ขอบคุณมากครับ บทความมีประโยชน์มากครับ
  • ท.ทหาร
    เมื่อไหร่จะมาแนะนำในส่วนที่เหลือคับ
  • tanomsak
    ช่วงนี้ยุ่งจนไม่ค่อยได้นั้งนิ่งๆเลยครับ :)

    ลองดูบทความอื่นๆใน category tutorial ดูนะครับ http://www.tanomsak.com/index.php/category/tuto...
  • bb
    ลองทำตามแล้วนะคะ พอถึงขั้นตอนที่ 4 ก้องงไปเลย ทำไม่เป็นอ่า ขอแบบละเอียดๆๆๆ ได้มั๊ยอ่าคะ
    ขอบพระคุณค๊า
  • tanomsak
    ผมอาจจะเขียนงงไปนิดครับ จริงๆมันขั้นตอนที่ 4 เีนี้ยมันแบ่งออกเป็นสองส่วนครับ

    1. ฝั่ง server (เช่น php หรือ Rails)

    อ่านค่าออกมาจาก database อันนี้ขึ้นอยู่กับว่าใช้ภาษาทางฝั่ง server เป็นอะำไรครับ ที่ผมใช้คือ Ruby on Rails ถ้าเกิดคุณ bb ใช้ php ก็เขียนถึงข้อมูลจาก database ออกมาตามปกติครับ

    จากนั้นก็เอาค่าที่ได้ ไปเขียนในหน้า html ที่จะแสดงภายใน block javascript
    <script type="text/javascript">
    var markers = [{"marker": {"lng": -122.083235, "lat": 37.38714}}, {"marker": {"lng": -122.078916, "lat": 37.393885}}, {"marker": {"lng": -122.085823, "lat": 37.386339}}, {"marker": {"lng": -122.079354, "lat": 37.402653 }}, {"marker": {"lng": -122.081463, "lat":37.389578 }}] ;
    </script type>

    แค่นี้ก็จบฝั่ง server ครับ

    2. ฝั่ง client ก็เขียน javascript ไปอ่านค่าตัวแปล array ชื่อ marker มาใช้สร้างหมุดครับ

    var point = new GLatLng(markers[i]['marker']['lat'],markers[i]['marker']['lng']);

    ตอบช้าไปนิดหวังว่ายังทันนะครับ
  • wit
    คือผมจะสร้างหมุดจากดาต้าเบสอะคับ แ่ต่ใช้ภาษา asp.net อะคับ ผมไม่รู้จะเขียนโค๊ดในส่วนของ java script ยังไงอะคับ ใหมันดึงข้อมูลมาจาก
    sql server อะัคับ ขอคำปรึกษาด้วยคับ
  • tanomsak
    ส่วน javascript น่าจะไม่ต่างกันนะครับ หลักมันอยู่ตรงที่ว่าต้องเอาค่าที่ asp.net อ่านออกมาจาก database เขียนเป็น javascript ลงในหน้า page ครับ ผมไม่เคยใช้ asp.net อาจจะแนะนำในรายละเอียดไม่ได้ เอาเป็นว่าเขียน script ออกมาใน format ข่างล่างนี้ครับ

    <script type="text/javascript">
    var markers = [{"marker": {"lng": -122.083235, "lat": 37.38714}}, {"marker": {"lng": -122.078916, "lat": 37.393885}}, {"marker": {"lng": -122.085823, "lat": 37.386339}}, {"marker": {"lng": -122.079354, "lat": 37.402653 }}, {"marker": {"lng": -122.081463, "lat":37.389578 }}] ;
    </script type>
  • ยุ้มยิ้ม
    งง ค่ะ ไม่เก่งโค้ดเลย - -*
    ภาษาอะไรก็ช่างเหอะ ไม่เก่งเลยค่ะ - -
  • ขอบคุณน่ะคับ สำหรับความรู้ที่แบ่งปัน

    การให้ความรู้ ยิ่งใหญ่กว่าสิ่งอื่นใด คับ... ขอบคุณจิง ๆ จากใจคับ...

    dynaz of iDeeZiGn
  • ืnienzart
    ติดตามคร๊าฟฟ

    ขอเรวๆด่วนๆได้ม่ะครับเรื่องนี้

    กาลังทำโปรเจคจบเรื่องนี้อยู่เลย

    ขอบพระคุนครับ
  • ^^
    ติดตามๆๆๆ
blog comments powered by Disqus