溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何在iOS中集成weex-amap

發(fā)布時(shí)間:2021-08-10 10:01:13 來源:億速云 閱讀:126 作者:小新 欄目:web開發(fā)

這篇文章給大家分享的是有關(guān)如何在iOS中集成weex-amap的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。

在移動(dòng)應(yīng)用開發(fā)中,地圖是一個(gè)很重要的工具,基于地圖的定位、導(dǎo)航等特點(diǎn)衍生出了很多著名的移動(dòng)應(yīng)用。在Weex開發(fā)中,如果要使用定位、導(dǎo)航和坐標(biāo)計(jì)算等常見的地圖功能,可以使用weex-amap插件。

weex-amap是高德針對Weex開發(fā)的一款地圖插件,在Eros開發(fā)中,Eros對weex-amap進(jìn)行二次封裝,以便讓開發(fā)者更集成地圖功能。和其他的插件一樣,集成此插件需要在原生平臺中進(jìn)行集成。

1.高德地圖開發(fā)準(zhǔn)備工作

  • 1.1 iOS高德地圖開發(fā)流程簡單介紹

  • 1.2 android高德地圖開發(fā)流程簡單介紹

  • 1.3 web高德地圖開發(fā)流程簡單介紹

2. weex-iOS地圖組件擴(kuò)展方式介紹

  • 2.1 dwd-weex-amap

  • 2.2 dwd-weex-amap-marker

  • 2.3 dwd-weex-amap-info-window

  • 2.4 dwd-weex-amap-circle

  • 2.5 dwd-weex-amap-polygon

  • 2.5 dwd-weex-amap-polyline

3.weex-android地圖組件擴(kuò)展方式介紹

  • 3.1 dwd-weex-amap

  • 3.2 dwd-weex-amap-marker

  • 3.3 dwd-weex-amap-info-window

  • 3.4 dwd-weex-amap-circle

  • 3.5 dwd-weex-amap-polygon

  • 3.6 dwd-weex-amap-polyline

4.weex-html5地圖組件擴(kuò)展方式介紹

  • 4.1 dwd-weex-amap

  • 4.2 dwd-weex-amap-marker

  • 4.3 dwd-weex-amap-info-window

  • 4.4 dwd-weex-amap-circle

  • 4.5 dwd-weex-amap-polygon

  • 4.6 dwd-weex-amap-polyline

5.獲取地圖數(shù)據(jù)(例如騎行路徑規(guī)劃)

  • 5.1 weex-iOS地圖騎行路徑規(guī)劃

  • 5.2 weex-android地圖騎行路徑規(guī)劃

  • 5.3 weex-web地圖騎行路徑規(guī)劃

如何在iOS中集成weex-amap

準(zhǔn)備工作

1.1 開發(fā)流程簡紹

1.使用 CocoaPods 安裝AMapSearch,AMap3DMap SDK
2.前往高德開放平臺控制臺申請 iOS Key
3.配置高德Key至AppDelegate.m文件

1.2 android高德地圖開發(fā)流程簡紹

1.使用 CocoaPods 安裝AMapSearch,AMap3DMap SDK
2.前往高德開放平臺控制臺申請 android Key
3.AndroidManifest.xml的application標(biāo)簽中配置Key
4.AndroidManifest.xml中配置權(quán)限

1.3 HTML5高德地圖開發(fā)流程簡紹

1.前往高德開放平臺控制臺申請 jsAPI Key
2.可通過CDN同步加載方式或使用require異步方式來加載key

參考:高德地圖開發(fā)文檔,vue-amap開發(fā)文檔

weex-iOS地圖組件擴(kuò)展

2.1 weex-amap

地圖展示是地圖最基本的功能,其常見的效果如下:

如何在iOS中集成weex-amap

如有要在iOS中自定義weex-amap可以從以下幾個(gè)步驟完成:

1.新建DMapViewComponent類繼承WXComponent;
2.在DMapViewComponent實(shí)現(xiàn)文件中實(shí)現(xiàn)MAMapViewDelegate代理;
3. 重寫DMapViewComponent的loadView方法加載地圖視圖并設(shè)置自身為代理對象;
4.在DMapViewComponent的初始化函數(shù)viewDidLoad中做一些準(zhǔn)備工作;
5.在DMapViewComponent的initWithRef方法中實(shí)現(xiàn)屬性綁定;
6.通過fireEvent添加適當(dāng)時(shí)機(jī)可以觸發(fā)的事件;
7.重寫insertSubview方法來添加子組建包括覆蓋物,線,圓等等。

下面是部分的業(yè)務(wù)實(shí)現(xiàn)代碼:

@implementation DMapViewComponent
...
// 屬性綁定
- (instancetype)initWithRef:(NSString *)ref
            type:(NSString*)type
           styles:(nullable NSDictionary *)styles
         attributes:(nullable NSDictionary *)attributes
           events:(nullable NSArray *)events
        weexInstance:(WXSDKInstance *)weexInstance
{
  self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance];
  if (self) {
    // 中心點(diǎn)
    NSArray *center = [attributes map_safeObjectForKey:@"center"];
    _zoomLevel = [[attributes map_safeObjectForKey:@"zoom"] floatValue];
    // 是否允許顯示指南針
    _compass = [[attributes map_safeObjectForKey:@"compass"] boolValue];
    // sdkKey
    if ([attributes map_safeObjectForKey:@"sdkKey"]) {
      [self setAPIKey:[attributes[@"sdkKey"] objectForKey:@"ios"] ? : @""];
    }
...
  }
  return self;
}
// 重寫DMapViewComponent的loadView方法加載地圖視圖并設(shè)置自身為代理對象  
- (UIView *) loadView
{
  UIWindow *window = [UIApplication sharedApplication].keyWindow;
  CGSize windowSize = window.rootViewController.view.frame.size;
  self.mapView = [[MAMapView alloc] initWithFrame:CGRectMake(0, 0, windowSize.width, windowSize.height)];
  self.mapView.showsUserLocation = _showGeolocation;
  self.mapView.delegate = self;
  self.mapView.customMapStyleEnabled = YES;
  [self.mapView setCustomMapStyleWithWebData:[self getMapData]];

  return self.mapView;
}
// 設(shè)置地圖樣式
- (NSData *)getMapData
{
  NSString *path = [NSString stringWithFormat:@"%@/gaodeMapStyle.data", [NSBundle mainBundle].bundlePath];
  NSData *data = [NSData dataWithContentsOfFile:path];
  return data;
}

- (void)viewDidLoad
{
  [super viewDidLoad];
  self.mapView.showsScale = _showScale;
  self.mapView.showsCompass = _compass;
  [self.mapView setCenterCoordinate:_centerCoordinate];
  [self.mapView setZoomLevel:_zoomLevel];
}

// 添加覆蓋物
- (void)insertSubview:(WXComponent *)subcomponent atIndex:(NSInteger)index
{
  if ([subcomponent isKindOfClass:[DMapRenderer class]]) {
    DMapRenderer *overlayRenderer = (DMapRenderer *)subcomponent;
    [self addOverlay:overlayRenderer];
  }else if ([subcomponent isKindOfClass:[DMapViewMarkerComponent class]]) {
    [self addMarker:(DMapViewMarkerComponent *)subcomponent];
  }
}
// 更新屬性
- (void)updateAttributes:(NSDictionary *)attributes
{
...
  if (attributes[@"zoom"]) {
    [self setZoomLevel:[attributes[@"zoom"] floatValue]];
  }
 ...
}
#pragma mark - component interface
- (void)setAPIKey:(NSString *)appKey
{
  [AMapServices sharedServices].apiKey = appKey;
}
- (void)setZoomLevel:(CGFloat)zoom
{
  [self.mapView setZoomLevel:zoom animated:YES];
}
#pragma mark - publish method
- (NSDictionary *)getUserLocation
{
  if(self.mapView.userLocation.updating && self.mapView.userLocation.location) {
    NSArray *coordinate = @[[NSNumber numberWithDouble:self.mapView.userLocation.location.coordinate.longitude],[NSNumber numberWithDouble:self.mapView.userLocation.location.coordinate.latitude]];
    NSDictionary *userDic = @{@"result":@"success",@"data":@{@"position":coordinate,@"title":@""}};
    return userDic;
  }
  return @{@"resuldt":@"false",@"data":@""};
}

#pragma mark - mapview delegate
/*!
 @brief 根據(jù)anntation生成對應(yīng)的View
 */
- (MAAnnotationView*)mapView:(MAMapView *)mapView viewForAnnotation:(id <MAAnnotation>)annotation
{
  if ([annotation isKindOfClass:[MAPointAnnotation class]])
  {
    MAPointAnnotation *pointAnnotation = (MAPointAnnotation *)annotation;
    if ([pointAnnotation.component isKindOfClass:[WXMapInfoWindowComponent class]]) {
      return [self _generateCustomInfoWindow:mapView viewForAnnotation:pointAnnotation];

    }else {
      return [self _generateAnnotationView:mapView viewForAnnotation:pointAnnotation];
    }
  }

  return nil;
}

/**
 * @brief 當(dāng)選中一個(gè)annotation views時(shí),調(diào)用此接口
 * @param mapView 地圖View
 * @param view 選中的annotation views
 */
- (void)mapView:(MAMapView *)mapView didSelectAnnotationView:(MAAnnotationView *)view
{
  MAPointAnnotation *annotation = view.annotation;
  for (WXComponent *component in self.subcomponents) {
    if ([component isKindOfClass:[WXMapViewMarkerComponent class]] &&
      [component.ref isEqualToString:annotation.component.ref]) {
      WXMapViewMarkerComponent *marker = (WXMapViewMarkerComponent *)component;
      if (marker.clickEvent) {
        [marker fireEvent:marker.clickEvent params:[NSDictionary dictionary]];
      }
    }
  }
}

/**
 * @brief 當(dāng)取消選中一個(gè)annotation views時(shí),調(diào)用此接口
 * @param mapView 地圖View
 * @param view 取消選中的annotation views
 */
- (void)mapView:(MAMapView *)mapView didDeselectAnnotationView:(MAAnnotationView *)view
{

}

/**
 * @brief 地圖移動(dòng)結(jié)束后調(diào)用此接口
 * @param mapView    地圖view
 * @param wasUserAction 標(biāo)識是否是用戶動(dòng)作
 */
- (void)mapView:(MAMapView *)mapView mapDidMoveByUser:(BOOL)wasUserAction
{
  if (_isDragend) {
    [self fireEvent:@"dragend" params:[NSDictionary dictionary]];
  }
}

/**設(shè)置地圖縮放級別 */
- (void)setMapViewRegion:(NSMutableArray *)poiArray animated:(BOOL)animated {
  NSMutableArray *arrays = [NSMutableArray array];
  for (MAPointAnnotation *anot in self.mapView.annotations) {
    CLLocationCoordinate2D coordinate = anot.coordinate;
    NSDictionary *poidic = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:coordinate.latitude * 1000000], @"lat",
                [NSNumber numberWithInt:coordinate.longitude * 1000000], @"lng", nil];
    [arrays addObject:poidic];
  }

  MACoordinateRegion region = [self getCoordinateMapSpan:arrays];
  [self.mapView setRegion:region animated:animated];
}

/**配置地圖region */
- (MACoordinateRegion)getCoordinateMapSpan:(NSMutableArray *)knightArray {
  MACoordinateRegion region;
  MACoordinateSpan span;

  CLLocationDegrees maxLat = -90;
  CLLocationDegrees maxLon = -180;
  CLLocationDegrees minLat = 90;
  CLLocationDegrees minLon = 180;

  if (knightArray && knightArray.count > 1) {
    for (int i = 0; i < knightArray.count; i++) {
      NSDictionary *knightDictionary = [knightArray objectAtIndex:i];
      float lat = [[knightDictionary objectForKey:@"lat"] floatValue] / 1000000;
      float lng = [[knightDictionary objectForKey:@"lng"] floatValue] / 1000000;

      if(lat > maxLat)
        maxLat = lat;
      if(lat < minLat)
        minLat = lat;
      if(lng > maxLon)
        maxLon = lng;
      if(lng < minLon)
        minLon = lng;
    }

    span.latitudeDelta = (maxLat - minLat) * 2 + 0.005;
    span.longitudeDelta = (maxLon - minLon) * 2 + 0.005;
    region.center.latitude = (maxLat + minLat) / 2;
    region.center.longitude = (maxLon + minLon) / 2;
    region.span = span;
  } else {
    NSDictionary *knightDictionary = [knightArray objectAtIndex:0];
    span.latitudeDelta = 0.01;
    span.longitudeDelta = 0.01;
    float lat = [[knightDictionary objectForKey:@"lat"] floatValue] / 1000000;
    float lng = [[knightDictionary objectForKey:@"lng"] floatValue] / 1000000;
    if (lat !=0 && lng != 0) {
      region.center.longitude = lng;
      region.center.latitude = lat;
    } else {
      region.center = [[ShopLocateManager shared] getLocationCoordinate];
    }
    region.span = span;
  }

  return region;
}
...
@end

2.2 weex-amap-marker

marker主要用于實(shí)現(xiàn)錨點(diǎn),其效果如下:

如何在iOS中集成weex-amap

要在Weex中自定義錨點(diǎn),需要遵循以下幾步:

  • 新建DMapViewMarkerComponent類繼承WXComponent;

  • 在DMapViewComponent中使用mapview的addAnnotation方法添加DMapViewMarkerComponent組件;

  • 在DMapViewComponent重寫insertSubview方法來添加子組建覆蓋物。

部分實(shí)現(xiàn)代碼如下:

- (instancetype)initWithRef:(NSString *)ref
            type:(NSString*)type
           styles:(nullable NSDictionary *)styles
         attributes:(nullable NSDictionary *)attributes
           events:(nullable NSArray *)events
        weexInstance:(WXSDKInstance *)weexInstance
{
  self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance];
  if (self) {
    if ([events containsObject:@"click"]) {
      _clickEvent = @"click";
    }
    NSArray *offset = attributes[@"offset"];
    if ([WXConvert isValidatedArray:offset]) {
      _offset = CGPointMake([WXConvert CGFloat:offset[0]],
                 [WXConvert CGFloat:offset[1]]);//[WXConvert sizeToWXPixelType:attributes[@"offset"] withInstance:self.weexInstance];
    }
    if (styles[@"zIndex"]) {
      _zIndex = [styles[@"zIndex"] integerValue];
    }
    _hideCallout = [[attributes map_safeObjectForKey:@"hideCallout"] boolValue];
    NSArray *position = [attributes map_safeObjectForKey:@"position"];
    if ([WXConvert isValidatedArray:position]) {
      _location = [attributes map_safeObjectForKey:@"position"];
    }
    _title = [attributes map_safeObjectForKey:@"title"];
    _icon = [attributes map_safeObjectForKey:@"icon"];
  }
  return self;
}

- (void)updateAttributes:(NSDictionary *)attributes
{
  DMapViewComponent *mapComponent = (DMapViewComponent *)self.supercomponent;
  if (attributes[@"title"]) {
    _title = attributes[@"title"];
    [mapComponent updateTitleMarker:self];
  }

  if ([attributes map_safeObjectForKey:@"icon"]) {
    _icon = attributes[@"icon"];
    [mapComponent updateIconMarker:self];
  }

  NSArray *position = [attributes map_safeObjectForKey:@"position"];
  if ([WXConvert isValidatedArray:position]) {
    _location = position;
    [mapComponent updateLocationMarker:self];
  }
}

weex-amap-info-window

weex-amap-info-window組件主要用于顯示地圖信息,如地圖的圖片模式,其效果如下:

如何在iOS中集成weex-amap

要自定義窗體組件,需要用到以下幾個(gè)步驟:

  • 新建DMapInfoWindowComponent類繼承WXComponent;

  • 在DMapViewComponent中使用mapview的addAnnotation方法添加DMapInfoWindowComponent組件;

  • 在DMapViewComponent重寫insertSubview方法來添加子組建信息窗體。

部分實(shí)現(xiàn)代碼如下:

- (instancetype)initWithRef:(NSString *)ref
            type:(NSString*)type
           styles:(nullable NSDictionary *)styles
         attributes:(nullable NSDictionary *)attributes
           events:(nullable NSArray *)events
        weexInstance:(WXSDKInstance *)weexInstance
{
  self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance];
  if (self) {
    if (attributes[@"open"]) {
      _isOpen = [attributes[@"open"] boolValue];
    }

  }
  return self;
}

- (UIView *) loadView
{
  return [[DMapInfoWindow alloc] initWithAnnotation:_annotation reuseIdentifier:_identifier];
}

- (void)insertSubview:(WXComponent *)subcomponent atIndex:(NSInteger)index{}
- (void)updateAttributes:(NSDictionary *)attributes
{
  [super updateAttributes:attributes];
  if (attributes[@"open"])
  {
    _isOpen = [attributes[@"open"] boolValue];
    if (_isOpen) {
      [self _addSubView];
    }else {
      [self _removeViewFromSuperView];
    }
  }
}

#pragma mark - private method
 1. (void)_addSubView
{
  [self _removeViewFromSuperView];
  [(DMapViewComponent *)self.supercomponent addMarker:self];
}

 2. (void)_removeViewFromSuperView
{
  [(DMapViewComponent *)self.supercomponent removeMarker:self];
}

2.4 weex-amap-circle

weex-amap-circle組件主要用于實(shí)現(xiàn)畫圈功能,如地圖范圍,其效果如下圖所示:

如何在iOS中集成weex-amap

  • 新建DMapCircleComponent類繼承WXComponent;

  • 在DMapViewComponent中使用mapview的addOverlay方法添加DMapCircleComponent組件;

  • 在DMapViewComponent重寫insertSubview方法來添加子組建圓。

下面是部分實(shí)現(xiàn)邏輯:

- (instancetype)initWithRef:(NSString *)ref
            type:(NSString*)type
           styles:(nullable NSDictionary *)styles
         attributes:(nullable NSDictionary *)attributes
           events:(nullable NSArray *)events
        weexInstance:(WXSDKInstance *)weexInstance
{
  self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance];
  if (self) {
    NSArray *centerArray = [attributes map_safeObjectForKey:@"center"];
    if ([WXConvert isValidatedArray:centerArray]) {
      _center = centerArray;
    }
    _radius = [[attributes map_safeObjectForKey:@"radius"] doubleValue];
  }
  return self;
}

- (void)updateAttributes:(NSDictionary *)attributes
{
  NSArray *centerArray = [attributes map_safeObjectForKey:@"center"];
  DMapViewComponent *parentComponent = (DMapViewComponent *)self.supercomponent;
  if ([WXConvert isValidatedArray:centerArray]) {
    _center = centerArray;
    [parentComponent removeOverlay:self];
    [parentComponent addOverlay:self];
  }else if ([[attributes map_safeObjectForKey:@"radius"] doubleValue] >= 0) {
    _radius = [[attributes map_safeObjectForKey:@"radius"] doubleValue];
    [parentComponent removeOverlay:self];
    [parentComponent addOverlay:self];
  }else {
    [super updateAttributes:attributes];
  }
}

2.5 weex-amap-polygon

weex-amap-polygon主要用于繪制多邊形,其效果如下圖:

如何在iOS中集成weex-amap

要自定義weex-amap-polygon,可以從以下步驟著手:

  • 新建DMapPolygonComponent類繼承WXComponent;

  • 在DMapViewComponent中使用mapview的addOverlay方法添加DMapPolygonComponent組件;

  • 在DMapViewComponent重寫insertSubview方法來添加子組建多邊形。

部分實(shí)現(xiàn)代碼如下:

- (instancetype)initWithRef:(NSString *)ref
            type:(NSString*)type
           styles:(nullable NSDictionary *)styles
         attributes:(nullable NSDictionary *)attributes
           events:(nullable NSArray *)events
        weexInstance:(WXSDKInstance *)weexInstance
{
  self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance];
  if (self) {
    _fillColor = [attributes map_safeObjectForKey:@"fillColor"];
    _fillOpacity = [attributes map_safeObjectForKey:@"fillOpacity"];
  }
  return self;
}

- (void)updateAttributes:(NSDictionary *)attributes
{
  if ([attributes map_safeObjectForKey:@"fillColor"]) {
    _fillColor = [attributes map_safeObjectForKey:@"fillColor"];
  }else if ([attributes map_safeObjectForKey:@"fillOpacity"]) {
    _fillOpacity = [attributes map_safeObjectForKey:@"fillOpacity"];
  }else {
    [super updateAttributes:attributes];
  }
}

2.6 weex-amap-polyline

weex-amap-polyline組件主要用于在地圖上實(shí)現(xiàn)劃線操作,其最終效果如下圖:

如何在iOS中集成weex-amap

在iOS中,自定義直接需要從以下幾步著手:

  1. 新建DMapPolylineComponent類繼承WXComponent;

  2. 在DMapViewComponent中使用mapview的addOverlay方法添加DMapPolylineComponent組件;

  3. 在DMapViewComponent重寫insertSubview方法來添加子組建折線。

@implementation DMapPolylineComponent


- (instancetype)initWithRef:(NSString *)ref
            type:(NSString*)type
           styles:(nullable NSDictionary *)styles
         attributes:(nullable NSDictionary *)attributes
           events:(nullable NSArray *)events
        weexInstance:(WXSDKInstance *)weexInstance
{
  self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance];
  if (self) {
    NSArray * pathArray = [attributes map_safeObjectForKey:@"path"];
    if ([WXConvert isValidatedArray:pathArray]) {
      _path = pathArray;
    }
    _strokeColor = [attributes map_safeObjectForKey:@"strokeColor"];
    _strokeWidth = [[attributes map_safeObjectForKey:@"strokeWidth"] doubleValue];
    _strokeOpacity = [[attributes map_safeObjectForKey:@"strokeOpacity"] doubleValue];
    _strokeStyle = [attributes map_safeObjectForKey:@"strokeStyle"];
  }
  _viewLoaded = NO;
  return self;
}

- (void)updateAttributes:(NSDictionary *)attributes
{
  NSArray * pathArray = [attributes map_safeObjectForKey:@"path"];
  DMapViewComponent *parentComponent = (DMapViewComponent *)self.supercomponent;
  if (pathArray) {
    if ([WXConvert isValidatedArray:pathArray]) {
      _path = pathArray;
    }
    [parentComponent removeOverlay:self];
    [parentComponent addOverlay:self];
    return;
  }else if ([attributes map_safeObjectForKey:@"strokeColor"]) {
    _strokeColor = [attributes map_safeObjectForKey:@"strokeColor"];
  }else if ([[attributes map_safeObjectForKey:@"strokeWidth"] doubleValue] >= 0) {
    _strokeWidth = [[attributes map_safeObjectForKey:@"strokeWidth"] doubleValue];
  }else if ([[attributes map_safeObjectForKey:@"strokeOpacity"] doubleValue] >= 0) {
    _strokeOpacity = [[attributes map_safeObjectForKey:@"strokeOpacity"] doubleValue];
  }else if ([attributes map_safeObjectForKey:@"strokeStyle"]) {
    _strokeStyle = [attributes map_safeObjectForKey:@"strokeStyle"];
  }
  [parentComponent updateOverlayAttributes:self];
}

@end

地圖組件擴(kuò)展

當(dāng)然,我們也可以不使用weex-amap,而是直接使用高德地圖進(jìn)行擴(kuò)展。

3.1 weex-amap

例如,我們自己擴(kuò)展一個(gè)基于原生高德SDK生成的weex-amap組件。

如何在iOS中集成weex-amap

要實(shí)現(xiàn)這么一個(gè)地圖顯示的功能,實(shí)現(xiàn)的步驟如下:

  • 新建DMapViewComponent類繼承WXVContainer實(shí)現(xiàn)LocationSource;

  • 使用initComponentHostView(context)初始化;

  • 在DMapViewComponent實(shí)現(xiàn)文件中實(shí)現(xiàn)初始化map對象initMap,設(shè)置map的key;

  • @WXComponentProp注解實(shí)現(xiàn)屬性綁定;

  • 通過fireEvent添加適當(dāng)時(shí)機(jī)可以觸發(fā)的事件;

  • 設(shè)置mapview的setInfoWindowAdapter,addPolyline,addPolygon,addCircle,addMarker等方式來實(shí)現(xiàn)覆蓋物,,線,圓等等。

實(shí)現(xiàn)代碼可以參考下面的代碼:

 @Override
  protected FrameLayout initComponentHostView(@NonNull Context context) {
    mapContainer = new FrameLayout(context) {
      @Override
      public boolean onInterceptTouchEvent(MotionEvent ev) {
        // 解決與Scroller的滑動(dòng)沖突
        if (ev.getAction() == MotionEvent.ACTION_UP) {
          requestDisallowInterceptTouchEvent(false);
        } else {
          requestDisallowInterceptTouchEvent(true);
        }
        return false;
      }
    };
    mapContainer.setBackgroundColor(fakeBackgroundColor);
    if (context instanceof Activity) {
      mActivity = (Activity) context;
    }

    return mapContainer;
  }

  @Override
  protected void setHostLayoutParams(FrameLayout host, int width, int height, int left, int right, int top, int bottom) {
    super.setHostLayoutParams(host, width, height, left, right, top, bottom);
    if (!isMapLoaded.get() && !isInited.get()) {
      isInited.set(true);
      mapContainer.postDelayed(new Runnable() {
        @Override
        public void run() {
          mMapView = new TextureMapView(getContext());
          mapContainer.addView(mMapView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
              ViewGroup.LayoutParams.MATCH_PARENT));
          WXLogUtils.e(TAG, "Create MapView " + mMapView.toString());
          initMap();
        }
      }, 0);
    }
  }

  private void initMap() {
    mMapView.onCreate(null);
    isMapLoaded.set(false);
    if (mAMap == null) {
      mAMap = mMapView.getMap();

      mAMap.setInfoWindowAdapter(new InfoWindowAdapter(this));
      mAMap.setOnMapLoadedListener(new AMap.OnMapLoadedListener() {
        @Override
        public void onMapLoaded() {
          WXLogUtils.e(TAG, "Map loaded");
          isMapLoaded.set(true);
          mZoomLevel = mAMap.getCameraPosition().zoom;
          mMapView.postDelayed(new Runnable() {
            @Override
            public void run() {
              execPaddingTasks();
            }
          }, 16);
        }
      });

      // 綁定 Marker 被點(diǎn)擊事件
      mAMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {
        // marker 對象被點(diǎn)擊時(shí)回調(diào)的接口
        // 返回 true 則表示接口已響應(yīng)事件,否則返回false
        @Override
        public boolean onMarkerClick(Marker marker) {

          if (marker != null) {
            for (int i = 0; i < getChildCount(); i++) {
              if (getChild(i) instanceof DMapMarkerComponent) {
                DMapMarkerComponent child = (DMapMarkerComponent) getChild(i);
                if (child.getMarker() != null && child.getMarker().getId() == marker.getId()) {
                  child.onClick();
                }
              }
            }
          }
          return false;
        }
      });
      mAMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {

        private boolean mZoomChanged;

        @Override
        public void onCameraChange(CameraPosition cameraPosition) {
          mZoomChanged = mZoomLevel != cameraPosition.zoom;
          mZoomLevel = cameraPosition.zoom;
        }

        @Override
        public void onCameraChangeFinish(CameraPosition cameraPosition) {
          if (mZoomChanged) {

            float scale = mAMap.getScalePerPixel();
            float scaleInWeex = scale / WXViewUtils.getWeexPxByReal(scale);

            VisibleRegion visibleRegion = mAMap.getProjection().getVisibleRegion();
            WXLogUtils.d(TAG, "Visible region: " + visibleRegion.toString());
            Map<String, Object> region = new HashMap<>();
            region.put("northeast", convertLatLng(visibleRegion.latLngBounds.northeast));
            region.put("southwest", convertLatLng(visibleRegion.latLngBounds.southwest));

            Map<String, Object> data = new HashMap<>();
            data.put("targetCoordinate", cameraPosition.target.toString());
            data.put("zoom", cameraPosition.zoom);
            data.put("tilt", cameraPosition.tilt);
            data.put("bearing", cameraPosition.bearing);
            data.put("isAbroad", cameraPosition.isAbroad);
            data.put("scalePerPixel", scaleInWeex);
            data.put("visibleRegion", region);
            getInstance().fireEvent(getRef(), WeexConstant.EVENT.ZOOM_CHANGE, data);
          }
        }
      });

      mAMap.setOnMapTouchListener(new AMap.OnMapTouchListener() {
        boolean dragged = false;

        @Override
        public void onTouch(MotionEvent motionEvent) {

          switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_MOVE:
              dragged = true;
              break;
            case MotionEvent.ACTION_UP:
              if (dragged)
                getInstance().fireEvent(getRef(), WeexConstant.EVENT.DRAG_CHANGE);
              dragged = false;
              break;
          }
        }
      });
      setUpMap();
    }
  }
}

3.2 weex-amap-info-window

當(dāng)然,我們也可以使用它實(shí)現(xiàn)weex-amap-info-window功能,雖然weex-amap-info-window已經(jīng)被內(nèi)置到weex-amap中。是的的思路如下:

新建DMapViewMarkerComponent類繼承WXComponent;

在DMapViewComponent中使用mapview的addMarker方法添加DMapViewMarkerComponent組件 。

在DMapViewComponent中使用mapview的addMarker方法添加DMapViewMarkerComponent組件 。

private static class InfoWindowAdapter implements AMap.InfoWindowAdapter {

    private DMapViewComponent mWXMapViewComponent;

    InfoWindowAdapter(DMapViewComponent wxMapViewComponent) {
      mWXMapViewComponent = wxMapViewComponent;
    }

    @Override
    public View getInfoWindow(Marker marker) {
      return render(marker);
    }

    @Override
    public View getInfoContents(Marker marker) {
      return null;
//      return render(marker);
    }

    private View render(Marker marker) {
      WXMapInfoWindowComponent wxMapInfoWindowComponent = mWXMapViewComponent.mInfoWindowHashMap.get(marker.getId());
      if (wxMapInfoWindowComponent != null) {
        WXFrameLayout host = wxMapInfoWindowComponent.getHostView();
//        WXFrameLayout content = (WXFrameLayout) host.getChildAt(0);
        host.getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
        host.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
        WXLogUtils.d(TAG, "Info size: " + host.getMeasuredWidth() + ", " + host.getMeasuredHeight());
        return host;
      } else {
        WXLogUtils.e(TAG, "WXMapInfoWindowComponent with marker id " + marker.getId() + " not found");
      }
      return null;
    }
  }

html5地圖組件擴(kuò)展

當(dāng)然,我們可以使用對html5的amap進(jìn)行擴(kuò)展,例如擴(kuò)展weex-amap。

4.1 weex-amap

如何在iOS中集成weex-amap

示例代碼如下:

<template> 
  <div class="amap-page-container">
   <el-amap ref="map" vid="amapDemo" :amap-manager="amapManager" :center="center" :zoom="zoom" :plugin="plugin" :events="events" class="amap-demo">
   </el-amap>

   <div class="toolbar">
    <button @click="getMap()">get map</button>
   </div>
  </div>
 </template>

 <style>
  .amap-demo {
   height: 300px;
  }
 </style>

 <script>
  // NPM 方式
  // import { AMapManager } from 'vue-amap';
  // CDN 方式
  let amapManager = new VueAMap.AMapManager();
  module.exports = {
   data: function() {
    return {
     amapManager,
     zoom: 12,
     center: [121.59996, 31.197646],
     events: {
      init: (o) => {
       console.log(o.getCenter())
       console.log(this.$refs.map.$$getInstance())
       o.getCity(result => {
        console.log(result)
       })
      },
      'moveend': () => {
      },
      'zoomchange': () => {
      },
      'click': (e) => {
       alert('map clicked');
      }
     },
     plugin: ['ToolBar', {
      pName: 'MapType',
      defaultType: 0,
      events: {
       init(o) {
        console.log(o);
       }
      }
     }]
    };
   },

   methods: {
    getMap() {
     // amap vue component
     console.log(amapManager._componentMap);
     // gaode map instance
     console.log(amapManager._map);
    }
   }
  };
</script>

4.2 weex-amap-marker

如何在iOS中集成weex-amap

實(shí)現(xiàn)代碼如下:

<template> 
  <div class="amap-page-container">
   <el-amap vid="amapDemo" :zoom="zoom" :center="center" class="amap-demo">
    <el-amap-marker vid="component-marker" :position="componentMarker.position" :content-render="componentMarker.contentRender" ></el-amap-marker>
    <el-amap-marker v-for="(marker, index) in markers" :position="marker.position" :events="marker.events" :visible="marker.visible" :draggable="marker.draggable" :vid="index"></el-amap-marker>
   </el-amap>
   <div class="toolbar">
    <button type="button" name="button" v-on:click="toggleVisible">toggle first marker</button>
    <button type="button" name="button" v-on:click="changePosition">change position</button>
    <button type="button" name="button" v-on:click="chnageDraggle">change draggle</button>
    <button type="button" name="button" v-on:click="addMarker">add marker</button>
    <button type="button" name="button" v-on:click="removeMarker">remove marker</button>
   </div>
  </div>
 </template>

 <style>
  .amap-demo {
   height: 300px;
  }
 </style>

 <script>
  const exampleComponents = {
   props: ['text'],
   template: `<div>text from parent: {{text}}</div>`
  }
  module.exports = {
   name: 'amap-page',
   data() {
    return {
     count: 1,
     slotStyle: {
      padding: '2px 8px',
      background: '#eee',
      color: '#333',
      border: '1px solid #aaa'
     },
     zoom: 14,
     center: [121.5273285, 31.21515044],
     markers: [
      {
       position: [121.5273285, 31.21515044],
       events: {
        click: () => {
         alert('click marker');
        },
        dragend: (e) => {
         console.log('---event---: dragend')
         this.markers[0].position = [e.lnglat.lng, e.lnglat.lat];
        }
       },
       visible: true,
       draggable: false,
       template: '<span>1</span>',
      }
     ],
     renderMarker: {
      position: [121.5273285, 31.21715058],
      contentRender: (h, instance) => {
       // if use jsx you can write in this
       // return <div style={{background: '#80cbc4', whiteSpace: 'nowrap', border: 'solid #ddd 1px', color: '#f00'}} onClick={() => ...}>marker inner text</div>
       return h(
        'div',
        {
         style: {background: '#80cbc4', whiteSpace: 'nowrap', border: 'solid #ddd 1px', color: '#f00'},
         on: {
          click: () => {
           const position = this.renderMarker.position;
           this.renderMarker.position = [position[0] + 0.002, position[1] - 0.002];
          }
         }
        },
        ['marker inner text']
       )
      }
     },
     componentMarker: {
      position: [121.5273285, 31.21315058],
      contentRender: (h, instance) => h(exampleComponents,{style: {backgroundColor: '#fff'}, props: {text: 'father is here'}}, ['xxxxxxx'])
     },
     slotMarker: {
      position: [121.5073285, 31.21715058]
     }
    };
   },
   methods: {
    onClick() {
     this.count += 1;
    },
    changePosition() {
     let position = this.markers[0].position;
     this.markers[0].position = [position[0] + 0.002, position[1] - 0.002];
    },
    chnageDraggle() {
     let draggable = this.markers[0].draggable;
     this.markers[0].draggable = !draggable;
    },
    toggleVisible() {
     let visableVar = this.markers[0].visible;
     this.markers[0].visible = !visableVar;
    },
    addMarker() {
     let marker = {
      position: [121.5273285 + (Math.random() - 0.5) * 0.02, 31.21515044 + (Math.random() - 0.5) * 0.02]
     };
     this.markers.push(marker);
    },
    removeMarker() {
     if (!this.markers.length) return;
     this.markers.splice(this.markers.length - 1, 1);
    }
   }
  };
</script>

4.3 weex-amap-info-window

如何在iOS中集成weex-amap

<template> 
  <div class="amap-page-container">
   <el-amap vid="amap" :zoom="zoom" :center="center" class="amap-demo">
    <el-amap-info-window
     :position="currentWindow.position"
     :content="currentWindow.content"
     :visible="currentWindow.visible"
     :events="currentWindow.events">
    </el-amap-info-window>
   </el-amap>
   <button @click="switchWindow(0)">Show First Window</button>
   <button @click="switchWindow(1)">Show Second Window</button>
  </div>
 </template>

 <style>
  .amap-demo {
   height: 300px;
  }
 </style>

 <script>
  module.exports = {
   data () {
    return {
     zoom: 14,
     center: [121.5273285, 31.21515044],
     windows: [
      {
       position: [121.5273285, 31.21515044],
       content: 'Hi! I am here!',
       visible: true,
       events: {
        close() {
         console.log('close infowindow1');
        }
       }
      }, {
       position: [121.5375285, 31.21515044],
       content: 'Hi! I am here too!',
       visible: true,
       events: {
        close() {
         console.log('close infowindow2');
        }
       }
      }
     ],
     slotWindow: {
      position: [121.5163285, 31.21515044]
     },
     currentWindow: {
      position: [0, 0],
      content: '',
      events: {},
      visible: false
     }
    }
   },

   mounted() {
    this.currentWindow = this.windows[0];
   },

   methods: {
    switchWindow(tab) {
     this.currentWindow.visible = false;
     this.$nextTick(() => {
      this.currentWindow = this.windows[tab];
      this.currentWindow.visible = true;
     });
    }
   }
  };
</script>

API

當(dāng)然,除了組件之外,我們還可以使用weex-amap的API來直接操作地圖。

5.1 騎行路徑Android實(shí)現(xiàn)

- (void)searchRidingRouteFromLat:(int)fromLat fromLng:(int)fromLng toLat:(int)toLat toLng:(int)toLng {

  AMapRidingRouteSearchRequest *request = [[AMapRidingRouteSearchRequest alloc] init];
  request.origin = [AMapGeoPoint locationWithLatitude:INT_2_FLOAT(fromLat) / 1000000
                       longitude:INT_2_FLOAT(fromLng) / 1000000];
  request.destination = [AMapGeoPoint locationWithLatitude:INT_2_FLOAT(toLat) / 1000000
                          longitude:INT_2_FLOAT(toLng) / 1000000];
  //發(fā)起路徑搜索
  [self.aMapSearch AMapRidingRouteSearch:request];
}

- (void)onRouteSearchDone:(AMapRouteSearchBaseRequest *)request response:(AMapRouteSearchResponse *)response {
  if(response.route == nil) {
    return;
  }
  //通過AMapNavigationSearchResponse對象處理搜索結(jié)果
  AMapRoute *route = response.route;
  if (route.paths.count > 0) {
    AMapPath *amapPath = route.paths[0];
    NSArray *coordArray = amapPath.steps;
    NSMutableArray *mArray = [NSMutableArray array];
    NSArray *start = @[[NSString stringWithFormat:@"%f", request.origin.longitude], [NSString stringWithFormat:@"%f", request.origin.latitude]];
    [mArray insertObject:start atIndex:0];
    for (AMapStep *step in coordArray) {
      NSString *polistring = step.polyline;
      NSArray *array = [polistring componentsSeparatedByString:@";"];
      for (NSString *str in array) {
        NSArray *loc =[str componentsSeparatedByString:@","];
        [mArray addObject:loc];
      }
    }
    NSArray *end = @[[NSString stringWithFormat:@"%f", request.destination.longitude], [NSString stringWithFormat:@"%f", request.destination.latitude]];
    [mArray insertObject:end atIndex:mArray.count];
    [[DMessageChannelManager shared] postMessage:@"mapLines" andData:@{@"result": @"success", @"data": @{@"mapLines":mArray}}];
  }
}

- (void)AMapSearchRequest:(id)request didFailWithError:(NSError *)error
{
  NSLog(@"Error: %@", error);
}

@end

5.2 騎行路徑iOS實(shí)現(xiàn)

private RouteTask.OnRouteCalculateListener calculateListener = new RouteTask.OnRouteCalculateListener() {
    @Override
    public void onRouteCalculate(RideRouteResult result, int code) {
      HashMap<String, Object> res = new HashMap<>(2);
      if (code == 1000 && result != null) {
        Map<String, Object> data = new HashMap<>(1);
        data.put("mapLines", getLatLngList(result.getPaths().get(0), routeTask.getStartPoint(), routeTask.getEndPoint()));
        res.put("result", "success");
        res.put("data", data);
      } else {
        res.put("result", "fail");
      }
      String dataJson = new Gson().toJson(res);
      NotifyDataManager.getInstance().postMessage("mapLines", dataJson);
      WXLogUtils.d("RideRouteResult Json: " + dataJson);
    }
  };
     routeTask.addRouteCalculateListener(calculateListener);

  /**
   * 通過首尾經(jīng)緯度計(jì)算走路規(guī)劃路徑中所有經(jīng)緯度
   *
   * @param fromLat
   * @param fromLng
   * @param toLat
   * @param toLng
   */
  @JSMethod
  public void searchRidingRouteFromLat(float fromLat, float fromLng, float toLat, float toLng) {
    LocationEntity fromLe = new LocationEntity();
    fromLe.lat = fromLat / 1e6;
    fromLe.lng = fromLng / 1e6;
    LocationEntity toLe = new LocationEntity();
    toLe.lat = toLat / 1e6;
    toLe.lng = toLng / 1e6;
    if (routeTask == null) {
      routeTask = RouteTask.getInstance(mWXSDKInstance.getContext());
      routeTask.addRouteCalculateListener(calculateListener);
    }
    routeTask.search(fromLe, toLe);
  }

5.3 騎行路徑Web實(shí)現(xiàn)

 let stream = weex.requireModule('stream')
  stream.fetch({
   timeout:20000,
   method: 'GET',
   url: 'https://restapi.amap.com/v4/direction/bicycling?key=87453539f02a65cd6585210fa2e64dc9&origin='+fromLng/1000000+','+fromLat/1000000+'&destination='+toLng/1000000+','+toLat/1000000,
 }, (response) => {
  if (response.status == 200) {
   let apiData = JSON.parse(response.data)

   if(apiData.data){
    var polyline= new Array(); 
    polyline[0] = apiData.data.origin.split(",");
    var polylineList = apiData.data.paths['0'].steps[0].polyline.split(";");

    for(var i=0;i<polylineList.length;i++) {
     var polylinePoint = polylineList[i].split(",");
     polyline.push(polylinePoint);
    }
    polyline.push(apiData.data.destination.split(",")); //字符分割 
    callback({"result":"success","data": {"mapLines":polyline}});

   }
  }
 }, () => {})

感謝各位的閱讀!關(guān)于“如何在iOS中集成weex-amap”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI