因爲博客遷移至www.coderyi.com,文章請看http://www.coderyi.com/archives/419git
以前工做在一家智能設備的公司,作過一個親友定位監控系統,相似如今比較流行的360兒童手環。因此這裏簡單介紹定位與地圖。數據庫
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,不在返回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; }
地圖我目前用過系統、百度以及高德,開發人員使用都是差很少的,下面的代碼涉及的類都是高德地圖api提供的類。編碼
我以前作項目,使用高德地圖,作到後期,項目會出現閃退,後來查出是地圖區域內存的問題,而後從新佈局了地圖區域,使得每個地圖區域可以及時銷燬,雖然閃退週期明顯延長,可是仍是存在,這裏不知道是何緣由,說來慚愧。spa
-(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]; }
-(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]; }
-(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,這是一個用於查詢的框架,有興趣的朋友能夠多加研究。