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

MapView "lite mode" as in Google Maps #990

Open
monsieurtanuki opened this Issue Apr 9, 2018 · 10 comments

Comments

Projects
None yet
3 participants
@monsieurtanuki
Copy link
Collaborator

monsieurtanuki commented Apr 9, 2018

Issue Type

  • Improvement

Description and/or steps/code to reproduce the problem

As mentioned by @AbduazizKayumov in #958, it would be nice to have a lite mode in MapView, similar to GoogleMaps':

A lite mode map is a bitmap image of a map at a specified location and zoom level

@spyhunter99

This comment has been minimized.

Copy link
Collaborator

spyhunter99 commented Apr 11, 2018

i feel like this was requested before. Someone had asked for a mechanism to fetch a specific tile from the cache, would that satisfy this need?

@monsieurtanuki

This comment has been minimized.

Copy link
Collaborator

monsieurtanuki commented Apr 12, 2018

@spyhunter99 Rather than just a tile fetch, it's more like "I would like to put MapView snapshots into a ListView or a CardView"
I know that in my app I used some kind of MapView bitmap export (including tiles, markers, polylines, ...).
I believe most of the export part is already coded. We just need to make it easy to use.

And with a nice demo! I'm currently building another demo with all US states and gathered their geo bounding boxes.
A ListView with 50 US states snapshots would be the target demo. Possibly with rounded corners ;)

@pasniak

This comment has been minimized.

Copy link
Contributor

pasniak commented Apr 12, 2018

I'd use it for thumbnails of locations in #719. Right now I have bitmap but it is a bit off (just part of a point is displayed i.e. just the tile containing the point, not the neighboring tile).

@monsieurtanuki

This comment has been minimized.

Copy link
Collaborator

monsieurtanuki commented Apr 12, 2018

A problem might be to know when a MapView is fully rendered and ready to export:

  • when are ALL the needed tiles available?
  • possible downgraded mode that includes MapTileApproximater?

For the record, when I exported a MapView into a Bitmap in my app, I used View.getDrawingCache(false). Can we do the same with many distinct maps to exports? I don't think so.

@monsieurtanuki monsieurtanuki self-assigned this Jul 20, 2018

@monsieurtanuki

This comment has been minimized.

Copy link
Collaborator

monsieurtanuki commented Aug 5, 2018

Working on it...

@monsieurtanuki

This comment has been minimized.

Copy link
Collaborator

monsieurtanuki commented Aug 13, 2018

Knowing when all the needed tiles are available is not an issue, a simple loop is enough.

I managed to export a large png from a geo area, but only the tiles.
I didn't have to create a MapView for that.

Now the problem is: should I create a dummy MapView just to use its draw method, and will it work in background mode, even if the MapView is not visible? Or is it possible to ignore the View aspect and draw directly on a Canvas? Of course the additional views like info windows would be ignored...

The problem is that MapView is at the same time a View, a Canvas drawer, a touch listener and - thanks to Android technology - a kind of repository for Context, Resources or Bitmaps.

@monsieurtanuki

This comment has been minimized.

Copy link
Collaborator

monsieurtanuki commented Jan 3, 2019

Working again on the subject.

A way to include all kinds of Overlays in the snapshot is to use Projection instead of MapView in method Overlay.draw(Canvas canvas, MapView mapView, boolean shadow).

@spyhunter99 While I'm creating Overlay.draw(Canvas canvas, Projection projection, boolean shadow), wouldn't we be even better off without the "shadow" parameter, which in the code comments seems to be deemed finally useless, cf. DefaultOverlayManager - always pass false, the shadow parameter will be removed in a later version of osmdroid. What do you think about that?

@monsieurtanuki

This comment has been minimized.

Copy link
Collaborator

monsieurtanuki commented Jan 4, 2019

@spyhunter99 Forget it, I'll make it more frictionless by creating both Overlay.draw(Canvas canvas, Projection projection, boolean shadow) and Overlay.draw(Canvas canvas, Projection projection), something like:

public void draw(final Canvas pCanvas, final MapView pMapView, final boolean pShadow) {
	if (pShadow) {
		return;
	}
	draw(pCanvas, pMapView.getProjection());
}

public void draw(final Canvas pCanvas, final Projection pProjection, final boolean pShadow) {
	if (pShadow) {
		return;
	}
	draw(pCanvas, pProjection);
}

public void draw(final Canvas c, final Projection pProjection) {}

The (reachable?) goal being for classes extending Overlay to override only draw(Canvas, Projection).

@spyhunter99

This comment has been minimized.

Copy link
Collaborator

spyhunter99 commented Jan 5, 2019

A good compromise for removing the method with the pShadow argument is exactly this. Make a new method without it, deprecate the old one and have the old one call the new one. Then may be few versions down the road, add an annoying log statement, that it will go away, then finally remove it

monsieurtanuki added a commit that referenced this issue Jan 5, 2019

feature/#990 - step 1 - Overlay.draw(Canvas, Projection)
Created method `Overlay.draw(Canvas, Projection)`, to be used and overridden rather than the now deprecated method `draw(Canvas, MapView, boolean)`.

Impacted interface:
* `OverlayManager`: created method `onDraw(Canvas, Projection)`, to be used and overridden rather than the now deprecated method `onDraw(Canvas, MapView)`

Impacted classes:
* `Overlay`: created method `draw(Canvas, Projection)`, to be used and overridden rather than the now deprecated method `draw(Canvas, MapView, boolean)`; gently refactored
* `Projection`: added getters `isHorizontalWrapEnabled`, `isVerticalWrapEnabled` and `getOrientation`

* `CirclePlottingOverlay`: removed useless overridden code of `draw(Canvas, MapView, boolean)` as there's no display
* `IconPlottingOverlay`: removed useless overridden code of `draw(Canvas, MapView, boolean)` as there's no display
* `MapEventsOverlay`: removed useless overridden code of `draw(Canvas, MapView, boolean)` as there's no display
* `MilStdPointPlottingOverlay`: removed useless overridden code of `draw(Canvas, MapView, boolean)` as there's no display
* `RotationGestureOverlay`: removed useless overridden code of `draw(Canvas, MapView, boolean)` as there's no display

* `Bug82WinDeath`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `CompassOverlay`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `CopyrightOverlay`: added field `mCopyrightNotice` and its setter; moved most of the code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `DirectedLocationOverlay`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `FolderOverlay`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `GroundOverlay2`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `IconOverlay`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `ItemizedOverlay`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`; replaced parameter `MapView` with `Projection` in method `onDrawItem(Canvas, Item, Point, MapView)`
* `ItemizedOverlayWithFocus`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `Marker`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `MinimapOverlay`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`; replaced method `setViewPort(Canvas, MapView)` with `setViewPort(Canvas, Projection)`
* `MyLocationNewOverlay`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`; replaced method `drawMyLocation(Canvas, MapView, Location)` with `drawMyLocation(Canvas, Projection, Location)`
* `PathOverlay`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `Polygon`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `Polyline`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `SampleTileStates`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `ScaleBarOverlay`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `SimpleLocationOverlay`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`
* `TilesOverlay`: moved code from `draw(Canvas, MapView, boolean)` to `draw(Canvas, Projection)`; replaced method `protectDisplayedTilesForCache(Canvas, MapView)` with `protectDisplayedTilesForCache(Canvas, Projection)`; replaced method `setViewPort(Canvas, MapView)` with `setViewPort(Canvas, Projection)`; `OverlayTileLooper`; unrelated little optimization in method `onTileReadyToDraw`

* `DefaultOverlayManager`: moved code from `onDraw(Canvas, MapView)` to new method `onDraw(Canvas, Projection)`
* `LinearRing`: remplace method `setClipArea(MapView)` with `setClipArea(Projection)`

monsieurtanuki added a commit that referenced this issue Jan 6, 2019

Merge pull request #1245 from osmdroid/feature/#990
feature/#990 - step 1 - Overlay.draw(Canvas, Projection)
@monsieurtanuki

This comment has been minimized.

Copy link
Collaborator

monsieurtanuki commented Jan 6, 2019

Step 1 was #1245 - merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment