/MapView/Map/RMCloudMadeMapSource.m

http://github.com/route-me/route-me · Objective C · 179 lines · 132 code · 19 blank · 28 comment · 13 complexity · 9bccce7d965d8c9bae6edb4cea36aff2 MD5 · raw file

  1. //
  2. // RMCloudMadeMapSource.m
  3. // MapView
  4. //
  5. // Copyright (c) 2008-2009, Cloudmade
  6. // All rights reserved.
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions are met:
  10. //
  11. // * Redistributions of source code must retain the above copyright notice, this
  12. // list of conditions and the following disclaimer.
  13. // * Redistributions in binary form must reproduce the above copyright notice,
  14. // this list of conditions and the following disclaimer in the documentation
  15. // and/or other materials provided with the distribution.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  21. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  24. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27. // POSSIBILITY OF SUCH DAMAGE.
  28. #import "RMCloudMadeMapSource.h"
  29. @implementation RMCloudMadeMapSource
  30. #define kDefaultCloudMadeStyleNumber 7
  31. #define kDefaultCloudMadeSize 256
  32. #define kTokenFileName @"accessToken"
  33. NSString * const RMCloudMadeAccessTokenRequestFailed = @"RMCloudMadeAccessTokenRequestFailed";
  34. #define CMTokenAuthorizationServer @"http://auth.cloudmade.com"
  35. + (NSString*)pathForSavedAccessToken
  36. {
  37. NSArray *paths;
  38. paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  39. if ([paths count] > 0) // Should only be one...
  40. {
  41. NSString *cachePath = [paths objectAtIndex:0];
  42. return [cachePath stringByAppendingPathComponent:kTokenFileName];
  43. }
  44. return nil;
  45. }
  46. -(BOOL) readTokenFromFile
  47. {
  48. NSString* pathToSavedAccessToken = [RMCloudMadeMapSource pathForSavedAccessToken];
  49. if([[NSFileManager defaultManager] fileExistsAtPath:pathToSavedAccessToken])
  50. {
  51. NSError* error;
  52. accessToken = [[NSString alloc] initWithContentsOfFile:pathToSavedAccessToken encoding:NSASCIIStringEncoding error:&error];
  53. if(!accessToken)
  54. {
  55. RMLog(@"can't read file %@ %@\n",pathToSavedAccessToken,error.localizedDescription);
  56. [[NSFileManager defaultManager] removeItemAtPath:pathToSavedAccessToken error:nil];
  57. return FALSE;
  58. }
  59. return TRUE;
  60. }
  61. return FALSE;
  62. }
  63. -(void) requestToken
  64. {
  65. if([self readTokenFromFile])
  66. return;
  67. NSString* url = [NSString stringWithFormat:@"%@/token/%@?userid=%u",CMTokenAuthorizationServer,accessKey,
  68. [[UIDevice currentDevice].uniqueIdentifier hash]];
  69. NSData* data = nil;
  70. RMLog(@"%s, url = %@\n",__FUNCTION__,url);
  71. NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
  72. cachePolicy:NSURLRequestUseProtocolCachePolicy
  73. timeoutInterval:5.0];
  74. [ theRequest setHTTPMethod: @"POST" ];
  75. NSURLResponse* response;
  76. NSError* error = nil;
  77. BOOL done = FALSE;
  78. int attempt = 0;
  79. do
  80. {
  81. data = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error];
  82. if(data && [(NSHTTPURLResponse*)response statusCode] == 200)
  83. {
  84. NSString* pathToSavedAccessToken = [RMCloudMadeMapSource pathForSavedAccessToken];
  85. accessToken = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
  86. [accessToken writeToFile:pathToSavedAccessToken atomically:YES encoding:NSASCIIStringEncoding error:nil];
  87. done = TRUE;
  88. }
  89. else
  90. {
  91. if([(NSHTTPURLResponse*)response statusCode] == 403 && !attempt)
  92. {
  93. RMLog(@"Token wasn't obtained.Response code = %d\n",[(NSHTTPURLResponse*)response statusCode]);
  94. attempt++;
  95. }
  96. else
  97. {
  98. RMLog(@"Token wasn't obtained %@\n",error.localizedDescription);
  99. [[NSNotificationCenter defaultCenter] postNotificationName:RMCloudMadeAccessTokenRequestFailed object:error];
  100. done = TRUE;
  101. }
  102. }
  103. }
  104. while(!done);
  105. }
  106. - (id) init
  107. {
  108. return [self initWithAccessKey:@""
  109. styleNumber:kDefaultCloudMadeStyleNumber];
  110. }
  111. /// designated initializer
  112. - (id) initWithAccessKey:(NSString *)developerAccessKey
  113. styleNumber:(NSUInteger)styleNumber;
  114. {
  115. NSAssert((styleNumber > 0), @"CloudMade style number must be positive");
  116. NSAssert(([developerAccessKey length] > 0), @"CloudMade access key must be non-empty");
  117. if (self = [super init])
  118. {
  119. [self setTileSideLength:kDefaultCloudMadeSize];
  120. accessKey = developerAccessKey;
  121. if (styleNumber > 0)
  122. cloudmadeStyleNumber = styleNumber;
  123. else
  124. cloudmadeStyleNumber = kDefaultCloudMadeStyleNumber;
  125. }
  126. [self requestToken];
  127. return self;
  128. }
  129. - (NSString*) tileURL: (RMTile) tile
  130. {
  131. NSAssert4(((tile.zoom >= self.minZoom) && (tile.zoom <= self.maxZoom)),
  132. @"%@ tried to retrieve tile with zoomLevel %d, outside source's defined range %f to %f",
  133. self, tile.zoom, self.minZoom, self.maxZoom);
  134. NSAssert(accessToken,@"CloudMade access token must be non-empty");
  135. return [NSString stringWithFormat:@"http://tile.cloudmade.com/%@/%d/%d/%d/%d/%d.png?token=%@",
  136. accessKey,
  137. cloudmadeStyleNumber,
  138. kDefaultCloudMadeSize, tile.zoom, tile.x, tile.y,accessToken];
  139. }
  140. -(NSString*) uniqueTilecacheKey
  141. {
  142. return [NSString stringWithFormat:@"CloudMadeMaps%d", cloudmadeStyleNumber];
  143. }
  144. -(NSString *)shortName
  145. {
  146. return [NSString stringWithFormat:@"Cloud Made %d", cloudmadeStyleNumber];
  147. }
  148. -(NSString *)longDescription
  149. {
  150. return @"CloudMade.com provides high quality renderings of Open Street Map data";
  151. }
  152. -(NSString *)shortAttribution
  153. {
  154. return @"© 2009 CloudMade.com";
  155. }
  156. -(NSString *)longAttribution
  157. {
  158. return @"Map © CloudMade.com. Map data CCBYSA 2009 OpenStreetMap.org contributors.";
  159. }
  160. @end