การดึงค่าละติจูดและลองจิจูดของสถานที่ด้วย Places search box บน Google Maps

       ก่อนจะพูดถึงเนื้อหาของบทความนี้ ผู้เขียนขอท้าวความไปถึงบทความก่อนหน้าที่เป็นเนื้อหาที่เกี่ยวข้องกับการดึงค่าละติจูด-ลองจิจูดของสถานที่ เพื่อมากำหนดจุดพิกัดบนแผนที่ หรือที่เรารู้จักกันดีในนามของ Google maps (ซึ่งสามารถหาอ่านได้จากลิงค์ ทำอย่างไรให้สามารถกำหนดจุดพิกัดบนแผนที่ Google map แบบจุดเดียวและหลายจุดจากฐานข้อมูลได้ด้วย ASP.NET C# (ภาคต่อ) และหากท่านต้องการศึกษาเกี่ยวกับวิธีการกำหนดพิกัดบนแผนที่เพิ่มเติมสามารถหาอ่านได้จากลิงค์ ทำอย่างไรให้สามารถกำหนดจุดพิกัดบนแผนที่ Google map แบบจุดเดียวและหลายจุดจากฐานข้อมูลได้ด้วย ASP.NET C# เช่นกัน) แต่หลังจากที่ผู้เขียนได้นำไปทดลองใช้งานการดึงค่าพิกัดที่ค้นหา พบว่าเกิดปัญหาในการค้นหาพิกัดของสถานที่ในบางกรณี คือ ไม่สามารถค้นหาพิกัดของบางสถานที่ที่ต้องการได้ และในบางครั้งผู้ใช้เลือกสถานที่ที่จะดึงค่าพิกัดมาใช้งานผิด เนื่องจากชื่อสถานที่อาจคล้ายกัน แต่ตั้งอยู่กันคนละประเทศ หรือทวีป โดยผู้ใช้อาจไม่เห็นภาพว่าสถานที่ดังกล่าวอยู่ส่วนใดของแผนที่ จึงทำให้พิกัดที่ได้มีความผิดพลาดหรือคลาดเคลื่อนได้ ผู้เขียนจึงได้ลองศึกษาเพิ่มเติม และปรับเปลี่ยนวิธีการ เพื่อให้การดึงค่าพิกัดเป็นไปได้ง่าย และอำนวยความสะดวกต่อผู้ใช้งานมากขึ้น รวมทั้งเพิ่มช่องทางในการค้นหาข้อมูลพิกัดได้มากขึ้นและมีความถูกต้องแม่นยำขึ้น

ตัวอย่างภาพการทำงานของการดึงค่าพิกัดที่ผู้เขียนเคยเขียนไว้ก่อนหน้านี้

แบบที่ 1 การเรียกใช้เซอร์วิสของ Google Geocoding API โดยการส่งพารามิเตอร์เป็นที่อยู่ของสถานที่ดังกล่าว

   

แบบที่ 2 แบบใช้ place Autocomplete ซึ่งเป็น feature ของ Google Places API ที่จะช่วยในการค้นหาที่อยู่จากชื่อสถานที่ได้และประยุกต์เพิ่มเติมเพื่อดึงค่ามาแสดงเมื่อมีการเลือกรายการสถานที่นั้นๆ

     

       จากปัญหาดังกล่าวข้างต้น ผู้เขียนได้ปรับเปลี่ยนวิธีการในการดึงค่าละติจูด-ลองจิจูดจากชื่อสถานที่ที่ผู้ใช้พิมพ์ค้นหาไว้ โดยมีการนำ “Places search box” มาใส่ไว้ในแผนที่ที่เราต้องการแทน เพื่อให้ผู้ใช้สามารถมองเห็นสถานที่จริงที่เลือกได้จากแผนที่ ซึ่งสามารถตรวจสอบได้ว่าสถานที่ดังกล่าวเป็นสถานที่ที่ต้องการจะดึงค่าละติจูด-ลองจิจูดจริงหรือไม่อีกทางหนึ่งนั่นเอง โดยมีวิธีการดังนี้

  • ส่วนของสไตล์ชีทในการแสดงผล ขึ้นกับการตกแต่งของผู้พัฒนาแต่ละท่าน
<!—ส่วนของ 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: 50%;
}
#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>
  • ส่วนของการประกาศค่าเริ่มต้นและตัวแปร รวมถึงการเรียกใช้งานฟังก์ชั่นเพื่อใช้ในการแสดงผล
<script>
/***** function ในการประกาศค่าเริ่มต้นให้กับแผนที่*****/
 function initMap() {
 
 /***** กำหนดรายละเอียดคุณสมบัติของแผนที่*****/
 var map = new google.maps.Map(document.getElementById('map'), {
 center: {lat: -33.8688, lng: 151.2195},
 zoom: 13
 });

 /***** กำหนดตำแหน่งที่ตั้งของ 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)
 });

 /***** ทำงานกับ 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);
 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>
  • ส่วนของการแสดงผล (ใน tag body)
<body>
<!--ส่วนของ Element ที่ใช้ในการแสดงผล-->
<input id="searchInput" class="controls" type="text" placeholder="Enter a location">
<div id="map"></div>
<!--ส่วนของการแสดงรายละเอียดผลลัพธ์ที่ได้-->
<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>

<!--ส่วนของการประกาศค่าเริ่มต้นและตัวแปร รวมถึงการเรียกใช้งานฟังก์ชั่นเพื่อใช้ในการแสดงผลที่กล่าวไว้ก่อนหน้านี้-->
                                                            
<script>
/***** function ในการประกาศค่าเริ่มต้นให้กับแผนที่ และอื่นๆตามที่กล่าวไว้แล้วข้างต้น*****/
</script>
<!--สิ้นสุดส่วนของการประกาศค่าเริ่มต้นและตัวแปร รวมถึงการเรียกใช้งานฟังก์ชั่นเพื่อใช้ในการแสดงผล->
 </body>

ผลลัพธ์ที่ได้

1. เมื่อพิมพ์ชื่อสถานที่ เช่น มหาวิทยาลัยสงขลานครินทร์ จะมีรายการชื่อสถานที่ให้ผู้ใช้เลือก

2. เมื่อเลือกชื่อสถานที่ที่ต้องการ เช่น มหาวิทยาลัยสงขลานครินทร์ จะมีการแสดงรายละเอียดของสถานที่ดังกล่าวดังภาพตามหมายเลข 1,2 และ 3 ตามลำดับ

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

แหล่งข้อมูลอ้างอิง :

https://www.tutorialspoint.com/google_maps/google_maps_symbols.htm

http://www.codexworld.com/autocomplete-places-search-box-google-maps-javascript-api/

Leave a Reply