1. Wprowadzenie
Flutter to pakiet SDK do tworzenia aplikacji mobilnych od Google, który umożliwia szybkie tworzenie wysokiej jakości aplikacji natywnych na iOS i Androida.
Za pomocą wtyczki Map Google dla Flutter możesz dodawać do aplikacji mapy oparte na danych z Map Google. Wtyczka automatycznie obsługuje dostęp do serwerów Map Google, wyświetlanie mapy i reagowanie na gesty użytkownika, takie jak kliknięcia i przeciągnięcia. Możesz też dodawać znaczniki do mapy. Obiekty te zawierają dodatkowe informacje o lokalizacjach na mapie i umożliwiają użytkownikowi interakcję z mapą.
Co utworzysz
W tym ćwiczeniu utworzysz aplikację mobilną z Mapą Google za pomocą pakietu Flutter SDK. Twoja aplikacja będzie:
|
|
Co to jest Flutter?
Flutter ma 3 podstawowe funkcje.
- Szybkie tworzenie: dzięki funkcji stanowego gorącego przeładowania możesz tworzyć aplikacje na Androida i iOS w milisekundach.
- Wyrazistość i elastyczność: szybko wdrażaj funkcje, koncentrując się na wrażeniach użytkowników.
- Wydajność natywna na iOS i Androidzie: widżety Fluttera uwzględniają wszystkie kluczowe różnice między platformami, takie jak przewijanie, nawigacja, ikony i czcionki, aby zapewnić pełną wydajność natywną.
Mapy Google oferują:
- Zasięg na poziomie 99% na świecie: twórz aplikacje, korzystając z wiarygodnych i wyczerpujących danych z ponad 200 krajów i regionów.
- 25 milionów aktualizacji dziennie: możesz liczyć na dokładne informacje o bieżącej lokalizacji.
- Miliard aktywnych użytkowników miesięcznie: skaluj bez obaw dzięki infrastrukturze Map Google.
W tym ćwiczeniu z programowania dowiesz się, jak utworzyć w aplikacji Flutter funkcję Map Google na iOS i Androida.
Czego się nauczysz
- Jak utworzyć nową aplikację Flutter.
- Jak skonfigurować wtyczkę Map Google dla Fluttera.
- Jak dodawać znaczniki do mapy za pomocą danych o lokalizacji z usługi internetowej.
Te warsztaty skupiają się na dodawaniu mapy Google do aplikacji Flutter. Nieistotne koncepcje i bloki kodu zostały zamaskowane. Można je po prostu skopiować i wkleić.
Czego chcesz się nauczyć podczas tego laboratorium?
2. Konfigurowanie środowiska Flutter
Do ukończenia tego modułu potrzebne są 2 elementy: pakiet Flutter SDK i edytor. W tym laboratorium zakłada się, że używasz Androida Studio, ale możesz użyć dowolnego edytora.
Ten przewodnik możesz wykonać na dowolnym z tych urządzeń:
- urządzenie fizyczne (Android lub iOS) podłączone do komputera i ustawione w trybie deweloperskim;
- Symulator iOS. (Wymaga zainstalowania narzędzi Xcode).
- emulator Androida, (Wymaga konfiguracji w Android Studio).
3. Pierwsze kroki
Pierwsze kroki z Flutterem
Najprostszym sposobem na rozpoczęcie pracy z Flutterem jest użycie narzędzia wiersza poleceń flutter do utworzenia całego kodu wymaganego do prostego rozpoczęcia pracy.
$ flutter create google_maps_in_flutter --platforms android,ios,web Creating project google_maps_in_flutter... Resolving dependencies in `google_maps_in_flutter`... Downloading packages... Got dependencies in `google_maps_in_flutter`. Wrote 81 files. All done! You can find general documentation for Flutter at: https://docs.flutter.dev/ Detailed API documentation is available at: https://api.flutter.dev/ If you prefer video documentation, consider: https://www.youtube.com/c/flutterdev In order to run your application, type: $ cd google_maps_in_flutter $ flutter run Your application code is in google_maps_in_flutter/lib/main.dart.
Dodawanie wtyczki Map Google dla Flutter jako zależności
Dodawanie dodatkowych funkcji do aplikacji Flutter jest łatwe dzięki pakietom Pub. W tym Codelabs wprowadzisz wtyczkę Map Google Flutter, uruchamiając to polecenie z katalogu projektu.
$ cd google_maps_in_flutter $ flutter pub add google_maps_flutter Resolving dependencies... Downloading packages... + csslib 1.0.0 + flutter_plugin_android_lifecycle 2.0.19 + flutter_web_plugins 0.0.0 from sdk flutter + google_maps 7.1.0 + google_maps_flutter 2.6.1 + google_maps_flutter_android 2.8.0 + google_maps_flutter_ios 2.6.0 + google_maps_flutter_platform_interface 2.6.0 + google_maps_flutter_web 0.5.7 + html 0.15.4 + js 0.6.7 (0.7.1 available) + js_wrapping 0.7.4 leak_tracker 10.0.4 (10.0.5 available) leak_tracker_flutter_testing 3.0.3 (3.0.5 available) material_color_utilities 0.8.0 (0.11.1 available) meta 1.12.0 (1.14.0 available) + plugin_platform_interface 2.1.8 + sanitize_html 2.1.0 + stream_transform 2.1.0 test_api 0.7.0 (0.7.1 available) + web 0.5.1 Changed 16 dependencies! 6 packages have newer versions incompatible with dependency constraints. Try `flutter pub outdated` for more information.
Konfigurowanie iOS platform
Aby uzyskać najnowszą wersję pakietu Google Maps SDK na iOS, wymagana jest minimalna wersja platformy iOS 14. Zmodyfikuj początek pliku konfiguracji ios/Podfile w ten sposób:
ios/Podfile
# Google Maps SDK requires platform version 14
# https://developers.google.com/maps/flutter-package/config#ios
platform :ios, '14.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Konfigurowanie Androida minSDK
Aby używać pakietu Google Maps SDK na Androidzie, musisz ustawić minSdk na 21. Zmodyfikuj plik konfiguracji android/app/build.gradle w ten sposób:
android/app/build.gradle
android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.google_maps_in_flutter"
// Minimum Android version for Google Maps SDK
// https://developers.google.com/maps/flutter-package/config#android
minSdk = 21
targetSdk = flutter.targetSdkVersion
versionCode = flutterVersionCode.toInteger()
versionName = flutterVersionName
}
}
4. Dodawanie Map Google do aplikacji
Wszystko zależy od kluczy interfejsu API
Aby korzystać z Map Google w aplikacji Flutter, musisz skonfigurować projekt interfejsu API z Google Maps Platform, postępując zgodnie z instrukcjami w sekcjach Używanie klucza interfejsu API w pakiecie Maps SDK na Androida, Używanie klucza interfejsu API w pakiecie Maps SDK na iOS i Używanie klucza interfejsu API w interfejsie Maps JavaScript API. Po uzyskaniu kluczy interfejsu API wykonaj te czynności, aby skonfigurować aplikacje na Androida i iOS.
Dodawanie klucza interfejsu API do aplikacji na Androida
Aby dodać klucz interfejsu API do aplikacji na Androida, edytuj plik AndroidManifest.xml w android/app/src/main. Dodaj pojedynczy wpis meta-data zawierający klucz interfejsu API utworzony w poprzednim kroku w węźle application.
android/app/src/main/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:label="google_maps_in_flutter"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<!-- TODO: Add your Google Maps API key here -->
<meta-data android:name="com.google.android.geo.API_KEY"
android:value="YOUR-KEY-HERE"/>
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>
Dodawanie klucza interfejsu API do aplikacji na iOS
Aby dodać klucz interfejsu API do aplikacji na iOS, edytuj plik AppDelegate.swift w ios/Runner. W przeciwieństwie do Androida dodanie klucza interfejsu API w iOS wymaga wprowadzenia zmian w kodzie źródłowym aplikacji Runner. AppDelegate to podstawowy singleton, który jest częścią procesu inicjowania aplikacji.
Wprowadź w tym pliku 2 zmiany. Najpierw dodaj instrukcję #import, aby pobrać nagłówki Map Google, a potem wywołaj metodę provideAPIKey() pojedynczej instancji GMSServices. Ten klucz API umożliwia Mapom Google prawidłowe wyświetlanie fragmentów mapy.
ios/Runner/AppDelegate.swift
import Flutter
import UIKit
import GoogleMaps // Add this import
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
// TODO: Add your Google Maps API key
GMSServices.provideAPIKey("YOUR-API-KEY") // Add this line
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Dodawanie klucza interfejsu API do aplikacji internetowej
Aby dodać klucz interfejsu API do aplikacji internetowej, edytuj plik index.html w web. Dodaj odwołanie do skryptu Maps JavaScript w sekcji head, używając klucza interfejsu API.
web/index.html
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="google_maps_in_flutter">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<!-- Add your Google Maps API key here -->
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR-KEY-HERE"></script>
<title>google_maps_in_flutter</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<script src="flutter_bootstrap.js" async></script>
</body>
</html>
Wyświetlanie mapy na ekranie
Pora wyświetlić mapę na ekranie. Zastąp zawartość pliku lib/main.dart tym kodem:
lib/main.dart
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late GoogleMapController mapController;
final LatLng _center = const LatLng(45.521563, -122.677433);
void _onMapCreated(GoogleMapController controller) {
mapController = controller;
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
useMaterial3: true,
colorSchemeSeed: Colors.green[700],
),
home: Scaffold(
appBar: AppBar(
title: const Text('Maps Sample App'),
elevation: 2,
),
body: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: CameraPosition(
target: _center,
zoom: 11.0,
),
),
),
);
}
}
Uruchamianie aplikacji
Uruchom aplikację Flutter na iOS lub Androidzie, aby zobaczyć pojedynczy widok mapy z Portland na środku. Możesz też uruchomić emulator Androida lub symulator iOS. Możesz zmienić środek mapy, aby przedstawić swoje miasto lub inne ważne dla Ciebie miejsce.
$ flutter run
|
|
5. Put Google on the Map
Google ma wiele biur na całym świecie, m.in. w Ameryce Północnej, Ameryce Łacińskiej, Europie, regionie Azji i Pacyfiku oraz w Afryce i na Bliskim Wschodzie. Zaletą tych map jest to, że mają łatwy w użyciu punkt końcowy interfejsu API, który dostarcza informacje o lokalizacji biura w formacie JSON. W tym kroku umieścisz lokalizacje biur na mapie. W tym kroku użyjesz generowania kodu do analizowania JSON.
Dodaj do projektu 3 nowe zależności Fluttera w ten sposób: Dodaj pakiet http, który ułatwia wysyłanie żądań HTTP, pakiety json_serializable i json_annotation do deklarowania struktury obiektu reprezentującego dokumenty JSON oraz pakiet build_runner do obsługi generowania kodu.
$ flutter pub add http json_annotation json_serializable dev:build_runner Resolving dependencies... Downloading packages... + _fe_analyzer_shared 67.0.0 (68.0.0 available) + analyzer 6.4.1 (6.5.0 available) + args 2.5.0 + build 2.4.1 + build_config 1.1.1 + build_daemon 4.0.1 + build_resolvers 2.4.2 + build_runner 2.4.9 + build_runner_core 7.3.0 + built_collection 5.1.1 + built_value 8.9.2 + checked_yaml 2.0.3 + code_builder 4.10.0 + convert 3.1.1 + crypto 3.0.3 + dart_style 2.3.6 + file 7.0.0 + fixnum 1.1.0 + frontend_server_client 4.0.0 + glob 2.1.2 + graphs 2.3.1 + http 1.2.1 + http_multi_server 3.2.1 + http_parser 4.0.2 + io 1.0.4 js 0.6.7 (0.7.1 available) + json_annotation 4.9.0 + json_serializable 6.8.0 leak_tracker 10.0.4 (10.0.5 available) leak_tracker_flutter_testing 3.0.3 (3.0.5 available) + logging 1.2.0 material_color_utilities 0.8.0 (0.11.1 available) meta 1.12.0 (1.14.0 available) + mime 1.0.5 + package_config 2.1.0 + pool 1.5.1 + pub_semver 2.1.4 + pubspec_parse 1.2.3 + shelf 1.4.1 + shelf_web_socket 1.0.4 + source_gen 1.5.0 + source_helper 1.3.4 test_api 0.7.0 (0.7.1 available) + timing 1.0.1 + typed_data 1.3.2 + watcher 1.1.0 + web_socket_channel 2.4.5 + yaml 3.1.2 Changed 42 dependencies! 8 packages have newer versions incompatible with dependency constraints. Try `flutter pub outdated` for more information.
Analizowanie JSON z generowaniem kodu
Być może zauważysz, że dane JSON zwracane z punktu końcowego interfejsu API mają regularną strukturę. Przydatne byłoby wygenerowanie kodu, który przekształci te dane w obiekty, których można używać w kodzie.
W katalogu lib/src utwórz plik locations.dart i opisz strukturę zwracanych danych JSON w ten sposób:
lib/src/locations.dart
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:http/http.dart' as http;
import 'package:json_annotation/json_annotation.dart';
part 'locations.g.dart';
@JsonSerializable()
class LatLng {
LatLng({
required this.lat,
required this.lng,
});
factory LatLng.fromJson(Map<String, dynamic> json) => _$LatLngFromJson(json);
Map<String, dynamic> toJson() => _$LatLngToJson(this);
final double lat;
final double lng;
}
@JsonSerializable()
class Region {
Region({
required this.coords,
required this.id,
required this.name,
required this.zoom,
});
factory Region.fromJson(Map<String, dynamic> json) => _$RegionFromJson(json);
Map<String, dynamic> toJson() => _$RegionToJson(this);
final LatLng coords;
final String id;
final String name;
final double zoom;
}
@JsonSerializable()
class Office {
Office({
required this.address,
required this.id,
required this.image,
required this.lat,
required this.lng,
required this.name,
required this.phone,
required this.region,
});
factory Office.fromJson(Map<String, dynamic> json) => _$OfficeFromJson(json);
Map<String, dynamic> toJson() => _$OfficeToJson(this);
final String address;
final String id;
final String image;
final double lat;
final double lng;
final String name;
final String phone;
final String region;
}
@JsonSerializable()
class Locations {
Locations({
required this.offices,
required this.regions,
});
factory Locations.fromJson(Map<String, dynamic> json) =>
_$LocationsFromJson(json);
Map<String, dynamic> toJson() => _$LocationsToJson(this);
final List<Office> offices;
final List<Region> regions;
}
Future<Locations> getGoogleOffices() async {
const googleLocationsURL = 'https://about.google/static/data/locations.json';
// Retrieve the locations of Google offices
try {
final response = await http.get(Uri.parse(googleLocationsURL));
if (response.statusCode == 200) {
return Locations.fromJson(
json.decode(response.body) as Map<String, dynamic>);
}
} catch (e) {
if (kDebugMode) {
print(e);
}
}
// Fallback for when the above HTTP request fails.
return Locations.fromJson(
json.decode(
await rootBundle.loadString('assets/locations.json'),
) as Map<String, dynamic>,
);
}
Po dodaniu tego kodu w IDE (jeśli go używasz) powinny pojawić się czerwone zygzaki, ponieważ odwołuje się on do nieistniejącego pliku równorzędnego locations.g.dart.. Ten wygenerowany plik konwertuje nietypowe struktury JSON na nazwane obiekty. Utwórz go, uruchamiając build_runner w ten sposób:
$ dart run build_runner build --delete-conflicting-outputs [INFO] Generating build script... [INFO] Generating build script completed, took 357ms [INFO] Creating build script snapshot...... [INFO] Creating build script snapshot... completed, took 10.5s [INFO] There was output on stdout while compiling the build script snapshot, run with `--verbose` to see it (you will need to run a `clean` first to re-snapshot). [INFO] Initializing inputs [INFO] Building new asset graph... [INFO] Building new asset graph completed, took 646ms [INFO] Checking for unexpected pre-existing outputs.... [INFO] Deleting 1 declared outputs which already existed on disk. [INFO] Checking for unexpected pre-existing outputs. completed, took 3ms [INFO] Running build... [INFO] Generating SDK summary... [INFO] 3.4s elapsed, 0/3 actions completed. [INFO] Generating SDK summary completed, took 3.4s [INFO] 4.7s elapsed, 2/3 actions completed. [INFO] Running build completed, took 4.7s [INFO] Caching finalized dependency graph... [INFO] Caching finalized dependency graph completed, took 36ms [INFO] Succeeded after 4.8s with 2 outputs (7 actions)
Kod powinien być teraz ponownie analizowany bez problemów. Następnie dodajmy plik locations.json używany w funkcji getGoogleOffices. Jednym z powodów uwzględnienia tej funkcji rezerwowej jest to, że statyczne dane wczytywane w tej funkcji są udostępniane bez nagłówków CORS, a tym samym nie będą się wczytywać w przeglądarce internetowej. Aplikacje Flutter na Androida i iOS nie wymagają nagłówków CORS, ale dostęp do danych mobilnych może być w najlepszym razie kapryśny.
Otwórz w przeglądarce stronę https://about.google/static/data/locations.json i zapisz jej zawartość w katalogu zasobów. Możesz też użyć wiersza poleceń w ten sposób:
$ mkdir assets
$ cd assets
$ curl -o locations.json https://about.google/static/data/locations.json
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 30348 100 30348 0 0 75492 0 --:--:-- --:--:-- --:--:-- 75492
Po pobraniu pliku zasobu dodaj go do sekcji Flutter w pliku pubspec.yaml.
pubspec.yaml
flutter:
uses-material-design: true
assets:
- assets/locations.json
Zmodyfikuj plik main.dart, aby poprosić o dane mapy, a następnie użyj zwróconych informacji do dodania biur do mapy:
lib/main.dart
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'src/locations.dart' as locations;
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final Map<String, Marker> _markers = {};
Future<void> _onMapCreated(GoogleMapController controller) async {
final googleOffices = await locations.getGoogleOffices();
setState(() {
_markers.clear();
for (final office in googleOffices.offices) {
final marker = Marker(
markerId: MarkerId(office.name),
position: LatLng(office.lat, office.lng),
infoWindow: InfoWindow(
title: office.name,
snippet: office.address,
),
);
_markers[office.name] = marker;
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
useMaterial3: true,
colorSchemeSeed: Colors.green[700],
),
home: Scaffold(
appBar: AppBar(
title: const Text('Google Office Locations'),
elevation: 2,
),
body: GoogleMap(
onMapCreated: _onMapCreated,
initialCameraPosition: const CameraPosition(
target: LatLng(0, 0),
zoom: 2,
),
markers: _markers.values.toSet(),
),
),
);
}
}
Ten kod wykonuje kilka operacji:
- W
_onMapCreatedużywa kodu analizy JSON z poprzedniego kroku,awaiting, aż zostanie załadowany. Następnie używa zwróconych danych do tworzeniaMarkerwsetState()wywołaniu zwrotnym. Gdy aplikacja otrzyma nowe znaczniki, funkcja setState poinformuje Fluttera o konieczności ponownego narysowania ekranu, co spowoduje wyświetlenie lokalizacji biur. - Markery są przechowywane w
Mappowiązanym z widgetemGoogleMap. Dzięki temu znaczniki zostaną połączone z odpowiednią mapą. Możesz oczywiście mieć wiele map i wyświetlać na każdej z nich różne znaczniki.

Oto zrzut ekranu z Twoimi osiągnięciami. Na tym etapie można wprowadzić wiele ciekawych dodatków. Możesz na przykład dodać widok listy biur, który przesuwa i powiększa mapę, gdy użytkownik kliknie biuro. Ale jak to się mówi, to zadanie pozostawiamy czytelnikowi.
6. Dalsze kroki
Gratulacje!
Udało Ci się ukończyć ćwiczenie i utworzyć aplikację we Flutterze z Mapą Google. Korzystasz też z usługi internetowej JSON.
Inne dalsze kroki
W tym laboratorium kodowania utworzyliśmy funkcję wizualizacji wielu punktów na mapie. Istnieje wiele aplikacji mobilnych, które wykorzystują tę funkcję, aby zaspokajać różne potrzeby użytkowników. Istnieją inne materiały, które mogą Ci pomóc w dalszym rozwoju:
- Tworzenie aplikacji mobilnych za pomocą Fluttera i Map Google (prezentacja na konferencji Cloud Next ’19)
- Pakiet
google_maps_webserviceHadriena Lejarda, który sprawia, że korzystanie z usług internetowych Map Google, takich jak Directions API, Distance Matrix API i Places API, jest bardzo proste. - Jeśli chcesz poznać różne opcje korzystania z interfejsu API za pomocą JSON REST, zapoznaj się z tym artykułem na Medium autorstwa Andrew Brogdona, w którym znajdziesz różne sposoby pracy z interfejsami API typu JSON REST.

