地圖

 

目錄[-]git

 

以前工做在一家智能設備的公司,作過一個親友定位監控系統,相似如今比較流行的360兒童手環。因此這裏簡單介紹定位與地圖。數據庫

 

1 定位服務

    iOS設備提供三種不一樣定位途徑,蜂窩式移動電話基站定位;WiFi定位,經過查詢一個WiFi路由器的地理位置信息,比較省電;GPS衛星定位,經過3~4顆衛星定位,最爲準確,可是耗電量大。iOS系統若是可以接收GPS信息,那麼設備優先採用GPS,其次是WiFi,最後是基站,開發人員不能選擇哪一種定位方式。api

    定位服務使用CoreLocation框架,主要使用CLLocationMananger、CLLocationManangerDelegate和CLLocation三個類,CLLocationMananger是定位服務管理類,獲取設備的位置信息,CLLocationManangerDelegate是代理協議,CLLocation封裝了位置信息。數組

    這裏要注意,CLLocationManangerDelegate 的locationManager:didUpdateToLocation:fromLocation:方法獲得的座標是火星座標,這個緣由你懂得,因此須要轉換成真實的地理座標。我使用的是一個第三方的CSqlite類,有一個轉換座標的數據庫,你調用就能夠轉換爲正確座標了。app

    獲得經緯度後,要進行地理位置信息反編碼,使用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提供的類。編碼

    我以前作項目,使用高德地圖,作到後期,項目會出現閃退,後來查出是地圖區域內存的問題,而後從新佈局了地圖區域,使得每個地圖區域可以及時銷燬,雖然閃退週期明顯延長,可是仍是存在,這裏不知道是何緣由,說來慚愧。spa

 

設置地圖區域

?
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:完成添加標註。.net

    高德地圖實現的原理也是同樣的,高德地圖使用的是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,這是一個用於查詢的框架,有興趣的朋友能夠多加研究。

相關文章
相關標籤/搜索