moagrius / TileView

TileView is a subclass of android.view.ViewGroup that asynchronously displays, pans and zooms tile-based images. Plugins are available for features like markers, hotspots, and path drawing.
MIT License
1.46k stars 337 forks source link

Tiles not properly laid out when Scale < 1 with remote tiles #525

Open LRP-sgravel opened 5 years ago

LRP-sgravel commented 5 years ago

I'm trying to use your TileView to display a tiled large document. I'm having a problem when the Scale goes under the value of 1. Tiles are not properly laid out, the engine tries to display extra columns (black tiles on the right) and I also get a lot of bitmap decoding errors when going back to a scale of 1 or larger until it all settles down by panning.

Scale = 1 image

Scale = ~0.37 image

LRP-sgravel commented 5 years ago

I'm getting a similar result in the Http demo. Tiles do not align (and load extremely slowly)

image

moagrius commented 5 years ago

Can you post your project somewhere I can view it?

LRP-sgravel commented 5 years ago

Unfortunately, no. First, it is a Xamarin project with bindings I created. Second, it's an extremely large customer's project that includes iOS, WPF and a web back and front end...

moagrius commented 5 years ago

Have you tried previous stable, 2.7 something?

LRP-sgravel commented 5 years ago

Not yet, let me try to add a demo activity that uses our tiles URL and see how it behaves.

LRP-sgravel commented 5 years ago

Alright, so I'm getting the same result in teh demo using this activity :


import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.annotation.Nullable;

import com.moagrius.tileview.Tile;
import com.moagrius.tileview.TileView;
import com.moagrius.tileview.io.StreamProviderHttp;
import com.moagrius.tileview.plugins.LowFidelityBackgroundPlugin;

public class TileViewDemoSmartUse extends TileViewDemoActivity implements TileView.TileDecodeErrorListener {

  private TileView mTileView;

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_demos_tileview);
    frameToCenterOnReady();
    mTileView = findViewById(R.id.tileview);
    mTileView.setTileDecodeErrorListener(this);
    mTileView.setMinimumScale(0.25f);
    mTileView.setMaximumScale(2.5f);
    new TileView.Builder(mTileView)
        .setSize(3456, 2592)
        .setStreamProvider(new StreamProviderHttp())
        .setDiskCachePolicy(TileView.DiskCachePolicy.CACHE_ALL)
        .defineZoomLevel("https://smartusev5canadaeast.blob.core.windows.net/content-a6c5a7a4-902f-4f73-bf9a-b53044f6e5e1/3d2481d0-1b84-43d7-865e-1d732770c4cd/200/tile_001_%1$03d_%2$03d.png?sv=2017-07-29&sr=c&sig=BUOF9sn%%2BeCQNLlRkg%%2FghdntzwMvP3hjQ1CrMBccT%%2FZ8%%3D&se=2019-06-08T15:06:01Z&sp=r")
        .build();
  }

  @Override
  public void onTileDecodeError(Tile tile, Exception e) {
    mTileView.retryTileDecode(tile);
  }

}
moagrius commented 5 years ago

I'll give it a shot tonight or tomorrow

moagrius commented 5 years ago

I ran it briefly when a I had a down minute at work. Since you're URLs are HTTPS (rather than HTTP), you probably want tochange line 16 of StreamProviderHttps to HttpURLConnection connection = (HttpURLConnection) url.openConnection();

That gave me decent results, but with the latency of a network with our aggressive caching, network is a weak spot right now.

I'd suggest either:

  1. User the stable version 2 build. it's here as https://github.com/moagrius/TileView/tree/version-2.7.7 (which is actually a typo, it should be 2.2.7), as implement com.qozix:tileview:2.2.7, or i think you can grab it all the way up to patch 9 with the old namespace: implement com.qozix:tileview:2.2.9. The API is slightly different but that lived in the wild for several years and is pretty mature. This version is not as optimized for a single tile tile - if you have multiple scales (say 0.5, and 0.25) you should probably create those sets and pass them to the TileView.

or...

  1. if you're always using the same set of tiles, i'd download them all upfront and keep them on disk, and use internal or external stream providers, or even a custom one from the cache dir if you don't want them to persist between installs. It won't actually use any more space since you're using disk cache anyway. This will give you much faster and more reliable local read and decode.

I do plan on returning to the remote images bug (I believe there's still an open issue), but it's probably going to be a month before I can put serious time into this project again.

LMK what you decide, and good luck.

LRP-sgravel commented 5 years ago

Version 2.2.9 is even worse. I can't even get the document to properly layout at any zoom level. The tiles flash all over the place, panning and zooming swaps the tiles around. This library simply doesn't appear to work for our very simple scenario. Not sure how this is possible given the history of your library.

LRP-sgravel commented 5 years ago

image

Then I pan and look at the top, new tiles have loaded...

image

moagrius commented 5 years ago

Yeah that is weird. As I said, I'll take a look when I can, but I'm don't have time for any major upgrades (like refactoring remote images) to until probably sometime early next month.

I do know that the great majority of users use local tiles. Unless you've got a situation where that's not possible (infinite scroll, wrap-around scroll, etc) you're definitely better off to download them up front (or maybe on first launch) then read them from internal or external storage. Is that a possibility for you?

Otherwise, as mentioned, I'll try to find a fix for what you posted as soon as I get a minute.

Thanks for posting.

On Mon, Jun 10, 2019 at 8:14 AM Sylvain Gravel notifications@github.com wrote:

[image: image] https://user-images.githubusercontent.com/15251145/59197781-237c9800-8b60-11e9-9a79-078e5d1f0eee.png

Then I pan and look at the top, new tiles have loaded...

[image: image] https://user-images.githubusercontent.com/15251145/59197809-35f6d180-8b60-11e9-9b19-1b3ed5453f3b.png

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/moagrius/TileView/issues/525?email_source=notifications&email_token=AAFLHICOGSBAUCBMO7WWIWDPZZHVHA5CNFSM4HVYBOZKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODXJ26TI#issuecomment-500412237, or mute the thread https://github.com/notifications/unsubscribe-auth/AAFLHIFHCKLHBR66BXXCOZ3PZZHVHANCNFSM4HVYBOZA .

LRP-sgravel commented 5 years ago

I could try, I just don't see how it's related. Your engine doesn't know if the input stream / bitmap comes from the web or not and it lays out images seemingly randomly. Changing the location of the data doesn'T appear to have anything to do with the issue.

moagrius commented 5 years ago

I'm not saying that the issue is absolutely around the HTTP request, or specifically the long-lived nature of the HTTP request, but I can see now it might: we have bounded ThreadPool, and for long-running tasks (like fetching bitmap data on the wire, then decoding it), I can imagine it's possible to have a race condition as the Threads are recycled, if Thread 33 was trying to get the image at row 9, 9 then the user flung and that same thread gets recycled to fetch 1, 2, i could see it displaying the 9-9 in the place of 1-3.

Of course, that should NOT happen, if it's true that's a bug and a bug I thought I had already solved. That's on me to fix, and I'm very happy and even eager to get it fixed, but with all the demands on my time (like everyone), open source only gets about a week every couple of months.

I can say that locally rendered images are pretty much bulletproof. I can say with almost certainty that local images in 2.2.7 will never fail or draw in the wrong position. I hope to become that confident with version 4.x.x but it just doesn't have that level of maturity yet (remember that version 4 is pretty young, especially in terms of adpoption).

Finally, when I run your tiles in the demo (making similar changes to what you posted earlier in this thread), I do see some bad behavior, that I do not see in the demo itself, so when I do have time to review, I'll try to debug your sample first and eliminate all the easy fixes. Again, that's probably not until the first week of July.

Sorry for the hassle - if you have the time and inclination to do a deep dive, I'm very happy to merge quality pull requests that fixes or improves the existing codebase. Otherwise, if you wait until July, I can spend some time on it myself. Or as I said, try them downloaded - 2.2.7 should be pretty much 100%, and the 4.x.x latest version should be pretty close for local files as well. Take a look yourself at the demos and maybe try the download. Honestly that should be a plugin, or just a custom stream provider. Get the data for the tile, check some map if it's been saved to disk, if it has, return that stream, otherwise get the HTTP stream, start a process of saving to disk, and then return the stream.

One other thing to check is to make sure you're row and columns are correct, and that your size accurately reflects the number of rows and columns you expect.

Hope that was helpful. If I can answer any more questions, feel free to post back.

On Mon, Jun 10, 2019 at 10:09 AM Sylvain Gravel notifications@github.com wrote:

I could try, I just don't see how it's related. Your engine doesn't know if the input stream / bitmap comes from the web or not and it lays out images seemingly randomly. Changing the location of the data doesn'T appear to have anything to do with the issue.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/moagrius/TileView/issues/525?email_source=notifications&email_token=AAFLHIG24MZQGX3W47PRKHLPZZVBJA5CNFSM4HVYBOZKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODXKEYLY#issuecomment-500452399, or mute the thread https://github.com/notifications/unsubscribe-auth/AAFLHIEDJAZDLACTRS47RHDPZZVBJANCNFSM4HVYBOZA .

LRP-sgravel commented 5 years ago

No worries, I know what lacking the time to do all those great projects feels like. The link I provided will have expired by the time you get to looking into it as it is session bound. Hopefully you ca reproduce some other way.

I'm not comfortable using a library with what definitely looks like a race condition into a production software.

moagrius commented 5 years ago

Totally understandable, and good luck with your project!

Just for documentary purposes, and future readers, this bug only applies to remote tiles (tile image files on a web server, fetched over http or something similar).

And a final note to self: this could also be a disk caching issue.