@maplibre/maplibre-react-native 9.0.1 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,9 +5,12 @@ Please add unreleased changes in the following style:
5
5
  PR Title ([#123](link to my pr))
6
6
  ```
7
7
 
8
- ## 9.0.1
8
+ ## 9.1.0
9
9
 
10
+ Update react to 18.2.0 and react-native to 0.72.1. ([#49](https://github.com/maplibre/maplibre-react-native/pull/49))
11
+ fix(markerview): make PointAnnotationProps component extend ViewProps ([#41](https://github.com/maplibre/maplibre-react-native/issues/41))
10
12
  Fix build issue on iOS ([#29](https://github.com/maplibre/maplibre-react-native/issues/29))
13
+ Add clusterProperties to ShapeSource ([#46](https://github.com/maplibre/maplibre-react-native/pull/46))
11
14
 
12
15
  ## 9.0.0
13
16
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  buildscript {
4
4
  ext {
5
- buildToolsVersion = "28.0.3"
5
+ buildToolsVersion = "33.0.0"
6
6
  minSdkVersion = 16
7
7
  compileSdkVersion = 33
8
8
  targetSdkVersion = 33
@@ -13,7 +13,7 @@ buildscript {
13
13
  jcenter()
14
14
  }
15
15
  dependencies {
16
- classpath 'com.android.tools.build:gradle:3.5.2'
16
+ classpath 'com.android.tools.build:gradle'
17
17
 
18
18
  // NOTE: Do not place your application dependencies here; they belong
19
19
  // in the individual module build.gradle files
@@ -29,10 +29,8 @@ android {
29
29
  }
30
30
 
31
31
  dependencies {
32
- implementation fileTree(dir: 'libs', include: ['*.jar'])
33
-
34
- // React Native
35
- implementation "com.facebook.react:react-native:+"
32
+ // The version of react-native is set by the React Native Gradle Plugin
33
+ implementation("com.facebook.react:react-android")
36
34
 
37
35
  // MapLibre SDK
38
36
  implementation "org.maplibre.gl:android-sdk:9.6.0"
@@ -22,6 +22,7 @@ import com.mapbox.rctmgl.R;
22
22
  import com.mapbox.rctmgl.components.mapview.RCTMGLMapView;
23
23
  import com.mapbox.rctmgl.events.AndroidCallbackEvent;
24
24
  import com.mapbox.rctmgl.events.FeatureClickEvent;
25
+ import com.mapbox.rctmgl.utils.ClusterPropertyEntry;
25
26
  import com.mapbox.rctmgl.utils.DownloadMapImageTask;
26
27
  import com.mapbox.rctmgl.utils.ImageEntry;
27
28
 
@@ -44,6 +45,7 @@ public class RCTMGLShapeSource extends RCTSource<GeoJsonSource> {
44
45
  private Boolean mCluster;
45
46
  private Integer mClusterRadius;
46
47
  private Integer mClusterMaxZoom;
48
+ private List<Map.Entry<String, ClusterPropertyEntry>> mClusterProperties;
47
49
 
48
50
  private Integer mMaxZoom;
49
51
  private Integer mBuffer;
@@ -110,6 +112,10 @@ public class RCTMGLShapeSource extends RCTSource<GeoJsonSource> {
110
112
  mClusterMaxZoom = clusterMaxZoom;
111
113
  }
112
114
 
115
+ public void setClusterProperties(List<Map.Entry<String, ClusterPropertyEntry>> clusterProperties) {
116
+ mClusterProperties = clusterProperties;
117
+ }
118
+
113
119
  public void setMaxZoom(int maxZoom) {
114
120
  mMaxZoom = maxZoom;
115
121
  }
@@ -145,6 +151,14 @@ public class RCTMGLShapeSource extends RCTSource<GeoJsonSource> {
145
151
  options.withClusterMaxZoom(mClusterMaxZoom);
146
152
  }
147
153
 
154
+ if (mClusterProperties != null) {
155
+ for (Map.Entry<String, ClusterPropertyEntry> entry : mClusterProperties) {
156
+ ClusterPropertyEntry property = entry.getValue();
157
+
158
+ options.withClusterProperty(entry.getKey(), property.operator, property.mapping);
159
+ }
160
+ }
161
+
148
162
  if (mMaxZoom != null) {
149
163
  options.withMaxZoom(mMaxZoom);
150
164
  }
@@ -18,11 +18,13 @@ import com.facebook.react.common.MapBuilder;
18
18
  import com.facebook.react.uimanager.ThemedReactContext;
19
19
  import com.facebook.react.uimanager.ViewGroupManager;
20
20
  import com.facebook.react.uimanager.annotations.ReactProp;
21
+ import com.mapbox.mapboxsdk.style.expressions.Expression;
21
22
  import com.mapbox.rctmgl.components.AbstractEventEmitter;
22
23
  import com.mapbox.rctmgl.components.annotation.RCTMGLCallout;
23
24
  import com.mapbox.rctmgl.components.mapview.RCTMGLMapView;
24
25
  import com.mapbox.rctmgl.components.styles.layers.RCTLayer;
25
26
  import com.mapbox.rctmgl.events.constants.EventKeys;
27
+ import com.mapbox.rctmgl.utils.ClusterPropertyEntry;
26
28
  import com.mapbox.rctmgl.utils.ExpressionParser;
27
29
  import com.mapbox.rctmgl.utils.ImageEntry;
28
30
  import com.mapbox.rctmgl.utils.ResourceUtils;
@@ -113,6 +115,30 @@ public class RCTMGLShapeSourceManager extends AbstractEventEmitter<RCTMGLShapeSo
113
115
  source.setClusterMaxZoom(clusterMaxZoom);
114
116
  }
115
117
 
118
+ @ReactProp(name = "clusterProperties")
119
+ public void setClusterProperties(RCTMGLShapeSource source, ReadableMap map) {
120
+ List<Map.Entry<String, ClusterPropertyEntry>> properties = new ArrayList<>();
121
+
122
+ ReadableMapKeySetIterator iterator = map.keySetIterator();
123
+ while (iterator.hasNextKey()) {
124
+ String name = iterator.nextKey();
125
+ ReadableArray expressions = map.getArray(name);
126
+
127
+ Expression operator;
128
+ if (expressions.getType(0) == ReadableType.Array) {
129
+ operator = ExpressionParser.from(expressions.getArray(0));
130
+ } else {
131
+ operator = Expression.literal(expressions.getString(0));
132
+ }
133
+
134
+ Expression mapping = ExpressionParser.from(expressions.getArray(1));
135
+
136
+ properties.add(new AbstractMap.SimpleEntry<>(name, new ClusterPropertyEntry(operator, mapping)));
137
+ }
138
+
139
+ source.setClusterProperties(properties);
140
+ }
141
+
116
142
  @ReactProp(name = "maxZoomLevel")
117
143
  public void setMaxZoomLevel(RCTMGLShapeSource source, int maxZoom) {
118
144
  source.setMaxZoom(maxZoom);
@@ -0,0 +1,13 @@
1
+ package com.mapbox.rctmgl.utils;
2
+
3
+ import com.mapbox.mapboxsdk.style.expressions.Expression;
4
+
5
+ public class ClusterPropertyEntry {
6
+ public Expression operator;
7
+ public Expression mapping;
8
+
9
+ public ClusterPropertyEntry(Expression _operator, Expression _mapping) {
10
+ operator = _operator;
11
+ mapping = _mapping;
12
+ }
13
+ }
@@ -11,6 +11,7 @@
11
11
  | cluster | `bool` | `none` | `false` | Enables clustering on the source for point shapes. |
12
12
  | clusterRadius | `number` | `none` | `false` | Specifies the radius of each cluster if clustering is enabled.<br/>A value of 512 produces a radius equal to the width of a tile.<br/>The default value is 50. |
13
13
  | clusterMaxZoomLevel | `number` | `none` | `false` | Specifies the maximum zoom level at which to cluster points if clustering is enabled.<br/>Defaults to one zoom level less than the value of maxZoomLevel so that, at the maximum zoom level,<br/>the shapes are not clustered. |
14
+ | clusterProperties | `object` | `none` | `false` | Specifies custom properties on the generated clusters if clustering<br/>is enabled, aggregating values from clustered points.<br/><br/>Has the form `{ "property_name": [operator, map_expression]}`, where<br/> `operator` is a custom reduce expression that references a special `["accumulated"]` value -<br/> it accumulates the property value from clusters/points the cluster contains<br/> `map_expression` produces the value of a single point<br/><br/>Example: `{ "resultingSum": [["+", ["accumulated"], ["get", "resultingSum"]], ["get", "scalerank"]] }` |
14
15
  | maxZoomLevel | `number` | `none` | `false` | Specifies the maximum zoom level at which to create vector tiles.<br/>A greater value produces greater detail at high zoom levels.<br/>The default value is 18. |
15
16
  | buffer | `number` | `none` | `false` | Specifies the size of the tile buffer on each side.<br/>A value of 0 produces no buffer. A value of 512 produces a buffer as wide as the tile itself.<br/>Larger values produce fewer rendering artifacts near tile edges and slower performance.<br/>The default value is 128. |
16
17
  | tolerance | `number` | `none` | `false` | Specifies the Douglas-Peucker simplification tolerance.<br/>A greater value produces simpler geometries and improves performance.<br/>The default value is 0.375. |
package/docs/docs.json CHANGED
@@ -3934,6 +3934,13 @@
3934
3934
  "default": "none",
3935
3935
  "description": "Specifies the maximum zoom level at which to cluster points if clustering is enabled.\nDefaults to one zoom level less than the value of maxZoomLevel so that, at the maximum zoom level,\nthe shapes are not clustered."
3936
3936
  },
3937
+ {
3938
+ "name": "clusterProperties",
3939
+ "required": false,
3940
+ "type": "object",
3941
+ "default": "none",
3942
+ "description": "Specifies custom properties on the generated clusters if clustering\nis enabled, aggregating values from clustered points.\n\nHas the form `{ \"property_name\": [operator, map_expression]}`, where\n `operator` is a custom reduce expression that references a special `[\"accumulated\"]` value -\n it accumulates the property value from clusters/points the cluster contains\n `map_expression` produces the value of a single point\n\nExample: `{ \"resultingSum\": [[\"+\", [\"accumulated\"], [\"get\", \"resultingSum\"]], [\"get\", \"scalerank\"]] }`"
3943
+ },
3937
3944
  {
3938
3945
  "name": "maxZoomLevel",
3939
3946
  "required": false,
package/index.d.ts CHANGED
@@ -783,7 +783,7 @@ export interface LightProps extends Omit<ViewProps, 'style'> {
783
783
  style?: LightStyle;
784
784
  }
785
785
 
786
- export interface PointAnnotationProps {
786
+ export interface PointAnnotationProps extends ViewProps {
787
787
  id: string;
788
788
  title?: string;
789
789
  snippet?: string;
@@ -837,6 +837,7 @@ export interface ShapeSourceProps extends ViewProps {
837
837
  cluster?: boolean;
838
838
  clusterRadius?: number;
839
839
  clusterMaxZoomLevel?: number;
840
+ clusterProperties?: object;
840
841
  maxZoomLevel?: number;
841
842
  buffer?: number;
842
843
  tolerance?: number;
@@ -21,6 +21,7 @@
21
21
  @property (nonatomic, strong) NSNumber *cluster;
22
22
  @property (nonatomic, strong) NSNumber *clusterRadius;
23
23
  @property (nonatomic, strong) NSNumber *clusterMaxZoomLevel;
24
+ @property (nonatomic, strong) NSDictionary<NSString *, NSArray<NSExpression *> *> *clusterProperties;
24
25
 
25
26
  @property (nonatomic, strong) NSNumber *maxZoomLevel;
26
27
  @property (nonatomic, strong) NSNumber *buffer;
@@ -82,6 +82,20 @@ static UIImage * _placeHolderImage;
82
82
  options[MGLShapeSourceOptionMaximumZoomLevelForClustering] = _clusterMaxZoomLevel;
83
83
  }
84
84
 
85
+ if (_clusterProperties != nil) {
86
+ NSMutableDictionary<NSString *, NSArray *> *properties = [NSMutableDictionary new];
87
+
88
+ for (NSString *propertyName in _clusterProperties.allKeys) {
89
+ NSArray<NSExpression *> *expressions = [_clusterProperties objectForKey: propertyName];
90
+ NSExpression *firstExpression = [NSExpression expressionWithMGLJSONObject:[expressions objectAtIndex: 0]];
91
+ NSExpression *secondExpression = [NSExpression expressionWithMGLJSONObject:[expressions objectAtIndex: 1]];
92
+
93
+ [properties setObject:@[firstExpression, secondExpression] forKey:propertyName];
94
+ }
95
+
96
+ options[MGLShapeSourceOptionClusterProperties] = properties;
97
+ }
98
+
85
99
  if (_maxZoomLevel != nil) {
86
100
  options[MGLShapeSourceOptionMaximumZoomLevel] = _maxZoomLevel;
87
101
  }
@@ -23,6 +23,7 @@ RCT_EXPORT_VIEW_PROPERTY(shape, NSString)
23
23
  RCT_EXPORT_VIEW_PROPERTY(cluster, NSNumber)
24
24
  RCT_EXPORT_VIEW_PROPERTY(clusterRadius, NSNumber)
25
25
  RCT_EXPORT_VIEW_PROPERTY(clusterMaxZoomLevel, NSNumber)
26
+ RCT_EXPORT_VIEW_PROPERTY(clusterProperties, NSDictionary)
26
27
  RCT_EXPORT_VIEW_PROPERTY(maxZoomLevel, NSNumber)
27
28
  RCT_EXPORT_VIEW_PROPERTY(buffer, NSNumber)
28
29
  RCT_EXPORT_VIEW_PROPERTY(tolerance, NSNumber)
@@ -495,6 +495,7 @@
495
495
  D8C1903423F53B0F00223486 /* RCTMGLImagesManager.m */,
496
496
  );
497
497
  name = Images;
498
+ };
498
499
  DF3CFC0122CFCD8B00A83174 /* Location */ = {
499
500
  isa = PBXGroup;
500
501
  children = (
@@ -63,6 +63,20 @@ class ShapeSource extends NativeBridgeComponent(AbstractSource) {
63
63
  */
64
64
  clusterMaxZoomLevel: PropTypes.number,
65
65
 
66
+ /**
67
+ * Specifies custom properties on the generated clusters if clustering
68
+ * is enabled, aggregating values from clustered points.
69
+ *
70
+ * Has the form `{ "property_name": [operator, map_expression]}`, where
71
+ * `operator` is a custom reduce expression that references a special `["accumulated"]` value -
72
+ * it accumulates the property value from clusters/points the cluster contains
73
+ * `map_expression` produces the value of a single point
74
+ *
75
+ * Example: `{ "resultingSum": [["+", ["accumulated"], ["get", "resultingSum"]], ["get", "scalerank"]] }`
76
+ *
77
+ */
78
+ clusterProperties: PropTypes.object,
79
+
66
80
  /**
67
81
  * Specifies the maximum zoom level at which to create vector tiles.
68
82
  * A greater value produces greater detail at high zoom levels.
@@ -324,6 +338,7 @@ class ShapeSource extends NativeBridgeComponent(AbstractSource) {
324
338
  cluster: this.props.cluster ? 1 : 0,
325
339
  clusterRadius: this.props.clusterRadius,
326
340
  clusterMaxZoomLevel: this.props.clusterMaxZoomLevel,
341
+ clusterProperties: this.props.clusterProperties,
327
342
  maxZoomLevel: this.props.maxZoomLevel,
328
343
  buffer: this.props.buffer,
329
344
  tolerance: this.props.tolerance,
@@ -163,6 +163,9 @@ function getShapeSource(id, source) {
163
163
  if (source.clusterMaxZoom !== undefined) {
164
164
  sourceProps.clusterMaxZoomLevel = source.clusterMaxZoom;
165
165
  }
166
+ if (source.clusterProperties !== undefined) {
167
+ sourceProps.clusterProperties = source.clusterProperties;
168
+ }
166
169
  if (source.buffer !== undefined) {
167
170
  sourceProps.buffer = source.buffer;
168
171
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@maplibre/maplibre-react-native",
3
3
  "description": "A MapLibre GL Native plugin for creating maps in React Native",
4
- "version": "9.0.1",
4
+ "version": "9.1.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -49,7 +49,7 @@
49
49
  "@types/geojson": "^7946.0.7",
50
50
  "@types/node": "^18.11.18",
51
51
  "debounce": "^1.2.0",
52
- "deprecated-react-native-prop-types": "^2.3.0"
52
+ "deprecated-react-native-prop-types": "^4.1.0"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@babel/core": "^7.20.5",
@@ -58,11 +58,12 @@
58
58
  "@babel/runtime": "7.17.2",
59
59
  "@react-native-community/eslint-config": "^3.0.1",
60
60
  "@react-native-community/eslint-plugin": "^1.3.0",
61
+ "@react-native/metro-config": "^0.72.7",
61
62
  "@sinonjs/fake-timers": "^8.0.1",
62
63
  "@testing-library/react-native": "^8.0.0",
63
64
  "@typescript-eslint/eslint-plugin": "^5.2.0",
64
65
  "@typescript-eslint/parser": "^5.8.0",
65
- "babel-jest": "^27.5.1",
66
+ "babel-jest": "^29.6.0",
66
67
  "documentation": "^14.0.0",
67
68
  "ejs": "^3.1.3",
68
69
  "ejs-lint": "^1.1.0",
@@ -79,17 +80,17 @@
79
80
  "eslint-plugin-react-native": "^4.0.0",
80
81
  "expo-module-scripts": "^3.0.4",
81
82
  "husky": "4.3.8",
82
- "jest": "^27.5.1",
83
- "jest-cli": "^27.5.1",
83
+ "jest": "^29.6.0",
84
+ "jest-cli": "^29.6.0",
84
85
  "lint-staged": "^12.1.2",
85
- "metro-react-native-babel-preset": "^0.70.3",
86
+ "metro-react-native-babel-preset": "^0.76.7",
86
87
  "node-dir": "0.1.17",
87
88
  "prettier": "^2.0.4",
88
89
  "prop-types": "^15.8.1",
89
- "react": "^18.0.0",
90
+ "react": "^18.2.0",
90
91
  "react-docgen": "rnmapbox/react-docgen#rnmapbox-dist",
91
- "react-native": "0.68.0",
92
- "react-test-renderer": "^18.0.0",
92
+ "react-native": "0.72.1",
93
+ "react-test-renderer": "^18.2.0",
93
94
  "standard": "*",
94
95
  "typescript": "^4.4.3"
95
96
  },
package/setup-jest.js CHANGED
@@ -110,7 +110,9 @@ NativeModules.MGLSnapshotModule = {
110
110
 
111
111
  NativeModules.MGLLocationModule = {
112
112
  getLastKnownLocation: jest.fn(),
113
+ setMinDisplacement: jest.fn(),
113
114
  start: jest.fn(),
115
+ stop: jest.fn(),
114
116
  pause: jest.fn(),
115
117
  };
116
118