Amap map component Flutter plugin

GitHub address: github.com/fluttify-pr…

The demo apk download

Rely on

dependencies:
  flutter:
    sdk: flutter
  amap_map_fluttify: ^x.x.x
Copy the code

configuration

Android

  1. Note that inapp/build.gradletheandroidBlock to configure the signature information in thebuildTypesBlock, otherwise you will not be able to match the appkey you configured in autonavi background, for example:
android {
    signingConfigs {
        release {
            keyAlias 'amap_map_test'
            keyPassword 'amap_map_test'
            storeFile file('.. /amap_map_test.jks')
            storePassword 'amap_map_test'} } buildTypes { debug { signingConfig signingConfigs.release } profile { signingConfig signingConfigs.release } release  { signingConfig signingConfigs.release } } }Copy the code

iOS

  1. To use the map you need to enable UiKitView, add to info.plist:
<key>io.flutter.embedded_views_preview</key>
<string>YES</string>
Copy the code
  1. To declare permissions for positioning, add:
<key>NSLocationWhenInUseUsageDescription</key>
<string>Location permission required</string>
Copy the code
  1. To call Amap, add whitelist:
<key>LSApplicationQueriesSchemes</key>
<array>
	<string>iosamap</string>
	<string>amapuri</string>
</array>
Copy the code

The import

import 'package:amap_map_fluttify/amap_map_fluttify.dart';
Copy the code

use

According to the map

Set the Autonavi Key

Add the following to the Application tag:

<meta-data android:name="com.amap.api.v2.apikey" android:value="key">
// The key requested by the developer
</meta-data>
Copy the code

Click me to get Key. Click me to view the necessary data SHA1 and package name for Key registration.

Initialize the map container

AmapView is a subclass of the Widget class for placing a map in the Widget tree. AmapView is the map container. Loading a map with AmapView is the same as any of the other widgets provided. The steps are as follows:

import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:flutter/material.dart';

class CreateMapScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Custom map')), body: AmapView(), ); }}Copy the code

The plug-in already handles the related callbacks in the APP lifecycle callback.

According to the map

The AmapController class is the controller class for the map and is used to manipulate the map. The tasks it carries include: Map layer switch (such as satellite image, night map), change map state (map rotation Angle, pitch Angle, center point coordinate and zoom level), add point Marker, draw geometric graph (Polyline, Polygon, Circle), monitor all kinds of events (click, gesture, etc.), etc. AmapController is the most important core class of the Map SDK, and many operations depend on it.

After the AmapView object is initialized, the AmapController object is constructed. Example code is as follows:

import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:flutter/material.dart';

class CreateMapScreen extends StatefulWidget {
  @override
  _CreateMapScreenState createState() => _CreateMapScreenState();
}

class _CreateMapScreenState extends State<CreateMapScreen> {
  AmapController _controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Custom map')),
      body: AmapView(
        onMapCreated: (controller) async{ _controller = controller; },),); }}Copy the code

Run the project you just completed to see Amap in your APP. The running effect is as follows (left Android, right iOS) :

Display positioning blue dot

Locating the blue dot refers to the function that shows the current location of the dot after entering the map. Since Android 3D map SDK 5.0.0, blue point positioning implementation does not rely on Android positioning SDK. Before 5.0.0, map SDK and positioning SDK need to be introduced into the project. The effect is as follows:

Structural positioning parameter

final option = MyLocationOption(
  show: true.// Whether to display
  myLocationType: MyLocationType.Locate, // Location mode
  interval: Duration.zero, // Locate the interval
  strokeColor: Colors.transparent, // Precision circle border color
  strokeWidth: 0.// The width of the precision circle
  fillColor: Colors.transparent, // Precision circle fill color
  iconProvider: AssetImage('Picture path'), // Customize the location icon
  anchorU: 0.0./ / the anchor point u
  anchorV: 0.0./ / anchor point v
);
Copy the code

Locate the blue dot display mode

enum MyLocationType {
  /// Only positioning
  Show,
  /// Position once and move to center
  Locate,
  /// follow
  Follow,
  /// Follow the direction
  Rotate,
}
Copy the code

Get latitude and longitude information

through

class AmapController {
  Future<LatLng> getLocation({
    Duration interval = const Duration(milliseconds: 500),
    Duration timeout = const Duration(seconds: 10)}); }Copy the code

Method to obtain latitude and longitude information. It is recommended to call inverse geocoding interface to obtain the location.

Display indoor map

The Android 3D Map SDK integrates the indoor map function and supports the integrated display of indoor and outdoor maps.

Function is introduced

After opening the indoor map, if the visible area contains the indoor map coverage area (such as: Cade Mall and other well-known malls), and the zoom reaches a certain level, you can directly see the fine indoor map effect on the map.

When zoom level ≥17, the indoor map can be displayed on the map.

When zoom level ≥18, not only can you see the interior map effect, but also allow you to switch floors and display the fine interior map.

As shown below:

Enable the indoor map method

3D map SDK will turn off indoor map display by default, if necessary can use the showIndoorMap class AmapController (bool enable) to turn it on.

await controller.showIndoorMap(bool enable); //true: display indoor map; False: not displayed.
Copy the code

Toggle map layers

The map plugin provides several preset map layers, including satellite maps, daytime maps (the most common yellow and white maps), night maps, navigation maps, and road maps. Note: The road layer is controlled by switches, not constants.

The name of the instructions
MapType.Standard The standard view
MapType.Satellite Satellite view
MapType.Night The night view
MapType.Navi The navigation view
MapType.Bus Bus view

Satellite maps

The satellite map can display the road network information as well as the sanitary photos (satellite photos). The codes and display effects of the satellite map are as follows:

await controller.setMapType(MapType.Satellite);
Copy the code

The following information is displayed:

Night view map

The code for setting up the night map is as follows:

await controller.setMapType(MapType.Night);
Copy the code

The following information is displayed:

The road layer

The road map is rendered according to real-time road data, which is different from the previous two Settings. The road map implementation method is as follows:

await controller.showTraffic(true);
Copy the code

The following information is displayed:

Using offline maps

Autonavi 3D Map SDK supports offline map function. (THE 2D map SDK does not support the offline map function.) The offline map can meet the requirements for viewing map information in a non-network environment. If the offline map data is available on the device, the SDK preferentially loads the offline map.

Offline map UI component

Offline map UI component covers functions such as city download, pause, update, delete and keyword city query, which is a subset of the offline map function of Amap client. The UI interaction style is close to that of Amap app, and the integration with developers’ UI is also taken into account, so as to keep it simple and extreme as possible. The following methods achieve one-click offline map development:

import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:flutter/material.dart';

class OfflineManagerScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Open offline Map Management')),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            // Open the offline map UI component
            AmapService.instance.openOfflineMapManager();
          },
          child: Text('Offline Map Management'),),),); }}Copy the code

The UI indicated:

Display English map

Map support switching between Chinese and English display. Specific implementation code:

await controller.setMapLanguage(Language.English);
Copy the code

The following information is displayed:

Custom map

Amap supports the use of visual custom map template to change the base map color and style, to achieve visual editing and control display map elements.

Creating a map Style

Amap open platform developers can access after obtaining a developer accountDeveloper consoleIn theMap custom platformSelect Create Map Style to select a template to create.

Edit map styles

Select any of the elements in the left list of the page you created to edit the style properties; You can also click the map and select elements from the list that pops up to edit the map.

Publish the map style and download it

After editing, click “Save” -> “Publish” in the upper right corner. After publishing, select “Usage”, then select “Android” platform, and click “Download offline File”.

Set style file

Set up offline style files

1. Select the version corresponding to the currently used map SDK version number from the official website console – My Map Style to download the style file:

2. The internal directory structure of the downloaded Zip file is as follows, and each file corresponds to one parameter in setCustomMapStyle:

The file name Description of File Contents Corresponding parameters
style_extra.data Extended content, such as grid background colors, etc styleExtraPath
style.data Specific style configuration styleDataPath
textures.zip Texture image (ZIP file) texturePath
import 'package:amap_map_fluttify/amap_map_fluttify.dart';
import 'package:flutter/material.dart';

class CreateMapScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: AmapView(
        zoomLevel: 10,
        onMapCreated: (controller) async {
          // styleDataPath and other parameter paths are the same as when using image. asset('path');
          await controller.setCustomMapStyle(styleDataPath: 'raw/style.data', styleExtraPath: 'raw/style_extra.data'); },),); }}Copy the code

The following information is displayed:

Control interaction

Controls are a set of components that float on a map surface and are used to manipulate the map, such as zoom buttons, compasses, positioning buttons, scales, and so on.

The zoom button

Zoom button is an exchange button for App users to control the zoom level of the map. Each click changes one level. This control is opened by default and can be controlled to hide by the following methods:



await controller.showZoomControl(true);
Copy the code

The compass

Compass is used to show map direction to App end users, which is not displayed by default. Control its display through the following interface:



await controller.showCompass(true);
Copy the code

Positioning button

Users on the App end can mark a blue registration point on the map by clicking the location button, representing their current location. Unlike the controls above, the logic inside the location button relies on the location SDK.

The SDK does not provide the ability to customize location buttons, so if you want to implement this feature, you can refer to itCustom location buttonThe content of the.



await controller.showLocateControl(true);
Copy the code

Scale control

Scale control (maximum ratio is 1:10 m, minimum ratio is 1:1000 km), located in the lower right corner of the map, can control its display and hide, setting method is:



await controller.showScaleControl(true);
Copy the code

Gesture interaction

The map SDK provides a variety of gestures for App users to interact with the map, such as zooming, rotating, sliding and tilting. These gestures are turned on by default, and if you want to turn some of them off, you can turn them on or off through an interface provided by the AmapController class.

Gesture method description

Here’s how to control whether a gesture works:

The name of the A method is called
Zoom gestures AmapController.setZoomGesturesEnabled(bool)
Sliding gesture AmapController.setScrollGesturesEnabled(bool)
Rotation gestures AmapController.setRotateGesturesEnabled(bool)
Tilting gesture AmapController.setTiltGesturesEnabled(bool)
All the hand gestures AmapController.setAllGesturesEnabled(bool)

Zoom gestures

Zoom gestures change the zoom level of the map, and the map responds with the following gestures:

  • Double clicking on the map increases zoom level by 1 (Zoom in)
  • Pinch/stretch with two fingers

You can also disable or enable zooming gestures. Disabling the zoom gesture does not affect the user’s use of the zoom control button on the map. Here is the code that controls the zoom gesture on and off:

await controller.setZoomGesturesEnabled(true);
Copy the code

Sliding gesture

You can drag the map with your finger to scroll around (pan) or slide the map with your finger (animation). You can also disable or turn on pan (slide) gestures. The following describes how to control the zoom gesture on and off. The sample code is as follows:

await controller.isScrollGesturesEnabled(true);
Copy the code

Rotation gestures

You can rotate the 3D vector map with two fingers, and you can disable the rotation gesture. The following describes the method of controlling rotation gesture on and off. The sample code is as follows:

await controller.setRotateGesturesEnabled(true);
Copy the code

Tilting gesture

Users can place two fingers on a map and move them together down or up to increase or decrease the tilt Angle, as well as disable the tilt gesture. Here is the code that controls the tilting gesture on and off:

await controller.setTiltGesturesEnabled(true);
Copy the code

Open the gesture operation method with the center point:

await controller.setZoomByCenter(true);
Copy the code

Call method interaction

The concept of method interaction is developed from a program perspective. The map SDK provides many interface methods to interact with the map, such as: changing the display area of the map (i.e. changing the center point of the map), changing the zoom level of the map, limiting the display area of the map, etc. The core methods for map perspective interaction all rely on the methods provided by the AmapController class.

Change the center of the map

If you want to change the center of the map, either animated or animated can be moved using the following method:

await controller.setCenterCoordinate(LatLng(23.16.113.23), animated: false);
Copy the code

Changes the zoom level of the map

If you want to change the zoom level of the map, either animated or animated can be animated using the following method:

await controller.setZoomLevel(10, animated: false);
Copy the code

Limit the display range of the map

The screen of the mobile phone displays only the set map range. For example, if you want to display only the map of downtown Beijing, you can use this function. Note: The map rotation gesture will no longer work if you limit the map display area.

final southWest = LatLng(40.116);
final northEast = LatLng(42.118);
await controller.setMapRegionLimits(southWest, northEast);
Copy the code

Map screenshot function

The map SDK supports screen capture of the display area of the current screen, and screen capture of maps, coverings (including information Windows) and logos, excluding map controls and Toast Windows. A detailed example is as follows:

final Uint8List data = await controller.screenShot();
Copy the code

The object returned is Image data, which can be displayed directly using image.memory (:Uint8List).

Draw point mark

Dot markers are used to mark any location on a map, such as user location, vehicle location, store location, anything with location attributes. The dot marking function provided by the map SDK consists of two parts, one is a point (commonly known as Marker) and the other is an information window floating above the point (commonly known as InfoWindow). At the same time, the SDK encapsulates a large number of trigger events for Marker and InfoWindow, such as click events, long press events, drag events. Markers have a default style and also support customization. Due to the rich content, the following can only show the use of some basic functions. For details, please refer to the manual. Marker MarkerOption

Draw default Marker

The code for drawing Marker is as follows:

LatLng latLng = LatLng(39.906901.116.397972);
final Marker marker = controller.addMarker(MarkerOption(coordinate: latLng));
Copy the code

The Marker effect drawn by the above code is shown as follows:

Common attributes of Marker

The name of the instructions
position Mark the latitude and longitude of a location on a map. Required parameters
title Dot labeled title
snippet Dot the content of the tag
draggable Whether the dot mark can be dragged
visible Whether the dot mark is visible
anchorU,anchorV Dot marks the anchor point
alpha Point transparency

Draw a custom Marker

According to actual business requirements, user-defined markers can be added at the locations specified on the map. MarkerOptions is a class that sets parameter variables of Marker and is often used when customizing markers. The following code description takes the custom Marker icon as an example:

final marker = await controller.addMarker(
  MarkerOption(
    coordinate: LatLng(39.906901.116.397972),
    iconProvider: AssetImage('images/test_icon.png'),),);Copy the code

The Marker effect drawn by the above code is shown as follows:

Draw animation effect Marker

The plug-in provides a method to set animation for Marker, and the specific implementation method is as follows:

final marker = await controller.addMarker(
  MarkerOption(
    coordinate: getNextLatLng(),
    iconProvider: AssetImage('images/test_icon.png'),
    anchorU: 0.5,
    anchorV: 1,
    visible: false,),);await marker.startAnimation(ScaleMarkerAnimation(
  fromValue: 0.8,
  toValue: 1.2,
  duration: Duration(milliseconds: 1000),
  repeatCount: 0));await marker.setVisible(true);
Copy the code

Since the animation display process is asynchronous, if the marker is directly added and the animation is executed immediately, it may appear that the marker is first added to the map and then flashes by to start the animation. The workaround provided here is to add a hidden marker and wait for the animation to start calling before displaying the marker.

Marker events that can be triggered

Marker click event

Click the Marker when the callback AmapController: : setMarkerClickedListener, listener implementation examples are as follows:

await controller.setMarkerClickedListener((marker) async {
  // Click marker to replace image
  marker.setIcon(
    AssetImage('images/test_icon.png'),
    createLocalImageConfiguration(context),
  );
});
Copy the code

Marker drag event callback when they drag the Marker AmapController: : setMarkerDragListener (: onMarkerDragStart: onMarkerDragging: onMarkerDragEnd), An example of a listener implementation is as follows:

await controller.setMarkerDragListener(
  onMarkerDragStart: (marker) async {
    // Drag begins
  },
  onMarkerDragging: (marker) async {
    / / drag
  },
  onMarkerDragEnd: (marker) async {
    // End of drag});Copy the code

Draw the InfoWindow

InfoWindow is part of the dot Marker. The default InfoWindow displays only two properties of the Marker object, title and snippet. If you want to customize the style or content of InfoWindow, see the following.

Draws the default Infowindow

The SDK provides the user with the default InfoWindow style, calledMarkerOf the classshowInfoWindow()hideInfoWindow()Method to control show and hide. When changeMarkertitlesnippetProperty is called againshowInfoWindow(), can be updatedInfoWindowDisplay content. The effect is as follows:

Draw a custom InfoWindow

Customizing InfoWindow requires a call to showCustomInfoWindow on the AmapController, passing in the Marker object and the widget for the custom InfoWindow. Note that the widget is only provided as a screenshot for native display. If the widget has dynamic content, such as buttons, it will not be valid when converted to a static screenshot. The implementation example is as follows:

await controller.setMarkerClickedListener((marker) async {
  await controller.showCustomInfoWindow(
    marker,
    Card(
      elevation: 10,
      child: Container(
        padding: EdgeInsets.all(16),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(Icons.location_on),
            Text(await marker.title),
          ],
        ),
      ),
    ),
  );
});
Copy the code

The InfoWindow event that can be triggered

When they click the InfoWindow callback AmapController. SetInfoWindowClickListener (: onInfoWindowClicked), listener implementation examples are as follows:

await controller.setInfoWindowClickListener((marker) async {
  toast('${await marker.title}.${await marker.coordinate}');
});
Copy the code

Draw the line

The lines drawn on the map are implemented by the Polyline class definition and are connected by a set of latitude and longitude (LatLng object) points.

Draw a line

As with dot markers, Polyline’s property operations are concentrated in the PolylineOption class. An example of adding a line is as follows:

await controller.addPolyline(PolylineOption(
  coordinateList: [
    LatLng(39.999391.116.135972),
    LatLng(39.898323.116.057694),
    LatLng(39.900430.116.265061),
    LatLng(39.955192.116.140092),
  ],
  strokeColor: Colors.red,
  width: 10));Copy the code

The code above defines the line to be red and 10 pixels wide, as shown below:

Common parameters for drawing lines

The name of the instructions
coordinateList List of longitude and latitude of broken lines
width The line width
strokeColor Line color
textureProvider Custom texture
lineCapType Line segment end style
lineJoinType Style of line segment connection
dashType Whether the dotted line

Draw faces

The faces on the map are divided into circles and polygons.

Draw the circle

The Circle is implemented by the Circle class definition. To construct a Circle, you need to determine its center and radius. Example code is as follows:

await controller.addCircle(CircleOption(
  center: LatLng(39.999391.116.135972),
  radius: 10000,
  width: 10,
  strokeColor: Colors.green,
));
Copy the code

The code above defines the edge color of the circle as green and 10 pixels wide, as shown below:

Draw polygons

A Polygon is a group of closed line segments on a map defined by the Polygon class. It is a closed figure connected by a group of LatLng points in incoming order. Similar to drawing lines, the manipulation of faces’ properties is centralized in PolygonOption.

final polygon = await controller.addPolygon(PolygonOption(
  coordinateList: [
    LatLng(39.999391.116.135972),
    LatLng(39.898323.116.057694),
    LatLng(39.900430.116.265061),
    LatLng(39.955192.116.140092),
  ],
  width: 10,
  strokeColor: Colors.green,
));
Copy the code

The code above defines the edge color of the circle as green and 10 pixels wide, as shown below:

Thermal map

The thermal chart function displays business data on the map, which can visually describe the heat status of people, vehicles and other things in an area for users.

Organize thermal map data

Taking the local simulation data as an example, the SDK thermal map needs latitude and longitude points group/list data.

Example code is as follows:

await controller.addHeatmapTileOverlay(
  HeatmapTileOption(
    coordinateList: getNextBatchLatLng(50),
    gradient: RadialGradient(
      colors: [Colors.blue, Colors.yellow, Colors.red],
      stops: <double> [0.08.0.4.1.0],),),);Copy the code

The renderings are as follows:

Point smooth movement

Function description: according to the input key points and time parameters, the smooth movement of points.

Usage scenario: It can be used to display vehicle track and user movement track.

Examples of effects:

How to achieve smooth point movement

The configuration parameters to achieve smooth movement are all in the SmoothMoveMarkerOption class, where Path is the latitude and longitude list of the moving path, iconProvider is the picture of marker, and duration is the animation duration.

await controller.addSmoothMoveMarker(
  SmoothMoveMarkerOption(
    path: [for (int i = 0; i < 10; i++) getNextLatLng()],
    iconProvider: AssetImage('images/test_icon.png'),
    duration: Duration(seconds: 10),),);Copy the code

Draw a large number of dot layers

Mass point layer applied to mobile terminal is used to display coordinate point data with similar properties in batches. The mass point layer supports a large range of point orders, from dozens of points to 100,000 points (it is recommended not to exceed 100,000 point data) can be applied to the mass point layer for processing.

A massive dot layer effect with tens of thousands of points is shown below:

Show mass point

Adding mass points is similar to adding common markers, and only the corresponding type parameters need to be constructed. Sample code:

final overlay = await controller.addMultiPointOverlay(
  MultiPointOption(
    pointList: [
      for (int i = 0; i < 10000; i++)
        PointOption(
          coordinate: getNextLatLng(),
          id: i.toString(),
          title: 'Point$i',
          snippet: 'Snippet$i',
          object: 'Object$i',
        )
    ],
    iconProvider: AssetImage('images/test_icon.png'),),);Copy the code

Call remove on the returned Overlay object to remove the corresponding overlay layer.

Massive click events

await controller.setMultiPointClickedListener(
  (id, title, snippet, object) async {
    toast(
      'id: $id, title: $title, snippet: $snippet, object: $object',); });Copy the code

LICENSE

Copyright (C) 2020 yohom

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see www.gnu.org/licenses/.