สวัสดีครับนักพัฒนาทุกท่าน ก่อนหน้านี้เราเคยได้พูดถึงการพัฒนา Web App แผนที่ออนไลน์ จาก Framework ต่าง ๆ อย่าง Vue.js และ React กันไปบ้างแล้ว แต่บทความนี้เราจะมาแนะนำขั้นตอนการพัฒนาแผนที่ออนไลน์ Longdo Map ด้วย Flutter framework กันครับ
เริ่มติดตั้ง (Setup)
ขั้นตอนแรกคือการเพิ่ม Longdo Map Flutter plugin ที่เป็น dependency ลงในไฟล์ pubspec.yaml จาก longdo_maps_flutter
dependencies:
...
longdo_maps_flutter: ^1.0.0
หลักจากใส่เรียบร้อยแล้ว ให้ใช้คำสั่ง flutter pub get
ในขั้นตอนต่อไป ให้นักพัฒนาทำสมัครบัญชี Longdo.com เพื่อทำการขอ Longdo Map API Key ตามตัวอย่างนี้ได้เลยครับ วิธีขอ API Key
หลังจากนั้นท่านจะได้รับคีย์ยาวๆ เช่น 10118100f0c602384xxxxxxxxxxxxxxx
สำหรับ iOS
นักพัฒนาจำเป็นต้องตั้งค่าในไฟล์ Info.plist (ios/Runner/Infro.plist) ก่อน
<key>io.flutter.embedded_views_preview</key>
<true/>
<key>NSLocationAlwaysUsageDescription</key>
<key>NSLocationWhenInUseUsageDescription</key>
สำหรับ Android
ในไฟล์ build.gradle (android/app/src/build.gradle) เราแนะนำให้ตั้งค่า minSdkVersion ตั้งแต่ 17 ขึ้นไป ตามตัวอย่างด้านล่างนี้
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.longdo_map_flutter"
minSdkVersion 17
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
การใช้งาน Longdo Map
ทำการ import package longdo map และเพิ่ม Widget ในไฟล์ main.dart ตามตัวอย่างด้านล่างนี้ได้เลย (อย่าลืมเปลี่ยน API_KEY ที่ใช้ด้วยนะครับ)
import 'package:flutter/material.dart';
import 'package:longdo_maps_flutter/longdo_maps_flutter.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
State createState() => _MyAppState();
}
class AppTheme {
static final DATA = ThemeData(
primaryColor: Colors.white,
accentColor: Colors.black87,
scaffoldBackgroundColor: Colors.white);
}
class _MyAppState extends State<MyApp> implements MapInterface {
// STEP 1 : Get a Key API
// https://map.longdo.com/docs/javascript/getting-started
static const API_KEY = "10118100f0c602384xxxxxxxxxxxxxxx";
MapController map;
List<Marker> markers = [];
final global = GlobalKey<ScaffoldState>();
bool thaiChote = false;
bool traffic = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: AppTheme.DATA,
home: Scaffold(
key: global,
body: Builder(builder: (context) {
return Column(children: <Widget>[
Expanded(
child: LongdoMapView(
apiKey: API_KEY, listener: this, markers: markers),
flex: 1),
Row(children: <Widget>[
Expanded(
child: IconButton(
icon: Icon(Icons.add),
onPressed: () {
map?.zoom(zoom: Zooms.IN, anim: true);
},
),
flex: 1),
Expanded(
child: IconButton(
icon: Icon(Icons.remove),
onPressed: () {
map?.zoom(zoom: Zooms.OUT, anim: true);
},
),
flex: 1),
Expanded(
child: IconButton(
icon: Icon(Icons.my_location),
onPressed: () async {
var location = await map.currentLocation();
if (location != null) {
map.go(lon: location.lon, lat: location.lat);
}
},
),
flex: 1),
Expanded(
child: IconButton(
icon: Icon(Icons.pin_drop),
onPressed: () async {
final mapLocation = await map?.crosshairLocation();
final marker = Marker(
id: DateTime.now()
.millisecondsSinceEpoch
.toString(),
mapLocation: mapLocation);
setState(() {
markers.add(marker);
});
},
),
flex: 1),
Expanded(
child: IconButton(
icon: Icon(Icons.delete),
onPressed: () {
if (markers.isNotEmpty) {
setState(() {
markers?.clear();
});
}
},
),
flex: 1)
])
]);
}),
));
}
@override
void onInit(MapController map) {
this.map = map;
}
@override
void onOverlayClicked(BaseOverlay overlay) {
if (overlay is Marker) {
var location = overlay.mapLocation;
map?.go(lon: location.lon, lat: location.lat);
}
}
}
เพียงเท่านี้ เราก็จะได้แผนที่พื้นฐานมาเรียบร้อยแล้ว พร้อมตัวอย่างการทำงานต่างๆ บนแผนที่ที่แถบเครื่องมือด้านล่าง ดังภาพผลลัพธ์นี้
อธิบายคำสั่งต่างๆ
การ Zoom เข้า
map?.zoom(zoom: Zooms.IN, anim: true);
การ Zoom ออก
map?.zoom(zoom: Zooms.IN, anim: true);
การเคลื่อนแผนที่ไปยังพิกัดที่ต้องการ
map?.go(lon: location.lon, lat: location.lat);
ผู้ใช้สามารถระบุพิกัดในรูปแบบ latitude, longitude ด้วยตัวเองได้เลย
การหาตำแหน่งปัจจุบัน
var location = await map.currentLocation();
ตัวแปร location จะได้รับตำแหน่งพิกัดแบบ latitude, longitude ของผู้ใช้มือถือ
ประยุกต์ใช้งาน: การเคลื่อนแผนที่ไปยังตำแหน่งปัจจุบันของผู้ใช้มือถือ
var location = await map.currentLocation();
if (location != null) {
map?.go(lon: location.lon, lat: location.lat);
}
การเพิ่มหมุดลงบนแผนที่ (แบบ Drop) โดยใช้พิกัดจากจุดกึ่งกลาง (crosshair)
final mapLocation = await map?.crosshairLocation();
final marker = Marker(
id: DateTime.now()
.millisecondsSinceEpoch
.toString(),
mapLocation: mapLocation);
setState(() {
markers.add(marker);
});
การเคลียร์หมุดทั้งหมดบนแผนที่
markers?.clear();
สามารถดักจับ Event ของเหตุการณ์
นักพัฒนาจำเป็นต้อง implement MapInterface ก่อน แล้วค่อย Override function ที่สามารถดักจับการกดคลิกที่หมุดของผู้ใช้ได้ โดยใช้คำสั่งดังนี้ (ด้านล่างนี้เป็นการแสดงว่า type ของ overlay เป็น Marker type หรือไม่)
@override
void onOverlayClicked(BaseOverlay overlay) {
if (overlay is Marker) {
var location = overlay.mapLocation;
map?.go(lon: location.lon, lat: location.lat);
}
}
การเปลี่ยนภาพแผนที่พื้นฐาน (Base Map)
นอกจากเรื่องพื้นฐานข้างต้นแล้ว Longdo Map ยังมีแผนที่ Base Map อีกหลากหลายรูปแบบ อาทิ สีเทา (Gray), สถานที่ (POI), ถนน (Normal) และอื่น ๆ ดูเพิ่มเติม
// ภาพแผนที่แบบเฉพาะถนน
map?.base(name: Layers.BASE_NORMAL);
// ภาพแผนที่แบบมีสถานที่
map?.base(name: Layers.BASE_POI);
// ภาพแผนที่แบบสีเทา
map?.base(name: Layers.BASE_GRAY);
// ภาพแผนที่แบบกลับทิศ
map?.base(name: Layers.BASE_REVERSE);
หมายเหตุ: แผนที่ฐาน (Base Map) สามารถเรียกใช้ได้ทีละ Layer เท่านั้น
การเพิ่มชั้นข้อมูล
Longdo Map รองรับการแสดงชั้นมูล อาทิ ภาพถ่ายดาวเทียมไทยโชต (GISTDA), เส้นสีจราจร (iTIC)
เส้นสีจราจร (iTIC) ภาพถ่ายดาวเทียมไทยโชต (GISTDA)
// เพิ่มชั้นข้อมูลภาพถ่ายดาวเทียมไทยโชต
map?.layer(layer: Layers.LAYER_THAICHOTE, add: true);
// ลบชั้นข้อมูลภาพถ่ายดาวเทียมไทยโชต
map?.layer(layer: Layers.LAYER_THAICHOTE, add: false);
// เพิ่มชั้นข้อมูลเส้นสีจราจร
map?.layer(layer: Layers.LAYER_TRAFFIC, add: true);
// ลบชั้นข้อมูลเส้นสีจราจร
map?.layer(layer: Layers.LAYER_TRAFFIC, add: false);
API อื่นๆ ทั้งหมด
ด้วยการเรียกแผนที่แบบ Web View เราจึงสามารถสั่งแผนที่ผ่านทางช่องทางที่เตรียมไว้ให้ได้ .run เช่น
map?.run(script: "map.Layers.setBase(longdo.Layers.GRAY)");
อ้างอิง Syntax ของ Javascript API :https://map.longdo.com/docs/javascript/maplayers/createmap#setbaselayer
จากตัวอย่างที่กล่าวมาข้างต้น เป็นเพียงส่วนหนึ่งที่นำมาอธิบายให้นักพัฒนาเข้าใจมากยิ่งขึ้น ท่านสามารถดาวน์โหลดตัวอย่างโปรเจคได้ที่ Github Longdo Map – Flutter
Longdo Map เป็นแผนที่ออนไลน์คนไทย ที่มีนักพัฒนาและหน่วยงานต่าง ๆ เลือกใช้อย่างแพร่หลาย หากต้องการศึกษาเพิ่มเติม สามารถดูได้ที่นี่เลยครับ https://map.longdo.com/products
แล้วพบกันใหม่ในบทความต่อไป สวัสดีครับ : )