1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
/*
* MaplyQuadLoader.h
*
* Created by Steve Gifford on 2/12/19.
* Copyright 2012-2022 Saildrone Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#import <Foundation/Foundation.h>
#import <WhirlyGlobeMaplyComponent/MaplyControllerLayer.h>
#import <WhirlyGlobeMaplyComponent/MaplyCoordinateSystem.h>
#import <WhirlyGlobeMaplyComponent/MaplyTileSourceNew.h>
#import <WhirlyGlobeMaplyComponent/MaplyRenderController.h>
#import <WhirlyGlobeMaplyComponent/MaplyQuadSampler.h>
#import <WhirlyGlobeMaplyComponent/MaplyRemoteTileFetcher.h>
@class MaplyQuadLoaderBase;
/**
Passed in to and returned by the Loader Interpreter.
We pass this into the interpreter with the unparsed data. It parses it and passes that
data back, possibly with an error.
*/
@interface MaplyLoaderReturn : NSObject
/// Initialize with the loader this will be attached to
- (id __nonnull)initWithLoader:(MaplyQuadLoaderBase * __nonnull)loader;
/// Tile this is the data for
@property (nonatomic) MaplyTileID tileID;
/// If set, the frame. -1 by default
@property (nonatomic,readonly) int frame;
/// Data returned from a tile request. Unparsed.
/// You can add multiple of these, but the interpreter should be expecting that
- (void)addTileData:(id __nonnull) tileData;
/// Return the tile NSData objects as an array
- (NSArray<id> * __nonnull)getTileData;
/// Return the first data object. You're probably only expecting the one.
- (id __nullable)getFirstData;
/// Set when the QuadLoader cancels a tile. You can check this in your dataForTile:
- (bool)isCancelled;
/// If this is set, the tile failed to parse
/// You can set it and the system will deal with the results
@property (nonatomic,strong) NSError * __nullable error;
@end
/**
Loader Interpreter converts raw data into images and objects.
Converts data returned from a remote source (or cache) into images and/or
MaplyComponentObjects that have already been added to the view (disabled).
*/
@protocol MaplyLoaderInterpreter<NSObject>
/** Set when the loader first starts up.
If you need to tweak loader settings, do it here.
*/
- (void)setLoader:(MaplyQuadLoaderBase * __nonnull)loader;
/**
Parse the data coming back from a remote request and turn it into something we can use.
Convert the NSData passed in to image and component objects (e.g. add stuff to the view controller).
Everything added should be disabled to start.
*/
- (void)dataForTile:(MaplyLoaderReturn * __nonnull)loadReturn loader:(MaplyQuadLoaderBase * __nonnull)loader;
/**
Notification that the tile was unloaded by the system. If you're tracking your own resources, you may need this.
*/
- (void)tileUnloaded:(MaplyTileID)tileID;
@end
/** Base class for the quad loaders.
The image, frame, and data paging loaders all share much of the same functionality.
*/
@interface MaplyQuadLoaderBase : NSObject
/**
Control how tiles are indexed, either from the lower left or the upper left.
If set, we'll use the OSM approach (also Google Maps) to y indexing. That's that default and it's normally what you're run into.
Strictly speaking, TMS addressing (the standard) is flipped the other way. So if your tile source looks odd, try setting this to false.
Default value is true.
*/
@property (nonatomic) bool flipY;
/// Set for a lot of debugging output
@property (nonatomic,assign) bool debugMode;
/// View controller this is attached to.
/// Useful for delegate calls that might not be tracking that.
@property (nonatomic,readonly,weak,nullable) NSObject<MaplyRenderControllerProtocol> *viewC;
/// If set, we'll call the interpreter on this queue
@property (nonatomic,nullable,strong) dispatch_queue_t queue;
/// Number of simulataneous tiles we'll parse
/// This is really just a limit on the number of tiles we'lll parse concurrently to keep memory use under control
@property (nonatomic) unsigned int numSimultaneousTiles;
// True if the loader is not currently loading anything
- (bool)isLoading;
/**
Calculate the bounding box for a single tile in geographic.
This is a utility method for calculating the extents of a given tile in geographic (e.g. lon/lat).
@param tileID The ID for the tile we're interested in.
@return The lower left and upper right corner of the tile in geographic coordinates. Returns kMaplyNullBoundingBox in case of error
*/
- (MaplyBoundingBox)geoBoundsForTile:(MaplyTileID)tileID;
/**
Calculate the bounding box for a single tile in geographic using doubles.
This is a utility method for calculating the extents of a given tile in geographic (e.g. lon/lat).
@param tileID The ID for the tile we're interested in.
@return The lower left and upper right corner of the tile in geographic coordinates. Returns kMaplyNullBoundingBoxD in case of error
*/
- (MaplyBoundingBoxD)geoBoundsForTileD:(MaplyTileID)tileID;
/**
Calculate the bounding box for a single tile in the local coordinate system.
This utility method calculates the bounding box for a tile in the coordinate system used for the layer.
@param tileID The ID for the tile we're interested in.
@return The lower left and upper right corner of the tile in local coordinates.
*/
- (MaplyBoundingBox)boundsForTile:(MaplyTileID)tileID;
/**
Calculate the bounding box for a single tile in the local coordinate system using doubles.
This utility method calculates the bounding box for a tile in the coordinate system used for the layer.
@param tileID The ID for the tile we're interested in.
@return The lower left and upper right corner of the tile in geographic coordinates.
*/
- (MaplyBoundingBoxD)boundsForTileD:(MaplyTileID)tileID;
/**
Return the center of the tile in display coordinates.
@param tileID The ID for the tile we're interested in.
@return Return the center in display space for the given tile.
*/
- (MaplyCoordinate3d)displayCenterForTile:(MaplyTileID)tileID;
/**
Each sampling layer allocates a slot to keep track of continuous zoom levels.
Those are passed all the way through to the individual shaders.
*/
- (int)getZoomSlot;
/// Use a specific tile fetcher rather than the one shared by everyone else
- (void)setTileFetcher:(NSObject<MaplyTileFetcher> * __nonnull)tileFetcher;
/// Set the interpreter for the data coming back. If you're just getting images, don't set this.
- (void)setInterpreter:(NSObject<MaplyLoaderInterpreter> * __nonnull)interp;
/// Return the current interpreter
- (NSObject<MaplyLoaderInterpreter> * __nullable)getInterpreter;
/**
Change the interpreter and reload all the data.
<br>
You can change the tile interpreter being used to build objects and images.
This will then force a reload of the tiles (hopefully from cache) and the
visuals will change as everything comes in.
*/
- (void)changeInterpreter:(NSObject<MaplyLoaderInterpreter> *__nonnull)interp;
/**
Force a reload of the data.
<br>
All the current loads will be cancelled, any in flight will be ignored
and the loader will ask for a whole new set of data.
*/
- (void)reload;
/**
Force a reload of the tiles overlapping a bounding box.
<br>
All the current loads will be cancelled, any in flight will be ignored
and the loader will ask for a whole new set of data.
*/
- (void)reloadArea:(MaplyBoundingBox)bounds;
/**
Force a reload of the tiles overlapping a set of bounding boxes
<br>
All the current loads will be cancelled, any in flight will be ignored
and the loader will ask for a whole new set of data.
*/
- (void)reloadAreas:(NSArray<NSValue*>* __nullable)bounds;
/** Turn off the loader and shut things down.
This unregisters us with the sampling layer and shuts down the various objects we created.
*/
- (void)shutdown;
@end
|