В процессе. Карта отображается. Ошибка: накапливаются запросы на получение карты.

This commit is contained in:
sasha80
2023-11-13 10:21:17 +03:00
parent c067e36e6f
commit 892cfabfda
11 changed files with 213 additions and 121 deletions

View File

@@ -19,8 +19,11 @@ boot_splash/show_image=false
boot_splash/fullsize=false
boot_splash/use_filter=false
config/icon="res://data/icon.png"
config/map_addr="https://a.tile.openstreetmap.org"
config/map_bcs=Vector3(0.5, 1.8, 0.3)
config/map_server_addr="https://a.tile.openstreetmap.org"
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
[autoload]
@@ -38,7 +41,7 @@ yemsboards="*res://scripts/yemsboards.gd"
yemsconsts="*res://scripts/yems-consts.gd"
interfer="*res://scripts/interfer.gd"
hotkeys="*res://scripts/hotkeys.gd"
mercantile="*res://scripts/mercator.gd"
mercator="*res://scripts/mercator.gd"
[debug]
@@ -71,6 +74,10 @@ version_control/autoload_on_startup=true
enabled=PackedStringArray()
[global]
map_server_addr=false
[gui]
common/text_edit_undo_stack_max_size=10

View File

@@ -11,9 +11,9 @@ action_mode = 0
texture_normal = ExtResource("1_r871k")
ignore_texture_size = true
stretch_mode = 0
metadata/i_scale = 0
metadata/prefix = "Масштаб:"
metadata/scales = [10.0, 20.0, 50.0, 100.0, 250.0]
metadata/prefix = "Детализация:"
metadata/i_zoom = 0
metadata/zooms = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[node name="lbl" type="Label" parent="."]
layout_mode = 0

View File

@@ -1,62 +1,119 @@
extends Sprite2D
## Состояния КА карты
enum TILE_STATE {
IDLE, ## Покой
WAIT, ## Ожидание
DONE, ## Выполнено
ERROR ## Ошибка
## Возможные состояния конечного автомата заданий
enum TASK_STATE {
DONE, ## Выполнено
WAIT, ## Ожидание плитки
RUN, ## Запуск выполнения
CHECK, ## Проверка пустого места
ERROR ## Ошибка
}
var curent_map_tile: Vector3i ## Текущая запрошенная плитка
var curent_state: TILE_STATE = TILE_STATE.IDLE ## Текущее состояние КА карты
var image: Image ## Изображение с картой
var map_bcs: Vector3 ## Яркость, контраст насыщенность
## Координаты для проверок [lng, lat]
var TEST_DATA: = {
'Калиниград': [ 20.51095, 54.70649 ],
'Москва': [ 37.6156, 55.7522 ],
'Нью-Йорк': [ -74.006, 40.7143 ],
'Сидней': [ 151.20732, -33.8678500 ],
'Таганрог': [ 38.8969, 47.2362 ],
'Хельсинки': [ 24.9354, 60.1695 ],
'Азорские о-ва': [ 28.3996582, 38.5397568 ],
'Мехико': [ -99.12766, 19.42847 ],
'Белое море': [ 68.136606, 42.045546 ],
'море Беллинсгаузена': [ -72.406587, -74.857997 ],
'Море' : [ 19.4, 54.91 ] }
var map_image: Image ## Изображение с картой
var map_tile_state: TASK_STATE ## Текущее состояние конечного автомата плитки
var map_bcs: Vector3 ## Яркость, контраст насыщенность
var map_server_addr: String ## Адрес сервера изображений карт в проекции Меркатора
var map_tile_stack: Array ## Стек для хранения плиток карты
var map_request: HTTPRequest ## Обработчик запросов http
var map_zoom: int ## Уровень детализации карты
var map_rects: Array[Rect2i] ## Занятые плиткой области изображения карты
var map_tile: Rect2i ## Область одной плитки: [x-координата области, y-координата области, x-индекс плитки, y-индекс плитки]
func _ready():
# Create an HTTP request node and connect its completion signal.
var tile = mercantile.Tile.new()
print_debug('Плитка: %s %s' % [tile, tile.is_valid()])
var http_request = HTTPRequest.new()
add_child(http_request)
http_request.request_completed.connect(self._http_request_completed)
curent_map_tile = Vector3i(0, 0, 0)
image = Image.create(512, 512, true, Image.FORMAT_RGB8)
map_tile_state = TASK_STATE.DONE
map_request = HTTPRequest.new()
add_child(map_request)
map_request.request_completed.connect(self._map_request_completed)
var map_image_width = ProjectSettings.get_setting('application/config/map_image_width', 512)
var map_image_hight = ProjectSettings.get_setting('application/config/map_image_hight', 512)
map_image = Image.create(map_image_width, map_image_hight, true, Image.FORMAT_RGB8)
map_bcs = ProjectSettings.get_setting('application/config/map_bcs', Vector3(1.0, 1.0, 1.0))
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)
signaller.connect('zoom_changed', Callable(self, '_on_zoom_changed'))
var error = http_request.request('https://a.tile.openstreetmap.org/0/0/0.png')
if error == OK:
curent_state = TILE_STATE.WAIT
else:
push_error('Ошибка: Не возможно сформировать запрос HTTP')
curent_state = TILE_STATE.ERROR
func _on_zoom_changed(zoom: int):
map_zoom = zoom
var tile: = mercator.create_tile(TEST_DATA['Таганрог'][0], TEST_DATA['Таганрог'][1], zoom)
map_tile_stack.push_front(tile)
func request_tile(tile: mercator.Tile, server_addr: String) -> Error:
var tile_addr: = '%s/%d/%d/%d.png' % [server_addr, tile.z, tile.x , tile.y]
return map_request.request(tile_addr)
func _process(delta: float):
pass
if (map_tile_state == TASK_STATE.DONE) and map_tile_stack.size():
var tile: mercator.Tile = map_tile_stack[-1]
if request_tile(tile, map_server_addr) == OK:
map_tile_state = TASK_STATE.WAIT
else:
push_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)
for tile in neighbors_tiles:
tile.is_root = false
map_tile_stack.push_front(tile)
map_tile_state = TASK_STATE.DONE
func _http_request_completed(result, response_code, headers, data):
func _map_request_completed(result, response_code, headers, data):
if result != HTTPRequest.RESULT_SUCCESS:
push_error('Ошибка: запрос не обработан: %s' % result)
curent_state = TILE_STATE.ERROR
log.error('Запрос не обработан. result:\"%s\" response_code:\"%s\", headers:\"%s\"' % [result, response_code, headers])
map_tile_state = TASK_STATE.ERROR
return
var image0 = Image.new()
var error = image0.load_png_from_buffer(data)
var img_tile = Image.new()
var error = img_tile.load_png_from_buffer(data)
if error != OK:
push_error('Ошибка: Полученые данные невозможно использовать для формироания изображения')
curent_state = TILE_STATE.ERROR
log.error('Полученые данные невозможно использовать для формироания изображения. result:\"%s\" response_code:\"%s\", headers:\"%s\"' % [result, response_code, headers])
map_tile_state = TASK_STATE.ERROR
return
curent_state = TILE_STATE.DONE
var tile_size = image0.get_size()
image.blit_rect(image0, Rect2i(0, 0, tile_size.x, tile_size.y), Vector2i( 0, 0))
image.blit_rect(image0, Rect2i(0, 0, tile_size.x, tile_size.y), Vector2i(tile_size.x, 0))
image.blit_rect(image0, Rect2i(0, 0, tile_size.x, tile_size.y), Vector2i( 0, tile_size.y))
image.blit_rect(image0, Rect2i(0, 0, tile_size.x, tile_size.y), Vector2i(tile_size.y, tile_size.y))
image.adjust_bcs(map_bcs.x, map_bcs.y, map_bcs.z)
texture = ImageTexture.create_from_image(image)
print_debug(map_tile_stack)
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() # очистить список занятых областей изображения карты
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 # смещение в пискселях центра плитки от заданной точки по горизонтали
var sy = map_tile.size.y / (bounds.north - bounds.south) * (lat_c - tile.lat) - map_tile.size.y / 2.0 # смещение в пискселях центра плитки от заданной точки по вертикали
var dst_pos = Vector2i(sx, -sy)
map_image.blit_rect(img_tile, map_tile, dst_pos)
map_rects.append(Rect2i(dst_pos.x, dst_pos.y, tile.x, tile.y)) # сохранить корневую плитку
else:
# Отображение соседних плиток
var root_rect: Rect2i = map_rects[0] # Получить корневую плитку
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
map_image.blit_rect(img_tile, map_tile, dst_pos)
map_rects.append(Rect2i(dst_pos.x, dst_pos.y, tile.x, tile.y))
texture = ImageTexture.create_from_image(map_image)

View File

@@ -6,9 +6,7 @@
[sub_resource type="ShaderMaterial" id="ShaderMaterial_pmqvj"]
resource_local_to_scene = true
shader = ExtResource("1_tsdui")
shader_parameter/center = Vector2(0.5, 0.5)
shader_parameter/radius = 0.4
shader_parameter/rotation = 0.0
[node name="tilemap" type="Sprite2D"]
material = SubResource("ShaderMaterial_pmqvj")

View File

@@ -64,6 +64,7 @@ func _ready():
threats.connect('threat_lost', Callable(self, 'on_threat_lost'))
threats.connect('threats_resized', Callable(self, 'on_threats_resized'))
threats.connect('threat_update', Callable(self, 'on_threat_update'))
signaller.emit_signal('zoom_changed', 0)
## Производит отображение цели на диаграмму
@@ -175,12 +176,11 @@ func _input(event) -> void:
shift_pressed = event.pressed
## Изменяет масштаб
## Изменяет детализацию
func _on_btn_scale_pressed() -> void:
var i_scale = $btn_scale.get_meta('i_scale')
var zoom = $btn_scale.get_meta('zoom')
var prefix = $btn_scale.get_meta('prefix')
var scales = $btn_scale.get_meta('scales')
i_scale += 1
i_scale %= scales.size()
$btn_scale.set_meta('i_scale', i_scale)
$btn_scale/lbl.text = '%s %.0f км' % [prefix, scales[i_scale]]
zoom = (zoom + 1) % 20
$btn_scale.set_meta('zoom', zoom)
$btn_scale/lbl.text = '%s %d' % [prefix, zoom]
signaller.emit_signal('zoom_changed', zoom)

View File

@@ -12,10 +12,10 @@
[ext_resource type="PackedScene" uid="uid://bbq6nklh36yij" path="res://scenes/tilemap.tscn" id="10_wpi4s"]
[ext_resource type="Shader" path="res://shaders/tilemap.gdshader" id="11_7ohqv"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_whr8j"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_6tiyy"]
resource_local_to_scene = true
shader = ExtResource("11_7ohqv")
shader_parameter/radius = 0.4
shader_parameter/radius = 0.39
[node name="Работа" type="Panel"]
script = ExtResource("1_vmjjl")
@@ -44,6 +44,9 @@ offset_right = 1594.0
offset_bottom = 1170.0
metadata/_edit_lock_ = true
[node name="tilemap" parent="." instance=ExtResource("10_wpi4s")]
material = SubResource("ShaderMaterial_6tiyy")
[node name="canvas" parent="." instance=ExtResource("7_pvt8f")]
metadata/_edit_lock_ = true
@@ -131,9 +134,7 @@ offset_left = 952.0
offset_top = 1038.0
offset_right = 1104.0
offset_bottom = 1056.0
[node name="tilemap" parent="." instance=ExtResource("10_wpi4s")]
material = SubResource("ShaderMaterial_whr8j")
metadata/zoom = 0
[connection signal="drag_begin" from="." to="." method="_on_drag_begin"]
[connection signal="drag_continue" from="." to="." method="_on_drag_continue"]

View File

@@ -2,12 +2,14 @@ extends Node
## Веб-утилиты для работы с меркаторскими XYZ-плитками.
const R2D: = 180.0 / PI
const RE: = 6378137.0
const CE: = 2.0 * PI * RE
const EPSILON: = 1e-14
const LL_EPSILON: = 1e-11
const MAX_ZOOM: = 28
const R2D: = 180.0 / PI
const RE: = 6378137.0 ## Радиус Земли в метрах
const CE: = 2.0 * PI * RE ## Длина окружности Земли в метрах
const EPSILON: = 1e-14
const LL_EPSILON: = 1e-11
const MAX_ZOOM: = 20
const MAX_NORTH = 85.051129
const MAX_SOUTH = -85.051129
## XYZ-плитка веб-меркатора [param x], [param y], [param z] индексы
@@ -16,15 +18,19 @@ class Tile:
var x: int
var y: int
var z: int
var lng: float ## Координаты, которые плитка должна покрывать, долгота, градусы
var lat: float ## Широта, градусы
var is_root: bool ## Признак, что плитка корневая (покрывает координаты)
func as_array(): return [self.x, self.y, self.z]
func _to_string() -> String: return '[%d, %d, %d]' % [self.x, self.y, self.z]
func _init(x0: int = 0, y0: int = 0, z0: int = 0):
func _init(x0: int = 0, y0: int = 0, z0: int = 0, is_root0: bool = true):
self.x = x0
self.y = y0
self.z = z0
self.is_root = is_root0
func is_valid() -> bool:
if (self.z >= 0) and (self.z < MAX_ZOOM):
@@ -38,8 +44,12 @@ class Tile:
class LngLat:
var lng: float = 0.0 ## Долгота в десятичных градусах восточной долготы.
var lat: float = 0.0 ## Широта в десятичных градусах северной широты.
## Возвращает в виде массива
func as_array() -> Array: return [self.lng, self.lat]
func _to_string() -> String: return '[%f, %f, %f]' % [self.x, self.y, self.z]
func _init(lng0, lat0):
self.lng = lng0
self.lat = lat0
@@ -51,8 +61,12 @@ class LngLatBbox:
var south: float ## Юг
var east: float ## Восток
var north: float ## Север
## Возвращает в виде массива
func as_array() -> Array: return [self.west, self.south, self.east, self.north]
func _to_string() -> String: return '[%f, %f, %f, %f]' % [self.west, self.south, self.east, self.north]
func _init(w: float = 0.0, s: float = 0.0, e: float = 0.0, n: float = 0.0):
self.west = w
self.south = s
@@ -83,6 +97,21 @@ func radians(v: float) -> float: return (v * PI) / 180.0
func rshift(val: int, n: int) -> int: return (val % 0x100000000) >> n
## Расстояние по горизонтали в метрах, представленное одним пикселем
## [paramn lat] - Широта, градусы.[br]
## [paramn zoom] - Уровень детализации.[br]
## [paramn size] - Размер плитки в пикселях.[br]
func dist_per_pixel(lat: float, zoom: int, size: int = 256) -> float:
return (CE / float(size)) * cos(radians(lat)) / float(2 ** zoom)
## Расстояние по горизонтали в метрах, представленное одной плиткой
## [paramn lat] - Широта, градусы.[br]
## [paramn zoom] - Уровень детализации.[br]
func dist_per_tile(lat: float, zoom: int) -> float:
return CE * cos(radians(lat)) / float(2 ** zoom)
## Возвращает плитки и занимаемый ими размер области в пикселях:
## ширина, высота, левая граница, верхняя граница, плитки.[br]
## [param west] - Западная граница области.[br]
@@ -130,6 +159,7 @@ func get_degrees_bounds(m: float, lng: float, lat: float) -> Array[float]:
return [x_y[0] - m, x_y[1] - m, x_y[0] + m, x_y[1] + m]
## Возвращает границы плиток в градусах
func get_tiles_bounds(tiles: Array[Tile]) -> Array:
var mm = []
for t in tiles: mm.append(bounds(t).west)
@@ -182,17 +212,17 @@ func ul2(tile: Tile) -> Array[float]:
## Возвращает граничную область плитки.[br]
## [param tile] - Плитка.[br]
func bounds(tile: Tile) -> LngLatBbox:
var Z2: = pow(2, tile.z)
var ul_lon_deg = tile.x / Z2 * 360.0 - 180.0
var ul_lat_rad = atan(sinh(PI * (1 - 2 * tile.y / Z2)))
var z2: = pow(2, tile.z)
var ul_lon_deg = tile.x / z2 * 360.0 - 180.0
var lr_lon_deg = (tile.x + 1) / z2 * 360.0 - 180.0
var ul_lat_rad = atan(sinh(PI * (1 - 2 * tile.y / z2)))
var ul_lat_deg = degrees(ul_lat_rad)
var lr_lon_deg = (tile.x + 1) / Z2 * 360.0 - 180.0
var lr_lat_rad = atan(sinh(PI * (1 - 2 * (tile.y + 1) / Z2)))
var lr_lat_rad = atan(sinh(PI * (1 - 2 * (tile.y + 1) / z2)))
var lr_lat_deg = degrees(lr_lat_rad)
return LngLatBbox.new(ul_lon_deg, lr_lat_deg, lr_lon_deg, ul_lat_deg)
func truncate_lnglat(lng: float, lat: float) -> Array:
func truncate_lnglat(lng: float, lat: float) -> Array[float]:
if lng > 180.0: lng = 180.0
elif lng < -180.0: lng = -180.0
if lat > 90.0: lat = 90.0
@@ -200,7 +230,7 @@ func truncate_lnglat(lng: float, lat: float) -> Array:
return [lng, lat]
## Преобразование долготы и широты в веб-меркатор x, y.[br]
## Преобразование долготы и широты в веб-меркатор x, y в метрах.[br]
## [param lng] - Долгота в десятичных градусах.[br]
## [param lat] - Широта в десятичных градусах.[br]
## [param truncate] - Нужно ли усекать входные данные до пределов веб-меркатора.[br]
@@ -234,14 +264,17 @@ func lnglat(x: float, y: float, truncate: bool = false) -> LngLat:
## >>> neighbors(Tile(486, 332, 10))
## [Tile(x=485, y=331, z=10), Tile(x=485, y=332, z=10), Tile(x=485, y=333, z=10), Tile(x=486, y=331, z=10), Tile(x=486, y=333, z=10), Tile(x=487, y=331, z=10), Tile(x=487, y=332, z=10), Tile(x=487, y=333, z=10)]
## [/codeblock]
func neighbors(tile: Tile) -> Array[Tile]:
var tiles: = Array()
var lo_hi = [0, 2 ** tile.z - 1]
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 > lo_hi[1] or tile.y + j > lo_hi[i]: continue
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():
tiles.append(t)
@@ -260,9 +293,9 @@ func xy_bounds(tile: Tile, zoom: int) -> Bbox:
return Bbox.new(left, bottom, right, top)
func _xy(lng, lat, truncate=false) -> Array:
func _xy(lng, lat, truncate=false) -> Array[float]:
var ll: = [lng, lat] if not truncate else truncate_lnglat(lng, lat)
var x = ll[0] / 360.0 + 0.5
var x: float = ll[0] / 360.0 + 0.5
var sinlat: = sin(radians(ll[1]))
var y: = 0.5 - 0.25 * log((1.0 + sinlat) / (1.0 - sinlat)) / PI
return [x, y]
@@ -274,25 +307,27 @@ func _xy(lng, lat, truncate=false) -> Array:
## [param truncate] - Нужно ли усекать вводимые данные до границ веб-меркатора.[br]
func create_tile(lng: float, lat: float, zoom: int, truncate: bool=false) -> Tile:
var xy0: = _xy(lng, lat, truncate)
var Z2 = pow(2, zoom)
var z2 = pow(2, zoom)
# Чтобы устранить потерю точности при переходе от одной плитки к другой
# и lng/lat, точки в пределах EPSILON от правой стороны тайла
# и lng/lat, точки в пределах EPSILON от правой стороны плитки
# считаются в следующей за ней плитке.
var tile: = Tile.new()
if xy0[0] <= 0: tile.x = 0
elif xy0[0] >= 1: tile.x = int(Z2 - 1)
else: tile.x = int(floor((xy0[0] + EPSILON) * Z2))
elif xy0[0] >= 1: tile.x = int(z2 - 1)
else: tile.x = int(floor((xy0[0] + EPSILON) * z2))
if xy0[1] <= 0: tile.y = 0
elif xy0[1] >= 1: tile.y = int(Z2 - 1)
else: tile.y = int(floor((xy0[1] + EPSILON) * Z2))
elif xy0[1] >= 1: tile.y = int(z2 - 1)
else: tile.y = int(floor((xy0[1] + EPSILON) * z2))
tile.z = zoom
tile.lng = lng
tile.lat = lat
return tile
## Получение четверного ключа плитки.[br]
## [param tile] Плитка
## [param tile] - Плитка
func quadkey(tile: Tile, zoom: int) -> String:
var rs: = ''
for z in range(zoom, 0, -1):
@@ -337,9 +372,7 @@ func quadkey_to_tile(qk: Array) -> Tile:
## [param truncate] [bool] - Нужно ли усекать вводимые данные до границ веб-меркатора.[br]
## [i]В параметрах south и east используется небольшой эпсилон, чтобы
## функция выдавала ровно одну плитку при задании границ этой же плитки.[/i]
func create_tiles(west: float, south: float, east: float, north: float, zooms, truncate: bool=false) -> Array[Tile]:
var west_south = [west, south] if truncate else truncate_lnglat(west, south)
var east_north = [east, north] if truncate else truncate_lnglat(east, north)
func create_tiles(west: float, south: float, east: float, north: float, zooms) -> Array[Tile]:
var bboxes = [[west, south, east, north]] if west <= east else [[-180.0, south, east, north], [west, south, 180.0, north]]
var tiles = []
if not is_instance_of(zooms, TYPE_ARRAY):
@@ -351,7 +384,7 @@ func create_tiles(west: float, south: float, east: float, north: float, zooms, t
var n = box[3]
# Зажим граничных значений.
w = max(-180.0, w)
s = max(-85.051129, s)
s = max(MAX_SOUTH, s)
e = min(180.0, e)
n = min(85.051129, n)
for z in zooms:
@@ -412,8 +445,7 @@ func parent(tile: Tile, zoom=null) -> Tile:
## >>> children(Tile(0, 0, 0), zoom=2)
## [Tile(x=0, y=0, z=2), Tile(x=0, y=1, z=2), Tile(x=0, y=2, z=2), Tile(x=0, y=3, z=2), ...]
## [/codeblock]
func children(tile, zoom) -> Array:
assert((tile.z <= zoom) and zoom == int(zoom), 'Масштаб (zoom) должен быть целым числом и превышать масштаб входной плитки (tile)')
func children(tile: Tile, zoom: int) -> Array:
var target_zoom = zoom if zoom != null else tile.z + 1
var tiles: Array[Tile] = [tile]
while tiles[0].z >= target_zoom:
@@ -484,33 +516,26 @@ func simplify(tiles: Array) -> Array:
## Tile(x=0, y=0, z=0).
## [param bbox] последовательность [float] значений границ запада, юга, востока,
## севера в десятичных градусах.
func bounding_tile(bbox, truncate: bool = false) -> Tile:
if len(bbox) == 2:
bbox += bbox
var w = bbox[0]
var s = bbox[1]
var e = bbox[2]
var n = bbox[3]
func bounding_tile(bbox: Bbox, truncate: bool = false) -> Tile:
if truncate:
var w_s = truncate_lnglat(w, s)
w = w_s[0]
s = w_s[1]
var e_n = truncate_lnglat(e, n)
n = e_n[0]
e = e_n[1]
var w_s = truncate_lnglat(bbox.left, bbox.bottom)
bbox.left = w_s[0]
bbox.bottom = w_s[1]
var e_n = truncate_lnglat(bbox.right, bbox.north)
bbox.right = e_n[0]
bbox.top = e_n[1]
e -= LL_EPSILON
s += LL_EPSILON
bbox.right -= LL_EPSILON
bbox.bottom += LL_EPSILON
var tmin = create_tile(w, n, 32)
var tmax = create_tile(e, s, 32)
var tmin = create_tile(bbox.left, bbox.top, 32)
var tmax = create_tile(bbox.right, bbox.bottom, 32)
assert(tmin.is_valid())
assert(tmax.is_valid())
var cell = [tmin.x, tmin.y, tmax.x, tmax.y]
var z = _getBboxZoom(cell)
var z = _get_bbox_zoom(cell)
if z == 0:
return Tile.new()
@@ -521,7 +546,7 @@ func bounding_tile(bbox, truncate: bool = false) -> Tile:
return Tile.new(x, y, z)
func _getBboxZoom(bbox: Array):
func _get_bbox_zoom(bbox: Array):
for z in MAX_ZOOM:
var mask: int = 1 << (32 - (z + 1))
if (bbox[0] & mask) != (bbox[2] & mask) or (bbox[1] & mask) != (bbox[3] & mask):

View File

@@ -20,3 +20,8 @@ signal threat_unselected(threats: Dictionary, th)
## Вызывается, когда пользователь переключает режим окна программы полный экран - оконный
## [param id] - Идентификатор окна. Присваевается вручную
signal full_screen(id: int)
## Вызывается при изменении уровня детализации карты
## [param zoom] - Вновь установленный уровень детализации
signal zoom_changed(zoom: int)

View File

@@ -54,7 +54,6 @@ func _ready() -> void:
timer_check_lost.start(repsettings.ThreatParams.time_lost / 1000.0)
## Периодически удаляет устаревшие цели
func on_timer_check_lost(time_lost: int, threats: Dictionary):
var tick = Time.get_ticks_msec()

View File

@@ -1,6 +1,6 @@
extends Node
##
##
const INPUT_ROWS1 = [
[12,['283333 МР-231S, Строб ЭМС', 'X52', '0.00', '0.00']],
[13,['29НРЛС МР-231-3, УИЗП', 'X54', '0.00', '0.00']],

View File

@@ -4,11 +4,11 @@ shader_type canvas_item;
/* Рисует текстуру по маске в форме окружности */
uniform float radius: hint_range(0.0, 1.0) = 0.4; /* Радиус */
uniform float radius: hint_range(0.0, 1.0) = 0.8; /* Радиус */
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);// * smooth_px(length(UV - center), radius, DS);
}