PHP Ionic Angularjs Phonegap AJAX Javascript CSS MySQL jQuery Forum

แนวทางเพิ่มเติม google map ใน app ionic material

01 November 2016 By


สำหรับเนื้อหานี้ จะขยายหรือแสดงตัวอย่างการใช้งาน การปรับแต่ง
google map ใน app ionic ของบทความก่อนหน้า จริงๆ แล้วสามารถ
ประยุกต์จากบทความเกี่ยวกับ google map ที่ใช้หน้าเว็บปกติทั่วไป
ดูได้ที่  
http://www.ninenik.com/google_search.php?tags=google%20map
 
อย่างไรก็ตาม เพื่อให้สามารถเข้าใจ  และต่อยอดได้ง่ายขึ้นจึงขอนำตัวอย่าง
โค้ดมาปรับให้ใช้งานใน app ionic material เป็นแนวทาง  โดยเนื้อหา จะเน้นไป
ในส่วนของโค้ดเกี่ยวกับ google map เท่านั้น
 
บทความนี้ต่อเนื่องจากบทความก่อนหน้า
แสดงตำแหน่งปัจจุบัน บนแผนที่ google map ใน app ionic material 
http://www.ninenik.com/content.php?arti_id=731 via @ninenik
 


แนวทางการปรับแต่ง google map

 

การให้แผนที่แสดงเป็นภาษาไทย 
 

ในไฟล์ index.html ส่วนของการใช้ library google map ให้เพิ่มค่านี้เข้าไป
 
&language=th&region=TH
 
จะได้เป็น
 
<script src="https://maps.googleapis.com/maps/api/js?key=your_key&language=th&region=TH"  
            async defer></script>  
 
 
ต่อไป มาดู MapCtrl controller ในไฟล์ controllers.js ที่ปรับแต่งแล้ว ทั้งหมด
 
.controller('MapCtrl', function(
    $scope, $stateParams, $timeout, ionicMaterialInk, ionicMaterialMotion
    ,$ionicPlatform,$cordovaGeolocation, $cordovaSpinnerDialog) {
    $scope.$parent.showHeader();
    $scope.$parent.clearFabs();
    $scope.$parent.setHeaderFab(false);
    $scope.$parent.hasShadow();

    $timeout(function() {
        $scope.isExpanded = false;
        $scope.$parent.setExpanded(false);
    }, 300);

    // ฟังก์ชั่นหาตำแหน่งปัจจุบันในแผนที่ google map
    $scope.getMapLocation = function() {
        $ionicPlatform.ready(function() { // เตรียมก่อนเรียกใช้ plugin
            // กำหนดการตั้งค่าการระบุตำแหน่ง
            var posOptions = {timeout: 10000, enableHighAccuracy: false};
            // plugin เริ่มทำงานหาตำแหน่งปัจจุบันด้วยคำสั่ง getCurrentPosition
            $cordovaGeolocation
                .getCurrentPosition(posOptions)
                .then(function (position) { // พบตำแหน่ง
                    // เก็บค่าตำแหน่งในตัวไป
                    var lat  = position.coords.latitude;
                    var long = position.coords.longitude;
                    // เรียกฟังก์ชั่นสร้างแผนที่ โดยส่งค่าตำแหน่งไป
                    $scope.getMap(lat, long);
                }, function(err) { // ถ้าหาตำแหน่งไม่ได้ หรือไม่พบ
                    $cordovaSpinnerDialog.hide(); // ซ่อน loading
                    console.log(err);
                    // เช็คว่ามี plugin Native settings หรือไม่
                    if(typeof cordova.plugins.settings.openSetting != undefined){
                        // ถ้ามีก็เรียกใช้ ให้เปิดหน้าตั้งค่าที่ต้องการ
                        cordova.plugins.settings.open(function(){
                                 // ถ้าเปิดหน้าตั้งค่าได้ ให้เปิด หน้าตั้งค่า location
                                cordova.plugins.settings.openSetting(
                                "location_source",
                                function(){
                                    // ถ้าเปิดหน้า locaton แล้วและผู้ใช้ เปิด gps แล้วกลับมาที่ app
                                    // แสดง loading อีกครั้ง และเรียกฟังก์ชั่นหาตำแหน่งใหม่อีกครั้ง
                                    $cordovaSpinnerDialog.show(null,"รอสักครู่..");
                                    $scope.getMapLocation();
                                    console.log("opened location settings")
                                },
                                function(){// เปิดหน้าตั้งคา location ไม่ได้
                                    console.log("failed to open");
                                });
                                console.log("opened settings")
                            },
                            function(){ // ถ้าเปิดหน้าตั้งค่าไม่ได้
                                console.log("failed to open settings")
                            });
                    }
                });
        });
    };

    // ฟังก์ชั่นสร้างแผนที่ ตัว markder และ infowindow รับค่าตำแหน่งที่ได้มา
    $scope.getMap = function(latitude, longitude) {

        // กำหนดให้มีการเรียกใช้ฟังก์ชั่นแสดงชื่อจากตำแหน่ง ใน google map
        var geocoder = new google.maps.Geocoder();

        // กำหนดตำแหน่งของแผนที่ จากค่าที่ส่งมา
        var myLatLng = new google.maps.LatLng(latitude, longitude);

        // กำนหนด option การแสดงแผนที่
        var mapOption = {
            center:myLatLng,
            zoom:13,
            mapTypeControl:false, // ไม่แสดงปุ่มเลือกรูปแบบแผนที่
            zoomControl:false, // ไม่แสดงปุ่ม zoom
            streetViewControl:true,// แสดงปุ่มเลือกมุมมอง streetview
            scaleControl:false, // ไม่แสดงรายละเอียด scale
            mapTypeId:google.maps.MapTypeId.ROADMAP
        };

        // แสดงแผนที่ในตำแหน่ง div id=map
        var map = new google.maps.Map(document.getElementById("map"),mapOption);

        // สร้างตัวแปรสำหรับ marker เพือแสดงตำแหน่งในแผนที่
        var marker = new google.maps.Marker({
            draggable:true,// ให้สามารถลากตัว marker ได้
            position: myLatLng
        });

        // แสดง markder ในแผนที่
        marker.setMap(map);

        // สร้างตัวแปร infowindow เพื่อแสดงข้อความเมื่อคลิกที่ marker
        var infowindow = new google.maps.InfoWindow({
            disableAutoPan : true,
            content: '' // ข้อความใน infowindow เป็นว่างไปก่อน
        });

        // กำหนด event ให้กับ markder ถ้า คลิก marker ให้เปิด infowindow
        google.maps.event.addListener(marker, "click", function(){
            var my_Point = marker.getPosition();// หาตำแหน่ง marker ที่คลิก
            getGeocode(my_Point); // เรียกฟังก์ชั่นหาชื่อตำแหน่ง
        });

        // กำหนด event ให้กับ แผนที่ ถ้าแผนที่ ไม่ได้ทำอะไรแล้ว คล้ายๆ แผนที่โหลดเสร็จแล้ว
        google.maps.event.addListenerOnce(map, 'idle', function(){
            $cordovaSpinnerDialog.hide(); // ซ่อน loading
        });

        // กำหนด event ให้กับตัว map แผนท่ เมื่อมีการเลื่อนผนที่ และจุดกลากเปลี่ยน
        google.maps.event.addListener(map,'center_changed', function() {
            infowindow.close(); // ปิด infowindow
            marker.setPosition(map.getCenter()); //เปลี่ยนจำแหน่ง marker ไปตรงกลาง
            var my_Point = map.getCenter(); // หาค่าตำแหน่งตรงกลาง
            getGeocode(my_Point); // เรียกฟังก์ชั่นหาชื่อตำแหน่ง
        });

        // กำหนด event ให้กับตัว marker เมื่อเริ่มลากตัว marker ให้ทำงานอะไร
        google.maps.event.addListener(marker, 'drag', function() {
            infowindow.close(); // ปิด infowindow ไปก่อน
        });

        // กำหนด event ให้กับตัว marker เมื่อสิ้นสุดการลากตัว marker ให้ทำงานอะไร
        google.maps.event.addListener(marker, 'dragend', function() {
            var my_Point = marker.getPosition();  // หาตำแหน่งของตัว marker เมื่อกดลากแล้วปล่อย
            map.panTo(my_Point);  // ให้แผนที่แสดงไปที่ตัว marker
            getGeocode(my_Point); // เรียกฟังก์ชั่นหาชื่อตำแหน่ง
        });

        // ฟังก์ชั่นสำหรับ หาชื่อตำแหน่งในแผนที่ แล้วแสดงใน infowindow
        var getGeocode = function(my_Point){
            var contentResult = null;
            infowindow.setContent(contentResult); // กำหนดให้เป็นค่าว่างก่อน
            // นำตำแหน่ง lat,lng จากตัวแปร my_Point ที่ส่งเข้ามาไป
            geocoder.geocode({'latLng': my_Point}, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) { // ถ้าพบชื่อตำแหน่ง
                    if (results[1]) {
                         // จัดรูปแบบข้อความที่จะแสดง แสดงชื่อและตำแหน่ง lat,lng
                        contentResult = '<div style="text-align: center;">'
                            +results[1].formatted_address+
                            '<br />'+my_Point.lat()+','+my_Point.lng()+
                            '</div>';
                    }
                } else {
                    // ถ้าไม่พบชื่อจากตำแหน่ง
                    contentResult = 'Geocoder failed due to: ' + status;
                }
                if(contentResult){ // กำหนดข้อความใน infowindow
                    infowindow.setContent(contentResult);
                    infowindow.open(map,marker); // แสดง infowindow
                }
            });
        };
        // กำหนดค่าตัวแปร map เผื่อได้เรียกใช้งาน
        $scope.map = map;

    };


    // สร้างถูกเรียกใช้เมื่อเข้ามาหน้า map
    $scope.init = function(){
        $ionicPlatform.ready(function() { // กำหนดก่อนเรียกใช้ plugin
            $cordovaSpinnerDialog.show(null,"รอสักครู่.."); // แสดง loading
            $scope.getMapLocation(); // เรียกฟังก์ชั่นหาตำแหน่งในแผนที่ให้ทำงาน
        });
    };

   ionicMaterialMotion.fadeSlideInRight();

   ionicMaterialInk.displayEffect();

})
 
 

ถ้าต้องการหาชื่อสถานที่จากตำแหน่ง lat,lng ต้องเรียกใช้ Geocoder() ตามบรรทัด

 
        // กำหนดให้มีการเรียกใช้ฟังก์ชั่นแสดงชื่อจากตำแหน่ง ใน google map
        var geocoder = new google.maps.Geocoder();

การกำหนดให้แสดงหรือไม่แสดงปุ่มควบคุมต่างๆ ในแผนที่ ให้ดูในโค้ดส่วนนี้

        // กำนหนด option การแสดงแผนที่
        var mapOption = {
            center:myLatLng,
            zoom:13,
            mapTypeControl:false, // ไม่แสดงปุ่มเลือกรูปแบบแผนที่
            zoomControl:false, // ไม่แสดงปุ่ม zoom
            streetViewControl:true,// แสดงปุ่มเลือกมุมมอง streetview
            scaleControl:false, // ไม่แสดงรายละเอียด scale
            mapTypeId:google.maps.MapTypeId.ROADMAP
        };
 
    รายละเอียดเพิ่มเติมสามารถดูได้ที่
    https://developers.google.com/maps/documentation/javascript/controls
 

การกำหนดให้สามารถลากเปลี่ยนตำแหน่ง marker ได้ให้กำหนด option ใน marker

draggable:true, ดังตัวอย่างโค้ดด้านล่าง
 
        // สร้างตัวแปรสำหรับ marker เพือแสดงตำแหน่งในแผนที่
        var marker = new google.maps.Marker({
            draggable:true,// ให้สามารถลากตัว marker ได้
            position: myLatLng
        });
 

ป้องกันไม่ไห้ตำแหน่ง marker เคลื่อนเมื่อเปิด infowindow ให้กำหนด option ใน infowindow

disableAutoPan : true, ดังตัวอย่างโค้ดด้านล่าง
 
        // สร้างตัวแปร infowindow เพื่อแสดงข้อความเมื่อคลิกที่ marker
        var infowindow = new google.maps.InfoWindow({
            disableAutoPan : true,
            content: '' // ข้อความใน infowindow เป็นว่างไปก่อน
        });
 
 

ต้องการทำงานคำสั่งเมื่อคลิกที่ marker ให้ตรวจจับด้วย event click บน marker 

 
        // กำหนด event ให้กับ markder ถ้า คลิก marker ให้เปิด infowindow
        google.maps.event.addListener(marker, "click", function(){
            var my_Point = marker.getPosition();// หาตำแหน่ง marker ที่คลิก
            getGeocode(my_Point); // เรียกฟังก์ชั่นหาชื่อตำแหน่ง
        });
 

ต้องการทำงานคำสั่งเมื่อเลื่อน map ให้ตรวจจับด้วย event center_changed ของ map

 
        // กำหนด event ให้กับตัว map แผนท่ เมื่อมีการเลื่อนผนที่ และจุดกลางเปลี่ยน
        google.maps.event.addListener(map,'center_changed', function() {
            infowindow.close(); // ปิด infowindow
            marker.setPosition(map.getCenter()); //เปลี่ยนจำแหน่ง marker ไปตรงกลาง
            var my_Point = map.getCenter(); // หาค่าตำแหน่งตรงกลาง
            getGeocode(my_Point); // เรียกฟังก์ชั่นหาชื่อตำแหน่ง
        });
 
 

ต้องการทำงานคำสั่งเมื่อเริ่มคลิกลาก marker ให้ตรวจจับด้วย event drag ใน marker

 
        // กำหนด event ให้กับตัว marker เมื่อเริ่มลากตัว marker ให้ทำงานอะไร
        google.maps.event.addListener(marker, 'drag', function() {
            infowindow.close(); // ปิด infowindow ไปก่อน
        });
 
 

ต้องการทำงานคำสั่งเมื่อสิ้นสุดการลาก marker ให้ตรวจจับด้วย event dragend ใน marker

 
        // กำหนด event ให้กับตัว marker เมื่อสิ้นสุดการลากตัว marker ให้ทำงานอะไร
        google.maps.event.addListener(marker, 'dragend', function() {
            var my_Point = marker.getPosition();  // หาตำแหน่งของตัว marker เมื่อกดลากแล้วปล่อย
            map.panTo(my_Point);  // ให้แผนที่แสดงไปที่ตัว marker
            getGeocode(my_Point); // เรียกฟังก์ชั่นหาชื่อตำแหน่ง
        });
 
    รายละเอียดเพิ่มเติมสามารถดูได้ที่
    https://developers.google.com/maps/documentation/javascript/events
 
 

ถ้าต้องการทำงานคำสั่งเดิมซ้ำๆ ให้สร้างเป็นฟังก์ชั่น และเรียกใข้งาน 
 

ตัวอย่าง การสร้างฟังก์ชัน getGeocode เพื่อส่งค่าตำแหน่งไปหาชื่อสถานที่
ใน method geocode() ของ google map 
 
        // ฟังก์ชั่นสำหรับ หาชื่อตำแหน่งในแผนที่ แล้วแสดงใน infowindow
        var getGeocode = function(my_Point){
            var contentResult = null;
            infowindow.setContent(contentResult); // กำหนดให้เป็นค่าว่างก่อน
            // นำตำแหน่ง lat,lng จากตัวแปร my_Point ที่ส่งเข้ามาไป
            geocoder.geocode({'latLng': my_Point}, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) { // ถ้าพบชื่อตำแหน่ง
                    if (results[1]) {
                         // จัดรูปแบบข้อความที่จะแสดง แสดงชื่อและตำแหน่ง lat,lng
                        contentResult = '<div style="text-align: center;">'
                            +results[1].formatted_address+
                            '<br />'+my_Point.lat()+','+my_Point.lng()+
                            '</div>';
                    }
                } else {
                    // ถ้าไม่พบชื่อจากตำแหน่ง
                    contentResult = 'Geocoder failed due to: ' + status;
                }
                if(contentResult){ // กำหนดข้อความใน infowindow
                    infowindow.setContent(contentResult);
                    infowindow.open(map,marker); // แสดง infowindow
                }
            });
        };

 
ทั้งหมดที่อธิบายมาเพื่อให้เห็นภาพ นอกจากเราสามารถนำ google map มาแสดงใน app 
ionic material แล้ว เรายังสามารถที่จะเพิ่มความสามารถต่างๆ เข้าไปได้ตามต้องการ
แต่ถ้าเราไม่รู้หรือนึกภาพไม่ออก เราจะไม่สามารถประยุกต์ต่อยอดได้ ดังนั้นการอธิบาย
ข้างต้นเพื่อเป็นการเปิดมุมมอง เพื่อหาข้อมูลเพิ่มเติม และนำมาปรับใช้ ตัวอย่างเช่น
สมมติเราต้องการ ให้แสดงแผนที่ และผู้ใช้สามารถลากหาตำแหน่งเริ่ม และตำแหน่งปลายทาง
แล้วให้ทำการสร้างแส้นทาง แบบนี้เป็นต้น
 
อย่างไรก็ตามหากมีเนื้อหา หรือส่วนขยายเพิ่มเติม ที่เห็นว่ามีประโยชน์ 
จะนำมาอธิบายเพิ่มเติมต่อไป
 
โค้ดข้างต้นสามารถนำไปใช้ในตัวอย่าง และ build เป็น apk ไฟล์ทดสอบ รันผ่านมือถือ android ได้
 

Tags:: ionicframework ionicmaterial

เนื้อหาพิเศษ เฉพาะสำหรับสมาชิก

กรุณาล็อกอิน และลงชื่อติดตาม


สมัครสมาชิกได้ที่        ล็อกอินได้ที่   





URL สำหรับอ้างอิง