เรียนรู้ Flutter Google Map และ Geolocator และ การคำนวนระยะห่างระหว่าง จุด 2 จุด

0

เมื่อภรรยาอยากได้แอปลงเวลา บนมือถือ  แบบ ระบุตำแหน่ง จะทำไงดีละ ? ก็…ต้องทำนะสิครับ เอาไงละ เริ่มไงดี

อันดับแรก Search Google  ด้วยคำว่า flutter Google Map How to…. ก็มีข้อมูลมาเยอะเลย แต่จะเอาตัวไหนมาดูละ.. ประเด็นที่น่าสนใจ คือ พยายามหา Version ของ flutter ที่ใหม่ที่สุด เพราะ code สำหรับ Version เก่า อาจจะรันไม่ได้เนื่องจากติดปัญหา และต้องขอบคุณ อ.ตั้มสำหรับตำราเอามาอ้างอิงได้ 

เริ่มต้นยังไงดี

1.สร้าง Google Key API เพื่อนำมาใช้งาน เข้าไปที่ Google Maps Platform https://mapsplatform.google.com/   ในที่นี้จะไม่กล่าวถึงนะว่าทำไง เพราะมีคลิปสอนทำอยู่แล้วใน Youtube  “วิธีสร้าง API Key สำหรับ Google Maps (อัพเดทล่าสุด)” โดย Designil

2. เตรียมข้อมูล SHA-1 จาก เครื่องคอมที่ใช้พัฒนาแอป (โดยไปรัน Android Studio แล้ว. เลือก Tab Gradle กดรูปช้างน้อย พิมพ์ต่อท้าย Gradle signingreport แล้วหด  Enter จะเห็นเลข SHA-1

 

 

 

 

 

 

 

นำเลขนี้ไปใช้ตอนสร้าง API-Key สำหรับ ให้ Google Map อนุญาตให้ใช้งาน API   แล้วเราจะได้ API-Key มาใช้งาน 

ซึ่ง อย่านำเลขนี้ไปเปิดเผย เพราะคนอื่นจะนำไปใช้ฟรี แล้วเราเป็นคนเสียเงินค่าบริการ (ปล. ในปี 2022 Google Map บังคับให้ป้อนเลขบัตรเครดิสตอนที่เราสร้างระบบ  Google Map Platform กรณีที่มีการใช้งานถึงข้อกำหนดจ่ายเงิน Google จะเรียกเก็บเงินมาที่เรา)

 

 

 

 

1. เรียกใช้งาน package  google_map_flutter และ geolocator โดยเพิ่มลงใน ไฟล์ pubspec.yaml  

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  google_maps_flutter: ^2.2.1
  geolocator: ^9.0.2
และแก้ไขไฟล์ android->app->build.gradle
โดยเพิ่มต่อท้ายไฟล์   ตามนี้
android {
    compileSdkVersion 33
    defaultConfig {
        minSdkVersion 20
    }
}

2.ระบบ Android  แก้ไขไฟล์   android->app->src->main->AndroidManifest.xml

นำเลข API Key มาใช้ใน App ของเรา โดยนำไปใวางไว้ในไฟล์

ให้เพิ่ม
    <uses-permission android:name =”android.permission.ACCESS_FINE_LOCATION” />
    <uses-permission android:name =”android.permission.ACCESS_COARSE_LOCATION” />
 

3.ระบบ IOS แก้ไขไฟล์ ios->Runner->AppDelegate.swift

 

เมื่อเตรียมทุกอย่างพร้อมก็เริ่มเขียน Code ได้เลย  โดย Code ตัวอย่างได้ นำเอาวิธีการมาจาก

Youtube เรื่อง “Flutter : การดึง Location และแสดง Google Maps” โดย Phisan Sookkhee เผยแพร่เมื่อ 29 ม.ค.21 (ซึ่งในปีปัจจุบัน การเรียกใช้งานจะมีเรื่อง ความปลอดภัย และ Null Safety ดังนั้น จึงไม่สามารถนำโค๊ตมาใช้ได้ทั้งหมด ซึ่งได้มีการค้นคว้าเพิ่มเติมเพื่อให้ใช้งานกับ Flutter 3) 

การออกแบบหน้าจอ จะเป้นแบบนี้

 

เปิดแอป กดปุ่มวงกลม แล้วเปิดหน้า Map

Source Code 

1.ไฟล์ main.dart

import ‘package:flutter/material.dart’;
import ‘package:googlemap/map.dart’;
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: ‘Flutter Demo’,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: ‘Flutter Google Map’),
    );
  }
}
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              ‘Welcome to Google Map Application’,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.push(
              context, MaterialPageRoute(builder: (context) => MapPage()));
        },
        tooltip: ‘Increment’,
        child: const Icon(Icons.near_me),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
 
2.ไฟล์  map.dart

import ‘dart:math’;
import ‘package:flutter/material.dart’;
import ‘package:geolocator/geolocator.dart’;
import ‘package:google_maps_flutter/google_maps_flutter.dart’;
import ‘dart:async’;
class MapPage extends StatefulWidget {
  const MapPage({super.key});
  @override
  State<MapPage> createState() => _MapPageState();
}
class _MapPageState extends State<MapPage> {
  // กำหนดตัวแปรสำหรับใช้งาน
  Position? userLocation;
  bool? serviceEnabled;
  LocationPermission? permission;
  static const double _defaultLat = 15.12030;
  static const double _defaultLng = 104.90555;
  static const CameraPosition _defaultLocation =
  CameraPosition(target: LatLng(_defaultLat, _defaultLng), zoom: 15);
  double distance = 0;
  GoogleMapController? mapController;
  void _onMapCreate(GoogleMapController controller) {
    mapController = controller;
  }
//สร้าง Mark ในแผนที่สำหรับ ที่ตั้งสำนักงาน
  List<Marker> _marker = [];
  final List<Marker> _list = const [
    Marker(
        markerId: MarkerId(‘defaultLocation’),
        position: LatLng(_defaultLat, _defaultLng),
        icon: BitmapDescriptor.defaultMarker,
        infoWindow: InfoWindow(title: ‘UBU Office’, snippet: ‘5 Star Rating’))
  ];
// ดึงข้อมูล GPS จากอุปกรณ์
  Future<Position?> _getLocation() async {
    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled!) {
      return Future.error(‘Location services are disabled’);
    }
// ตรวจสอบสิทธิ การเข้าถึง GPS
    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        return Future.error(‘Location permissions are denied’);
      }
    }
    if (permission == LocationPermission.deniedForever) {
      return Future.error(
          ‘Location permissions are permanently denied, we cannot request permissions.’);
    }
// ดึงตำแหน่งจากปัจจุบัน GPS
    userLocation = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.bestForNavigation);
    return userLocation;
  }
// จบการดึง GPS
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _marker.addAll(_list);
  }
  double calculateDistance(double lat1, double lng1, double lat2, double lng2) {
    double distance = 0;
    var p = 0.017453292519943295;
    var c = cos;
    var a = 0.5 –
        c((lat2 – lat1) * p) / 2 +
        c(lat1 * p) * c(lat2 * p) * (1 – c((lng2 – lng1) * p)) / 2;
    distance = 12742 * asin(sqrt(a));
    return distance;
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(“Flutter Google Map”),
        ),
        body: FutureBuilder(
          future: _getLocation(),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.hasData) {
              distance = calculateDistance(_defaultLat, _defaultLng,
              userLocation!.latitude, userLocation!.longitude);
              print(‘distance =$distance’);
              return GoogleMap(
                compassEnabled: false,
                mapToolbarEnabled: true,
                tiltGesturesEnabled: false,
                myLocationEnabled: true,
                mapType: MapType.normal,
                onMapCreated: _onMapCreate,
                initialCameraPosition: CameraPosition(
                    target:
                        LatLng(userLocation!.latitude, userLocation!.longitude),
                    zoom: 15),
                markers: Set<Marker>.of(_marker),
              );
            } else {
              return Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[CircularProgressIndicator()],
                ),
              );
            }
          },
        ));
  }
}
 

สิ่งที่ได้จากการทดลองเขียนแอพนี้คือ การทำ Map การ Mark จุดพิกัดเริ่มต้นในการแสดงผล    การตรวจสอบสิทธิ์การเข้าถึง GPS ของอุปกรณ์มือถือ และการคำนวนหาระยะห่างระหว่างจุด 2 จุด  เพื่อจะได้นำไปเขียนแอพอื่นต่อไป   

อ้างอิงเพิ่มเติม

แหล่งศึกษาหาข้อมูลเพิ่มเติมการทำ Marker   Youtube 

“Part – 5 || Flutter Add Multiple Marker On Google Map || Flutter Google Map Tutorials”  โดย The Tech Brothers เป็นภาษาอังกฤษ สำเนียงอินเดีย..ฟังเพลินมาก 555+ (ขำๆ)

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *