ความเดิมจากตอนที่แล้วของบทความ “การดึงค่าละติจูดและลองจิจูดของสถานที่ด้วย 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