Skip to content

Commit

Permalink
simplify the MAP_SERVICES
Browse files Browse the repository at this point in the history
standardize get_url() in all the mapServers
  • Loading branch information
heldersepu committed Sep 21, 2012
1 parent aa501c1 commit 266a290
Show file tree
Hide file tree
Showing 32 changed files with 231 additions and 402 deletions.
6 changes: 3 additions & 3 deletions download.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from gmapcatcher.xmlUtils import load_gpx_coords

mConf = mapConf.MapConf()
ctx_map = MapServ(mConf.init_path, mConf.repository_type)
ctx_map = MapServ(mConf)
downloader = None


Expand Down Expand Up @@ -82,11 +82,11 @@ def download_coordpath(gpxfile, max_zl, min_zl, layer, arround=2):
print "Download %s (%f, %f), range (%f, %f), mapsource: \"%s %s\", zoom level: %d to %d" % \
(args.location, args.lat, args.lng,
args.lat_range, args.lng_range,
MAP_SERVICES[args.layer]['serviceName'], MAP_SERVICES[args.layer]['layerName'],
'', '',
args.max_zl, args.min_zl)
else:
print "Download path in %s, mapsource: \"%s %s\", zoom level: %d to %d, width=%d tiles" % \
(args.gpx, MAP_SERVICES[args.layer]['serviceName'], MAP_SERVICES[args.layer]['layerName'], args.max_zl, args.min_zl, args.width)
(args.gpx, '', '', args.max_zl, args.min_zl, args.width)

downloader = MapDownloader(ctx_map, args.nr_threads)
try:
Expand Down
6 changes: 3 additions & 3 deletions gmapcatcher/DLWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def _buttons(strFolder):

gtk.stock_add([(gtk.STOCK_HARDDISK, "_Download", 0, 0, "")])
self.b_download = gtk.Button(stock=gtk.STOCK_HARDDISK)
self.b_download.connect('clicked', self.run, conf.init_path, conf.repository_type, strFolder)
self.b_download.connect('clicked', self.start_download, strFolder)
hbbox.pack_start(self.b_download)

hbox = gtk.HBox()
Expand Down Expand Up @@ -139,9 +139,9 @@ def _buttons(strFolder):
self.show_all()

## Start the download
def run(self, w, init_path, repostype, strFolder):
def start_download(self, w, strFolder):
# Creating our own gmap
self.gmap = mapServices.MapServ(init_path, repostype)
self.gmap = mapServices.MapServ(self.conf)
self.complete = []
self.downloader = MapDownloader(self.gmap)
if self.conf.map_service in NO_BULK_DOWN:
Expand Down
3 changes: 1 addition & 2 deletions gmapcatcher/mapArgs.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,7 @@ def __init__(self, arrArgs=()):
elif arg.startswith('--hybrid'):
self.layer = LAYER_HYB
elif arg.startswith('--mapid='):
mid = arg[8:]
self.layer = [i for i in range(len(MAP_SERVICES)) if MAP_SERVICES[i]['TextID'] == mid][0]
self.layer = arg[8:]
elif arg.startswith('--full-range'):
self.location = "Whole World"
self.lng = 0
Expand Down
140 changes: 19 additions & 121 deletions gmapcatcher/mapConst.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,132 +43,29 @@
LAYER_NAMES = ["Map", "Satellite", "Terrain", "Hybrid"]
LAYER_DIRS = ["tiles", "sat_tiles", "ter_tiles", "hyb_tiles"]

#If layers are added / removed - change the decision making in mapServices.get_url_from_coord()
# name of the layer service is created as: serviceName + layerName

# ID should be renamed to "layerType", its no longer an ID (after update from end of april 2010)
# IDM stands for numerical ID of map (used previously by ID), used as map ID in sqlite3 repository
# same as "layerDir" for filesystem repos types.

FIRST_LAYER_ID = 0
MAP_SERVICES = [
{"ID": LAYER_MAP, "TextID": "gmap", "serviceName":MAP_SERVERS[GOOGLE],
"layerDir": "tiles", "layerName": LAYER_NAMES[LAYER_MAP]},
{"ID": LAYER_SAT, "TextID": "gsat", "serviceName":MAP_SERVERS[GOOGLE],
"layerDir": "sat_tiles", "layerName": LAYER_NAMES[LAYER_SAT]},
{"ID": LAYER_TER, "TextID": "gter", "serviceName":MAP_SERVERS[GOOGLE],
"layerDir": "ter_tiles", "layerName": LAYER_NAMES[LAYER_TER]},
{"ID": LAYER_HYB, "TextID": "ghyb", "serviceName":MAP_SERVERS[GOOGLE],
"layerDir": "hyb_tiles", "layerName": LAYER_NAMES[LAYER_HYB]},

{"ID": LAYER_MAP, "TextID": "ymap", "serviceName":MAP_SERVERS[YAHOO],
"layerDir": "yahoomap", "layerName": LAYER_NAMES[LAYER_MAP]},
{"ID": LAYER_SAT, "TextID": "yter", "serviceName":MAP_SERVERS[YAHOO],
"layerDir": "yahooter", "layerName": LAYER_NAMES[LAYER_SAT]},
{"ID": LAYER_HYB, "TextID": "yhyb", "serviceName":MAP_SERVERS[YAHOO],
"layerDir": "yahoohyb", "layerName": LAYER_NAMES[LAYER_HYB]},

{"ID": LAYER_MAP, "TextID": "vemap", "serviceName":MAP_SERVERS[VIRTUAL_EARTH],
"layerDir": "vemap", "layerName": LAYER_NAMES[LAYER_MAP]},
{"ID": LAYER_SAT, "TextID": "vesat", "serviceName":MAP_SERVERS[VIRTUAL_EARTH],
"layerDir": "vesat", "layerName": LAYER_NAMES[LAYER_SAT]},
{"ID": LAYER_TER, "TextID": "veter", "serviceName":MAP_SERVERS[VIRTUAL_EARTH],
"layerDir": "veter", "layerName": LAYER_NAMES[LAYER_TER]},

{"ID": LAYER_MAP, "TextID": "osmmap", "serviceName":MAP_SERVERS[OSM],
"layerDir": "osmTiles", "layerName": ""},
{"ID": LAYER_MAP, "TextID": "cmmap", "serviceName":MAP_SERVERS[CLOUDMADE],
"layerDir": "cloudmadeTiles", "layerName": ""},
{"ID": LAYER_MAP, "TextID": "ifwmap", "serviceName":MAP_SERVERS[INFO_FREEWAY],
"layerDir": "ifwTiles", "layerName": ""},
{"ID": LAYER_MAP, "TextID": "ocmmap", "serviceName":MAP_SERVERS[OPENCYCLEMAP],
"layerDir": "ocmTiles", "layerName": ""},
{"ID": LAYER_MAP, "TextID": "gmmmap", "serviceName":MAP_SERVERS[GOOGLE_MAKER],
"layerDir": "gmmTiles", "layerName": ""},
{"ID": LAYER_MAP, "TextID": "yandexmap", "serviceName":MAP_SERVERS[YANDEX],
"layerDir": "yandexTiles", "layerName": ""},
#Seznam.cz base
{"ID": LAYER_MAP, "TextID": "seznam_base", "serviceName": MAP_SERVERS[SEZNAM],
"layerDir": "seznambase", "layerName": "Mapa"},
{"ID": LAYER_SAT, "TextID": "seznam_satellite", "serviceName":MAP_SERVERS[SEZNAM],
"layerDir": "seznamsat", "layerName": "Letecká"},
{"ID": LAYER_TER, "TextID": "seznam_terrain", "serviceName": MAP_SERVERS[SEZNAM],
"layerDir": "seznamter", "layerName": "Stínování"},
{"ID": LAYER_HYB, "TextID": "seznam_hybrid", "serviceName": MAP_SERVERS[SEZNAM],
"layerDir": "seznamhybrid", "layerName": "Popisy"},
#Seznam.cz hiking
# it seems that hybrid layers work only with satelitte maps, that's why the map seznam_hiking
# is marked as satellite - I want to combine it with layer seznam_hiking_routes
{"ID": LAYER_SAT, "TextID": "seznam_hiking", "serviceName": MAP_SERVERS[SEZNAM_HIKING],
"layerDir": "seznamhiking", "layerName": "Mapa"},
{"ID": LAYER_TER, "TextID": "seznam_terrain", "serviceName": MAP_SERVERS[SEZNAM_HIKING],
"layerDir": "seznamter", "layerName": "Stínování"},
{"ID": LAYER_HYB, "TextID": "seznam_hiking_routes", "serviceName": MAP_SERVERS[SEZNAM_HIKING],
"layerDir": "seznamhikingroutes", "layerName": "Trasy"},
#Seznam.cz cyclo
# it seems that hybrid layers work only with satelitte maps, that's why the map seznam_cyclo
# is marked as satellite - I want to combine it with layer seznam_cyclo_routes
{"ID": LAYER_SAT, "TextID": "seznam_cyclo", "serviceName": MAP_SERVERS[SEZNAM_CYCLO],
"layerDir": "seznamcyclo", "layerName": "Mapa"},
{"ID": LAYER_TER, "TextID": "seznam_terrain", "serviceName": MAP_SERVERS[SEZNAM_CYCLO],
"layerDir": "seznamter", "layerName": "Stínování"},
{"ID": LAYER_HYB, "TextID": "seznam_cyclo_routes", "serviceName": MAP_SERVERS[SEZNAM_CYCLO],
"layerDir": "seznamcycloroutes", "layerName": "Trasy"},
#Seznam.cz historical
# it seems that hybrid layers work only with satelitte maps, that's why the map seznam_hist
# is marked as satellite - I want to combine it with layer seznam_hybrid
{"ID": LAYER_SAT, "TextID": "seznam_hist", "serviceName": MAP_SERVERS[SEZNAM_HIST],
"layerDir": "seznamhist", "layerName": "Mapa"},
{"ID": LAYER_TER, "TextID": "seznam_terrain", "serviceName": MAP_SERVERS[SEZNAM_HIST],
"layerDir": "seznamter", "layerName": "Stínování"},
{"ID": LAYER_HYB, "TextID": "seznam_hybrid", "serviceName": MAP_SERVERS[SEZNAM_HIST],
"layerDir": "seznamhybrid", "layerName": "Popisy"},
# Stamen map
{"ID": LAYER_MAP, "TextID": "stamen_toner", "serviceName":MAP_SERVERS[STAMEN],
"layerDir": "toner", "layerName": "Toner"},
{"ID": LAYER_SAT, "TextID": "stamen_water", "serviceName":MAP_SERVERS[STAMEN],
"layerDir": "watercolor", "layerName": "Watercolor"},
{"ID": LAYER_TER, "TextID": "stamen_terrain", "serviceName":MAP_SERVERS[STAMEN],
"layerDir": "terrain", "layerName": "Terrain"},
# Refuges.info
{"ID": LAYER_MAP, "TextID": "refhyk", "serviceName":MAP_SERVERS[REFUGES],
"layerDir": "hiking", "layerName": "Combined"},
{"ID": LAYER_SAT, "TextID": "refter", "serviceName":MAP_SERVERS[REFUGES],
"layerDir": "relief", "layerName": LAYER_NAMES[LAYER_TER]},
{"ID": LAYER_HYB, "TextID": "refonlyhyk", "serviceName":MAP_SERVERS[REFUGES],
"layerDir": "hiking_without_contours", "layerName": LAYER_NAMES[LAYER_HYB]},
# OpenSeaMap
{"ID": LAYER_MAP, "TextID": "openstreetmap", "serviceName":MAP_SERVERS[OPENSEAMAP],
"layerDir": "openseamap_map", "layerName": LAYER_NAMES[LAYER_MAP]},
{"ID": LAYER_HYB, "TextID": "openseamap", "serviceName":MAP_SERVERS[OPENSEAMAP],
"layerDir": "openseamap_hybrid", "layerName": LAYER_NAMES[LAYER_HYB]},
# Eniro
{"ID": LAYER_MAP, "TextID": "eniro", "serviceName":MAP_SERVERS[ENIRO],
"layerDir": "eniro_map", "layerName": LAYER_NAMES[LAYER_MAP]},
{"ID": LAYER_HYB, "TextID": "enirosea", "serviceName":MAP_SERVERS[ENIRO],
"layerDir": "eniro_hybrid", "layerName": LAYER_NAMES[LAYER_HYB]},
{"ID": GOOGLE, "layers": [LAYER_MAP,LAYER_SAT,LAYER_TER,LAYER_HYB]},
{"ID": YAHOO, "layers": [LAYER_MAP,LAYER_SAT,LAYER_HYB]},
{"ID": VIRTUAL_EARTH, "layers": [LAYER_MAP,LAYER_SAT,LAYER_TER]},
{"ID": OSM, "layers": [LAYER_MAP]},
{"ID": CLOUDMADE, "layers": [LAYER_MAP]},
{"ID": INFO_FREEWAY, "layers": [LAYER_MAP]},
{"ID": OPENCYCLEMAP, "layers": [LAYER_MAP]},
{"ID": GOOGLE_MAKER, "layers": [LAYER_MAP]},
{"ID": YANDEX, "layers": [LAYER_MAP]},
{"ID": SEZNAM, "layers": [LAYER_MAP,LAYER_SAT,LAYER_TER,LAYER_HYB]},
{"ID": SEZNAM_HIKING, "layers": [LAYER_SAT,LAYER_TER,LAYER_HYB]},
{"ID": SEZNAM_CYCLO, "layers": [LAYER_SAT,LAYER_TER,LAYER_HYB]},
{"ID": SEZNAM_HIST, "layers": [LAYER_SAT,LAYER_TER,LAYER_HYB]},
{"ID": STAMEN, "layers": [LAYER_MAP,LAYER_SAT,LAYER_TER]},
{"ID": REFUGES, "layers": [LAYER_MAP,LAYER_SAT,LAYER_HYB]},
{"ID": OPENSEAMAP, "layers": [LAYER_MAP,LAYER_HYB]},
{"ID": ENIRO, "layers": [LAYER_MAP,LAYER_HYB]},
]
HYB_SAT_LAYER_OFFSETS = {
"Google": 2,
"Yahoo": 1,
MAP_SERVERS[SEZNAM]: 2,
MAP_SERVERS[SEZNAM_HIKING]: 2,
MAP_SERVERS[SEZNAM_CYCLO]: 2,
MAP_SERVERS[SEZNAM_HIST]: 2,
MAP_SERVERS[REFUGES]: 2,
MAP_SERVERS[OPENSEAMAP]: 2,
MAP_SERVERS[ENIRO]: 2
}

NO_BULK_DOWN = ["Google", "OpenStreetMap", "OpenCycleMap"]
NO_GPS = ["Yahoo"]
NON_ONEDIR_COMBO_INDICES = {}

for name in MAP_SERVERS:
thelist = []
for el in MAP_SERVICES:
if el['serviceName'] == name:
thelist.append(el["ID"])
NON_ONEDIR_COMBO_INDICES[name] = thelist[:]

MAP_MAX_ZOOM_LEVEL = 17
MAP_MIN_ZOOM_LEVEL = -2
Expand Down Expand Up @@ -240,3 +137,4 @@
REGULAR_EXPRESSION = 3
ENTRY_SUB_MENU = ['Starts With...', 'Ends With...',
'Contains...', 'Regular Expression...']

5 changes: 1 addition & 4 deletions gmapcatcher/mapDownloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,7 @@ def query_tile(self, coord, layer, callback,
if layer == LAYER_HYB:
ret += self.query_tile(coord, LAYER_SAT, callback,
online, force_update, conf)
elif MAP_SERVICES[layer]['ID'] == LAYER_HYB:
ret += self.query_tile(coord, layer -
HYB_SAT_LAYER_OFFSETS[MAP_SERVICES[layer]['serviceName']],
callback, online, force_update, conf)

#print "query_tile(",coord,layer,callback,online,force_update,")"
world_tiles = mapUtils.tiles_on_level(coord[2])
coord = (mapUtils.mod(coord[0], world_tiles),
Expand Down
4 changes: 2 additions & 2 deletions gmapcatcher/mapServers/cloudMade.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ def layer_url_template(API_KEY):


## Returns the URL to the CloudMade tile
def get_url(counter, coord, conf, dimensions=256):
def get_url(counter, coord, layer, conf):
server = ['a', 'b', 'c']
return layer_url_template(conf.cloudMade_API) % (server[counter % 3],
conf.cloudMade_styleID, dimensions,
conf.cloudMade_styleID, 256,
MAP_MAX_ZOOM_LEVEL - coord[2], coord[0], coord[1])
2 changes: 1 addition & 1 deletion gmapcatcher/mapServers/googleMapMaker.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def layer_url_template(layer):


## Returns the URL to the Google Map Maker tile
def get_url(counter, coord):
def get_url(counter, coord, layer, conf):
return layer_url_template('gwm') % \
(counter, coord[0], coord[1], coord[2] + 1)

Expand Down
5 changes: 2 additions & 3 deletions gmapcatcher/mapServers/googleMaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@

known_layers = {}


## Returns a template URL for the GoogleMaps
def layer_url_template(layer, conf):
if layer not in known_layers:
map_server_query = {"gmap": "m", "ghyb": "h", "gsat": "k", "gter": "p"}
map_server_query = ["m", "k", "p", "h"]

oa = openanything.fetch(
'http://maps.google.com/maps?t=' + map_server_query[MAP_SERVICES[layer]["TextID"]])
'http://maps.google.com/maps?t=' + map_server_query[layer])

if oa['status'] != 200:
print "Trying to fetch http://maps.google.com/maps but failed"
Expand Down
2 changes: 1 addition & 1 deletion gmapcatcher/mapServers/informationFreeway.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def layer_url_template():


## Returns the URL to the informationFreeway tile
def get_url(counter, coord):
def get_url(counter, coord, layer, conf):
server = ['a', 'b', 'c']
return layer_url_template() % (server[counter % 3],
MAP_MAX_ZOOM_LEVEL - coord[2], coord[0], coord[1])
2 changes: 1 addition & 1 deletion gmapcatcher/mapServers/openCycleMap.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def layer_url_template():


## Returns the URL to the OpenCycleMap tile
def get_url(counter, coord):
def get_url(counter, coord, layer, conf):
server = ['a', 'b', 'c']
return layer_url_template() % (server[counter % 3],
MAP_MAX_ZOOM_LEVEL - coord[2], coord[0], coord[1])
2 changes: 1 addition & 1 deletion gmapcatcher/mapServers/openStreetMaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def layer_url_template():


## Returns the URL to the openStreetMaps tile
def get_url(counter, coord):
def get_url(counter, coord, layer, conf):
server = ['a', 'b', 'c']
return layer_url_template() % (server[counter % 3],
MAP_MAX_ZOOM_LEVEL - coord[2], coord[0], coord[1])
4 changes: 2 additions & 2 deletions gmapcatcher/mapServers/refugesInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def layer_url_template():


## Returns the URL to the Stamen tile
def get_url(counter, layer_name, coord):
def get_url(counter, coord, layer, conf):
# server = ['', 'a.', 'b.', 'c.', 'd.']
return layer_url_template() % (layer_name,
return layer_url_template() % (layer,
MAP_MAX_ZOOM_LEVEL - coord[2], coord[0], coord[1])
19 changes: 1 addition & 18 deletions gmapcatcher/mapServers/seznam.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,27 +108,10 @@ def layer_url_template(layername):
return 'http://m%i.mapserver.mapy.cz/' + layername + '/%i_%x_%x'


def get_url_base(counter, coord, layer):
def get_url(counter, coord, layer, conf):
layer_names = ["base-n", "ophoto", "relief-l", "hybrid"]
return get_url_internal(counter, coord, layer_names[layer])

get_url = get_url_base # provide some default method get_url


def get_url_hiking(counter, coord, layer):
layer_names = ["turist", "turist", "relief-l", "ttur"]
return get_url_internal(counter, coord, layer_names[layer])


def get_url_cyclo(counter, coord, layer):
layer_names = ["turist", "turist", "relief-l", "tcyklo"]
return get_url_internal(counter, coord, layer_names[layer])


def get_url_hist(counter, coord, layer):
layer_names = ["army2", "army2", "relief-l", "hybrid"]
return get_url_internal(counter, coord, layer_names[layer])


def get_url_internal(counter, coord, layername):
#The recomputation of the coordinates gives bad results, but at least the whole
Expand Down
11 changes: 11 additions & 0 deletions gmapcatcher/mapServers/seznamCyclo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
## @package gmapcatcher.mapServers.seznamCyclo
# All the interaction with mapy.cz (mapy.seznam.cz)

from seznam import get_url_internal


def get_url(counter, coord, layer, conf):
layer_names = ["turist", "turist", "relief-l", "tcyklo"]
return get_url_internal(counter, coord, layer_names[layer])

12 changes: 12 additions & 0 deletions gmapcatcher/mapServers/seznamHiking.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
## @package gmapcatcher.mapServers.seznamHiking
# All the interaction with mapy.cz (mapy.seznam.cz)

from seznam import get_url_internal


def get_url(counter, coord, layer, conf):
layer_names = ["turist", "turist", "relief-l", "ttur"]
return get_url_internal(counter, coord, layer_names[layer])


12 changes: 12 additions & 0 deletions gmapcatcher/mapServers/seznamHist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
## @package gmapcatcher.mapServers.seznamHist
# All the interaction with mapy.cz (mapy.seznam.cz)

from seznam import get_url_internal


def get_url(counter, coord, layer, conf):
layer_names = ["army2", "army2", "relief-l", "hybrid"]
return get_url_internal(counter, coord, layer_names[layer])


4 changes: 2 additions & 2 deletions gmapcatcher/mapServers/stamenMaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def layer_url_template():


## Returns the URL to the Stamen tile
def get_url(counter, layer_name, coord):
def get_url(counter, coord, layer, conf):
server = ['', 'a.', 'b.', 'c.', 'd.']
return layer_url_template() % (server[counter % 5], layer_name,
return layer_url_template() % (server[counter % 5], layer,
MAP_MAX_ZOOM_LEVEL - coord[2], coord[0], coord[1])
2 changes: 1 addition & 1 deletion gmapcatcher/mapServers/virtualEarth.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def layer_url_template(layer):


## Returns the URL to the virtualEarth tile
def get_url(counter, coord, layer):
def get_url(counter, coord, layer, conf):
version = 392
return layer_url_template(layer) % (counter, tile_to_quadkey(coord), version)

Expand Down
2 changes: 1 addition & 1 deletion gmapcatcher/mapServers/yahoo.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def layer_url_template(layer):


## Returns the URL to the Yahoo map tile
def get_url(counter, coord, layer):
def get_url(counter, coord, layer, conf):
#server = ['a', 'b', 'c']
return layer_url_template(layer) % (
coord[0],
Expand Down
2 changes: 1 addition & 1 deletion gmapcatcher/mapServers/yandex.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ def layer_url_template():


## Returns the URL to the yandex tile
def get_url(counter, coord):
def get_url(counter, coord, layer, conf):
return layer_url_template() % (counter + 1,
coord[0], coord[1], MAP_MAX_ZOOM_LEVEL - coord[2])
Loading

0 comments on commit 266a290

Please sign in to comment.