ความเดิมจากตอนที่แล้วของบทความ “การดึงค่าละติจูดและลองจิจูดของสถานที่ด้วย Places search box บน Google Maps” เพื่อแก้ปัญหาในการดึงค่าละติจูด-ลองจิจูดจากชื่อสถานที่ที่ผู้ใช้พิมพ์ค้นหาไว้ โดยมีการนำ “Places search box” มาใส่ไว้ในแผนที่ที่เราต้องการแทนนั้น ถือเป็นตัวช่วยให้กับผู้ใช้ในระดับหนึ่ง แต่สำหรับในบทความนี้ ผู้เขียนจะขอต่อยอดความรู้ดังกล่าว โดยได้ศึกษาและนำวิธีการแสดงผลภาพจากข้อมูล Street view มาประยุกต์ใช้ร่วมด้วย เพื่อให้ผู้ใช้สามารถมองเห็นสถานที่จริงที่เลือกได้จากแผนที่ได้ด้วย ซึ่งจะยิ่งช่วยอำนวยความสะดวกให้กับผู้ใช้ ทำให้ผู้ใช้สามารถตรวจสอบได้ว่าสถานที่ดังกล่าวเป็นสถานที่ที่ต้องการจะดึงค่าละติจูด-ลองจิจูดจริงหรือไม่ได้อีกทางหนึ่งนั่นเอง ซึ่งวิธีการบางส่วนจะขอยกยอดมาจากบทความก่อนหน้านี้ เกี่ยวกับเรื่องการดึงค่าละติจูด-ลองจิจูดจากการค้นหาโดยใช้ Places search box และจะขอเพิ่มเติมความสามารถในการแสดงผลภาพ Street View รวมทั้งสามารถคลิกจุดพิกัดใหม่บนแผนที่ เพื่อค้นหาตำแหน่ง สถานที่ตั้ง และรายละเอียด รวมถึงภาพจาก Street View ได้อีกด้วย เพื่อให้การดึงค่าพิกัดใกล้เคียงความจริงมากที่สุด โดยมีวิธีการดังนี้
- ส่วนของสไตล์ชีทในการแสดงผล ขึ้นกับการตกแต่งของผู้พัฒนาแต่ละท่าน
<!—ส่วนของ Style Sheets-> <style> html, body { height: 100%; margin: 0; padding: 0; } #map { width: 100%; height: 400px; } .controls { margin-top: 10px; border: 1px solid transparent; border-radius: 2px 0 0 2px; box-sizing: border-box; -moz-box-sizing: border-box; height: 32px; outline: none; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3); } #searchInput { background-color: #fff; font-family: Roboto; font-size: 15px; font-weight: 300; margin-left: 12px; padding: 0 11px 0 13px; text-overflow: ellipsis; width: 80%; } #searchInput:focus { border-color: #4d90fe; } </style>
- ส่วนของการอ้างอิง libraries เพื่อใช้งาน Google API
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCRbMoDPc_mTv3D3QPqe0Ar84nSvRhA8nk&libraries=places&callback=initMap" async defer></script>
- ส่วนของการประกาศค่าเริ่มต้นและตัวแปร รวมถึงการเรียกใช้งานฟังก์ชั่นเพื่อใช้ในการแสดงผล
- ฟังก์ชั่น initMap() ซึ่งจะเรียกใช้งานตอนเริ่มต้นโหลดหน้าจอขึ้นมา
<script> var panorama; var map; var markers = []; /***** function ในการประกาศค่าเริ่มต้นให้กับแผนที่*****/ function initMap() { /***** ประกาศตำแหน่งพิกัดกึ่งกลางให้กับการแสดงผลแผนที่ ในที่นี้กำหนดเป็นกรุงเทพมหานคร*****/ var center_point = { lat: 13.7563309, lng: 100.50176510000006 }; var sv = new google.maps.StreetViewService(); /***** เป็นส่วนของการแสดงผลภาพจาก Street View *****/ panorama = new google.maps.StreetViewPanorama(document.getElementById('pano')); /***** กำหนดรายละเอียดคุณสมบัติของแผนที่*****/ var map = new google.maps.Map(document.getElementById('map'), { center: {lat: center_point.lat, lng: center_point.lng}, zoom: 13, streetViewControl: false // เป็นส่วนที่ Set เพิ่มเติมจากปกติ }); sv.getPanorama({ location: center_point, radius: 50 }, processSVData); /***** กำหนด event เมื่อมีการคลิกแผนที่*****/ map.addListener('click', function(event) { /***** ล้างข้อมูลการกำหนดจุด เพื่อให้มีการกำหนดจุดพิกัดเพียงจุดเดียว*****/ for (i = 0; i < markers.length; i++) { markers[i].setMap(null); } /***** ดึงค่าข้อมูลจาก Street View ตามพิกัดที่คลิกบนแผนที่ *****/ sv.getPanorama({ location: event.latLng, radius: 50 }, processSVData); var geocoder = new google.maps.Geocoder(); geocoder.geocode({ 'latLng': event.latLng }, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { /***** แสดงผลข้อมูลรายละเอียดสถานที่*****/ if (results[0]) { var place = results[0]; for (var i = 0; i < place.address_components.length; i++) { if (place.address_components[i].types[0] == 'postal_code') { document.getElementById('postal_code').innerHTML = place.address_components[i].long_name; } if (place.address_components[i].types[0] == 'country') { document.getElementById('country').innerHTML = place.address_components[i].long_name; } } document.getElementById('location').innerHTML = results[0].formatted_address; document.getElementById('lat').innerHTML = results[0].geometry.location.lat(); document.getElementById('lon').innerHTML = results[0].geometry.location.lng(); } } }); }); /***** กำหนดตำแหน่งที่ตั้งของ control ที่จะวางในแผนที่*****/ var input = document.getElementById('searchInput'); map.controls[google.maps.ControlPosition.TOP_LEFT].push(input); /***** เพิ่ม Feature ให้กับ textbox ให้สามารถพิมพ์ค้นหาสถานที่ได้*****/ var autocomplete = new google.maps.places.Autocomplete(input); autocomplete.bindTo('bounds', map); var infowindow = new google.maps.InfoWindow(); /***** กำหนดคุณสมบัติให้กับตัวพิกัดจุดหรือ marker *****/ var marker = new google.maps.Marker({ map: map, anchorPoint: new google.maps.Point(0, -29) }); markers.push(marker); //เก็บค่าการกำหนดจุดพิกัดไว้ในตัวแปร markers เพื่อใช้ล้างข้อมูลการกำหนดจุดได้ /***** ทำงานกับ event place_changed หรือเมื่อมีการเปลี่ยนแปลงค่าสถานที่ที่ค้นหา*****/ autocomplete.addListener('place_changed', function() { infowindow.close(); marker.setVisible(false); var place = autocomplete.getPlace(); if (!place.geometry) { window.alert("ไม่ค้นพบพิกัดจากสถานที่ดังกล่าว"); return; } /***** แสดงผลบนแผนที่เมื่อพบข้อมูลที่ต้องการค้นหา *****/ if (place.geometry.viewport) { map.fitBounds(place.geometry.viewport); } else { map.setCenter(place.geometry.location); sv.getPanorama({ location: place.geometry.location, radius: 50 }, processSVData); map.setZoom(17); } marker.setIcon(({ url: place.icon, size: new google.maps.Size(71, 71), origin: new google.maps.Point(0, 0), anchor: new google.maps.Point(17, 34), scaledSize: new google.maps.Size(35, 35) })); marker.setPosition(place.geometry.location); marker.setVisible(true); /***** แสดงรายละเอียดผลลัพธ์การค้นหา *****/ var address = ''; if (place.address_components) { address = [ (place.address_components[0] && place.address_components[0].short_name || ''), (place.address_components[1] && place.address_components[1].short_name || ''), (place.address_components[2] && place.address_components[2].short_name || '') ].join(' '); } /***** แสดงรายละเอียดผลลัพธ์การค้นหาเป็น popup โดยมีชื่อและสถานที่ดังกล่าว *****/ infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address); infowindow.open(map, marker); /***** แสดงรายละเอียดผลลัพธ์การค้นหา ซึ่งประกอบด้วย ที่อยู่ รหัสไปรษณีย์ ประเทศ ละติจูดและลองจิจูด *****/ for (var i = 0; i < place.address_components.length; i++) { if(place.address_components[i].types[0] == 'postal_code'){ document.getElementById('postal_code').innerHTML = place.address_components[i].long_name; } if(place.address_components[i].types[0] == 'country'){ document.getElementById('country').innerHTML = place.address_components[i].long_name; } } document.getElementById('location').innerHTML = place.formatted_address; document.getElementById('lat').innerHTML = place.geometry.location.lat(); document.getElementById('lon').innerHTML = place.geometry.location.lng(); }); } </script>
- ฟังก์ชั่น processSVData() เป็นฟังก์ชั่นที่ใช้ในการนำค่าของ Street view มาแสดงผล
<script> function processSVData(data, status) { if (status === 'OK') { marker = new google.maps.Marker({ position: data.location.latLng, map: map, title: data.location.description }); markers.push(marker); panorama.setPano(data.location.pano); panorama.setPov({ heading: 270, pitch: 0 }); panorama.setVisible(true); marker.addListener('click', function() { var markerPanoID = data.location.pano; // Set the Pano to use the passed panoID. panorama.setPano(markerPanoID); panorama.setPov({ heading: 270, pitch: 0 }); panorama.setVisible(true); }); } else { console.error('ไม่พบข้อมูล Street view ตามสถานที่ดังกล่าว'); } } </script>
- ส่วนของการแสดงผล (ใน tag body)
<body> <!--ส่วนของการแสดงรายละเอียดผลลัพธ์ที่ได้-> <table style="width: 100%"> <tr> <td> <!--ส่วนของ Element ที่ใช้ในการแสดงผล-> <input id="searchInput" class="controls" type="text" placeholder="Enter a location"> <div id="map" style="width: 60%;height:360px;float:left"></div> <div id="pano" style="width: 40%;height:360px; float:left"> </div><br /> </td> </tr> <tr> <td> <div id="Div1" style="width: 100%;" > <ul id="geoData"> <li>ที่อยู่: <span id="location"></span></li> <li>รหัสไปรษณีย์ : <span id="postal_code"></span></li> <li>ประเทศ: <span id="country"></span></li> <li>ละติจูด: <span id="lat"></span></li> <li>ลองจิจูด: <span id="lon"></span></li> </ul> </div> </td> </tr> </table> <!--ส่วนของการประกาศค่าเริ่มต้นและตัวแปร รวมถึงการเรียกใช้งานฟังก์ชั่นเพื่อใช้ในการแสดงผลที่กล่าวไว้ก่อนหน้านี้-> <script> /***** function ในการประกาศค่าเริ่มต้นให้กับแผนที่ และอื่นๆตามที่กล่าวไว้แล้วข้างต้น*****/ </script> <!--สิ้นสุดส่วนของการประกาศค่าเริ่มต้นและตัวแปร รวมถึงการเรียกใช้งานฟังก์ชั่นเพื่อใช้ในการแสดงผล-> </body>
ผลลัพธ์ที่ได้
1. เมื่อเปิดหน้าจอขึ้นมา จะแสดงพิกัดที่จังหวัดกรุงเทพมหานครเป็นค่าตั้งต้น และฝั่งขวาเป็นภาพที่ดึงข้อมูลมาได้จากพิกัดดังกล่าวจากข้อมูล Street Views
2. พิมพ์ค้นหาชื่อสถานที่ และเลือกสถานที่ที่ต้องการ
3. เมื่อเลือกสถานที่เรียบร้อย จะมีการกำหนดพิกัดจุดตามชื่อสถานที่ที่เลือกไว้ และแสดงผลภาพจาก Street View รวมทั้งแสดงรายละเอียดในส่วนล่างของหน้าจอ ดังภาพ
นอกจากการค้นหาพิกัดและข้อมูลภาพจาก Street View โดยใช้วิธีการพิมพ์ค้นหาแล้วนั้น ผู้ใช้ยังสามารถค้นหาพิกัดใหม่ได้จากการคลิกบนแผนที่ได้อีกด้วย ซึ่งจะแสดงผลลัพธ์ได้เช่นกัน ดังภาพ
ผู้เขียนหวังเป็นอย่างยิ่งว่า บทความนี้จะช่วยเพิ่มประสิทธิภาพและเป็นอีกหนึ่งทางเลือกให้กับผู้พัฒนาได้หยิบยกวิธีการดึงค่าละติจูด-ลองจิจูดและการแสดงผลข้อมูลไปประยุกต์ใช้กับงานของแต่ละท่าน และอาจถือเป็นการเพิ่มลูกเล่นให้กับเว็บไซต์ของท่านให้มีความสามารถที่หลากหลายมากขึ้นเกี่ยวกับการใช้งานร่วมกับแผนที่ Google Maps หากผู้อ่านท่านใดมีข้อเสนอแนะหรือแนะนำวิธีเพิ่มเติมเกี่ยวกับเรื่องดังกล่าว ผู้เขียนยินดีเป็นอย่างยิ่งที่จะรับฟังและร่วมแบ่งปันความรู้ร่วมกันค่ะ หากบทความนี้มีส่วนผิดพลาดประการใด ผู้เขียนขออภัยไว้ ณ ที่นี้ด้วยค่ะ ^^
แหล่งข้อมูลอ้างอิง :
https://www.tutorialspoint.com/google_maps/google_maps_symbols.htm
http://www.codexworld.com/autocomplete-places-search-box-google-maps-javascript-api/
https://developers.google.com/maps/documentation/javascript/examples/streetview-service