В процессе. Исправление отображение карты для граничных областей

This commit is contained in:
sasha80
2023-11-24 09:02:55 +03:00
parent 80f462261c
commit 6e00101e82
6 changed files with 73 additions and 23 deletions

View File

@@ -23,7 +23,7 @@ config/map_bcs=Vector3(0.5, 1.5, 0.3)
config/map_tile_size=256 config/map_tile_size=256
config/map_image_hight=512 config/map_image_hight=512
config/map_image_width=512 config/map_image_width=512
config/map_minimum_zoom=5 config/map_minimum_zoom=3
config/map_maximum_zoom=19 config/map_maximum_zoom=19
config/map_server_addr="https://b.tile.openstreetmap.org" config/map_server_addr="https://b.tile.openstreetmap.org"

View File

@@ -22,6 +22,10 @@ var TEST_DATA: = {
'Мехико': [ -99.12766, 19.42847 ], 'Мехико': [ -99.12766, 19.42847 ],
'Белое море': [ 68.136606, 42.045546 ], 'Белое море': [ 68.136606, 42.045546 ],
'море Беллинсгаузена': [ -72.406587, -74.857997 ], 'море Беллинсгаузена': [ -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 ] } 'Море' : [ 19.4, 54.91 ] }
@@ -35,7 +39,6 @@ var map_zoom: int ## Уровень детализации кар
var map_rects: Array[Rect2i] ## Занятые плиткой области изображения карты var map_rects: Array[Rect2i] ## Занятые плиткой области изображения карты
var map_tile: Rect2i ## Область одной плитки: [x-координата области, y-координата области, x-индекс плитки, y-индекс плитки] var map_tile: Rect2i ## Область одной плитки: [x-координата области, y-координата области, x-индекс плитки, y-индекс плитки]
var prev_tiles_dic = {} ## var prev_tiles_dic = {} ##
var map_done: bool ##
func _ready(): func _ready():
@@ -50,7 +53,6 @@ func _ready():
map_server_addr = ProjectSettings.get_setting('application/config/map_server_addr') map_server_addr = ProjectSettings.get_setting('application/config/map_server_addr')
var map_tile_size = ProjectSettings.get_setting('application/config/map_tile_size', 256) 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_tile = Rect2i(0, 0, map_tile_size, map_tile_size)
map_done = true
signaller.connect('zoom_changed', Callable(self, '_on_zoom_changed')) 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: if map_tile_stack.size() != 0:
return return
map_zoom = zoom map_zoom = zoom
var ll = TEST_DATA['Мехико'] var ll = TEST_DATA['Фиджи']
var tile: = mercator.create_tile(ll[0], ll[1], zoom) var tile: = mercator.create_tile(ll[0], ll[1], zoom)
map_tile_stack.clear() map_tile_stack.clear()
map_tile_stack.append(tile) map_tile_stack.append(tile)
@@ -90,22 +92,24 @@ func _process(_delta: float):
if request_tile(tile, map_server_addr) == OK: if request_tile(tile, map_server_addr) == OK:
map_tile_state = TASK_STATE.WAIT map_tile_state = TASK_STATE.WAIT
else: else:
push_error('Ошибка: Невозможно сформировать запрос HTTP') log.error('Ошибка: Невозможно сформировать запрос HTTP')
map_tile_state = TASK_STATE.ERROR map_tile_state = TASK_STATE.ERROR
elif map_tile_state == TASK_STATE.CHECK: elif map_tile_state == TASK_STATE.CHECK:
var root_rect: Rect2i = map_rects[0] var root_rect: Rect2i = map_rects[0]
var root_tile: = mercator.Tile.new(root_rect.size.x, root_rect.size.y, map_zoom) 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 = {} var neighbors_tiles_dic = {}
for tile in neighbors_tiles: 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: if neighbors_tiles_dic != prev_tiles_dic:
for tile in neighbors_tiles: for tile in neighbors_tiles:
tile.is_root = false tile.is_root = false
map_tile_stack.push_front(tile) map_tile_stack.push_front(tile)
prev_tiles_dic[str(tile)] = false prev_tiles_dic[[tile.x, tile.y]] = false
else: else:
signaller.emit_signal('zoom_complete', map_zoom) 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 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() var tile = map_tile_stack.pop_back()
map_tile_state = TASK_STATE.CHECK map_tile_state = TASK_STATE.CHECK
if tile.is_root: if tile.is_root:
# Отображение корневой плитки # Отображение корневой плитки
map_image.fill(Color(0, 0, 0, 0)) map_image.fill(Color(0, 0, 0, 0))
map_rects.clear() # очистить список занятых областей изображения карты map_rects.clear() # Очистить список занятых областей изображения карты
var bounds: = mercator.bounds(tile) var bounds: = mercator.bounds(tile)
var lng_c = (bounds.east + bounds.west) / 2.0 var lng_c = (bounds.east + bounds.west) / 2.0
var lat_c = (bounds.north + bounds.south) / 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 sx: float = float(map_tile.size.x) / (bounds.east - bounds.west) * (lng_c - tile.lng) + map_tile.size.x / 2 # Cмещение в пискселях центра плитки от заданной точки по горизонтали.
var sy = map_tile.size.y / (bounds.north - bounds.south) * (lat_c - tile.lat) - map_tile.size.y / 2.0 # 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(sx, -sy) var dst_pos: Vector2i = Vector2i(sx, -sy)
img_tile_to_map_image(img_tile, dst_pos, tile) img_tile_to_map_image(img_tile, dst_pos, tile)
else: else:
# Отображение соседних плиток # Отображение соседних плиток
var root_rect: Rect2i = map_rects[0] # Получить корневую плитку 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 dy: int = tile.y - root_rect.size.y
var dst_pos: Vector2i = root_rect.position + Vector2i(dx, dy) * map_tile.size var dst_pos: Vector2i = root_rect.position + Vector2i(dx, dy) * map_tile.size
img_tile_to_map_image(img_tile, dst_pos, tile) img_tile_to_map_image(img_tile, dst_pos, tile)

View File

@@ -131,7 +131,7 @@ offset_left = 952.0
offset_top = 1038.0 offset_top = 1038.0
offset_right = 1104.0 offset_right = 1104.0
offset_bottom = 1056.0 offset_bottom = 1056.0
metadata/zoom = 4 metadata/zoom = 2
[node name="canvas" parent="." instance=ExtResource("11_b6su4")] [node name="canvas" parent="." instance=ExtResource("11_b6su4")]

View File

@@ -40,6 +40,21 @@ class Tile:
return false 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: class LngLat:
var lng: float = 0.0 ## Долгота в десятичных градусах восточной долготы. var lng: float = 0.0 ## Долгота в десятичных градусах восточной долготы.
@@ -287,18 +302,43 @@ func lnglat(x: float, y: float, truncate: bool = false) -> LngLat:
## [/codeblock] ## [/codeblock]
func neighbors(tile: Tile) -> Array: func neighbors(tile: Tile) -> Array:
var tiles: = [] var tiles: = []
var hi = 2 ** tile.z - 1
for i in [-1, 0, 1]: for i in [-1, 0, 1]:
for j in [-1, 0, 1]: for j in [-1, 0, 1]:
if i == 0 and j == 0: if i == 0 and j == 0:
continue 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) var t = Tile.new(tile.x + i, tile.y + j, tile.z)
if t.is_valid(): t.fix_xy()
tiles.append(t) 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 return tiles

View File

@@ -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 - если иначе ## Возвращает true, если val число, false - если иначе
func type_is_num(val) -> bool: return (typeof(val) == TYPE_INT) or (typeof(val) == typeof(0.0)) func type_is_num(val) -> bool: return (typeof(val) == TYPE_INT) or (typeof(val) == typeof(0.0))

View File

@@ -9,6 +9,7 @@ const vec2 center = vec2(0.5, 0.5);
void fragment() 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);
} }