Map

Description: creating a map with timeline, which data is loaded from file.

The ViewController.h File

#import <MapCharting/MapChart.h>
#import <MapCharting/MapChart2D.h>
#import "MapDataSource.h"
#import "CustomMap.h"
@interface ViewController : UIViewController {
    CustomMap *m_view; // 2D map
    MapDataSource *datasource; // Map data source
}
@end

The ViewController.m File

#import &quot;ViewController.h&quot;
#import &lt;MapCharting/MapTopobase.h&gt;
#import &lt;MapCharting/MapAreaVisual.h&gt;
#import &quot;SolidColorBrush.h&quot;
#import &quot;DataDependency.h&quot;
#import &lt;MapCharting/MapTooltip.h&gt;
#import &lt;MapCharting/MapLabel.h&gt;
#import &lt;MapCharting/MapLegend.h&gt;
#import &lt;MapCharting/MapShape.h&gt;
#import &quot;UIColor+transition.h&quot;
#import &lt;MapCharting/MapLabel.h&gt;
#import &lt;MapCharting/MapChartSign.h&gt;
#import &lt;MapCharting/MapArrow.h&gt;
#import &lt;MapCharting/MapFilledArrow.h&gt;
#import &lt;MapCharting/MapBarVisual.h&gt;
#import &lt;MapCharting/MapPieVisual.h&gt;
#import &quot;UIColor+hex.h&quot;
#import &quot;CustomMap.h&quot;
#import &quot;CustomMapBubblePopoverView.h&quot;
@implementation ViewController
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Load data from source
    datasource = [[MapDataSource alloc]initWithFileName:@&quot;data.txt&quot;];
    // Determine minimum and maximum data values
    [datasource prepare];
    // Create a map based on loaded data
    [self dataSourceFinishedLoadData];
}
// Creates a map based on loaded data
- (void)dataSourceFinishedLoadData
{
    // Create a 2D map
    m_view = [[CustomMap alloc] init];
    // Load file with topobase
    NSData *file = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@&quot;world.svg&quot; ofType:nil]];
    // Create a set an object for working with map topobase
    MapTopobase *topobase = [[MapTopobase alloc] initWithData:file];
    [m_view setTopobase: topobase];
    // Determine affine transformation applied to all map areas
    [topobase setTransform: CGAffineTransformIdentity];
    [m_view setClipsToBounds:YES];
    // Disable map zoom
    [m_view setZoomEnabled:NO];
    
    // Create an object for working with map factor
    MapAreaVisual *visual = [[MapAreaVisual alloc] init];
    // Set data source
    [visual setDataSource: datasource];
    /* Determine whether map area background fill parameters
    depend on data source */
    [[visual background] setIsDependent:YES];
    
    // Create an object for working with map layer
    MapLayer *layer = [[m_view topobase] rootLayer];
    // Create a tooltip for layer
    layer.tooltip = [MapTooltip new];
    // Create colors for filling map layer area background
    NSArray *colors = [NSArray arrayWithObjects:@&quot;ff462c&quot;, @&quot;ebaf36&quot;, @&quot;ffd900&quot;, @&quot;b1ca40&quot;, @&quot;6a8535&quot;, nil];
    // Determine minimum map value
    double value = [datasource minValue];
    // Determine map scale step
    double step = (datasource.maxValue - datasource.minValue) / [colors count];
    // Determine correspondence between map scale intervals and layer area background fill colors
    ValueScale *scale = [[ValueScale new] autorelease];
    for (int i = 1; i &lt;[colors count]; i++) {
        value += step;
        [scale.value addObject:[NSNumber numberWithDouble:value]];
        // Determine colors for the Less value
        UIColor *lessColor = [UIColor colorWithHex:[colors objectAtIndex:(i - 1)]];
        [scale.less addObject:[SolidColorBrush solidColorBrushWithColor:lessColor]];
        // Determine colors for the Equal or Greater value
        UIColor *equalColor = [UIColor colorWithHex:[colors objectAtIndex:(i)]];
        [scale.equal addObject:[SolidColorBrush solidColorBrushWithColor:equalColor]];
        [scale.greater addObject:[SolidColorBrush solidColorBrushWithColor:equalColor]];
    }
    // Set map scale
    [[visual background] setScale:scale];
    
    // Set brush for map background fill
    [m_view setBackground:[SolidColorBrush solidColorBrushWithColor:[UIColor whiteColor]]];
    // Set map title color
    m_view.caption.textColor = [UIColor blackColor];
    
    // Set label text for map layer areas, for which there is no data
    [m_view setNoDataText: NSLocalizedString(@&quot;NO_DATA&quot;, nil)];
    // Create a brush for filling map layer areas that have no data
    SolidColorBrush *brush = [[[SolidColorBrush alloc] init] autorelease];
    // Set brush transparency
    [brush setOpacity: 0.2];
    // Set brush color
    brush.color = [UIColor grayColor];
    // Set this brush
    [[[visual background] scale] setNoData: brush];
    
    Thickness th = {0};
    th.top = 20;
    th.bottom = 20;
    // Determine title text
    [[m_view caption] setText: NSLocalizedString(@&quot;WORLD_MAP&quot;, nil)];
    // Set title margin
    [[m_view caption] setMargin: th];
    // Determine font parameters
    [[m_view caption] setFont:[UIFont systemFontOfSize:18]];
    // Use text direction from left to right
    [m_view setUsingRightToLeft: NO];
    
    // Get map legend
    MapLegend *legend = [m_view legend];
    // Set map scale
    [legend setValueScale: scale];
    // Align legend by map center
    [legend setBlockAlignment: NWLegendBlockAlignmentBottomCenter];
    // Set legend margins
    Thickness margin = {0,20,0,0};
    [legend setMargin:margin];
    // Set text color and legend font parameters
    [legend setTextColor:[UIColor blackColor]];
    [legend setFont:[UIFont systemFontOfSize:12]];
    // Set the Less interval record format
    NSString *lessFormat = [NSMutableString stringWithString:NSLocalizedString(@&quot;LESS_FORMAT&quot;, nil)];
    [legend setLessFormat:lessFormat];
    // Set the Greater interval record format
    NSString *greaterFormat = [NSMutableString stringWithString:NSLocalizedString(@&quot;GREATER_FORMAT&quot;, nil)];
    [legend setGreaterFormat:greaterFormat];
    
    // Create legend top text
    MapLabel *header = [[MapLabel new] autorelease];
    [header setText: NSLocalizedString(@&quot;HEADER_TEXT&quot;, nil)];
    // Set text font parameters
    [header setFont: [UIFont systemFontOfSize:14]];
    [header setTextColor:[UIColor blackColor]];
    // Set text margins
    Thickness headerMargin = {5, 0, 0, 0};
    [header setMargin:headerMargin];
    // Set legend top text
    [[m_view legend] setHeader:header];
    
    // Set marker shape for map legend
    [legend setMarkerShape: MarkerShapeRectangle];
    // Set legend orientation
    [legend setOrientation: NWLegendOrientationFreeVertical];
    // Set legend position
    CGPoint pt = {[m_view legend].origin.x, 325};
    [legend setOrigin: pt];
    
    // Get timeline
    MapTimeAxis *timeAxis = [m_view timeAxis];
    // Display timeline
    [timeAxis setHidden: NO];
    // Set object containing methods for working with timeline
    [timeAxis setDelegate: m_view];
    // Set data source
    [timeAxis setDataSource:datasource];
    // Set up animation delay
    [timeAxis setDelayTime: AnimateTypeSlow];
    // Set font parameters for timeline
    [timeAxis setFont:[UIFont fontWithName:@&quot;Arial&quot; size:16]];
    // Set minimum distance in points between two neighbor axis tick marks
    [timeAxis setMinTickSpacing:1.0];
    // Set blue color for timeline tick marks
    [timeAxis setTickColor: [UIColor blueColor]];
    /* Set time of moving from one axis value
    to other one during animation playback */
    [timeAxis setJumpTime: AnimateTypeNormal];
    // Set current timeline slider position
    [m_view.timeAxis setIndex:0];
    // Create and display label over the current timeline slider position
    MapTooltip *caption = [[MapTooltip new] autorelease];
    [caption setVisibility:YES];
    [timeAxis setLabel: caption];
    
    /* Add an object for working with map factor
    to array of visual elements corresponding to child layers and areas */
    [[layer visuals] addObject: visual];
    // Add map layer to array of displayed layers
    [[m_view layers] addObject:layer];
    [self setView:m_view];
}
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    // Set new map size
    struct CGRect frame;
    frame = CGRectMake(0, 0, 375, 470);
    [m_view setFrame:frame];
    // Set gray color border
    [[m_view layer] setBorderColor: [[UIColor colorWithRed:0.75 green:0.75 blue:0.75 alpha:1] CGColor]];
    [[m_view layer] setBorderWidth: 1.0f];
    
    // Set three map layer areas
    NSMutableArray *shapes = [[NSMutableArray new] autorelease];
    NSArray *shapesIds = [NSArray arrayWithObjects:@&quot;AU&quot;, @&quot;RU&quot;, @&quot;BR&quot;, nil];
    for (NSString *id in shapesIds) {
        MapShape *shape = [[[m_view layers] objectAtIndex:0] shapeWithId:id];
        [shapes addObject:shape];
    }
    /* Display popup window for the AU map layer area
    with arrow position in the right top window corner */
    [self showBubblePopoverForShape:[shapes objectAtIndex:0] withOrientation:PopoverArrowRightTop];
    /* Display popup window for the RU map layer area
    with optimum arrow position */
    [self showBubblePopoverForShape:[shapes objectAtIndex:1] withOrientation:NAN];
    /* Display popup window for the BR map layer area
    with arrow position in the middle of the bottom window border */
    [self showBubblePopoverForShape:[shapes objectAtIndex:2] withOrientation:PopoverArrowBottom];
}
// Displays popup windows for map layer areas
-(void)showBubblePopoverForShape:(MapShape *) shape withOrientation:(BubblePopoverViewArrowOrientation) arrowOrientation {
    // Create a popup window
    CustomMapBubblePopoverView *popover = [[CustomMapBubblePopoverView new] autorelease];
    // Determine popup window size
    CGSize contentSize = CGSizeMake(60, 30);
    [popover setContentSize:contentSize];
    // Determine left top point of this window
    CGPoint originPoint = [shape centerPoint];
    // Transform SVG map coordinates into screen coordinates
    originPoint = [self convertOriginalPointToScreen:originPoint];
    
    // Determine popup window arrow position
    if (arrowOrientation == NAN) {
        CGRect baseRect;
        baseRect.origin = originPoint;
        baseRect.size = contentSize;
        // Place arrow optimally
        [popover alignArrowForOrigin:originPoint inRect: baseRect];
        } else {
        [popover setArrowOrientation: arrowOrientation];
    }
    
    // Calculate and set optimum window size and position
    CGRect frame = [popover computeRectForOrigin:originPoint];
    frame.size = contentSize;
    [popover setFrame:frame];
    // Set popup window border color
    [popover setBorderColor:[UIColor grayColor]];
    // Set text color
    [popover setTintColor:[UIColor blackColor]];
    // Set window background color
    MapPlaced *placed = [[MapPlaced new] autorelease];
    [placed setBackground:[SolidColorBrush solidColorBrushWithColor:[UIColor lightTextColor]]];
    // Set window border rounding radius
    [placed setBorderRadius:12];
    // Set window border thickness
    [placed setBorderThickness:2];
    /* Set map layer area identifier,
    for which a popup window is displayed */
    [placed setID:[shape ID]];
    [popover setPlaced:placed];
    // Display popup window
    [m_view addSubview:popover];
}
// Transforms SVG map coordinates into screen coordinates
- (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

See also:

Creating a Map Popup Window