Описание: создание карты с временной шкалой, данные для которой загружаются из файла.
#import <MapCharting/MapChart.h>
#import <MapCharting/MapChart2D.h>
#import "MapDataSource.h"
#import "CustomMap.h"
@interface ViewController : UIViewController {
CustomMap *m_view; // Двумерная карта
MapDataSource *datasource; // Источник данных карты
}
@end
#import "ViewController.h"
#import <MapCharting/MapTopobase.h>
#import <MapCharting/MapAreaVisual.h>
#import "SolidColorBrush.h"
#import "DataDependency.h"
#import <MapCharting/MapTooltip.h>
#import <MapCharting/MapLabel.h>
#import <MapCharting/MapLegend.h>
#import <MapCharting/MapShape.h>
#import "UIColor+transition.h"
#import <MapCharting/MapLabel.h>
#import <MapCharting/MapChartSign.h>
#import <MapCharting/MapArrow.h>
#import <MapCharting/MapFilledArrow.h>
#import <MapCharting/MapBarVisual.h>
#import <MapCharting/MapPieVisual.h>
#import "UIColor+hex.h"
#import "CustomMap.h"
#import "CustomMapBubblePopoverView.h"
@implementation ViewController
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Загружаем данные из источника
datasource = [[MapDataSource alloc]initWithFileName:@"data.txt"];
// Определяем минимальное и максимальное значения данных
[datasource prepare];
// Создаём карту на основе загруженных данных
[self dataSourceFinishedLoadData];
}
// Создаёт карту на основе загруженных данных
- (void)dataSourceFinishedLoadData
{
// Создаём двумерную карту
m_view = [[CustomMap alloc] init];
// Загружаем файл с топоосновой
NSData *file = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"world.svg" ofType:nil]];
// Создаём и устанавливаем объект для работы с топоосновой карты
MapTopobase *topobase = [[MapTopobase alloc] initWithData:file];
[m_view setTopobase: topobase];
// Определяем аффинное преобразование, применяемое ко всем областям карты
[topobase setTransform: CGAffineTransformIdentity];
[m_view setClipsToBounds:YES];
// Запрещаем масштабирование карты
[m_view setZoomEnabled:NO];
// Создаём объект для работы с картографическим показателем
MapAreaVisual *visual = [[MapAreaVisual alloc] init];
// Устанавливаем источник данных
[visual setDataSource: datasource];
/* Устанавливаем признак того, что параметры заливки фона областей карты
зависят от источника данных */
[[visual background] setIsDependent:YES];
// Создаём объект для работы со слоем карты
MapLayer *layer = [[m_view topobase] rootLayer];
// Создаём всплывающую подсказку для слоя
layer.tooltip = [MapTooltip new];
// Задаём цвета для заливки фона областей слоя карты
NSArray *colors = [NSArray arrayWithObjects:@"ff462c", @"ebaf36", @"ffd900", @"b1ca40", @"6a8535", nil];
// Определяем минимальное значение карты
double value = [datasource minValue];
// Определяем шаг для шкалы карты
double step = (datasource.maxValue - datasource.minValue) / [colors count];
// Определяем соответствие между интервалами шкалы карты и цветами заливки фона областей слоя
ValueScale *scale = [[ValueScale new] autorelease];
for (int i = 1; i <[colors count]; i++) {
value += step;
[scale.value addObject:[NSNumber numberWithDouble:value]];
// Определяем цвета для значения «меньше»
UIColor *lessColor = [UIColor colorWithHex:[colors objectAtIndex:(i - 1)]];
[scale.less addObject:[SolidColorBrush solidColorBrushWithColor:lessColor]];
// Определяем цвета для значения «равно» или «больше»
UIColor *equalColor = [UIColor colorWithHex:[colors objectAtIndex:(i)]];
[scale.equal addObject:[SolidColorBrush solidColorBrushWithColor:equalColor]];
[scale.greater addObject:[SolidColorBrush solidColorBrushWithColor:equalColor]];
}
// Устанавливаем шкалу карты
[[visual background] setScale:scale];
// Устанавливаем кисть для заливки фона карты
[m_view setBackground:[SolidColorBrush solidColorBrushWithColor:[UIColor whiteColor]]];
// Устанавливаем цвет заголовка карты
m_view.caption.textColor = [UIColor blackColor];
// Устанавливаем текст подписи для областей слоя карты, для которых отсутствуют данные
[m_view setNoDataText: NSLocalizedString(@"NO_DATA", nil)];
// Создаём кисть для заливки областей слоя карты с отсутствующими данными
SolidColorBrush *brush = [[[SolidColorBrush alloc] init] autorelease];
// Установим прозрачность кисти
[brush setOpacity: 0.2];
// Установим цвет кисти
brush.color = [UIColor grayColor];
// Установим данную кисть
[[[visual background] scale] setNoData: brush];
Thickness th = {0};
th.top = 20;
th.bottom = 20;
// Определяем текст заголовка
[[m_view caption] setText: NSLocalizedString(@"WORLD_MAP", nil)];
// Задаём отступ для заголовка
[[m_view caption] setMargin: th];
// Определяем параметры шрифта
[[m_view caption] setFont:[UIFont systemFontOfSize:18]];
// Используем направление письма слева направо
[m_view setUsingRightToLeft: NO];
// Получаем легенду карты
MapLegend *legend = [m_view legend];
// Устанавливаем шкалу карты
[legend setValueScale: scale];
// Выравниваем легенду по центру карты
[legend setBlockAlignment: NWLegendBlockAlignmentBottomCenter];
// Устанавливаем отступы для легенды
Thickness margin = {0,20,0,0};
[legend setMargin:margin];
// Устанавливаем цвет текста и параметры шрифта легенды
[legend setTextColor:[UIColor blackColor]];
[legend setFont:[UIFont systemFontOfSize:12]];
// Устанавливаем формат записи интервала «меньше»
NSString *lessFormat = [NSMutableString stringWithString:NSLocalizedString(@"LESS_FORMAT", nil)];
[legend setLessFormat:lessFormat];
// Устанавливаем формат записи интервала «больше»
NSString *greaterFormat = [NSMutableString stringWithString:NSLocalizedString(@"GREATER_FORMAT", nil)];
[legend setGreaterFormat:greaterFormat];
// Создаём верхний текст легенды
MapLabel *header = [[MapLabel new] autorelease];
[header setText: NSLocalizedString(@"HEADER_TEXT", nil)];
// Устанавливаем параметры шрифта для текста
[header setFont: [UIFont systemFontOfSize:14]];
[header setTextColor:[UIColor blackColor]];
// Устанавливаем отступы текста
Thickness headerMargin = {5, 0, 0, 0};
[header setMargin:headerMargin];
// Устанавливаем верхний текст для легенды
[[m_view legend] setHeader:header];
// Устанавливаем форму маркеров для легенды карты
[legend setMarkerShape: MarkerShapeRectangle];
// Задаём ориентацию легенды
[legend setOrientation: NWLegendOrientationFreeVertical];
// Устанавливаем позицию легенды
CGPoint pt = {[m_view legend].origin.x, 325};
[legend setOrigin: pt];
// Получаем временную шкалу
MapTimeAxis *timeAxis = [m_view timeAxis];
// Отображаем временную шкалу
[timeAxis setHidden: NO];
// Устанавливаем объект, содержащий методы для работы со шкалой
[timeAxis setDelegate: m_view];
// Устанавливаем источник данных
[timeAxis setDataSource:datasource];
// Настраиваем задержку анимации
[timeAxis setDelayTime: AnimateTypeSlow];
// Задаём параметры шрифта для временной шкалы
[timeAxis setFont:[UIFont fontWithName:@"Arial" size:16]];
// Задаём минимальное расстояние в точках между двумя соседними делениями оси
[timeAxis setMinTickSpacing:1.0];
// Устанавливаем для делений шкалы синий цвет
[timeAxis setTickColor: [UIColor blueColor]];
/* Устанавливаем длительность перемещения от одного значения оси
к другому во время воспроизведения анимации */
[timeAxis setJumpTime: AnimateTypeNormal];
// Устанавливаем текущее положение ползунка шкалы
[m_view.timeAxis setIndex:0];
// Создаём и отображаем подпись над текущим положением ползунка шкалы
MapTooltip *caption = [[MapTooltip new] autorelease];
[caption setVisibility:YES];
[timeAxis setLabel: caption];
/* Добавляем объект для работы с картографическим показателем
в массив визуальных элементов, соответствующих дочерним слоям и областям */
[[layer visuals] addObject: visual];
// Добавляем слой карты в массив отображаемых слоёв
[[m_view layers] addObject:layer];
[self setView:m_view];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Устанавливаем новые размеры карты
struct CGRect frame;
frame = CGRectMake(0, 0, 375, 470);
[m_view setFrame:frame];
// Устанавливаем рамку серого цвета
[[m_view layer] setBorderColor: [[UIColor colorWithRed:0.75 green:0.75 blue:0.75 alpha:1] CGColor]];
[[m_view layer] setBorderWidth: 1.0f];
// Зададим три области слоя карты
NSMutableArray *shapes = [[NSMutableArray new] autorelease];
NSArray *shapesIds = [NSArray arrayWithObjects:@"AU", @"RU", @"BR", nil];
for (NSString *id in shapesIds) {
MapShape *shape = [[[m_view layers] objectAtIndex:0] shapeWithId:id];
[shapes addObject:shape];
}
/* Отображаем всплывающее окно для области слоя карты «AU»
с расположением стрелки в правом верхнем углу окна */
[self showBubblePopoverForShape:[shapes objectAtIndex:0] withOrientation:PopoverArrowRightTop];
/* Отображаем всплывающее окно для области слоя карты «RU»
с оптимальным расположением стрелки */
[self showBubblePopoverForShape:[shapes objectAtIndex:1] withOrientation:NAN];
/* Отображаем всплывающее окно для области слоя карты «BR»
с расположением стрелки посередине нижней границы окна */
[self showBubblePopoverForShape:[shapes objectAtIndex:2] withOrientation:PopoverArrowBottom];
}
// Отображает всплывающие окна для областей слоя карты
-(void)showBubblePopoverForShape:(MapShape *) shape withOrientation:(BubblePopoverViewArrowOrientation) arrowOrientation {
// Создаём всплывающее окно
CustomMapBubblePopoverView *popover = [[CustomMapBubblePopoverView new] autorelease];
// Определяем размеры всплывающего окна
CGSize contentSize = CGSizeMake(60, 30);
[popover setContentSize:contentSize];
// Определяем левую верхную точку данного окна
CGPoint originPoint = [shape centerPoint];
// Преобразуем координаты SVG-карты в экранные координаты
originPoint = [self convertOriginalPointToScreen:originPoint];
// Определяем расположение стрелки всплывающего окна
if (arrowOrientation == NAN) {
CGRect baseRect;
baseRect.origin = originPoint;
baseRect.size = contentSize;
// Располагаем стрелку оптимальным образом
[popover alignArrowForOrigin:originPoint inRect: baseRect];
} else {
[popover setArrowOrientation: arrowOrientation];
}
// Вычисляем и задаём оптимальные размеры и расположение окна
CGRect frame = [popover computeRectForOrigin:originPoint];
frame.size = contentSize;
[popover setFrame:frame];
// Устанавливаем цвет границы всплывающего окна
[popover setBorderColor:[UIColor grayColor]];
// Задаём цвет текста
[popover setTintColor:[UIColor blackColor]];
// Устанавливаем цвет фона данного окна
MapPlaced *placed = [[MapPlaced new] autorelease];
[placed setBackground:[SolidColorBrush solidColorBrushWithColor:[UIColor lightTextColor]]];
// Задаём радиус закругления границы окна
[placed setBorderRadius:12];
// Устанавливаем толщину его границы
[placed setBorderThickness:2];
/* Задаём идентификатор области слоя карты,
для которой отображается всплывающее окно */
[placed setID:[shape ID]];
[popover setPlaced:placed];
// Отображаем всплывающее окно
[m_view addSubview:popover];
}
// Преобразует координаты SVG-карты в экранные координаты
- (CGPoint) convertOriginalPointToScreen: (CGPoint) originalPoint {
CGFloat coef = [m_view boundsWithMargin].size.width / ([m_view pivot].x * 2);
originalPoint.x *= coef;
originalPoint.x += 15;
CGFloat topoCoef = [m_view pivot].y / [m_view pivot].x;
originalPoint.y *= coef;
originalPoint.y += ([m_view boundsWithMargin].size.height -
[m_view boundsWithMargin].size.width * topoCoef)/2;
originalPoint.y += -4;
return originalPoint;
}
@end
См. также: