Files
smart-city-digital-twin-mar…/smart-app-city/frontend/node_modules/react-native-maps/ios/AirGoogleMaps/RNMapsGoogleMapView.mm
Eric FELIXINE e30ae8ed09 feat(smart-app): implement complete mobile app MVP
- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
2026-06-01 18:00:35 -04:00

693 lines
30 KiB
Plaintext

//
// RNMapsGoogleMapView.mm
//
//
// Created by Salah Ghanim on 23.11.24.
// Copyright © 2024 react-native-maps. All rights reserved.
//
#ifdef HAVE_GOOGLE_MAPS
#import "RNMapsGoogleMapView.h"
#import "RNMapsGooglePolygonView.h"
#import "AIRGoogleMap.h"
#import "AIRGoogleMapManager.h"
#if __has_include(<ReactNativeMaps/generated/RNMapsAirModuleDelegate.h>)
#import <ReactNativeMaps/generated/RNMapsAirModuleDelegate.h>
#import <ReactNativeMaps/generated/RNMapsHostViewDelegate.h>
#import <ReactNativeMaps/generated/ComponentDescriptors.h>
#import <ReactNativeMaps/generated/EventEmitters.h>
#import <ReactNativeMaps/generated/Props.h>
#import <ReactNativeMaps/generated/RCTComponentViewHelpers.h>
#else
#import "../generated/RNMapsAirModuleDelegate.h"
#import "../generated/RNMapsSpecs/ComponentDescriptors.h"
#import "../generated/RNMapsSpecs/EventEmitters.h"
#import "../generated/RNMapsSpecs/Props.h"
#import "../generated/RNMapsSpecs/RCTComponentViewHelpers.h"
#endif
#import "RCTFabricComponentsPlugins.h"
#import <React/RCTConversions.h>
#import <React/RCTUtils.h>
#import "RCTConvert+GMSMapViewType.h"
#if __has_include(<ReactNativeMaps/RCTConvert+AirMap.h>)
#import <ReactNativeMaps/RCTConvert+AirMap.h>
#import <ReactNativeMaps/UIView+AirMap.h>
#else
#import "RCTConvert+AirMap.h"
#import "UIView+AirMap.h"
#endif
using namespace facebook::react;
@interface RNMapsGoogleMapView () <RCTRNMapsGoogleMapViewViewProtocol>
@end
@implementation RNMapsGoogleMapView {
AIRGoogleMap *_view;
AIRGoogleMapManager* _legacyMapManager;
NSMutableDictionary<NSNumber*, UIView*>* _pendingInsertsSubviews;
NSMutableArray *_polygons;
}
- (id<RNMapsAirModuleDelegate>) mapView {
return (id<RNMapsAirModuleDelegate>)_view;
}
#pragma mark - JS Commands
- (void)animateToRegion:(NSString *)regionJSON duration:(NSInteger)duration{
NSDictionary* regionDic = [RCTConvert dictonaryFromString:regionJSON];
MKCoordinateRegion region = [RCTConvert MKCoordinateRegion:regionDic];
GMSCameraPosition *camera = [AIRGoogleMap makeGMSCameraPositionFromMap:_view andMKCoordinateRegion:region];
if (duration == 0){
[_view setRegion:region];
} else {
[_view animateToCameraPosition:camera];
}
}
- (void)setCamera:(NSString *)cameraJSON{
NSDictionary* cameraDic = [RCTConvert dictonaryFromString:cameraJSON];
GMSCameraPosition* camera = [RCTConvert GMSCameraPositionWithDefaults:cameraDic existingCamera:[_view camera]];
[_view setCamera:camera];
}
- (void)animateCamera:(NSString *)cameraJSON duration:(NSInteger)duration{
NSDictionary* cameraDic = [RCTConvert dictonaryFromString:cameraJSON];
GMSCameraPosition* camera = [RCTConvert GMSCameraPositionWithDefaults:cameraDic existingCamera:[_view camera]];
[_view animateToCameraPosition:camera];
}
- (void)fitToElements:(NSString *)edgePaddingJSON animated:(BOOL)animated {
NSDictionary* edgePadding = [RCTConvert dictonaryFromString:edgePaddingJSON];
[_view fitToElementsWithEdgePadding:edgePadding animated:animated];
}
- (void)fitToSuppliedMarkers:(NSString *)markersJSON edgePaddingJSON:(NSString *)edgePaddingJSON animated:(BOOL)animated {
NSArray* markers = [RCTConvert arrayFromString:markersJSON];
NSDictionary* edgePadding = [RCTConvert dictonaryFromString:edgePaddingJSON];
[_view fitToSuppliedMarkers:markers withEdgePadding:edgePadding animated:animated];
}
- (void)fitToCoordinates:(NSString *)coordinatesJSON edgePaddingJSON:(NSString *)edgePaddingJSON animated:(BOOL)animated {
NSArray* coordinatesArr = [RCTConvert arrayFromString:coordinatesJSON];
NSMutableArray<AIRGoogleMapCoordinate*>* coordinatesArray = [NSMutableArray new];
for (id json : coordinatesArr){
[coordinatesArray addObject:[RCTConvert AIRGoogleMapCoordinate:json]];
}
NSDictionary* edgePadding = [RCTConvert dictonaryFromString:edgePaddingJSON];
[_view fitToCoordinates:coordinatesArray withEdgePadding:edgePadding animated:animated];
}
- (void) setIndoorActiveLevelIndex:(NSInteger)activeLevelIndex
{
if (!_view.indoorDisplay) {
return;
}
if ( activeLevelIndex < [_view.indoorDisplay.activeBuilding.levels count]) {
_view.indoorDisplay.activeLevel = _view.indoorDisplay.activeBuilding.levels[activeLevelIndex];
}
}
#pragma mark - Native commands
- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args
{
RCTRNMapsGoogleMapViewHandleCommand(self, commandName, args);
}
+ (ComponentDescriptorProvider)componentDescriptorProvider
{
return concreteComponentDescriptorProvider<RNMapsGoogleMapViewComponentDescriptor>();
}
- (void) loadPendingInsertSubviews
{
if ([_pendingInsertsSubviews count] > 0){
NSArray<NSNumber *> *sortedKeys = [[_pendingInsertsSubviews allKeys] sortedArrayUsingSelector:@selector(compare:)];
for (NSNumber *key in sortedKeys) {
// Get the corresponding view
UIView *view = [_pendingInsertsSubviews objectForKey:key];
[_view insertReactSubview:view atIndex:[key integerValue]];
// Remove the entry from the dictionary
[_pendingInsertsSubviews removeObjectForKey:key];
}
}
}
- (void) prepareContentView {
_view = (AIRGoogleMap *)[_legacyMapManager view];
_polygons = [NSMutableArray new];
self.contentView = _view;
_view.onPress = [self](NSDictionary* dictionary) {
if (_eventEmitter) {
// Extract values from the NSDictionary
NSDictionary* coordinateDict = dictionary[@"coordinate"];
NSDictionary* positionDict = dictionary[@"position"];
// Populate the OnMapPressCoordinate struct
facebook::react::RNMapsGoogleMapViewEventEmitter::OnPressCoordinate coordinate = {
.latitude = [coordinateDict[@"latitude"] doubleValue],
.longitude = [coordinateDict[@"longitude"] doubleValue],
};
// Populate the OnMapPressPosition struct
facebook::react::RNMapsGoogleMapViewEventEmitter::OnPressPosition position = {
.x = [positionDict[@"x"] doubleValue],
.y = [positionDict[@"y"] doubleValue],
};
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnPress data = {
.action = std::string([@"press" UTF8String]),
.position = position,
.coordinate = coordinate
};
mapViewEventEmitter->onPress(data);
}
};
_view.onLongPress = [self](NSDictionary* dictionary) {
if (_eventEmitter) {
// Extract values from the NSDictionary
NSDictionary* coordinateDict = dictionary[@"coordinate"];
NSDictionary* positionDict = dictionary[@"position"];
// Populate the OnMapPressCoordinate struct
facebook::react::RNMapsGoogleMapViewEventEmitter::OnLongPressCoordinate coordinate = {
.latitude = [coordinateDict[@"latitude"] doubleValue],
.longitude = [coordinateDict[@"longitude"] doubleValue],
};
// Populate the OnMapPressPosition struct
facebook::react::RNMapsGoogleMapViewEventEmitter::OnLongPressPosition position = {
.x = [positionDict[@"x"] doubleValue],
.y = [positionDict[@"y"] doubleValue],
};
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnLongPress data = {
.action = std::string([@"press" UTF8String]),
.position = position,
.coordinate = coordinate
};
mapViewEventEmitter->onLongPress(data);
}
};
_view.onMapReady = [self](NSDictionary* dictionary) {
[self loadPendingInsertSubviews];
if (_eventEmitter) {
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnMapReady data = {};
mapViewEventEmitter->onMapReady(data);
}
};
_view.onIndoorLevelActivated = [self](NSDictionary* dictionary) {
if (_eventEmitter) {
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnIndoorLevelActivated data = {
.activeLevelIndex= (int) [dictionary[@"activeLevelIndex"] integerValue],
.name = [dictionary[@"name"] UTF8String],
.shortName = [dictionary[@"shortName"] UTF8String],
};
mapViewEventEmitter->onIndoorLevelActivated(data);
}
};
_view.onIndoorBuildingFocused = [self](NSDictionary* dictionary) {
if (_eventEmitter) {
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
NSError *jsError = nil;
NSString *levelsStr = RCTJSONStringify(dictionary[@"levels"], &jsError);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnIndoorBuildingFocused data = {
.underground = [dictionary[@"underground"] boolValue],
.activeLevelIndex = (int) [dictionary[@"activeLevelIndex"] integerValue],
.levels = [levelsStr UTF8String]
};
mapViewEventEmitter->onIndoorBuildingFocused(data);
}
};
_view.onMapLoaded = [self](NSDictionary* dictionary) {
if (_eventEmitter) {
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnMapLoaded data = {};
mapViewEventEmitter->onMapLoaded(data);
}
};
_view.onKmlReady = [self](NSDictionary* dictionary) {
if (_eventEmitter) {
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnKmlReady data = {};
mapViewEventEmitter->onKmlReady(data);
}
};
_view.onRegionChange = [self](NSDictionary* dictionary) {
if (_eventEmitter) {
NSDictionary* regionDict = dictionary[@"region"];
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnRegionChange data = {
.region.latitude = [regionDict[@"latitude"] doubleValue],
.region.longitude = [regionDict[@"longitude"] doubleValue],
.region.latitudeDelta = [regionDict[@"latitudeDelta"] doubleValue],
.region.longitudeDelta = [regionDict[@"longitudeDelta"] doubleValue],
.isGesture = [dictionary[@"isGesture"] boolValue],
};
mapViewEventEmitter->onRegionChange(data);
}
};
_view.onPanDrag = [self](NSDictionary* dictionary) {
if (_eventEmitter) {
NSDictionary* coordinateDict = dictionary[@"coordinate"];
NSDictionary* positionDict = dictionary[@"position"];
// Populate the OnMapPressCoordinate struct
facebook::react::RNMapsGoogleMapViewEventEmitter::OnPanDragCoordinate coordinate = {
.latitude = [coordinateDict[@"latitude"] doubleValue],
.longitude = [coordinateDict[@"longitude"] doubleValue],
};
// Populate the OnMapDouplePressPosition struct
facebook::react::RNMapsGoogleMapViewEventEmitter::OnPanDragPosition position = {
.x = [positionDict[@"x"] doubleValue],
.y = [positionDict[@"y"] doubleValue],
};
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnPanDrag data = {
.position = position,
.coordinate = coordinate,
};
mapViewEventEmitter->onPanDrag(data);
}
};
_view.onUserLocationChange = [self](NSDictionary* dictionary) {
if (_eventEmitter) {
NSDictionary* coordinateDict = dictionary[@"coordinate"];
NSDictionary* errorDict = dictionary[@"error"];
// Populate the OnMapPressCoordinate struct
facebook::react::RNMapsGoogleMapViewEventEmitter::OnUserLocationChangeCoordinate coordinate = {
.latitude = [coordinateDict[@"latitude"] doubleValue],
.longitude = [coordinateDict[@"longitude"] doubleValue],
};
NSString* str = @"";
if (errorDict){
str = errorDict[@"message"];
}
facebook::react::RNMapsGoogleMapViewEventEmitter::OnUserLocationChangeError error = {
.message = std::string([str UTF8String]),
};
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnUserLocationChange data = {
.coordinate = coordinate,
.error = error,
};
mapViewEventEmitter->onUserLocationChange(data);
}
};
_view.onPoiClick = [self](NSDictionary* dictionary) {
if (_eventEmitter) {
NSDictionary* coordinateDict = dictionary[@"coordinate"];
NSDictionary* positionDict = dictionary[@"position"];
// Populate the OnMapPressCoordinate struct
facebook::react::RNMapsGoogleMapViewEventEmitter::OnPoiClickCoordinate coordinate = {
.latitude = [coordinateDict[@"latitude"] doubleValue],
.longitude = [coordinateDict[@"longitude"] doubleValue],
};
// Populate the OnMapDouplePressPosition struct
facebook::react::RNMapsGoogleMapViewEventEmitter::OnPoiClickPosition position = {
.x = [positionDict[@"x"] doubleValue],
.y = [positionDict[@"y"] doubleValue],
};
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnPoiClick data = {
.coordinate = coordinate,
.position = position,
.placeId = [dictionary[@"placeId"] UTF8String],
.name = [dictionary[@"name"] UTF8String],
};
mapViewEventEmitter->onPoiClick(data);
}
};
_view.onRegionChangeStart = [self](NSDictionary* dictionary) {
if (_eventEmitter) {
NSDictionary* regionDict = dictionary[@"region"];
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnRegionChangeStart data = {
.region.latitude = [regionDict[@"latitude"] doubleValue],
.region.longitude = [regionDict[@"longitude"] doubleValue],
.region.latitudeDelta = [regionDict[@"latitudeDelta"] doubleValue],
.region.longitudeDelta = [regionDict[@"longitudeDelta"] doubleValue],
.isGesture = [dictionary[@"isGesture"] boolValue],
};
mapViewEventEmitter->onRegionChangeStart(data);
}
};
_view.onRegionChangeComplete = [self](NSDictionary* dictionary) {
if (_eventEmitter) {
NSDictionary* regionDict = dictionary[@"region"];
auto mapViewEventEmitter = std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter);
facebook::react::RNMapsGoogleMapViewEventEmitter::OnRegionChangeComplete data = {
.region.latitude = [regionDict[@"latitude"] doubleValue],
.region.longitude = [regionDict[@"longitude"] doubleValue],
.region.latitudeDelta = [regionDict[@"latitudeDelta"] doubleValue],
.region.longitudeDelta = [regionDict[@"longitudeDelta"] doubleValue],
.isGesture = [dictionary[@"isGesture"] boolValue],
};
mapViewEventEmitter->onRegionChangeComplete(data);
}
};
#define HANDLE_MARKER_DRAG_EVENT(eventName, emitterFunction) \
if (_eventEmitter) { \
NSDictionary* coordinateDict = dictionary[@"coordinate"]; \
auto mapViewEventEmitter = \
std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter); \
facebook::react::RNMapsGoogleMapViewEventEmitter::eventName data = { \
.coordinate.latitude = [coordinateDict[@"latitude"] doubleValue], \
.coordinate.longitude = [coordinateDict[@"longitude"] doubleValue], \
.id = std::string([[dictionary valueForKey:@"id"] UTF8String]), \
}; \
mapViewEventEmitter->emitterFunction(data); \
}
#define HANDLE_MARKER_EVENT(eventName, emitterFunction, actionName) \
if (_eventEmitter) { \
NSDictionary* coordinateDict = dictionary[@"coordinate"]; \
facebook::react::RNMapsGoogleMapViewEventEmitter::eventName##Coordinate coordinate = { \
.latitude = [coordinateDict[@"latitude"] doubleValue], \
.longitude = [coordinateDict[@"longitude"] doubleValue], \
}; \
\
auto mapViewEventEmitter = \
std::static_pointer_cast<RNMapsGoogleMapViewEventEmitter const>(_eventEmitter); \
facebook::react::RNMapsGoogleMapViewEventEmitter::eventName data = { \
.action = std::string([@actionName UTF8String]), \
.id = std::string([[dictionary valueForKey:@"id"] UTF8String]), \
.coordinate = coordinate \
}; \
mapViewEventEmitter->emitterFunction(data); \
}
_view.onMarkerSelect = [self](NSDictionary* dictionary) {
HANDLE_MARKER_EVENT(OnMarkerSelect, onMarkerSelect, "marker-select");
};
_view.onMarkerDeselect = [self](NSDictionary* dictionary) {
HANDLE_MARKER_EVENT(OnMarkerDeselect, onMarkerDeselect, "marker-deselect");
};
_view.onMarkerPress = [self](NSDictionary* dictionary) {
HANDLE_MARKER_EVENT(OnMarkerPress, onMarkerPress, "marker-press");
};
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
static const auto defaultProps = std::make_shared<const RNMapsGoogleMapViewProps>();
_props = defaultProps;
_legacyMapManager = [[AIRGoogleMapManager alloc] init];
_pendingInsertsSubviews = [NSMutableDictionary new];
}
return self;
}
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index{
id<RCTComponent> paperView = [childComponentView getPaperViewFromChildComponentView];
if (paperView){
if(_view && [_view isReady]){
[_view insertReactSubview:paperView atIndex:index];
} else {
[_pendingInsertsSubviews setObject:paperView forKey:[NSNumber numberWithInteger:index]];
}
} else {
[_view insertReactSubview:childComponentView atIndex:index];
if ([childComponentView isKindOfClass:[RNMapsGooglePolygonView class]]){
RNMapsGooglePolygonView* polygon = (RNMapsGooglePolygonView *) childComponentView;
[_polygons addObject:childComponentView];
[polygon didInsertInMap:_view];
}
}
}
- (void) unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
{
id<RCTComponent> paperView = [childComponentView getPaperViewFromChildComponentView];
if (paperView){
if(_view && [_view isReady]){
[_view removeReactSubview:paperView];
} else {
[_pendingInsertsSubviews removeObjectForKey:[NSNumber numberWithInteger:index]];
}
} else {
[_view removeReactSubview:childComponentView];
if ([childComponentView isKindOfClass:[RNMapsGooglePolygonView class]]){
RNMapsGooglePolygonView* polygon = (RNMapsGooglePolygonView *) childComponentView;
[_polygons removeObject:childComponentView];
[polygon didRemoveFromMap];
}
}
}
- (void) prepareForRecycle
{
[super prepareForRecycle];
static const auto defaultProps = std::make_shared<const RNMapsGoogleMapViewProps>();
_props = defaultProps;
_legacyMapManager = [[AIRGoogleMapManager alloc] init];
_pendingInsertsSubviews = [NSMutableDictionary new];
[_view removeFromSuperview];
_view = nil;
}
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
{
const auto &oldViewProps = *std::static_pointer_cast<RNMapsGoogleMapViewProps const>(_props);
const auto &newViewProps = *std::static_pointer_cast<RNMapsGoogleMapViewProps const>(props);
if (oldViewProps.googleMapId != newViewProps.googleMapId) {
NSString* mapID = RCTNSStringFromString(newViewProps.googleMapId);
if (mapID && [mapID length]){
_legacyMapManager.googleMapId = mapID;
}
}
if (oldViewProps.customMapStyleString != newViewProps.customMapStyleString) {
NSString* customStyle = RCTNSStringFromString(newViewProps.customMapStyleString);
if (customStyle && [customStyle length]){
_legacyMapManager.customMapStyle = customStyle;
}
}
if (!newViewProps.zoomTapEnabled) {
_legacyMapManager.zoomTapEnabled = newViewProps.zoomTapEnabled;
} else {
_legacyMapManager.zoomTapEnabled = true;
}
if (oldViewProps.loadingBackgroundColor != newViewProps.loadingBackgroundColor){
_legacyMapManager.backgroundColor = RCTUIColorFromSharedColor(newViewProps.backgroundColor);
}
// bug with zoom / pitch / heading where value is not 0 even though
// nothing is passed from JS so we depend on lat / lng comparison for now
if (newViewProps.initialCamera.center.latitude != oldViewProps.initialCamera.center.latitude ||
newViewProps.initialCamera.center.longitude != oldViewProps.initialCamera.center.longitude ||
newViewProps.initialCamera.pitch != oldViewProps.initialCamera.pitch ||
newViewProps.initialCamera.zoom != oldViewProps.initialCamera.zoom
|| newViewProps.initialCamera.heading != oldViewProps.initialCamera.heading) {
GMSCameraPosition* camera = [GMSCameraPosition cameraWithLatitude:newViewProps.initialCamera.center.latitude
longitude:newViewProps.initialCamera.center.longitude
zoom:newViewProps.initialCamera.zoom
bearing:newViewProps.initialCamera.heading
viewingAngle:newViewProps.initialCamera.pitch];
_legacyMapManager.camera = camera;
}
if (!_view){
[self prepareContentView];
}
#define REMAP_MAPVIEW_PROP(name) \
if (oldViewProps.name != newViewProps.name) { \
_view.name = newViewProps.name; \
}
#define REMAP_MAPVIEW_STRING_PROP(name) \
if (oldViewProps.name != newViewProps.name) { \
_view.name = RCTNSStringFromString(newViewProps.name); \
}
#define REMAP_MAPVIEW_POINT_PROP(name) \
if (newViewProps.name.x != oldViewProps.name.x || \
newViewProps.name.y != oldViewProps.name.y) { \
_view.name = CGPointMake(newViewProps.name.x, newViewProps.name.y); \
}
#define REMAP_MAPVIEW_REGION_PROP(name) \
if (newViewProps.name.latitude != oldViewProps.name.latitude || \
newViewProps.name.longitude != oldViewProps.name.longitude || \
newViewProps.name.latitudeDelta != oldViewProps.name.latitudeDelta ||\
newViewProps.name.longitudeDelta != oldViewProps.name.longitudeDelta) { \
MKCoordinateSpan span = MKCoordinateSpanMake(newViewProps.name.latitudeDelta, \
newViewProps.name.longitudeDelta); \
MKCoordinateRegion region = MKCoordinateRegionMake(CLLocationCoordinate2DMake( \
newViewProps.name.latitude, newViewProps.name.longitude), span); \
_view.name = region; \
}
#define REMAP_MAPVIEW_EDGEINSETS_PROP(name) \
if (newViewProps.name.top != oldViewProps.name.top || \
newViewProps.name.right != oldViewProps.name.right || \
newViewProps.name.bottom != oldViewProps.name.bottom || \
newViewProps.name.left != oldViewProps.name.left) { \
_view.name = UIEdgeInsetsMake(newViewProps.name.top, \
newViewProps.name.left, \
newViewProps.name.bottom, \
newViewProps.name.right); \
}
REMAP_MAPVIEW_PROP(pitchEnabled)
REMAP_MAPVIEW_PROP(zoomTapEnabled)
REMAP_MAPVIEW_PROP(scrollEnabled)
REMAP_MAPVIEW_STRING_PROP(kmlSrc)
REMAP_MAPVIEW_STRING_PROP(customMapStyleString)
REMAP_MAPVIEW_PROP(showsBuildings)
REMAP_MAPVIEW_PROP(rotateEnabled)
if (newViewProps.minZoom != oldViewProps.minZoom || newViewProps.maxZoom != oldViewProps.maxZoom){
[_view setMinZoom:newViewProps.minZoom maxZoom:newViewProps.maxZoom];
}
REMAP_MAPVIEW_PROP(showsCompass)
REMAP_MAPVIEW_PROP(showsMyLocationButton)
REMAP_MAPVIEW_PROP(showsTraffic)
REMAP_MAPVIEW_PROP(showsUserLocation)
REMAP_MAPVIEW_PROP(zoomEnabled)
REMAP_MAPVIEW_REGION_PROP(region)
REMAP_MAPVIEW_REGION_PROP(initialRegion)
if (newViewProps.camera.center.latitude != oldViewProps.camera.center.latitude ||
newViewProps.camera.center.longitude != oldViewProps.camera.center.longitude ||
newViewProps.camera.heading != oldViewProps.camera.heading ||
newViewProps.camera.pitch != oldViewProps.camera.pitch ||
newViewProps.camera.zoom != oldViewProps.camera.zoom) {
GMSCameraPosition* camera = [GMSCameraPosition cameraWithLatitude:newViewProps.camera.center.latitude
longitude:newViewProps.camera.center.longitude
zoom:newViewProps.camera.zoom
bearing:newViewProps.camera.heading
viewingAngle:newViewProps.camera.pitch];
_view.cameraProp = camera;
}
REMAP_MAPVIEW_EDGEINSETS_PROP(mapPadding)
if (oldViewProps.mapType != newViewProps.mapType){
switch (newViewProps.mapType) {
case RNMapsGoogleMapViewMapType::Standard:
_view.mapType = kGMSTypeNormal;
break;
case RNMapsGoogleMapViewMapType::Satellite:
_view.mapType = kGMSTypeSatellite;
break;
case RNMapsGoogleMapViewMapType::Terrain:
_view.mapType = kGMSTypeTerrain;
break;
case RNMapsGoogleMapViewMapType::Hybrid:
_view.mapType = kGMSTypeHybrid;
break;
case RNMapsGoogleMapViewMapType::None:
_view.mapType = kGMSTypeNone;
break;
default:
_view.mapType = kGMSTypeNormal;
break;
}
}
if (oldViewProps.userInterfaceStyle != newViewProps.userInterfaceStyle){
switch (newViewProps.userInterfaceStyle) {
case RNMapsGoogleMapViewUserInterfaceStyle::Light:
_view.overrideUserInterfaceStyle = UIUserInterfaceStyleLight;
break;
case RNMapsGoogleMapViewUserInterfaceStyle::Dark:
_view.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;
break;
case RNMapsGoogleMapViewUserInterfaceStyle::System:
_view.overrideUserInterfaceStyle = UIUserInterfaceStyleUnspecified;
break;
}
}
if (oldViewProps.paddingAdjustmentBehavior != newViewProps.paddingAdjustmentBehavior){
switch (newViewProps.paddingAdjustmentBehavior) {
case RNMapsGoogleMapViewPaddingAdjustmentBehavior::Never:
_view.paddingAdjustmentBehavior = kGMSMapViewPaddingAdjustmentBehaviorNever;
break;
case RNMapsGoogleMapViewPaddingAdjustmentBehavior::Automatic:
_view.paddingAdjustmentBehavior = kGMSMapViewPaddingAdjustmentBehaviorAutomatic;
break;
case RNMapsGoogleMapViewPaddingAdjustmentBehavior::Always:
_view.paddingAdjustmentBehavior = kGMSMapViewPaddingAdjustmentBehaviorAlways;
break;
}
}
[super updateProps:props oldProps:oldProps];
}
@end
Class<RCTComponentViewProtocol> RNMapsGoogleMapViewCls(void)
{
return RNMapsGoogleMapView.class;
}
#endif