Рефактор.
This commit is contained in:
@@ -52,7 +52,6 @@ func is_toggle_mode(): return $button.is_toggle_mode()
|
||||
func _on_resized() -> void: $back.scale = size
|
||||
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
$back.scale = size
|
||||
save_modulate = modulate
|
||||
|
||||
@@ -11,7 +11,7 @@ enum TASK_STATE {
|
||||
|
||||
|
||||
## Координаты для проверок [lng, lat]
|
||||
var TEST_DATA: = {
|
||||
const TEST_DATA: = {
|
||||
'Калиниград': [ 20.51095, 54.70649 ],
|
||||
'Москва': [ 37.6156, 55.7522 ],
|
||||
'Нью-Йорк': [ -74.006, 40.7143 ],
|
||||
@@ -29,30 +29,41 @@ var TEST_DATA: = {
|
||||
'Море' : [ 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-индекс плитки]
|
||||
var prev_tiles_dic = {} ##
|
||||
|
||||
|
||||
const MAP_MODES: = {
|
||||
0: 'application/config/map_image_size_rto',
|
||||
1: 'application/config/map_image_size_rls' }
|
||||
|
||||
|
||||
const MAP_RELATIVE_RADIUSES: = {
|
||||
0: 0.39,
|
||||
1: 0.466
|
||||
}
|
||||
|
||||
|
||||
var map_image: Image ## Изображение с картой
|
||||
var map_tile_state: TASK_STATE ## Текущее состояние конечного автомата плитки
|
||||
var map_bcs: Vector3 ## Яркость, контраст насыщенность
|
||||
var map_server_addr: String ## Адрес сервера изображений карт в проекции Меркатора
|
||||
var map_tile_format: String ##
|
||||
var map_tile_stack: Array ## Стек для хранения плиток карты
|
||||
var map_request: HTTPRequest ## Обработчик запросов http
|
||||
var map_zoom: int ## Уровень детализации карты
|
||||
var map_tile: Rect2i ## Область одной плитки: [x-координата области, y-координата области, x-индекс плитки, y-индекс плитки]
|
||||
var map_mode: int ## Режим карты: 0 - приоритет РТО, 1 - приоритет РЛС
|
||||
var prev_tiles_dic: Dictionary ##
|
||||
var lnglat: Array ## Текущие координаты
|
||||
var root_rect: Rect2i
|
||||
|
||||
|
||||
func _ready():
|
||||
lnglat = TEST_DATA['Таганрог']
|
||||
map_tile_state = TASK_STATE.DONE
|
||||
map_request = HTTPRequest.new()
|
||||
add_child(map_request)
|
||||
map_request.request_completed.connect(self._map_request_completed)
|
||||
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')
|
||||
map_tile_format = ProjectSettings.get_setting('application/config/map_tile_format', '%s/%d/%d/%d.png')
|
||||
var map_image_size = ProjectSettings.get_setting(MAP_MODES[0], Vector2i(512, 512))
|
||||
var map_tile_size = ProjectSettings.get_setting('application/config/map_tile_size', 256)
|
||||
map_image = Image.create(map_image_size.x, map_image_size.y, true, Image.FORMAT_RGB8)
|
||||
@@ -65,11 +76,12 @@ func _ready():
|
||||
|
||||
func _on_map_mode_changed(mode: int) -> void:
|
||||
var map_image_size = ProjectSettings.get_setting(MAP_MODES[mode])
|
||||
material.set('shader_parameter/radius', MAP_RELATIVE_RADIUSES[mode])
|
||||
map_image.fill(Color(0, 0, 0, 0))
|
||||
map_image.resize(map_image_size.x, map_image_size.y)
|
||||
map_tile_state = TASK_STATE.DONE
|
||||
var ll = TEST_DATA['Хельсинки']
|
||||
var tile: = mercator.create_tile(ll[0], ll[1], map_zoom)
|
||||
map_mode = mode
|
||||
var tile: = mercator.create_tile(lnglat[0], lnglat[1], map_zoom)
|
||||
map_tile_stack.clear()
|
||||
map_tile_stack.append(tile)
|
||||
prev_tiles_dic.clear()
|
||||
@@ -87,18 +99,12 @@ func _on_zoom_changed(zoom: int):
|
||||
if map_tile_stack.size() != 0:
|
||||
return
|
||||
map_zoom = zoom
|
||||
var ll = TEST_DATA['Хельсинки']
|
||||
var tile: = mercator.create_tile(ll[0], ll[1], zoom)
|
||||
var tile: = mercator.create_tile(lnglat[0], lnglat[1], zoom)
|
||||
map_tile_stack.clear()
|
||||
map_tile_stack.append(tile)
|
||||
prev_tiles_dic.clear()
|
||||
|
||||
|
||||
func request_tile(tile: mercator.Tile, server_addr: String, tile_format: String = '%s/%d/%d/%d.png') -> Error:
|
||||
var tile_addr: = tile_format % [server_addr, tile.z, tile.x , tile.y]
|
||||
return map_request.request(tile_addr)
|
||||
|
||||
|
||||
func img_tile_to_map_image(image: Image, dst_pos: Vector2i):
|
||||
image.adjust_bcs(map_bcs.x, map_bcs.y, map_bcs.z)
|
||||
map_image.blit_rect(image, map_tile, dst_pos)
|
||||
@@ -107,15 +113,16 @@ func img_tile_to_map_image(image: Image, dst_pos: Vector2i):
|
||||
func _process(_delta: float):
|
||||
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:
|
||||
var tile_addr: = map_tile_format % [map_server_addr, tile.z, tile.x , tile.y]
|
||||
var rc = map_request.request(tile_addr)
|
||||
if rc == OK:
|
||||
map_tile_state = TASK_STATE.WAIT
|
||||
else:
|
||||
log.error('%s: Невозможно сформировать запрос HTTP' % self)
|
||||
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.get_perimetr_tiles(root_tile, (map_image.get_size().x / map_tile.size.x) / 1) # = mercator.neighbors(root_tile)
|
||||
var neighbors_tiles = mercator.get_perimetr_tiles(root_tile, (map_image.get_size().x / map_tile.size.x) / 2)
|
||||
var neighbors_tiles_dic = {}
|
||||
for tile in neighbors_tiles:
|
||||
neighbors_tiles_dic[[tile.x, tile.y]] = false
|
||||
@@ -149,22 +156,18 @@ func _map_request_completed(result, response_code, headers, data):
|
||||
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: 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)
|
||||
var sx: float = float(map_tile.size.x) / (bounds.east - bounds.west) * (lng_c - tile.lng) + map_tile.size.x / 2.0 # Cмещение в пискселях центра плитки от заданной точки по горизонтали.
|
||||
var sy: float = float(map_tile.size.y) / (bounds.north - bounds.south) * (lat_c - tile.lat) - map_tile.size.y / 2.0 # Cмещение в пискселях центра плитки от заданной точки по вертикали.
|
||||
var dst_pos: Vector2i = Vector2i(sx, -sy) + map_tile.size * map_mode
|
||||
img_tile_to_map_image(img_tile, dst_pos)
|
||||
map_rects.append(Rect2i(dst_pos.x, dst_pos.y, tile.x, tile.y))
|
||||
root_rect = 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
|
||||
var delta: = Vector2i(tile.x - root_rect.size.x, tile.y - root_rect.size.y)
|
||||
var dst_pos: Vector2i = root_rect.position + delta * map_tile.size
|
||||
img_tile_to_map_image(img_tile, dst_pos)
|
||||
map_rects.append(Rect2i(dst_pos.x, dst_pos.y, tile.x, tile.y))
|
||||
mark_image_center(map_image)
|
||||
texture = ImageTexture.create_from_image(map_image)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_pmqvj"]
|
||||
resource_local_to_scene = true
|
||||
shader = ExtResource("1_tsdui")
|
||||
shader_parameter/radius = 0.4
|
||||
shader_parameter/radius = 0.39
|
||||
|
||||
[node name="tilemap" type="Sprite2D"]
|
||||
material = SubResource("ShaderMaterial_pmqvj")
|
||||
|
||||
@@ -45,15 +45,16 @@ enum DragFSM {
|
||||
}
|
||||
|
||||
|
||||
func on_button_view_toggled(toggled: bool):
|
||||
$canvas.set_view_mode(int(toggled))
|
||||
signaller.emit_signal('map_mode_changed', int(toggled))
|
||||
|
||||
|
||||
## Обработчик сигнала изменения списка целей
|
||||
func on_threats_resized(threats: Dictionary): $count_all_pad/count_all.text = '%02d' % threats.size()
|
||||
|
||||
|
||||
func on_threat_selected(th, ecm_btns): on_rto_threat_sel(th.id, ecm_btns)
|
||||
|
||||
|
||||
func on_button_view_toggled(toggled: bool): signaller.emit_signal('map_mode_changed', int(toggled))
|
||||
|
||||
|
||||
##
|
||||
func _enter_tree() -> void:
|
||||
var timer1 = Timer.new()
|
||||
@@ -74,24 +75,24 @@ func _exit_tree() -> void:
|
||||
func _ready():
|
||||
min_zoom = ProjectSettings.get_setting('application/config/map_minimum_zoom', 5)
|
||||
max_zoom = ProjectSettings.get_setting('application/config/map_maximum_zoom', 19)
|
||||
drag_fsm = DragFSM.OFF
|
||||
$btn_zoom.set_meta('zoom', min_zoom - 1)
|
||||
$btn_strob.button_connect('pressed', Callable(self, 'on_button_strobe_pressed'))
|
||||
$btn_view.button_connect('toggled', Callable(self, 'on_button_view_toggled'))
|
||||
drag_fsm = DragFSM.OFF
|
||||
var nodes: Array = get_tree().get_nodes_in_group('группа-режим-помехи')
|
||||
nodes.any(func(btn): btn.button_connect('pressed', Callable(self, 'on_button_pressed').bind(btn, nodes)))
|
||||
threats.connect('threat_new', Callable(self, 'on_threat_new'))
|
||||
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.connect('zoom_complete', Callable(self, '_on_zoom_complete'))
|
||||
signaller.connect('rto_threat_sel', Callable(self, 'on_rto_threat_sel').bind(nodes))
|
||||
threats.connect('threat_new', Callable(self, 'on_threat_new'))
|
||||
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.connect('zoom_complete', Callable(self, '_on_zoom_complete'))
|
||||
signaller.connect('rto_threat_sel', Callable(self, 'on_rto_threat_sel').bind(nodes))
|
||||
signaller.connect('rto_threat_unsel', Callable(self, 'on_rto_threat_unsel').bind(nodes))
|
||||
signaller.connect('threat_selected', Callable(self, 'on_threat_selected').bind(nodes))
|
||||
signaller.connect('threat_selected', Callable(self, 'on_threat_selected').bind(nodes))
|
||||
signaller.connect('interfer_selected', Callable(self, 'on_interfer_selected').bind(nodes))
|
||||
signaller.connect('interfer_new', Callable(self, 'on_interfer_new'))
|
||||
signaller.connect('interfer_off_all', Callable(self, 'interfer_off_all'))
|
||||
interfer.connect('interfer_update', Callable(self, 'on_interfer_new'))
|
||||
signaller.connect('interfer_new', Callable(self, 'on_interfer_new'))
|
||||
signaller.connect('interfer_off_all', Callable(self, 'interfer_off_all'))
|
||||
interfer.connect('interfer_update', Callable(self, 'on_interfer_new'))
|
||||
|
||||
func on_enter_tree() -> void:
|
||||
call_deferred('_on_btn_scale_pressed')
|
||||
@@ -179,10 +180,6 @@ func on_rto_threat_unsel(th_id, ecm_btns):
|
||||
btn.set_disabled(true)
|
||||
|
||||
|
||||
func on_threat_selected(th, ecm_btns):
|
||||
on_rto_threat_sel(th.id, ecm_btns)
|
||||
|
||||
|
||||
## Обработчик нажатия кнопки "Строб". Управляет отображением строба
|
||||
func on_button_strobe_pressed() -> void:
|
||||
drag_fsm = DragFSM.IDLE if $btn_strob.is_pressed() else DragFSM.OFF
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
extends Node
|
||||
|
||||
## Веб-утилиты для работы с меркаторовскими XYZ-плитками.
|
||||
## Утилиты для работы с меркаторовскими XYZ-плитками.
|
||||
|
||||
const R2D: = 180.0 / PI
|
||||
const RE: = 6378137.0 ## Радиус Земли экваториальный в метрах
|
||||
const RP: = 6356752.31424518 ## Радиус Земли полярный в метрах
|
||||
const CE: = 2.0 * PI * RE ## Длина окружности Земли в метрах по экватору
|
||||
const CP: = 2.0 * PI * RP ## Длина окружности Земли в метрах через полюсы
|
||||
const EPSILON: = 1e-14
|
||||
const LL_EPSILON: = 1e-11
|
||||
const MAX_ZOOM: = 20
|
||||
@@ -28,21 +29,21 @@ class Tile:
|
||||
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, is_root0: bool = true):
|
||||
self.x = x0
|
||||
self.y = y0
|
||||
self.z = z0
|
||||
self.is_root = is_root0
|
||||
x = x0
|
||||
y = y0
|
||||
z = z0
|
||||
is_root = is_root0
|
||||
|
||||
func is_valid() -> bool:
|
||||
if (self.z >= 0) and (self.z < MAX_ZOOM):
|
||||
var mz: int = 2 ** self.z
|
||||
return (self.x >= 0) and (self.x < mz) \
|
||||
and (self.y >= 0) and (self.y < mz)
|
||||
if (z >= 0) and (z < MAX_ZOOM):
|
||||
var mz: int = 2 ** z
|
||||
return (x >= 0) and (x < mz) \
|
||||
and (y >= 0) and (y < mz)
|
||||
return false
|
||||
|
||||
|
||||
func _bound_index(index: int) -> int:
|
||||
var mi: int = 2 ** self.z
|
||||
var mi: int = 2 ** z
|
||||
if index < 0:
|
||||
index *= -1
|
||||
index %= mi
|
||||
@@ -52,8 +53,8 @@ class Tile:
|
||||
return index
|
||||
|
||||
func fix_xy():
|
||||
self.x = _bound_index(self.x)
|
||||
self.y = _bound_index(self.y)
|
||||
x = _bound_index(x)
|
||||
y = _bound_index(y)
|
||||
|
||||
|
||||
## Пара долготы и широты.
|
||||
@@ -113,13 +114,14 @@ func radians(v: float) -> float: return (v * PI) / 180.0
|
||||
func rshift(val: int, n: int) -> int: return (val % 0x100000000) >> n
|
||||
|
||||
|
||||
# Возвращает арксинус гиперболический от значения [param val]
|
||||
func asinh(val: float): return log(val + sqrt(val * val + 1.0))
|
||||
|
||||
|
||||
# To convert lon/lat/alt (lon in degrees East, lat in degrees North, alt in
|
||||
# meters) to earth centered fixed coordinates (x, y, z)
|
||||
func lnglat_to_ecef(lng: float, lat: float, alt: float = 0.0):
|
||||
alt += RE
|
||||
# Преобразует [param lon] в градусах восточной долготы, [param lat] в градусах
|
||||
# северной долготы, [param alt] высоты в метрах в фиксированные координаты (x, y, z) Земли.
|
||||
func lnglat_to_ecef(lng: float, lat: float, alt: float = 0.0) -> Array:
|
||||
alt += (RE + RP) / 2.0
|
||||
var latrad: float = radians(lat)
|
||||
var lonrad: float = radians(lng)
|
||||
var coslat: float = cos(latrad)
|
||||
@@ -163,9 +165,9 @@ func num2deg(x: int, y: int, zoom: int):
|
||||
|
||||
|
||||
## Расстояние по горизонтали в метрах, представленное одним пикселем
|
||||
## [paramn lat] - Широта, градусы.[br]
|
||||
## [paramn zoom] - Уровень детализации.[br]
|
||||
## [paramn size] - Размер плитки в пикселях.[br]
|
||||
## [param lat] - Широта, градусы.[br]
|
||||
## [param zoom] - Уровень детализации.[br]
|
||||
## [param size] - Размер плитки в пикселях.[br]
|
||||
func dist_per_pixel(lat: float, zoom: int, size: int = 256) -> float:
|
||||
return (CE / float(size)) * cos(radians(lat)) / float(2 ** zoom)
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ void sector(inout vec4 c, vec2 uv, vec2 center, float a, float da, float r0, flo
|
||||
|
||||
void antenas(inout vec4 c, vec2 uv, vec2 p0, int cnt, float r0, float r1, vec4 c0, vec4 c1)
|
||||
{
|
||||
float da = 180.0f / float(cnt);
|
||||
float da = 180.0 / float(cnt);
|
||||
for (int i = -cnt; i <= cnt; i ++)
|
||||
{
|
||||
float v = float(i & 1);
|
||||
@@ -85,7 +85,7 @@ void fragment()
|
||||
{
|
||||
ivec2 isz = textureSize(TEXTURE, 0);
|
||||
vec2 uv = UV * vec2(float(isz.x), float(isz.y)); // координаты текущей точки в пикселях
|
||||
COLOR = vec4(0, 0, 0, 0.0); //texture(TEXTURE, UV); // Цвет текущей точки
|
||||
COLOR = vec4(0, 0, 0, 0); //texture(TEXTURE, UV); // Цвет текущей точки
|
||||
|
||||
// Сетка антенн
|
||||
antenas(COLOR, uv, pc0, ant_band_count_0, ant_band_r0_0[mode], ant_band_r1_0[mode], color1, color0);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
#include "tools.gdshaderinc"
|
||||
#include "res://shaders/tools.gdshaderinc"
|
||||
|
||||
/* Закрашенная окружность */
|
||||
uniform vec4 color: source_color = vec4(1, 1, 1, 1);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
#include "tools.gdshaderinc"
|
||||
#include "res://shaders/tools.gdshaderinc"
|
||||
|
||||
/* Закрашенный сектор окружности ограниченный угловым сектором и радиусами */
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
#include "tools.gdshaderinc"
|
||||
#include "res://shaders/tools.gdshaderinc"
|
||||
|
||||
/* Рисует текстуру по маске в форме окружности */
|
||||
|
||||
@@ -11,4 +11,3 @@ void fragment()
|
||||
{
|
||||
COLOR.a *= smooth_px(length(UV - center), radius, DS);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
#include "res://shaders/tools.gdshaderinc"
|
||||
|
||||
uniform vec4 ColorFig:source_color;
|
||||
uniform vec2 point_1;
|
||||
uniform vec2 point_2;
|
||||
@@ -14,10 +17,6 @@ const float DSS = 0.002525;
|
||||
const float radius = 0.125;
|
||||
uniform float speed: hint_range(0.0, 1024.0) = 0.0;
|
||||
|
||||
float smooth_px(float r, float R, float dss)
|
||||
{
|
||||
return 1.0 - smoothstep(R - dss, R + dss, r);
|
||||
}
|
||||
|
||||
float line(vec2 p1, vec2 p2, float width, vec2 uv)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user