├── README.md ├── WMSOnMapKit.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── WMSOnMapKit.xccheckout │ └── xcuserdata │ │ └── ssumbera.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings └── xcuserdata │ └── ssumbera.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── WMSOnMapKit.xcscheme │ └── xcschememanagement.plist └── WMSOnMapKit ├── AppDelegate.h ├── AppDelegate.m ├── Images.xcassets ├── AppIcon.appiconset │ └── Contents.json └── LaunchImage.launchimage │ └── Contents.json ├── MapViewController.h ├── MapViewController.m ├── MapViewUtils.h ├── WMSOnMapKit-Info.plist ├── WMSOnMapKit-Prefix.pch ├── WMSTileOverlay.h ├── WMSTileOverlay.m ├── en.lproj └── InfoPlist.strings └── main.m /README.md: -------------------------------------------------------------------------------- 1 | 2 | WMSOnMapKit-iOS 3 | ===================== 4 | Update 2018 for iOS11 there is also a hack to enable ARKit 5 | 8 | 9 | Update 2017 for iOS9 : check this video that sets in this sample mkMapView.mapType = MKMapTypeHybridFlyover; 10 | in [MapViewController.m Line 38] ( https://github.com/Sumbera/WMSOnMapKit-iOS7/blob/master/WMSOnMapKit/MapViewController.m#L38 ) 11 | 12 | 15 | 16 | sample code of using WMS in MapKit on iOS 17 | 18 | iOS7 introduced new class MKTileOverlay sample derives from this class WMSTileOverlay 19 | 20 | Key method to custom tile loading (and cache control) is loadTileAtPath:result 21 | 22 | – (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error)) result 23 | 24 | this method is called by MapKit (or better by MKTileOverlayRenderer ) when it needs to draw a tile . It asks for NSData (and error) from x,y,z tile coordinates. In this method you can load NSData either from local cache or from NSURLConnection and pass resulting NSData (when ready) back to MapKit, for example like this (reading from cache) 25 | 26 | result ([NSData dataWithContentsOfFile:filePath], nil); 27 | 28 | if you do not need to use cache and you do not provide loadTileAtPath method , you can use another hook (callback) that is provided by MKTileOverlay, URLForTilePath:path 29 | 30 | – (NSURL *)URLForTilePath:(MKTileOverlayPath)path 31 | 32 | this method enables to custom format URL required to load tile, thus you can use WMS HTTP-GET parameters, for example : 33 | 34 | NSString * resolvedUrl = [NSString stringWithFormat:@”%@&BBOX=%f,%f,%f,%f”,self.url,left,bottom,right,top]; 35 | 36 | if there is neither method in the derived class, then you probably do not need to derive at all from MKTileOverlay and directly use it with initWithUrlTemplate (not case for WMS, but for any other x,y,z sources) 37 | 38 | 39 | Example of using WMS source 40 | 41 | NSString * url = @"http://services.cuzk.cz/wms/wms.asp?&LAYERS=KN&REQUEST=GetMap&SERVICE=WMS&VERSION=1.3.0&FORMAT=image/png&TRANSPARENT=TRUE&STYLES=&CRS=EPSG:900913&WIDTH=256&HEIGHT=256"; 42 | [ mapViewController.mkMapView addOverlay:[[WMSTileOverlay alloc] initWithUrl:url UseMercator:YES]]; 43 | 44 | info available also here : http://blog.sumbera.com/2014/05/17/wms-on-mapkit-with-ios7/ 45 | -------------------------------------------------------------------------------- /WMSOnMapKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5A3769A81926AAF20053B3A5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A3769A71926AAF20053B3A5 /* Foundation.framework */; }; 11 | 5A3769AA1926AAF20053B3A5 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A3769A91926AAF20053B3A5 /* CoreGraphics.framework */; }; 12 | 5A3769AC1926AAF20053B3A5 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A3769AB1926AAF20053B3A5 /* UIKit.framework */; }; 13 | 5A3769B21926AAF20053B3A5 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5A3769B01926AAF20053B3A5 /* InfoPlist.strings */; }; 14 | 5A3769B41926AAF20053B3A5 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A3769B31926AAF20053B3A5 /* main.m */; }; 15 | 5A3769B81926AAF20053B3A5 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A3769B71926AAF20053B3A5 /* AppDelegate.m */; }; 16 | 5A3769BA1926AAF20053B3A5 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5A3769B91926AAF20053B3A5 /* Images.xcassets */; }; 17 | 5A3769D71926AB0A0053B3A5 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A3769D61926AB0A0053B3A5 /* MapKit.framework */; }; 18 | 5A3769D91926AB110053B3A5 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A3769D81926AB110053B3A5 /* CoreLocation.framework */; }; 19 | 5A3769E31926AFA90053B3A5 /* MapViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A3769E21926AFA90053B3A5 /* MapViewController.m */; }; 20 | 5A438A561928076A008540AB /* WMSTileOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A438A551928076A008540AB /* WMSTileOverlay.m */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXFileReference section */ 24 | 5A3769A41926AAF20053B3A5 /* WMSOnMapKit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WMSOnMapKit.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | 5A3769A71926AAF20053B3A5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 26 | 5A3769A91926AAF20053B3A5 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 27 | 5A3769AB1926AAF20053B3A5 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 28 | 5A3769AF1926AAF20053B3A5 /* WMSOnMapKit-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "WMSOnMapKit-Info.plist"; sourceTree = ""; }; 29 | 5A3769B11926AAF20053B3A5 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 30 | 5A3769B31926AAF20053B3A5 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 31 | 5A3769B51926AAF20053B3A5 /* WMSOnMapKit-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WMSOnMapKit-Prefix.pch"; sourceTree = ""; }; 32 | 5A3769B61926AAF20053B3A5 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 33 | 5A3769B71926AAF20053B3A5 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 34 | 5A3769B91926AAF20053B3A5 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 35 | 5A3769C01926AAF20053B3A5 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 36 | 5A3769D61926AB0A0053B3A5 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; }; 37 | 5A3769D81926AB110053B3A5 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; 38 | 5A3769DD1926ABCF0053B3A5 /* MapViewUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MapViewUtils.h; sourceTree = ""; }; 39 | 5A3769E11926AFA90053B3A5 /* MapViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapViewController.h; sourceTree = ""; }; 40 | 5A3769E21926AFA90053B3A5 /* MapViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MapViewController.m; sourceTree = ""; }; 41 | 5A438A541928076A008540AB /* WMSTileOverlay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMSTileOverlay.h; sourceTree = ""; }; 42 | 5A438A551928076A008540AB /* WMSTileOverlay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WMSTileOverlay.m; sourceTree = ""; }; 43 | /* End PBXFileReference section */ 44 | 45 | /* Begin PBXFrameworksBuildPhase section */ 46 | 5A3769A11926AAF20053B3A5 /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | 5A3769D91926AB110053B3A5 /* CoreLocation.framework in Frameworks */, 51 | 5A3769D71926AB0A0053B3A5 /* MapKit.framework in Frameworks */, 52 | 5A3769AA1926AAF20053B3A5 /* CoreGraphics.framework in Frameworks */, 53 | 5A3769AC1926AAF20053B3A5 /* UIKit.framework in Frameworks */, 54 | 5A3769A81926AAF20053B3A5 /* Foundation.framework in Frameworks */, 55 | ); 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXFrameworksBuildPhase section */ 59 | 60 | /* Begin PBXGroup section */ 61 | 5A37699B1926AAF20053B3A5 = { 62 | isa = PBXGroup; 63 | children = ( 64 | 5A3769AD1926AAF20053B3A5 /* WMSOnMapKit */, 65 | 5A3769A61926AAF20053B3A5 /* Frameworks */, 66 | 5A3769A51926AAF20053B3A5 /* Products */, 67 | ); 68 | sourceTree = ""; 69 | }; 70 | 5A3769A51926AAF20053B3A5 /* Products */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 5A3769A41926AAF20053B3A5 /* WMSOnMapKit.app */, 74 | ); 75 | name = Products; 76 | sourceTree = ""; 77 | }; 78 | 5A3769A61926AAF20053B3A5 /* Frameworks */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 5A3769D81926AB110053B3A5 /* CoreLocation.framework */, 82 | 5A3769D61926AB0A0053B3A5 /* MapKit.framework */, 83 | 5A3769A71926AAF20053B3A5 /* Foundation.framework */, 84 | 5A3769A91926AAF20053B3A5 /* CoreGraphics.framework */, 85 | 5A3769AB1926AAF20053B3A5 /* UIKit.framework */, 86 | 5A3769C01926AAF20053B3A5 /* XCTest.framework */, 87 | ); 88 | name = Frameworks; 89 | sourceTree = ""; 90 | }; 91 | 5A3769AD1926AAF20053B3A5 /* WMSOnMapKit */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 5A3769DD1926ABCF0053B3A5 /* MapViewUtils.h */, 95 | 5A3769E11926AFA90053B3A5 /* MapViewController.h */, 96 | 5A3769E21926AFA90053B3A5 /* MapViewController.m */, 97 | 5A3769B61926AAF20053B3A5 /* AppDelegate.h */, 98 | 5A3769B71926AAF20053B3A5 /* AppDelegate.m */, 99 | 5A3769B91926AAF20053B3A5 /* Images.xcassets */, 100 | 5A3769AE1926AAF20053B3A5 /* Supporting Files */, 101 | 5A438A541928076A008540AB /* WMSTileOverlay.h */, 102 | 5A438A551928076A008540AB /* WMSTileOverlay.m */, 103 | ); 104 | path = WMSOnMapKit; 105 | sourceTree = ""; 106 | }; 107 | 5A3769AE1926AAF20053B3A5 /* Supporting Files */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 5A3769AF1926AAF20053B3A5 /* WMSOnMapKit-Info.plist */, 111 | 5A3769B01926AAF20053B3A5 /* InfoPlist.strings */, 112 | 5A3769B31926AAF20053B3A5 /* main.m */, 113 | 5A3769B51926AAF20053B3A5 /* WMSOnMapKit-Prefix.pch */, 114 | ); 115 | name = "Supporting Files"; 116 | sourceTree = ""; 117 | }; 118 | /* End PBXGroup section */ 119 | 120 | /* Begin PBXNativeTarget section */ 121 | 5A3769A31926AAF20053B3A5 /* WMSOnMapKit */ = { 122 | isa = PBXNativeTarget; 123 | buildConfigurationList = 5A3769D01926AAF20053B3A5 /* Build configuration list for PBXNativeTarget "WMSOnMapKit" */; 124 | buildPhases = ( 125 | 5A3769A01926AAF20053B3A5 /* Sources */, 126 | 5A3769A11926AAF20053B3A5 /* Frameworks */, 127 | 5A3769A21926AAF20053B3A5 /* Resources */, 128 | ); 129 | buildRules = ( 130 | ); 131 | dependencies = ( 132 | ); 133 | name = WMSOnMapKit; 134 | productName = WMSOnMapKit; 135 | productReference = 5A3769A41926AAF20053B3A5 /* WMSOnMapKit.app */; 136 | productType = "com.apple.product-type.application"; 137 | }; 138 | /* End PBXNativeTarget section */ 139 | 140 | /* Begin PBXProject section */ 141 | 5A37699C1926AAF20053B3A5 /* Project object */ = { 142 | isa = PBXProject; 143 | attributes = { 144 | LastUpgradeCheck = 0510; 145 | ORGANIZATIONNAME = sumbera; 146 | }; 147 | buildConfigurationList = 5A37699F1926AAF20053B3A5 /* Build configuration list for PBXProject "WMSOnMapKit" */; 148 | compatibilityVersion = "Xcode 3.2"; 149 | developmentRegion = English; 150 | hasScannedForEncodings = 0; 151 | knownRegions = ( 152 | en, 153 | ); 154 | mainGroup = 5A37699B1926AAF20053B3A5; 155 | productRefGroup = 5A3769A51926AAF20053B3A5 /* Products */; 156 | projectDirPath = ""; 157 | projectRoot = ""; 158 | targets = ( 159 | 5A3769A31926AAF20053B3A5 /* WMSOnMapKit */, 160 | ); 161 | }; 162 | /* End PBXProject section */ 163 | 164 | /* Begin PBXResourcesBuildPhase section */ 165 | 5A3769A21926AAF20053B3A5 /* Resources */ = { 166 | isa = PBXResourcesBuildPhase; 167 | buildActionMask = 2147483647; 168 | files = ( 169 | 5A3769B21926AAF20053B3A5 /* InfoPlist.strings in Resources */, 170 | 5A3769BA1926AAF20053B3A5 /* Images.xcassets in Resources */, 171 | ); 172 | runOnlyForDeploymentPostprocessing = 0; 173 | }; 174 | /* End PBXResourcesBuildPhase section */ 175 | 176 | /* Begin PBXSourcesBuildPhase section */ 177 | 5A3769A01926AAF20053B3A5 /* Sources */ = { 178 | isa = PBXSourcesBuildPhase; 179 | buildActionMask = 2147483647; 180 | files = ( 181 | 5A3769B81926AAF20053B3A5 /* AppDelegate.m in Sources */, 182 | 5A3769E31926AFA90053B3A5 /* MapViewController.m in Sources */, 183 | 5A3769B41926AAF20053B3A5 /* main.m in Sources */, 184 | 5A438A561928076A008540AB /* WMSTileOverlay.m in Sources */, 185 | ); 186 | runOnlyForDeploymentPostprocessing = 0; 187 | }; 188 | /* End PBXSourcesBuildPhase section */ 189 | 190 | /* Begin PBXVariantGroup section */ 191 | 5A3769B01926AAF20053B3A5 /* InfoPlist.strings */ = { 192 | isa = PBXVariantGroup; 193 | children = ( 194 | 5A3769B11926AAF20053B3A5 /* en */, 195 | ); 196 | name = InfoPlist.strings; 197 | sourceTree = ""; 198 | }; 199 | /* End PBXVariantGroup section */ 200 | 201 | /* Begin XCBuildConfiguration section */ 202 | 5A3769CE1926AAF20053B3A5 /* Debug */ = { 203 | isa = XCBuildConfiguration; 204 | buildSettings = { 205 | ALWAYS_SEARCH_USER_PATHS = NO; 206 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 207 | CLANG_CXX_LIBRARY = "libc++"; 208 | CLANG_ENABLE_MODULES = YES; 209 | CLANG_ENABLE_OBJC_ARC = YES; 210 | CLANG_WARN_BOOL_CONVERSION = YES; 211 | CLANG_WARN_CONSTANT_CONVERSION = YES; 212 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 213 | CLANG_WARN_EMPTY_BODY = YES; 214 | CLANG_WARN_ENUM_CONVERSION = YES; 215 | CLANG_WARN_INT_CONVERSION = YES; 216 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 217 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 218 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 219 | COPY_PHASE_STRIP = NO; 220 | GCC_C_LANGUAGE_STANDARD = gnu99; 221 | GCC_DYNAMIC_NO_PIC = NO; 222 | GCC_OPTIMIZATION_LEVEL = 0; 223 | GCC_PREPROCESSOR_DEFINITIONS = ( 224 | "DEBUG=1", 225 | "$(inherited)", 226 | ); 227 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 228 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 229 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 230 | GCC_WARN_UNDECLARED_SELECTOR = YES; 231 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 232 | GCC_WARN_UNUSED_FUNCTION = YES; 233 | GCC_WARN_UNUSED_VARIABLE = YES; 234 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 235 | ONLY_ACTIVE_ARCH = YES; 236 | SDKROOT = iphoneos; 237 | TARGETED_DEVICE_FAMILY = "1,2"; 238 | }; 239 | name = Debug; 240 | }; 241 | 5A3769CF1926AAF20053B3A5 /* Release */ = { 242 | isa = XCBuildConfiguration; 243 | buildSettings = { 244 | ALWAYS_SEARCH_USER_PATHS = NO; 245 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 246 | CLANG_CXX_LIBRARY = "libc++"; 247 | CLANG_ENABLE_MODULES = YES; 248 | CLANG_ENABLE_OBJC_ARC = YES; 249 | CLANG_WARN_BOOL_CONVERSION = YES; 250 | CLANG_WARN_CONSTANT_CONVERSION = YES; 251 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 252 | CLANG_WARN_EMPTY_BODY = YES; 253 | CLANG_WARN_ENUM_CONVERSION = YES; 254 | CLANG_WARN_INT_CONVERSION = YES; 255 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 256 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 257 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 258 | COPY_PHASE_STRIP = YES; 259 | ENABLE_NS_ASSERTIONS = NO; 260 | GCC_C_LANGUAGE_STANDARD = gnu99; 261 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 262 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 263 | GCC_WARN_UNDECLARED_SELECTOR = YES; 264 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 265 | GCC_WARN_UNUSED_FUNCTION = YES; 266 | GCC_WARN_UNUSED_VARIABLE = YES; 267 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 268 | SDKROOT = iphoneos; 269 | TARGETED_DEVICE_FAMILY = "1,2"; 270 | VALIDATE_PRODUCT = YES; 271 | }; 272 | name = Release; 273 | }; 274 | 5A3769D11926AAF20053B3A5 /* Debug */ = { 275 | isa = XCBuildConfiguration; 276 | buildSettings = { 277 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 278 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 279 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 280 | GCC_PREFIX_HEADER = "WMSOnMapKit/WMSOnMapKit-Prefix.pch"; 281 | INFOPLIST_FILE = "WMSOnMapKit/WMSOnMapKit-Info.plist"; 282 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 283 | PRODUCT_NAME = "$(TARGET_NAME)"; 284 | WRAPPER_EXTENSION = app; 285 | }; 286 | name = Debug; 287 | }; 288 | 5A3769D21926AAF20053B3A5 /* Release */ = { 289 | isa = XCBuildConfiguration; 290 | buildSettings = { 291 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 292 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 293 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 294 | GCC_PREFIX_HEADER = "WMSOnMapKit/WMSOnMapKit-Prefix.pch"; 295 | INFOPLIST_FILE = "WMSOnMapKit/WMSOnMapKit-Info.plist"; 296 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 297 | PRODUCT_NAME = "$(TARGET_NAME)"; 298 | WRAPPER_EXTENSION = app; 299 | }; 300 | name = Release; 301 | }; 302 | /* End XCBuildConfiguration section */ 303 | 304 | /* Begin XCConfigurationList section */ 305 | 5A37699F1926AAF20053B3A5 /* Build configuration list for PBXProject "WMSOnMapKit" */ = { 306 | isa = XCConfigurationList; 307 | buildConfigurations = ( 308 | 5A3769CE1926AAF20053B3A5 /* Debug */, 309 | 5A3769CF1926AAF20053B3A5 /* Release */, 310 | ); 311 | defaultConfigurationIsVisible = 0; 312 | defaultConfigurationName = Release; 313 | }; 314 | 5A3769D01926AAF20053B3A5 /* Build configuration list for PBXNativeTarget "WMSOnMapKit" */ = { 315 | isa = XCConfigurationList; 316 | buildConfigurations = ( 317 | 5A3769D11926AAF20053B3A5 /* Debug */, 318 | 5A3769D21926AAF20053B3A5 /* Release */, 319 | ); 320 | defaultConfigurationIsVisible = 0; 321 | defaultConfigurationName = Release; 322 | }; 323 | /* End XCConfigurationList section */ 324 | }; 325 | rootObject = 5A37699C1926AAF20053B3A5 /* Project object */; 326 | } 327 | -------------------------------------------------------------------------------- /WMSOnMapKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WMSOnMapKit.xcodeproj/project.xcworkspace/xcshareddata/WMSOnMapKit.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 7C892011-610A-4D73-8B7B-AE71D97B4A9B 9 | IDESourceControlProjectName 10 | WMSOnMapKit 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 799954749969AC384399D3AE8CE1CAAE3CFE0C91 14 | https://github.com/Sumbera/WMSOnMapKit-iOS7.git 15 | 16 | IDESourceControlProjectPath 17 | WMSOnMapKit.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 799954749969AC384399D3AE8CE1CAAE3CFE0C91 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/Sumbera/WMSOnMapKit-iOS7.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 799954749969AC384399D3AE8CE1CAAE3CFE0C91 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 799954749969AC384399D3AE8CE1CAAE3CFE0C91 36 | IDESourceControlWCCName 37 | WMSOnMapKit 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /WMSOnMapKit.xcodeproj/project.xcworkspace/xcuserdata/ssumbera.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sumbera/WMSOnMapKit-iOS7/91df776a8a1b8bf206122e69251a9debafd01595/WMSOnMapKit.xcodeproj/project.xcworkspace/xcuserdata/ssumbera.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WMSOnMapKit.xcodeproj/project.xcworkspace/xcuserdata/ssumbera.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /WMSOnMapKit.xcodeproj/xcuserdata/ssumbera.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 40 | 52 | 53 | 54 | 56 | 68 | 69 | 70 | 72 | 84 | 85 | 86 | 88 | 100 | 101 | 102 | 104 | 116 | 117 | 118 | 120 | 132 | 133 | 134 | 136 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /WMSOnMapKit.xcodeproj/xcuserdata/ssumbera.xcuserdatad/xcschemes/WMSOnMapKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /WMSOnMapKit.xcodeproj/xcuserdata/ssumbera.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WMSOnMapKit.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 5A3769A31926AAF20053B3A5 16 | 17 | primary 18 | 19 | 20 | 5A3769BE1926AAF20053B3A5 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /WMSOnMapKit/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WMSOnMapKit 4 | // 5 | // Created by Stanislav Sumbera on 16/05/14. 6 | // Copyright (c) 2014 sumbera. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WMSOnMapKit/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WMSOnMapKit 4 | // 5 | // Created by Stanislav Sumbera on 16/05/14. 6 | // Copyright (c) 2014 sumbera. All rights reserved. 7 | // 8 | #import 9 | #import "AppDelegate.h" 10 | #import "MapViewController.h" 11 | #import "WMSTileOverlay.h" 12 | 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 19 | MapViewController * mapViewController = [[MapViewController alloc] init]; 20 | UINavigationController *mainNavCtrl = [[UINavigationController alloc]initWithRootViewController:mapViewController]; 21 | 22 | self.window.rootViewController = mainNavCtrl; 23 | 24 | [self.window makeKeyAndVisible]; 25 | 26 | NSString * url = @"http://services.cuzk.cz/wms/wms.asp?&LAYERS=KN&REQUEST=GetMap&SERVICE=WMS&VERSION=1.3.0&FORMAT=image/png&TRANSPARENT=TRUE&STYLES=&CRS=EPSG:900913&WIDTH=256&HEIGHT=256"; 27 | [ mapViewController.mkMapView addOverlay:[[WMSTileOverlay alloc] initWithUrl:url UseMercator:YES]]; 28 | 29 | 30 | return YES; 31 | } 32 | 33 | - (void)applicationWillResignActive:(UIApplication *)application 34 | { 35 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 36 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 37 | } 38 | 39 | - (void)applicationDidEnterBackground:(UIApplication *)application 40 | { 41 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 42 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 43 | } 44 | 45 | - (void)applicationWillEnterForeground:(UIApplication *)application 46 | { 47 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 48 | } 49 | 50 | - (void)applicationDidBecomeActive:(UIApplication *)application 51 | { 52 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 53 | } 54 | 55 | - (void)applicationWillTerminate:(UIApplication *)application 56 | { 57 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /WMSOnMapKit/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /WMSOnMapKit/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /WMSOnMapKit/MapViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MapViewController.h 3 | // MapView 4 | // 5 | // Created by Stanislav Sumbera on 6/20/12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @interface MapViewController : UIViewController 12 | 13 | @property(nonatomic, readonly, weak) MKMapView *mkMapView; 14 | 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WMSOnMapKit/MapViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MapViewController.m 3 | // MapView 4 | // 5 | // Created by Stanislav Sumbera on 6/20/12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "MapViewController.h" 10 | 11 | 12 | @implementation MapViewController 13 | 14 | //---------------------------------------------------------------------------- 15 | - (void)didReceiveMemoryWarning 16 | { 17 | // Releases the view if it doesn't have a superview. 18 | [super didReceiveMemoryWarning]; 19 | 20 | // Release any cached data, images, etc that aren't in use. 21 | } 22 | 23 | #pragma mark - View lifecycle 24 | 25 | //--------------------------------------------------- 26 | - (void)dealloc { 27 | self.mkMapView.delegate = nil; 28 | 29 | } 30 | //---------------------------------------------------------------------------- 31 | // Implement loadView to create a view hierarchy programmatically, without using a nib. 32 | - (void)loadView 33 | { 34 | CGRect initFrame = CGRectMake(0, 0, 380, 460); 35 | MKMapView *mkMapView = [[MKMapView alloc] initWithFrame:initFrame]; 36 | self.view = mkMapView; 37 | 38 | mkMapView.mapType = MKMapTypeStandard; 39 | mkMapView.pitchEnabled = YES; 40 | mkMapView.delegate = self; 41 | 42 | MKMapCamera *camera1 = [MKMapCamera 43 | cameraLookingAtCenterCoordinate: (CLLocationCoordinate2D){ .latitude = 50.070, .longitude = 14.416} 44 | fromEyeCoordinate: (CLLocationCoordinate2D){ .latitude = 50.069, .longitude = 14.417} 45 | eyeAltitude:300.0]; 46 | 47 | [mkMapView setCamera:camera1 animated:YES]; 48 | 49 | } 50 | 51 | 52 | /* 53 | // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 54 | - (void)viewDidLoad 55 | { 56 | [super viewDidLoad]; 57 | } 58 | */ 59 | 60 | //---------------------------------------------------------------------------- 61 | - (void)viewDidUnload 62 | { 63 | [super viewDidUnload]; 64 | // Release any retained subviews of the main view. 65 | // e.g. self.myOutlet = nil; 66 | } 67 | 68 | //--------------------------------------------------------- 69 | - (void)viewWillAppear:(BOOL)animated 70 | { 71 | self.navigationController.navigationBarHidden = YES; 72 | [super viewWillAppear:animated]; 73 | } 74 | //--------------------------------------------------------- 75 | - (void)viewDidAppear:(BOOL)animated 76 | { 77 | [super viewDidAppear:animated]; 78 | } 79 | //--------------------------------------------------------- 80 | - (void)viewWillDisappear:(BOOL)animated 81 | { 82 | [super viewWillDisappear:animated]; 83 | } 84 | //--------------------------------------------------------- 85 | - (void)viewDidDisappear:(BOOL)animated 86 | { 87 | [super viewDidDisappear:animated]; 88 | } 89 | 90 | //---------------------------------------------------------------------------- 91 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 92 | { 93 | // Return YES for supported orientations 94 | return YES; 95 | } 96 | 97 | //---------------------------------------------------------------------------- 98 | -(MKMapView*) mkMapView { 99 | return (MKMapView *) self.view; 100 | 101 | } 102 | 103 | #pragma mark -- MKMapView delegate 104 | //---------------------------------------------------------------------------- 105 | - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id )overlay { 106 | return [[MKTileOverlayRenderer alloc] initWithTileOverlay:(MKTileOverlay *)overlay]; 107 | 108 | } 109 | 110 | 111 | @end 112 | -------------------------------------------------------------------------------- /WMSOnMapKit/MapViewUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // MapViewUtils.h 3 | // MapView 4 | // 5 | // Created by Stanislav Sumbera on 6/20/12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | #import 9 | #import 10 | #import 11 | 12 | #define TILE_SIZE 256 13 | #define MINIMUM_ZOOM 0 14 | #define MAXIMUM_ZOOM 25 15 | 16 | #define TILE_CACHE @"TILE_CACHE" 17 | #define TILE_CACHE_TIME_LIMIT 7200 // 2 hours 18 | 19 | 20 | //------------------------------------------------------------ 21 | NS_INLINE NSUInteger TileZ(MKZoomScale zoomScale){ 22 | double numTilesAt1_0 = MKMapSizeWorld.width / TILE_SIZE; // 256 is a tile size 23 | NSInteger zoomLevelAt1_0 = log2(numTilesAt1_0); // add 1 because the convention skips a virtual level with 1 tile. 24 | NSInteger zoomLevel = MAX(0, zoomLevelAt1_0 + floor(log2f(zoomScale) + 0.5)); 25 | return zoomLevel; 26 | } 27 | 28 | 29 | //---------------------------------------------------------------------------- 30 | NS_INLINE double xOfColumn(NSInteger column,NSInteger zoom){ 31 | 32 | double x = column; 33 | double z = zoom; 34 | 35 | return x / pow(2.0, z) * 360.0 - 180; 36 | } 37 | //---------------------------------------------------------------------------- 38 | 39 | NS_INLINE double yOfRow(NSInteger row,NSInteger zoom){ 40 | 41 | double y = row; 42 | double z = zoom; 43 | 44 | double n = M_PI - 2.0 * M_PI * y / pow(2.0, z); 45 | return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))); 46 | } 47 | 48 | 49 | 50 | //------------------------------------------------------------------------------------- 51 | NS_INLINE double MercatorXofLongitude(double lon){ 52 | return lon * 20037508.34 / 180; 53 | } 54 | 55 | //------------------------------------------------------------ 56 | NS_INLINE double MercatorYofLatitude(double lat){ 57 | double y = log(tan((90 + lat) * M_PI / 360)) / (M_PI / 180); 58 | y = y * 20037508.34 / 180; 59 | 60 | return y; 61 | } 62 | 63 | //-------------------------------------------------------------------------------------------------- 64 | NS_INLINE NSString* md5Hash (NSString* stringData) { 65 | NSData *data = [stringData dataUsingEncoding:NSUTF8StringEncoding]; 66 | unsigned char result[CC_MD5_DIGEST_LENGTH]; 67 | CC_MD5([data bytes], (unsigned int)[data length], result); 68 | 69 | return [NSString stringWithFormat: 70 | @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 71 | result[0], result[1], result[2], result[3], result[4], result[5], result[6], result[7], 72 | result[8], result[9], result[10], result[11], result[12], result[13], result[14], result[15] 73 | ]; 74 | } 75 | 76 | //-------------------------------------------------------------------------------------------------- 77 | NS_INLINE BOOL createPathIfNecessary (NSString* path) { 78 | BOOL succeeded = YES; 79 | 80 | NSFileManager* fm = [NSFileManager defaultManager]; 81 | if (![fm fileExistsAtPath:path]) { 82 | succeeded = [fm createDirectoryAtPath: path 83 | withIntermediateDirectories: YES 84 | attributes: nil 85 | error: nil]; 86 | } 87 | 88 | return succeeded; 89 | } 90 | 91 | //-------------------------------------------------------------------------------------------------- 92 | NS_INLINE NSString* cachePathWithName(NSString* name) { 93 | NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 94 | NSString* cachesPath = [paths objectAtIndex:0]; 95 | NSString* cachePath = [cachesPath stringByAppendingPathComponent:name]; 96 | 97 | createPathIfNecessary(cachesPath); 98 | createPathIfNecessary(cachePath); 99 | 100 | return cachePath; 101 | } 102 | 103 | 104 | //-------------------------------------------------------------------------------------------------- 105 | 106 | NS_INLINE NSString* getFilePathForURL( NSString* url,NSString* folderName){ 107 | return [cachePathWithName(folderName) stringByAppendingPathComponent:md5Hash(url)]; 108 | } 109 | 110 | 111 | //------------------------------------------------------------ 112 | NS_INLINE void cacheUrlToLocalFolder(NSString* url,NSData* data, NSString* folderName){ 113 | NSString *localFilePath = getFilePathForURL(url,folderName); 114 | [data writeToFile: localFilePath atomically:YES]; 115 | 116 | } 117 | 118 | 119 | -------------------------------------------------------------------------------- /WMSOnMapKit/WMSOnMapKit-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.sumbera.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | NSAppTransportSecurity 45 | 46 | NSAllowsArbitraryLoads 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /WMSOnMapKit/WMSOnMapKit-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /WMSOnMapKit/WMSTileOverlay.h: -------------------------------------------------------------------------------- 1 | // 2 | // WMSTileOverlay.h 3 | // WMSOnMapKit 4 | // 5 | // Created by Stanislav Sumbera on 17/05/14. 6 | // Copyright (c) 2014 sumbera. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WMSTileOverlay : MKTileOverlay 12 | 13 | @property (nonatomic, strong) NSString * url; 14 | @property (nonatomic, assign) BOOL useMercator; // -- if use 900913 mercator projection or WGS84 15 | 16 | - (id)initWithUrl:(NSString*)urlArg UseMercator: (BOOL) useMercatorArg; 17 | @end 18 | -------------------------------------------------------------------------------- /WMSOnMapKit/WMSTileOverlay.m: -------------------------------------------------------------------------------- 1 | // 2 | // WMSTileOverlay.m 3 | // WMSOnMapKit 4 | // 5 | // Created by Stanislav Sumbera on 17/05/14. 6 | // Copyright (c) 2014 sumbera. All rights reserved. 7 | // 8 | 9 | #import "WMSTileOverlay.h" 10 | #import "MapViewUtils.h" 11 | 12 | @implementation WMSTileOverlay 13 | 14 | 15 | //------------------------------------------------------------ 16 | - (id)initWithUrl:(NSString*)urlArg UseMercator: (BOOL) useMercatorArg 17 | { 18 | 19 | if ((self = [self init])) { 20 | self.url = urlArg; 21 | self.useMercator = useMercatorArg; 22 | } 23 | return self; 24 | } 25 | 26 | //------------------------------------------------------------ 27 | - (NSURL *)URLForTilePath:(MKTileOverlayPath)path{ 28 | // BBOX in WGS84 29 | double left = xOfColumn(path.x,path.z); //minX 30 | double right = xOfColumn(path.x+1,path.z); //maxX 31 | double bottom = yOfRow(path.y+1,path.z); //minY 32 | double top = yOfRow(path.y,path.z); //maxY 33 | 34 | // BBOX in mercator 35 | if (self.useMercator){ 36 | left = MercatorXofLongitude(left); //minX 37 | right = MercatorXofLongitude(right); //maxX 38 | bottom = MercatorYofLatitude(bottom); //minY 39 | top = MercatorYofLatitude(top); //maxY 40 | } 41 | NSString * resolvedUrl = [NSString stringWithFormat:@"%@&BBOX=%f,%f,%f,%f",self.url,left,bottom,right,top]; 42 | 43 | NSLog(@"Url tile overlay %@", resolvedUrl); 44 | return [NSURL URLWithString:resolvedUrl]; 45 | 46 | } 47 | 48 | //------------------------------------------------------------ 49 | - (NSDate *)creationDateForFile:(NSString *)fileName 50 | { 51 | NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:fileName error:nil]; 52 | NSDate *fileTimestamp = [fileAttributes fileCreationDate]; 53 | 54 | return fileTimestamp; 55 | } 56 | 57 | //------------------------------------------------------------ 58 | - (void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error)) result{ 59 | 60 | NSURL *url = [self URLForTilePath: path]; 61 | NSString *filePath = getFilePathForURL([url absoluteString],TILE_CACHE); 62 | // -- check if tile is cached and if it has reached the tile cache time limit 63 | if ([[NSFileManager defaultManager] fileExistsAtPath: filePath]){ 64 | 65 | NSDate *fileTimestamp = [self creationDateForFile:filePath]; 66 | int ageOfFile = (int) [[NSDate date] timeIntervalSinceDate:fileTimestamp]; 67 | 68 | if (ageOfFile <= TILE_CACHE_TIME_LIMIT){ 69 | NSData *tileData = [NSData dataWithContentsOfFile:filePath]; 70 | result (tileData, nil); 71 | return; 72 | } 73 | } 74 | 75 | // -- download 76 | NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] 77 | delegate:nil 78 | delegateQueue:[NSOperationQueue mainQueue]]; 79 | 80 | NSURLSessionDataTask *sessionTask = [session dataTaskWithURL:url 81 | completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){ 82 | if (error) { 83 | NSLog(@"Error downloading tile ! \n"); 84 | result(nil, error); 85 | } else { 86 | [data writeToFile: filePath atomically:YES]; 87 | result (data, nil); 88 | } 89 | }]; 90 | 91 | [sessionTask resume]; 92 | } 93 | 94 | @end 95 | -------------------------------------------------------------------------------- /WMSOnMapKit/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /WMSOnMapKit/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WMSOnMapKit 4 | // 5 | // Created by Stanislav Sumbera on 16/05/14. 6 | // Copyright (c) 2014 sumbera. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | --------------------------------------------------------------------------------