• 地图


    目录[-]

    之前工作在一家智能设备的公司,做过一个亲友定位监控系统,类似现在比较流行的360儿童手环。所以这里简单介绍定位与地图。

    1 定位服务

        iOS设备提供三种不同定位途径,蜂窝式移动电话基站定位;WiFi定位,通过查询一个WiFi路由器的地理位置信息,比较省电;GPS卫星定位,通过3~4颗卫星定位,最为准确,但是耗电量大。iOS系统如果能够接收GPS信息,那么设备优先采用GPS,其次是WiFi,最后是基站,开发人员不能选择哪种定位方式。

        定位服务使用CoreLocation框架,主要使用CLLocationMananger、CLLocationManangerDelegate和CLLocation三个类,CLLocationMananger是定位服务管理类,获取设备的位置信息,CLLocationManangerDelegate是代理协议,CLLocation封装了位置信息。

        这里要注意,CLLocationManangerDelegate 的locationManager:didUpdateToLocation:fromLocation:方法得到的坐标是火星坐标,这个原因你懂得,所以需要转换成真实的地理坐标。我使用的是一个第三方的CSqlite类,有一个转换坐标的数据库,你调用就可以转换为正确坐标了。

        得到经纬度后,要进行地理位置信息反编码,使用CLGeocoder类实现,将地理坐标转换为地理文字描述信息,这些文字描述信息被封装在CLPlacemark类中。

        当然给定地理信息的文字描述,也可以进行地理信息编码查询,转换为地理坐标,也是采用CLGeocoder类。

    判断一个坐标点是否在一个无规则的多边形内

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    //    在范围内返回1,不在返回0
    -(int)mutableBoundConrtolAction:(NSMutableArray *)arrSome:(CLLocationCoordinate2D )myCoordinate4{
        int n=arrSome.count;
        float vertx[n];
        float verty[n];
        for (int i=0; i<arrSome.count; i++) {
    //MyPoint类存储的是经度和纬度
            vertx[i]=((MyPoint *)(arrSome[i])).x;
            verty[i]=((MyPoint *)(arrSome[i])).y;
        }
        if (arrSome.count==0) {
             
            return 1;
        }
        BOOL i=pnpoly(arrSome.count, vertx, verty, myCoordinate4.latitude, myCoordinate4.longitude);
         
         
        if (i) {
            return 1;
        }else{
            return 0;
        }
         
         
        return 1;
    }
    //多边形由边界的坐标点所构成的数组组成,参数格式 该数组的count,  多边形边界点x坐标 的组成的数组,多边形边界点y坐标 的组成的数组,需要判断的点的x坐标,需要判断的点的y坐标
    BOOL pnpoly (int nvert, float *vertx, float *verty, float testx, float testy) {
        int i, j;
        BOOL c=NO;
        for (i = 0, j = nvert-1; i < nvert; j = i++) {
             
            if ( ( (verty[i]>testy) != (verty[j]>testy) ) &&
                (testx < (vertx[j]-vertx[i]) * (testy-verty[i]) / (verty[j]-verty[i]) + vertx[i]) )
                c = !c;
        }
        return c;
    }

    2 系统地图

        地图我目前用过系统、百度以及高德,开发人员使用都是差不多的,下面的代码涉及的类都是高德地图api提供的类。

        我之前做项目,使用高德地图,做到后期,项目会出现闪退,后来查出是地图区域内存的问题,然后重新布局了地图区域,使得每一个地图区域能够及时销毁,虽然闪退周期明显延长,但是还是存在,这里不知道是何原因,说来惭愧。

    设置地图区域

    1
    2
    3
    4
    5
    6
    7
    8
    9
    -(void)SetMapRegion:(CLLocationCoordinate2D)myCoordinate
    {
        MACoordinateRegion theRegion = { {0.0, 0.0 }, { 0.0, 0.0 } };
        theRegion.center=myCoordinate;
        [self.m_map setScrollEnabled:YES];
        theRegion.span.longitudeDelta = 0.01f;
        theRegion.span.latitudeDelta = 0.01f;
        [self.m_map setRegion:theRegion animated:YES];
    }



    平移地图,上下左右

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    -(void)panMap:(NSString *)direction{
        CLLocationCoordinate2D changeCoordinate=self.m_map.centerCoordinate;
        CGPoint changePoint=[self.m_map convertCoordinate:changeCoordinate toPointToView:self.m_map];
         
        if ([direction isEqualToString:@"up"]) {
            changePoint.y=changePoint.y+50;
             
        }else if ([direction isEqualToString:@"down"]) {
            changePoint.y=changePoint.y-50;
        }else if ([direction isEqualToString:@"left"]) {
            changePoint.x=changePoint.x-50;
        }else if ([direction isEqualToString:@"right"]) {
            changePoint.x=changePoint.x+50;
        }
        changeCoordinate=[self.m_map convertPoint:changePoint toCoordinateFromView:self.m_map];
        [self.m_map setCenterCoordinate:changeCoordinate animated:YES];
    }



    判断某一个坐标点是否在当前地图区域内

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    -(void)isAtCurrentRegion:(CLLocationCoordinate2D)coordiante{
         
        CGPoint point=[self.m_map convertCoordinate:coordiante toPointToView:self.view];
        if ((point.x<0)||(point.y<0)||(point.x>WScreen)||(point.y>HScreen)) {
    //        如果不在 设置该点为地图中心点
            [self SetMapRegion:coordiante];
        }
         
         
    }

    在地图上添加标注

        系统地图使用MapKit框架,核心是MKMapView类,显示地图只要添加MKMapView实例就可以了。如果要实现在地图上添加标注点,第以是触发添加动作,第二实现MKMapViewDelegate的mapView:viewForAnnotation:完成添加标注。

        高德地图实现的原理也是一样的,高德地图使用的是MAMapKit框架。对于annotation,一般会自定义一个继承NSobject并且实现了maannotation协议的类,然后使用mapview的addAnnotation:方法就可以。MKReverseGeocoder类可以实现coordinate的反编码,这里需要实现它的代理,把得到的地理文字描述信息赋给annotation。这里需要实现代理的mapView:viewForAnnotation:方法,一个标注其实就是一个MAAnnotationView,标注有点类似tableviewcell,这里也有重用机制。实现代理的mapView:annotationView:calloutAccessoryControlTapped:方法可以响应leftCalloutAccessoryView或者rightCalloutAccessoryView的点击事件,不过这个accessory view必须继承自UIControl。

    在地图上绘制线条和多边形

        MAPolyline类定义一个由多个点相连的多段线,点与点之间尾部想连但第一点与最后一个点不相连, 通常MAPolyline是MAPolylineView的model,它提供了两个方法polylineWithPoints:count:、polylineWithCoordinates:count:用来添加线条,然后再通过map view的addOverlay:方法把Polyline实例添加进去,最后实现mapviewdelegate的mapView:viewForOverlay:方法就可以了。注意如果一开始添加的不是coordinate,而是point,可以通过map view的convertPoint:toCoordinateFromView:方法进行转换。

        MAPolygon类定义的就是一个不规则的由多个点组成的闭合多边形,点与点之间按顺序尾部相连, 第一个点与最后一个点相连, 通常MAPolygon是MAPolygonView的model,首先需要添加坐标点的数组,可以使用polygonWithCoordinates:count:方法或者polygonWithPoints:count:方法,然后把这个polygon通过addOverlay:方法添加到map view上就可以了。然后可以在mapviewdelegate里面的mapView:viewForOverlay:方法里面给MAPolygonView的属性赋值,这样一个完整的多边形就出来了。

        不管是高德地图还是百度地图等第三方,都会有一个mapsearchkit,这是一个用于查询的框架,有兴趣的朋友可以多加研究。

  • 相关阅读:
    Django-建立网页
    selenium、unittest——POM框架并出报告
    unittest,requests——接口测试脚本及报告
    从浏览器地址栏输入网址,到网页彻底打开,中间都发生了什么?
    HTTP结构讲解——《HTTP权威指南》系列
    charles基本使用文档
    接口测试操作指引
    环境更新
    Linux查看文件内容
    通过Jmeter对Dubbo接口进行接口及性能测试
  • 原文地址:https://www.cnblogs.com/fengmin/p/4949578.html
Copyright © 2020-2023  润新知