В процессе. Добавлена работа с картами Меркатора. Добавлен общий шейдер. Рефактор

This commit is contained in:
sasha80
2023-11-02 12:49:19 +03:00
parent 94206beb47
commit d186f316f0
9 changed files with 159 additions and 211 deletions

View File

@@ -4,7 +4,7 @@
[ext_resource type="PackedScene" uid="uid://b276iygic5itk" path="res://scenes/работа.tscn" id="2_pdbvn"]
[ext_resource type="PackedScene" uid="uid://lwmw4egynmd1" path="res://scenes/контроль.tscn" id="3_2apbp"]
[ext_resource type="PackedScene" uid="uid://trt0q8th3bn2" path="res://scenes/журнал.tscn" id="4_yq6c0"]
[ext_resource type="PackedScene" uid="uid://dab6loryocc73" path="res://scenes/ЭМС.tscn" id="5_tlyql"]
[ext_resource type="PackedScene" uid="uid://dab6loryocc73" path="res://scenes/эмс.tscn" id="5_tlyql"]
[ext_resource type="PackedScene" uid="uid://bnptm4rlp60dq" path="res://scenes/настройки.tscn" id="6_rxq15"]
[node name="tab_switch" type="TabContainer"]

View File

@@ -8,6 +8,7 @@ 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

@@ -12,10 +12,9 @@
[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_x7kiv"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_whr8j"]
resource_local_to_scene = true
shader = ExtResource("11_7ohqv")
shader_parameter/center = Vector2(0.5, 0.5)
shader_parameter/radius = 0.4
[node name="Работа" type="Panel"]
@@ -134,8 +133,7 @@ offset_right = 1104.0
offset_bottom = 1056.0
[node name="tilemap" parent="." instance=ExtResource("10_wpi4s")]
material = SubResource("ShaderMaterial_x7kiv")
position = Vector2(548, 552)
material = SubResource("ShaderMaterial_whr8j")
[connection signal="drag_begin" from="." to="." method="_on_drag_begin"]
[connection signal="drag_continue" from="." to="." method="_on_drag_continue"]

View File

@@ -1,5 +1,6 @@
extends Node
## Web mercator XYZ tile utilities
## Веб-утилиты для работы с меркаторскими XYZ-плитками.
const R2D: = 180.0 / PI
const RE: = 6378137.0
@@ -9,9 +10,8 @@ const LL_EPSILON: = 1e-11
const MAX_ZOOM: = 28
## An XYZ web mercator tile
## x, y, z : int
## x and y indexes of the tile and zoom level z.
## XYZ-плитка веб-меркатора [param x], [param y], [param z] индексы
# [b]x[/b] и [b]y[/b] плитки и уровень масштабирования [b]z[/b].
class Tile:
var x: int
var y: int
@@ -38,20 +38,21 @@ class Tile:
class LngLat:
var lng: float = 0.0 ## Долгота в десятичных градусах восточной долготы.
var lat: float = 0.0 ## Широта в десятичных градусах северной широты.
## Возвращает в виде массива
func as_array() -> Array: return [self.lng, self.lat]
func _init(lng0, lat0):
self.lng = lng0
self.lat = lat0
## Географическое ограничивающее поле.
## запад, юг, восток, север : float
## Значения границ в десятичных градусах.
## Географические границы. Хранит значения границ в десятичных градусах.
class LngLatBbox:
var west: float
var south: float
var east: float
var north: float
func as_array(): return [self.west, self.south, self.east, self.north]
var west: float ## Запад
var south: float ## Юг
var east: float ## Восток
var north: float ## Север
## Возвращает в виде массива
func as_array() -> Array: return [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
@@ -59,15 +60,13 @@ class LngLatBbox:
self.north = n
## Граничная область веб-меркатора.
## Атрибуты: left, bottom, right, top : float.
## Значения границ в метрах.
## Граничная область веб-меркатора. Хранит значения границ в метрах.
class Bbox:
var left: float
var bottom: float
var right: float
var top: float
func as_array(): return [self.left, self.bottom, self.right, self.top]
func as_array() -> Array: return [self.left, self.bottom, self.right, self.top]
func _init(l: float = 0.0, b: float = 0.0, r: float = 0.0, t: float = 0.0):
self.left = l
self.bottom = b
@@ -75,25 +74,26 @@ class Bbox:
self.top = t
func degrees(v: float): return (v * 180.0) / PI
func degrees(v: float) -> float: return (v * 180.0) / PI
func radians(v: float): return (v * PI) / 180.0
func radians(v: float) -> float: return (v * PI) / 180.0
func rshift(val: int, n: int): return (val % 0x100000000) >> n
func rshift(val: int, n: int) -> int: return (val % 0x100000000) >> n
## Возвращает плитки и занимаемый ими размер области в пикселях:
## ширина, высота, левая граница, верхняя граница, плитки
## [param west] [float] Западная граница области
## [param east] [float] Восточная граница области
## [param south] [float] Южная граница области
## [param north] [float] Северная граница области
## [param size] [float] Размер плитки в пикселях
## [param zoom] [float] Детализация
func get_tiles(west, south, east, north, zoom, size):
var tiles = [create_tiles(west, south, east, north, zoom)]
## ширина, высота, левая граница, верхняя граница, плитки.[br]
## [param west] - Западная граница области.[br]
## [param east] - Восточная граница области.[br]
## [param south] - Южная граница области.[br]
## [param north] - Северная граница области.[br]
## [param size] - Размер плитки в пикселях.[br]
## [param zoom] - Детализация.[br]
func get_tiles(west: float, south: float, east: float, north: float, zoom: int, size: int) -> Array:
var tiles: = create_tiles(west, south, east, north, zoom)
var mm = []
for t in tiles: mm.append(t.x)
var min_x = mm.min()
@@ -109,32 +109,28 @@ func get_tiles(west, south, east, north, zoom, size):
return [w, h, min_x, min_y, tiles, max_x - min_x + 1]
## Возвращает размер области в метрах
## [param west] [float] - Западная граница области
## [param param] [float] - Восточная граница области
## [param south] [float] - Южная граница области
## [param north] [float] - Северная граница области
## [return] [Array]
func get_size_from_degrees(west, south, east, north) -> Array[float]:
## Возвращает размер области в метрах.[br]
## [param west] - Западная граница области.[br]
## [param param] - Восточная граница области.[br]
## [param south] - Южная граница области.[br]
## [param north] - Северная граница области.[br]
func get_size_from_degrees(west: float, south: float, east: float, north: float) -> Array[float]:
var xy0: = xy(west, north, true)
var xy1: = xy(east, south, true)
return [xy0[0] - xy1[0], xy0[1] - xy1[1]]
## Возвращает границы области в градусах
## [param m] [float] - Размер карты в метрах.
## [param lng] [float] - Долгота центра области в градусах (-180...180).
## [param lat] [float] - Широта центра области в градусах (-90...90).
## [return] [float, float, float, float]
func get_degrees_bounds(m: float, lng: float, lat: float):
## Возвращает границы области в градусах.[br]
## [param m] - Размер карты в метрах.[br]
## [param lng] - Долгота центра области в градусах (-180...180).[br]
## [param lat] - Широта центра области в градусах (-90...90).[br]
func get_degrees_bounds(m: float, lng: float, lat: float) -> Array[float]:
m /= 2.0
var x_y = xy(lng, lat, true)
var ws = lnglat(x_y[0] - m, x_y[1] - m)
var en = lnglat(x_y[0] + m, x_y[1] + m)
return [ws[0], ws[1], en[0], en[1]]
return [x_y[0] - m, x_y[1] - m, x_y[0] + m, x_y[1] + m]
func get_tiles_bounds(tiles):
func get_tiles_bounds(tiles: Array[Tile]) -> Array:
var mm = []
for t in tiles: mm.append(bounds(t).west)
var mmw = mm.min(); mm.clear()
@@ -151,17 +147,15 @@ func get_tiles_bounds(tiles):
return [mmw, mms, mme, mmn]
## Возвращает левую верхнюю долготу и широту плитки.
## [param tile] Плитка или последовательность int. Может быть либо экземпляр
## Tile, либо 3 ints, X, Y, Z.
## [return] LngLat
## Возвращает левую верхнюю долготу и широту плитки.[br]
## [param tile] Плитка.[br]
## [codeblock]
## >>> ul(Tile(x=0, y=0, z=1))
## LngLat(lng=-180.0, lat=85.0511287798066)
## >>> mercantile.ul(1, 1, 1)
## LngLat(lng=0.0, lat=0.0)
## [/codeblock]
func ul(tile: Tile, zoom: int):
func ul(tile: Tile, zoom: int) -> LngLat:
var Z2 = pow(2, zoom)
var lon_deg = tile.x / Z2 * 360.0 - 180.0
var lat_rad = atan(sinh(PI * (1 - 2 * tile.y / Z2)))
@@ -169,9 +163,8 @@ func ul(tile: Tile, zoom: int):
return LngLat.new(lon_deg, lat_deg)
## Возвращает левую верхнюю долготу и широту плитки.
## [param tile] [Плитка] Может быть либо экземпляром Tile, либо 3 интами, X, Y, Z.
## [return] [LngLat]
## Возвращает левую верхнюю долготу и широту плитки.[br]
## [param tile] - Плитка.[br]
## [codeblock]
## >>> ul(Tile(x=0, y=0, z=1))
## LngLat(lng=-180.0, lat=85.0511287798066)
@@ -186,21 +179,16 @@ func ul2(tile: Tile) -> Array[float]:
return [lat_deg, lon_deg]
## Возвращает граничную область плитки.
## [param tile] [Tile] или [Array]. Может быть либо экземпляром [Tile], либо 3
## целыми числами (X, Y, Z).
## [return] [LngLatBbox]
## Возвращает граничную область плитки.[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 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_deg = degrees(lr_lat_rad)
return LngLatBbox.new(ul_lon_deg, lr_lat_deg, lr_lon_deg, ul_lat_deg)
@@ -212,12 +200,11 @@ func truncate_lnglat(lng: float, lat: float) -> Array:
return [lng, lat]
## Преобразование долготы и широты в веб-меркатор x, y.
## [param lng] [param lat]: float
## Долгота и широта в десятичных градусах [param truncate] [bool] -Нужно ли
## усекать или обрезать входные данные до пределов веб-меркатора.
## [return] [x: float, y: float]. [param y] будет [b]inf[/b] на северном полюсе.
## ([param lat] >= 90) и [b]-inf[/b] на южном полюсе ([param lat] <= -90).
## Преобразование долготы и широты в веб-меркатор x, y.[br]
## [param lng] - Долгота в десятичных градусах.[br]
## [param lat] - Широта в десятичных градусах.[br]
## [param truncate] - Нужно ли усекать входные данные до пределов веб-меркатора.[br]
## ([param lat] >= 90) [b]inf[/b] на северном и [b]-inf[/b] на южном полюсе ([param lat] <= -90).
func xy(lng: float, lat: float, truncate: bool = false) -> Array[float]:
var ll = truncate_lnglat(lng, lat) if truncate else [0.0, 0.0]
var x: float = RE * radians(lng)
@@ -228,18 +215,17 @@ func xy(lng: float, lat: float, truncate: bool = false) -> Array[float]:
return [x, y]
## Преобразование координат веб-меркатора x, y в долготу и широту.
## [param x] [float], [param y] [float] - Координаты веб-меркатора в метрах.
## [param truncate] [bool] - Нужно ли усекать или обрезать входные данные до границ веб-меркатора.
## [return] [LngLat]
func lnglat(x, y, truncate=false):
var lng = x * R2D / RE
var lat = ((PI * 0.5) - 2.0 * atan(exp(-y / RE))) * R2D
var ll = truncate_lnglat(lng, lat) if truncate else [0.0, 0.0]
## Преобразование координат веб-меркатора x, y в долготу и широту.[br]
## [param x], [param y] - Координаты веб-меркатора в метрах.[br]
## [param truncate] - Нужно ли усекать или обрезать входные данные до границ веб-меркатора.
func lnglat(x: float, y: float, truncate: bool = false) -> LngLat:
var lng: = x * R2D / RE
var lat: = ((PI * 0.5) - 2.0 * atan(exp(-y / RE))) * R2D
var ll: = truncate_lnglat(lng, lat) if truncate else [0.0, 0.0]
return LngLat.new(ll[0], ll[1])
## Соседи плитки. [func neighbors] возвращает до восьми
## Соседи плитки. [method neighbors] возвращает до восьми
## соседних плиток, при этом плитки будут опущены, если они не являются действительными, например.
## Tile(-1, -1, z). [param tile]: Плитка или последовательность int
## Может быть либо экземпляр Tile, либо 3 ints, X, Y, Z.
@@ -262,11 +248,9 @@ func neighbors(tile: Tile) -> Array[Tile]:
return tiles
## Получение меркаторской граничной рамки веб-плитки
## [param tile] - Плитка или последовательность int. Может быть либо экземпляр
## [Tile], либо 3 ints, X, Y, Z.
## [return] [Bbox]
## Примечания. Эпсилон вычитается из правой границы и прибавляется к нижней.
## Получение меркаторской граничной рамки веб-плитки.[br]
## [param tile] - Плитка.[br]
## [i]Эпсилон вычитается из правой границы и прибавляется к нижней[/i]
func xy_bounds(tile: Tile, zoom: int) -> Bbox:
var tile_size = CE / pow(2, zoom)
var left = tile.x * tile_size - CE / 2
@@ -285,10 +269,9 @@ func _xy(lng, lat, truncate=false) -> Array:
## Получение плитки, содержащей долготу и широту
## [param lng], [param lat] [float] - Пара долготы и широты в десятичных градусах.
## [param zoom] [int] - Уровень масштабирования веб-меркатора.
## [param truncate] [bool] - Нужно ли усекать вводимые данные до границ веб-меркатора.
## [return] [Tile]
## [param lng], [param lat] - Пара долготы и широты в десятичных градусах.[br]
## [param zoom] - Уровень масштабирования веб-меркатора.[br]
## [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)
@@ -308,12 +291,10 @@ func create_tile(lng: float, lat: float, zoom: int, truncate: bool=false) -> Til
return tile
## Получение четверного ключа плитки
## [param tile] [Tile] или последовательность [int]. Может быть либо экземпляр
## [Tile] или 3 целых, X, Y, Z.
## [return] [String]
func quadkey(tile: Tile, zoom) -> String:
var rs: = String()
## Получение четверного ключа плитки.[br]
## [param tile] Плитка
func quadkey(tile: Tile, zoom: int) -> String:
var rs: = ''
for z in range(zoom, 0, -1):
var digit = 0
var mask = 1 << (z - 1)
@@ -325,10 +306,9 @@ func quadkey(tile: Tile, zoom) -> String:
return rs
## Получение плитки, соответствующей четверному ключу.
## [param qk] [String] - Строка четверного ключа.
## [return] [Tile]
func quadkey_to_tile(qk: Array):
## Получение плитки, соответствующей четверному ключу.[br]
## [param qk] - Строка четверного ключа.
func quadkey_to_tile(qk: Array) -> Tile:
var tile: = Tile.new()
if len(qk) == 0: return tile
var i = 0
@@ -351,14 +331,12 @@ func quadkey_to_tile(qk: Array):
return tile
## Получение плиток, перекрываемых географической рамкой
## [param west], [param south], [param east], [param north]: последовательность [float]
## - Значения границ в десятичных градусах.
## [param zooms] [int] или [Array[int]]. - Один или несколько уровней масштабирования.
## [param truncate] [bool] - Нужно ли усекать вводимые данные до границ веб-меркатора.
## [return] Tile
## Примечания. В параметрах south и east используется небольшой эпсилон, чтобы
## функция выдавала ровно одну плитку при задании границ этой же плитки.
## Получение плиток, перекрываемых географической рамкой.[br]
## [param west], [param south], [param east], [param north] - Значения границ в десятичных градусах.[br]
## [param zooms] - Один или несколько уровней масштабирования.[br]
## [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)
@@ -386,19 +364,17 @@ func create_tiles(west: float, south: float, east: float, north: float, zooms, t
## Получение родителя плитки. Родительская плитка - это плитка на один уровень масштабирования ниже, которая
## содержит данную "дочернюю" плитку.
## [param tile] [Tile] или последовательность int - Может быть либо экземпляром Tile.
## или 3 ints, X, Y, Z.
## [param zoom] [int] - Определяет уровень *масштабирования* возвращаемой родительской плитки.
## По умолчанию это значение на один ниже, чем у плитки (непосредственного родителя).
## [return] [Tile]
## содержит данную "дочернюю" плитку.[br]
## [param tile] - Плитка.[br]
## [param zoom] - Определяет уровень *масштабирования* возвращаемой родительской плитки.
## По умолчанию это значение на один ниже, чем у плитки (непосредственного родителя).[br]
## [codeblock]
## >>> parent(Tile(0, 0, 2))
## Tile(x=0, y=0, z=1)
## >>> parent(Tile(0, 0, 2), zoom=0)
## Tile(x=0, y=0, z=0)
## [/codeblock]
func parent(tile: Tile, zoom=null):
func parent(tile: Tile, zoom=null) -> Tile:
if tile.z == 0: return null
assert((zoom != null) and (tile.z > zoom or zoom == int(zoom)), 'Масштаб (zoom) должен быть целым числом и меньше масштаба входной плитки (tile).')
@@ -424,13 +400,12 @@ func parent(tile: Tile, zoom=null):
## Получение дочерних элементов плитки. Дочерние элементы упорядочены:
## верхний-левый, верхний-правый, bottom-right, bottom-left.
## [tile] [Tile] или последовательность int. Может быть либо экземпляром Tile,
## либо 3 интами, X, Y, Z.
## [param zoom] [int] Возвращает все дочерние элементы с масштабом *zoom*, в порядке убывания глубины.
## в порядке намотки по часовой стрелке. Если не указано, возвращаются ближайшие (т.е. zoom + 1)
## дочерние элементы плитки.
## [return] [Array]
## верхний-левый, верхний-правый, нижний-правый, нижний-левый. Возвращает все
## дочерние элементы с масштабом *zoom*, в порядке убывания глубины в порядке
## вращения по часовой стрелке. Если не указано, возвращаются ближайшие
## (т.е. zoom + 1) дочерние элементы плитки.[br]
## [param tile] - Плитка.[br]
## [param zoom] - Уровень детализации.
## [codeblock]
## >>> children(Tile(0, 0, 0))
## [Tile(x=0, y=0, z=1), Tile(x=0, y=1, z=1), Tile(x=1, y=0, z=1), Tile(x=1, y=1, z=1)]
@@ -455,7 +430,7 @@ func children(tile, zoom) -> Array:
## Если есть, то происходит их слияние. Возвращает список плиток, а также булево
## число, указывающее, были ли они объединены. При многократном применяя
## [method merge], можно упростить набор плиток.
func merge(merge_set):
func merge(merge_set) -> Array:
var upwards_merge: = {}
for tile in merge_set.keys():
var tile_parent = parent(tile)
@@ -476,8 +451,7 @@ func merge(merge_set):
## Максимально уменьшает размер набора плиток путем слияния листьев с родителями.
## [param tiles] - Последовательность плиток для слияния.
## [return] [Array]
func simplify(tiles: Array):
func simplify(tiles: Array) -> Array:
# Проверьте, существует ли уже плитка и ее родитель.
# Убедитесь, что плитки отсортированы по масштабу, поэтому родительские
# плитки встречаются первыми. Если да, отбросьте дочернюю плитку
@@ -510,8 +484,7 @@ func simplify(tiles: Array):
## Tile(x=0, y=0, z=0).
## [param bbox] последовательность [float] значений границ запада, юга, востока,
## севера в десятичных градусах.
## [return] [Tile]
func bounding_tile(bbox, truncate: bool = false):
func bounding_tile(bbox, truncate: bool = false) -> Tile:
if len(bbox) == 2:
bbox += bbox
@@ -556,18 +529,14 @@ func _getBboxZoom(bbox: Array):
return MAX_ZOOM
## Получение GeoJSON-функции, соответствующей плитке
## [param tile] [Плитка] или последовательность int - Может быть либо экземпляром [Плитка], либо 3 int, X, Y, Z.
## [Tile] или 3 целых, X, Y, Z.
## [param fid] [String] - Идентификатор объекта.
## [param props] [Dictionary] - Необязательные дополнительные свойства признака.
## [param projected] [String] - Можно создать нестандартный веб-меркатор GeoJSON.
## передав 'mercator'.
## [param buffer] [float] - Необязательное буферное расстояние для полигона GeoJSON.
## [param precision] [int] - Координаты GeoJSON будут усечены до данного
## количества знаков после запятой.
## [return] [Dictionary]
func feature(tile: Tile, fid=null, props=null, projected='geographic', buffer=null):
## Получение GeoJSON-функции, соответствующей плитке.[br]
## [param tile] - Плитка.[br]
## [param fid] - Идентификатор объекта.[br]
## [param props] - Необязательные дополнительные свойства признака.[br]
## [param projected] - Можно создать нестандартный веб-меркатор GeoJSON передав 'mercator'[br]
## [param buffer] - Необязательное буферное расстояние для полигона GeoJSON.[br]
## [param precision] - Координаты GeoJSON будут усечены до данного количества знаков после запятой.[br]
func feature(tile: Tile, fid:String = 'null', props=null, projected='geographic', buffer=null) -> Dictionary:
var west_south_east_north = bounds(tile).as_array()
var west = west_south_east_north[0]
var south = west_south_east_north[1]
@@ -605,23 +574,22 @@ func feature(tile: Tile, fid=null, props=null, projected='geographic', buffer=nu
if props:
feat['properties'].update(props)
if fid != null:
if fid != 'null':
feat['id'] = fid
return feat
func isinstance(obj, types: Array):
func isinstance(obj, types: Array) -> bool:
for type in types:
if is_instance_of(obj, type):
return true
return false
## Все кортежи координат из геометрии, объекта или коллекции
## [param lng] [float] - Долгота
## [param lat] [float] - широта
## [return] [Array]
## Все кортежи координат из геометрии, объекта или коллекции.[br]
## [param lng] - Долгота.[br]
## [param lat] - широта.[br]
func _coords(obj) -> Array:
var coordinates = []
if is_instance_of(obj, TYPE_ARRAY):
@@ -645,7 +613,7 @@ func _coords(obj) -> Array:
return v
func func1(bbox: Array, coords: Array):
func _func1(bbox: Array, coords: Array) -> Array[float]:
var w = bbox[0]
var s = bbox[1]
var e = bbox[2]
@@ -655,10 +623,9 @@ func func1(bbox: Array, coords: Array):
return [min(w, lng), min(s, lat), max(e, lng), max(n, lat)]
## Возвращает граничную область объекта GeoJSON.
## [param obj] - Отображение, геометрия GeoJSON, объект или коллекция объектов.
## [returns] [LngLatBbox]
func geojson_bounds(obj):
## Возвращает граничную область объекта GeoJSON.[br]
## [param obj] - Отображение, геометрия GeoJSON, объект или коллекция объектов.[br]
func geojson_bounds(obj) -> LngLatBbox:
var coords: Array = _coords(obj)
var wsen = coords.reduce(func1, [180.0, 90.0, -180.0, -90.0])
var wsen = coords.reduce(_func1, [180.0, 90.0, -180.0, -90.0])
return LngLatBbox.new(wsen[0], wsen[1], wsen[2], wsen[3])

View File

@@ -1,7 +1,8 @@
shader_type canvas_item;
/* Закрашенная окружность */
#include "tools.gdshaderinc"
/* Закрашенная окружность */
uniform vec4 color: source_color = vec4(1, 1, 1, 1);
uniform vec4 color_up: source_color = vec4(1, 1, 1, 1); /* Цвет вспышки при обновлении */
uniform uint tick_update = 0; /* Время последнего обновления, мс */
@@ -11,13 +12,8 @@ const vec2 center = vec2(0.125, 0.125); /* Центр долже
const float radius = 0.125 - ds * 2.0; /* Радиус должен быть 0.5, но это не так */
float smooth_px(float r, float R)
{
return 1.0 - smoothstep(R - ds, R + ds, r);
}
void fragment()
{
COLOR = color * smooth_px(length(UV - center), radius);
COLOR = color * smooth_px(length(UV - center), radius, ds);
}

View File

@@ -1,5 +1,7 @@
shader_type canvas_item;
#include "tools.gdshaderinc"
/* Закрашенный сектор окружности ограниченный угловым сектором и радиусами */
uniform vec4 color: source_color = vec4(1, 1, 1, 1);
@@ -16,12 +18,6 @@ const float dsa = 0.0025; /* Относительное расс
const float dsr = 0.00025; /* Относительное расстояние на котором выполняется сглаживание краёв по круговым линиям */
float smooth_px(float r, float R, float ds)
{
return 1.0 - smoothstep(R - ds, R + ds, r);
}
vec4 sector(vec4 c, vec2 uv_pos, float r0, float r1, float w)
{
bool rc = false;
@@ -49,17 +45,9 @@ vec4 sector(vec4 c, vec2 uv_pos, float r0, float r1, float w)
}
void rotate_vec2(inout vec2 vert, float a)
{
float sin_a = sin(a);
float cos_a = cos(a);
vert *= mat2(vec2(cos_a, sin_a), vec2(-sin_a, cos_a));
}
void vertex()
{
rotate_vec2(VERTEX, radians(90.0 - dir));
rotate_vec2(VERTEX, radians(90.0 - dir), vec2(0, 0));
}

View File

@@ -3,6 +3,8 @@
[sub_resource type="Shader" id="1"]
code = "shader_type canvas_item;
#include \"tools.gdshaderinc\"
uniform vec2 pc0; /* Центр сетки антенн */
uniform float rotation: hint_range(0.0, 360.0) = 0.0; /* */
uniform vec4 color0: source_color = vec4(0.38, 0.47, 0.51, 0.4);
@@ -40,12 +42,6 @@ const float d4 = 90.0;
const float ds = 1.0;
float SMOOTH(float r, float R, float d)
{
return 1.0 - smoothstep(R - d, R + d, r);
}
void sector(inout vec4 c, vec2 uv, vec2 center, float a, float da, float r0, float r1, vec4 color)
{
float l = distance(center, uv);
@@ -55,8 +51,8 @@ void sector(inout vec4 c, vec2 uv, vec2 center, float a, float da, float r0, flo
da /= 2.0;
float a0 = radians(a - da);
float a1 = radians(a + da);
float va = SMOOTH(a0 * sf, theta, ds) - SMOOTH(a1 * sf, theta, ds);
float vr = SMOOTH(r0, l, ds) - SMOOTH(r1, l, ds);
float va = smooth_px(a0 * sf, theta, ds) - smooth_px(a1 * sf, theta, ds);
float vr = smooth_px(r0, l, ds) - smooth_px(r1, l, ds);
float rgb = sqrt(va * vr);
c.rgb += color.rgb * rgb * color.a;
c.a += rgb * color.a;
@@ -75,37 +71,9 @@ void antenas(inout vec4 c, vec2 uv, vec2 p0, int cnt, float r0, float r1, vec4 c
}
void circle_thin(inout vec3 color, vec2 uv, vec2 p, float r, float w, vec3 c, float a)
{
float d = distance(uv, p);
float v0 = r - w;
float v1 = r + w;
color += a * sqrt(smoothstep(v1, v0, d) * smoothstep(v0, v1, d) * c);
}
void line_r(inout vec4 color, vec2 uv, vec2 center, float theta0, float radius, vec4 c)
{
vec2 d = uv - center;
vec2 p = radius * vec2(cos(theta0 * PI / 180.0), - sin(theta0 * PI / 180.0));
float l = length(d - p * clamp(dot(d, p) / dot(p, p), 0.0, 1.0));
color.rgb += c.rgb * SMOOTH(l, 1.0, ds) * c.a;
}
void rotate_vec2(inout vec2 vert, float a)
{
float sin_a = sin(a);
float cos_a = cos(a);
vert *= mat2(vec2(cos_a, sin_a), vec2(-sin_a, cos_a));
}
void vertex()
{
VERTEX -= pc0;
rotate_vec2(VERTEX, radians(rotation));
VERTEX += pc0;
rotate_vec2(VERTEX, radians(rotation), pc0);
}

View File

@@ -2,9 +2,10 @@ shader_type canvas_item;
#include "tools.gdshaderinc"
uniform vec2 center = vec2(0.5, 0.5);
uniform float radius: hint_range(0.0, 1.0) = 0.4; /* Радиус */
/* Рисует текстуру по маске в форме окружности */
uniform float radius: hint_range(0.0, 1.0) = 0.4; /* Радиус */
const vec2 center = vec2(0.5, 0.5);
void fragment()
{

View File

@@ -1,6 +1,35 @@
const float DS = 0.004; /* Относительное расстояние на котором выполняется сглаживание краёв */
float smooth_px(float r, float R, float ds)
{
return 1.0 - smoothstep(R - ds, R + ds, r);
}
void circle_thin(inout vec3 color, vec2 uv, vec2 p, float r, float w, vec3 c, float a)
{
float d = distance(uv, p);
float v0 = r - w;
float v1 = r + w;
color += a * sqrt(smoothstep(v1, v0, d) * smoothstep(v0, v1, d) * c);
}
void line_r(inout vec4 color, vec2 uv, vec2 center, float theta0, float radius, vec4 c)
{
vec2 d = uv - center;
vec2 p = radius * vec2(cos(theta0 * PI / 180.0), - sin(theta0 * PI / 180.0));
float l = length(d - p * clamp(dot(d, p) / dot(p, p), 0.0, 1.0));
color.rgb += c.rgb * smooth_px(l, 1.0, DS) * c.a;
}
void rotate_vec2(inout vec2 vert, float a, vec2 pos)
{
vert -= pos;
float sin_a = sin(a);
float cos_a = cos(a);
vert *= mat2(vec2(cos_a, sin_a), vec2(-sin_a, cos_a));
vert += pos;
}