Skip to content

Commit

Permalink
feat(google-init): Improve Google Maps Initialisation on Android
Browse files Browse the repository at this point in the history
* chore(update-RN): examples: fix linking for android

* feat(google-init): Improve google maps initialisation
 - Improve Camera Initialisation on Android

* feat(google-init): Improve google maps initialisation
     - Introduce googleRenderer prop to support legacy renderers.

* chore(update-RN): breaking change: remove deprecated enableLatestRenderer method

---------

Co-authored-by: salah ghanim <[email protected]>
  • Loading branch information
salah-ghanim and salah ghanim authored Apr 1, 2024
1 parent 537c181 commit a1be51b
Show file tree
Hide file tree
Showing 8 changed files with 504 additions and 520 deletions.
867 changes: 447 additions & 420 deletions android/src/main/java/com/rnmaps/maps/MapManager.java

Large diffs are not rendered by default.

28 changes: 1 addition & 27 deletions android/src/main/java/com/rnmaps/maps/MapModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@
import android.net.Uri;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.annotation.NonNull;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
Expand All @@ -25,8 +23,6 @@
import com.facebook.react.uimanager.UIBlock;
import com.facebook.react.uimanager.UIManagerModule;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.OnMapsSdkInitializedCallback;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;

Expand All @@ -35,10 +31,9 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

@ReactModule(name = MapModule.NAME)
public class MapModule extends ReactContextBaseJavaModule {
Expand Down Expand Up @@ -356,25 +351,4 @@ public void execute(NativeViewHierarchyManager nvhm)
}
});
}

@ReactMethod
public void enableLatestRenderer(final Promise promise) {
final ReactApplicationContext context = getReactApplicationContext();

UIManagerModule uiManager = context.getNativeModule(UIManagerModule.class);
uiManager.addUIBlock(new UIBlock()
{
@Override
public void execute(NativeViewHierarchyManager nvhm)
{
MapsInitializer.initialize(context, MapsInitializer.Renderer.LATEST, new OnMapsSdkInitializedCallback() {
@Override
public void onMapsSdkInitialized(@NonNull MapsInitializer.Renderer renderer) {
Log.d("AirMapRenderer", renderer.toString());
promise.resolve(renderer.toString());
}
});
}
});
}
}
77 changes: 33 additions & 44 deletions android/src/main/java/com/rnmaps/maps/MapView.java
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
package com.rnmaps.maps;

import static androidx.core.content.PermissionChecker.checkSelfPermission;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.PermissionChecker;
import androidx.core.view.GestureDetectorCompat;
import androidx.core.view.MotionEventCompat;
import android.location.Location;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.location.Location;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.PermissionChecker;
import androidx.core.view.GestureDetectorCompat;
import androidx.core.view.MotionEventCompat;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReadableArray;
Expand All @@ -28,21 +32,22 @@
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerHelper;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.common.UIManagerType;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.Projection;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.GroundOverlay;
import com.google.android.gms.maps.model.IndoorBuilding;
import com.google.android.gms.maps.model.IndoorLevel;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.MapStyleOptions;
Expand All @@ -52,8 +57,6 @@
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.TileOverlay;
import com.google.android.gms.maps.model.IndoorBuilding;
import com.google.android.gms.maps.model.IndoorLevel;
import com.google.maps.android.collections.CircleManager;
import com.google.maps.android.collections.GroundOverlayManager;
import com.google.maps.android.collections.MarkerManager;
Expand All @@ -75,8 +78,6 @@
import java.util.Map;
import java.util.concurrent.ExecutionException;

import static androidx.core.content.PermissionChecker.checkSelfPermission;

public class MapView extends com.google.android.gms.maps.MapView implements GoogleMap.InfoWindowAdapter,
GoogleMap.OnMarkerDragListener, OnMapReadyCallback, GoogleMap.OnPoiClickListener, GoogleMap.OnIndoorStateChangeListener {
public GoogleMap map;
Expand Down Expand Up @@ -104,12 +105,10 @@ public class MapView extends com.google.android.gms.maps.MapView implements Goog
private boolean moveOnMarkerPress = true;
private boolean cacheEnabled = false;
private ReadableMap initialRegion;
private ReadableMap initialCamera;
private ReadableMap region;
private ReadableMap camera;
private String customMapStyleString;
private boolean initialRegionSet = false;
private boolean initialCameraSet = false;
private LatLngBounds cameraLastIdleBounds;
private int cameraMoveReason = 0;
private MapMarker selectedMarker;
Expand Down Expand Up @@ -173,9 +172,8 @@ public MapView(ThemedReactContext reactContext, ReactApplicationContext appConte

this.manager = manager;
this.context = reactContext;

MapsInitializer.initialize(context, this.manager.renderer, renderer -> Log.d("AirMapRenderer", renderer.toString()));
super.onCreate(null);
// TODO(lmr): what about onStart????
super.onResume();
super.getMapAsync(this);

Expand Down Expand Up @@ -538,23 +536,10 @@ public void setInitialRegion(ReadableMap initialRegion) {
}
}

public void setInitialCamera(ReadableMap initialCamera) {
this.initialCamera = initialCamera;
// Theoretically onMapReady might be called before setInitialCamera
// In that case, trigger moveToCamera manually
if (!initialCameraSet && map != null) {
moveToCamera(initialCamera);
initialCameraSet = true;
}
}

private void applyBridgedProps() {
if(initialRegion != null) {
moveToRegion(initialRegion);
initialRegionSet = true;
} else if(initialCamera != null) {
moveToCamera(initialCamera);
initialCameraSet = true;
} else if(region != null) {
moveToRegion(region);
} else {
Expand Down Expand Up @@ -602,24 +587,28 @@ public void setCamera(ReadableMap camera) {
moveToCamera(camera);
}
}
public static CameraPosition cameraPositionFromMap(ReadableMap camera){
if (camera == null) return null;

public void moveToCamera(ReadableMap camera) {
if (camera == null) return;

CameraPosition.Builder builder = new CameraPosition.Builder();
CameraPosition.Builder builder = new CameraPosition.Builder();

ReadableMap center = camera.getMap("center");
if (center != null) {
double lng = center.getDouble("longitude");
double lat = center.getDouble("latitude");
builder.target(new LatLng(lat, lng));
}
ReadableMap center = camera.getMap("center");
if (center != null) {
double lng = center.getDouble("longitude");
double lat = center.getDouble("latitude");
builder.target(new LatLng(lat, lng));
}

builder.tilt((float)camera.getDouble("pitch"));
builder.bearing((float)camera.getDouble("heading"));
builder.zoom((float)camera.getDouble("zoom"));
builder.tilt((float)camera.getDouble("pitch"));
builder.bearing((float)camera.getDouble("heading"));
builder.zoom((float)camera.getDouble("zoom"));

CameraUpdate update = CameraUpdateFactory.newCameraPosition(builder.build());
return builder.build();
}
public void moveToCamera(ReadableMap cameraMap) {
CameraPosition camera = cameraPositionFromMap(cameraMap);
if (camera == null) return;
CameraUpdate update = CameraUpdateFactory.newCameraPosition(camera);

if (super.getHeight() <= 0 || super.getWidth() <= 0) {
// in this case, our map has not been laid out yet, so we save the camera update in a
Expand Down
20 changes: 0 additions & 20 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,26 +100,6 @@ None of these keys are required anymore and can be removed, if not used by other
from there you will see a button to update it (do not search within the
Play Store).

### Using the new Google Maps Renderer

A new renderer for Google Maps on Android will become the default through a progressive rollout starting in June 2022 at the earliest. (Read more about it [here](https://developers.google.com/maps/documentation/android-sdk/renderer))

react-native-maps added support for the new renderer in v0.31.0.

To opt in to the new renderer add the following code in your entry file (e.g. App.js):

```javascript
import {enableLatestRenderer} from 'react-native-maps';

enableLatestRenderer();
```

`enableLatestRenderer` returns a promise (on android) specifying the map renderer being used, either `'LATEST' | 'LEGACY'`. It can be called at any point to get the renderer being used, but it won't change after the first map has been rendered.

Make sure to test your app thoroughly after enabling the new renderer, as it seems to cause some behavioural changes, e.g. [this](https://github.com/react-native-maps/react-native-maps/pull/4055#issuecomment-1063358886).

---

## Troubleshooting

### The map background is blank (Google Maps)
Expand Down
10 changes: 10 additions & 0 deletions example/react-native.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const path = require('path');
const pak = require('../package.json');

module.exports = {
dependencies: {
[pak.name]: {
root: path.join(__dirname, '..'),
},
},
};
1 change: 1 addition & 0 deletions example/src/examples/GradientPolylines.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class GradientPolylines extends React.Component<any, any> {
render() {
return (
<MapView
googleRenderer={'LEGACY'}
provider={this.props.provider}
style={styles.container}
initialRegion={this.state.region}>
Expand Down
18 changes: 11 additions & 7 deletions src/MapView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,15 @@ export type MapViewProps = ViewProps & {
*/
googleMapId?: string;

/**
* https://developers.google.com/maps/documentation/android-sdk/renderer
* google maps renderer
* @default `LATEST`
* @platform iOS: Not supported
* @platform Android: Supported
*/
googleRenderer?: 'LATEST' | 'LEGACY';

/**
* Sets loading background color.
*
Expand Down Expand Up @@ -1060,6 +1069,7 @@ class MapView extends React.Component<MapViewProps, State> {
onMapReady: this._onMapReady,
liteMode: this.props.liteMode,
googleMapId: this.props.googleMapId,
googleRenderer: this.props.googleRenderer,
ref: this.map,
customMapStyleString: this.props.customMapStyle
? JSON.stringify(this.props.customMapStyle)
Expand All @@ -1083,6 +1093,7 @@ class MapView extends React.Component<MapViewProps, State> {
region: null,
liteMode: this.props.liteMode,
googleMapId: this.props.googleMapId,
googleRenderer: this.props.googleRenderer,
initialRegion: this.props.initialRegion || null,
initialCamera: this.props.initialCamera,
ref: this.map,
Expand Down Expand Up @@ -1126,13 +1137,6 @@ const getNativeMapComponent = (provider: Provider) =>

export const AnimatedMapView = RNAnimated.createAnimatedComponent(MapView);

export const enableLatestRenderer = () => {
if (Platform.OS !== 'android') {
return;
}
return NativeModules.AirMapModule.enableLatestRenderer();
};

MapView.Animated = AnimatedMapView;

export default MapView;
3 changes: 1 addition & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import MapView, {
AnimatedMapView as Animated,
MAP_TYPES,
enableLatestRenderer,
MapViewProps,
} from './MapView';

Expand Down Expand Up @@ -40,7 +39,7 @@ export type {GeojsonProps} from './Geojson';

export {Marker, Overlay};
export type {MapViewProps};
export {Animated, MAP_TYPES, enableLatestRenderer};
export {Animated, MAP_TYPES};

export * from './ProviderConstants';
export * from './MapView.types';
Expand Down

0 comments on commit a1be51b

Please sign in to comment.