Привет!
В этой статье я постараюсь описать как мы (разработчики Maptrix) победили Apple карты и заменили их картами от OpenStreetMap.
Проблема:
Ни для кого не секрет, что, начиная с прошивки iOS 6.0 во встроенном компоненте MkMapkit, используются карты от Apple. Наконец, Apple стали самостоятельными и смогли отказаться от Google. На презентации все выглядело обалденно!
Но как всегда одно «но»: все эти 3d чудеса доступны только для пользователей США (ну и некоторых других развитых стран). В частности, по представлениям Apple жители России живут в одной большой пустыне.
Возможные решения:
Первой мыслью было уйти от MKMapView.
К сожалению, из рассмотренных аналогов найти полноценную копию этой библиотеки не удалось. Более менее похожая структура, кстати, у яндекс библиотеки (http://github.com/yandexmobile/yandexmapkit-ios и github.com/yandexmobile/yandexmapkit-ios).
Так, мы пришли к мысли, что работу с картой, пинами и т.п. надо оставлять как есть, а вместо картинок карт от Apple подставлять какие-нибудь более проработанные.
В итоге, мы решили использовать Open Street Map и вот эту библиотеку с некоторыми доработками.
Что не устраивало:
1. При переключении Satelite Map карта не переключалась
2. Если карта не прогружена, вначале показывалась Apple карте, после чего ее перекрывала карта OSM
Итак, сам код:
1. Добавляем необходимые файлы
github.com/nutiteq/ldiw-iphone/tree/master/OSM
2. .h файл ViewController
#import "TileOverlay.h"
@interface MapView : UIViewController <MKMapViewDelegate> {
IBOutlet MKMapView *mapView;
}
@property (nonatomic, retain) TileOverlay *overlay;
3. .m файл ViewController
#import "TileOverlay.h"
#import "TileOverlayView.h"
@synthesize overlay;
- (void)viewDidLoad {
[super viewDidLoad];
overlay = [[TileOverlay alloc] initOverlay];
MKMapRect visibleRect = [mapView mapRectThatFits:overlay.boundingMapRect];
visibleRect.size.width /= 2;
visibleRect.size.height /= 2;
visibleRect.origin.x += visibleRect.size.width / 2;
visibleRect.origin.y += visibleRect.size.height / 2;
mapView.visibleMapRect = visibleRect;
[self SetMapDisplayTypeToSatelite:NO];
}
- (void)SetMapDisplayTypeToSatelite:(BOOL)IsSatelite{
mapView.mapType = (IsSatelite == NO) ? MKMapTypeSatellite : MKMapTypeStandard;
[self AddRemoveOverlay:IsSatelite];
}
- (void)AddRemoveOverlay:(BOOL)show{
// мои доработки 1: используем OSM только на прошивке свыше 6.0
NSString *reqSysVer = @"6.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending){
if (show == YES && [Maptrix appmodel].SegmentMapPressed == YES) {
[mapView addOverlay:overlay];
//мои доработки 2: для того, чтобы не показывать слой карт Apple устанавливаем у него прозрачность
if ( [mapView.subviews count] && [((UIView *)[mapView.subviews objectAtIndex:0]).subviews count] )
((UIView *)[((UIView *)[mapView.subviews objectAtIndex:0]).subviews objectAtIndex:0]).alpha = 0.0;
}else if (show == NO && [Maptrix appmodel].SegmentMapPressed == NO){
[mapView removeOverlay:overlay];
//мои доработки 3: для отображения карты в режиме спутник используем снова карты от Apple
if ( [mapView.subviews count] && [((UIView *)[mapView.subviews objectAtIndex:0]).subviews count] )
((UIView *)[((UIView *)[mapView.subviews objectAtIndex:0]).subviews objectAtIndex:0]).alpha = 1.0;
}
}
}
Итог
Для прошивки свыше 6.0 используются карты OSM. Причем пока карта не подгрузилась, пользователь не увидит карты Apple. При переключении между карта/спутник карта меняется между OSM и Apple.
Я честно говоря боялся, вдруг Apple нас не заапрувит. Мы перекрыли карты Apple, сделали их карту прозрачной (alpha = 0). И тем не менее нас заапрувили. Вот ссылка .
Теперь планируем подключать OSM на андроиде. Но об этом в следующей статье.
Автор: Filippov_D