Skip to content

Commit 286d9f8

Browse files
hwolbertobrun
andauthored
Define annotation order (#523)
* Add annotation order on ios side * Add annotation order on Android side * Add annotation order on dart side * Add an annotation order page example * Add another safety check * Change polygone naming to fill Co-authored-by: Tobrun <[email protected]>
1 parent a688f88 commit 286d9f8

File tree

8 files changed

+260
-31
lines changed

8 files changed

+260
-31
lines changed

android/src/main/java/com/mapbox/mapboxgl/Convert.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,15 @@ static CameraPosition toCameraPosition(Object o) {
6363
return builder.build();
6464
}
6565

66+
static List<String> toAnnotationOrder(Object o) {
67+
final List<?> data = toList(o);
68+
List<String> annotations = new ArrayList();
69+
for (int index = 0; index < data.size(); index++) {
70+
annotations.add(toString(data.get(index)));
71+
}
72+
return annotations;
73+
}
74+
6675
static boolean isScrollByCameraUpdate(Object o) {
6776
return toString(toList(o).get(0)).equals("scrollBy");
6877
}

android/src/main/java/com/mapbox/mapboxgl/MapboxMapBuilder.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import io.flutter.plugin.common.PluginRegistry;
1818

1919
import java.util.concurrent.atomic.AtomicInteger;
20+
import java.util.List;
21+
import java.util.ArrayList;
2022

2123

2224
class MapboxMapBuilder implements MapboxMapOptionsSink {
@@ -29,11 +31,12 @@ class MapboxMapBuilder implements MapboxMapOptionsSink {
2931
private int myLocationTrackingMode = 0;
3032
private int myLocationRenderMode = 0;
3133
private String styleString = Style.MAPBOX_STREETS;
34+
private List<String> annotationOrder = new ArrayList();
3235

3336
MapboxMapController build(
3437
int id, Context context, BinaryMessenger messenger, MapboxMapsPlugin.LifecycleProvider lifecycleProvider, String accessToken) {
3538
final MapboxMapController controller =
36-
new MapboxMapController(id, context, messenger, lifecycleProvider, options, accessToken, styleString);
39+
new MapboxMapController(id, context, messenger, lifecycleProvider, options, accessToken, styleString, annotationOrder);
3740
controller.init();
3841
controller.setMyLocationEnabled(myLocationEnabled);
3942
controller.setMyLocationTrackingMode(myLocationTrackingMode);
@@ -171,4 +174,8 @@ public void setAttributionButtonMargins(int x, int y) {
171174
(int) y, //bottom
172175
});
173176
}
177+
178+
public void setAnnotationOrder(List<String> annotations) {
179+
this.annotationOrder = annotations;
180+
}
174181
}

android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,10 @@
7171

7272
import java.io.IOException;
7373
import java.io.InputStream;
74-
import java.util.ArrayList;
75-
import java.util.Arrays;
76-
import java.util.Collections;
77-
import java.util.HashMap;
74+
import java.util.*;
75+
import java.util.concurrent.atomic.AtomicInteger;
7876
import java.util.List;
79-
import java.util.Map;
77+
import java.util.ArrayList;
8078

8179
import io.flutter.plugin.common.BinaryMessenger;
8280
import io.flutter.plugin.common.MethodCall;
@@ -132,6 +130,7 @@ final class MapboxMapController
132130
private LocationEngineCallback<LocationEngineResult> locationEngineCallback = null;
133131
private LocalizationPlugin localizationPlugin;
134132
private Style style;
133+
private List<String> annotationOrder = new ArrayList();
135134

136135
MapboxMapController(
137136
int id,
@@ -140,7 +139,8 @@ final class MapboxMapController
140139
MapboxMapsPlugin.LifecycleProvider lifecycleProvider,
141140
MapboxMapOptions options,
142141
String accessToken,
143-
String styleStringInitial) {
142+
String styleStringInitial,
143+
List<String> annotationOrder) {
144144
MapBoxUtils.getMapbox(context, accessToken);
145145
this.id = id;
146146
this.context = context;
@@ -154,6 +154,7 @@ final class MapboxMapController
154154
this.lifecycleProvider = lifecycleProvider;
155155
methodChannel = new MethodChannel(messenger, "plugins.flutter.io/mapbox_maps_" + id);
156156
methodChannel.setMethodCallHandler(this);
157+
this.annotationOrder = annotationOrder;
157158
}
158159

159160
@Override
@@ -289,10 +290,25 @@ public void setStyleString(String styleString) {
289290
@Override
290291
public void onStyleLoaded(@NonNull Style style) {
291292
MapboxMapController.this.style = style;
292-
enableLineManager(style);
293-
enableSymbolManager(style);
294-
enableCircleManager(style);
295-
enableFillManager(style);
293+
for(String annotationType : annotationOrder) {
294+
switch (annotationType) {
295+
case "AnnotationType.fill":
296+
enableFillManager(style);
297+
break;
298+
case "AnnotationType.line":
299+
enableLineManager(style);
300+
break;
301+
case "AnnotationType.circle":
302+
enableCircleManager(style);
303+
break;
304+
case "AnnotationType.symbol":
305+
enableSymbolManager(style);
306+
break;
307+
default:
308+
throw new IllegalArgumentException("Unknown annotation type: " + annotationType + ", must be either 'fill', 'line', 'circle' or 'symbol'");
309+
}
310+
}
311+
296312
if (myLocationEnabled) {
297313
enableLocationComponent(style);
298314
}

android/src/main/java/com/mapbox/mapboxgl/MapboxMapFactory.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44

55
import com.mapbox.mapboxsdk.camera.CameraPosition;
66

7-
import java.util.Map;
8-
97
import io.flutter.plugin.common.BinaryMessenger;
108
import io.flutter.plugin.common.StandardMessageCodec;
119
import io.flutter.plugin.platform.PlatformView;
1210
import io.flutter.plugin.platform.PlatformViewFactory;
1311

12+
import java.util.Map;
13+
import java.util.concurrent.atomic.AtomicInteger;
14+
import java.util.List;
15+
import java.util.ArrayList;
16+
1417
public class MapboxMapFactory extends PlatformViewFactory {
1518

1619
private final BinaryMessenger messenger;
@@ -32,6 +35,10 @@ public PlatformView create(Context context, int id, Object args) {
3235
CameraPosition position = Convert.toCameraPosition(params.get("initialCameraPosition"));
3336
builder.setInitialCameraPosition(position);
3437
}
38+
if (params.containsKey("annotationOrder")) {
39+
List<String> annotations = Convert.toAnnotationOrder(params.get("annotationOrder"));
40+
builder.setAnnotationOrder(annotations);
41+
}
3542
return builder.build(id, context, messenger, lifecycleProvider, (String) params.get("accessToken"));
3643
}
3744
}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter/rendering.dart';
3+
import 'package:mapbox_gl/mapbox_gl.dart';
4+
5+
import 'main.dart';
6+
import 'page.dart';
7+
8+
class AnnotationOrderPage extends ExamplePage {
9+
AnnotationOrderPage()
10+
: super(const Icon(Icons.layers), 'Annotation order maps');
11+
12+
@override
13+
Widget build(BuildContext context) => AnnotationOrderBody();
14+
}
15+
16+
class AnnotationOrderBody extends StatefulWidget {
17+
AnnotationOrderBody();
18+
19+
@override
20+
_AnnotationOrderBodyState createState() => _AnnotationOrderBodyState();
21+
}
22+
23+
class _AnnotationOrderBodyState extends State<AnnotationOrderBody> {
24+
MapboxMapController controllerOne;
25+
MapboxMapController controllerTwo;
26+
27+
final LatLng center = const LatLng(36.580664, 32.5563837);
28+
29+
@override
30+
Widget build(BuildContext context) {
31+
return Column(
32+
children: <Widget>[
33+
Card(
34+
child: Padding(
35+
padding: const EdgeInsets.symmetric(vertical: 0.0),
36+
child: Column(
37+
children: <Widget>[
38+
const Padding(
39+
padding: EdgeInsets.only(bottom: 5.0),
40+
child: Text(
41+
'This map has polygones (fill) above all other anotations (default behavior)'),
42+
),
43+
Center(
44+
child: SizedBox(
45+
width: 250.0,
46+
height: 250.0,
47+
child: MapboxMap(
48+
accessToken: MapsDemo.ACCESS_TOKEN,
49+
onMapCreated: onMapCreatedOne,
50+
onStyleLoadedCallback: () => onStyleLoaded(controllerOne),
51+
initialCameraPosition: CameraPosition(
52+
target: center,
53+
zoom: 5.0,
54+
),
55+
annotationOrder: const [
56+
AnnotationType.line,
57+
AnnotationType.symbol,
58+
AnnotationType.circle,
59+
AnnotationType.fill,
60+
],
61+
),
62+
),
63+
),
64+
],
65+
),
66+
),
67+
),
68+
Card(
69+
child: Padding(
70+
padding: const EdgeInsets.symmetric(vertical: 0.0),
71+
child: Column(
72+
children: <Widget>[
73+
const Padding(
74+
padding: EdgeInsets.only(bottom: 5.0, top: 5.0),
75+
child: Text(
76+
'This map has polygones (fill) under all other anotations'),
77+
),
78+
Center(
79+
child: SizedBox(
80+
width: 250.0,
81+
height: 250.0,
82+
child: MapboxMap(
83+
accessToken: MapsDemo.ACCESS_TOKEN,
84+
onMapCreated: onMapCreatedTwo,
85+
onStyleLoadedCallback: () => onStyleLoaded(controllerTwo),
86+
initialCameraPosition: CameraPosition(
87+
target: center,
88+
zoom: 5.0,
89+
),
90+
annotationOrder: const [
91+
AnnotationType.fill,
92+
AnnotationType.line,
93+
AnnotationType.symbol,
94+
AnnotationType.circle,
95+
],
96+
),
97+
),
98+
),
99+
],
100+
),
101+
),
102+
),
103+
],
104+
);
105+
}
106+
107+
void onMapCreatedOne(MapboxMapController controller) {
108+
this.controllerOne = controller;
109+
}
110+
111+
void onMapCreatedTwo(MapboxMapController controller) {
112+
this.controllerTwo = controller;
113+
}
114+
115+
void onStyleLoaded(MapboxMapController controller) {
116+
controller.addSymbol(
117+
SymbolOptions(
118+
geometry: LatLng(
119+
center.latitude,
120+
center.longitude,
121+
),
122+
iconImage: "airport-15",
123+
),
124+
);
125+
controller.addLine(
126+
LineOptions(
127+
draggable: false,
128+
lineColor: "#ff0000",
129+
lineWidth: 7.0,
130+
lineOpacity: 1,
131+
geometry: [
132+
LatLng(35.3649902, 32.0593003),
133+
LatLng(34.9475098, 31.1187944),
134+
LatLng(36.7108154, 30.7040582),
135+
LatLng(37.6995850, 33.6512083),
136+
LatLng(35.8648682, 33.6969227),
137+
LatLng(35.3814697, 32.0546447),
138+
],
139+
),
140+
);
141+
controller.addFill(
142+
FillOptions(
143+
draggable: false,
144+
fillColor: "#008888",
145+
fillOpacity: 0.3,
146+
geometry: [
147+
[
148+
LatLng(35.3649902, 32.0593003),
149+
LatLng(34.9475098, 31.1187944),
150+
LatLng(36.7108154, 30.7040582),
151+
LatLng(37.6995850, 33.6512083),
152+
LatLng(35.8648682, 33.6969227),
153+
LatLng(35.3814697, 32.0546447),
154+
]
155+
],
156+
),
157+
);
158+
}
159+
}

example/lib/main.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:mapbox_gl_example/full_map.dart';
99
import 'package:mapbox_gl_example/offline_regions.dart';
1010

1111
import 'animate_camera.dart';
12+
import 'annotation_order_maps.dart';
1213
import 'full_map.dart';
1314
import 'line.dart';
1415
import 'map_ui.dart';
@@ -32,6 +33,7 @@ final List<ExamplePage> _allPages = <ExamplePage>[
3233
PlaceFillPage(),
3334
ScrollingMapPage(),
3435
OfflineRegionsPage(),
36+
AnnotationOrderPage(),
3537
];
3638

3739
class MapsDemo extends StatelessWidget {

ios/Classes/MapboxMapController.swift

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma
2222
private var lineAnnotationController: MGLLineAnnotationController?
2323
private var fillAnnotationController: MGLPolygonAnnotationController?
2424

25+
private var annotationOrder = [String]()
26+
2527
func view() -> UIView {
2628
return mapView
2729
}
@@ -63,6 +65,9 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma
6365
mapView.setCenter(camera.centerCoordinate, zoomLevel: zoom, direction: camera.heading, animated: false)
6466
initialTilt = camera.pitch
6567
}
68+
if let annotationOrderArg = args["annotationOrder"] as? [String] {
69+
annotationOrder = annotationOrderArg
70+
}
6671
}
6772
}
6873

@@ -671,22 +676,29 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma
671676
mapView.setCamera(camera, animated: false)
672677
}
673678

674-
lineAnnotationController = MGLLineAnnotationController(mapView: self.mapView)
675-
lineAnnotationController!.annotationsInteractionEnabled = true
676-
lineAnnotationController?.delegate = self
677-
678-
symbolAnnotationController = MGLSymbolAnnotationController(mapView: self.mapView)
679-
symbolAnnotationController!.annotationsInteractionEnabled = true
680-
symbolAnnotationController?.delegate = self
681-
682-
circleAnnotationController = MGLCircleAnnotationController(mapView: self.mapView)
683-
circleAnnotationController!.annotationsInteractionEnabled = true
684-
circleAnnotationController?.delegate = self
679+
for annotationType in annotationOrder {
680+
switch annotationType {
681+
case "AnnotationType.fill":
682+
fillAnnotationController = MGLPolygonAnnotationController(mapView: self.mapView)
683+
fillAnnotationController!.annotationsInteractionEnabled = true
684+
fillAnnotationController?.delegate = self
685+
case "AnnotationType.line":
686+
lineAnnotationController = MGLLineAnnotationController(mapView: self.mapView)
687+
lineAnnotationController!.annotationsInteractionEnabled = true
688+
lineAnnotationController?.delegate = self
689+
case "AnnotationType.circle":
690+
circleAnnotationController = MGLCircleAnnotationController(mapView: self.mapView)
691+
circleAnnotationController!.annotationsInteractionEnabled = true
692+
circleAnnotationController?.delegate = self
693+
case "AnnotationType.symbol":
694+
symbolAnnotationController = MGLSymbolAnnotationController(mapView: self.mapView)
695+
symbolAnnotationController!.annotationsInteractionEnabled = true
696+
symbolAnnotationController?.delegate = self
697+
default:
698+
print("Unknown annotation type: \(annotationType), must be either 'fill', 'line', 'circle' or 'symbol'")
699+
}
700+
}
685701

686-
fillAnnotationController = MGLPolygonAnnotationController(mapView: self.mapView)
687-
fillAnnotationController!.annotationsInteractionEnabled = true
688-
fillAnnotationController?.delegate = self
689-
690702
mapReadyResult?(nil)
691703
if let channel = channel {
692704
channel.invokeMethod("map#onStyleLoaded", arguments: nil)

0 commit comments

Comments
 (0)