maps4fs 1.6.0__py3-none-any.whl → 1.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- maps4fs/generator/background.py +27 -1
- maps4fs/generator/component.py +1 -1
- maps4fs/generator/dem.py +15 -0
- maps4fs/generator/dtm/dtm.py +36 -1
- maps4fs/generator/dtm/srtm.py +147 -7
- maps4fs/generator/i3d.py +14 -5
- maps4fs/generator/map.py +4 -1
- maps4fs/generator/satellite.py +1 -1
- maps4fs/generator/settings.py +14 -1
- maps4fs/generator/texture.py +3 -5
- {maps4fs-1.6.0.dist-info → maps4fs-1.6.1.dist-info}/METADATA +1 -1
- maps4fs-1.6.1.dist-info/RECORD +27 -0
- {maps4fs-1.6.0.dist-info → maps4fs-1.6.1.dist-info}/WHEEL +1 -1
- maps4fs-1.6.0.dist-info/RECORD +0 -27
- {maps4fs-1.6.0.dist-info → maps4fs-1.6.1.dist-info}/LICENSE.md +0 -0
- {maps4fs-1.6.0.dist-info → maps4fs-1.6.1.dist-info}/top_level.txt +0 -0
maps4fs/generator/background.py
CHANGED
@@ -148,6 +148,9 @@ class Background(Component):
|
|
148
148
|
"east": east,
|
149
149
|
"west": west,
|
150
150
|
}
|
151
|
+
|
152
|
+
dem_info_sequence = self.dem.info_sequence()
|
153
|
+
data["DEM"] = dem_info_sequence
|
151
154
|
return data # type: ignore
|
152
155
|
|
153
156
|
def qgis_sequence(self) -> None:
|
@@ -294,7 +297,7 @@ class Background(Component):
|
|
294
297
|
mesh.apply_transform(rotation_matrix_z)
|
295
298
|
|
296
299
|
# if not include_zeros:
|
297
|
-
z_scaling_factor =
|
300
|
+
z_scaling_factor = self.get_z_scaling_factor()
|
298
301
|
self.logger.debug("Z scaling factor: %s", z_scaling_factor)
|
299
302
|
mesh.apply_scale([1 / resize_factor, 1 / resize_factor, z_scaling_factor])
|
300
303
|
|
@@ -309,6 +312,29 @@ class Background(Component):
|
|
309
312
|
mesh.apply_scale([0.5, 0.5, 0.5])
|
310
313
|
self.mesh_to_stl(mesh)
|
311
314
|
|
315
|
+
def get_z_scaling_factor(self) -> float:
|
316
|
+
"""Calculates the scaling factor for the Z axis based on the map settings.
|
317
|
+
|
318
|
+
Returns:
|
319
|
+
float -- The scaling factor for the Z axis.
|
320
|
+
"""
|
321
|
+
|
322
|
+
scaling_factor = 1 / self.map.dem_settings.multiplier
|
323
|
+
self.logger.debug("Z scaling factor including DEM multiplier: %s", scaling_factor)
|
324
|
+
|
325
|
+
if self.map.shared_settings.height_scale_multiplier:
|
326
|
+
scaling_factor *= self.map.shared_settings.height_scale_multiplier
|
327
|
+
self.logger.debug(
|
328
|
+
"Z scaling factor including height scale multiplier: %s", scaling_factor
|
329
|
+
)
|
330
|
+
if self.map.shared_settings.mesh_z_scaling_factor:
|
331
|
+
scaling_factor *= 1 / self.map.shared_settings.mesh_z_scaling_factor
|
332
|
+
self.logger.debug(
|
333
|
+
"Z scaling factor including mesh z scaling factor: %s", scaling_factor
|
334
|
+
)
|
335
|
+
|
336
|
+
return scaling_factor
|
337
|
+
|
312
338
|
def mesh_to_stl(self, mesh: trimesh.Trimesh) -> None:
|
313
339
|
"""Converts the mesh to an STL file and saves it in the previews directory.
|
314
340
|
Uses powerful simplification to reduce the size of the file since it will be used
|
maps4fs/generator/component.py
CHANGED
maps4fs/generator/dem.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
"""This module contains DEM class for processing Digital Elevation Model data."""
|
2
2
|
|
3
3
|
import os
|
4
|
+
from typing import Any
|
4
5
|
|
5
6
|
import cv2
|
6
7
|
import numpy as np
|
@@ -63,6 +64,7 @@ class DEM(Component):
|
|
63
64
|
size=self.map_rotated_size,
|
64
65
|
directory=self.temp_dir,
|
65
66
|
logger=self.logger,
|
67
|
+
map=self.map,
|
66
68
|
)
|
67
69
|
|
68
70
|
@property
|
@@ -280,3 +282,16 @@ class DEM(Component):
|
|
280
282
|
list: Empty list.
|
281
283
|
"""
|
282
284
|
return []
|
285
|
+
|
286
|
+
def info_sequence(self) -> dict[Any, Any] | None: # type: ignore
|
287
|
+
"""Returns the information sequence for the component. Must be implemented in the child
|
288
|
+
class. If the component does not have an information sequence, an empty dictionary must be
|
289
|
+
returned.
|
290
|
+
|
291
|
+
Returns:
|
292
|
+
dict[Any, Any]: The information sequence for the component.
|
293
|
+
"""
|
294
|
+
provider_info_sequence = self.dtm_provider.info_sequence()
|
295
|
+
if provider_info_sequence is None:
|
296
|
+
return {}
|
297
|
+
return provider_info_sequence
|
maps4fs/generator/dtm/dtm.py
CHANGED
@@ -5,7 +5,7 @@ and specific settings for downloading and processing the data."""
|
|
5
5
|
from __future__ import annotations
|
6
6
|
|
7
7
|
import os
|
8
|
-
from typing import Type
|
8
|
+
from typing import TYPE_CHECKING, Type
|
9
9
|
|
10
10
|
import numpy as np
|
11
11
|
import osmnx as ox # type: ignore
|
@@ -15,6 +15,9 @@ from pydantic import BaseModel
|
|
15
15
|
|
16
16
|
from maps4fs.logger import Logger
|
17
17
|
|
18
|
+
if TYPE_CHECKING:
|
19
|
+
from maps4fs.generator.map import Map
|
20
|
+
|
18
21
|
|
19
22
|
class DTMProviderSettings(BaseModel):
|
20
23
|
"""Base class for DTM provider settings models."""
|
@@ -45,6 +48,7 @@ class DTMProvider:
|
|
45
48
|
size: int,
|
46
49
|
directory: str,
|
47
50
|
logger: Logger,
|
51
|
+
map: Map | None = None, # pylint: disable=W0622
|
48
52
|
):
|
49
53
|
self._coordinates = coordinates
|
50
54
|
self._user_settings = user_settings
|
@@ -56,6 +60,27 @@ class DTMProvider:
|
|
56
60
|
os.makedirs(self._tile_directory, exist_ok=True)
|
57
61
|
|
58
62
|
self.logger = logger
|
63
|
+
self.map = map
|
64
|
+
|
65
|
+
self._data_info: dict[str, int | str | float] | None = None
|
66
|
+
|
67
|
+
@property
|
68
|
+
def data_info(self) -> dict[str, int | str | float] | None:
|
69
|
+
"""Information about the DTM data.
|
70
|
+
|
71
|
+
Returns:
|
72
|
+
dict: Information about the DTM data.
|
73
|
+
"""
|
74
|
+
return self._data_info
|
75
|
+
|
76
|
+
@data_info.setter
|
77
|
+
def data_info(self, value: dict[str, int | str | float] | None) -> None:
|
78
|
+
"""Set information about the DTM data.
|
79
|
+
|
80
|
+
Arguments:
|
81
|
+
value (dict): Information about the DTM data.
|
82
|
+
"""
|
83
|
+
self._data_info = value
|
59
84
|
|
60
85
|
@property
|
61
86
|
def coordinates(self) -> tuple[float, float]:
|
@@ -260,3 +285,13 @@ class DTMProvider:
|
|
260
285
|
raise ValueError("No data in the tile.")
|
261
286
|
|
262
287
|
return data
|
288
|
+
|
289
|
+
def info_sequence(self) -> dict[str, int | str | float] | None:
|
290
|
+
"""Returns the information sequence for the component. Must be implemented in the child
|
291
|
+
class. If the component does not have an information sequence, an empty dictionary must be
|
292
|
+
returned.
|
293
|
+
|
294
|
+
Returns:
|
295
|
+
dict[str, int | str | float] | None: Information sequence for the component.
|
296
|
+
"""
|
297
|
+
return self.data_info
|
maps4fs/generator/dtm/srtm.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
"""This module contains provider of Shuttle Radar Topography Mission (SRTM) 30m data."""
|
2
2
|
|
3
|
+
# Author: https://github.com/iwatkot
|
4
|
+
|
3
5
|
import gzip
|
4
6
|
import math
|
5
7
|
import os
|
@@ -7,7 +9,14 @@ import shutil
|
|
7
9
|
|
8
10
|
import numpy as np
|
9
11
|
|
10
|
-
from maps4fs.generator.dtm.dtm import DTMProvider
|
12
|
+
from maps4fs.generator.dtm.dtm import DTMProvider, DTMProviderSettings
|
13
|
+
|
14
|
+
|
15
|
+
class SRTM30ProviderSettings(DTMProviderSettings):
|
16
|
+
"""Settings for SRTM 30m provider."""
|
17
|
+
|
18
|
+
easy_mode: bool = True
|
19
|
+
power_factor: int = 0
|
11
20
|
|
12
21
|
|
13
22
|
class SRTM30Provider(DTMProvider):
|
@@ -24,19 +33,30 @@ class SRTM30Provider(DTMProvider):
|
|
24
33
|
_author = "[iwatkot](https://github.com/iwatkot)"
|
25
34
|
|
26
35
|
_instructions = (
|
27
|
-
"ℹ️ If you'
|
28
|
-
"
|
29
|
-
"
|
30
|
-
"
|
31
|
-
"
|
36
|
+
"ℹ️ If you don't know how to work with DEM data, it is recommended to use the "
|
37
|
+
"**Easy mode** option. It will automatically change the values in the image, so the "
|
38
|
+
"terrain will be visible in the Giants Editor. If you're an experienced modder, it's "
|
39
|
+
"recommended to disable this option and work with the DEM data in a usual way. \n"
|
40
|
+
"ℹ️ If the terrain height difference in the real world is bigger than 255 meters, "
|
41
|
+
"the [Height scale](https://github.com/iwatkot/maps4fs/blob/main/docs/dem.md#height-scale)"
|
42
|
+
" parameter in the **map.i3d** file will be changed automatically. \n"
|
43
|
+
"⚡ If the **Easy mode** option is disabled, you will probably get completely flat "
|
44
|
+
"terrain, unless you adjust the DEM Multiplier Setting or the Height scale parameter in "
|
45
|
+
"the Giants Editor. \n"
|
46
|
+
"💡 You can use the **Power factor** setting to make the difference between heights "
|
47
|
+
"bigger. Be extremely careful with this setting, and use only low values, otherwise your "
|
48
|
+
"terrain may be completely broken. \n"
|
32
49
|
)
|
33
50
|
|
51
|
+
_settings = SRTM30ProviderSettings
|
52
|
+
|
34
53
|
def __init__(self, *args, **kwargs):
|
35
54
|
super().__init__(*args, **kwargs)
|
36
55
|
self.hgt_directory = os.path.join(self._tile_directory, "hgt")
|
37
56
|
self.gz_directory = os.path.join(self._tile_directory, "gz")
|
38
57
|
os.makedirs(self.hgt_directory, exist_ok=True)
|
39
58
|
os.makedirs(self.gz_directory, exist_ok=True)
|
59
|
+
self.data_info: dict[str, int | str | float] | None = None # type: ignore
|
40
60
|
|
41
61
|
def get_tile_parameters(self, *args, **kwargs) -> dict[str, str]:
|
42
62
|
"""Returns latitude band and tile name for SRTM tile from coordinates.
|
@@ -83,4 +103,124 @@ class SRTM30Provider(DTMProvider):
|
|
83
103
|
with open(decompressed_tile_path, "wb") as f_out:
|
84
104
|
shutil.copyfileobj(f_in, f_out)
|
85
105
|
|
86
|
-
|
106
|
+
data = self.extract_roi(decompressed_tile_path)
|
107
|
+
|
108
|
+
self.data_info = {}
|
109
|
+
self.add_numpy_params(data, "original")
|
110
|
+
|
111
|
+
data = self.signed_to_unsigned(data)
|
112
|
+
self.add_numpy_params(data, "grounded")
|
113
|
+
|
114
|
+
original_deviation = int(self.data_info["original_deviation"])
|
115
|
+
in_game_maximum_height = 65535 // 255
|
116
|
+
if original_deviation > in_game_maximum_height:
|
117
|
+
suggested_height_scale_multiplier = (
|
118
|
+
original_deviation / in_game_maximum_height # type: ignore
|
119
|
+
)
|
120
|
+
suggested_height_scale_value = int(255 * suggested_height_scale_multiplier)
|
121
|
+
else:
|
122
|
+
suggested_height_scale_multiplier = 1
|
123
|
+
suggested_height_scale_value = 255
|
124
|
+
|
125
|
+
self.data_info["suggested_height_scale_multiplier"] = suggested_height_scale_multiplier
|
126
|
+
self.data_info["suggested_height_scale_value"] = suggested_height_scale_value
|
127
|
+
|
128
|
+
self.map.shared_settings.height_scale_multiplier = ( # type: ignore
|
129
|
+
suggested_height_scale_multiplier
|
130
|
+
)
|
131
|
+
self.map.shared_settings.height_scale_value = suggested_height_scale_value # type: ignore
|
132
|
+
|
133
|
+
if self.user_settings.easy_mode: # type: ignore
|
134
|
+
try:
|
135
|
+
data = self.normalize_dem(data)
|
136
|
+
self.add_numpy_params(data, "normalized")
|
137
|
+
|
138
|
+
normalized_deviation = self.data_info["normalized_deviation"]
|
139
|
+
z_scaling_factor = normalized_deviation / original_deviation # type: ignore
|
140
|
+
self.data_info["z_scaling_factor"] = z_scaling_factor
|
141
|
+
|
142
|
+
self.map.shared_settings.mesh_z_scaling_factor = z_scaling_factor # type: ignore
|
143
|
+
self.map.shared_settings.change_height_scale = True # type: ignore
|
144
|
+
|
145
|
+
except Exception as e: # pylint: disable=W0718
|
146
|
+
self.logger.error(
|
147
|
+
"Failed to normalize DEM data. Error: %s. Using original data.", e
|
148
|
+
)
|
149
|
+
|
150
|
+
return data
|
151
|
+
|
152
|
+
def add_numpy_params(
|
153
|
+
self,
|
154
|
+
data: np.ndarray,
|
155
|
+
prefix: str,
|
156
|
+
) -> None:
|
157
|
+
"""Add numpy array parameters to the data_info dictionary.
|
158
|
+
|
159
|
+
Arguments:
|
160
|
+
data (np.ndarray): Numpy array of the tile.
|
161
|
+
prefix (str): Prefix for the parameters.
|
162
|
+
"""
|
163
|
+
self.data_info[f"{prefix}_minimum_height"] = int(data.min()) # type: ignore
|
164
|
+
self.data_info[f"{prefix}_maximum_height"] = int(data.max()) # type: ignore
|
165
|
+
self.data_info[f"{prefix}_deviation"] = int(data.max() - data.min()) # type: ignore
|
166
|
+
self.data_info[f"{prefix}_unique_values"] = int(np.unique(data).size) # type: ignore
|
167
|
+
|
168
|
+
def signed_to_unsigned(self, data: np.ndarray, add_one: bool = True) -> np.ndarray:
|
169
|
+
"""Convert signed 16-bit integer to unsigned 16-bit integer.
|
170
|
+
|
171
|
+
Arguments:
|
172
|
+
data (np.ndarray): DEM data from SRTM file after cropping.
|
173
|
+
|
174
|
+
Returns:
|
175
|
+
np.ndarray: Unsigned DEM data.
|
176
|
+
"""
|
177
|
+
data = data - data.min()
|
178
|
+
if add_one:
|
179
|
+
data = data + 1
|
180
|
+
return data.astype(np.uint16)
|
181
|
+
|
182
|
+
def normalize_dem(self, data: np.ndarray) -> np.ndarray:
|
183
|
+
"""Normalize DEM data to 16-bit unsigned integer using max height from settings.
|
184
|
+
|
185
|
+
Arguments:
|
186
|
+
data (np.ndarray): DEM data from SRTM file after cropping.
|
187
|
+
|
188
|
+
Returns:
|
189
|
+
np.ndarray: Normalized DEM data.
|
190
|
+
"""
|
191
|
+
maximum_height = int(data.max())
|
192
|
+
minimum_height = int(data.min())
|
193
|
+
deviation = maximum_height - minimum_height
|
194
|
+
self.logger.debug(
|
195
|
+
"Maximum height: %s. Minimum height: %s. Deviation: %s.",
|
196
|
+
maximum_height,
|
197
|
+
minimum_height,
|
198
|
+
deviation,
|
199
|
+
)
|
200
|
+
self.logger.debug("Number of unique values in original DEM data: %s.", np.unique(data).size)
|
201
|
+
|
202
|
+
adjusted_maximum_height = maximum_height * 255
|
203
|
+
adjusted_maximum_height = min(adjusted_maximum_height, 65535)
|
204
|
+
scaling_factor = adjusted_maximum_height / maximum_height
|
205
|
+
self.logger.debug(
|
206
|
+
"Adjusted maximum height: %s. Scaling factor: %s.",
|
207
|
+
adjusted_maximum_height,
|
208
|
+
scaling_factor,
|
209
|
+
)
|
210
|
+
|
211
|
+
if self.user_settings.power_factor: # type: ignore
|
212
|
+
power_factor = 1 + self.user_settings.power_factor / 10 # type: ignore
|
213
|
+
self.logger.debug(
|
214
|
+
"Applying power factor: %s to the DEM data.",
|
215
|
+
power_factor,
|
216
|
+
)
|
217
|
+
data = np.power(data, power_factor).astype(np.uint16)
|
218
|
+
|
219
|
+
normalized_data = np.round(data * scaling_factor).astype(np.uint16)
|
220
|
+
self.logger.debug(
|
221
|
+
"Normalized data maximum height: %s. Minimum height: %s. Number of unique values: %s.",
|
222
|
+
normalized_data.max(),
|
223
|
+
normalized_data.min(),
|
224
|
+
np.unique(normalized_data).size,
|
225
|
+
)
|
226
|
+
return normalized_data
|
maps4fs/generator/i3d.py
CHANGED
@@ -14,7 +14,6 @@ import numpy as np
|
|
14
14
|
from maps4fs.generator.component import Component
|
15
15
|
from maps4fs.generator.texture import Texture
|
16
16
|
|
17
|
-
DEFAULT_HEIGHT_SCALE = 2000
|
18
17
|
DISPLACEMENT_LAYER_SIZE_FOR_BIG_MAPS = 32768
|
19
18
|
DEFAULT_MAX_LOD_DISTANCE = 10000
|
20
19
|
DEFAULT_MAX_LOD_OCCLUDER_DISTANCE = 10000
|
@@ -81,6 +80,20 @@ class I3d(Component):
|
|
81
80
|
|
82
81
|
root = tree.getroot()
|
83
82
|
for map_elem in root.iter("Scene"):
|
83
|
+
for terrain_elem in map_elem.iter("TerrainTransformGroup"):
|
84
|
+
if self.map.shared_settings.change_height_scale:
|
85
|
+
suggested_height_scale = self.map.shared_settings.height_scale_value
|
86
|
+
if suggested_height_scale is not None and suggested_height_scale > 255:
|
87
|
+
new_height_scale = int(
|
88
|
+
self.map.shared_settings.height_scale_value # type: ignore
|
89
|
+
)
|
90
|
+
terrain_elem.set("heightScale", str(new_height_scale))
|
91
|
+
self.logger.info(
|
92
|
+
"heightScale attribute set to %s in TerrainTransformGroup element.",
|
93
|
+
new_height_scale,
|
94
|
+
)
|
95
|
+
|
96
|
+
self.logger.debug("TerrainTransformGroup element updated in I3D file.")
|
84
97
|
sun_elem = map_elem.find(".//Light[@name='sun']")
|
85
98
|
|
86
99
|
if sun_elem is not None:
|
@@ -97,10 +110,6 @@ class I3d(Component):
|
|
97
110
|
)
|
98
111
|
|
99
112
|
if self.map_size > 4096:
|
100
|
-
terrain_elem = root.find(".//TerrainTransformGroup")
|
101
|
-
if terrain_elem is None:
|
102
|
-
self.logger.warning("TerrainTransformGroup element not found in I3D file.")
|
103
|
-
return
|
104
113
|
displacement_layer = terrain_elem.find(".//DisplacementLayer") # pylint: disable=W0631
|
105
114
|
|
106
115
|
if displacement_layer is not None:
|
maps4fs/generator/map.py
CHANGED
@@ -16,6 +16,7 @@ from maps4fs.generator.settings import (
|
|
16
16
|
GRLESettings,
|
17
17
|
I3DSettings,
|
18
18
|
SatelliteSettings,
|
19
|
+
SharedSettings,
|
19
20
|
SplineSettings,
|
20
21
|
TextureSettings,
|
21
22
|
)
|
@@ -123,6 +124,8 @@ class Map:
|
|
123
124
|
with open(save_path, "w", encoding="utf-8") as file:
|
124
125
|
json.dump(settings_json, file, indent=4)
|
125
126
|
|
127
|
+
self.shared_settings = SharedSettings()
|
128
|
+
|
126
129
|
self.texture_custom_schema = kwargs.get("texture_custom_schema", None)
|
127
130
|
if self.texture_custom_schema:
|
128
131
|
save_path = os.path.join(self.map_directory, "texture_custom_schema.json")
|
@@ -245,7 +248,7 @@ class Map:
|
|
245
248
|
str: Path to the archive.
|
246
249
|
"""
|
247
250
|
archive_path = shutil.make_archive(archive_path, "zip", self.map_directory)
|
248
|
-
self.logger.
|
251
|
+
self.logger.debug("Map packed to %s.zip", archive_path)
|
249
252
|
if remove_source:
|
250
253
|
try:
|
251
254
|
shutil.rmtree(self.map_directory)
|
maps4fs/generator/satellite.py
CHANGED
@@ -34,7 +34,7 @@ class Satellite(Component):
|
|
34
34
|
"""Downloads the satellite images for the map."""
|
35
35
|
self.image_paths = [] # pylint: disable=W0201
|
36
36
|
if not self.map.satellite_settings.download_images:
|
37
|
-
self.logger.
|
37
|
+
self.logger.debug("Satellite images download is disabled.")
|
38
38
|
return
|
39
39
|
|
40
40
|
margin = self.map.satellite_settings.satellite_margin
|
maps4fs/generator/settings.py
CHANGED
@@ -4,7 +4,20 @@ from __future__ import annotations
|
|
4
4
|
|
5
5
|
from typing import Any
|
6
6
|
|
7
|
-
from pydantic import BaseModel
|
7
|
+
from pydantic import BaseModel, ConfigDict
|
8
|
+
|
9
|
+
|
10
|
+
class SharedSettings(BaseModel):
|
11
|
+
"""Represents the shared settings for all components."""
|
12
|
+
|
13
|
+
mesh_z_scaling_factor: float | None = None
|
14
|
+
height_scale_multiplier: float | None = None
|
15
|
+
height_scale_value: float | None = None
|
16
|
+
change_height_scale: bool = False
|
17
|
+
|
18
|
+
model_config = ConfigDict(
|
19
|
+
frozen=False,
|
20
|
+
)
|
8
21
|
|
9
22
|
|
10
23
|
class SettingsModel(BaseModel):
|
maps4fs/generator/texture.py
CHANGED
@@ -187,7 +187,7 @@ class Texture(Component):
|
|
187
187
|
custom_schema = self.kwargs.get("texture_custom_schema")
|
188
188
|
if custom_schema:
|
189
189
|
layers_schema = custom_schema # type: ignore
|
190
|
-
self.logger.
|
190
|
+
self.logger.debug("Custom schema loaded with %s layers.", len(layers_schema))
|
191
191
|
else:
|
192
192
|
if not os.path.isfile(self.game.texture_schema):
|
193
193
|
raise FileNotFoundError(
|
@@ -202,15 +202,13 @@ class Texture(Component):
|
|
202
202
|
|
203
203
|
try:
|
204
204
|
self.layers = [self.Layer.from_json(layer) for layer in layers_schema] # type: ignore
|
205
|
-
self.logger.
|
205
|
+
self.logger.debug("Loaded %s layers.", len(self.layers))
|
206
206
|
except Exception as e: # pylint: disable=W0703
|
207
207
|
raise ValueError(f"Error loading texture layers: {e}") from e
|
208
208
|
|
209
209
|
base_layer = self.get_base_layer()
|
210
210
|
if base_layer:
|
211
211
|
self.logger.debug("Base layer found: %s.", base_layer.name)
|
212
|
-
else:
|
213
|
-
self.logger.warning("No base layer found.")
|
214
212
|
|
215
213
|
self._weights_dir = self.game.weights_dir_path(self.map_directory)
|
216
214
|
self.logger.debug("Weights directory: %s.", self._weights_dir)
|
@@ -595,7 +593,7 @@ class Texture(Component):
|
|
595
593
|
geometry_type = geometry.geom_type
|
596
594
|
converter = self._converters(geometry_type)
|
597
595
|
if not converter:
|
598
|
-
self.logger.
|
596
|
+
self.logger.debug("Geometry type %s not supported.", geometry_type)
|
599
597
|
return None
|
600
598
|
return converter(geometry, width)
|
601
599
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
maps4fs/__init__.py,sha256=WbT36EzJ_74GN0RUUrLIYECdSdtRiZaxKl17KUt7pjA,492
|
2
|
+
maps4fs/logger.py,sha256=B-NEYpMjPAAqlV4VpfTi6nbBFnEABVtQOaYe6nMpidg,1489
|
3
|
+
maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
4
|
+
maps4fs/generator/background.py,sha256=UQlYobpDuUaRM9Ke20-ZKhAYtMS-FC-ekYeaLhimhyQ,22374
|
5
|
+
maps4fs/generator/component.py,sha256=GrTI7803gOQFhqocdjFG-wh0HOkC6HWoyKr8pR2Xp28,20409
|
6
|
+
maps4fs/generator/config.py,sha256=0QmK052B8bxyHVhg3jzCORLfOBMMmqVfhhbqXKf6OMk,4383
|
7
|
+
maps4fs/generator/dem.py,sha256=20gx0dzX0LyO6ipvDitst-BwGfcKogFqgQf9Q2qMH5U,10933
|
8
|
+
maps4fs/generator/game.py,sha256=QHgVnyGYvEnfwGZ84-u-dpbCRr3UeVVqBbrwr5WG8dE,7992
|
9
|
+
maps4fs/generator/grle.py,sha256=u8ZwSs313PIOkH_0B_O2tVTaZ-eYNkc30eKGtBxWzTM,17846
|
10
|
+
maps4fs/generator/i3d.py,sha256=rjOm_vlh9dofmNpYJd9P2U9S7VxZ6r3e-JDJxnMQFD8,24943
|
11
|
+
maps4fs/generator/map.py,sha256=8CYUs7NNVoQBvABqtoKtnbj280JuvseNORDCsebkQ_c,9357
|
12
|
+
maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
|
13
|
+
maps4fs/generator/satellite.py,sha256=_7RcuNmR1mjxEJWMDsjnzKUIqWxnGUn50XtjB7HmSPg,3661
|
14
|
+
maps4fs/generator/settings.py,sha256=1ORjaa55sDIiwVZ0G7TIHEBSDLt7c8xAWgp4QcsInUM,4817
|
15
|
+
maps4fs/generator/texture.py,sha256=dtMpNkmJalaV5IOuv6vhVQHmjbfaWZGYZSSfhs2_m8U,31134
|
16
|
+
maps4fs/generator/dtm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
+
maps4fs/generator/dtm/dtm.py,sha256=azy-RWsc5PgenKDtgG0lrddMwWEw1hYzdng9V8zphMk,9167
|
18
|
+
maps4fs/generator/dtm/srtm.py,sha256=2-pX6bWrJX6gr8IM7ueX6mm_PW7_UQ58MtdzDHae2OQ,9030
|
19
|
+
maps4fs/generator/dtm/usgs.py,sha256=U0kDog1UAa1lWiK4Pe3nnhXnnplOS4HZde1yqYqCiDw,13123
|
20
|
+
maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
21
|
+
maps4fs/toolbox/background.py,sha256=9BXWNqs_n3HgqDiPztWylgYk_QM4YgBpe6_ZNQAWtSc,2154
|
22
|
+
maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
|
23
|
+
maps4fs-1.6.1.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
|
24
|
+
maps4fs-1.6.1.dist-info/METADATA,sha256=6LPuSkp0S7c0USSsUBF6n5MPuNMIuSA_J7IviBUHaKA,36231
|
25
|
+
maps4fs-1.6.1.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
|
26
|
+
maps4fs-1.6.1.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
|
27
|
+
maps4fs-1.6.1.dist-info/RECORD,,
|
maps4fs-1.6.0.dist-info/RECORD
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
maps4fs/__init__.py,sha256=WbT36EzJ_74GN0RUUrLIYECdSdtRiZaxKl17KUt7pjA,492
|
2
|
-
maps4fs/logger.py,sha256=B-NEYpMjPAAqlV4VpfTi6nbBFnEABVtQOaYe6nMpidg,1489
|
3
|
-
maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
4
|
-
maps4fs/generator/background.py,sha256=moTsEJM-hZgHQQiBjFVTWBKgPMqxup-58EErh4bq_dE,21342
|
5
|
-
maps4fs/generator/component.py,sha256=RtXruvT4Fxfr7_xo9Bi-i3IIWcPd5QQOSpYJ_cNC49o,20408
|
6
|
-
maps4fs/generator/config.py,sha256=0QmK052B8bxyHVhg3jzCORLfOBMMmqVfhhbqXKf6OMk,4383
|
7
|
-
maps4fs/generator/dem.py,sha256=gXmHRckXf9-3fNwEhZ8jk89oMn6eElghIQ1kUa0rcuk,10328
|
8
|
-
maps4fs/generator/game.py,sha256=QHgVnyGYvEnfwGZ84-u-dpbCRr3UeVVqBbrwr5WG8dE,7992
|
9
|
-
maps4fs/generator/grle.py,sha256=u8ZwSs313PIOkH_0B_O2tVTaZ-eYNkc30eKGtBxWzTM,17846
|
10
|
-
maps4fs/generator/i3d.py,sha256=FLVlj0g90IXRuaRARD1HTnufsLpuaa5kHKdiME-LUZY,24329
|
11
|
-
maps4fs/generator/map.py,sha256=-iUFGqe11Df-oUrxhcnJzRZ0o6NZKRQ_blTq1h1Wezg,9287
|
12
|
-
maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
|
13
|
-
maps4fs/generator/satellite.py,sha256=Qnb6XxmXKnHdHKVMb9mJ3vDGtGkDHCOv_81hrrXdx3k,3660
|
14
|
-
maps4fs/generator/settings.py,sha256=NWuK76ICr8gURQnzePat4JH9w-iACbQEKQebqu51gBE,4470
|
15
|
-
maps4fs/generator/texture.py,sha256=7Z6Ci7urMvqk3-Jp9K2AKH2KlD1smEQS2qoc8Qzn8Uw,31204
|
16
|
-
maps4fs/generator/dtm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
|
-
maps4fs/generator/dtm/dtm.py,sha256=THQ3RWVL9ut7A4omS8hEog-oQSSwYV0JcDMe0Iiw4fY,8009
|
18
|
-
maps4fs/generator/dtm/srtm.py,sha256=x78VjI4onXxPx5CLrzpwEgFOA_E9f9zhouPdKC2YnBE,3190
|
19
|
-
maps4fs/generator/dtm/usgs.py,sha256=U0kDog1UAa1lWiK4Pe3nnhXnnplOS4HZde1yqYqCiDw,13123
|
20
|
-
maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
21
|
-
maps4fs/toolbox/background.py,sha256=9BXWNqs_n3HgqDiPztWylgYk_QM4YgBpe6_ZNQAWtSc,2154
|
22
|
-
maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
|
23
|
-
maps4fs-1.6.0.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
|
24
|
-
maps4fs-1.6.0.dist-info/METADATA,sha256=36OOMtK0RoswMn9iyTDeJFuNeIVlhcmrDknK4Xe8HE4,36231
|
25
|
-
maps4fs-1.6.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
26
|
-
maps4fs-1.6.0.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
|
27
|
-
maps4fs-1.6.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|