Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MapDataStore and POIs doesn't work as expected #792

Closed
ksaihtam opened this issue Mar 16, 2016 · 20 comments
Closed

MapDataStore and POIs doesn't work as expected #792

ksaihtam opened this issue Mar 16, 2016 · 20 comments

Comments

@ksaihtam
Copy link

I have setup a MapDataStore with dynamic added/removed POIs without any labels or ways. I initialize the MapReadResult with a custom tag like "Tag("test", "test")" and my render rule is like:

<rule cat="none" e="node" k="test" v="test">
<symbol id="poi" src="assets:symbols/transport/airport.svg" display="always" />
<circle radius="1.45" scale-radius="true" fill="#000000" />
</rule>

So, the POI should be appear as a black circle and a symbol.

The getDataTimestamp from my MapDataStore class returns always the current timestamp. For the Tile Cache i tried a persistent and non-persistent tile cache without any changes. I also tried to purge the Tile Cache on application start but without success.

Now the problems:

  1. If i initialize the TileRenderLayer with renderLabels = false i only see the circle. If i use renderLabels = true i see both. As described i don't use any labels.
  2. If i add some POIs later and trigger a requestRedraw i see that the engine gets the new POIs from readMapData but they don't get drawn in the current zoom level. If i change the zoomlevel i see all new POIs. If i switch back to the initial zoomlevel they don't get drawn, they are still not there.

Did i overlooked something or is it still a mapsforge problem?

@devemux86
Copy link
Collaborator

You mean trying the SimpleDataStoreMapViewer example in Samples?

The renderLabels probably needs refactoring, as it involves labels and symbols.
It's about using the LabelLayer or not. Normally should work both ways.

BTW which Mapsforge version?

@ksaihtam
Copy link
Author

I use a MapDataStore-Layer like from SimpleDataStoreMapViewer as a additional layer in a modified DownloadLayerViewer example.

I use the latest (from today) dev Version.

@ksaihtam
Copy link
Author

As additional information: Currently i always purge the tile cache on application start. So it looks like the engine simple ignores new POIs and only redraw if the tile cache is empty.

@devemux86
Copy link
Collaborator

If you follow Mapsforge life cycle the cache is cleared on exit (unless you use persistent tile cache).

@ksaihtam
Copy link
Author

Yes, i know. But how i can force a tile redraw if there is new data available to draw? It seems the requestRedraw currently doesn't work with the tile cache. It simple ignore the timestamp. If i purge the tile cache before i call requestRedraw the new data is drawn.

@devemux86
Copy link
Collaborator

There are two caches, the memory and the file cache (persistent or not).

If the map is changed after it was rendered and cached, then depending on which caches you declared on its creation, you may need to reinitialized them too.
I have not played with that but comes in mind the RenderThemeChanger example.

Regular redraw works normally with overlays on top of map.

@ksaihtam
Copy link
Author

I can't reinitialize the overlay every some seconds because the cache ignores the timestamp. Is there any other meaning for the timestamp as to tell the cache that he should junk the tile, in memory or as file, and redraw it?

@devemux86
Copy link
Collaborator

You can debug the TileRendererLayer.isTileStale, is the data store updated with new time?

@ksaihtam
Copy link
Author

The TileRendererLayer.isTileStale is true but the tile still exists in the tileCache and the if-clause in TileLayer fails because !this.tileCache.containsKey(job).

            boolean a = isTileStale(tile, bitmap);
            boolean b = this.hasJobQueue;
            boolean c = !this.tileCache.containsKey(job);

            if (a && b && c) {
                this.jobQueue.add(job);
            }

a is true
b is true
c is false

If i remove c the job is added but not redrawn.

@ksaihtam
Copy link
Author

The line in TileLayer

if (isTileStale(tile, bitmap) && this.hasJobQueue && !this.tileCache.containsKey(job)) {

should be changed to

if (this.hasJobQueue && (isTileStale(tile, bitmap) || !this.tileCache.containsKey(job))) {

So the job is added on a new timestamp or if the tile doesn't exist in the tile cache. And thats the point i'm out. I have no clue from the tile/redraw engine. I hope this helps and the problem can be fixed.

@devemux86
Copy link
Collaborator

Thanks for the debugging, will need to check it.

Reminder: and see if that alters library behavior in other places.

@ksaihtam
Copy link
Author

For your reminder: The AndroidTileBitmap.isExpired function returns the wrong value if expiration is set. This cause heavy redraw action for TileDownloadLayers with my changes.

@ksaihtam
Copy link
Author

The next thing i see. If a tile from a TileDownloadLayer is expired it would not get downloaded on a requestRedraw(). It will end up in TileDownloadThread.doWork but there is no expiration check and only the tileCache.containsKey check which is always true.

@devemux86
Copy link
Collaborator

All these with persistent cache?

Because I don't recall we had an expiration mechanism before introducing that feature.

@ksaihtam
Copy link
Author

Yes with persistent cache. It was a bitmap with expiration = 0 and a timestamp in the past that got expired. Because my changes it was every time added to the queue on requestRedraw. But it ended up in TileDownloadThread.doWork but there is no expiration check and the download never start.

@devemux86
Copy link
Collaborator

For reference the persistent cache forum topic and pull request.

@ksaihtam
Copy link
Author

Ouch, i see. Looks like the timestamp thing and a cache behind a tile layer is "not well implemented" ;-). I would prefer a "force" flag in the job class to trigger the work independent of any wired label or cache stuff.

@ksaihtam
Copy link
Author

As example of wired. I was wondering why my jobs don't get added to the joblist in the TileLayer.draw(). The reason was in MapWorkerPool.run(). The job was added to the queue but it never get executed or removed and because that all new jobs for this tile never get added because there was already a job for this tile in the queue. And the main reason for this mess is this if case:

if (!this.tileCache.containsKey(rendererJob) || rendererJob.labelsOnly)

i changed it to

if (!this.tileCache.containsKey(rendererJob) || !rendererJob.labelsOnly)

but redraw doesn't work. I think there is a deeper label or cache dependency that prevent any simple redraw of a simple POI as symbol.

@devemux86
Copy link
Collaborator

@ksaihtam is there anything else on that issue?

@ksaihtam
Copy link
Author

ksaihtam commented Apr 4, 2016

The issue is still present in MapDataStore with dynamic pois. I moved away from MapDataStore and wrote my own simple layer to get it working.

@ksaihtam ksaihtam closed this as completed Apr 4, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants