23
23
import mahomaps .api .YmapsApiBase ;
24
24
import mahomaps .overlays .TileCacheForbiddenOverlay ;
25
25
import mahomaps .overlays .TileDownloadForbiddenOverlay ;
26
+ import tube42 .lib .imagelib .ImageUtils ;
26
27
import mahomaps .overlays .CacheFailedOverlay ;
27
28
28
29
public class TilesProvider implements Runnable {
@@ -77,6 +78,10 @@ public static final String[] GetLayerNames() {
77
78
return s ;
78
79
}
79
80
81
+ public String GetLocalPath () {
82
+ return localPath ;
83
+ }
84
+
80
85
public TilesProvider (String lang ) {
81
86
if (lang == null )
82
87
throw new NullPointerException ("Language must be non-null!" );
@@ -184,18 +189,40 @@ public void RunCache() {
184
189
}
185
190
}
186
191
187
- Image img = null ;
188
- if (Settings .cacheMode == Settings .CACHE_FS && localPath != null ) {
189
- img = tryLoadFromFS (tc );
190
- } else if (Settings .cacheMode == Settings .CACHE_RMS ) {
191
- img = tryLoadFromRMS (tc );
192
+ Image img = tryLoad (tc );
193
+ boolean tryDownloadAnyway = false ;
194
+
195
+ // if tile is not cached...
196
+ if (img == null ) {
197
+ // and cache lookup actually was attempted...
198
+ if (Settings .cacheMode != Settings .CACHE_DISABLED ) {
199
+ // but we can't download it
200
+ if (!Settings .allowDownload ) {
201
+ // let's try lower zooms and upscale them.
202
+ img = tryLoadFallback (tc );
203
+ }
204
+ // or scaling explicitly allowed before downloading
205
+ else if (Settings .readCachedBeforeDownloading ) {
206
+ // let's try lower zooms and upscale them.
207
+ img = tryLoadFallback (tc );
208
+ // but still attempt to download
209
+ tryDownloadAnyway = true ;
210
+ }
211
+ }
192
212
}
193
213
194
214
synchronized (tc ) {
195
215
if (img != null ) {
196
216
tc .img = img ;
197
- tc .state = TileCache .STATE_READY ;
198
- MahoMapsApp .GetCanvas ().requestRepaint ();
217
+
218
+ // readCachedBeforeDownloading is still require server lookup
219
+ if (tryDownloadAnyway ) {
220
+ tc .state = TileCache .STATE_SERVER_PENDING ;
221
+ downloadGate .Reset ();
222
+ } else {
223
+ tc .state = TileCache .STATE_READY ;
224
+ MahoMapsApp .GetCanvas ().requestRepaint ();
225
+ }
199
226
} else if (Settings .allowDownload ) {
200
227
tc .state = TileCache .STATE_SERVER_PENDING ;
201
228
downloadGate .Reset ();
@@ -211,6 +238,50 @@ public void RunCache() {
211
238
}
212
239
}
213
240
241
+ private final Image tryLoad (TileId id ) {
242
+ if (Settings .cacheMode == Settings .CACHE_FS && localPath != null ) {
243
+ return tryLoadFromFS (id );
244
+ } else if (Settings .cacheMode == Settings .CACHE_RMS ) {
245
+ return tryLoadFromRMS (id );
246
+ }
247
+ return null ;
248
+ }
249
+
250
+ private final Image tryLoadFallback (TileId id ) {
251
+ final int map = id .map ;
252
+ int zoom = id .zoom ;
253
+ int downscale = 1 ; // how small is required tile comparing to loaded one
254
+ int x = id .x ;
255
+ int y = id .y ;
256
+ int xoff = 0 ; // in tile sizes
257
+ int yoff = 0 ;
258
+ while (true ) {
259
+ zoom -= 1 ;
260
+ if (zoom < 0 || downscale >= 64 )
261
+ return null ;
262
+ if (x % 2 == 1 )
263
+ xoff += downscale ;
264
+ if (y % 2 == 1 )
265
+ yoff += downscale ;
266
+ // at downscale of 2 above ops require 1, at 4 - 2 and so on
267
+ downscale *= 2 ;
268
+ x /= 2 ;
269
+ y /= 2 ;
270
+ Image raw = tryLoad (new TileId (x , y , zoom , map ));
271
+ if (raw != null ) {
272
+ int size = (256 / downscale ); // of tile
273
+ // System.out.println("downscale: " + downscale + ", size: " + size);
274
+ // System.out.println("x: " + xoff + ", y: " + yoff);
275
+ int xoffp = xoff * size ; // in pixels
276
+ int yoffp = yoff * size ;
277
+ Image cropped = ImageUtils .crop (raw , xoffp , yoffp , xoffp + size , yoffp + size );
278
+ raw = null ; // to free heap
279
+ return ImageUtils .resize (cropped , 256 , 256 , true , false );
280
+ }
281
+ }
282
+
283
+ }
284
+
214
285
public void RunNetwork () {
215
286
try {
216
287
// цикл обработки
@@ -284,6 +355,20 @@ else if (l != s)
284
355
}
285
356
286
357
Image img = Settings .allowDownload ? download (tc ) : null ;
358
+ boolean fallbackUsed = false ;
359
+
360
+ // if nothing loaded
361
+ if (img == null ) {
362
+ // if the cache available...
363
+ if (Settings .cacheMode != Settings .CACHE_DISABLED ) {
364
+ // let's try lower zooms and upscale them.
365
+ // If download is forbidden, this happened in cache thread and this path won't
366
+ // run at all.
367
+ img = tryLoadFallback (tc );
368
+ if (img != null )
369
+ fallbackUsed = true ;
370
+ }
371
+ }
287
372
288
373
boolean waitAfterError = false ;
289
374
@@ -297,7 +382,13 @@ else if (l != s)
297
382
}
298
383
} else {
299
384
tc .img = img ;
300
- tc .state = TileCache .STATE_READY ;
385
+ if (fallbackUsed ) {
386
+ // image is present, but it's bad. We still want to download a proper one.
387
+ tc .state = TileCache .STATE_ERROR ;
388
+ waitAfterError = true ;
389
+ } else {
390
+ tc .state = TileCache .STATE_READY ;
391
+ }
301
392
MahoMapsApp .GetCanvas ().requestRepaint ();
302
393
}
303
394
}
@@ -306,8 +397,10 @@ else if (l != s)
306
397
Thread .sleep (4000 );
307
398
}
308
399
309
- if (idleCount != cache .size () || queueChanged )
400
+ if (idleCount != cache .size () || queueChanged ) {
401
+ Thread .yield ();
310
402
continue ;
403
+ }
311
404
downloadGate .Pass ();
312
405
}
313
406
} catch (InterruptedException e ) {
@@ -389,7 +482,6 @@ private Image download(TileId id) throws InterruptedException {
389
482
} catch (RuntimeException e1 ) {
390
483
}
391
484
} catch (Exception e ) {
392
- e .printStackTrace ();
393
485
} catch (OutOfMemoryError e ) {
394
486
} finally {
395
487
if (hc != null ) {
@@ -586,8 +678,7 @@ public TileCache getTile(TileId tileId) {
586
678
}
587
679
588
680
private String getUrl (TileId tileId ) {
589
- String url = tilesUrls [tileId .map ] + lang + "&x=" + tileId .x + "&y=" + tileId .y
590
- + "&z=" + tileId .zoom ;
681
+ String url = tilesUrls [tileId .map ] + lang + "&x=" + tileId .x + "&y=" + tileId .y + "&z=" + tileId .zoom ;
591
682
if (Settings .proxyTiles && url .startsWith ("https" )) {
592
683
return Settings .proxyServer + YmapsApiBase .EncodeUrl (url );
593
684
}
0 commit comments