一、简介:

Mapbox致力于打造全球最漂亮的个性化地图。
 
在一次偶然的地图相关资料搜索过程中发现了一个很神奇又很漂亮的地图,这个地图支持高度自定义各种地图元素,比如,道路,水系,绿地,建筑物,背景色,等等。Mapbox打造的Mapbox studio地图制作虚拟工作室,就是一个很完美的地图元素个性化编辑器。另外,我们也可以把自己项目的地理信息数据上传到Mapbox云端,然后在自己项目的客户端展现出来。
 
Mapbox地图数据来源于Open Street Map(OSM)等其他地图数据供应商,和Google Map、Apple Map等地图厂商的地图数据来源差不多。
 
 

二、使用:

1、注册账号:

在 https://www.mapbox.com 网址找到 sign up 注册一个开发者账号。
进入个人中心后,我们能看到 Integrate Mapbox 字样,我们点进去,然后根据网页的引导,我们最终会得到一个
和我们的项目相关的 Access tokens ,这个 tokens 就是我们访问SDK的唯一key,
 
选择SDK平台,这里我们选择iOS
然后选择 Cocoapod 安装方式:
再接下来我们就能看到 Access tokens 了:

2、引入工程:

这里我们使用下载好的 Mapbox.framework 做示例,当然使用 cocoa pod 也行。
  • 把Mapbox.frameworks 文件拖拽到 “ 项目 -> TARGETS -> Build Phases -> Embed Frameworks ” 这个路径下;
  • 在路径 “项目 -> TARGETS -> Build Phases ->  +  -> New Run Script phase” 粘贴一串 shel l脚本代码 : 
    bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mapbox.framework/strip-frameworks.sh"
 
 
接下来把我们的 Access tokens 填写到项目工程的 Info.plist 文件中:
  • 在Info.plist 文件中添加 key 为 MGLMapboxAccessToken 其值为【Access tokens】 字符串;
  • 在Info.plist 文件中添加 key 为 NSLocationWhenInUseUsageDescription 其值为 bool 类型的 YES;

 

3、Mapbox.framework类的使用:

【1】加载地图:

  1.  
    #import "LoadMapboxViewController.h"
  2.  
    #import <Mapbox/Mapbox.h>
  3.  
     
  4.  
    @interface LoadMapboxViewController ()<MGLMapViewDelegate>
  5.  
     
  6.  
    @property (nonatomic, strong) MGLMapView *mapView;
  7.  
     
  8.  
    @end
  9.  
     
  10.  
    @implementation LoadMapboxViewController
  11.  
     
  12.  
    - (void)viewDidLoad {
  13.  
    [super viewDidLoad];
  14.  
    // Do any additional setup after loading the view.
  15.  
     
  16.  
    self.title = @"加载地图";
  17.  
     
  18.  
    [self.view addSubview:self.mapView];
  19.  
    }
  20.  
     
  21.  
    - (MGLMapView *)mapView {
  22.  
    if (_mapView == nil) {
  23.  
    //设置地图的 frame 和 地图个性化样式
  24.  
    _mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:[NSURL URLWithString:@"mapbox://styles/mapbox/streets-v10"]];
  25.  
    _mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  26.  
    //设置地图默认显示的地点和缩放等级
  27.  
    [_mapView setCenterCoordinate:CLLocationCoordinate2DMake(39.980528, 116.306745) zoomLevel:15 animated:YES];
  28.  
    //显示用户位置
  29.  
    _mapView.showsUserLocation = YES;
  30.  
    //定位模式
  31.  
    _mapView.userTrackingMode = MGLUserTrackingModeFollow;
  32.  
    //是否倾斜地图
  33.  
    _mapView.pitchEnabled = YES;
  34.  
    //是否旋转地图
  35.  
    _mapView.rotateEnabled = NO;
  36.  
    //代理
  37.  
    _mapView.delegate = self;
  38.  
    }
  39.  
    return _mapView;
  40.  
    }
  41.  
     
  42.  
    @end

【2】加载各种样式的地图:

我们可以通过如下代码修改地图样式:
[self.mapView setStyleURL:[NSURL URLWithString:@"mapbox://styles/mapbox/streets-v10"]];

这是所有地图已经做好的模板样式参数:

  • mapbox://styles/mapbox/streets-v10
  • mapbox://styles/mapbox/outdoors-v10
  • mapbox://styles/mapbox/light-v9
  • mapbox://styles/mapbox/dark-v9
  • mapbox://styles/mapbox/satellite-v9
  • mapbox://styles/mapbox/satellite-streets-v10
  • mapbox://styles/mapbox/navigation-preview-day-v2
  • mapbox://styles/mapbox/navigation-preview-night-v2
  • mapbox://styles/mapbox/navigation-guidance-day-v2
  • mapbox://styles/mapbox/navigation-guidance-night-v2
 

使用不同的参数呈现出来的地图风格变不一样。

【3】加载大头针和默认气泡:

  1.  
    //
  2.  
    // DefaultAnnotationCalloutViewController.m
  3.  
    // MapboxExample
  4.  
    //
  5.  
    // Created by iron on 2018/1/30.
  6.  
    // Copyright © 2018年 wangzhengang. All rights reserved.
  7.  
    //
  8.  
     
  9.  
    #import "DefaultAnnotationCalloutViewController.h"
  10.  
    #import <Mapbox/Mapbox.h>
  11.  
     
  12.  
    @interface DefaultAnnotationCalloutViewController ()<MGLMapViewDelegate>
  13.  
    @property (nonatomic, strong) MGLMapView *mapView;
  14.  
    @property (nonatomic, copy) NSArray *annotationsArray;
  15.  
    @end
  16.  
     
  17.  
    @implementation DefaultAnnotationCalloutViewController
  18.  
     
  19.  
    - (void)dealloc {
  20.  
    [_mapView removeFromSuperview];
  21.  
    _mapView.delegate = nil;
  22.  
    _mapView = nil;
  23.  
    }
  24.  
     
  25.  
    - (void)viewDidLoad {
  26.  
    [super viewDidLoad];
  27.  
     
  28.  
    [self.view addSubview:self.mapView];
  29.  
    }
  30.  
     
  31.  
    - (void)didReceiveMemoryWarning {
  32.  
    [super didReceiveMemoryWarning];
  33.  
    // Dispose of any resources that can be recreated.
  34.  
    }
  35.  
     
  36.  
     
  37.  
    - (MGLMapView *)mapView {
  38.  
    if (_mapView == nil) {
  39.  
    //设置地图的 frame 和 地图个性化样式
  40.  
    _mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:[NSURL URLWithString:@"mapbox://styles/mapbox/streets-v10"]];
  41.  
    _mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  42.  
    //设置地图默认显示的地点和缩放等级
  43.  
    [_mapView setCenterCoordinate:CLLocationCoordinate2DMake(39.980528, 116.306745) zoomLevel:15 animated:NO];
  44.  
    //显示用户位置
  45.  
    _mapView.showsUserLocation = YES;
  46.  
    //定位模式
  47.  
    _mapView.userTrackingMode = MGLUserTrackingModeNone;
  48.  
    //是否倾斜地图
  49.  
    _mapView.pitchEnabled = YES;
  50.  
    //是否旋转地图
  51.  
    _mapView.rotateEnabled = NO;
  52.  
    //代理
  53.  
    _mapView.delegate = self;
  54.  
    }
  55.  
    return _mapView;
  56.  
    }
  57.  
     
  58.  
    - (NSArray *)annotationsArray {
  59.  
    if (_annotationsArray == nil) {
  60.  
    CLLocationCoordinate2D coords[2];
  61.  
    coords[0] = CLLocationCoordinate2DMake(39.980528, 116.306745);
  62.  
    coords[1] = CLLocationCoordinate2DMake(40.000, 116.306745);
  63.  
    NSMutableArray *pointsArray = [NSMutableArray array];
  64.  
    for (NSInteger i = 0; i < 2; ++i) {
  65.  
    MGLPointAnnotation *pointAnnotation = [[MGLPointAnnotation alloc] init];
  66.  
    pointAnnotation.coordinate = coords[i];
  67.  
    pointAnnotation.title = [NSString stringWithFormat:@"title:%ld", (long)i];
  68.  
    pointAnnotation.subtitle = [NSString stringWithFormat:@"subtitle: %ld%ld%ld", (long)i,(long)i,(long)i];
  69.  
    [pointsArray addObject:pointAnnotation];
  70.  
    }
  71.  
    _annotationsArray = [pointsArray copy];
  72.  
    }
  73.  
    return _annotationsArray;
  74.  
    }
  75.  
     
  76.  
    #pragma mark MGLMapViewDelegate
  77.  
     
  78.  
    - (void)mapViewDidFinishLoadingMap:(MGLMapView *)mapView {
  79.  
    ///地图加载完成时加载大头针
  80.  
    [mapView addAnnotations:self.annotationsArray];
  81.  
    }
  82.  
     
  83.  
    - (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id<MGLAnnotation>)annotation {
  84.  
    if (![annotation isKindOfClass:[MGLPointAnnotation class]]) {
  85.  
    return nil;
  86.  
    }
  87.  
    MGLAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"MGLAnnotationView"];
  88.  
    if (annotationView == nil) {
  89.  
    annotationView = [[MGLAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"MGLAnnotationView"];
  90.  
    [annotationView setFrame:CGRectMake(0, 0, 40, 40)];
  91.  
    [annotationView setBackgroundColor:[UIColor redColor]];
  92.  
    annotationView.layer.cornerRadius = 20.f;
  93.  
    annotationView.layer.masksToBounds= YES;
  94.  
    annotationView.layer.borderColor = [UIColor whiteColor].CGColor;
  95.  
    annotationView.layer.borderWidth = 5.f;
  96.  
    }
  97.  
    return annotationView;
  98.  
    }
  99.  
     
  100.  
    ///是否显示气泡
  101.  
    -(BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id<MGLAnnotation>)annotation {
  102.  
    return YES;
  103.  
    }
  104.  
    ///完成加载大头针
  105.  
    - (void)mapView:(MGLMapView *)mapView didAddAnnotationViews:(NSArray<MGLAnnotationView *> *)annotationViews {
  106.  
    [mapView showAnnotations:self.annotationsArray edgePadding:UIEdgeInsetsMake(100, 50, 100, 50) animated:YES];
  107.  
    }
  108.  
     
  109.  
    ///气泡左侧视图
  110.  
    - (UIView *)mapView:(MGLMapView *)mapView leftCalloutAccessoryViewForAnnotation:(id<MGLAnnotation>)annotation {
  111.  
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
  112.  
    view.backgroundColor= [UIColor blueColor];
  113.  
    UILabel *lab = [[UILabel alloc] initWithFrame:view.bounds];
  114.  
    lab.text = @"左侧视图";
  115.  
    lab.textColor = [UIColor whiteColor];
  116.  
    lab.font = [UIFont systemFontOfSize:10];
  117.  
    lab.textAlignment = NSTextAlignmentCenter;
  118.  
    [view addSubview:lab];
  119.  
    return view;
  120.  
    }
  121.  
    ///气泡右侧视图,
  122.  
    - (UIView *)mapView:(MGLMapView *)mapView rightCalloutAccessoryViewForAnnotation:(id<MGLAnnotation>)annotation {
  123.  
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
  124.  
    view.backgroundColor= [UIColor greenColor];
  125.  
    UILabel *lab = [[UILabel alloc] initWithFrame:view.bounds];
  126.  
    lab.text = @"右侧视图";
  127.  
    lab.textColor = [UIColor blackColor];
  128.  
    lab.font = [UIFont systemFontOfSize:10];
  129.  
    [view addSubview:lab];
  130.  
    return view;
  131.  
    }
  132.  
     
  133.  
     
  134.  
     
  135.  
     
  136.  
    @end

【4】加载图片大头针和自定义气泡:

  • 创建一个继承 UIview 的类 CustomeMapViewCalloutView  并遵守 < MGLCalloutView > 这个协议;
  • 在 CustomeMapViewCalloutView 中实现各种需求;
          
实现自定义callout view:
  1.  
    //
  2.  
    // CustomeMapViewCalloutView.h
  3.  
    // Etoury
  4.  
    //
  5.  
    // Created by iron on 2017/5/21.
  6.  
    // Copyright © 2017年 iron. All rights reserved.
  7.  
    //
  8.  
     
  9.  
    #import <UIKit/UIKit.h>
  10.  
    #import <Mapbox/Mapbox.h>
  11.  
     
  12.  
    @interface CustomeMapViewCalloutView : UIView<MGLCalloutView>
  13.  
     
  14.  
     
  15.  
     
  16.  
    @end
  1.  
    //
  2.  
    // CustomeMapViewCalloutView.m
  3.  
    // Etoury
  4.  
    //
  5.  
    // Created by iron on 2017/5/21.
  6.  
    // Copyright © 2017年 iron. All rights reserved.
  7.  
    //
  8.  
     
  9.  
    #import "CustomeMapViewCalloutView.h"
  10.  
     
  11.  
    // Set defaults for custom tip drawing
  12.  
    static CGFloat const tipHeight = 10.0;
  13.  
    static CGFloat const tipWidth = 20.0;
  14.  
     
  15.  
    @interface CustomeMapViewCalloutView ()
  16.  
    @property (strong, nonatomic) UIButton *mainBody;
  17.  
    @end
  18.  
     
  19.  
    @implementation CustomeMapViewCalloutView {
  20.  
    id <MGLAnnotation> _representedObject;
  21.  
    __unused UIView *_leftAccessoryView;/* unused */
  22.  
    __unused UIView *_rightAccessoryView;/* unused */
  23.  
    __weak id <MGLCalloutViewDelegate> _delegate;
  24.  
    BOOL _dismissesAutomatically;
  25.  
    BOOL _anchoredToAnnotation;
  26.  
    }
  27.  
     
  28.  
    @synthesize representedObject = _representedObject;
  29.  
    @synthesize leftAccessoryView = _leftAccessoryView;/* unused */
  30.  
    @synthesize rightAccessoryView = _rightAccessoryView;/* unused */
  31.  
    @synthesize delegate = _delegate;
  32.  
    @synthesize anchoredToAnnotation = _anchoredToAnnotation;
  33.  
    @synthesize dismissesAutomatically = _dismissesAutomatically;
  34.  
     
  35.  
    - (instancetype)initWithFrame:(CGRect)frame
  36.  
    {
  37.  
    self = [super initWithFrame:frame];
  38.  
    if (self)
  39.  
    {
  40.  
    self.backgroundColor = [UIColor clearColor];
  41.  
     
  42.  
    // Create and add a subview to hold the callout’s text
  43.  
    UIButton *mainBody = [UIButton buttonWithType:UIButtonTypeSystem];
  44.  
    mainBody.backgroundColor = [self backgroundColorForCallout];
  45.  
    mainBody.tintColor = [UIColor whiteColor];
  46.  
    mainBody.contentEdgeInsets = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
  47.  
    mainBody.layer.cornerRadius = 4.0;
  48.  
    self.mainBody = mainBody;
  49.  
     
  50.  
    [self addSubview:self.mainBody];
  51.  
    }
  52.  
     
  53.  
    return self;
  54.  
    }
  55.  
     
  56.  
     
  57.  
    #pragma mark - MGLCalloutView API
  58.  
     
  59.  
    - (void)presentCalloutFromRect:(CGRect)rect inView:(UIView *)view constrainedToView:(UIView *)constrainedView animated:(BOOL)animated
  60.  
    {
  61.  
    // Do not show a callout if there is no title set for the annotation
  62.  
    if (![self.representedObject respondsToSelector:@selector(title)])
  63.  
    {
  64.  
    return;
  65.  
    }
  66.  
     
  67.  
    [view addSubview:self];
  68.  
     
  69.  
    // Prepare title label
  70.  
    [self.mainBody setTitle:self.representedObject.title forState:UIControlStateNormal];
  71.  
    [self.mainBody sizeToFit];
  72.  
     
  73.  
    if ([self isCalloutTappable])
  74.  
    {
  75.  
    // Handle taps and eventually try to send them to the delegate (usually the map view)
  76.  
    [self.mainBody addTarget:self action:@selector(calloutTapped) forControlEvents:UIControlEventTouchUpInside];
  77.  
    }
  78.  
    else
  79.  
    {
  80.  
    // Disable tapping and highlighting
  81.  
    self.mainBody.userInteractionEnabled = NO;
  82.  
    }
  83.  
     
  84.  
    // Prepare our frame, adding extra space at the bottom for the tip
  85.  
    CGFloat frameWidth = self.mainBody.bounds.size.width;
  86.  
    CGFloat frameHeight = self.mainBody.bounds.size.height + tipHeight;
  87.  
    CGFloat frameOriginX = rect.origin.x + (rect.size.width/2.0) - (frameWidth/2.0);
  88.  
    CGFloat frameOriginY = rect.origin.y - frameHeight;
  89.  
    self.frame = CGRectMake(frameOriginX, frameOriginY,
  90.  
    frameWidth, frameHeight);
  91.  
     
  92.  
    if (animated)
  93.  
    {
  94.  
    self.alpha = 0.0;
  95.  
     
  96.  
    [UIView animateWithDuration:0.2 animations:^{
  97.  
    self.alpha = 1.0;
  98.  
    }];
  99.  
    }
  100.  
    }
  101.  
     
  102.  
    - (void)dismissCalloutAnimated:(BOOL)animated
  103.  
    {
  104.  
    if (self.superview)
  105.  
    {
  106.  
    if (animated)
  107.  
    {
  108.  
    [UIView animateWithDuration:0.2 animations:^{
  109.  
    self.alpha = 0.0;
  110.  
    } completion:^(BOOL finished) {
  111.  
    [self removeFromSuperview];
  112.  
    }];
  113.  
    }
  114.  
    else
  115.  
    {
  116.  
    [self removeFromSuperview];
  117.  
    }
  118.  
    }
  119.  
    }
  120.  
     
  121.  
    // Allow the callout to remain open during panning.
  122.  
    - (BOOL)dismissesAutomatically {
  123.  
    return NO;
  124.  
    }
  125.  
     
  126.  
    - (BOOL)isAnchoredToAnnotation {
  127.  
    return YES;
  128.  
    }
  129.  
     
  130.  
    // https://github.com/mapbox/mapbox-gl-native/issues/9228
  131.  
    - (void)setCenter:(CGPoint)center {
  132.  
    center.y = center.y - CGRectGetMidY(self.bounds);
  133.  
    [super setCenter:center];
  134.  
    }
  135.  
     
  136.  
    #pragma mark - Callout interaction handlers
  137.  
     
  138.  
    - (BOOL)isCalloutTappable
  139.  
    {
  140.  
    if ([self.delegate respondsToSelector:@selector(calloutViewShouldHighlight:)]) {
  141.  
    return [self.delegate performSelector:@selector(calloutViewShouldHighlight:) withObject:self];
  142.  
    }
  143.  
     
  144.  
    return NO;
  145.  
    }
  146.  
     
  147.  
    - (void)calloutTapped
  148.  
    {
  149.  
    if ([self isCalloutTappable] && [self.delegate respondsToSelector:@selector(calloutViewTapped:)])
  150.  
    {
  151.  
    [self.delegate performSelector:@selector(calloutViewTapped:) withObject:self];
  152.  
    }
  153.  
    }
  154.  
     
  155.  
    #pragma mark - Custom view styling
  156.  
     
  157.  
    - (UIColor *)backgroundColorForCallout
  158.  
    {
  159.  
    return [UIColor darkGrayColor];
  160.  
    }
  161.  
     
  162.  
    - (void)drawRect:(CGRect)rect
  163.  
    {
  164.  
    // Draw the pointed tip at the bottom
  165.  
    UIColor *fillColor = [self backgroundColorForCallout];
  166.  
     
  167.  
    CGFloat tipLeft = rect.origin.x + (rect.size.width / 2.0) - (tipWidth / 2.0);
  168.  
    CGPoint tipBottom = CGPointMake(rect.origin.x + (rect.size.width / 2.0), rect.origin.y + rect.size.height);
  169.  
    CGFloat heightWithoutTip = rect.size.height - tipHeight - 1;
  170.  
     
  171.  
    CGContextRef currentContext = UIGraphicsGetCurrentContext();
  172.  
     
  173.  
    CGMutablePathRef tipPath = CGPathCreateMutable();
  174.  
    CGPathMoveToPoint(tipPath, NULL, tipLeft, heightWithoutTip);
  175.  
    CGPathAddLineToPoint(tipPath, NULL, tipBottom.x, tipBottom.y);
  176.  
    CGPathAddLineToPoint(tipPath, NULL, tipLeft + tipWidth, heightWithoutTip);
  177.  
    CGPathCloseSubpath(tipPath);
  178.  
     
  179.  
    [fillColor setFill];
  180.  
    CGContextAddPath(currentContext, tipPath);
  181.  
    CGContextFillPath(currentContext);
  182.  
    CGPathRelease(tipPath);
  183.  
    }
  184.  
     
  185.  
     
  186.  
     
  187.  
     
  188.  
     
  189.  
    @end

在view controller中使用自定义的callout view:

  1.  
    //
  2.  
    // CustomeAnnotationCalloutViewController.m
  3.  
    // MapboxExample
  4.  
    //
  5.  
    // Created by iron on 2018/1/30.
  6.  
    // Copyright © 2018年 wangzhengang. All rights reserved.
  7.  
    //
  8.  
     
  9.  
    #import "CustomeAnnotationCalloutViewController.h"
  10.  
    #import <Mapbox/Mapbox.h>
  11.  
    #import "CustomeMapViewCalloutView.h"
  12.  
     
  13.  
    @interface CustomeAnnotationCalloutViewController ()<MGLMapViewDelegate>
  14.  
    @property (nonatomic, strong) MGLMapView *mapView;
  15.  
    @property (nonatomic, copy) NSArray *annotationsArray;
  16.  
     
  17.  
    @end
  18.  
     
  19.  
    @implementation CustomeAnnotationCalloutViewController
  20.  
     
  21.  
     
  22.  
    - (void)dealloc {
  23.  
    [_mapView removeFromSuperview];
  24.  
    _mapView.delegate = nil;
  25.  
    _mapView = nil;
  26.  
    }
  27.  
     
  28.  
     
  29.  
    - (void)viewDidLoad {
  30.  
    [super viewDidLoad];
  31.  
     
  32.  
    [self.view addSubview:self.mapView];
  33.  
    }
  34.  
     
  35.  
     
  36.  
    - (MGLMapView *)mapView {
  37.  
    if (_mapView == nil) {
  38.  
    //设置地图的 frame 和 地图个性化样式
  39.  
    _mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:[NSURL URLWithString:@"mapbox://styles/mapbox/streets-v10"]];
  40.  
    _mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  41.  
    //设置地图默认显示的地点和缩放等级
  42.  
    [_mapView setCenterCoordinate:CLLocationCoordinate2DMake(39.980528, 116.306745) zoomLevel:15 animated:NO];
  43.  
    //显示用户位置
  44.  
    _mapView.showsUserLocation = YES;
  45.  
    //定位模式
  46.  
    _mapView.userTrackingMode = MGLUserTrackingModeNone;
  47.  
    //是否倾斜地图
  48.  
    _mapView.pitchEnabled = YES;
  49.  
    //是否旋转地图
  50.  
    _mapView.rotateEnabled = NO;
  51.  
    //代理
  52.  
    _mapView.delegate = self;
  53.  
    }
  54.  
    return _mapView;
  55.  
    }
  56.  
     
  57.  
    - (NSArray *)annotationsArray {
  58.  
    if (_annotationsArray == nil) {
  59.  
    CLLocationCoordinate2D coords[2];
  60.  
    coords[0] = CLLocationCoordinate2DMake(39.980528, 116.306745);
  61.  
    coords[1] = CLLocationCoordinate2DMake(40.000, 116.306745);
  62.  
    NSMutableArray *pointsArray = [NSMutableArray array];
  63.  
    for (NSInteger i = 0; i < 2; ++i) {
  64.  
    MGLPointAnnotation *pointAnnotation = [[MGLPointAnnotation alloc] init];
  65.  
    pointAnnotation.coordinate = coords[i];
  66.  
    pointAnnotation.title = [NSString stringWithFormat:@"title:%ld", (long)i];
  67.  
    pointAnnotation.subtitle = [NSString stringWithFormat:@"subtitle: %ld%ld%ld", (long)i,(long)i,(long)i];
  68.  
    [pointsArray addObject:pointAnnotation];
  69.  
    }
  70.  
    _annotationsArray = [pointsArray copy];
  71.  
    }
  72.  
    return _annotationsArray;
  73.  
    }
  74.  
     
  75.  
     
  76.  
    #pragma mark MGLMapViewDelegate
  77.  
    - (void)mapViewDidFinishLoadingMap:(MGLMapView *)mapView {
  78.  
    ///地图加载完成时加载大头针
  79.  
    [mapView addAnnotations:self.annotationsArray];
  80.  
    }
  81.  
     
  82.  
    - (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id<MGLAnnotation>)annotation {
  83.  
    if (![annotation isKindOfClass:[MGLPointAnnotation class]]) {
  84.  
    return nil;
  85.  
    }
  86.  
    MGLAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"MGLAnnotationView"];
  87.  
    if (annotationView == nil) {
  88.  
    annotationView = [[MGLAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"MGLAnnotationView"];
  89.  
    [annotationView setFrame:CGRectMake(0, 0, 40, 40)];
  90.  
    [annotationView setBackgroundColor:[UIColor redColor]];
  91.  
    annotationView.layer.cornerRadius = 20.f;
  92.  
    annotationView.layer.masksToBounds= YES;
  93.  
    annotationView.layer.borderColor = [UIColor whiteColor].CGColor;
  94.  
    annotationView.layer.borderWidth = 5.f;
  95.  
    }
  96.  
    return annotationView;
  97.  
    }
  98.  
     
  99.  
    ///是否显示气泡
  100.  
    -(BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id<MGLAnnotation>)annotation {
  101.  
    return YES;
  102.  
    }
  103.  
    ///完成加载大头针
  104.  
    - (void)mapView:(MGLMapView *)mapView didAddAnnotationViews:(NSArray<MGLAnnotationView *> *)annotationViews {
  105.  
    [mapView showAnnotations:self.annotationsArray edgePadding:UIEdgeInsetsMake(100, 50, 100, 50) animated:YES];
  106.  
    }
  107.  
     
  108.  
    ///加载定义callout view
  109.  
    - (id<MGLCalloutView>)mapView:(MGLMapView *)mapView calloutViewForAnnotation:(id<MGLAnnotation>)annotation {
  110.  
    CustomeMapViewCalloutView *calloutView = [[CustomeMapViewCalloutView alloc] init];
  111.  
    calloutView.representedObject = annotation;
  112.  
    return calloutView;
  113.  
    }
  114.  
     
  115.  
    ///气泡点击事件
  116.  
    - (void)mapView:(MGLMapView *)mapView tapOnCalloutForAnnotation:(id<MGLAnnotation>)annotation {
  117.  
    NSLog(@"点击了气泡: %@", annotation);
  118.  
    [mapView deselectAnnotation:annotation animated:YES];
  119.  
     
  120.  
    [self showAlertControllerWithViewContorller:self title:@"点击了气泡" message:nil leftButtonTitle:nil rightButtonTitle:@"确定"];
  121.  
    }
  122.  
     
  123.  
     
  124.  
    #pragma mark - 警告框
  125.  
    - (void)showAlertControllerWithViewContorller:(UIViewController *)viewController title:(NSString *)title message:(NSString *)message leftButtonTitle:(NSString *)leftBtnTitle rightButtonTitle:(NSString *)rightBtnTitle {
  126.  
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
  127.  
    if (leftBtnTitle) {
  128.  
    [alert addAction:[UIAlertAction actionWithTitle:leftBtnTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  129.  
     
  130.  
    }]];
  131.  
    }
  132.  
    if (rightBtnTitle) {
  133.  
    [alert addAction:[UIAlertAction actionWithTitle:rightBtnTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
  134.  
     
  135.  
    }]];
  136.  
    }
  137.  
    [viewController presentViewController:alert animated:YES completion:nil];
  138.  
    }
  139.  
     
  140.  
     
  141.  
    @end

效果如下:

【5】绘制线段和多边形:

老实说 Mapbox 的 绘制线段和多边形的相关类,相比高德地图和百度地图写的并不好,用起来很不方便,比如:
  • MGLPolygon 有 strokeColor 这个参数,却没有设置 描边线宽度和样式的参数;
  • MGLPolyline 没有 strokeColor 和 fillColor 之分,而且画虚线的代码写起来很麻烦;

总体来讲,MGLPolygon 和 MGLPolyline 这两个类没有高德地图和百度地图那样使用起来方便,另外,MGLPolyline 这个类中的 MGLShapeSource 、MGLStyleLayer 虽然使用起来很麻烦,但是相对来说倒是保持了灵活性。

为了提高 MGLPolygon 和 MGLPolyline 的使用便利性,我对 MGLPolygon 、MGLPolyline 的基类 MGLShape 扩展了几个属性:

  • @property (nonatomic, strong) UIColor *fillColor;//填充颜色
  • @property (nonatomic, assign) CGFloat fillOpacity;//填充透明度
  • @property (nonatomic, strong) UIColor *strokeColor;//描边颜色
  • @property (nonatomic, assign) BOOL isDash;//YES = 虚线/NO = 实线
  • @property (nonatomic, assign) NSInteger strokeWeight;//描边宽度
 
接下来让我们看看整体代码是如何实现的,以及最后的效果是怎样的:

MGLShape+PolygonParamer.h

  1.  
    //
  2.  
    // MGLShape+PolygonParamer.h
  3.  
    // Etoury
  4.  
    //
  5.  
    // Created by dev on 2018/1/3.
  6.  
    // Copyright © 2018年 iron. All rights reserved.
  7.  
    //
  8.  
     
  9.  
    #import <Mapbox/Mapbox.h>
  10.  
     
  11.  
    @interface MGLShape (PolygonParamer)
  12.  
     
  13.  
     
  14.  
     
  15.  
    @property (nonatomic, strong) UIColor *fillColor;//填充颜色
  16.  
    @property (nonatomic, assign) CGFloat fillOpacity;//填充透明度
  17.  
    @property (nonatomic, strong) UIColor *strokeColor;//描边颜色
  18.  
    @property (nonatomic, assign) BOOL isDash;//YES = 虚线/NO = 实线
  19.  
    @property (nonatomic, assign) NSInteger strokeWeight;//描边宽度
  20.  
     
  21.  
     
  22.  
     
  23.  
     
  24.  
    @end

MGLShape+PolygonParamer.h

  1.  
    //
  2.  
    // MGLShape+PolygonParamer.m
  3.  
    // Etoury
  4.  
    //
  5.  
    // Created by dev on 2018/1/3.
  6.  
    // Copyright © 2018年 iron. All rights reserved.
  7.  
    //
  8.  
     
  9.  
    #import "MGLShape+PolygonParamer.h"
  10.  
    #import <objc/runtime.h>
  11.  
     
  12.  
     
  13.  
    static UIColor *_fillColor;//填充颜色
  14.  
    static NSInteger _fillOpacity;//填充透明度
  15.  
    static UIColor *_strokeColor;//描边颜色
  16.  
    static BOOL _isDash;//YES = 虚线/NO = 实线
  17.  
    static NSInteger _strokeWeight;//描边宽度
  18.  
     
  19.  
     
  20.  
     
  21.  
    @implementation MGLShape (PolygonParamer)
  22.  
     
  23.  
     
  24.  
    - (void)setFillColor:(UIColor *)fillColor {
  25.  
    objc_setAssociatedObject(self, &_fillColor, fillColor, OBJC_ASSOCIATION_COPY);
  26.  
    }
  27.  
    - (UIColor *)fillColor {
  28.  
    return objc_getAssociatedObject(self, &_fillColor);
  29.  
    }
  30.  
     
  31.  
     
  32.  
    - (void)setFillOpacity:(CGFloat)fillOpacity {
  33.  
    NSNumber *fillOpacityNumber = @(fillOpacity);
  34.  
    objc_setAssociatedObject(self, &_fillOpacity, fillOpacityNumber, OBJC_ASSOCIATION_COPY);
  35.  
    }
  36.  
    - (CGFloat)fillOpacity {
  37.  
    NSNumber *fillOpacityNumber = objc_getAssociatedObject(self, &_fillOpacity);
  38.  
    return [fillOpacityNumber floatValue];
  39.  
    }
  40.  
     
  41.  
     
  42.  
    - (void)setStrokeColor:(UIColor *)strokeColor {
  43.  
    objc_setAssociatedObject(self, &_strokeColor, strokeColor, OBJC_ASSOCIATION_COPY);
  44.  
    }
  45.  
    - (UIColor *)strokeColor {
  46.  
    return objc_getAssociatedObject(self, &_strokeColor);
  47.  
    }
  48.  
     
  49.  
     
  50.  
    - (void)setIsDash:(BOOL)isDash {
  51.  
    NSNumber *isDashNumber = [NSNumber numberWithBool:isDash];
  52.  
    objc_setAssociatedObject(self, &_isDash, isDashNumber, OBJC_ASSOCIATION_COPY);
  53.  
    }
  54.  
    - (BOOL)isDash {
  55.  
    NSNumber *isDashNumber = objc_getAssociatedObject(self, &_isDash);
  56.  
    return [isDashNumber boolValue];
  57.  
    }
  58.  
     
  59.  
     
  60.  
    - (void)setStrokeWeight:(NSInteger)strokeWeight {
  61.  
    NSNumber *strokeWeightNumber = @(strokeWeight);
  62.  
    objc_setAssociatedObject(self, &_strokeWeight, strokeWeightNumber, OBJC_ASSOCIATION_COPY);
  63.  
    }
  64.  
    - (NSInteger)strokeWeight {
  65.  
    NSNumber *strokeWeightNumber = objc_getAssociatedObject(self, &_strokeWeight);
  66.  
    return [strokeWeightNumber integerValue];
  67.  
    }
  68.  
     
  69.  
     
  70.  
     
  71.  
     
  72.  
    @end

把 MGLShape+PolygonParamer引入到 view controller 中:

  1.  
    //
  2.  
    // LinePolygonMapboxViewController.m
  3.  
    // MapboxExample
  4.  
    //
  5.  
    // Created by iron on 2018/1/30.
  6.  
    // Copyright © 2018年 wangzhengang. All rights reserved.
  7.  
    //
  8.  
     
  9.  
    #import "LinePolygonMapboxViewController.h"
  10.  
    #import <Mapbox/Mapbox.h>
  11.  
    #import "MGLShape+PolygonParamer.h"
  12.  
     
  13.  
     
  14.  
    @interface LinePolygonMapboxViewController ()<MGLMapViewDelegate>
  15.  
    @property (nonatomic, strong) MGLMapView *mapView;
  16.  
     
  17.  
    @property (nonatomic, strong) MGLPolyline *blueLine;//蓝色线段
  18.  
     
  19.  
    @property (nonatomic, strong) MGLPolyline *strokeLine;//多边形边线
  20.  
    @property (nonatomic, strong) MGLPolygon *polygon;//多边形
  21.  
     
  22.  
    @end
  23.  
     
  24.  
    @implementation LinePolygonMapboxViewController
  25.  
     
  26.  
    - (void)dealloc {
  27.  
    [_mapView removeFromSuperview];
  28.  
    _mapView.delegate = nil;
  29.  
    _mapView = nil;
  30.  
    }
  31.  
     
  32.  
    - (void)viewDidLoad {
  33.  
    [super viewDidLoad];
  34.  
     
  35.  
    self.title = @"线段和多边形";
  36.  
     
  37.  
    [self.view addSubview:self.mapView];
  38.  
    }
  39.  
     
  40.  
    - (void)didReceiveMemoryWarning {
  41.  
    [super didReceiveMemoryWarning];
  42.  
    // Dispose of any resources that can be recreated.
  43.  
    }
  44.  
     
  45.  
    - (MGLMapView *)mapView {
  46.  
    if (_mapView == nil) {
  47.  
    //设置地图的 frame 和 地图个性化样式
  48.  
    _mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds styleURL:[NSURL URLWithString:@"mapbox://styles/mapbox/streets-v10"]];
  49.  
    _mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  50.  
    //设置地图默认显示的地点和缩放等级
  51.  
    [_mapView setCenterCoordinate:CLLocationCoordinate2DMake(39.980528, 116.306745) zoomLevel:8 animated:YES];
  52.  
    //显示用户位置
  53.  
    _mapView.showsUserLocation = YES;
  54.  
    //定位模式
  55.  
    _mapView.userTrackingMode = MGLUserTrackingModeNone;
  56.  
    //是否倾斜地图
  57.  
    _mapView.pitchEnabled = YES;
  58.  
    //是否旋转地图
  59.  
    _mapView.rotateEnabled = NO;
  60.  
    //代理
  61.  
    _mapView.delegate = self;
  62.  
    }
  63.  
    return _mapView;
  64.  
    }
  65.  
     
  66.  
     
  67.  
    - (MGLPolyline *)blueLine {
  68.  
    if (_blueLine == nil) {
  69.  
    CLLocationCoordinate2D coords[3];
  70.  
    coords[0] = CLLocationCoordinate2DMake(27.000, 95.356745);
  71.  
    coords[1] = CLLocationCoordinate2DMake(20.000, 105.356745);
  72.  
    coords[2] = CLLocationCoordinate2DMake(27.000, 115.356745);
  73.  
     
  74.  
    _blueLine = [MGLPolyline polylineWithCoordinates:coords count:3];
  75.  
    _blueLine.strokeColor = [UIColor blueColor];
  76.  
    _blueLine.strokeWeight = 3.f;
  77.  
    _blueLine.fillOpacity = 0.75f;
  78.  
    _blueLine.isDash = NO;
  79.  
    }
  80.  
    return _blueLine;
  81.  
    }
  82.  
     
  83.  
    - (MGLPolyline *)strokeLine {
  84.  
    if (_strokeLine == nil) {
  85.  
    CLLocationCoordinate2D coords[6];
  86.  
    coords[0] = CLLocationCoordinate2DMake(30.980528, 110.306745);
  87.  
    coords[2] = CLLocationCoordinate2DMake(30.000, 120.306745);
  88.  
    coords[1] = CLLocationCoordinate2DMake(40.000, 120.306745);
  89.  
    coords[3] = CLLocationCoordinate2DMake(40.000, 110.306745);
  90.  
    coords[4] = CLLocationCoordinate2DMake(35.000, 95.356745);
  91.  
    coords[5] = CLLocationCoordinate2DMake(30.980528, 110.306745);;
  92.  
    _strokeLine = [MGLPolyline polylineWithCoordinates:coords count:6];
  93.  
    _strokeLine.strokeColor = [UIColor blackColor];
  94.  
    _strokeLine.strokeWeight = 2.f;
  95.  
    _strokeLine.fillOpacity = 0.75f;
  96.  
    _strokeLine.isDash = YES;
  97.  
    }
  98.  
    return _strokeLine;
  99.  
    }
  100.  
     
  101.  
    - (MGLPolygon *)polygon {
  102.  
    if (_polygon == nil) {
  103.  
    CLLocationCoordinate2D coords[6];
  104.  
    coords[0] = CLLocationCoordinate2DMake(30.980528, 110.306745);
  105.  
    coords[2] = CLLocationCoordinate2DMake(30.000, 120.306745);
  106.  
    coords[1] = CLLocationCoordinate2DMake(40.000, 120.306745);
  107.  
    coords[3] = CLLocationCoordinate2DMake(40.000, 110.306745);
  108.  
    coords[4] = CLLocationCoordinate2DMake(35.000, 95.356745);
  109.  
    _polygon = [MGLPolygon polygonWithCoordinates:coords count:5];
  110.  
    _polygon.fillColor = [UIColor redColor];
  111.  
    _polygon.strokeColor = [UIColor blueColor];
  112.  
    _polygon.strokeWeight= 2.f;
  113.  
    _polygon.fillOpacity = 0.5f;
  114.  
    }
  115.  
    return _polygon;
  116.  
    }
  117.  
     
  118.  
    #pragma mark MGLMapViewDelegate
  119.  
    - (void)mapViewDidFinishLoadingMap:(MGLMapView *)mapView {
  120.  
    ///地图加载完成后绘制 线段 和 多边形
  121.  
    [mapView addOverlays:@[self.blueLine, self.strokeLine, self.polygon]];
  122.  
    ///把窗口显示到合适的范围
  123.  
    [mapView setVisibleCoordinateBounds:self.polygon.overlayBounds edgePadding:UIEdgeInsetsMake(0, 10, 200, 10) animated:YES];
  124.  
     
  125.  
    // [mapView setVisibleCoordinateBounds:self.line.overlayBounds edgePadding:UIEdgeInsetsMake(300, 10, 0, 10) animated:YES];
  126.  
    }
  127.  
     
  128.  
    - (CGFloat)mapView:(MGLMapView *)mapView alphaForShapeAnnotation:(MGLShape *)annotation {
  129.  
    ///MGLPolyline 和 MGLPolygon 都执行这个方法
  130.  
    return annotation.fillOpacity;
  131.  
    }
  132.  
     
  133.  
    - (UIColor *)mapView:(MGLMapView *)mapView strokeColorForShapeAnnotation:(MGLShape *)annotation {
  134.  
    ///MGLPolyline 和 MGLPolygon 都执行这个方法
  135.  
    if ([@"MGLPolyline" isEqualToString:NSStringFromClass([annotation class])]) {
  136.  
     
  137.  
    if (annotation.isDash) {
  138.  
    MGLShapeSource *shapeSource = [self addSourceWithShape:annotation];
  139.  
    [self.mapView.style addSource:shapeSource];
  140.  
    MGLStyleLayer *styleLayer = [self dashedLineWithStyle:shapeSource shape:annotation lineDashPattern:@[@2.f, @1.f] lineCap:MGLLineCapButt lineColor:[UIColor blackColor] lineWidth:@2];
  141.  
    [self.mapView.style addLayer:styleLayer];
  142.  
    return [UIColor clearColor];
  143.  
    } else {
  144.  
    return annotation.strokeColor;
  145.  
    }
  146.  
    } else if ([@"MGLPolygon" isEqualToString:NSStringFromClass([annotation class])]) {
  147.  
     
  148.  
    return annotation.strokeColor;
  149.  
    }
  150.  
    return annotation.strokeColor;
  151.  
    }
  152.  
     
  153.  
    - (UIColor *)mapView:(MGLMapView *)mapView fillColorForPolygonAnnotation:(MGLPolygon *)annotation {
  154.  
    /// MGLPolygon 执行这个方法, MGLPolyline 不执行这个方法
  155.  
    return annotation.fillColor;
  156.  
    }
  157.  
     
  158.  
    - (CGFloat)mapView:(MGLMapView *)mapView lineWidthForPolylineAnnotation:(MGLPolyline *)annotation {
  159.  
    ///MGLPolyline 执行这个方法, MGLPolygon 不执行
  160.  
    return annotation.strokeWeight;
  161.  
    }
  162.  
     
  163.  
    #pragma mark 画虚线
  164.  
    - (MGLShapeSource *)addSourceWithShape:(MGLShape *)shape {
  165.  
    return [[MGLShapeSource alloc] initWithIdentifier:@"DashLines" shape:shape options:nil];
  166.  
    }
  167.  
     
  168.  
    - (MGLStyleLayer *)dashedLineWithStyle:(MGLShapeSource *)shapeSource shape:(MGLShape *)shape lineDashPattern:(NSArray<NSNumber *> *)lineDashPattern lineCap:(MGLLineCap)cap lineColor:(UIColor *)lineColor lineWidth:(NSNumber *)lineWidth {
  169.  
    MGLLineStyleLayer *lineStyleLayer = [[MGLLineStyleLayer alloc] initWithIdentifier:@"DashLines" source:shapeSource];
  170.  
    //线段模型
  171.  
    lineStyleLayer.lineDashPattern = [MGLStyleValue valueWithRawValue:lineDashPattern];
  172.  
    //线段头部
  173.  
    lineStyleLayer.lineCap = [MGLStyleValue valueWithRawValue:[NSNumber numberWithInteger:cap]];
  174.  
    //线段颜色
  175.  
    lineStyleLayer.lineColor = [MGLStyleValue valueWithRawValue:lineColor];
  176.  
    //线段宽度
  177.  
    lineStyleLayer.lineWidth = [MGLStyleValue valueWithRawValue:lineWidth];
  178.  
    return lineStyleLayer;
  179.  
    }
  180.  
     
  181.  
     
  182.  
     
  183.  
     
  184.  
     
  185.  
    @end

整个代码的是用步骤是这样的:

  • 实现 MGLShape (PolygonParamer) 扩展类 MGLShape+PolygonParamer ;
  • 把 MGLShape+PolygonParamer.h 引入到  LinePolygonMapboxViewController.h 这个 view controller 中;
  • 运行看效果;

三、后续更新:

现在文章到这里只是讲述了 Mapbox 的常规使用,后续我会更新关于 多点聚合、位置方向等的使用。。。
 

四、和其他地图的对比:

五、项目代码地址:

项目示例代码在GitHub上的地址:https://github.com/wangzhengang/MapboxExample/  
如果您觉得对您有用,请在GitHub上给个星星。

Mapbox使用详解的更多相关文章

  1. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  2. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  3. EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

    前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...

  4. Java 字符串格式化详解

    Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...

  5. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

  6. Android Notification 详解——基本操作

    Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...

  7. Git初探--笔记整理和Git命令详解

    几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...

  8. Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

    Android XML shape 标签使用详解   一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...

  9. Node.js npm 详解

    一.npm简介 安装npm请阅读我之前的文章Hello Node中npm安装那一部分,不过只介绍了linux平台,如果是其它平台,有前辈写了更加详细的介绍. npm的全称:Node Package M ...

随机推荐

  1. java定时任务调度-Timer(1)

    一.定义 有且仅有一个后台线程对多个业务线程进行定时定频率的调度 二. Timer  ---->  Timer Task  (中有run();方法) 通过 new Timer().schedul ...

  2. 以Kafka Connect作为实时数据集成平台的基础架构有什么优势?

    Kafka Connect是一种用于在Kafka和其他系统之间可扩展的.可靠的流式传输数据的工具,可以更快捷和简单地将大量数据集合移入和移出Kafka的连接器.Kafka Connect为DataPi ...

  3. sql server 死锁排查

    记得以前客户在使用软件时,有偶发出现死锁问题,因为发生的时间不确定,不好做问题的重现,当时解决问题有点棘手了. 现总结下查看死锁的常用二种方式: 第一种是图形化监听: sqlserver --> ...

  4. BackBox错误,无法获得锁...资源暂时不可用...无法锁定管理目录

    今天准备给BackBox安装leafpad时,输入 sudo apt install leafpad 后出现了如下的错误提示: E: 无法获得锁 /var/lib/dpkg/lock - open ( ...

  5. Load balancer does not have available server for client

    最近在研究spring-cloud,研究zuul组件时发生下列错误: Caused by: com.netflix.client.ClientException: Load balancer does ...

  6. How nginx "location if" works

    Nginx's if directive does have some weirdness in practice. And people may misuse it when they do not ...

  7. 使用STM32Cube在STM32F7开发板上实现SD+Freertos+Fatfs

    简介 最近项目中可能需要使用到SD卡,所以需要对SD卡的配置和使用调研,在配置过程中遇到了一些问题,在此记录一下. STM32Cube配置 Pinout 只需要注意绿色部分的设定 Clock配置 这里 ...

  8. 记录一波由会话堵塞导致tomcat应用故障事件

    一.故障基本信息 发生时间 消除时间 故障历时 故障类别 影响 2018-5-17 18:14:30 2018-05-18 08:58:15 16小时 应用故障 业务瘫痪,用户投诉 二.故障现象 AP ...

  9. BZOJ4944 泳池 解题报告

    题目描述 有一个 \(n\) 行无穷列的海域,每个格子有 \(q\) 的概率安全, \(1-q\) 的概率不安全.从中框出一个面积最大的矩形,满足以下两个条件: (1)矩形内的格子均安全: (2)矩形 ...

  10. BZOJ_1251_序列终结者

    BZOJ_1251_序列终结者 [问题描述] 给定一个长度为N的序列,每个序列的元素是一个整数(废话).要支持以下三种操作: 1. 将[L,R]这个区间内的所有数加上V. 2. 将[L,R]这个区间翻 ...