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

เพิ่มหมุดจาก Google Maps ลง Database

24 Dec 2008

ในเวป ddproperty.com ที่ผมกับเพื่อนดูแลอยู่เนี้ย เราให้คนที่ลงประกาศทุกคนต้องระบุตำแหน่งด้วยว่า อสังหาฯที่กำลังลงประกาศตำแหน่งอยู่ตรงไหน ผมก็ใ้ช้ google maps นี้แหละครับในการระบุตำแหน่ง

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

  1. หาค่า lat, lng จากตำแหน่งที่ click บนแผนที่
  2. เขียนค่า lat, lng ไว้ใน hidden fields ของ form ที่เราจะใช้ส่งค่ากลับไปฝั่ง server
  3. ทางฝั่ง server ก็รับกา่ร submit แล้วก็เขียนค่าลง database

ง่ายไหมครับ ลองมาดูกันทีละขั้น

ขั้นแรก หาค่า lat, lng จากตำแหน่งที่ click บนแผนที่

Google Maps API มี function ต่างๆที่เตรียมไว้ให้ใช้งานเยอะมากครับ รวมถึงเมื่อผู้ใช้ Interactive กับแผนที่เช่น Click บนแผนที่ ซูมเข้า ซูมออก หรือว่าจะขยับหมุดก็มี Event เกี่ยวข้องทั้งหมด สิ่งที่เราต้องทำเพื่อหาตำแหน่งที่ผู้ใช้งาน Click บนแผนที่ก็คือสร้าง Listerner เพื่อมาดักจับ Event เหล่านี้ ซึ่งทำได้อย่างนี้ครับ

 GEvent.addListener(map, "click", function(overlay, latlng) { /*เรา check ค่า overlay เพื่อดูว่าเป็นการกดบนแผนที่ หรือว่ากดบน overlay ที่อยู่บนแผนที่เช่น marker โดยตัวแปล overlay จะมีค่าเป็น null ในกรณีที่กดบนแผนที่เปล่าๆ*/ if (!overlay) { var lat = latlng.lat(); var lng = latlng.lng(); } }); 

โดย Event “click” เนี้ยจะส่งค่าตัวแปลไปให้ function ที่เราเขียนขึ้นมารับด้วย คือ overlay และ latlng โดย overlay จะเป็นตัวบอกว่าเป็นการ click บนแผนที่ หรือว่า click บน overlay ส่วน latlng จะเป็นตัวแปลประเภท GLatLng ซึ่งมี method lat(), lng() เพื่อหาค่า lat, lng แค่นี้เราก็จะได้ค่า lat, lng ของตำแหน่งที่ click บนแผนที่แล้วครับ

เขียนค่า lat, lng ไว้ใน hidden fields ของ form ที่เราจะใช้ส่งค่ากลับไปฝั่ง server

อันนี้ก็ตรงไปตรงมาครับ โดยเราจะำสร้าง form ที่มี hidden fields ชื่อ lat กับ lng ไว้ แล้วทำการ update ค่าทุกครั้งที่มีกาีร click บนแผนที่

</p> <form action=&quot;/new_marker&quot;> <p><input name=&quot;marker[name]&quot; size=&quot;30&quot;/> <input name=&quot;marker[address]&quot; size=&quot;30&quot;/> <input type=&quot;hidden&quot; id=&quot;marker_lat&quot; name=&quot;marker[lat]&quot;/> <input type=&quot;hidden&quot; id=&quot;marker_lng&quot; name=&quot;marker[lng]&quot;/> <input type=&quot;submit&quot; name=&quot;commit&quot; value=&quot;submit&quot;/></p> </form> <p>

แล้วก็จัดกา่รแก้ไข javascript ของเราให้ Update value ของ hidden fields lat, lng สังเกตุว่า ผมใช้ $(‘marker_lat’) แทนการ getElementById เพราะผมใช้ Prototype Framework อันนี้เพราะผมชินครับ ส่วนใครจะใช้ javascript แบบมาตราฐานก็ตามสะดวกครับ

 var map; var present = null; function updateHiddenFields(marker) { latlng = marker.getLatLng(); var lng = latlng.lng(); var lat = latlng.lat(); $('marker_lat').value = lat; $('marker_lng').value = lng; } function addMarker(latlng) { if (!present) { /*ใส่ options draggable เป็น true เพื่อให้สามารถย้ายตำแหน่งของหมุดได้ ส่วน bouncy เป็น false เพื่อไม่ให้หมุดเด้งหลังการย้ายตำแหน่ง*/ var newMarker = new GMarker(latlng, { draggable: true, bouncy: false}); map.addOverlay(newMarker); /*ตรวจจับ Event dragend เพื่อทำการ update ค่า lat,lng เมื่อมีย้ายหมุด*/ GEvent.addListener(newMarker, &quot;dragend&quot;, function() { updateHiddenFields(newMarker); }); updateHiddenFields(newMarker); map.panTo(latlng); present = true; } } function load() { if (GBrowserIsCompatible()) { map = new GMap2(document.getElementById(&quot;map&quot;)); map.setCenter(new GLatLng(37.4419, -122.1419), 13); GEvent.addListener(map, &quot;click&quot;, function(overlay, latlng) { if (!overlay) { addMarker(latlng); } }); } } 

เนื่องจากผมต้องการให้ระบุตำแหน่งทีละหนึ่งอัน (หนึ่งอสังหาฯ หนึ่งตำแหน่ง) เลยต้องมีตั้งค่าตัวแปล present เอาไว้ check ไม่ให้เพิ่มหมุดซ้ำ

ทางฝั่ง server รับกา่ร submit แล้วก็เขียนค่าลง database

ที่นี้ก็จัดกา่ร insert ค่าที่ได้รับจาก form ลง database ครับ

 def new_marker _marker = params[:marker] @marker = Marker.new(_marker) @marker.save! end 

เท่านี้ก็เป็นอันเรียบร้อยครับ ลองดูตัวอย่าง ลองดู Firebug console นะครับว่า ค่า value ของ hiddle fields เปลี่ยนหลังจากย้ายหมุดตามที่ต้องการหรือเปล่า

Del.icio.us : ,
Technorati : ,

  • lovetummy
    def new_marker _marker = params[:marker] @marker = Marker.new(_marker) @marker.save! end
    ช่วยอธิบายโค้ดนี้หน่อยครับ เผื่อผมจะไปปรับใช้กับ php
  • tanomsak
    params[:marker] เป็น parameter ที่รับมาจาก browser ครับ

    โดย Marker.new(_marker) @marker.save! ก็คือสร้าง record ใน database ด้วย parameter ที่รับมาจาก browser ครับ
  • poe ค่ะ
    -/\- ก่อนอื่นต้องขอขอบคุณ tanomsak ที่เขียนบทความนี้มีประโยชน์มากเลยค่ะ แต่อยากให้เพิ่มเติมส่วนนึงค่ะ คืออยากให้มันแสดงหมุดก่อนเลื่อนไปตำแหน่งอื่นค่ะ ทำ code ต่อจากคุณ tanomsak มาหลายวันแล้วยังไม่ได้เลย ขอความกรุณาด้วยค่ะ ^-^
  • pasinty
    ช่วยแนะนำ การค้นหาหมุดที่เราสร้างขึ่นเองครับบน google map โดยค้นจาก texbox หรืืิอ listbox ก็ได้ครับ หามา เป็นอาทิตย์แล้วครับ
  • Test Twitter Connect
  • indysoft
    ต้องขอขอบคุณพี่มากเลยครับ ผมกำลังทำโปรเจคเกี่ยวกับ Google Maps API อยู่ด้วยครับ

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

    จะต้องสร้า้งฟังก์ชั่นยังไงค่ะ
    ให้เลือกหมุดได้หลายๆแบบค่ะ
  • chokul
    จากรูปข้างบน icon 3 อันที่อยู่ข้างๆ แผนที่เอามาจากไหนค่ะ

    แล้วต้องทำยังไงถึงจะมีiconแบบนี้ค่ะ
  • tanomsak
    เอามาปุ่มขาวๆมาจาก maps.google.com ครับ แล้วมาวาดรูปข้างในเอง ส่วนวิธีเิอารูปมาใช้เป็นการทำ custom control ครับ

    อยากเขียนถึงเรื่องนี้เหมือนกันครับ แ่่ต่ว่ายุ่งมากๆขอแบบย่อก่อนนะครับ จริงๆแล้ว icon ที่เห็นมันคือ DIV 3 อันที่มี background เป็นรูปภาพ icon +, - , หมุด

    ผมสร้าง DIV ขึ้นมาตั้งค่า CSS ต่างๆให้สวยงาม แล้วก็ bind event onclick ให้กับ DIV แต่ละอันให้ตรงกับ icon เช่น ปุ่ม + ก็มี code ประมาณนี้

    GEvent.addDomListener(zoomInDiv, "click", function() {
    map.zoomIn();
    });

    แล้วก็ add ปุ่มพวกนี้ลงไปใน map โดย

    map.getContainer().appendChild(zoomInDIV);

    ประมาณนี้ครับ งงไหมเอ่ย ลองเล่นดูนะครับ clear งานได้เมื่่อไหร่จะมาเขียนต่อครับ
  • มือใหม่
    แล้วที่ผมทำการดึงค่าจากละติจูดและลองติจูดจากฐานข้อมูลขึ้นมาโชว์บนแผนที่นั้นก็ไม่มีอะไรเลยครับ 55+ ทำแบบง่ายๆเลย เขียนเปิดฐานข้อมูลแล้วก็ echo ค่าต่างๆออกมาเอาครับ จากค่ามาร์กเกอร์ที่มันจะระบุไว้ตายตัวผมก็เอาคำสั่ง<?php echo $row1 ["lat"] ?>ไปแทนที่ซะมันก็จะดึงเอาพิกัดที่มีอยู่ในฐานข้อมูลดึงออกมาให้เราเองครับแค่นี้ครับ
  • มือใหม่
    มีคำถามมาใหม่ครับว่าเราจะลากเส้นจากจุดหนึ่งไปหาอีกจุดหนึ่งยังไงครับโดยเส้นที่วาดลงไปบนแผนที่วิ่งไปตามถนนอะครับเหมือนกับว่ามันหาเส้นทางให้เราอะครับรบกวนด้วยครับหรือว่ามีตัวอย่างก็รบกวนด้วยนะครับ
  • มือใหม่
    ขอบคุณครับแต่ว่ามีเป็นแบบ PHP ไหมครับ
  • tanomsak
    ผมใช้เป็นแต่ RoR อะครับ
    ลองทำความเข้าใจแล้วเปลี่ยนเป็น PHP ดูนะครับ :) ทำได้แล้วอย่าลืม มาเล่าให้ฟังด้วยครับว่าทำไง
  • มือใหม่
    อยากให้เขียนเอาค่า ละติจูดและลองติจูด จากฐานข้อมูลขึ้นมาโชว์บน Google maps ครับ ขอความกรุณาด้วยครับ
  • tanomsak
    ลองดูที่ http://www.tanomsak.com/index.php/2008/12/googl... นะครับ ถ้าสงสัยตรงไหนก็ถามได้เลยนะครับ ผมมือใหม่หัดเขียน blog เหมือนกันครับ
blog comments powered by Disqus