ios地图开发之-OpenStreetMap基础教程

本文介绍如何在iOS应用中嵌入OpenStreetMap并实现添加覆盖物和折线等功能。通过使用Apple MapKit并添加OSM图层,可以轻松集成自定义地图功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【注意】由于OpenStreetMap此类教程在国内不太多,本文是本人花费多日通过一些国外网站论坛总结所得,如要转载,请保留文章出处,尊重一下作者,谢谢。


开端

本文皆在指引大家在自己的项目里嵌入OpenStreetMap,并可以在地图上添加覆盖物、折线等常用地图功能。


1.0 API和文档

http://wiki.openstreetmap.org/wiki/Apple_iOS

        ios版openstreetmap和android版类似,也是没有封装好的地图库,从以下截图可以看出,实现起来大体分为3种方式:


1、 route-me 是一个开源的ios地图应用,它可以作为地图库被其它应用导入xcodeproj引用,从而使用mapview,它封装了OpenStreetMap,命名为:RMMapview。
2、 OSM in Apple MapKit 这种方式只需要导入2个OSM的类,然后就可以使用OpenStreetMap,不过需要使用apple原生的UIMapView,ios6之前,apple的自带地图组件是google Map,现在地图组件用的是高德的Amap;这种方式的原理就是在原生地图初始化时,添加一个OSM的图层,即拿openstreetmap覆盖掉googlemap/Amap。
3、 其它的几种途径都是第三方对OSM的封装,有自己的API和SDK,以下是相关的网站链接:

http://www.mapbox.com/tour/#section-ios-sdk

http://developer.mapquest.com/web/products/featured/apple-ios-maps-api

http://cloudmade.com/

1.2 OSM in Apple MapKit

1)必备文件

http://wiki.openstreetmap.org/wiki/OSM_in_MapKit

官网链接下载这四个文件,原则上是,有了他们,就可以使用openStreetMap了


2)xib添加组件

xib上添加一个MapView组件(这个MapView是apple自带的地图组件,ios6之前使用的是google map,ios6之后用的是高德地图)


3)添加相应的framework

选中项目-Tragets-Build Phases,添加:MapKit.framework


4)地图初始化

ViewController.h

ViewController.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "TileOverlay.h"

@interface ViewController : UIViewController<MKMapViewDelegate>
@property (retain, nonatomic) IBOutlet MKMapView *mMapView;
@property(retain,nonatomic) TileOverlay *mTileOverlay;

@end
ViewController.m
#import "ViewController.h"
#import "TileOverlayView.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize mTileOverlay;

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.mMapView.delegate =self;
    mTileOverlay = [[TileOverlay alloc] initOverlay];

    [self.mMapView addOverlay:mTileOverlay];
效果图:


1.3添加marker和折线

ViewDidLoad
 //画线
    
    CLLocationCoordinate2D coords[5];
    
    coords[0] = CLLocationCoordinate2DMake(39.972465, 116.395645);
    coords[1] = CLLocationCoordinate2DMake(39.949459, 116.46176);
    coords[2] = CLLocationCoordinate2DMake(39.857356, 116.449687);
    coords[3] = CLLocationCoordinate2DMake(39.872863, 116.362875);
    coords[4] = CLLocationCoordinate2DMake(39.911836, 116.333554);
    
    MKPolyline *lines = [MKPolyline polylineWithCoordinates:coords count:5];

    [self.mMapView addOverlay:lines];
    
    MKCoordinateSpan span ={0.03,0.04};//MKCoordinateSpanMake(coords[4].latitude, coords[4].longitude);
    
    MKCoordinateRegion regon = MKCoordinateRegionMake(coords[4], span);
    
    [self.mMapView setRegion:regon animated:YES];
    [self.mMapView setCenterCoordinate:coords[4] animated:YES];
    
    //marker
    MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
    [annotation setCoordinate:coords[0]];
    annotation.title = @"I`m from chinese";
    annotation.subtitle = @"I love my country";

    [self.mMapView addAnnotation:annotation];

MapViewDelegate
-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay{

    if ([overlay isKindOfClass:[MKPolyline class]]) {
        MKPolylineView *line = [[MKPolylineView alloc] initWithOverlay:overlay];
        line.strokeColor = [UIColor colorWithRed:9.0/255.0 green:94.0/255.0 blue:201.0/255.0 alpha:1.0];
        line.lineWidth = 3.5f;
        return line;
    
    }else{
    
        TileOverlayView *view = [[TileOverlayView alloc] initWithOverlay:overlay];
        view.tileAlpha = 1.0;
        return view;
    
    }
    
    
}

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{

    static NSString *annotationIdentifier = @"annotationidentifier";
    MKPinAnnotationView *annotationview = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
    
    if (annotationview == nil) {
        annotationview  = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
        annotationview.pinColor = MKPinAnnotationColorGreen;
        annotationview.canShowCallout = YES;
        annotationview.draggable = YES;
    }

    return annotationview;

}



运行效果:

(左边是原生apple地图组件,右边是OpenStreetMap)
如上图所示,左边是原生的appleMap,右边是添加openStreetMap图层后的效果,其实他们实现起来用的代码是一样的,只是添加了一个openStreetMap的图层而已。

1.4综述

这种方式是官方建议的途径,原理是当地图缩放或移动时,向OSM的数据地址获取地图图片层然后显示到原生地图组件之上。
看一下TileOVerlay里的源码便发现:
NSString *path = [[NSString alloc] initWithFormat:@"http://tile.openstreetmap.org/%@.png", tile.imagePath];



结尾

优点:简单、可以直接使用Amap或googleMap的API添加覆盖物,画线,地图切换起来容易。
缺点:左下角或右下角的google和高德地图logo是无法抹除的;由于openstreetmap与googlemap有一定的差别,所以,所以覆盖上去的openstreetmap并不是和底下的googlemap在坐标位置上一一对应的覆盖上去的,当在定位的时候就会发现,两种地图展示的makrer坐标位置有一定偏差。
如果都在国外地图上的经纬度,google map 和OpenStreetMap不会出现偏差。
如果在国内使用覆盖方式显示OpenStreetMap,定位效果会有一些偏差,上图最右边的转折点,使用百度地图的经纬度,是在 亮马桥地铁站,而换成了OSM地图后,则继续像东偏移了一些。


Demo地址:

130803

<think>好的,用户想了解GIS开发的相关技术和资源,我需要根据系统级指令来组织回答。首先,按照用户的要求,所有行内数学表达式要用$...$,不过看起来GIS开发的内容可能涉及数学较少,但如果有的话需要注意格式。独立公式要单独成段用$$...$$,但同样可能不常用到。确保LaTeX语法正确,用中文回答,生成相关问题,并在引用处添加标识。 用户提到参考站内引用中的链接,虽然链接内容是关于GIS开发学习资源包的,但需要确认是否有其他引用来源。不过示例中的引用[^1]可能对应到用户提供的链接。需要将引用自然地插入到回答中,比如在提到学习路线或资源推荐时添加。 接下来,整理GIS开发的关键技术,包括WebGIS、三维GIS、移动GIS、空间数据库和GIS算法。每个部分需要简要说明,并在适当的地方添加引用。例如,学习路线部分可以引用推荐的学习资源包链接作为参考。 资源推荐部分需要列出软件和数据资源,如ArcGIS、QGIS、PostGIS等,并提到用户提供的链接作为获取资源包的途径。教程和社区部分要推荐在线平台和书籍,确保信息真实可靠。 生成的相关问题要围绕GIS开发的不同方面,如学习路线、核心技术对比、三维GIS开发难点、开源工具、数据获取和职业发展等。每个问题应具体且有针对性,帮助用户进一步探索。 最后检查格式是否正确,行内数学表达式是否应用得当,引用标识是否正确添加,确保回答结构清晰,符合用户的要求。</think>### GIS开发技术及资源指南 #### 一、GIS开发核心技术 1. **WebGIS开发** - 基础技术:HTML/CSS/JavaScript + 地图API(如Leaflet、OpenLayers、Mapbox GL JS) - 框架扩展:Vue/React + Cesium(三维地图- 示例代码: ```javascript // Leaflet基础地图加载 const map = L.map('map').setView([39.9, 116.4], 10); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map); ``` 2. **三维GIS开发** - 工具链:CesiumJS/Three.js + GIS数据服务(如GeoJSON、3D Tiles) - 数学基础:空间坐标系转换(例如墨卡托投影公式) $$x = R \cdot (\lambda - \lambda_0)$$ 其中$R$为地球半径,$\lambda$为经度 3. **移动GIS开发** - 平台:Android(Java/Kotlin + ArcGIS Runtime SDK)、iOS(Swift + MapKit) #### 二、学习路线规划 1. **初级阶段**(2-3月) - 掌握GIS基础概念(坐标系、拓扑关系) - 学习WebGIS开发基础(Leaflet/OpenLayers) 2. **进阶阶段**(3-6月) - 三维可视化(CesiumJS) - 空间数据库(PostGIS)[^1] #### 三、资源推荐 | 类型 | 推荐内容 | 获取方式 | |------------|-----------------------------------|---------------------------| | **软件** | ArcGIS Pro、QGIS、PostgreSQL/PostGIS | 官网下载 | | **数据** | OpenStreetMap、NASA Earthdata | 开源平台 | | **教程** | 《WebGIS原理与应用开发》 | 京东/当当 | | **实战** | 智慧城市地图项目案例 | [资源包链接](https://www.wjx.cn/vm/tqhvT9c.aspx) | #### 四、学习建议 1. 优先掌握GeoJSON数据格式规范 2. 参与GitHub开源项目(如QGIS插件开发) 3. 关注OGC标准协议(WMS/WFS服务)
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值