From e847fdf8df85c546df24879956ec512c8bfd2270 Mon Sep 17 00:00:00 2001
From: Joscha <34318751+josxha@users.noreply.github.com>
Date: Fri, 20 Sep 2024 23:53:22 +0200
Subject: [PATCH] feat: add event system (#34)
## Implementation
- [x] android integration
- [x] web integration
- [x] public API
- [x] example app
- [x] changelog
- [x] update docs
## Events
- [x] map created
- [x] style loaded
- [x] clicked
- [x] long clicked
- [x] secondary clicked
- [x] double clicked
- [x] camera changed
More events can be added later.
## Resources
-
https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/MapEventType/
-
https://maplibre.org/maplibre-native/android/api/-map-libre%20-native%20-android/org.maplibre.android.maps/-map-view/index.html
---
CHANGELOG.md | 7 +-
README.md | 76 +++++++++++---
analysis_options.yaml | 2 +-
android/build.gradle | 2 +-
.../josxha/maplibre/MapLibreMapController.kt | 30 +++---
.../com/github/josxha/maplibre/Pigeon.g.kt | 18 ++++
docs/docs/features/_category_.json | 8 --
docs/docs/getting-started/add-dependency.md | 5 +-
docs/docs/getting-started/use-widget.md | 2 +-
docs/docs/index.md | 6 +-
docs/docs/layers/_category_.json | 8 ++
docs/docs/layers/circle-layer.md | 60 +++++++++++
docs/docs/layers/fill-extrusion-layer.md | 31 ++++++
docs/docs/layers/fill-layer.md | 31 ++++++
docs/docs/layers/heatmap-layer.md | 31 ++++++
docs/docs/layers/hillshade-layer.md | 31 ++++++
docs/docs/layers/line-layer.md | 31 ++++++
docs/docs/layers/raster-layer.md | 31 ++++++
docs/docs/layers/symbol-layer.md | 31 ++++++
docs/docs/map-events.md | 94 ++++++++++++++++++
.../docs/{features => }/supported-features.md | 4 +-
docs/docusaurus.config.ts | 4 +-
docs/{docs => static}/img/first_map.jpg | Bin
docs/static/img/layers/circle_layer.jpg | Bin 0 -> 157054 bytes
.../img/layers/fill_extrusion_layer.jpg | Bin 0 -> 503372 bytes
docs/static/img/layers/fill_layer.jpg | Bin 0 -> 144198 bytes
docs/static/img/layers/heatmap_layer.jpg | Bin 0 -> 386890 bytes
docs/static/img/layers/hillshade_layer.jpg | Bin 0 -> 775252 bytes
docs/static/img/layers/line_layer.jpg | Bin 0 -> 116294 bytes
docs/static/img/layers/raster_layer.jpg | Bin 0 -> 811424 bytes
docs/static/img/layers/symbol_layer.jpg | Bin 0 -> 430637 bytes
example/analysis_options.yaml | 2 +-
example/lib/callbacks_page.dart | 11 +-
example/lib/events_page.dart | 65 ++++++++++++
example/lib/main.dart | 2 +
example/lib/menu_page.dart | 6 ++
ios/Classes/Pigeon.g.swift | 21 ++++
lib/maplibre.dart | 1 +
lib/src/map.dart | 7 ++
lib/src/map_events.dart | 67 +++++++++++++
lib/src/map_options.dart | 13 ++-
lib/src/native/pigeon.g.dart | 32 ++++++
lib/src/native/widget_state.dart | 53 ++++++++--
lib/src/web/interop/events.dart | 4 +
lib/src/web/widget_state.dart | 79 +++++++++------
linux/pigeon.g.cc | 79 +++++++++++++++
linux/pigeon.g.h | 66 ++++++++++++
macos/Classes/Pigeon.g.swift | 21 ++++
pigeons/pigeon.dart | 3 +
windows/runner/pigeon.g.cpp | 25 +++++
windows/runner/pigeon.g.h | 5 +
51 files changed, 995 insertions(+), 110 deletions(-)
delete mode 100644 docs/docs/features/_category_.json
create mode 100644 docs/docs/layers/_category_.json
create mode 100644 docs/docs/layers/circle-layer.md
create mode 100644 docs/docs/layers/fill-extrusion-layer.md
create mode 100644 docs/docs/layers/fill-layer.md
create mode 100644 docs/docs/layers/heatmap-layer.md
create mode 100644 docs/docs/layers/hillshade-layer.md
create mode 100644 docs/docs/layers/line-layer.md
create mode 100644 docs/docs/layers/raster-layer.md
create mode 100644 docs/docs/layers/symbol-layer.md
create mode 100644 docs/docs/map-events.md
rename docs/docs/{features => }/supported-features.md (97%)
rename docs/{docs => static}/img/first_map.jpg (100%)
create mode 100644 docs/static/img/layers/circle_layer.jpg
create mode 100644 docs/static/img/layers/fill_extrusion_layer.jpg
create mode 100644 docs/static/img/layers/fill_layer.jpg
create mode 100644 docs/static/img/layers/heatmap_layer.jpg
create mode 100644 docs/static/img/layers/hillshade_layer.jpg
create mode 100644 docs/static/img/layers/line_layer.jpg
create mode 100644 docs/static/img/layers/raster_layer.jpg
create mode 100644 docs/static/img/layers/symbol_layer.jpg
create mode 100644 example/lib/events_page.dart
create mode 100644 lib/src/map_events.dart
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55ba3fcc..2999f7c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,15 +2,16 @@
### Features
-- Add sources and layers to the map programmatically.
-- Remove sources and layers from the map programmatically.
+- Add event system to the map.
+- Add and remove sources to the active map style programmatically.
+- Add and remove layers to the active map style programmatically.
- Add `duration` parameter to `flyTo()`.
- `flyTo()` returns after the animation completes or throws an exception if it
has been cancelled.
### Bug fixes
-- Fix `jumpTo()` never returns
+- Fix `jumpTo()` never returns on Android.
## 0.0.1+1
diff --git a/README.md b/README.md
index 7fdcd2fb..e429eada 100644
--- a/README.md
+++ b/README.md
@@ -17,22 +17,66 @@ This package provides unofficial Flutter bindings for MapLibre SDKs.
named maplibre-gl) is used for android and in the future for iOS,
windows, macOS and Linux
-MapLibre is a permissive and open source solution for the MVT
-(Mapbox Vector Tile) standard. By binding to native SDKs the package
-accomplishes performant rendering while supporting a lot of complex
+MapLibre is a permissive and open source solution for the MVT
+(Mapbox Vector Tile) standard. By binding to native SDKs the package
+accomplishes performant rendering while supporting a lot of complex
functionality.
-
-Use custom styles for your map |
-Tilt or rotate your map |
-
-
-
- |
- |
-
-
+
+
+
+ Use custom vector styles
+
+ |
+
+ Tilt or rotate the map
+
+ |
+
+ Use raster tiles
+
+ |
+
+
+
+ Add circles
+
+ |
+
+ Add 3D building outlines
+
+ |
+
+ Add polygons
+
+ |
+
+
+
+ Add heatmaps
+
+ |
+
+ Render elevation
+
+ |
+
+ Add lines
+
+ |
+
+
+
+ Add markers
+
+ |
+
+ |
+
+ |
+
+
## Resources
@@ -56,7 +100,7 @@ the [API docs](https://pub.dev/documentation/maplibre/latest/maplibre/maplibre-l
This package is still a young package and in an early stage.
While it offers a modern implementation, it currently lacks some
-functionality. [See our documentation to learn more.](https://flutter-maplibre.pages.dev/docs/features/supported-features)
+functionality. [See our documentation to learn more.](https://flutter-maplibre.pages.dev/docs/supported-features)
## Development & Contributing
@@ -65,10 +109,10 @@ welcome.
#### Run Code Generation
-We use code generation from [pigeon](https://pub.dev/packages/pigeon).
+We use code generation from [pigeon](https://pub.dev/packages/pigeon).
If you change the file [pigeons/pigeon.dart](pigeons/pigeon.dart) you'll have
to run the code generator.
-Use the generator script in the [./pigeons](./pigeons) directory (or run the
+Use the generator script in the [./pigeons](./pigeons) directory (or run the
commands manually) to generate the necessary code.
#### Test with WebAssembly
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 16c10983..73af3bc2 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -8,4 +8,4 @@ linter:
rules:
lines_longer_than_80_chars: false
flutter_style_todos: false
- cascade_invocations: false
\ No newline at end of file
+ cascade_invocations: false
diff --git a/android/build.gradle b/android/build.gradle
index c2463e58..c1e2e58e 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -9,7 +9,7 @@ buildscript {
}
dependencies {
- classpath("com.android.tools.build:gradle:8.6.1")
+ classpath("com.android.tools.build:gradle:7.3.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
}
}
diff --git a/android/src/main/kotlin/com/github/josxha/maplibre/MapLibreMapController.kt b/android/src/main/kotlin/com/github/josxha/maplibre/MapLibreMapController.kt
index 5897f3b2..074e07d5 100644
--- a/android/src/main/kotlin/com/github/josxha/maplibre/MapLibreMapController.kt
+++ b/android/src/main/kotlin/com/github/josxha/maplibre/MapLibreMapController.kt
@@ -58,8 +58,7 @@ class MapLibreMapController(
private val context: Context,
private val lifecycleProvider: LifecycleProvider,
binaryMessenger: BinaryMessenger
-) : PlatformView, DefaultLifecycleObserver, OnMapReadyCallback, MapLibreHostApi,
- MapLibreMap.OnMapClickListener, MapLibreMap.OnMapLongClickListener {
+) : PlatformView, DefaultLifecycleObserver, OnMapReadyCallback, MapLibreHostApi {
private val mapViewContainer = FrameLayout(context)
private lateinit var mapLibreMap: MapLibreMap
private lateinit var mapView: MapView
@@ -105,10 +104,23 @@ class MapLibreMapController(
override fun onMapReady(mapLibreMap: MapLibreMap) {
this.mapLibreMap = mapLibreMap
if (initialOptions.listensOnClick) {
- this.mapLibreMap.addOnMapClickListener(this)
+ this.mapLibreMap.addOnMapClickListener { latLng ->
+ flutterApi.onClick(LngLat(latLng.longitude, latLng.latitude)) { }
+ true
+ }
}
if (initialOptions.listensOnLongClick) {
- this.mapLibreMap.addOnMapLongClickListener(this)
+ this.mapLibreMap.addOnMapLongClickListener { latLng ->
+ flutterApi.onLongClick(LngLat(latLng.longitude, latLng.latitude)) { }
+ true
+ }
+ }
+ this.mapLibreMap.addOnCameraMoveListener {
+ val position = mapLibreMap.cameraPosition
+ val target = mapLibreMap.cameraPosition.target!!
+ val center = LngLat(target.longitude, target.latitude)
+ val camera = MapCamera(center, position.zoom, position.tilt, position.bearing)
+ flutterApi.onCameraMoved(camera) {}
}
val style = Style.Builder().fromUri(initialOptions.style)
mapLibreMap.setStyle(style) { loadedStyle ->
@@ -512,14 +524,4 @@ class MapLibreMapController(
override fun getMetersPerPixelAtLatitude(latitude: Double): Double =
mapLibreMap.projection.getMetersPerPixelAtLatitude(latitude)
-
- override fun onMapClick(point: LatLng): Boolean {
- flutterApi.onClick(LngLat(point.longitude, point.latitude)) { }
- return true
- }
-
- override fun onMapLongClick(point: LatLng): Boolean {
- flutterApi.onLongClick(LngLat(point.longitude, point.latitude)) { }
- return true
- }
}
\ No newline at end of file
diff --git a/android/src/main/kotlin/com/github/josxha/maplibre/Pigeon.g.kt b/android/src/main/kotlin/com/github/josxha/maplibre/Pigeon.g.kt
index b9bde775..91f03734 100644
--- a/android/src/main/kotlin/com/github/josxha/maplibre/Pigeon.g.kt
+++ b/android/src/main/kotlin/com/github/josxha/maplibre/Pigeon.g.kt
@@ -1088,4 +1088,22 @@ class MapLibreFlutterApi(private val binaryMessenger: BinaryMessenger, private v
}
}
}
+ /** Callback when the map camera changes. */
+ fun onCameraMoved(cameraArg: MapCamera, callback: (Result) -> Unit)
+{
+ val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
+ val channelName = "dev.flutter.pigeon.maplibre.MapLibreFlutterApi.onCameraMoved$separatedMessageChannelSuffix"
+ val channel = BasicMessageChannel(binaryMessenger, channelName, codec)
+ channel.send(listOf(cameraArg)) {
+ if (it is List<*>) {
+ if (it.size > 1) {
+ callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
+ } else {
+ callback(Result.success(Unit))
+ }
+ } else {
+ callback(Result.failure(createConnectionError(channelName)))
+ }
+ }
+ }
}
diff --git a/docs/docs/features/_category_.json b/docs/docs/features/_category_.json
deleted file mode 100644
index ff173cc6..00000000
--- a/docs/docs/features/_category_.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "label": "Features",
- "position": 4,
- "link": {
- "type": "generated-index",
- "description": "Dive in to the features MapLibre for Flutter provides."
- }
-}
diff --git a/docs/docs/getting-started/add-dependency.md b/docs/docs/getting-started/add-dependency.md
index 10b9fb70..2712d71d 100644
--- a/docs/docs/getting-started/add-dependency.md
+++ b/docs/docs/getting-started/add-dependency.md
@@ -4,6 +4,8 @@ sidebar_position: 1
# Add Dependency
+## Use the package from pub.dev
+
Add `maplibre` to your project by running this command:
```bash
@@ -42,9 +44,10 @@ list.
```yaml title="pubspec.yaml"
dependencies:
- # highlight-next-line
+ # highlight-start
maplibre:
git:
url: https://github.com/josxha/flutter-maplibre
ref: main # or a specific commit hash
+ # highlight-end
```
diff --git a/docs/docs/getting-started/use-widget.md b/docs/docs/getting-started/use-widget.md
index 062da7cd..7ace2573 100644
--- a/docs/docs/getting-started/use-widget.md
+++ b/docs/docs/getting-started/use-widget.md
@@ -44,7 +44,7 @@ class MapScreenState extends State {
The result should look something like this:
-![First map](../img/first_map.jpg)
+![First map](/img/first_map.jpg)
If the map style isn't specified, the default MapLibre style is used. Use the
style of a tile provider or create and use your own map style.
\ No newline at end of file
diff --git a/docs/docs/index.md b/docs/docs/index.md
index c060a095..2f42246d 100644
--- a/docs/docs/index.md
+++ b/docs/docs/index.md
@@ -8,5 +8,7 @@ This is the documentation for the unofficial MapLibre Flutter package.
flutter-maplibre provides bindings to MapLibre Native and MapLibre-GL-JS.
-- [Getting started](getting-started/add-dependency)
-- [Map Styles](map-styles)
+- [Getting started](./getting-started/add-dependency)
+- [Map Styles](./map-styles)
+- [Map Layers](./category/layers)
+- [Map Events](./map-events)
diff --git a/docs/docs/layers/_category_.json b/docs/docs/layers/_category_.json
new file mode 100644
index 00000000..7ea4a043
--- /dev/null
+++ b/docs/docs/layers/_category_.json
@@ -0,0 +1,8 @@
+{
+ "label": "Layers",
+ "position": 5,
+ "link": {
+ "type": "generated-index",
+ "description": "Add or remove layers from the active map style."
+ }
+}
diff --git a/docs/docs/layers/circle-layer.md b/docs/docs/layers/circle-layer.md
new file mode 100644
index 00000000..b57584c3
--- /dev/null
+++ b/docs/docs/layers/circle-layer.md
@@ -0,0 +1,60 @@
+---
+sidebar_position: 1
+description: 'Add Circles to the map.'
+---
+
+# Circle Layer
+
+The `CircleLayer` is either used by the map style or can be added to the map
+programmatically to symbolize data on the map.
+
+[![Circle Layer](/img/layers/circle_layer.jpg)](/demo/#/layers/circle)
+
+## Basic Usage
+
+```dart
+late final MapController _controller;
+
+@override
+Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(title: const Text('Events')),
+ body: MapLibreMap(
+ options: MapOptions(center: Position(9.17, 47.68)),
+ onMapCreated: (controller) => _controller = controller,
+ onStyleLoaded: () async {
+ // highlight-start
+ // add the source
+ const earthquakes = GeoJsonSource(
+ id: _sourceId,
+ data:
+ 'https://maplibre.org/maplibre-gl-js/docs/assets/earthquakes.geojson',
+ );
+ await _controller.addSource(earthquakes);
+
+ // add the source with a layer on the map
+ const circleLayer = CircleLayer(id: _layerId, sourceId: _sourceId);
+ await _controller.addLayer(circleLayer);
+ // highlight-end
+ }
+ ),
+ );
+}
+```
+
+Check out
+the [example app](https://github.com/josxha/flutter-maplibre/blob/main/example/lib/layers_circle_page.dart)
+for to learn more.
+
+## Style
+
+Use the `paint` property to style your `CircleLayer` to change the style of the
+map.
+
+See
+the [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/layers/#circle)
+for all available properties.
+
+## Layout
+
+Use the `layout` property to change how the circles behave on the map.
\ No newline at end of file
diff --git a/docs/docs/layers/fill-extrusion-layer.md b/docs/docs/layers/fill-extrusion-layer.md
new file mode 100644
index 00000000..a44be504
--- /dev/null
+++ b/docs/docs/layers/fill-extrusion-layer.md
@@ -0,0 +1,31 @@
+---
+sidebar_position: 1
+description: 'Add 3D building outlines to the map.'
+---
+
+# Fill Extrusion Layer
+
+The `FillExtrusionLayer` is either used by the map style or can be added to the
+map programmatically to symbolize data on the map.
+
+[![Fill Extrusion Layer](/img/layers/fill_extrusion_layer.jpg)](/demo/#/layers/fill-extrusion)
+
+## Basic Usage
+
+Check out
+the [example app](https://github.com/josxha/flutter-maplibre/blob/main/example/lib/layers_fill_extrusion_page.dart)
+to learn more.
+
+## Style
+
+Use the `paint` property to style your `FillExtrusionLayer` to change the style
+of the map.
+
+See
+the [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/layers/#fill-extrusion)
+for all available properties.
+
+## Layout
+
+Use the `layout` property to change how the
+fill extrusions behave on the map.
\ No newline at end of file
diff --git a/docs/docs/layers/fill-layer.md b/docs/docs/layers/fill-layer.md
new file mode 100644
index 00000000..011173ec
--- /dev/null
+++ b/docs/docs/layers/fill-layer.md
@@ -0,0 +1,31 @@
+---
+sidebar_position: 1
+description: 'Add Polygons to the map.'
+---
+
+# Fill Layer
+
+The `FillLayer` is either used by the map style or can be added to the map
+programmatically to symbolize data on the map.
+
+[![Fill Layer](/img/layers/fill_layer.jpg)](/demo/#/layers/fill)
+
+## Basic Usage
+
+Check out
+the [example app](https://github.com/josxha/flutter-maplibre/blob/main/example/lib/layers_fill_page.dart)
+to learn more.
+
+## Style
+
+Use the `paint` property to style your `FillLayer` to change the style of the
+map.
+
+See
+the [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/layers/#fill)
+for all available properties.
+
+## Layout
+
+Use the `layout` property to change how the fills
+behave on the map.
\ No newline at end of file
diff --git a/docs/docs/layers/heatmap-layer.md b/docs/docs/layers/heatmap-layer.md
new file mode 100644
index 00000000..0a318006
--- /dev/null
+++ b/docs/docs/layers/heatmap-layer.md
@@ -0,0 +1,31 @@
+---
+sidebar_position: 1
+description: 'Add Heatmaps to the map.'
+---
+
+# Heatmap Layer
+
+The `HeatmapLayer` is either used by the map style or can be added to the map
+programmatically to symbolize data on the map.
+
+[![Heatmap Layer](/img/layers/heatmap_layer.jpg)](/demo/#/layers/heatmap)
+
+## Basic Usage
+
+Check out
+the [example app](https://github.com/josxha/flutter-maplibre/blob/main/example/lib/layers_heatmap_page.dart)
+to learn more.
+
+## Style
+
+Use the `paint` property to style your `HeatmapLayer` to change the style of the
+map.
+
+See
+the [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/layers/#heatmap)
+for all available properties.
+
+## Layout
+
+Use the `layout` property to change how the
+heatmaps behave on the map.
\ No newline at end of file
diff --git a/docs/docs/layers/hillshade-layer.md b/docs/docs/layers/hillshade-layer.md
new file mode 100644
index 00000000..c81bc280
--- /dev/null
+++ b/docs/docs/layers/hillshade-layer.md
@@ -0,0 +1,31 @@
+---
+sidebar_position: 1
+description: 'Render elevation on the map.'
+---
+
+# Hillshade Layer
+
+The `HillshadeLayer` is either used by the map style or can be added to the map
+programmatically to use DEM tiles. Those tiles are used to render elevation on
+the map.
+
+[![Hillshade Layer](/img/layers/hillshade_layer.jpg)](/demo/#/layers/hillshade)
+
+## Basic Usage
+
+Check out
+the [example app](https://github.com/josxha/flutter-maplibre/blob/main/example/lib/layers_hillshade_page.dart)
+to learn more.
+
+## Style
+
+Use the `paint` property to style your `HillshadeLayer` to change the style of the
+map.
+
+See
+the [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/layers/#hillshade)
+for all available properties.
+
+## Layout
+
+Use the `layout` property to change how the layer behave on the map.
\ No newline at end of file
diff --git a/docs/docs/layers/line-layer.md b/docs/docs/layers/line-layer.md
new file mode 100644
index 00000000..01092b28
--- /dev/null
+++ b/docs/docs/layers/line-layer.md
@@ -0,0 +1,31 @@
+---
+sidebar_position: 1
+description: 'Add Lines to the map.'
+---
+
+# Line Layer
+
+The `LineLayer` is either used by the map style or can be added to the map
+programmatically to symbolize data on the map.
+
+[![Line Layer](/img/layers/line_layer.jpg)](/demo/#/layers/line)
+
+## Basic Usage
+
+Check out
+the [example app](https://github.com/josxha/flutter-maplibre/blob/main/example/lib/layers_line_page.dart)
+to learn more.
+
+## Style
+
+Use the `paint` property to style your `LineLayer` to change the style of the
+map.
+
+See
+the [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/layers/#line)
+for all available properties.
+
+## Layout
+
+Use the `layout` property to change how the lines
+behave on the map.
\ No newline at end of file
diff --git a/docs/docs/layers/raster-layer.md b/docs/docs/layers/raster-layer.md
new file mode 100644
index 00000000..90933be6
--- /dev/null
+++ b/docs/docs/layers/raster-layer.md
@@ -0,0 +1,31 @@
+---
+sidebar_position: 1
+description: 'Add Raster Tiles on the map.'
+---
+
+# Raster Layer
+
+The `RasterLayer` is either used by the map style or can be added to the map
+programmatically to render raster tiles on your map.
+
+[![Raster Layer](/img/layers/raster_layer.jpg)](/demo/#/layers/raster)
+
+## Basic Usage
+
+Check out
+the [example app](https://github.com/josxha/flutter-maplibre/blob/main/example/lib/layers_raster_page.dart)
+to learn more.
+
+## Style
+
+Use the `paint` property to style your `RasterLayer` to change the style of the
+map.
+
+See
+the [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/layers/#raster)
+for all available properties.
+
+## Layout
+
+Use the `layout` property to change how the rasters
+behave on the map.
\ No newline at end of file
diff --git a/docs/docs/layers/symbol-layer.md b/docs/docs/layers/symbol-layer.md
new file mode 100644
index 00000000..8d2728bf
--- /dev/null
+++ b/docs/docs/layers/symbol-layer.md
@@ -0,0 +1,31 @@
+---
+sidebar_position: 1
+description: 'Add Markers to the map.'
+---
+
+# Symbol Layer
+
+The `SymbolLayer` is either used by the map style or can be added to the map
+programmatically to symbolize data on the map.
+
+[![Symbol Layer](/img/layers/symbol_layer.jpg)](/demo/#/layers/symbol)
+
+## Basic Usage
+
+Check out
+the [example app](https://github.com/josxha/flutter-maplibre/blob/main/example/lib/layers_symbol_page.dart)
+to learn more.
+
+## Style
+
+Use the `paint` property to style your `SymbolLayer` to change the style of the
+map.
+
+See
+the [MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/layers/#symbol)
+for all available properties.
+
+## Layout
+
+Use the `layout` property to change how the symbols
+behave on the map.
\ No newline at end of file
diff --git a/docs/docs/map-events.md b/docs/docs/map-events.md
new file mode 100644
index 00000000..83a25058
--- /dev/null
+++ b/docs/docs/map-events.md
@@ -0,0 +1,94 @@
+---
+sidebar_position: 6
+---
+
+# Map Events
+
+The event system is the used if you want to listen to any user interactions or
+state changes on the map.
+
+## Basic Usage
+
+To listen to map events, implement a callback function for the `onEvent`
+parameter.
+
+```dart
+ @override
+Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(title: const Text('Events')),
+ body: MapLibreMap(
+ options: MapOptions(center: Position(9.17, 47.68)),
+ // highlight-start
+ onEvent: _onEvent,
+ // highlight-end
+ ),
+ );
+}
+
+void _onEvent(event) {
+ print(event.runtimeType);
+
+ // check for the event type
+ // highlight-start
+ if (event is MapEventClicked) {
+ print('The map has been clicked at ${event.point.lng}, ${event.point.lat}');
+ }
+ // highlight-end
+
+ // or use a switch statement to listen to all the events you are interested in
+ // highlight-start
+ switch (event) {
+ case MapEventMapCreated():
+ print('map created');
+ case MapEventStyleLoaded():
+ print('style loaded');
+ default:
+ // ignore all other events
+ }
+ // highlight-end
+}
+```
+
+## Available Events
+
+- [MapLibre GL JS MapEventType](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/MapEventType/)
+- [MapLibre Native Android Listeners](https://maplibre.org/maplibre-native/android/api/-map-libre%20-native%20-android/org.maplibre.android.maps/-map-view/index.html)
+
+| Flutter | Web | Android | iOS | Windows | MacOS | Linux |
+|--------------------------|-------------|-----------------------------------|-----|---------|-------|-------|
+| MapEventMapCreated | | | | | | |
+| MapEventStyleLoaded | load | (OnDidFinishLoadingStyleListener) | | | | |
+| MapEventClicked | click | | | | | |
+| MapEventDoubleClicked | dblclick | | | | | |
+| MapEventSecondaryClicked | contextmenu | | | | | |
+| MapEventLongClicked | | | | | | |
+| | drag | | | | | |
+| | dragstart | | | | | |
+| | dragend | | | | | |
+| | error | | | | | |
+| | idle | OnDidBecomeIdleListener | | | | |
+| | mousedown | | | | | |
+| | mousemove | | | | | |
+| | mouseout | | | | | |
+| | mouseover | | | | | |
+| | mouseup | | | | | |
+| | move | OnCameraIsChangingListener | | | | |
+| | movestart | OnCameraWillChangeListener | | | | |
+| MapEventMovementStopped | moveend | OnCameraDidChangeListener | | | | |
+| | pitch | | | | | |
+| | pitchstart | | | | | |
+| | pitchend | | | | | |
+| | pitchend | | | | | |
+| | rotate | | | | | |
+| | rotatestart | | | | | |
+| | rotateend | | | | | |
+| | rotateend | | | | | |
+| | touchcancel | | | | | |
+| | touchend | | | | | |
+| | touchmove | | | | | |
+| | touchstart | | | | | |
+| | wheel | | | | | |
+| | zoom | | | | | |
+| | zoomstart | | | | | |
+| | zoomend | | | | | |
diff --git a/docs/docs/features/supported-features.md b/docs/docs/supported-features.md
similarity index 97%
rename from docs/docs/features/supported-features.md
rename to docs/docs/supported-features.md
index 2e5a3ccf..4693e029 100644
--- a/docs/docs/features/supported-features.md
+++ b/docs/docs/supported-features.md
@@ -1,5 +1,5 @@
---
-sidebar_position: 1
+sidebar_position: 4
---
# Supported Features
@@ -32,7 +32,7 @@ lack of platform views of these platforms.
| MapController | ✅ | ✅ | ❌ | ➖ | ➖ | ➖ |
| UI Controls for web | ✅ | ➖ | ➖ | ➖ | ➖ | ➖ |
| Offline | ➖ | ❌ | ❌ | ➖ | ➖ | ➖ |
-| Events | ❌ | ❌ | ❌ | ➖ | ➖ | ➖ |
+| Events | ✅ | ✅ | ❌ | ➖ | ➖ | ➖ |
| Snapshotter | ➖ | ❌ | ❌ | ➖ | ➖ | ➖ |
| Annotations | ❌ | ❌ | ❌ | ➖ | ➖ | ➖ |
| Circle Layer | ✅ | ✅ | ❌ | ➖ | ➖ | ➖ |
diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts
index ccac2b8e..02c59370 100644
--- a/docs/docusaurus.config.ts
+++ b/docs/docusaurus.config.ts
@@ -64,7 +64,7 @@ const config: Config = {
label: 'Getting Started',
},
{
- href: '/docs',
+ href: '/docs/',
sidebarId: 'docsSidebar',
position: 'left',
label: 'Docs',
@@ -107,7 +107,7 @@ const config: Config = {
},
{
label: 'Docs',
- to: '/docs/category/features',
+ to: '/docs/supported-features',
},
{
label: 'API Reference',
diff --git a/docs/docs/img/first_map.jpg b/docs/static/img/first_map.jpg
similarity index 100%
rename from docs/docs/img/first_map.jpg
rename to docs/static/img/first_map.jpg
diff --git a/docs/static/img/layers/circle_layer.jpg b/docs/static/img/layers/circle_layer.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..110add5340824b61ed86902895d9f1c0c6587405
GIT binary patch
literal 157054
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