Description
Describe the bug
The in built MapSource.get_y() does not produce the correct value for y for the southern hemisphere ie, latitudes that are negative.
And when it is fixed, the images are then indexed in the wrong order for surrounding images (indicating a negative increment).
N.B. I did not have this issue with the online sources for some reason they output the correct indexing. So I may be introducing a bug with my LocalMapSource class.
To Reproduce
Code example showing the issue:
I am using a new source that loads the map images from a local directory (could be part of the bug):
LocalSource.py:
# coding=utf-8
"""
Local tiles provider for MapView
============================
"""
__all__ = ["LocalMapSource"]
import io
import threading
import math
import os
from kivy.core.image import Image as CoreImage
from kivy.core.image import ImageLoader
from kivy_garden.mapview.downloader import Downloader
from kivy_garden.mapview.source import MapSource
from math import atan, ceil, cos, exp, log, pi, tan
from kivy_garden.mapview.utils import clamp
from kivy_garden.mapview.constants import (
CACHE_DIR,
MAX_LATITUDE,
MAX_LONGITUDE,
MIN_LATITUDE,
MIN_LONGITUDE,
)
from kivy.metrics import dp
class LocalMapSource(MapSource):
'''
Similar to the Source except references a local directory
{dir}/{z}/{x}/{y}.png
where {dir} is a local directory
'''
def __init__(self, directory, **kwargs):
super().__init__(**kwargs)
self.directory = directory
self.attribution = ""
self.projection = ''
self.is_xy = self.projection == "xy"
def fill_tile(self, tile):
if tile.state == "done":
return
Downloader.instance(self.cache_dir).submit(self._load_tile, tile)
def _load_tile(self, tile):
# global db context cannot be shared across threads.
filepath = os.path.abspath('{}/{}/{}/{}.png'.format(self.directory,
tile.zoom, tile.tile_x, tile.tile_y))
if os.path.exists(filepath):
im = CoreImage(filepath)
if im is None:
tile.state = "done"
return
return self._load_tile_done, (tile, im,)
else:
tile.state="done"
return
def _load_tile_done(self, tile, im):
tile.texture = im.texture
tile.state = "need-animation"
def get_x(self, zoom, lon):
if self.is_xy:
return lon
x = super().get_x(zoom, lon)
return x
#This is an alternate implementation from openstreetmap.
# n = 2.** zoom
# lon = clamp(lon, MIN_LONGITUDE, MAX_LONGITUDE)
# x = int(((lon +180.)/360.)*n)
# print('z {} lon {} x {}'.format(zoom, lon, x))
# return x
def get_y(self, zoom, lat):
if self.is_xy:
return lat
y= super().get_y(zoom, lat)
print("getY {} {} {}".format(lat, zoom, y))
return y
#This is an alternate implementation from openstreetmap.
# n = 2.**zoom
# lat = clamp(lat, MIN_LATITUDE, MAX_LATITUDE)
# lat_rad = math.radians(lat)
# y= int(n*(1.-math.asinh(tan(lat_rad))/pi)/2.0)
# print('z {} lat {} y {}'.format(zoom, lat, y))
# return y
def get_lon(self, zoom, x):
if self.is_xy:
return x
return super().get_lon(zoom, x)
def get_lat(self, zoom, y):
if self.is_xy:
return y
return super().get_lat(zoom, y)
main.py:
from kivy.app import App
from kivy_garden.mapview import MapView, MapSource
from local_source import LocalMapSource
from kivy.uix.widget import Widget
from kivy.properties import (
NumericProperty, ReferenceListProperty, ObjectProperty
)
class MapViewApp(App):
def build(self):
mapview = MapView(
zoom=11, lat=-27.5399, lon=152.8045)
mapview.map_source=LocalMapSource('local_dir')
return mapview
if __name__ == "__main__":
MapViewApp().run()
Expected behavior
A clear and concise description of what you expected to happen.
I expect the system to display the map correctly. To produce the correct y index for the relevant image. And to order neighbours in the vertical direction correctly.
I found a fix for the y value of the center image by removing the negation in this clamp
mapview/kivy_garden/mapview/source.py
Line 162 in 216ea42
That fixes the indexing issue. However the images are still in reverse order in the N-S direction. see image below:
Logs/output
If applicable, add screenshots to help explain your problem.
Platform (please complete the following information):
Linux, python 3.8
Additional context
Add any other context about the problem here.
Activity