From a0c8030c7a534e0ec162a3f8ac74a548aa7f3e9a Mon Sep 17 00:00:00 2001 From: lovebing Date: Mon, 15 Jun 2020 01:08:11 +0800 Subject: [PATCH] =?UTF-8?q?icon=20image=20=E5=A4=8D=E7=94=A8;=20Marker.ani?= =?UTF-8?q?mateType;=20BaiduMapManager.hasLocationPermission?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 ++- .../baidumap/module/BaiduMapManager.java | 9 +++ .../baidumap/module/GeolocationModule.java | 2 +- .../baidumap/support/AppUtils.java | 7 +- .../baidumap/support/ConvertUtils.java | 3 + .../uimanager/OverlayMarkerManager.java | 5 ++ .../baidumap/view/OverlayMarker.java | 40 ++++++++-- index.d.ts | 80 +++++++++++++------ ios/RCTBaiduMap/BMKPointAnnotationPro.m | 2 - ios/RCTBaiduMap/GeolocationModule.m | 4 + ios/RCTBaiduMap/Modules/BaiduMapManager.h | 1 + ios/RCTBaiduMap/Modules/BaiduMapManager.m | 10 +++ .../ViewManagers/OverlayMarkerManager.m | 1 + ios/RCTBaiduMap/Views/OverlayMarker.h | 1 + ios/RCTBaiduMap/Views/OverlayMarker.m | 25 +++++- js/Overlay/Marker.js | 2 + package.json | 2 +- react-native-baidu-map.podspec | 4 +- 18 files changed, 167 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 2467097b..35acb159 100644 --- a/README.md +++ b/README.md @@ -124,13 +124,14 @@ BaiduMapManager.initSDK('sIMQlfmOXhQmPLF1QMh4aBp8zZO9Lb2A'); | Prop | Type | Default | Description | ----------------------- |:-----:| :-------:| ------- | title | string| null | 如果没有 InfoWindow,将会根据 title 生成 InfoWindow -| titleOffsetY | int | -80 | title 作为 InfoWindow 展示的 y 轴偏移量,仅 Android +| titleOffsetY | int | -80 | title 作为 InfoWindow 展示的 y 轴偏移量,仅 Android | location | object| {latitude: 0, longitude: 0} | | perspective | bool | null | 仅 Android | flat | bool | null | 仅 Android | rotate | float | 0 | 旋转角度,仅 Android | icon | any | null | icon图片,同 的 source 属性 | alpha | float | 1 | 透明度,仅 Android +| animateType | string| | 动画效果:drop/grow/jump (iOS 仅支持 drop) | pinColor | string| red | red/green/purple,大头针颜色,仅 iOS | onClick | func | | 点击事件回调 ##### Cluster 点聚合 @@ -240,6 +241,13 @@ Cluster 示例 ``` +#### BaiduMapManager + +| Method | Description | Result +| ------------------------- | ---------------- | ------- +| void initSDK(string apiKey) | iOS 初始化 SDK | +| Promise hasLocationPermission | 是否有定位权限 | + #### Geolocation Methods | Method | Description | Result diff --git a/android/src/main/java/org/lovebing/reactnative/baidumap/module/BaiduMapManager.java b/android/src/main/java/org/lovebing/reactnative/baidumap/module/BaiduMapManager.java index 576fad08..2e4fe67c 100644 --- a/android/src/main/java/org/lovebing/reactnative/baidumap/module/BaiduMapManager.java +++ b/android/src/main/java/org/lovebing/reactnative/baidumap/module/BaiduMapManager.java @@ -7,11 +7,16 @@ package org.lovebing.reactnative.baidumap.module; +import android.Manifest; import android.util.Log; import androidx.annotation.NonNull; + +import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactMethod; +import org.lovebing.reactnative.baidumap.support.AppUtils; + /** * @author lovebing * @date 2019/10/30 @@ -33,4 +38,8 @@ public void initSDK(String key) { Log.i("initSDK", key); } + @ReactMethod + public void hasLocationPermission(Promise promise) { + promise.resolve(AppUtils.hasPermission(context.getCurrentActivity(), Manifest.permission.ACCESS_FINE_LOCATION)); + } } diff --git a/android/src/main/java/org/lovebing/reactnative/baidumap/module/GeolocationModule.java b/android/src/main/java/org/lovebing/reactnative/baidumap/module/GeolocationModule.java index 829c9d34..7d516235 100644 --- a/android/src/main/java/org/lovebing/reactnative/baidumap/module/GeolocationModule.java +++ b/android/src/main/java/org/lovebing/reactnative/baidumap/module/GeolocationModule.java @@ -56,7 +56,7 @@ public String getName() { } private void initLocationClient(String coorType) { - if(context.getCurrentActivity()!=null) { + if(context.getCurrentActivity() != null) { AppUtils.checkPermission(context.getCurrentActivity(), Manifest.permission.ACCESS_FINE_LOCATION); } LocationClientOption option = new LocationClientOption(); diff --git a/android/src/main/java/org/lovebing/reactnative/baidumap/support/AppUtils.java b/android/src/main/java/org/lovebing/reactnative/baidumap/support/AppUtils.java index e75a4fcd..5cd38a8b 100644 --- a/android/src/main/java/org/lovebing/reactnative/baidumap/support/AppUtils.java +++ b/android/src/main/java/org/lovebing/reactnative/baidumap/support/AppUtils.java @@ -23,11 +23,14 @@ public class AppUtils { public static void checkPermission(Activity activity, String permission) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (activity.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.M) { - if (ContextCompat.checkSelfPermission(activity, permission) - != PackageManager.PERMISSION_GRANTED) { + if (!hasPermission(activity, permission)) { ActivityCompat.requestPermissions(activity, new String[]{permission}, RequestCode.CODE_ASK_PERMISSIONS); } } } } + + public static boolean hasPermission(Activity activity, String permission) { + return ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED; + } } diff --git a/android/src/main/java/org/lovebing/reactnative/baidumap/support/ConvertUtils.java b/android/src/main/java/org/lovebing/reactnative/baidumap/support/ConvertUtils.java index ef4e8140..4ce1c46b 100644 --- a/android/src/main/java/org/lovebing/reactnative/baidumap/support/ConvertUtils.java +++ b/android/src/main/java/org/lovebing/reactnative/baidumap/support/ConvertUtils.java @@ -33,6 +33,9 @@ public static LatLng convert(LocationData locationData) { } public static T convert(ReadableMap readableMap, Class targetClass) { + if (readableMap == null) { + return null; + } if (!FILED_MAP.containsKey(targetClass)) { FILED_MAP.put(targetClass, targetClass.getDeclaredFields()); } diff --git a/android/src/main/java/org/lovebing/reactnative/baidumap/uimanager/OverlayMarkerManager.java b/android/src/main/java/org/lovebing/reactnative/baidumap/uimanager/OverlayMarkerManager.java index dff6d5c3..40e6b6a5 100644 --- a/android/src/main/java/org/lovebing/reactnative/baidumap/uimanager/OverlayMarkerManager.java +++ b/android/src/main/java/org/lovebing/reactnative/baidumap/uimanager/OverlayMarkerManager.java @@ -38,6 +38,11 @@ public void setTitle(OverlayMarker overlayMarker, String title) { overlayMarker.setTitle(title); } + @ReactProp(name = "animateType") + public void setAnimateType(OverlayMarker overlayMarker, String animateType) { + overlayMarker.setAnimateType(animateType); + } + @ReactProp(name = "titleOffsetY") public void setTitleOffsetY(OverlayMarker overlayMarker, int titleOffsetY) { overlayMarker.setTitleOffsetY(titleOffsetY); diff --git a/android/src/main/java/org/lovebing/reactnative/baidumap/view/OverlayMarker.java b/android/src/main/java/org/lovebing/reactnative/baidumap/view/OverlayMarker.java index 41b7cc88..66516ce8 100644 --- a/android/src/main/java/org/lovebing/reactnative/baidumap/view/OverlayMarker.java +++ b/android/src/main/java/org/lovebing/reactnative/baidumap/view/OverlayMarker.java @@ -43,12 +43,18 @@ import org.lovebing.reactnative.baidumap.model.IconInfo; import org.lovebing.reactnative.baidumap.util.BitmapUtil; +import java.util.Map; import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; public class OverlayMarker extends ViewGroup implements OverlayView, ClusterItem { + // TODO 1. 下载中的情况。 2. 清理零引用的 key + private static final Map BITMAP_DESCRIPTOR_MAP = new ConcurrentHashMap<>(); + private String title; private int titleOffsetY = -100; + private MarkerOptions.MarkerAnimateType animateType = MarkerOptions.MarkerAnimateType.none; private LatLng position; private Float rotate; private Boolean flat; @@ -66,10 +72,8 @@ public class OverlayMarker extends ViewGroup implements OverlayView, ClusterItem private final ControllerListener imageControllerListener = new BaseControllerListener() { @Override - public void onFinalImageSet( - String id, - final ImageInfo imageInfo, - Animatable animatable) { + public void onFinalImageSet(String id, final ImageInfo imageInfo, Animatable animatable) { + Log.i("onFinalImageSet", id); CloseableReference imageReference = null; try { imageReference = dataSource.getResult(); @@ -81,6 +85,7 @@ public void onFinalImageSet( if (bitmap != null) { bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true); iconBitmapDescriptor = BitmapDescriptorFactory.fromBitmap(bitmap); + BITMAP_DESCRIPTOR_MAP.put(iconInfo.getUri(), iconBitmapDescriptor); } } } @@ -167,8 +172,26 @@ public void setIconView(View iconView) { } } - public String getTitle() { - return title; + public void setAnimateType(String animateType) { + if (animateType == null) { + return; + } + switch (animateType) { + case "drop": + this.animateType = MarkerOptions.MarkerAnimateType.drop; + break; + case "grow": + this.animateType = MarkerOptions.MarkerAnimateType.grow; + break; + case "jump": + this.animateType = MarkerOptions.MarkerAnimateType.jump; + break; + default: + this.animateType = MarkerOptions.MarkerAnimateType.none; + } + if (marker != null) { + marker.setAnimateType(this.animateType.ordinal()); + } } public void setTitle(String title) { @@ -220,6 +243,10 @@ public void setIcon(IconInfo iconInfo) { if (iconInfo.getUri() == null || iconInfo.getUri().length() == 0) { return; } + if (BITMAP_DESCRIPTOR_MAP.containsKey(iconInfo.getUri())) { + iconBitmapDescriptor = BITMAP_DESCRIPTOR_MAP.get(iconInfo.getUri()); + return; + } Log.i("download", iconInfo.getUri()); this.iconInfo = iconInfo; String uri = iconInfo.getUri(); @@ -312,6 +339,7 @@ private void addOverlay(BaiduMap baiduMap) { MarkerOptions option = new MarkerOptions() .position(position) .alpha(getAlpha()) + .animateType(animateType) .icon(getBitmapDescriptor()); if (rotate != null) { option.rotate(rotate); diff --git a/index.d.ts b/index.d.ts index f1cf792a..987b5750 100644 --- a/index.d.ts +++ b/index.d.ts @@ -20,6 +20,19 @@ declare namespace ReactNativeBaiduMap { longitude: number; } + export interface Stroke { + width: number; + color: string; + } + + /** + * 颜色渐变对象 + */ + export interface Gradient { + colors: Array; + startPoints: Array + } + type CommonCallBack = (l: T) => void; /** @@ -176,6 +189,11 @@ declare namespace ReactNativeBaiduMap { */ icon?: ImageSourcePropType; + /** + * 动画效果:drop/grow/jump (iOS 仅支持 drop) + */ + animateType?: string; + /** * @default 0 */ @@ -190,19 +208,19 @@ declare namespace ReactNativeBaiduMap { export interface ArcProps extends ViewProps { /** - * @default 'AA00FF00' + * @default {width: 5, color: 'AA000000'} */ - color?: string; + stroke: Stroke; /** - * @default 4 + * 数值长度必须为 3 */ - width?: number; + points: [Location, Location, Location]; /** - * 数值长度必须为 3 + * 是否为虚线,仅 iOS */ - poins: [Location, Location, Location]; + dash: boolean; } export class Arc extends Component { @@ -227,23 +245,18 @@ declare namespace ReactNativeBaiduMap { center: Location; } - export interface CircleProps extends ViewProps {} + export interface CircleProps extends ViewProps { + radius: number; + fillColor: string; + stroke: Stroke; + center: Location; + } export class Circle extends Component {} export interface PolylineProps extends ViewProps { points: Location[]; - - /** - * 8位(AARRGGBB) - * @default 'AAFF0000' - */ - strokeColor?: string; - - /** - * @default 1 - */ - lineWidth?: number; + stroke: Stroke; } export class Polyline extends Component {} @@ -283,15 +296,23 @@ declare namespace ReactNativeBaiduMap { export class Text extends Component {} export interface InfoWindowProps extends ViewProps { - location: Location; - /** - * @default false + * 相对于 point 在 y 轴的偏移量,仅 Android */ - visible?: boolean; + offsetY: number; } - export class InfoWindowProps extends Component {} + export class InfoWindow extends Component {} + + export interface HeatMapProps extends ViewProps { + points: Array; + gradient: Gradient; + } + + /** + * 自定义热力图 + */ + export class HeatMap extends Component {} } export namespace Geolocation { @@ -431,6 +452,19 @@ declare namespace ReactNativeBaiduMap { */ export function openWalkNavi(sl: OpenLocation, el: OpenLocation): void; } + + export namespace BaiduMapManager { + /** + * iOS 初始化 SDK + * @param appKey + */ + export function initSDK(appKey: string): void; + + /** + * 是否有定位权限 + */ + export function hasLocationPermission(): Promise; + } } export = ReactNativeBaiduMap; diff --git a/ios/RCTBaiduMap/BMKPointAnnotationPro.m b/ios/RCTBaiduMap/BMKPointAnnotationPro.m index 4d22e205..077e3bfc 100644 --- a/ios/RCTBaiduMap/BMKPointAnnotationPro.m +++ b/ios/RCTBaiduMap/BMKPointAnnotationPro.m @@ -9,7 +9,6 @@ #import "BMKPointAnnotationPro.h" @implementation BMKPointAnnotationPro { - BMKActionPaopaoView *_pView; BMKActionPaopaoView *_paopaoView; } @@ -18,7 +17,6 @@ @implementation BMKPointAnnotationPro { - (instancetype)init { self = [super init]; _annotationView = [[BMKPinAnnotationView alloc] initWithAnnotation:self reuseIdentifier:markerIdentifier]; - _annotationView.animatesDrop = YES; _customPopView = [[UIView alloc] init]; _paopaoView = [[BMKActionPaopaoView alloc] initWithCustomView:_customPopView]; return self; diff --git a/ios/RCTBaiduMap/GeolocationModule.m b/ios/RCTBaiduMap/GeolocationModule.m index b32a3b62..212ebf26 100644 --- a/ios/RCTBaiduMap/GeolocationModule.m +++ b/ios/RCTBaiduMap/GeolocationModule.m @@ -290,4 +290,8 @@ - (void)sendEvent:(NSString *)name body:(NSMutableDictionary *)body { [self.bridge.eventDispatcher sendDeviceEventWithName:name body:body]; } ++ (BOOL)requiresMainQueueSetup { + return YES; +} + @end diff --git a/ios/RCTBaiduMap/Modules/BaiduMapManager.h b/ios/RCTBaiduMap/Modules/BaiduMapManager.h index 1789dea5..cb02a085 100644 --- a/ios/RCTBaiduMap/Modules/BaiduMapManager.h +++ b/ios/RCTBaiduMap/Modules/BaiduMapManager.h @@ -14,6 +14,7 @@ #import #import #import +#import @interface BaiduMapManager : NSObject diff --git a/ios/RCTBaiduMap/Modules/BaiduMapManager.m b/ios/RCTBaiduMap/Modules/BaiduMapManager.m index bcf189cc..0177eeff 100644 --- a/ios/RCTBaiduMap/Modules/BaiduMapManager.m +++ b/ios/RCTBaiduMap/Modules/BaiduMapManager.m @@ -24,4 +24,14 @@ @implementation BaiduMapManager } } +RCT_REMAP_METHOD(hasLocationPermission, + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { + if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) { + resolve(@NO); + } else { + resolve(@YES); + } +} + @end diff --git a/ios/RCTBaiduMap/ViewManagers/OverlayMarkerManager.m b/ios/RCTBaiduMap/ViewManagers/OverlayMarkerManager.m index c4c64a55..5c87409f 100644 --- a/ios/RCTBaiduMap/ViewManagers/OverlayMarkerManager.m +++ b/ios/RCTBaiduMap/ViewManagers/OverlayMarkerManager.m @@ -14,6 +14,7 @@ @implementation OverlayMarkerManager RCT_EXPORT_VIEW_PROPERTY(location, NSDictionary*) RCT_EXPORT_VIEW_PROPERTY(title, NSString*) RCT_EXPORT_VIEW_PROPERTY(icon, RCTImageSource*) +RCT_EXPORT_VIEW_PROPERTY(animateType, NSString*) RCT_EXPORT_VIEW_PROPERTY(pinColor, NSString*) RCT_EXPORT_VIEW_PROPERTY(onClick, RCTBubblingEventBlock) diff --git a/ios/RCTBaiduMap/Views/OverlayMarker.h b/ios/RCTBaiduMap/Views/OverlayMarker.h index 0f842c73..efc61bac 100644 --- a/ios/RCTBaiduMap/Views/OverlayMarker.h +++ b/ios/RCTBaiduMap/Views/OverlayMarker.h @@ -29,6 +29,7 @@ @property (nonatomic, strong) NSString *title; @property (nonatomic, strong) RCTImageSource *icon; @property (nonatomic, strong) BMKPointAnnotationPro *annotation; +@property (nonatomic, strong) NSString *animateType; @property (nonatomic, strong) NSString *pinColor; @property (nonatomic, strong) BMKActionPaopaoView *paopaoView; diff --git a/ios/RCTBaiduMap/Views/OverlayMarker.m b/ios/RCTBaiduMap/Views/OverlayMarker.m index a011eb20..9066db04 100644 --- a/ios/RCTBaiduMap/Views/OverlayMarker.m +++ b/ios/RCTBaiduMap/Views/OverlayMarker.m @@ -12,6 +12,8 @@ #import "InfoWindow.h" #import "OverlayMarkerIcon.h" +static NSMutableDictionary *ICON_MAGE_MAP; + @implementation OverlayMarker { RCTImageLoaderCancellationBlock _reloadImageCancellationBlock; UIImageView *_imageView; @@ -19,6 +21,10 @@ @implementation OverlayMarker { UIImage *_iconImage; } ++ (void)initialize { + ICON_MAGE_MAP = @{}.mutableCopy; +} + - (NSString *)getType { return @"marker"; } @@ -51,12 +57,25 @@ - (void)updateAnnotation:(BMKPointAnnotationPro *)annotation { } else { annotation.title = _title; } - _annotation.coordinate = [OverlayUtils getCoorFromOption:_location]; + annotation.coordinate = [OverlayUtils getCoorFromOption:_location]; + if ([@"drop" isEqualToString:self.animateType]) { + annotation.annotationView.animatesDrop = YES; + } else { + annotation.annotationView.animatesDrop = NO; + } if (_iconImage == nil && _icon != nil) { + UIImage *image = [ICON_MAGE_MAP objectForKey:_icon.request.URL.absoluteString]; + if (image != nil) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateAnnotationView:annotation image:image]; + }); + return; + } if (_reloadImageCancellationBlock) { _reloadImageCancellationBlock(); _reloadImageCancellationBlock = nil; } + NSLog(@"download %@", _icon.request.URL); _reloadImageCancellationBlock = [[_bridge moduleForName:@"ImageLoader"] loadImageWithURLRequest:_icon.request size:self.bounds.size scale:RCTScreenScale() @@ -69,9 +88,10 @@ - (void)updateAnnotation:(BMKPointAnnotationPro *)annotation { NSLog(@"download image error: %@", error); return; } + ICON_MAGE_MAP[self.icon.request.URL.absoluteString] = image; dispatch_async(dispatch_get_main_queue(), ^{ [self updateAnnotationView:annotation image:image]; - NSLog(@"download image success: %@", image); + NSLog(@"download image success: %@", self.icon.request.URL.absoluteString); }); }]; } else { @@ -91,7 +111,6 @@ - (void)updateAnnotationView:(BMKPointAnnotationPro *) annotation image:(UIImage } _imageView.frame = frame; annotation.annotationView.frame = frame; - } else { annotation.annotationView.image = image; annotation.annotationView.frame = CGRectMake(0, 0, CGImageGetWidth(image.CGImage), CGImageGetHeight(image.CGImage)); diff --git a/js/Overlay/Marker.js b/js/Overlay/Marker.js index 019e3475..a24cb4b0 100644 --- a/js/Overlay/Marker.js +++ b/js/Overlay/Marker.js @@ -24,12 +24,14 @@ export default class Marker extends Component { rotate: PropTypes.number, flat: PropTypes.bool, icon: PropTypes.any, + animateType: PropTypes.string, pinColor: PropTypes.string, onClick: PropTypes.func }; static defaultProps = { titleOffsetY: -80, + animateType: '', location: { latitude: 0, longitude: 0 diff --git a/package.json b/package.json index c3c8cc2f..333c7cae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-baidu-map", - "version": "1.0.36", + "version": "1.0.37", "description": "Baidu Map SDK modules and views for React Native(Android & iOS), support react native 0.61+. 百度地图 React Native 模块,支持 react native 0.61+,已更新到最新的百度地图 SDK 版本。", "main": "index.js", "scripts": { diff --git a/react-native-baidu-map.podspec b/react-native-baidu-map.podspec index 5737750c..aff006c6 100644 --- a/react-native-baidu-map.podspec +++ b/react-native-baidu-map.podspec @@ -9,7 +9,7 @@ Pod::Spec.new do |s| s.name = "react-native-baidu-map" - s.version = "1.0.36" + s.version = "1.0.37" s.summary = "Baidu Map for React Native" s.description = <<-DESC @@ -41,7 +41,7 @@ Pod::Spec.new do |s| # Supports git, hg, bzr, svn and HTTP. # - s.source = { :http => "http://repo.codeboot.net/pod/http/react-native-baidu-map/1.0.36/source.zip" } + s.source = { :http => "http://repo.codeboot.net/pod/http/react-native-baidu-map/1.0.37/source.zip" } s.source_files = "ios/RCTBaiduMap/**/*.{h,m}" s.exclude_files = ""