Authored by Justin R. Miller

refs #64: first cut of static map view

@@ -68,6 +68,7 @@ @@ -68,6 +68,7 @@
68 #import "RMProjection.h" 68 #import "RMProjection.h"
69 #import "RMQuadTree.h" 69 #import "RMQuadTree.h"
70 #import "RMShape.h" 70 #import "RMShape.h"
  71 +#import "RMStaticMapView.h"
71 #import "RMTile.h" 72 #import "RMTile.h"
72 #import "RMTileCache.h" 73 #import "RMTileCache.h"
73 #import "RMTileImage.h" 74 #import "RMTileImage.h"
  1 +//
  2 +// RMStaticMapView.h
  3 +//
  4 +// Copyright (c) 2008-2012, Route-Me Contributors
  5 +// All rights reserved.
  6 +//
  7 +// Redistribution and use in source and binary forms, with or without
  8 +// modification, are permitted provided that the following conditions are met:
  9 +//
  10 +// * Redistributions of source code must retain the above copyright notice, this
  11 +// list of conditions and the following disclaimer.
  12 +// * Redistributions in binary form must reproduce the above copyright notice,
  13 +// this list of conditions and the following disclaimer in the documentation
  14 +// and/or other materials provided with the distribution.
  15 +//
  16 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17 +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18 +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19 +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  20 +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  21 +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  22 +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  23 +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  24 +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  25 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  26 +// POSSIBILITY OF SUCH DAMAGE.
  27 +
  28 +#import <UIKit/UIKit.h>
  29 +
  30 +@interface RMStaticMapView : UIImageView
  31 +
  32 +- (id)initWithFrame:(CGRect)frame mapID:(NSString *)mapID centerCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(CGFloat)initialZoomLevel;
  33 +
  34 +// TODO: delegate
  35 +// TODO: markers
  36 +// TODO: attribution
  37 +// TODO: logo bug
  38 +
  39 +@end
  1 +//
  2 +// RMStaticMapView.m
  3 +//
  4 +// Copyright (c) 2008-2012, Route-Me Contributors
  5 +// All rights reserved.
  6 +//
  7 +// Redistribution and use in source and binary forms, with or without
  8 +// modification, are permitted provided that the following conditions are met:
  9 +//
  10 +// * Redistributions of source code must retain the above copyright notice, this
  11 +// list of conditions and the following disclaimer.
  12 +// * Redistributions in binary form must reproduce the above copyright notice,
  13 +// this list of conditions and the following disclaimer in the documentation
  14 +// and/or other materials provided with the distribution.
  15 +//
  16 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  17 +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18 +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19 +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  20 +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  21 +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  22 +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  23 +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  24 +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  25 +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  26 +// POSSIBILITY OF SUCH DAMAGE.
  27 +
  28 +#import "RMStaticMapView.h"
  29 +
  30 +#define RMStaticMapViewMaxWidth 640.0f
  31 +#define RMStaticMapViewMaxHeight 640.0f
  32 +#define RMStaticMapViewMinZoom 0.0f
  33 +#define RMStaticMapViewMaxZoom 17.0f
  34 +
  35 +@implementation RMStaticMapView
  36 +
  37 +- (id)initWithFrame:(CGRect)frame mapID:(NSString *)mapID centerCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(CGFloat)initialZoomLevel
  38 +{
  39 + if (!(self = [super initWithFrame:frame]))
  40 + return nil;
  41 +
  42 + CGRect requestFrame = CGRectMake(frame.origin.x, frame.origin.y, fminf(frame.size.width, RMStaticMapViewMaxWidth), fminf(frame.size.height, RMStaticMapViewMaxHeight));
  43 +
  44 + if ( ! CLLocationCoordinate2DIsValid(centerCoordinate))
  45 + centerCoordinate = CLLocationCoordinate2DMake(0, 0);
  46 +
  47 + initialZoomLevel = fmaxf(initialZoomLevel, RMStaticMapViewMinZoom);
  48 + initialZoomLevel = fminf(initialZoomLevel, RMStaticMapViewMaxZoom);
  49 +
  50 + self.backgroundColor = [UIColor colorWithPatternImage:[RMMapView resourceImageNamed:@"LoadingTile.png"]];
  51 +
  52 + self.contentMode = UIViewContentModeCenter;
  53 +
  54 + UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
  55 +
  56 + [spinner startAnimating];
  57 +
  58 + spinner.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
  59 +
  60 + spinner.center = self.center;
  61 +
  62 + [self addSubview:spinner];
  63 +
  64 + NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://api.tiles.mapbox.com/v3/%@/%f,%f,%i/%ix%i.png", mapID, centerCoordinate.longitude, centerCoordinate.latitude, (int)roundf(initialZoomLevel), (int)roundf(requestFrame.size.width), (int)roundf(requestFrame.size.height)]];
  65 +
  66 + [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:imageURL]
  67 + queue:[NSOperationQueue new]
  68 + completionHandler:^(NSURLResponse *response, NSData *responseData, NSError *error)
  69 + {
  70 + [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
  71 +
  72 + if (responseData)
  73 + {
  74 + dispatch_async(dispatch_get_main_queue(), ^(void)
  75 + {
  76 + self.image = [UIImage imageWithData:responseData];
  77 + });
  78 + }
  79 +
  80 + else
  81 + return; // TODO: notify delegate of error & display something
  82 + }];
  83 +
  84 + return self;
  85 +}
  86 +
  87 +@end
@@ -124,6 +124,8 @@ @@ -124,6 +124,8 @@
124 DD6A838C1644A26E0097F31F /* TrackingHeading@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DDA6B8C3155CAB9A003DB5D8 /* TrackingHeading@2x.png */; }; 124 DD6A838C1644A26E0097F31F /* TrackingHeading@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DDA6B8C3155CAB9A003DB5D8 /* TrackingHeading@2x.png */; };
125 DD6A838D1644A26E0097F31F /* TrackingLocation.png in Resources */ = {isa = PBXBuildFile; fileRef = DDA6B8C0155CAB9A003DB5D8 /* TrackingLocation.png */; }; 125 DD6A838D1644A26E0097F31F /* TrackingLocation.png in Resources */ = {isa = PBXBuildFile; fileRef = DDA6B8C0155CAB9A003DB5D8 /* TrackingLocation.png */; };
126 DD6A838E1644A26E0097F31F /* TrackingLocation@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DDA6B8C1155CAB9A003DB5D8 /* TrackingLocation@2x.png */; }; 126 DD6A838E1644A26E0097F31F /* TrackingLocation@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DDA6B8C1155CAB9A003DB5D8 /* TrackingLocation@2x.png */; };
  127 + DD7C7E38164C894F0021CCA5 /* RMStaticMapView.h in Headers */ = {isa = PBXBuildFile; fileRef = DD7C7E36164C894F0021CCA5 /* RMStaticMapView.h */; };
  128 + DD7C7E39164C894F0021CCA5 /* RMStaticMapView.m in Sources */ = {isa = PBXBuildFile; fileRef = DD7C7E37164C894F0021CCA5 /* RMStaticMapView.m */; };
127 DD8CDB4A14E0507100B73EB9 /* RMMapQuestOSMSource.h in Headers */ = {isa = PBXBuildFile; fileRef = DD8CDB4814E0507100B73EB9 /* RMMapQuestOSMSource.h */; }; 129 DD8CDB4A14E0507100B73EB9 /* RMMapQuestOSMSource.h in Headers */ = {isa = PBXBuildFile; fileRef = DD8CDB4814E0507100B73EB9 /* RMMapQuestOSMSource.h */; };
128 DD8CDB4B14E0507100B73EB9 /* RMMapQuestOSMSource.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8CDB4914E0507100B73EB9 /* RMMapQuestOSMSource.m */; }; 130 DD8CDB4B14E0507100B73EB9 /* RMMapQuestOSMSource.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8CDB4914E0507100B73EB9 /* RMMapQuestOSMSource.m */; };
129 DD8FD7541559E4A40044D96F /* RMUserLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = DD8FD7521559E4A40044D96F /* RMUserLocation.h */; }; 131 DD8FD7541559E4A40044D96F /* RMUserLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = DD8FD7521559E4A40044D96F /* RMUserLocation.h */; };
@@ -255,6 +257,8 @@ @@ -255,6 +257,8 @@
255 DD5FA1E915E2B020004EB6C5 /* RMLoadingTileView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMLoadingTileView.h; sourceTree = "<group>"; }; 257 DD5FA1E915E2B020004EB6C5 /* RMLoadingTileView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMLoadingTileView.h; sourceTree = "<group>"; };
256 DD5FA1EA15E2B020004EB6C5 /* RMLoadingTileView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMLoadingTileView.m; sourceTree = "<group>"; }; 258 DD5FA1EA15E2B020004EB6C5 /* RMLoadingTileView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMLoadingTileView.m; sourceTree = "<group>"; };
257 DD6A83751644A20C0097F31F /* MapBox.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MapBox.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 259 DD6A83751644A20C0097F31F /* MapBox.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MapBox.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
  260 + DD7C7E36164C894F0021CCA5 /* RMStaticMapView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMStaticMapView.h; sourceTree = "<group>"; };
  261 + DD7C7E37164C894F0021CCA5 /* RMStaticMapView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMStaticMapView.m; sourceTree = "<group>"; };
258 DD8CDB4814E0507100B73EB9 /* RMMapQuestOSMSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMMapQuestOSMSource.h; sourceTree = "<group>"; }; 262 DD8CDB4814E0507100B73EB9 /* RMMapQuestOSMSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMMapQuestOSMSource.h; sourceTree = "<group>"; };
259 DD8CDB4914E0507100B73EB9 /* RMMapQuestOSMSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMMapQuestOSMSource.m; sourceTree = "<group>"; }; 263 DD8CDB4914E0507100B73EB9 /* RMMapQuestOSMSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMMapQuestOSMSource.m; sourceTree = "<group>"; };
260 DD8FD7521559E4A40044D96F /* RMUserLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMUserLocation.h; sourceTree = "<group>"; }; 264 DD8FD7521559E4A40044D96F /* RMUserLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMUserLocation.h; sourceTree = "<group>"; };
@@ -484,6 +488,8 @@ @@ -484,6 +488,8 @@
484 B8C974690E8A1A50007D16AD /* RMMapView.h */, 488 B8C974690E8A1A50007D16AD /* RMMapView.h */,
485 B8C9746A0E8A1A50007D16AD /* RMMapView.m */, 489 B8C9746A0E8A1A50007D16AD /* RMMapView.m */,
486 12F2031E0EBB65E9003D7B6B /* RMMapViewDelegate.h */, 490 12F2031E0EBB65E9003D7B6B /* RMMapViewDelegate.h */,
  491 + DD7C7E36164C894F0021CCA5 /* RMStaticMapView.h */,
  492 + DD7C7E37164C894F0021CCA5 /* RMStaticMapView.m */,
487 B8C974B30E8A23C5007D16AD /* Coordinate Systems */, 493 B8C974B30E8A23C5007D16AD /* Coordinate Systems */,
488 B83E64E20E80E73F001663B6 /* Projections */, 494 B83E64E20E80E73F001663B6 /* Projections */,
489 B83E64CF0E80E73F001663B6 /* Tile Cache */, 495 B83E64CF0E80E73F001663B6 /* Tile Cache */,
@@ -645,6 +651,7 @@ @@ -645,6 +651,7 @@
645 DD5FA1EB15E2B020004EB6C5 /* RMLoadingTileView.h in Headers */, 651 DD5FA1EB15E2B020004EB6C5 /* RMLoadingTileView.h in Headers */,
646 DD4195C9162356900049E6BA /* RMBingSource.h in Headers */, 652 DD4195C9162356900049E6BA /* RMBingSource.h in Headers */,
647 DD1E3C6E161F954F004FC649 /* SMCalloutView.h in Headers */, 653 DD1E3C6E161F954F004FC649 /* SMCalloutView.h in Headers */,
  654 + DD7C7E38164C894F0021CCA5 /* RMStaticMapView.h in Headers */,
648 ); 655 );
649 runOnlyForDeploymentPostprocessing = 0; 656 runOnlyForDeploymentPostprocessing = 0;
650 }; 657 };
@@ -792,6 +799,7 @@ @@ -792,6 +799,7 @@
792 DD5FA1EC15E2B020004EB6C5 /* RMLoadingTileView.m in Sources */, 799 DD5FA1EC15E2B020004EB6C5 /* RMLoadingTileView.m in Sources */,
793 DD4195CA162356900049E6BA /* RMBingSource.m in Sources */, 800 DD4195CA162356900049E6BA /* RMBingSource.m in Sources */,
794 DD1E3C6F161F954F004FC649 /* SMCalloutView.m in Sources */, 801 DD1E3C6F161F954F004FC649 /* SMCalloutView.m in Sources */,
  802 + DD7C7E39164C894F0021CCA5 /* RMStaticMapView.m in Sources */,
795 ); 803 );
796 runOnlyForDeploymentPostprocessing = 0; 804 runOnlyForDeploymentPostprocessing = 0;
797 }; 805 };