Authored by Jon Hjelle

Added SpatialCloud map source

  1 +//
  2 +// RMSpatialCloudMapSource.h
  3 +//
  4 +// Copyright (c) 2011, SpatialCloud
  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 "RMAbstractMercatorWebSource.h"
  29 +
  30 +/*!
  31 + \brief Subclass of RMAbstractMercatorWebSource for access to SpatialCloud.com MapSources.
  32 +
  33 + Allows access to SpatialCloud.com MapSources. Direct access can be attained using a loginID
  34 + and password. Alternatively, a proxy server can be used in place of a loginID and password.
  35 + If both a loginID/password pair and a server URL are provided, the server URL will be used.
  36 +
  37 + SpatialCloud.com MapSources are available for purchase & resale for various US & world
  38 + datasets; in addition, SpatialCloud allows you to host/serve/resell your own datasets.
  39 + Please visit http://spatialcloud.com to setup your own account, subscribe to the
  40 + MapSource(s), & create your own MapStream(s), as well as licensing terms and fees.
  41 + */
  42 +
  43 +@interface RMSpatialCloudMapSource : RMAbstractMercatorWebSource <RMAbstractMercatorWebSource> {
  44 + NSString *customServerURL;
  45 + NSString *loginID;
  46 + NSString *password;
  47 +}
  48 +
  49 +// URL string of proxy server used to access SpatialCloud.com tiles
  50 +//
  51 +// If you don't have a proxy server, use the loginID/password combination below
  52 +// See http://www.spatialcloud.com/index.cfm?event=home.support for server sample code
  53 +// Examples:
  54 +// http://127.0.0.1:8080/openbd/custom/server/CFML/index.cfm?
  55 +// http://localhost:8080/openbd/SSCustomServer/server/JSP/index.jsp?
  56 +// http://localhost/server/PHP/index.php?
  57 +@property (nonatomic, retain) NSString *customServerURL;
  58 +
  59 +// LoginID and password used to access a MapStream
  60 +//
  61 +// See http://www.spatialcloud.com/index.cfm?event=home.support to signup
  62 +// For the purposes of this demo, use 20101213051851055 for the loginID and
  63 +// gRtXbm79CODFq for the password
  64 +// If you don't want to release your loginID in your app's binary, consider
  65 +// using a proxy server as mentioned above
  66 +@property (nonatomic, retain) NSString *loginID;
  67 +@property (nonatomic, retain) NSString *password;
  68 +
  69 +- (id)initWithLoginID:(NSString *)newLoginID password:(NSString *)newPassword;
  70 +- (id)initWithCustomServerURL:(NSString *)newCustomServerURL;
  71 +
  72 +@end
  1 +//
  2 +// RMSpatialCloudMapSource.m
  3 +//
  4 +// Copyright (c) 2011, SpatialCloud
  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 "RMSpatialCloudMapSource.h"
  29 +#import <CommonCrypto/CommonDigest.h>
  30 +
  31 +
  32 +@implementation RMSpatialCloudMapSource
  33 +
  34 +@synthesize customServerURL;
  35 +@synthesize loginID;
  36 +@synthesize password;
  37 +
  38 +- (id)init {
  39 + self = [super init];
  40 + if (self) {
  41 + [self setMaxZoom:18];
  42 + [self setMinZoom:1];
  43 + }
  44 + return self;
  45 +}
  46 +
  47 +- (id)initWithLoginID:(NSString *)newLoginID password:(NSString *)newPassword {
  48 + self = [self init];
  49 + if (self) {
  50 + loginID = [newLoginID retain];
  51 + password = [newPassword retain];
  52 + }
  53 + return self;
  54 +}
  55 +
  56 +- (id)initWithCustomServerURL:(NSString *)newCustomServerURL {
  57 + self = [self init];
  58 + if (self) {
  59 + customServerURL = [newCustomServerURL retain];
  60 + }
  61 + return self;
  62 +}
  63 +
  64 +- (void)dealloc {
  65 + [customServerURL release];
  66 + [loginID release];
  67 + [password release];
  68 + [super dealloc];
  69 +}
  70 +
  71 +- (NSString *)md5HexDigest:(NSString *)stringToHash {
  72 + const char *cStringToHash = [stringToHash UTF8String];
  73 + unsigned char hash[CC_MD5_DIGEST_LENGTH];
  74 + CC_MD5(cStringToHash, strlen(cStringToHash), hash);
  75 +
  76 + NSMutableString *hashString = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
  77 + for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
  78 + [hashString appendFormat:@"%02X", hash[i]];
  79 + }
  80 + return hashString;
  81 +}
  82 +
  83 +- (NSString *)tileURL:(RMTile)tile {
  84 + NSAssert4(((tile.zoom >= self.minZoom) && (tile.zoom <= self.maxZoom)),
  85 + @"%@ tried to retrieve tile with zoomLevel %d, outside source's defined range %f to %f",
  86 + self, tile.zoom, self.minZoom, self.maxZoom);
  87 + NSAssert(([self.loginID length] > 0) || ([self.customServerURL length] > 0),
  88 + @"Login ID or Custom Server URL for Spatial Cloud must be non-empty");
  89 + NSAssert(([self.password length] > 0) || ([self.customServerURL length] > 0),
  90 + @"Password or Custom Server URL for Spatial Cloud must be non-empty");
  91 +
  92 + // Flip the y-coordinate from the default route-me scheme to the Spatial Cloud tile scheme
  93 + uint32_t flippedYCoordinate = (1 << tile.zoom) - 1 - tile.y;
  94 +
  95 + NSString* fullURL = nil;
  96 + if ([self.customServerURL length] > 0) {
  97 + fullURL = [NSString stringWithFormat:@"%@%d/%d/%d.jpg",
  98 + customServerURL, tile.zoom, tile.x, flippedYCoordinate];
  99 + } else {
  100 + NSString *serverURL = @"http://ss.spatialcloud.com/getsign.cfm";
  101 + NSString *fileKey = [NSString stringWithFormat:@"%d/%d/%d.jpg",
  102 + tile.zoom, tile.x, flippedYCoordinate];
  103 +
  104 + NSString *authSign = [NSString stringWithFormat:@"%@%@%@",
  105 + fileKey, self.loginID, self.password];
  106 + NSString *authSignHash = [self md5HexDigest:authSign];
  107 +
  108 + fullURL = [NSString stringWithFormat:@"%@/1.0.0/spatialcloud/%@?loginid=%@&authSign=%@&viewer=viewer",
  109 + serverURL, fileKey, self.loginID, authSignHash];
  110 + }
  111 +
  112 + return fullURL;
  113 +}
  114 +
  115 +- (NSString *)uniqueTilecacheKey {
  116 + return @"SpatialCloud";
  117 +}
  118 +
  119 +- (NSString *)shortName {
  120 + return @"SpatialCloud.com";
  121 +}
  122 +
  123 +- (NSString *)longDescription {
  124 + return @"SpatialCloud.com MapSources are available for purchase & resale for various US & world datasets; in addition, SpatialCloud allows you to host/serve/resell your own datasets. Learn more at SpatialCloud.com.";
  125 +}
  126 +
  127 +- (NSString *)shortAttribution {
  128 + return @"Spatial Cloud Demo";
  129 +}
  130 +
  131 +- (NSString *)longAttribution {
  132 + return @"SpatialCloud MapSource terms vary, but this SpatialCloud Demo is for Route-Me code demo purposes only. The demo MapSource provided is SpatialCloud USA, which is typically licensed using the flexible Creative Commons Attribution 3.0 Unported terms when subscribed to. If implementing this Route-Me code in your application, please visit SpatialCloud.com and setup your own account, subscribe to the MapSource(s), & create your own MapStream(s). If the demo is abused SpatialCloud may be forced to disable this demo for all.";
  133 +}
  134 +
  135 +@end
@@ -40,6 +40,9 @@ @@ -40,6 +40,9 @@
40 25757F4F1291C8640083D504 /* RMCircle.h in Headers */ = {isa = PBXBuildFile; fileRef = 25757F4D1291C8640083D504 /* RMCircle.h */; }; 40 25757F4F1291C8640083D504 /* RMCircle.h in Headers */ = {isa = PBXBuildFile; fileRef = 25757F4D1291C8640083D504 /* RMCircle.h */; };
41 25757F501291C8640083D504 /* RMCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 25757F4E1291C8640083D504 /* RMCircle.m */; }; 41 25757F501291C8640083D504 /* RMCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 25757F4E1291C8640083D504 /* RMCircle.m */; };
42 25757F521291C8850083D504 /* RMCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 25757F4E1291C8640083D504 /* RMCircle.m */; }; 42 25757F521291C8850083D504 /* RMCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = 25757F4E1291C8640083D504 /* RMCircle.m */; };
  43 + 2599740912EB966400816331 /* RMSpatialCloudMapSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2599740712EB966400816331 /* RMSpatialCloudMapSource.h */; };
  44 + 2599740A12EB966400816331 /* RMSpatialCloudMapSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2599740812EB966400816331 /* RMSpatialCloudMapSource.m */; };
  45 + 2599740B12EB967600816331 /* RMSpatialCloudMapSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2599740812EB966400816331 /* RMSpatialCloudMapSource.m */; };
43 2B2BADD70FA3B45A00EE37AA /* marker-X.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B2BADD60FA3B45A00EE37AA /* marker-X.png */; }; 46 2B2BADD70FA3B45A00EE37AA /* marker-X.png in Resources */ = {isa = PBXBuildFile; fileRef = 2B2BADD60FA3B45A00EE37AA /* marker-X.png */; };
44 2B5682720F68E36000E8DF40 /* RMOpenAerialMapSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B5682700F68E36000E8DF40 /* RMOpenAerialMapSource.h */; }; 47 2B5682720F68E36000E8DF40 /* RMOpenAerialMapSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B5682700F68E36000E8DF40 /* RMOpenAerialMapSource.h */; };
45 2B5682730F68E36000E8DF40 /* RMOpenAerialMapSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */; }; 48 2B5682730F68E36000E8DF40 /* RMOpenAerialMapSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */; };
@@ -231,6 +234,8 @@ @@ -231,6 +234,8 @@
231 23A0ABA90EB923AF003A4521 /* RMLatLong.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMLatLong.h; sourceTree = "<group>"; }; 234 23A0ABA90EB923AF003A4521 /* RMLatLong.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMLatLong.h; sourceTree = "<group>"; };
232 25757F4D1291C8640083D504 /* RMCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMCircle.h; sourceTree = "<group>"; }; 235 25757F4D1291C8640083D504 /* RMCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMCircle.h; sourceTree = "<group>"; };
233 25757F4E1291C8640083D504 /* RMCircle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMCircle.m; sourceTree = "<group>"; }; 236 25757F4E1291C8640083D504 /* RMCircle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMCircle.m; sourceTree = "<group>"; };
  237 + 2599740712EB966400816331 /* RMSpatialCloudMapSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMSpatialCloudMapSource.h; sourceTree = "<group>"; };
  238 + 2599740812EB966400816331 /* RMSpatialCloudMapSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMSpatialCloudMapSource.m; sourceTree = "<group>"; };
234 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 239 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
235 2B2BADD60FA3B45A00EE37AA /* marker-X.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "marker-X.png"; path = "../marker-X.png"; sourceTree = "<group>"; }; 240 2B2BADD60FA3B45A00EE37AA /* marker-X.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "marker-X.png"; path = "../marker-X.png"; sourceTree = "<group>"; };
236 2B2BD41D0F79A95500B8B9A7 /* README-static-library-build.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = "README-static-library-build.rtf"; sourceTree = "<group>"; }; 241 2B2BD41D0F79A95500B8B9A7 /* README-static-library-build.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = "README-static-library-build.rtf"; sourceTree = "<group>"; };
@@ -610,6 +615,8 @@ @@ -610,6 +615,8 @@
610 B885ABB10EBB1332002206AB /* RMCloudMadeMapSource.m */, 615 B885ABB10EBB1332002206AB /* RMCloudMadeMapSource.m */,
611 2B5682700F68E36000E8DF40 /* RMOpenAerialMapSource.h */, 616 2B5682700F68E36000E8DF40 /* RMOpenAerialMapSource.h */,
612 2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */, 617 2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */,
  618 + 2599740712EB966400816331 /* RMSpatialCloudMapSource.h */,
  619 + 2599740812EB966400816331 /* RMSpatialCloudMapSource.m */,
613 ); 620 );
614 name = "Tile Source"; 621 name = "Tile Source";
615 sourceTree = "<group>"; 622 sourceTree = "<group>";
@@ -791,6 +798,7 @@ @@ -791,6 +798,7 @@
791 D1437B35122869E400888DAE /* RMDBTileImage.h in Headers */, 798 D1437B35122869E400888DAE /* RMDBTileImage.h in Headers */,
792 D1437B37122869E400888DAE /* RMDBMapSource.h in Headers */, 799 D1437B37122869E400888DAE /* RMDBMapSource.h in Headers */,
793 25757F4F1291C8640083D504 /* RMCircle.h in Headers */, 800 25757F4F1291C8640083D504 /* RMCircle.h in Headers */,
  801 + 2599740912EB966400816331 /* RMSpatialCloudMapSource.h in Headers */,
794 ); 802 );
795 runOnlyForDeploymentPostprocessing = 0; 803 runOnlyForDeploymentPostprocessing = 0;
796 }; 804 };
@@ -985,6 +993,7 @@ @@ -985,6 +993,7 @@
985 46B1C067117653930062018A /* GTMNSNumber+64Bit.m in Sources */, 993 46B1C067117653930062018A /* GTMNSNumber+64Bit.m in Sources */,
986 46B1C075117653F10062018A /* GTMObjC2Runtime.m in Sources */, 994 46B1C075117653F10062018A /* GTMObjC2Runtime.m in Sources */,
987 25757F521291C8850083D504 /* RMCircle.m in Sources */, 995 25757F521291C8850083D504 /* RMCircle.m in Sources */,
  996 + 2599740B12EB967600816331 /* RMSpatialCloudMapSource.m in Sources */,
988 ); 997 );
989 runOnlyForDeploymentPostprocessing = 0; 998 runOnlyForDeploymentPostprocessing = 0;
990 }; 999 };