Wemap Flutter SDK

Wemap

New home for Wemap Flutter SDKs

Getting Started

A Flutter plugin to display wemap's map. For the Android and iOS integration, we use wemap-sdk-android, wemap-sdk-ios.

Development

To develop Wemap software in this repository, ensure that you have at least the following software:

Installation

Before starting to develop your application with the WemapSDKs, you'll need to configure your credentials and add the SDK as a dependency.

Configure credentials

Wemap provides WemapSDKs via a private host and you will need to get secret, access keys and region to be able to access it. For additional information contact Wemap team.

Once you get the credentials, specify AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_REGION in your environment

export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_REGION=...

then you will send us your flutter team email, so you get permissions to use the SDK

Add the dependency

firstly login with the same email you have provided us:

dart pub global activate onepub
onepub login

Add the WemapSDKs to your app by adding in pubspec.yaml file:

wemap_sdk_flutter:
    hosted: https://onepub.dev/api/supddavuhn
    version: 0.26.2

Or by cmd:

onepub pub add wemap_sdk_flutter
  • And then you can bootstrap dependencies using:
flutter pub get

Android

  • Add this two repositories to repositories block inside allprojects in android/build.gradle:
maven { url "https://dist.nao-cloud.com/android/maven/" }
maven {
    url "s3://mobile-dev.getwemap.com/wemap/sdk/android"
    credentials(AwsCredentials) {
        accessKey  String.valueOf(System.getenv("AWS_ACCESS_KEY_ID"))
        secretKey  String.valueOf(System.getenv("AWS_SECRET_ACCESS_KEY"))
    }
}
  • Add the minSdkVersion to local.properties:
flutter.minSdkVersion=24
  • In your app/build.gradle set the minSdkVersion inside defaultConfig section to:
minSdkVersion localProperties.getProperty('flutter.minSdkVersion').toInteger()
  • If you want use VPS to access user location, you have to add into AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />

iOS

  • Add to Podfile head:
source 'https://cdn.cocoapods.org/'
source 'https://github.com/wemap/cocoapods-specs.git'
  • And set minimum deployment target to 13 or higher
platform :ios, '13.0'
  • (also in Podfile) Set BUILD_LIBRARY_FOR_DISTRIBUTION to true:
post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
    end
  end
end
  • Now you have to install those gems using Gemfile or manually:

    • Create a file with name Gemfile with this content:
      source 'https://rubygems.org'
      
      gem 'cocoapods'
      gem 'cocoapods-s3-download'
      
    • then run bundle install
  • Now, you can install the pods with pod install inside your iOS folder. and run your app.

  • NB: In case you are already depending on our SDK, and you are about to update to a new version: you have to use pod update instead.

  • If you want use VPS to access user location, you have to add into Info.plist:

<key>NSLocationWhenInUseUsageDescription</key>
<string></string>
<key>NSCameraUsageDescription</key>
<string></string>

and this into Podfile since permission_handler package is used :

config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',

    ## dart: PermissionGroup.camera
    'PERMISSION_CAMERA=1',

    ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
    'PERMISSION_LOCATION=1',
       ]

Usage

  • You can simply add the WemapMap widget as follow:
import 'package:flutter/material.dart';
import 'package:wemap_sdk_flutter/wemap_sdk_flutter.dart';

void main() {
  runApp(const MyHomePage(
    title: 'wemap sample',
  ));
}

class MyHomePage extends StatelessWidget {
  final String title;

  const MyHomePage({super.key, required this.title});

  void _onMapReady(MapData mapData, MapManager livemapManager) {
    // what ever to do, the map is ready
  }

  void _onBuildingFocusChanged(Building? building) {
    // print("on Building focus changed");
  }

  void _onActiveLevelChanged(Building building, Level level) {
    // print("on active level changed");
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(title: Text(title)),
            body: Container(
                constraints: const BoxConstraints.expand(),
                child: WemapMap(
                  options: MapOptions(
                      mapID: 23270, token: "", environment: Environment.PROD, locationSource: LocationSource.GPS),
                  onMapReady: _onMapReady,
                  onActiveLevelChanged: _onActiveLevelChanged,
                  onBuildingFocusChanged: _onBuildingFocusChanged,
                ))));
  }
}

Offline

For offline mode, you need to provide a full file path to the pack data ZIP file via packDataPath in MapOptions. There are two ways to do this:

Use PackDataManager.downloadPackData(mapID) to download pack data for a given map. The returned PackData contains a filePath you can pass to packDataPath:

final packData = await PackDataManager.downloadPackData(mapID);

MapOptions(
  mapID: mapID,
  token: token,
  environment: Environment.PROD,
  offlineMode: true,
  packDataPath: packData.filePath,
)

You can also check for updates with PackDataManager.isNewPackDataAvailable(mapID, packData.eTag).

Option 2: Use bundled pack data from assets

Add the offline ZIP file in example/assets and declare it in pubspec.yaml:

  assets:
    - assets/packdata.zip

The SDK expects a file path, so you must copy the asset to a temporary directory first. You'll need the path_provider package in your pubspec.yaml:

import 'dart:io';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';

Future<String> _getAssetPackDataPath(String assetPath) async {
  final dir = await getTemporaryDirectory();
  final fileName = assetPath.split('/').last;
  final file = File('${dir.path}/$fileName');
  if (!await file.exists()) {
    final bytes = await rootBundle.load(assetPath);
    await file.writeAsBytes(bytes.buffer.asUint8List());
  }
  return file.path;
}

// Usage
final packDataPath = await _getAssetPackDataPath('assets/packdata.zip');

MapOptions(
  mapID: xxx,
  token: xxx,
  environment: Environment.PROD,
  offlineMode: true,
  packDataPath: packDataPath,
)

Shared raster tiles (optional)

If you have multiple offline data packs (e.g., a ZIP file per language) and use raster tiles, you can specify a single raster ZIP file to be shared among the packs, reducing storage. Add it to assets in pubspec.yaml and use rasterZipFileName:

  assets:
    - assets/packdata.zip
    - assets/raster-tiles.zip
MapOptions(
  // ...
  offlineMode: true,
  packDataPath: packDataPath,
  rasterZipFileName: "raster-tiles.zip",
)

Continuous Integration

See CONTINUOUS_INTEGRATION.md

Libraries

wemap_sdk_flutter