集成地图的封装隔离

目的:

    将第三方地图隔离,与项目代码解耦和,实现项目内各地图(百度、高德等)的快捷切换。

思路:

    (1)集成百度地图。

    (2)实现百度地图集成设计。

    (3)实现百度地图工厂设计。

    (4)实现工厂管理。

    (5)配置文件实现一键切换

1、集成百度地图

    查看文档配置SDK(此处省略),调用方法如下:

 
 
  1.    // 创建百度地图
  2.    BMKMapView *mapView = [[BMKMapView alloc] initWithFrame:self.view.frame];
  3.    // 添加绑定
  4.    [self.view addSubview:mapView];

问题分析:切换地图时,所有用到百度地图的模块都需要修改。耦合度高,不易修改。


2、实现百度地图集成设计

    分析百度地图和高德地图的API:所有地图SDK-MapView都是UIView子类。定义MapView标准(协议)。    实现百度地图集成封装

(1)定义地图协议:

 
 
  1. #import <UIKit/UIKit.h>
  2. // 地图协议(标准)
  3. @protocol IMapView <NSObject>
  4. // 具体的标准
  5. // 返回地图MapView
  6. - (UIView *)getView;
  7. // 初始化需要指定地图的大小
  8. - (instancetype)initWithFrame:(CGRect)frame;
  9. @end

(2)百度地图类实现(1)中的协议方法

 
 
  1. #import "BaiduMapView.h"
  2. #import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相关所有的头文件
  3. #import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地图功能所有的头文件
  4. @interface BaiduMapView ()
  5. @property (nonatomic) BMKMapView *mapView;
  6. @end
  7. @implementation BaiduMapView
  8. // 初始化地图
  9. - (instancetype)initWithFrame:(CGRect)frame {
  10.    self = [super init];
  11.    if (self) {
  12.        // 初始化百度地图
  13.        _mapView = [[BMKMapView alloc] initWithFrame:frame];
  14.    }
  15.    return self;
  16. }
  17. // 返回地图
  18. - (UIView *)getView {
  19.    return _mapView;
  20. }
  21. @end

高德等地图封装同上

以上封装后的调用方法:

 
 
  1.    id<IMapView> mapView = [[BaiduMapView alloc] initWithFrame:self.view.frame];    // id<IMapView> mapView = [[GaodeMapView alloc] initWithFrame:self.view.frame];
  2.    [self.view addSubview:[mapView getView]];


    3、实现百度地图工厂设计

    创建百度地图使用工厂模式进一步封装,调用者无需关心是哪一个地图

    创建百度工厂类,创建方法返回协议实现类实例(.h文件声明方法):

 
 
  1. @implementation BaiduMapFactory
  2. - (id<IMapView>)getMapView:(CGRect)frame {
  3.    // 返回具体的实现类
  4.    return [[BaiduMapView alloc] initWithFrame:frame];
  5. }
  6. @end

高德等地图工厂方法封装同上    

调用方法:

 
 
  1.    // 创建工厂    // id<IMapFactory> factory = [[GaodeMapFactory alloc] init];
  2.    id<IMapFactory> factory = [[BaiduMapFactory alloc] init];
  3.    // 创建MapView
  4.    id<IMapView> mapView = [factory getMapView:self.view.frame];
  5.    // 绑定
  6.    [self.view addSubview:[mapView getView]];


4、实现工厂管理

    对不同地图的工厂方法进行封装,定义规范(使用协议实现)

    创建工厂方法的协议:

 
 
  1. #import <Foundation/Foundation.h>
  2. #import "IMapView.h"
  3. @protocol IMapFactory <NSObject>
  4. // 创建地图的规范
  5. - (id<IMapView>)getMapView:(CGRect)frame;
  6. // 创建定位的规范 。。。
  7. // 创建导航的规范 。。。
  8. @end

修改百度工厂方法(将方法改为实现协议的方法):

 
 
  1. #import <Foundation/Foundation.h>
  2. #import "IMapFactory.h"
  3. // 百度工厂,遵循工厂标准
  4. @interface BaiduMapFactory : NSObject<IMapFactory>
  5. @end
 
 
  1. #import "BaiduMapFactory.h"
  2. #import "BaiduMapView.h"
  3. @implementation BaiduMapFactory
  4. - (id<IMapView>)getMapView:(CGRect)frame {
  5.    // 返回具体的实现类
  6.    return [[BaiduMapView alloc] initWithFrame:frame];
  7. }
  8. @end


调用方法:

 
 
  1.    // 创建工厂
  2.    id<IMapFactory> factory = [[BaiduMapFactory alloc] init];
  3.    // 创建MapView
  4.    id<IMapView> mapView = [factory getMapView:self.view.frame];
  5.    // 绑定
  6.    [self.view addSubview:[mapView getView]];


5、配置文件实现一键切换

    创建地图引擎工厂(管理多个工厂:工厂嵌套)

 
 
  1. #import <Foundation/Foundation.h>
  2. #import "IMapFactory.h"
  3. // 地图引擎类
  4. @interface MapEngine : NSObject
  5. // 定义规范
  6. - (id<IMapFactory>)getFactory;
  7. @end
 
 
  1. #import "MapEngine.h"
  2. #import "BaiduMapFactory.h"
  3. #import "PlatformXmlParser.h"
  4. #import "Platform.h"
  5. @implementation MapEngine {
  6.    id<IMapFactory> _fac;
  7. }
  8. - (void)initMap{
  9.    PlatformXmlParser* parser = [[PlatformXmlParser alloc] init];
  10.    NSMutableArray *array = [parser parser];
  11.    //动态创建实例对象(Runtime动态创建)
  12.    for (Platform *model in array) {
  13.        if ([model.isOpen isEqualToString:@"YES"]) {
  14.            Class c = NSClassFromString(model.factoryName);
  15.            _fac = [[c alloc] init];
  16.        }
  17.    }
  18. }
  19. - (id<IMapFactory>)getFactory {
  20.    [self initMap];
  21.    // 返回具体工厂
  22.    return _fac;
  23. }
  24. @end

此步骤中还有一些类和配置文件需要创建:

    xml文件:配置需要加载的地图种类

 
 
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!--如何定义?-->
  3. <!--map标签:表示地图-->
  4. <map>
  5.    
  6.    <!--platform标签:表示平台(例如:百度SDK平台、高德SDK、GoogleSDK等等...)-->
  7.    <!--appKey标签:表示注册Key)-->
  8.    <!--factoryName标签:表示地图平台封装具体工厂类)-->
  9.    <!--isOpen标签:表示是否开启当前这个地图(开关))-->
  10.    <platform id="1" appKey="otAWxmzvBUVU8RQOaUll73YZowNpiRed" factoryName="BaiduMapFactory" isOpen="YES"/>
  11.    
  12.    <platform id="2" appKey="7525205809e3cb826ee1718e3adf440a" factoryName="GaodeMapFactory" isOpen="NO"/>
  13.    
  14. </map>

解析XML文件的模型类:

 
 
  1. #import <Foundation/Foundation.h>
  2. @interface Platform : NSObject
  3. @property (nonatomic,strong) NSString* mapId;
  4. @property (nonatomic,strong) NSString* appKey;
  5. @property (nonatomic,strong) NSString* factoryName;
  6. @property (nonatomic,strong) NSString* isOpen;
  7. @end

解析XML文件的方法类:

 
 
  1. #import "PlatformXmlParser.h"
  2. #include "Platform.h"
  3. //解析工厂
  4. @interface PlatformXmlParser()<NSXMLParserDelegate>
  5. @property (nonatomic) NSMutableArray* array;
  6. @end
  7. @implementation PlatformXmlParser
  8. - (instancetype)init
  9. {
  10.    self = [super init];
  11.    if (self) {
  12.        _array = [[NSMutableArray alloc] init];
  13.    }
  14.    return self;
  15. }
  16. /** 解析方法,返回数组*/
  17. -(NSMutableArray*)parser{
  18.    //加载XML配置文件
  19.    //绑定delegate
  20.    NSString* filePath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"map.xml"];
  21.    NSURL* url = [[NSURL alloc] initFileURLWithPath:filePath];
  22.    NSXMLParser* xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
  23.    xmlParser.delegate = self;
  24.    //解析
  25.    [xmlParser parse];
  26.    return _array;
  27. }
  28. - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(NSDictionary<NSString *, NSString *> *)attributeDict{
  29.    //解析xml
  30.    if([elementName isEqualToString:@"platform"]){
  31.        NSString* mapId = attributeDict[@"id"];
  32.        NSString* appKey = attributeDict[@"appKey"];
  33.        NSString* factoryName = attributeDict[@"factoryName"];
  34.        NSString* isOpen = attributeDict[@"isOpen"];
  35.        Platform* platform = [[Platform alloc] init];
  36.        platform.mapId = mapId;
  37.        platform.appKey = appKey;
  38.        platform.factoryName =factoryName;
  39.        platform.isOpen = isOpen;
  40.        //保存
  41.        [_array addObject:platform];
  42.    }
  43. }
  44. @end

此时再看 MapEngine 类,通过解析的配置文件,判断后加载不同的地图SDK,实现在配置文件中地图的一键切换。


地图创建使用的最终调用方法:

 
 
  1.    // 地图引擎(只关心功能和API即可,解耦和)
  2.    MapEngine *engine = [[MapEngine alloc] init];
  3.    id<IMapFactory> factory = [engine getFactory];
  4.    // 创建MapView
  5.    id<IMapView> mapView = [factory getMapView:self.view.frame];
  6.    //绑定
  7.    [self.view addSubview:[mapView getView]];


总结:

    该设计可以在不关系API的情况下,仅通过xml配置文件动态加载不同的地图。

    这是一种面向协议的编程思想。用协议定义标准(接口)适合多人开发,规范开发。

    同时,该设计也有可读性差的缺点。需要有一定开发经验方可架构实现。




### 如何在微信开发者工具中连接3D地图 要在微信开发者工具中集成3D地图,可以通过腾讯位置服务的JavaScript API GL来实现。以下是详细的说明: #### 1. 腾讯位置服务支持 腾讯位置服务提供了基于WebGL技术的高性能三维渲染引擎封装而成的3D地图API——JavaScript API GL[^2]。此API允许开发人员利用GPU的强大计算能力,在浏览器端高效渲染大量地理数据。 #### 2. 集成步骤概述 为了在微信小程序环境中加载和显示3D地图,需遵循以下流程: - **引入必要的库文件** 开发者应先下载或在线引用腾讯位置服务提供的最新版JavaScript API GL脚本资源。 - **初始化地图对象** 使用`TMap.Map()`构造函数创建一个新地图实例,并指定容器DOM节点作为参数之一。 - **配置基本属性** 设置诸如视图模式(`viewMode`)、初始缩放等级(`zoom`)、中心点经纬度(`center`)等基础选项[^3]。 - **增强交互功能** 添加自定义标记物(markers)、路径线(polylines)或者多边形区域覆盖层(polygons)。同时也可以监听用户操作行为比如鼠标单击事件以便动态更新界面状态。 #### 3. 示例代码片段 下面给出了一段简单的HTML页面嵌入代码用于演示如何快速启动一张带有特定地理位置标注的基础3D地图应用案例: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Tencent Map Demo</title> <!-- 加载腾讯地图JS API --> <script src='https://map.qq.com/api/gljs?v=1.exp&key=YOUR_KEY'></script> <style> #container { width: 100%; height: 500px; } </style> </head> <body> <div id="container"></div> <script type="text/javascript"> // 初始化地图 var map = new TMap.Map('container', { viewMode:'3D', pitch:30, rotation:-45, zoom:16, center:new TMap.LatLng(39.90973,116.39733), }); // 创建一个多图标集合类实例 var marker=new TMap.MultiMarker({ map:map, styles:{ marker:new TMap.MarkerStyle({ width:20,height:30, anchor:{x:10,y:30} }) }, geometries:[{ position:center,id:"marker" }] }); </script> </body> </html> ``` 注意替换其中 `YOUR_KEY` 占位符为你申请到的有效密钥字符串值。 #### 4. 微信环境适配注意事项 由于微信小程序运行于沙盒隔离机制之下,因此可能需要额外考虑跨域资源共享(CORS)策略调整等问题;另外还需确认所使用的接口权限范围是否符合官方文档规定的要求。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值