### Build Example App for APK Source: https://github.com/josxha/flutter-maplibre/blob/main/CONTRIBUTING.md Builds the example application to fetch Gradle dependencies. This step is necessary before running native build tools. ```bash (cd example/ && flutter build apk) ``` -------------------------------- ### Build Example App for iOS Source: https://github.com/josxha/flutter-maplibre/blob/main/CONTRIBUTING.md Builds the example application for iOS. This step is required before running ffigen for iOS. ```bash (cd example/ && flutter build ios --release --no-codesign) ``` -------------------------------- ### Install Dependencies Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/setup.md After modifying pubspec.yaml, run this command to install the package. ```bash flutter pub get ``` -------------------------------- ### Install JDK 17 and Configure Java Source: https://github.com/josxha/flutter-maplibre/blob/main/CONTRIBUTING.md Ensures JDK 17 is installed and set as the default Java version for building native components. This is a prerequisite for using jnigen. ```bash apt install openjdk-17-jdk-headless sudo update-alternatives --config java ``` ```bash brew install openjdk@17 echo 'export JAVA_HOME="$(/usr/libexec/java_home -v 17)"' >> ~/.zshrc source ~/.zshrc ``` -------------------------------- ### Display Your First Map with MapLibreMap Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/usage.md Use the `MapLibreMap` widget to display a map in your Flutter application. The `onMapCreated` callback provides access to the `MapController` for programmatic control, and `onStyleLoaded` can be used for post-load setup. ```dart import 'package:flutter/material.dart'; import 'package:maplibre/maplibre.dart'; class MapScreen extends StatefulWidget { const MapScreen({super.key}); @override State createState() => FullMapState(); } class MapScreenState extends State { MapController? _mapController; @override Widget build(BuildContext context) { return Scaffold( body: MapLibreMap( onMapCreated: (controller) { // Store the map controller for later use. You can use it to control // the map programmatically. _mapController = controller; }, onStyleLoaded: (style) { // Add your sources and layers here or do any other setup after the // style has been loaded. debugPrint('Map loaded 😎'); }, ), ); } } ``` -------------------------------- ### Set Custom Map Style URL Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/styles.md Use a URL to specify a custom map style. The URL should start with http(s):// and point to a remotely served custom map style. ```dart Widget build() { return MapLibreMap( options: MapOptions( center: Geographic(lon: 9.17, lat: 47.68), style: 'https://demotiles.maplibre.org/style.json', ) ); } ``` -------------------------------- ### Get Specific Offline Region Details Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/offline.md Fetch the details of a single offline region using its unique ID. ```dart manager.getOfflineRegion(regionId: 1) ``` -------------------------------- ### Add maplibre_webview Dependency via Command Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/setup.md To enable experimental Windows and macOS support, add the maplibre_webview dependency using this command. ```bash flutter pub add maplibre_webview ``` -------------------------------- ### Link Libraries and Include Directories Source: https://github.com/josxha/flutter-maplibre/blob/main/examples/windows/runner/CMakeLists.txt Links necessary libraries (like `flutter`, `flutter_wrapper_app`, and `dwmapi.lib`) and sets include directories for the application. Add any application-specific dependencies here. ```cmake # Add dependency libraries and include directories. Add any application-specific # dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") ``` -------------------------------- ### Enable Swift Package Manager for iOS Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/setup.md Enable the Swift Package Manager for your iOS project by running this command. ```bash flutter config --enable-swift-package-manager ``` -------------------------------- ### Android, iOS, Web Architecture Diagram Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/architecture.md This diagram illustrates the native interop architecture for Android, iOS, and Web platforms, showing the flow from user implementation to native MapLibre code. ```mermaid flowchart TB subgraph User["User Implementation"] end subgraph Public["Public API"] MapLibreMap MapController StyleController end subgraph Widget["StatefulWidget"] MapLibreMapState end subgraph Interop["Platform Bindings"] MapLibreMapStateAndroid MapLibreMapStateIos MapLibreMapStateWeb end subgraph Native["Native Code"] Android["MapLibre Native Android"] iOS["MapLibre Native iOS"] Web["MapLibre GL JS"] end User --[invoke method]--> MapLibreMap MapLibreMap --[uses]--> MapLibreMapState MapController --[implemented by]--> MapLibreMapState StyleController --[implemented by]--> MapLibreMapState MapLibreMapState --[extends]--> MapLibreMapStateAndroid MapLibreMapState --[extends]--> MapLibreMapStateIos MapLibreMapState --[extends]--> MapLibreMapStateWeb MapLibreMapStateAndroid --[jni]--> Android MapLibreMapStateIos --[ffi]--> iOS MapLibreMapStateWeb --[interop]--> Web ``` -------------------------------- ### Apply Standard Build Settings Source: https://github.com/josxha/flutter-maplibre/blob/main/examples/windows/runner/CMakeLists.txt Applies a standard set of build settings to the executable target. This can be customized for applications with different build requirements. ```cmake # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) ``` -------------------------------- ### Basic WidgetLayer Usage Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/annotations/widgets.md Demonstrates how to add a WidgetLayer with a location marker to the map. Ensure the Marker's size matches the child widget's size and set the alignment appropriately. ```dart Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Widget Layer')), body: MapLibreMap( options: MapOptions( initZoom: 3, initCenter: Geographic(lon: 0, lat: 0), ), children: [ WidgetLayer( markers: [ Marker( // must be the same dimension as the inner widget size: const Size.square(50), // the longitude / latitude position on the map point: Geographic(lon: -10, lat: 0), // child can be any flutter widget tree child: const Icon( Icons.location_on, color: Colors.red, // must be the same as Marker.size size: 50, ), // the used Icon should be attached to the map at the bottom center alignment: Alignment.bottomCenter, ), ], ), // display the UI widgets above the widget markers. const SourceAttribution(), ], ), ); } ``` -------------------------------- ### Windows, MacOS (WebView) Architecture Diagram Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/architecture.md This diagram outlines the architecture for Windows and MacOS, which uses a WebView for rendering maps and communicates via the `flutter_inappwebview` package. ```mermaid flowchart TB subgraph User["User Implementation"] end subgraph Public["Public API"] MapLibreMap MapController StyleController end subgraph Widget["StatefulWidget"] MapLibreMapState end subgraph Interop["Platform Bindings"] MapLibreMapStateWebView flutter_inappwebview end subgraph Native["Native Code"] Web["MapLibre GL JS"] end User --[invoke method]--> MapLibreMap MapLibreMap --[uses]--> MapLibreMapState MapController --[implemented by]--> MapLibreMapState StyleController --[implemented by]--> MapLibreMapState MapLibreMapState --[extends]--> MapLibreMapStateWebView MapLibreMapStateWebView --[uses]--> flutter_inappwebview flutter_inappwebview --[method channel, ws]--> Web ``` -------------------------------- ### Basic Marker Layer Usage Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/annotations/markers.md Demonstrates how to add a basic MarkerLayer to a MapLibreMap. It includes adding a custom marker image and handling click events to add new markers. ```dart late final MapController _controller; @override Widget build(BuildContext context) { return MapLibreMap( options: MapOptions(center: Geographic(lon: 9.17, lat: 47.68)), onEvent: (event) async { switch (event) { case MapEventMapCreated(): _controller = event.mapController; case MapEventStyleLoaded(): // add marker image to map final response = await http.get(Uri.parse(LayersSymbolPage.imageUrl)); final bytes = response.bodyBytes; await _controller.addImage('marker', bytes); case MapEventClick(): // add a new marker on click setState(() { _points.add(Point(event.point)); }); default: // ignore all other events break; } }, layers: [ MarkerLayer( points: [ Point(Geographic(lon: 9.17, lat: 47.68)), Point(Geographic(lon: 9.17, lat: 48)), Point(Geographic(lon: 9, lat: 48)), Point(Geographic(lon: 9.5, lat: 48)), ], textField: 'Marker', textAllowOverlap: true, iconImage: 'marker', iconSize: 0.08, iconAnchor: IconAnchor.bottom, textOffset: const [0, 1], ), ], ); } ``` -------------------------------- ### Enable Swift Package Manager in pubspec.yaml Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/setup.md Alternatively, enable the Swift Package Manager for the current project by adding this configuration to your pubspec.yaml file. ```yaml flutter: config: enable-swift-package-manager: true ``` -------------------------------- ### Include MapLibre GL JS and CSS for Web Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/setup.md Add these script and link tags to the of your web/index.html file to include MapLibre GL JS and its CSS. ```html ``` -------------------------------- ### Basic Polyline Layer Usage Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/annotations/polylines.md Demonstrates how to add a basic PolylineLayer to a MapLibreMap. Configure color, width, blur, and dash patterns for the polyline. ```dart Widget build(BuildContext context) { return MapLibreMap( options: MapOptions(zoom: 7, center: Geographic(lon: 9.17, lat: 47.68)), layers: [ PolylineLayer( polylines: [ LineString( coordinates: [ Geographic(lon: 9.17, lat: 47.68), Geographic(lon: 9.5, lat: 48), Geographic(lon: 9, lat: 48), ], ), ], color: Colors.red, width: 4, blur: 3, dashArray: const [5, 5], ), ], ); } ``` -------------------------------- ### Create Static Wrapper Library for Plugins Source: https://github.com/josxha/flutter-maplibre/blob/main/examples/windows/flutter/CMakeLists.txt Builds a static library for C++ wrapper code used by Flutter plugins. It includes core and plugin-specific source files and links against the Flutter library. ```cmake add_library(flutter_wrapper_plugin STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ) apply_standard_settings(flutter_wrapper_plugin) set_target_properties(flutter_wrapper_plugin PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(flutter_wrapper_plugin PROPERTIES CXX_VISIBILITY_PRESET hidden) target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) target_include_directories(flutter_wrapper_plugin PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_plugin flutter_assemble) ``` -------------------------------- ### Run ffigen for MapLibre iOS Source: https://github.com/josxha/flutter-maplibre/blob/main/CONTRIBUTING.md Executes the ffigen tool to generate Dart bindings for the MapLibre iOS native library. This should be run from the maplibre_ios directory. ```bash cd maplibre_ios dart run tool/ffigen.dart ``` -------------------------------- ### Add UI Widgets to MapLibreMap Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/ui.md Demonstrates how to include various UI widgets like MapScalebar, SourceAttribution, MapControlButtons, and MapCompass within the `children` list of the `MapLibreMap` widget. ```dart MapLibreMap( // ... children: [ MapScalebar(), SourceAttribution(), MapControlButtons(), MapCompass(), ], ); ``` -------------------------------- ### Create Static Wrapper Library for Runner Source: https://github.com/josxha/flutter-maplibre/blob/main/examples/windows/flutter/CMakeLists.txt Builds a static library for C++ wrapper code used by the Flutter application runner. It includes core and application-specific source files and links against the Flutter library. ```cmake add_library(flutter_wrapper_app STATIC ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_APP} ) apply_standard_settings(flutter_wrapper_app) target_link_libraries(flutter_wrapper_app PUBLIC flutter) target_include_directories(flutter_wrapper_app PUBLIC "${WRAPPER_ROOT}/include" ) add_dependencies(flutter_wrapper_app flutter_assemble) ``` -------------------------------- ### Append API Key to Tile URL Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/styles.md When a tile source requires an API key, append it directly to the URL as a query parameter. ```url https://tiles.example.com/{z}/{x}/{y}.pbf?api_key={your_key} ``` -------------------------------- ### Listen to Style Load Events Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/usage.md Use the `onEvent` callback to listen for `MapEventStyleLoaded` and access the `StyleController` to add sources and layers after the style has loaded. ```dart class _MyMapWidget extends State { @override Widget build(BuildContext context) { return Scaffold( body: MapLibreMap( options: MapOptions(initCenter: Geographic(lon: 9.17, lat: 47.68), initZoom: 3), onEvent: (event) { // check if the MapEvent type is a MapEventStyleLoaded if (event case MapEventStyleLoaded()) { // This event gets emitted every time a style finishes loading. event.style.addSource(...); event.style.addLayer(...); } } ), ); } } ``` -------------------------------- ### Flutter Tool Backend Custom Command Source: https://github.com/josxha/flutter-maplibre/blob/main/examples/windows/flutter/CMakeLists.txt Configures a custom command to run the Flutter tool backend script. This command generates necessary Flutter libraries and headers, and it's set to run every time due to a phony output file. ```cmake set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) add_custom_command( OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ${CPP_WRAPPER_SOURCES_APP} ${PHONY_OUTPUT} COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" ${FLUTTER_TARGET_PLATFORM} $ VERBATIM ) ``` -------------------------------- ### Run jnigen Code Generation Source: https://github.com/josxha/flutter-maplibre/blob/main/CONTRIBUTING.md Executes the jnigen script to generate native code. This script runs 'dart run jnigen --config jnigen.yaml' and applies manual fixes. ```bash ./run_jnigen.sh ``` -------------------------------- ### Define Executable Target Source: https://github.com/josxha/flutter-maplibre/blob/main/examples/windows/runner/CMakeLists.txt Defines the main executable for the Windows application. Source files and resources are listed here. Ensure BINARY_NAME is consistent with the top-level CMakeLists.txt for `flutter run` compatibility. ```cmake cmake_minimum_required(VERSION 3.14) project(runner LANGUAGES CXX) # Define the application target. To change its name, change BINARY_NAME in the # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer # work. # # Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} WIN32 "flutter_window.cpp" "main.cpp" "utils.cpp" "win32_window.cpp" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" "Runner.rc" "runner.exe.manifest" ) ``` -------------------------------- ### Add MapLibre from GitHub in pubspec.yaml Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/setup.md To use the development version from GitHub, specify the git URL and a reference (branch or commit hash) in your pubspec.yaml. ```yaml dependencies: maplibre: git: url: https://github.com/josxha/flutter-maplibre ref: main # or a specific commit hash ``` -------------------------------- ### Create OfflineManager Instance Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/offline.md Instantiate the OfflineManager asynchronously. Store the instance for later use. ```dart Future futureManager = OfflineManager.createInstance(); ``` -------------------------------- ### Configure Kotlin Version in settings.gradle Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/setup.md Ensure your Android project uses a compatible Kotlin version (1.9.0 or newer) by setting it in android/settings.gradle. ```gradle plugins { // ... id "org.jetbrains.kotlin.android" version "1.9.0" apply false } ``` -------------------------------- ### Configure Kotlin Version in build.gradle Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/setup.md If your app uses the old apply script method, set the Kotlin version in android/app/build.gradle. ```gradle buildscript { ext.kotlin_version = '1.9.0' // ... } ``` -------------------------------- ### Generate Swift Headers for MapLibre iOS Source: https://github.com/josxha/flutter-maplibre/blob/main/CONTRIBUTING.md Generates Objective-C headers for the native Swift layer of the MapLibre iOS library. This is a prerequisite for ffigen. ```bash (cd maplibre_ios/ios/maplibre_ios/Sources/maplibre_ios && ./gen_swift_headers.sh) ``` -------------------------------- ### Add maplibre_webview Dependency in pubspec.yaml Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/setup.md Add the maplibre_webview dependency to your pubspec.yaml file to enable Windows and macOS support. ```yaml dependencies: maplibre: ^0.3.4 maplibre_webview: ^0.3.4 ``` -------------------------------- ### Clone and Build MapLibre Native for iOS Source: https://github.com/josxha/flutter-maplibre/blob/main/CONTRIBUTING.md Clones the maplibre-native repository and builds it for iOS with debugging symbols. This is an optional step for debugging native code. ```bash git clone https://github.com/maplibre/maplibre-native \ --filter=blob:none \ --no-checkout \ ../maplibre-native cd ../maplibre-native git checkout ios-v6.19.2 git submodule update --init --recursive --depth 1 ``` ```bash cd maplibre_ios/ios ./build_maplibre.sh ``` -------------------------------- ### Add MapLibre Dependency via Command Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/setup.md Use this command to add the maplibre package to your Flutter project. ```bash flutter pub add maplibre ``` -------------------------------- ### Add Build Version Preprocessor Definitions Source: https://github.com/josxha/flutter-maplibre/blob/main/examples/windows/runner/CMakeLists.txt Adds preprocessor definitions for the Flutter build version. This allows the application to access version information during compilation. ```cmake # Add preprocessor definitions for the build version. target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") ``` -------------------------------- ### Add Basic CircleLayer Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/annotations/circles.md Use CircleLayer to add circles to the map. Customize appearance with color, radius, strokeColor, and strokeWidth. ```dart @override Widget build(BuildContext context) { return MapLibreMap( options: MapOptions(center: Geographic(lon: 9.17, lat: 47.68)), layers: [ CircleLayer( points: [ Point(Geographic(lon: 9.17, lat: 47.68)), Point(Geographic(lon: 9.17, lat: 48)), Point(Geographic(lon: 9, lat: 48)), Point(Geographic(lon: 9.5, lat: 48)), ], color: Colors.orange.withOpacity(0.5), radius: 20, strokeColor: Colors.red, strokeWidth: 2, ), ], ); } ``` -------------------------------- ### Configure Flutter Library Interface Source: https://github.com/josxha/flutter-maplibre/blob/main/examples/windows/flutter/CMakeLists.txt Defines an INTERFACE library for Flutter, specifying include directories and linking against the Flutter library. This is used to integrate the Flutter engine into the project. ```cmake list(APPEND FLUTTER_LIBRARY_HEADERS "flutter_export.h" "flutter_windows.h" "flutter_messenger.h" "flutter_plugin_registrar.h" "flutter_texture_registrar.h" ) list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}" ) target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") add_dependencies(flutter flutter_assemble) ``` -------------------------------- ### Programmatic Control of MapLibreMap Widget Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/usage.md Update the `MapLibreMap` widget declaratively by using a `StatefulWidget` and calling `setState()`. Parameters not prefixed with `init*` can be updated this way. ```dart @immutable class MyMapWidget extends StatefulWidget { const MyMapWidget({super.key}); @override State createState() => _MyMapWidget(); } class _MyMapWidget extends State { // Using this field to store the widget state bool _gesturesEnabed = true; @override Widget build(BuildContext context) { return Scaffold( body: MapLibreMap( options: MapOptions( // parameters that start with init* can't be updated initCenter: Geographic(lon: 9.17, lat: 47.68), initZoom: 3, // other parameters can be updated gestures: _gesturesEnabled ? MapGestures.all() : MapGestures.none(), ), onEvent: (event) { if (event case MapEventClick()) { // update the map widget using Flutters' state management setState() { _gesturesEnabed = !_gesturesEnabed; } } } ), ); } } ``` -------------------------------- ### Add Flutter Assemble Dependency Source: https://github.com/josxha/flutter-maplibre/blob/main/examples/windows/runner/CMakeLists.txt Ensures that the Flutter tool's assembly process is completed before the application target is built. This is a required step for Flutter builds. ```cmake # Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) ``` -------------------------------- ### Download Map Region for Offline Use Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/offline.md Download a specific map region for offline access, specifying zoom levels, bounds, map style, and pixel density. The download progress is streamed. ```dart Future downloadMyMap() async { final stream = await manager.downloadRegion( minZoom: 10, maxZoom: 14, bounds: LngLatBounds(/* ... */), mapStyleUrl: '...', pixelDensity: 1, ); await for (final update in stream) { if (update.downloadCompleted) { print('region downloaded: ${update.region}'); } else { print( '${update.loadedTiles} / ${update.totalTiles} ' '(${((update.progress ?? 0) * 100).toStringAsFixed(0)}%)', ); } } } ``` -------------------------------- ### Add a Symbol Style Layer Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/style-layers/symbol-layer.md This snippet demonstrates how to add a SymbolStyleLayer to a MapLibreMap. It involves loading an image, adding it to the map's style, creating a GeoJSON source with points, and then adding the SymbolStyleLayer to display the image at the specified points. ```dart late final MapController _controller; @override Widget build(BuildContext context) { return MapLibreMap( options: MapOptions(center: Geographic(lon: 9.17, lat: 47.68)), onMapCreated: (controller) => _controller = controller, onStyleLoaded: (style) async { // load the image data final response = await http.get(Uri.parse(StyleLayersSymbolPage.imageUrl)); final bytes = response.bodyBytes; // add the image to the map await style.addImage('marker', bytes); // add some points as GeoJSON source to the map await style.addSource( const GeoJsonSource( id: 'points', data: _geoJsonString, ), ); // display the image on the map await style.addLayer( const SymbolStyleLayer( id: 'images', sourceId: 'points', layout: { // see https://maplibre.org/maplibre-style-spec/layers/#symbol 'icon-image': 'marker', 'icon-size': 0.08, 'icon-anchor': 'bottom', }, ), ); } ); } ``` -------------------------------- ### Add MapLibre Dependency in pubspec.yaml Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/setup.md Alternatively, add the maplibre package directly to your pubspec.yaml file under dependencies. ```yaml dependencies: maplibre: ^0.3.0 ``` -------------------------------- ### Add Basic Polygon Layer Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/annotations/polygons.md Use PolygonLayer to add polygons to the map. Define the polygon's coordinates and styling properties like color and outlineColor. ```dart MapLibreMap( options: MapOptions(zoom: 7, center: Geographic(lon: 9.17, lat: 47.68)), layers: [ PolygonLayer( polygons: [ Polygon( coordinates: [ [ Geographic(lon: 8.201306116882563, lat: 48.107357488669464), Geographic(lon: 8.885254895692924, lat: 48.09428546381665), Geographic(lon: 8.759684141159909, lat: 47.69326800157776), Geographic(lon: 9.631980099303235, lat: 48.08929468133098), Geographic(lon: 8.68543348810175, lat: 48.45383566718806), Geographic(lon: 8.201306116882563, lat: 48.107357488669464), ], ], ), ], color: Colors.lightBlueAccent.withOpacity(0.6), outlineColor: Colors.blue, ), ], ) ``` -------------------------------- ### Set Location Permissions in AndroidManifest.xml Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/setup.md Add ACCESS_COARSE_LOCATION and optionally ACCESS_FINE_LOCATION permissions to your AndroidManifest.xml to enable location tracking on the map. ```xml ... ``` -------------------------------- ### Accessing MapController via onEvent Callback Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/usage.md Obtain the `MapController` by listening for the `MapEventMapCreated` event within the `onEvent` callback of the `MapLibreMap` widget. This controller can then be stored for later programmatic control of the map. ```dart class _MyMapWidget extends State { MapController? _mapController; @override Widget build(BuildContext context) { return Scaffold( body: MapLibreMap( options: MapOptions(initCenter: Geographic(lon: 9.17, lat: 47.68), initZoom: 3), onEvent: (event) { // check if the MapEvent type is a MapEventMapCreated if (event case MapEventMapCreated()) { // store the MapController for later use _mapController = event.mapController; } } ), ); } } ``` -------------------------------- ### Listen to Map Events Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/events.md Implement the `onEvent` callback in `MapLibreMap` options to receive map events. Inside the callback, check the event type using `is` for specific events like `MapEventClicked` or use a `switch` statement to handle multiple event types. ```dart Widget build(BuildContext context) { return MapLibreMap( options: MapOptions(center: Geographic(lon: 9.17, lat: 47.68)), onEvent: _onEvent, ); } void _onEvent(event) { print(event.runtimeType); // check for the event type if (event is MapEventClicked) { print('The map has been clicked at ${event.point.lng}, ${event.point.lat}'); } // or use a switch statement to listen to all the events you are interested in switch (event) { case MapEventMapCreated(): print('map created'); case MapEventStyleLoaded(): print('style loaded'); default: // ignore all other events } } ``` -------------------------------- ### Add Raster Source and Layer Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/style-layers/raster-layer.md This snippet demonstrates how to add a raster source with OpenStreetMap tiles and a corresponding raster style layer to the map. It's used when you need to display tile-based map data. ```dart late final MapController _controller; @override Widget build(BuildContext context) { return MapLibreMap( options: MapOptions(center: Geographic(lon: 9.17, lat: 47.68)), onMapCreated: (controller) => _controller = controller, onStyleLoaded: (style) async { const openStreetMap = RasterSource( id: _sourceId, tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'], maxZoom: 20, tileSize: 256, attribution: 'OpenStreetMap', ); await style.addSource(openStreetMap); const layer = RasterStyleLayer( id: _layerId, sourceId: _sourceId, ); await style.addLayer(layer); } ); } ``` -------------------------------- ### Add a Fill Layer with GeoJSON Data Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/style-layers/fill-layer.md This snippet demonstrates how to add a FillStyleLayer to the map. It loads GeoJSON data for a polygon and then adds a FillStyleLayer with a specified source ID and fill color. ```dart late final MapController _controller; @override Widget build(BuildContext context) { return MapLibreMap( options: MapOptions(center: Geographic(lon: 9.17, lat: 47.68)), onMapCreated: (controller) => _controller = controller, onStyleLoaded: (style) async { final geojsonPolygon = await rootBundle.loadString('assets/geojson/lake-constance.json'); await style.addSource( GeoJsonSource(id: 'LakeConstance', data: geojsonPolygon), ); await style.addLayer( const FillStyleLayer( id: 'geojson-fill', sourceId: 'LakeConstance', paint: {'fill-color': '#429ef5'}, ), ); } ); } ``` -------------------------------- ### List All Offline Regions Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/offline.md Retrieve a list of all previously downloaded offline map regions. ```dart manager.listOfflineRegions() ``` -------------------------------- ### Add Fill Extrusion Layer to Map Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/style-layers/fill-extrusion-layer.md This snippet demonstrates how to add a GeoJSON source and a FillExtrusionStyleLayer to a MapLibreMap. It configures the layer's appearance using data expressions for color, height, and base, and sets a fixed opacity. Ensure the GeoJSON data contains properties like 'color', 'height', and 'base_height' for the expressions to work correctly. ```dart late final MapController _controller; @override Widget build(BuildContext context) { return MapLibreMap( options: MapOptions(center: Geographic(lon: 9.17, lat: 47.68)), onMapCreated: (controller) => _controller = controller, onStyleLoaded: (style) async { // add the tile source await style.addSource( const GeoJsonSource( id: _sourceId, data: 'https://maplibre.org/maplibre-gl-js/docs/assets/indoor-3d-map.geojson', ), ); const layer = FillExtrusionStyleLayer( id: 'room-extrusion', sourceId: _sourceId, paint: { // See the MapLibre Style Specification for details on data expressions. // https://maplibre.org/maplibre-style-spec/expressions/ 'fill-extrusion-color': ['get', 'color'], 'fill-extrusion-height': ['get', 'height'], 'fill-extrusion-base': ['get', 'base_height'], 'fill-extrusion-opacity': 0.5 }, ); // add the layer await style.addLayer(layer); } ); } ``` -------------------------------- ### Add Line Layer to Map Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/style-layers/line-layer.md This snippet demonstrates how to add a LineStyleLayer to the map. It loads GeoJSON data and adds it as a source, then adds the line layer with specified paint properties. ```dart late final MapController _controller; @override Widget build(BuildContext context) { return MapLibreMap( options: MapOptions(center: Geographic(lon: 9.17, lat: 47.68)), onMapCreated: (controller) => _controller = controller, onStyleLoaded: (style) async { final geojsonLine = await rootBundle.loadString('assets/geojson/path.json'); await style.addSource( GeoJsonSource(id: 'Path', data: geojsonLine), ); await style.addLayer( const LineStyleLayer( id: 'geojson-line', sourceId: 'Path', paint: {'line-color': '#F00', 'line-width': 3}, ), ); } ); } ``` -------------------------------- ### Access StyleController via MapController Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/getting-started/usage.md Access the `StyleController` using the `style` getter on the `MapController`. Modifications are only possible after the style has loaded; the getter returns null if the style is not yet loaded. ```dart MapController? _mapController; void doSomething() { // only adds the source if the style has finished loading and a source can be added. _mapController?.style?.addSource(...); } ``` -------------------------------- ### Set Flutter Target Platform Fallback Source: https://github.com/josxha/flutter-maplibre/blob/main/examples/windows/flutter/CMakeLists.txt Sets a fallback value for FLUTTER_TARGET_PLATFORM if it's not already defined. This ensures a default platform is used when the Flutter tool doesn't provide one. ```cmake if (NOT DEFINED FLUTTER_TARGET_PLATFORM) set(FLUTTER_TARGET_PLATFORM "windows-x64") endif() ``` -------------------------------- ### Add Heatmap Layer to Map Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/style-layers/heatmap-layer.md This snippet demonstrates how to add a HeatmapStyleLayer to a MapLibreMap. It first adds a GeoJsonSource and then the HeatmapStyleLayer referencing that source. Ensure the source data is loaded before adding the layer. ```dart late final MapController _controller; @override Widget build(BuildContext context) { return MapLibreMap( options: MapOptions(center: Geographic(lon: 9.17, lat: 47.68)), onMapCreated: (controller) => _controller = controller, onStyleLoaded: (style) async { const earthquakes = GeoJsonSource( id: _sourceId, data: 'https://maplibre.org/maplibre-gl-js/docs/assets/earthquakes.geojson', ); await style.addSource(earthquakes); const layer = HeatmapStyleLayer(id: _layerId, sourceId: _sourceId); await style.addLayer(layer); } ); } ``` -------------------------------- ### Update MapLibre GL JS in web/index.html Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/migrate/upgrade-from-v0.1.x.md Update the MapLibre GL JS library version to 5.0.0 or higher in your web application's index.html file. ```html ``` -------------------------------- ### Flutter Assemble Custom Target Source: https://github.com/josxha/flutter-maplibre/blob/main/examples/windows/flutter/CMakeLists.txt Defines a custom target 'flutter_assemble' that depends on the output of the Flutter tool backend. This target ensures that all necessary Flutter artifacts are built before other dependent targets. ```cmake add_custom_target(flutter_assemble DEPENDS "${FLUTTER_LIBRARY}" ${FLUTTER_LIBRARY_HEADERS} ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} ${CPP_WRAPPER_SOURCES_APP} ) ``` -------------------------------- ### Add Circle Style Layer to Map Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/style-layers/circle-layer.md This snippet demonstrates how to add a CircleStyleLayer to a MapLibreMap. It first adds a GeoJsonSource and then associates a CircleStyleLayer with that source. ```dart late final MapController _controller; @override Widget build(BuildContext context) { return MapLibreMap( options: MapOptions(center: Geographic(lon: 9.17, lat: 47.68)), onMapCreated: (controller) => _controller = controller, onStyleLoaded: (style) async { // add the source const earthquakes = GeoJsonSource( id: _sourceId, data: 'https://maplibre.org/maplibre-gl-js/docs/assets/earthquakes.geojson', ); await style.addSource(earthquakes); // add the source with a layer on the map const layer = CircleStyleLayer(id: _layerId, sourceId: _sourceId); await style.addLayer(layer); } ); } ``` -------------------------------- ### Merge Offline Regions Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/offline.md Consolidate offline regions from a secondary MapLibre Native database into the main offline database. ```dart manager.mergeOfflineRegions(path: 'path/to/database') ``` -------------------------------- ### Dispose OfflineManager Instance Source: https://github.com/josxha/flutter-maplibre/blob/main/website/docs/offline.md Call manager.dispose() when the OfflineManager is no longer needed, typically in a widget's dispose method. ```dart @override void dispose() { manager.dispose(); super.dispose(); } ```