В процессе. Исправление отображение карты для граничных областей
This commit is contained in:
@@ -23,7 +23,7 @@ config/map_bcs=Vector3(0.5, 1.5, 0.3)
|
||||
config/map_tile_size=256
|
||||
config/map_image_hight=512
|
||||
config/map_image_width=512
|
||||
config/map_minimum_zoom=5
|
||||
config/map_minimum_zoom=3
|
||||
config/map_maximum_zoom=19
|
||||
config/map_server_addr="https://b.tile.openstreetmap.org"
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ var TEST_DATA: = {
|
||||
'Мехико': [ -99.12766, 19.42847 ],
|
||||
'Белое море': [ 68.136606, 42.045546 ],
|
||||
'море Беллинсгаузена': [ -72.406587, -74.857997 ],
|
||||
'Фиджи': [ 178.065032, -17.713371 ],
|
||||
'Ноль': [ 0.0, 0.0 ],
|
||||
'Точка1': [ 170.0, 0.0 ],
|
||||
'Точка2': [-170.0, 0.0 ],
|
||||
'Море' : [ 19.4, 54.91 ] }
|
||||
|
||||
|
||||
@@ -35,7 +39,6 @@ var map_zoom: int ## Уровень детализации кар
|
||||
var map_rects: Array[Rect2i] ## Занятые плиткой области изображения карты
|
||||
var map_tile: Rect2i ## Область одной плитки: [x-координата области, y-координата области, x-индекс плитки, y-индекс плитки]
|
||||
var prev_tiles_dic = {} ##
|
||||
var map_done: bool ##
|
||||
|
||||
|
||||
func _ready():
|
||||
@@ -50,7 +53,6 @@ func _ready():
|
||||
map_server_addr = ProjectSettings.get_setting('application/config/map_server_addr')
|
||||
var map_tile_size = ProjectSettings.get_setting('application/config/map_tile_size', 256)
|
||||
map_tile = Rect2i(0, 0, map_tile_size, map_tile_size)
|
||||
map_done = true
|
||||
signaller.connect('zoom_changed', Callable(self, '_on_zoom_changed'))
|
||||
|
||||
|
||||
@@ -66,7 +68,7 @@ func _on_zoom_changed(zoom: int):
|
||||
if map_tile_stack.size() != 0:
|
||||
return
|
||||
map_zoom = zoom
|
||||
var ll = TEST_DATA['Мехико']
|
||||
var ll = TEST_DATA['Фиджи']
|
||||
var tile: = mercator.create_tile(ll[0], ll[1], zoom)
|
||||
map_tile_stack.clear()
|
||||
map_tile_stack.append(tile)
|
||||
@@ -90,22 +92,24 @@ func _process(_delta: float):
|
||||
if request_tile(tile, map_server_addr) == OK:
|
||||
map_tile_state = TASK_STATE.WAIT
|
||||
else:
|
||||
push_error('Ошибка: Невозможно сформировать запрос HTTP')
|
||||
log.error('Ошибка: Невозможно сформировать запрос HTTP')
|
||||
map_tile_state = TASK_STATE.ERROR
|
||||
elif map_tile_state == TASK_STATE.CHECK:
|
||||
var root_rect: Rect2i = map_rects[0]
|
||||
var root_tile: = mercator.Tile.new(root_rect.size.x, root_rect.size.y, map_zoom)
|
||||
var neighbors_tiles = mercator.neighbors(root_tile)
|
||||
var neighbors_tiles = mercator.get_perimetr_tiles(root_tile, (map_image.get_size().x / map_tile.size.x) / 1) # = mercator.neighbors(root_tile)
|
||||
var neighbors_tiles_dic = {}
|
||||
for tile in neighbors_tiles:
|
||||
neighbors_tiles_dic[str(tile)] = false
|
||||
neighbors_tiles_dic[[tile.x, tile.y]] = false
|
||||
if neighbors_tiles_dic != prev_tiles_dic:
|
||||
for tile in neighbors_tiles:
|
||||
tile.is_root = false
|
||||
map_tile_stack.push_front(tile)
|
||||
prev_tiles_dic[str(tile)] = false
|
||||
prev_tiles_dic[[tile.x, tile.y]] = false
|
||||
else:
|
||||
if map_tile_stack.size() == 0:
|
||||
signaller.emit_signal('zoom_complete', map_zoom)
|
||||
print_debug('zoom_complete: %s' % [map_rects])
|
||||
map_tile_state = TASK_STATE.DONE
|
||||
|
||||
|
||||
@@ -124,21 +128,22 @@ func _map_request_completed(result, response_code, headers, data):
|
||||
|
||||
var tile = map_tile_stack.pop_back()
|
||||
map_tile_state = TASK_STATE.CHECK
|
||||
|
||||
if tile.is_root:
|
||||
# Отображение корневой плитки
|
||||
map_image.fill(Color(0, 0, 0, 0))
|
||||
map_rects.clear() # очистить список занятых областей изображения карты
|
||||
map_rects.clear() # Очистить список занятых областей изображения карты
|
||||
var bounds: = mercator.bounds(tile)
|
||||
var lng_c = (bounds.east + bounds.west) / 2.0
|
||||
var lat_c = (bounds.north + bounds.south) / 2.0
|
||||
var sx = map_tile.size.x / (bounds.east - bounds.west) * (lng_c - tile.lng) + map_tile.size.x / 2.0 # Cмещение в пискселях центра плитки от заданной точки по горизонтали.
|
||||
var sy = map_tile.size.y / (bounds.north - bounds.south) * (lat_c - tile.lat) - map_tile.size.y / 2.0 # Cмещение в пискселях центра плитки от заданной точки по вертикали.
|
||||
var dst_pos = Vector2i(sx, -sy)
|
||||
var sx: float = float(map_tile.size.x) / (bounds.east - bounds.west) * (lng_c - tile.lng) + map_tile.size.x / 2 # Cмещение в пискселях центра плитки от заданной точки по горизонтали.
|
||||
var sy: float = float(map_tile.size.y) / (bounds.north - bounds.south) * (lat_c - tile.lat) - map_tile.size.y / 2 # Cмещение в пискселях центра плитки от заданной точки по вертикали.
|
||||
var dst_pos: Vector2i = Vector2i(sx, -sy)
|
||||
img_tile_to_map_image(img_tile, dst_pos, tile)
|
||||
else:
|
||||
# Отображение соседних плиток
|
||||
var root_rect: Rect2i = map_rects[0] # Получить корневую плитку
|
||||
var dx: int = tile.x - root_rect.size.x # Вычислить положение дочерней плитки относительно корневой
|
||||
var dx: int = tile.x - root_rect.size.x # Вычислить смещение дочерней плитки относительно корневой
|
||||
var dy: int = tile.y - root_rect.size.y
|
||||
var dst_pos: Vector2i = root_rect.position + Vector2i(dx, dy) * map_tile.size
|
||||
img_tile_to_map_image(img_tile, dst_pos, tile)
|
||||
|
||||
@@ -131,7 +131,7 @@ offset_left = 952.0
|
||||
offset_top = 1038.0
|
||||
offset_right = 1104.0
|
||||
offset_bottom = 1056.0
|
||||
metadata/zoom = 4
|
||||
metadata/zoom = 2
|
||||
|
||||
[node name="canvas" parent="." instance=ExtResource("11_b6su4")]
|
||||
|
||||
|
||||
@@ -40,6 +40,21 @@ class Tile:
|
||||
return false
|
||||
|
||||
|
||||
func _bound_index(index: int) -> int:
|
||||
var mi: int = 2 ** self.z
|
||||
if index < 0:
|
||||
index *= -1
|
||||
index %= mi
|
||||
index = mi - index
|
||||
else:
|
||||
index %= mi
|
||||
return index
|
||||
|
||||
func fix_xy():
|
||||
self.x = _bound_index(self.x)
|
||||
self.y = _bound_index(self.y)
|
||||
|
||||
|
||||
## Пара долготы и широты.
|
||||
class LngLat:
|
||||
var lng: float = 0.0 ## Долгота в десятичных градусах восточной долготы.
|
||||
@@ -287,17 +302,42 @@ func lnglat(x: float, y: float, truncate: bool = false) -> LngLat:
|
||||
## [/codeblock]
|
||||
func neighbors(tile: Tile) -> Array:
|
||||
var tiles: = []
|
||||
var hi = 2 ** tile.z - 1
|
||||
for i in [-1, 0, 1]:
|
||||
for j in [-1, 0, 1]:
|
||||
if i == 0 and j == 0:
|
||||
continue
|
||||
elif (tile.x + i) < 0 or (tile.y + j) < 0:
|
||||
continue
|
||||
elif (tile.x + i) > hi or (tile.y + j) > hi:
|
||||
continue
|
||||
var t = Tile.new(tile.x + i, tile.y + j, tile.z)
|
||||
if t.is_valid():
|
||||
t.fix_xy()
|
||||
tiles.append(t)
|
||||
return tiles
|
||||
|
||||
|
||||
## Возвращает все плитки вокруг заданной плитки
|
||||
func get_allaround_tiles(tile: Tile, mr: int = 1) -> Array:
|
||||
var xys = {}
|
||||
var mi: int = 2 ** tile.z
|
||||
for r in mr:
|
||||
for a in range(0, 360, 180 / mi):
|
||||
var ra = radians(a)
|
||||
var ix = int(roundf(r * cos(ra))) + tile.x
|
||||
var iy = int(roundf(r * sin(ra))) + tile.y
|
||||
var t = Tile.new(ix, iy, tile.z)
|
||||
t.fix_xy()
|
||||
xys[[t.x, t.y]] = false
|
||||
var tiles = []
|
||||
for txy in xys.keys():
|
||||
tiles.append(Tile.new(txy[0], txy[1], tile.z))
|
||||
return tiles
|
||||
|
||||
|
||||
## Возвращает все плитки по периметру заданной плитки
|
||||
func get_perimetr_tiles(tile: Tile, mr: int = 1) -> Array:
|
||||
var tiles = []
|
||||
for i in range(-mr, mr + 1):
|
||||
for j in range(-mr, mr + 1):
|
||||
if i == 0 and j == 0: continue
|
||||
var t = Tile.new(i + tile.x, j + tile.y, tile.z)
|
||||
t.fix_xy()
|
||||
tiles.append(t)
|
||||
return tiles
|
||||
|
||||
|
||||
@@ -3,6 +3,10 @@ extends Node
|
||||
## Простые часто используемые функции
|
||||
|
||||
|
||||
## Возвращает округлённое значение [param v] с точностью [param a]
|
||||
func round_to(v: float, a: float) -> float: return snappedf(v, -a if v < 0 else a)
|
||||
|
||||
|
||||
## Возвращает true, если val число, false - если иначе
|
||||
func type_is_num(val) -> bool: return (typeof(val) == TYPE_INT) or (typeof(val) == typeof(0.0))
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ const vec2 center = vec2(0.5, 0.5);
|
||||
|
||||
void fragment()
|
||||
{
|
||||
COLOR = texture(TEXTURE, UV);// * smooth_px(length(UV - center), radius, DS);
|
||||
COLOR = texture(TEXTURE, UV);
|
||||
//COLOR.a *= smooth_px(length(UV - center), radius, DS);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user