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

Support Higher Zoom Level Than 22 #329

Closed
schrieveslaach opened this Issue Jun 6, 2016 · 22 comments

Comments

Projects
None yet
5 participants
@schrieveslaach

schrieveslaach commented Jun 6, 2016

At the moment osmdroid is restricted to use a maximum zoom level of 22 even if the tile server provides much higher resolution, for example 26.

The implementation of TileSystem restricts the maximum zoom level to 22. Is it possible to raise the maximum to higher numbers? It seems that using higher zoom level than 22 cause integer overflows.

I started a new fork trying to address this problem but it is not working. I appreciate any help on that.

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Jun 6, 2016

Collaborator

See the doubles branch
On Jun 6, 2016 9:56 AM, "schrieveslaach" notifications@github.com wrote:

At the moment osmdroid is restricted to use a maximum zoom level of 22
even if the tile server provides much higher resolution, for example 26.

The implementation of TileSystem restricts the maximum zoom level to 22.
Is it possible to raise the maximum to higher numbers? It seems that using
higher zoom level than 22 cause integer overflows.

I started a new fork trying to address this problem but it is not working.
I appreciate any help on that.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#329, or mute the thread
https://github.com/notifications/unsubscribe/AB4kGS2uexqYOvQhK-EURYI3q9xbjeyqks5qJCcIgaJpZM4Iu7Cb
.

Collaborator

spyhunter99 commented Jun 6, 2016

See the doubles branch
On Jun 6, 2016 9:56 AM, "schrieveslaach" notifications@github.com wrote:

At the moment osmdroid is restricted to use a maximum zoom level of 22
even if the tile server provides much higher resolution, for example 26.

The implementation of TileSystem restricts the maximum zoom level to 22.
Is it possible to raise the maximum to higher numbers? It seems that using
higher zoom level than 22 cause integer overflows.

I started a new fork trying to address this problem but it is not working.
I appreciate any help on that.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#329, or mute the thread
https://github.com/notifications/unsubscribe/AB4kGS2uexqYOvQhK-EURYI3q9xbjeyqks5qJCcIgaJpZM4Iu7Cb
.

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Jun 11, 2016

Collaborator

do you have a publicly accessible source for zoom 22 for testing?

Collaborator

spyhunter99 commented Jun 11, 2016

do you have a publicly accessible source for zoom 22 for testing?

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Jun 12, 2016

Collaborator

I just ran some tests on the doubles branch. Although you can zoom in as far as you want, there's still some overflow happening somewhere. When zooming in/out, the map is centering somewhere unexpected past zoom 20

Collaborator

spyhunter99 commented Jun 12, 2016

I just ran some tests on the doubles branch. Although you can zoom in as far as you want, there's still some overflow happening somewhere. When zooming in/out, the map is centering somewhere unexpected past zoom 20

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Jun 12, 2016

Collaborator

i just did a quick look into this. It's going to be a lot of work but not impossible.
scrollable area limits will need to be reworked

i also tried to narrow down where the overflow is i think i found it in Project.toMercatorPixels(int x, int y);

Root cause: we're using android's View.scrollTo to handle planning the map around. It uses an x,y coordinate in screen pixels that is integer based. To overcome the overflow issue, we'd have to write our own mechanism to pan the map that's not based on integers nor based on android's View class. Looks like a ton of work.

Collaborator

spyhunter99 commented Jun 12, 2016

i just did a quick look into this. It's going to be a lot of work but not impossible.
scrollable area limits will need to be reworked

i also tried to narrow down where the overflow is i think i found it in Project.toMercatorPixels(int x, int y);

Root cause: we're using android's View.scrollTo to handle planning the map around. It uses an x,y coordinate in screen pixels that is integer based. To overcome the overflow issue, we'd have to write our own mechanism to pan the map that's not based on integers nor based on android's View class. Looks like a ton of work.

spyhunter99 added a commit that referenced this issue Jun 12, 2016

#329 Code changes identify the root cause of overflows when zooming p…
…ast 20. it's overflowing on the y coordinate of android's view system.

#296 related issue
#237 related issue
#46 root issue
@schrieveslaach

This comment has been minimized.

Show comment
Hide comment
@schrieveslaach

schrieveslaach Jun 13, 2016

@spyhunter99, I ported TileSystem to long and I came across the same issues. In a lot of places I needed to convert from long to int... I also tried to switch to PointF and RectF but I do not have a running version yet.

What would be good approach to implement this? I'm not very familiar with the internal...

schrieveslaach commented Jun 13, 2016

@spyhunter99, I ported TileSystem to long and I came across the same issues. In a lot of places I needed to convert from long to int... I also tried to switch to PointF and RectF but I do not have a running version yet.

What would be good approach to implement this? I'm not very familiar with the internal...

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Jun 13, 2016

Collaborator

This is my current understanding and i'm probably wrong...

Essentially, at every zoom level, it creates a canvas that is equal to the size of the tile in pixels * the total number of tiles on at the zoom level. It doesn't actually allocate the ram for it but that's the size of the canvas. When scrolling (panning on the map), android moves the current view of the canvas around which triggers tile loading, etc. Android uses screen coordinates for everything (integer based). At a high enough zoom level, the conversion from lat/lon to pixel coordinates results in a value > Integer.MAX. The negative value will then send the map view flying off somewhere else. We use Android's scrolling mechanism that requires a Point instance (Integer coordinates). If we can get rid of that and use either doubles or longs everywhere, then the problem would be solved. However, using our own scrolling mechanism is not a trivial task

If you look at the files i touched with the last commit, MapController line 225, I put a fixme in place to identify where the first occurrence of overflow is that I've found.

Collaborator

spyhunter99 commented Jun 13, 2016

This is my current understanding and i'm probably wrong...

Essentially, at every zoom level, it creates a canvas that is equal to the size of the tile in pixels * the total number of tiles on at the zoom level. It doesn't actually allocate the ram for it but that's the size of the canvas. When scrolling (panning on the map), android moves the current view of the canvas around which triggers tile loading, etc. Android uses screen coordinates for everything (integer based). At a high enough zoom level, the conversion from lat/lon to pixel coordinates results in a value > Integer.MAX. The negative value will then send the map view flying off somewhere else. We use Android's scrolling mechanism that requires a Point instance (Integer coordinates). If we can get rid of that and use either doubles or longs everywhere, then the problem would be solved. However, using our own scrolling mechanism is not a trivial task

If you look at the files i touched with the last commit, MapController line 225, I put a fixme in place to identify where the first occurrence of overflow is that I've found.

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Jul 6, 2016

Collaborator

@schrieveslaach to more directly answer your question, i think we need some kind of custom view that does not rely on android's scrolling mechanism nor the canvas coordinate system.

Collaborator

spyhunter99 commented Jul 6, 2016

@schrieveslaach to more directly answer your question, i think we need some kind of custom view that does not rely on android's scrolling mechanism nor the canvas coordinate system.

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Aug 21, 2016

Collaborator

attempted to convert to SurfaceView, this will be problematic because we use childViews a lot. I also couldn't get anything to render.

attempted to extend View and ViewGroup, changing all integers to long. For some reason, extending "View" is not resolving any of the protected or public methods or variables.

Collaborator

spyhunter99 commented Aug 21, 2016

attempted to convert to SurfaceView, this will be problematic because we use childViews a lot. I also couldn't get anything to render.

attempted to extend View and ViewGroup, changing all integers to long. For some reason, extending "View" is not resolving any of the protected or public methods or variables.

@schrieveslaach

This comment has been minimized.

Show comment
Hide comment
@schrieveslaach

schrieveslaach Aug 22, 2016

This is still on our agenda. I could work on Thursday on it. Do you think I can support you on this?

schrieveslaach commented Aug 22, 2016

This is still on our agenda. I could work on Thursday on it. Do you think I can support you on this?

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Aug 22, 2016

Collaborator

absolutely!

Collaborator

spyhunter99 commented Aug 22, 2016

absolutely!

@schrieveslaach

This comment has been minimized.

Show comment
Hide comment
@schrieveslaach

schrieveslaach Aug 22, 2016

Do you have anything special in mind? Any commits, branches, ...

schrieveslaach commented Aug 22, 2016

Do you have anything special in mind? Any commits, branches, ...

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Aug 23, 2016

Collaborator

just make a branch with this ticket number and go to town. all of the attempts i've done have not been pushed nor committed (just as stashes).

edit. I normally do feature/#issueNumber or bug/#issueNumber but we're not picky about branching.

Collaborator

spyhunter99 commented Aug 23, 2016

just make a branch with this ticket number and go to town. all of the attempts i've done have not been pushed nor committed (just as stashes).

edit. I normally do feature/#issueNumber or bug/#issueNumber but we're not picky about branching.

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Sep 16, 2016

Collaborator

I think we can use a long based coordinate to keep track of what the view port is looking at, however this would require writing our own mechanism for scrolling and panning the map.

Collaborator

spyhunter99 commented Sep 16, 2016

I think we can use a long based coordinate to keep track of what the view port is looking at, however this would require writing our own mechanism for scrolling and panning the map.

@atoone

This comment has been minimized.

Show comment
Hide comment
@atoone

atoone Sep 23, 2016

It might make sense to write a 'shim' that sits between the view and the OSMDroid code, rather than extending the view itself. The shim could translate view pixel movements into the smallest logical 'world' pixel movements (longs? floats?) and OSMDroid queries that rather than the underlying view.

atoone commented Sep 23, 2016

It might make sense to write a 'shim' that sits between the view and the OSMDroid code, rather than extending the view itself. The shim could translate view pixel movements into the smallest logical 'world' pixel movements (longs? floats?) and OSMDroid queries that rather than the underlying view.

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Sep 23, 2016

Collaborator

I absolutely agree. It's probably the only logical solution aside from
rewriting everything for opengl

On Fri, Sep 23, 2016 at 3:14 AM, atoone notifications@github.com wrote:

It might make sense to write a 'shim' that sits between the view and the
OSMDroid code, rather than extending the view itself. The shim could
translate view pixel movements into the smallest logical 'world' pixel
movements (longs? floats?) and OSMDroid queries that rather than the
underlying view.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#329 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AB4kGeK8vBrW_CMnO08U8PRRGx4dse_6ks5qs3xCgaJpZM4Iu7Cb
.

Collaborator

spyhunter99 commented Sep 23, 2016

I absolutely agree. It's probably the only logical solution aside from
rewriting everything for opengl

On Fri, Sep 23, 2016 at 3:14 AM, atoone notifications@github.com wrote:

It might make sense to write a 'shim' that sits between the view and the
OSMDroid code, rather than extending the view itself. The shim could
translate view pixel movements into the smallest logical 'world' pixel
movements (longs? floats?) and OSMDroid queries that rather than the
underlying view.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#329 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AB4kGeK8vBrW_CMnO08U8PRRGx4dse_6ks5qs3xCgaJpZM4Iu7Cb
.

@atoone

This comment has been minimized.

Show comment
Hide comment
@atoone

atoone Sep 23, 2016

As an aside, where is the best place to discuss general OSMDroid development? The Google Group appears dead and the latest release has thrown up a lot of questions about offline caching and other features.

atoone commented Sep 23, 2016

As an aside, where is the best place to discuss general OSMDroid development? The Google Group appears dead and the latest release has thrown up a lot of questions about offline caching and other features.

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Sep 24, 2016

Collaborator

Great question. I wish google groups had notifications. I don't check it too often

Collaborator

spyhunter99 commented Sep 24, 2016

Great question. I wish google groups had notifications. I don't check it too often

@JonasDaWi

This comment has been minimized.

Show comment
Hide comment
@JonasDaWi

JonasDaWi Jan 18, 2017

Will there be support for higher zoom levels and if yes, when is this feature planned?

JonasDaWi commented Jan 18, 2017

Will there be support for higher zoom levels and if yes, when is this feature planned?

@monsieurtanuki

This comment has been minimized.

Show comment
Hide comment
@monsieurtanuki

monsieurtanuki Aug 2, 2017

Collaborator

Trying to do our own View.onScroll method would be very risky.

As already mentioned, the problem is that we use a virtual canvas that includes the whole world, and that we use int offsets to center the map: standard Android View.getScrollX/Y. We even store the scroll values into preferences, in order to keep the same map center. And that doesn't work very well: if you center your map on a location and tilt your smartphone, the map center will be offset by the difference between your Views width and height - my personal end-user assumption would be that the center would be kept. And that regardless of very high zoom levels.

And if we used the map center instead of the scroll offsets? In the Projection class we would compute long offsets according to the map center (for instance Tokyo in zoom 35), and compute Points relatively to this map center. Or maybe PointL (long version of Point, to be created), which would give us the ability to handle the overflow:

  • this is the current zoom and the current map center (Tokyo level 35)
  • compute the corresponding offset for map center
  • please add this location (Paris) => compute the PointL
  • display the location => no I won't, Paris' PointL is beyond the +- 2^31 overflow

Something like that.

Collaborator

monsieurtanuki commented Aug 2, 2017

Trying to do our own View.onScroll method would be very risky.

As already mentioned, the problem is that we use a virtual canvas that includes the whole world, and that we use int offsets to center the map: standard Android View.getScrollX/Y. We even store the scroll values into preferences, in order to keep the same map center. And that doesn't work very well: if you center your map on a location and tilt your smartphone, the map center will be offset by the difference between your Views width and height - my personal end-user assumption would be that the center would be kept. And that regardless of very high zoom levels.

And if we used the map center instead of the scroll offsets? In the Projection class we would compute long offsets according to the map center (for instance Tokyo in zoom 35), and compute Points relatively to this map center. Or maybe PointL (long version of Point, to be created), which would give us the ability to handle the overflow:

  • this is the current zoom and the current map center (Tokyo level 35)
  • compute the corresponding offset for map center
  • please add this location (Paris) => compute the PointL
  • display the location => no I won't, Paris' PointL is beyond the +- 2^31 overflow

Something like that.

monsieurtanuki added a commit to monsieurtanuki/osmdroid that referenced this issue Aug 25, 2017

feature/#329: store and restore the actual map center (instead of scr…
…oll) and the map orientation

This is the first (slightly unrelated) step.
Why should we use the map center instead of the scroll? Because when tilting the smartphone portrait-landscape-wise, the map center is kept only modulo the difference between `MapView`'s width and height.

Impactes classes:
* `OpenStreetMapConstants`: deprecated scroll preference tags, added latitude, longitude and orientation preference tags
* `MapView`: added the concept of `IGeoPoint initCenter`, took it into account in method `myOnLayout`, added a no-force-redraw version of method `setMapOrientation`
* `StarterMapFragment`: deprecated the use of scroll preferences tags, introduced the use of new preferences' tags (latitude, longitude, orientation), gently refactored in order to avoid Android Studio's nagging

@monsieurtanuki monsieurtanuki referenced this issue Aug 26, 2017

Merged

Bug/#680 #681

spyhunter99 added a commit that referenced this issue Aug 26, 2017

Bug/#680 (#681)
* feature/#329: store and restore the actual map center (instead of scroll) and the map orientation

This is the first (slightly unrelated) step.
Why should we use the map center instead of the scroll? Because when tilting the smartphone portrait-landscape-wise, the map center is kept only modulo the difference between `MapView`'s width and height.

Impactes classes:
* `OpenStreetMapConstants`: deprecated scroll preference tags, added latitude, longitude and orientation preference tags
* `MapView`: added the concept of `IGeoPoint initCenter`, took it into account in method `myOnLayout`, added a no-force-redraw version of method `setMapOrientation`
* `StarterMapFragment`: deprecated the use of scroll preferences tags, introduced the use of new preferences' tags (latitude, longitude, orientation), gently refactored in order to avoid Android Studio's nagging

* bug/#680: crash in PreferenceActivity

There's a call to `Toast.makeText` outside of the UI thread, which is not possible in Android and systematically leads to a crash.

Impacted class:
* `PreferenceActivity`: embedded the call to `Toast.makeText` inside an `Activity.runOnUIThread` method.

spyhunter99 added a commit that referenced this issue Sep 4, 2017

Bug/#683 (#702)
* feature/#329: store and restore the actual map center (instead of scroll) and the map orientation

This is the first (slightly unrelated) step.
Why should we use the map center instead of the scroll? Because when tilting the smartphone portrait-landscape-wise, the map center is kept only modulo the difference between `MapView`'s width and height.

Impactes classes:
* `OpenStreetMapConstants`: deprecated scroll preference tags, added latitude, longitude and orientation preference tags
* `MapView`: added the concept of `IGeoPoint initCenter`, took it into account in method `myOnLayout`, added a no-force-redraw version of method `setMapOrientation`
* `StarterMapFragment`: deprecated the use of scroll preferences tags, introduced the use of new preferences' tags (latitude, longitude, orientation), gently refactored in order to avoid Android Studio's nagging

* bug/#683: mMapView.zoomToBoundingBox is not calculating the required zoom level correctly

This commit:
* fixes the calculation of the zoom that matches a bounding box
* adds Unit Tests for `TileSystem`
* makes a more explicit demo

Impact on existing classes:
* `BoundingBox`: created method `getCenterWithDateLine` that takes into consideration the date line; deprecated `getCenter`
* `MapView`: created method `zoomToBoundingBox` with an additional `borderSizeInPixels` parameter; modified previous method `zoomToBoundingBox` in order to use the new `zoomToBoundingBox` with 0 as border size; fixed the bounding box zoom calculation that is now testable and moved to `TileSystem.getBoundingBoxZoom`
* `TileSystem`: created methods `getBoundingBoxZoom`, `getLongitudeZoom`, `getLatitudeZoom`, `getX01FromLongitude`and `getY01FromLatitude`; modified `LatLongToPixelXYMapSize` in order to take into account the new "XY01" methods; gently refactored javadoc version `6.0.0` to `5.6.6`
* `SampleZoomToBounding`: made a more explicit test (which is accessed in "More Samples / Events / Zoom to Bounding Box" demo)

New class:
* `TileSystemTest`: created in order to test methods `getY01FromLatitude`, `getX01FromLongitude`, `LatLongToPixelXYMapSize` and `getBoundingBoxZoom`

* Fixed and enhanced a unit test

Impact on existing classes:
* OpenStreetMapViewTest: added random iterations; set zoom before center for decent results; added a +-1 tolerance because of my benevolence towards rounding; wrote a relevant test tag; removed commented and deprecated code

* Fixed and enhanced unit tests

Impact on existing classes:
* Bug445Caching: made the test less resource dependent by limiting max zoom level to 16 (cf. https://operations.osmfoundation.org/policies/tiles/: "[tiles at zoom levels 17 and higher] are generally not available (cached) on the server in advance, and have to be rendered specifically for those requests, putting an unjustified burden on the available resources"); gently refactoring javadoc from `6.0` to `5.6.6`
* TileSystemTest: made the XY01 test stronger by checking [0,1]
@monsieurtanuki

This comment has been minimized.

Show comment
Hide comment
@monsieurtanuki

monsieurtanuki Sep 17, 2017

Collaborator

For the record, just managed to go up to zoom level 29 :)

Now I need to clean the code, and I should be able to PR within a week.

Collaborator

monsieurtanuki commented Sep 17, 2017

For the record, just managed to go up to zoom level 29 :)

Now I need to clean the code, and I should be able to PR within a week.

@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Sep 17, 2017

Collaborator

bravo!

Collaborator

spyhunter99 commented Sep 17, 2017

bravo!

@spyhunter99 spyhunter99 added this to the v5.6.6 milestone Sep 17, 2017

monsieurtanuki added a commit to monsieurtanuki/osmdroid that referenced this issue Sep 27, 2017

monsieurtanuki added a commit to monsieurtanuki/osmdroid that referenced this issue Sep 27, 2017

#329 Zoom level is now up to 29
New files:
* 30 `.png` files corresponding to the tiles of the same place on the 30 zoom levels from 0 to 29. I had no way to compute real tiles for high zoom levels, therefore I created the "Abstract" source of tiles with simple colored .png where the zoom level is displayed.

New classes:
* `PointL`: like a `Point`, but with long instead of int
* `ProjectionTest`: a unit test class for `Projection`
* `RectL`: like a `Rect`, but with long instead of int
* `SampleVeryHighZoomLevel`: a demo dedicated to high zoom levels, available in "More Samples / Tileproviders / Offline abstract tiles for zoom levels 0 to 29"

Biggest impacts on existing classes:
* `MapView`: used `PointL` and `RectL` types for Projected data; removed `initCenter`; added `GeoPoint mCenter`, `long mMapScrollX` and `mMapScrollY` and their setters/getters; overridden `scrollBy`; changed `scrollTo`; added `getMapScale`
* `Projection`: created a new constructor without any reference to `MapView`; created `getOffspring` in order to compute a `Projection` from another (e.g. for `MinimapOverlay`); renamed methods for clarity; created _many_ methods
* org.osmdroid.util.TileSystem: renamed methods for clarity; used `PointL` and `RectL` types for Mercator data; created _many_ methods

Other impacted classes:
* `CacheManager`: removed useless code that would have required refactoring
* `GeometryMath`: refactored `DEG2RAD` / `RAD2DEG`; used `MyMath.floorToInt` instead of `(int)` for better handling of negative values; used simpler syntax on `Rect` for easier unit testing purposes
* `GeoPoint`: created method `distanceToAsDouble` to go beyond the meter; used a distance calculation algorithm more precise for small distances; increased precision from float to double
* `GeoPointTest`: create methods `test_distanceTo_itself`, `test_distanceTo_Equator`, `test_distanceTo_Equator_Smaller`, `test_distanceTo_Parallels`, `getCleanLongitudeDiff`, `getRandomLongitude`, `getRandomLatitude`; removed less relevant methods `test_distanceTo_zero`, `test_distanceTo_one`, test_distanceTo_one_degree`
* `MapController`: changed animation methods according to the new scroll behavior
* `MapTileProviderBase`: used `PointL` and `RectL` types for Mercator data
* `Marker`: refactored the use of methods from `Projection` to `MapView`
* `MathConstants`: increased precision from float to double
* `MinimapOverlay`: relied more on inherited methods than on specific code
* `MyLocationNewOverlay`: used `PointL` type for Projected data; using `double` instead of `int` zoom level; using new method `Projection.getPixelsFromProjected`
* `MyMath`: created new methods `flootToLong` and `flootToInt` in order to fix a counter intuitive Java behavior
* `OpenStreetMapViewTest`: unrelated light refactoring
* `OsmBitmapShader`: used `PointL` type for Mercator data
* `PathOverlay`: used `PointL` and `RectL` types for Projected data
* `PathProjection`: used `PointL` type for Mercator data
* `Polygon`: used `PointL` type for Projected data
* `Polyline`: used `PointL` type for Projected data
* `SampleAnimateTo`: changed slightly for testing reasons
* `SampleFactory`: added new class `SampleVeryHighZoomLevel`
* `SampleZoomToBounding`: unrelated light refactoring
* `ScaleBarOverlay`: used more precise new method `GeoPoint.distanceToAsDouble`; handled double distances in method `scaleBarLengthText`; added helper method `getScaleString`; refactored the use of methods from `Projection` to `MapView`
* `StarterMapFragment`: unrelated bug fix *** setInitCenter
* `TileLooper`: used `RectL` type for Mercator data; slightly refactored
* `TilesOverlay`: used `PointL` and `RectL` types for Mercator data; refactored `onTileReadyToDraw`; created `protected` methods `setCanvasRect`, `getCanvasRect`, `setProjection` and `getProjection`
* `microsoft.mappoint.TileSystem`: used 64 instead of 32 as a limit parameter in `setTileSize`; introduced the notions of `primaryKeyMaxZoomLevel` and `projectionZoomLevel`
* `TileSystemTest`: added `testGetLatitudeFromY01`, `testLatitude`, `testGetLongitudeFromX01`, `testLongitude`, `checkLatitude` and `checkLongitude`; removed `testLatLongToPixelXYMapSize`

spyhunter99 added a commit that referenced this issue Oct 1, 2017

Feature/#329 (#723)
Feature/#329 long based coordinates with max zoom 29
@spyhunter99

This comment has been minimized.

Show comment
Hide comment
@spyhunter99

spyhunter99 Oct 1, 2017

Collaborator

done, thanks to @monsieurtanuki

Collaborator

spyhunter99 commented Oct 1, 2017

done, thanks to @monsieurtanuki

@spyhunter99 spyhunter99 closed this Oct 1, 2017

spyhunter99 added a commit that referenced this issue Oct 10, 2017

Feature/#725 (#729)
* feature/#329: store and restore the actual map center (instead of scroll) and the map orientation

This is the first (slightly unrelated) step.
Why should we use the map center instead of the scroll? Because when tilting the smartphone portrait-landscape-wise, the map center is kept only modulo the difference between `MapView`'s width and height.

Impactes classes:
* `OpenStreetMapConstants`: deprecated scroll preference tags, added latitude, longitude and orientation preference tags
* `MapView`: added the concept of `IGeoPoint initCenter`, took it into account in method `myOnLayout`, added a no-force-redraw version of method `setMapOrientation`
* `StarterMapFragment`: deprecated the use of scroll preferences tags, introduced the use of new preferences' tags (latitude, longitude, orientation), gently refactored in order to avoid Android Studio's nagging

* bug/#683: mMapView.zoomToBoundingBox is not calculating the required zoom level correctly

This commit:
* fixes the calculation of the zoom that matches a bounding box
* adds Unit Tests for `TileSystem`
* makes a more explicit demo

Impact on existing classes:
* `BoundingBox`: created method `getCenterWithDateLine` that takes into consideration the date line; deprecated `getCenter`
* `MapView`: created method `zoomToBoundingBox` with an additional `borderSizeInPixels` parameter; modified previous method `zoomToBoundingBox` in order to use the new `zoomToBoundingBox` with 0 as border size; fixed the bounding box zoom calculation that is now testable and moved to `TileSystem.getBoundingBoxZoom`
* `TileSystem`: created methods `getBoundingBoxZoom`, `getLongitudeZoom`, `getLatitudeZoom`, `getX01FromLongitude`and `getY01FromLatitude`; modified `LatLongToPixelXYMapSize` in order to take into account the new "XY01" methods; gently refactored javadoc version `6.0.0` to `5.6.6`
* `SampleZoomToBounding`: made a more explicit test (which is accessed in "More Samples / Events / Zoom to Bounding Box" demo)

New class:
* `TileSystemTest`: created in order to test methods `getY01FromLatitude`, `getX01FromLongitude`, `LatLongToPixelXYMapSize` and `getBoundingBoxZoom`

* Fixed and enhanced a unit test

Impact on existing classes:
* OpenStreetMapViewTest: added random iterations; set zoom before center for decent results; added a +-1 tolerance because of my benevolence towards rounding; wrote a relevant test tag; removed commented and deprecated code

* Fixed and enhanced unit tests

Impact on existing classes:
* Bug445Caching: made the test less resource dependent by limiting max zoom level to 16 (cf. https://operations.osmfoundation.org/policies/tiles/: "[tiles at zoom levels 17 and higher] are generally not available (cached) on the server in advance, and have to be rendered specifically for those requests, putting an unjustified burden on the available resources"); gently refactoring javadoc from `6.0` to `5.6.6`
* TileSystemTest: made the XY01 test stronger by checking [0,1]

* #329 Zoom level is now up to 29

New files:
* 30 `.png` files corresponding to the tiles of the same place on the 30 zoom levels from 0 to 29. I had no way to compute real tiles for high zoom levels, therefore I created the "Abstract" source of tiles with simple colored .png where the zoom level is displayed.

New classes:
* `PointL`: like a `Point`, but with long instead of int
* `ProjectionTest`: a unit test class for `Projection`
* `RectL`: like a `Rect`, but with long instead of int
* `SampleVeryHighZoomLevel`: a demo dedicated to high zoom levels, available in "More Samples / Tileproviders / Offline abstract tiles for zoom levels 0 to 29"

Biggest impacts on existing classes:
* `MapView`: used `PointL` and `RectL` types for Projected data; removed `initCenter`; added `GeoPoint mCenter`, `long mMapScrollX` and `mMapScrollY` and their setters/getters; overridden `scrollBy`; changed `scrollTo`; added `getMapScale`
* `Projection`: created a new constructor without any reference to `MapView`; created `getOffspring` in order to compute a `Projection` from another (e.g. for `MinimapOverlay`); renamed methods for clarity; created _many_ methods
* org.osmdroid.util.TileSystem: renamed methods for clarity; used `PointL` and `RectL` types for Mercator data; created _many_ methods

Other impacted classes:
* `CacheManager`: removed useless code that would have required refactoring
* `GeometryMath`: refactored `DEG2RAD` / `RAD2DEG`; used `MyMath.floorToInt` instead of `(int)` for better handling of negative values; used simpler syntax on `Rect` for easier unit testing purposes
* `GeoPoint`: created method `distanceToAsDouble` to go beyond the meter; used a distance calculation algorithm more precise for small distances; increased precision from float to double
* `GeoPointTest`: create methods `test_distanceTo_itself`, `test_distanceTo_Equator`, `test_distanceTo_Equator_Smaller`, `test_distanceTo_Parallels`, `getCleanLongitudeDiff`, `getRandomLongitude`, `getRandomLatitude`; removed less relevant methods `test_distanceTo_zero`, `test_distanceTo_one`, test_distanceTo_one_degree`
* `MapController`: changed animation methods according to the new scroll behavior
* `MapTileProviderBase`: used `PointL` and `RectL` types for Mercator data
* `Marker`: refactored the use of methods from `Projection` to `MapView`
* `MathConstants`: increased precision from float to double
* `MinimapOverlay`: relied more on inherited methods than on specific code
* `MyLocationNewOverlay`: used `PointL` type for Projected data; using `double` instead of `int` zoom level; using new method `Projection.getPixelsFromProjected`
* `MyMath`: created new methods `flootToLong` and `flootToInt` in order to fix a counter intuitive Java behavior
* `OpenStreetMapViewTest`: unrelated light refactoring
* `OsmBitmapShader`: used `PointL` type for Mercator data
* `PathOverlay`: used `PointL` and `RectL` types for Projected data
* `PathProjection`: used `PointL` type for Mercator data
* `Polygon`: used `PointL` type for Projected data
* `Polyline`: used `PointL` type for Projected data
* `SampleAnimateTo`: changed slightly for testing reasons
* `SampleFactory`: added new class `SampleVeryHighZoomLevel`
* `SampleZoomToBounding`: unrelated light refactoring
* `ScaleBarOverlay`: used more precise new method `GeoPoint.distanceToAsDouble`; handled double distances in method `scaleBarLengthText`; added helper method `getScaleString`; refactored the use of methods from `Projection` to `MapView`
* `StarterMapFragment`: unrelated bug fix *** setInitCenter
* `TileLooper`: used `RectL` type for Mercator data; slightly refactored
* `TilesOverlay`: used `PointL` and `RectL` types for Mercator data; refactored `onTileReadyToDraw`; created `protected` methods `setCanvasRect`, `getCanvasRect`, `setProjection` and `getProjection`
* `microsoft.mappoint.TileSystem`: used 64 instead of 32 as a limit parameter in `setTileSize`; introduced the notions of `primaryKeyMaxZoomLevel` and `projectionZoomLevel`
* `TileSystemTest`: added `testGetLatitudeFromY01`, `testLatitude`, `testGetLongitudeFromX01`, `testLongitude`, `checkLatitude` and `checkLongitude`; removed `testLatLongToPixelXYMapSize`

* Javadoc gentle fix

* Javadoc gentle fix

* Javadoc gentle fix

* Javadoc gentle fix

* Javadoc gentle fix

* Javadoc gentle fix

* Javadoc gentle fix

* Gentle conflict fix

* Gentle conflict fix

* Gentle conflict fix

* Impacts:
* `SampleFactory`: added a reference to new demo `SampleVeryHighZoomLevel`
* `TileSystem`: switched to `double` zoom level versions for methods `MapScale` and `GroundResolution`
* `TileSystemMathTest`: moved to `TileSystemTest` methods `test_MapSize`, `test_groundResolution` and `test_groundMapScale`
* `TileSystemTest`: moved from `TileSystemTest` methods `test_MapSize`, `test_groundResolution` and `test_groundMapScale`; improved their handling of high zoom levels

* Fixed `Polygon` issue as in https://www.youtube.com/watch?v=S4Pf2u9WSyQ

Impacts in `Polygon` class:
* `mOriginalPoints` is now an array of `double`, no more `intE6` (but it's not related to the bug fixing)
* new method `setCloserPoint`: the assumption is that 2 consecutive points should be as close as possible, therefore we add or subtract "the size of the world" if necessary

* First part of #725 - Polyline and Polygon issues at higher zoom levels with/wo hardware acceleration

With this fix, the `Polygon`s looks OK up to zoom 29.
What remains to be done:
* check with holes
* same work on `Polyline`
* low-zoom "best top-left version" of `Polygon` / `Polyline`

Regarding this delivery...

New classes:
* `SegmentIntersection`: tools in order to compute the intersection between two 2D segments through `public` method `intersection`
* `SegmentIntersectionTest`: unit tests on `SegmentIntersection`

Impacted classes:
* `PointL`: added overriden methods `toString` and `equals`; added methods `set` and `squareDistanceTo`
* `Polygon`: modified method `buildPathPortion` in order to use less overflow prone `PointL` (instead of `Point`), to consider `Path` as a list of 2D segments, and to clip those segments into a min/max values square; added methods `clip`, `isInClipArea`, `intersection`, `lineTo`
* `Projection`: added methods `getLongPixelsFromProjected`, `getLongPixelXFromMercator`, `getLongPixelYFromMercator` and `getLongPixelFromMercator` for overflow reasons; removed 2 unused imports

* Last part of #725 - Polyline and Polygon issues at higher zoom levels with/wo hardware acceleration :
* check with holes
* same work on `Polyline`
* low-zoom "best top-left version" of `Polygon` / `Polyline`

Regarding this delivery...

New classes:
* `Distance`: a tool class dedicated to the computation of 2D distances
* `DistanceTest`: a Unit Test class dedicated to `Distance`
* `LinearRing`: used to be an inner class in `Polygon` but needed to go out in order to be used by `Polyline` too; was enhanced too in order to match the new requirements and the new zoom level limit

Impacted classes:
* `PointL`: removed methods `squareDistanceTo` that are now more or less available in new dedicated class `Distance`
* `Polygon`: moved `LinearRing` code to the new eponymous class; handled a common offset for the main polygon and the holes
* `Polyline`: removed all the code that could now be handled by `LinearRing`
* `Projection`: added parameter `pCloser` to method `getLongPixelsFromProjected`

* Lower clip area threshold values:
* mClipMax is now 17000 (instead of Integer.MAX_VALUE / 8)
* mClipMin is now -mClipMax (instead of Integer.MIN_VALUE / 8)

* Modified `Bug445Caching` in order to avoid random Travis crash on "queue size":
* added `ensureCapacity` in order to actually cache all tiles
* added methods `getMaxTileExpected`, `getMinNumberExpected`, `getMaxNumberExpected`

* Lowered the clip area size in `LinearRing` in order to fix hardware acceleration related path not displaying bugs:
* `mClipMax` = 1400
* `mClipMin` = -600

* Final (?) fix for #725

Impacted classes:
* `LinearRing`: used `List<RectL>` for segments instead of `List<PointL>` for both segments start and end points; added method `applyOffset`; changed `getBestOffset` so that it focuses on the smallest distance to the screen center rather than on the biggest common area with the screen rect; removed `getCommonArea`
* `RectL`: added constructor `RectL(RectL other)` and method `set(RectL other)`

* (forgotten file of previous commit/push)

* Fix as we cannot use only `path.close()`. More robust segment clipping.

New class:
* `SegmentClipper`: a tool to clip segments
* `SegmentClipperTest`: a Unit Test class dedicated to `SegmentClipper`

Impacted classes:
* `LinearRing`: now has a constructor with a `Path` as a parameter; now implements `SegmentClipper.SegmentClippable`; moved clipping code to new class `SegmentClipper`; added parameter `boolean pClosePath` to method `getSegmentsFromProjected` as we cannot just use `path.close()` with the clipping process; remove parameter `boolean pClosePath` from method `getPathFromSegments` for the same reason ;)
* `PointL`: added constructor `PointL(PointL other)`
* `Polygon`: impacted the fact that `LinearRing`'s constructor now demands a `Path`
* `Polyline`: impacted the fact that `LinearRing`'s constructor now demands a `Path`
* `RectL`: added overridden methods `equals` and `hashCode`

This was referenced Oct 12, 2017

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