maps4fs 1.8.1__tar.gz → 1.8.12__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {maps4fs-1.8.1 → maps4fs-1.8.12}/PKG-INFO +5 -1
- {maps4fs-1.8.1 → maps4fs-1.8.12}/README.md +4 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/background.py +7 -11
- maps4fs-1.8.12/maps4fs/generator/component/base/__init__.py +1 -0
- {maps4fs-1.8.1/maps4fs/generator → maps4fs-1.8.12/maps4fs/generator/component/base}/component.py +39 -23
- maps4fs-1.8.12/maps4fs/generator/component/base/component_xml.py +95 -0
- {maps4fs-1.8.1/maps4fs/generator → maps4fs-1.8.12/maps4fs/generator/component}/config.py +15 -30
- maps4fs-1.8.12/maps4fs/generator/component/i3d.py +545 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dem.py +1 -10
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dtm/srtm.py +0 -2
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/game.py +33 -2
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/grle.py +10 -16
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/map.py +41 -1
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/satellite.py +1 -2
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/settings.py +11 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/texture.py +5 -7
- maps4fs-1.8.12/maps4fs/toolbox/__init__.py +1 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/toolbox/background.py +1 -3
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs.egg-info/PKG-INFO +5 -1
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs.egg-info/SOURCES.txt +6 -3
- {maps4fs-1.8.1 → maps4fs-1.8.12}/pyproject.toml +1 -1
- maps4fs-1.8.1/maps4fs/generator/i3d.py +0 -624
- {maps4fs-1.8.1 → maps4fs-1.8.12}/LICENSE.md +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/__init__.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/__init__.py +0 -0
- {maps4fs-1.8.1/maps4fs/toolbox → maps4fs-1.8.12/maps4fs/generator/component}/__init__.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dtm/__init__.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dtm/base/wcs.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dtm/base/wms.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dtm/bavaria.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dtm/dtm.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dtm/england.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dtm/hessen.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dtm/niedersachsen.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dtm/nrw.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dtm/usgs.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/dtm/utils.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/generator/qgis.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/logger.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/toolbox/custom_osm.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs/toolbox/dem.py +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs.egg-info/dependency_links.txt +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs.egg-info/requires.txt +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/maps4fs.egg-info/top_level.txt +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/setup.cfg +0 -0
- {maps4fs-1.8.1 → maps4fs-1.8.12}/tests/test_generator.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: maps4fs
|
3
|
-
Version: 1.8.
|
3
|
+
Version: 1.8.12
|
4
4
|
Summary: Generate map templates for Farming Simulator from real places.
|
5
5
|
Author-email: iwatkot <iwatkot@gmail.com>
|
6
6
|
License: MIT License
|
@@ -611,6 +611,8 @@ You can also apply some advanced settings to the map generation process.<br>
|
|
611
611
|
|
612
612
|
- Forest density - the density of the forest in meters. The lower the value, the lower the distance between the trees, which makes the forest denser. Note, that low values will lead to enormous number of trees, which may cause the Giants Editor to crash or lead to performance issues. By default, it's set to 10.
|
613
613
|
|
614
|
+
- Trees relative shift - represents the maximum possible shift of the tree from it's original position in percents of the forest density value. The higher the value, the more the trees will be shifted from their original positions. Warning: higher values can lead to overlapping trees.
|
615
|
+
|
614
616
|
### Texture Advanced settings
|
615
617
|
|
616
618
|
- Dissolve - if enabled, the values from one layer will be splitted between different layers of texture, making it look more natural. Warning: it's a time-consuming process, recommended to enable it, when you generating the final version of the map, not some test versions.
|
@@ -692,3 +694,5 @@ But also, I want to thank the people who helped me with the project in some way,
|
|
692
694
|
- [H4rdB4se](https://github.com/H4rdB4se) - for investigating the issue with custom OSM files and finding a proper way to work with the files in JOSM.
|
693
695
|
- [kbrandwijk](https://github.com/kbrandwijk) - for providing [awesome tool](https://github.com/Paint-a-Farm/satmap_downloader) to download the satellite images from the Google Maps and giving a permission to modify it and create a Python Package.
|
694
696
|
- [Maaslandmods](https://github.com/Maaslandmods) - for the awesome idea to edit the tree schema in UI, images and code snippets on how to do it.
|
697
|
+
- [StrauntMaunt](https://gitlab.com/StrauntMaunt) - for developing procedural generation scripts, providing with the required updates for maps4fs and preparing the docs on how to use procedural generation.
|
698
|
+
|
@@ -585,6 +585,8 @@ You can also apply some advanced settings to the map generation process.<br>
|
|
585
585
|
|
586
586
|
- Forest density - the density of the forest in meters. The lower the value, the lower the distance between the trees, which makes the forest denser. Note, that low values will lead to enormous number of trees, which may cause the Giants Editor to crash or lead to performance issues. By default, it's set to 10.
|
587
587
|
|
588
|
+
- Trees relative shift - represents the maximum possible shift of the tree from it's original position in percents of the forest density value. The higher the value, the more the trees will be shifted from their original positions. Warning: higher values can lead to overlapping trees.
|
589
|
+
|
588
590
|
### Texture Advanced settings
|
589
591
|
|
590
592
|
- Dissolve - if enabled, the values from one layer will be splitted between different layers of texture, making it look more natural. Warning: it's a time-consuming process, recommended to enable it, when you generating the final version of the map, not some test versions.
|
@@ -666,3 +668,5 @@ But also, I want to thank the people who helped me with the project in some way,
|
|
666
668
|
- [H4rdB4se](https://github.com/H4rdB4se) - for investigating the issue with custom OSM files and finding a proper way to work with the files in JOSM.
|
667
669
|
- [kbrandwijk](https://github.com/kbrandwijk) - for providing [awesome tool](https://github.com/Paint-a-Farm/satmap_downloader) to download the satellite images from the Google Maps and giving a permission to modify it and create a Python Package.
|
668
670
|
- [Maaslandmods](https://github.com/Maaslandmods) - for the awesome idea to edit the tree schema in UI, images and code snippets on how to do it.
|
671
|
+
- [StrauntMaunt](https://gitlab.com/StrauntMaunt) - for developing procedural generation scripts, providing with the required updates for maps4fs and preparing the docs on how to use procedural generation.
|
672
|
+
|
@@ -13,7 +13,7 @@ import numpy as np
|
|
13
13
|
import trimesh # type: ignore
|
14
14
|
from tqdm import tqdm
|
15
15
|
|
16
|
-
from maps4fs.generator.component import Component
|
16
|
+
from maps4fs.generator.component.base.component import Component
|
17
17
|
from maps4fs.generator.dem import DEM
|
18
18
|
from maps4fs.generator.texture import Texture
|
19
19
|
|
@@ -89,7 +89,7 @@ class Background(Component):
|
|
89
89
|
Raises:
|
90
90
|
ValueError: If the custom background image does not meet the requirements.
|
91
91
|
"""
|
92
|
-
image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
|
92
|
+
image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
|
93
93
|
if image.shape[0] != image.shape[1]:
|
94
94
|
raise ValueError("The custom background image must be a square.")
|
95
95
|
|
@@ -207,7 +207,7 @@ class Background(Component):
|
|
207
207
|
save_path = os.path.join(self.background_directory, f"{filename}.obj")
|
208
208
|
self.logger.debug("Generating obj file in path: %s", save_path)
|
209
209
|
|
210
|
-
dem_data = cv2.imread(self.dem.dem_path, cv2.IMREAD_UNCHANGED)
|
210
|
+
dem_data = cv2.imread(self.dem.dem_path, cv2.IMREAD_UNCHANGED)
|
211
211
|
self.plane_from_np(
|
212
212
|
dem_data,
|
213
213
|
save_path,
|
@@ -227,7 +227,7 @@ class Background(Component):
|
|
227
227
|
Returns:
|
228
228
|
str -- The path to the cutout DEM file.
|
229
229
|
"""
|
230
|
-
dem_data = cv2.imread(dem_path, cv2.IMREAD_UNCHANGED)
|
230
|
+
dem_data = cv2.imread(dem_path, cv2.IMREAD_UNCHANGED)
|
231
231
|
|
232
232
|
center = (dem_data.shape[0] // 2, dem_data.shape[1] // 2)
|
233
233
|
half_size = self.map_size // 2
|
@@ -238,7 +238,7 @@ class Background(Component):
|
|
238
238
|
dem_data = dem_data[x1:x2, y1:y2]
|
239
239
|
|
240
240
|
if save_path:
|
241
|
-
cv2.imwrite(save_path, dem_data)
|
241
|
+
cv2.imwrite(save_path, dem_data)
|
242
242
|
self.logger.debug("Not resized DEM saved: %s", save_path)
|
243
243
|
return save_path
|
244
244
|
|
@@ -251,12 +251,11 @@ class Background(Component):
|
|
251
251
|
except FileNotFoundError:
|
252
252
|
pass
|
253
253
|
|
254
|
-
# pylint: disable=no-member
|
255
254
|
resized_dem_data = cv2.resize(
|
256
255
|
dem_data, (output_size, output_size), interpolation=cv2.INTER_LINEAR
|
257
256
|
)
|
258
257
|
|
259
|
-
cv2.imwrite(main_dem_path, resized_dem_data)
|
258
|
+
cv2.imwrite(main_dem_path, resized_dem_data)
|
260
259
|
self.logger.debug("DEM cutout saved: %s", main_dem_path)
|
261
260
|
|
262
261
|
return main_dem_path
|
@@ -301,9 +300,7 @@ class Background(Component):
|
|
301
300
|
playable area is will be cut out.
|
302
301
|
"""
|
303
302
|
resize_factor = 1 / self.map.background_settings.resize_factor
|
304
|
-
dem_data = cv2.resize(
|
305
|
-
dem_data, (0, 0), fx=resize_factor, fy=resize_factor
|
306
|
-
)
|
303
|
+
dem_data = cv2.resize(dem_data, (0, 0), fx=resize_factor, fy=resize_factor)
|
307
304
|
if remove_center:
|
308
305
|
dem_data = self.remove_center(dem_data, resize_factor)
|
309
306
|
self.logger.debug("Center removed from DEM data.")
|
@@ -410,7 +407,6 @@ class Background(Component):
|
|
410
407
|
|
411
408
|
self.stl_preview_path = preview_path # pylint: disable=attribute-defined-outside-init
|
412
409
|
|
413
|
-
# pylint: disable=no-member
|
414
410
|
def previews(self) -> list[str]:
|
415
411
|
"""Returns the path to the image previews paths and the path to the STL preview file.
|
416
412
|
|
@@ -0,0 +1 @@
|
|
1
|
+
# pylint: disable=missing-module-docstring
|
{maps4fs-1.8.1/maps4fs/generator → maps4fs-1.8.12/maps4fs/generator/component/base}/component.py
RENAMED
@@ -7,11 +7,11 @@ import os
|
|
7
7
|
from copy import deepcopy
|
8
8
|
from typing import TYPE_CHECKING, Any
|
9
9
|
|
10
|
-
import cv2
|
11
|
-
import osmnx as ox
|
10
|
+
import cv2
|
11
|
+
import osmnx as ox
|
12
12
|
from pyproj import Transformer
|
13
|
-
from shapely.affinity import rotate, translate
|
14
|
-
from shapely.geometry import LineString, Polygon, box
|
13
|
+
from shapely.affinity import rotate, translate
|
14
|
+
from shapely.geometry import LineString, Polygon, box
|
15
15
|
|
16
16
|
from maps4fs.generator.qgis import save_scripts
|
17
17
|
|
@@ -20,7 +20,6 @@ if TYPE_CHECKING:
|
|
20
20
|
from maps4fs.generator.map import Map
|
21
21
|
|
22
22
|
|
23
|
-
# pylint: disable=R0801, R0903, R0902, R0904, R0913, R0917
|
24
23
|
class Component:
|
25
24
|
"""Base class for all map generation components.
|
26
25
|
|
@@ -39,7 +38,7 @@ class Component:
|
|
39
38
|
def __init__(
|
40
39
|
self,
|
41
40
|
game: Game,
|
42
|
-
map: Map,
|
41
|
+
map: Map,
|
43
42
|
coordinates: tuple[float, float],
|
44
43
|
map_size: int,
|
45
44
|
map_rotated_size: int,
|
@@ -59,7 +58,7 @@ class Component:
|
|
59
58
|
self.kwargs = kwargs
|
60
59
|
|
61
60
|
self.logger.debug(
|
62
|
-
"Component %s initialized. Map size: %s, map rotated size: %s",
|
61
|
+
"Component %s initialized. Map size: %s, map rotated size: %s",
|
63
62
|
self.__class__.__name__,
|
64
63
|
self.map_size,
|
65
64
|
self.map_rotated_size,
|
@@ -90,12 +89,13 @@ class Component:
|
|
90
89
|
raise NotImplementedError
|
91
90
|
|
92
91
|
def previews(self) -> list[str]:
|
93
|
-
"""Returns a list of paths to the preview images.
|
92
|
+
"""Returns a list of paths to the preview images. If the component does not generate any
|
93
|
+
previews, the method may not be re-implemented in the child class.
|
94
94
|
|
95
|
-
|
96
|
-
|
95
|
+
Returns:
|
96
|
+
list[str]: A list of paths to the preview images.
|
97
97
|
"""
|
98
|
-
|
98
|
+
return []
|
99
99
|
|
100
100
|
@property
|
101
101
|
def previews_directory(self) -> str:
|
@@ -205,7 +205,7 @@ class Component:
|
|
205
205
|
coordinates = coordinates or self.coordinates
|
206
206
|
distance = distance or int(self.map_rotated_size / 2)
|
207
207
|
|
208
|
-
west, south, east, north = ox.utils_geo.bbox_from_point(
|
208
|
+
west, south, east, north = ox.utils_geo.bbox_from_point(
|
209
209
|
coordinates,
|
210
210
|
dist=distance,
|
211
211
|
)
|
@@ -260,11 +260,11 @@ class Component:
|
|
260
260
|
epsg3857_south, epsg3857_east = transformer.transform(south, east)
|
261
261
|
|
262
262
|
if add_margin:
|
263
|
-
|
264
|
-
epsg3857_north = int(epsg3857_north -
|
265
|
-
epsg3857_south = int(epsg3857_south +
|
266
|
-
epsg3857_east = int(epsg3857_east -
|
267
|
-
epsg3857_west = int(epsg3857_west +
|
263
|
+
margin = 500
|
264
|
+
epsg3857_north = int(epsg3857_north - margin)
|
265
|
+
epsg3857_south = int(epsg3857_south + margin)
|
266
|
+
epsg3857_east = int(epsg3857_east - margin)
|
267
|
+
epsg3857_west = int(epsg3857_west + margin)
|
268
268
|
|
269
269
|
return epsg3857_north, epsg3857_south, epsg3857_east, epsg3857_west
|
270
270
|
|
@@ -345,7 +345,6 @@ class Component:
|
|
345
345
|
|
346
346
|
return cs_x, cs_y
|
347
347
|
|
348
|
-
# pylint: disable=R0914
|
349
348
|
def fit_object_into_bounds(
|
350
349
|
self,
|
351
350
|
polygon_points: list[tuple[int, int]] | None = None,
|
@@ -404,9 +403,7 @@ class Component:
|
|
404
403
|
fitted_osm_object = osm_object.intersection(bounds)
|
405
404
|
self.logger.debug("Fitted the osm_object into the bounds: %s", bounds)
|
406
405
|
except Exception as e:
|
407
|
-
raise ValueError(
|
408
|
-
f"Could not fit the osm_object into the bounds: {e}"
|
409
|
-
)
|
406
|
+
raise ValueError(f"Could not fit the osm_object into the bounds: {e}")
|
410
407
|
|
411
408
|
if not isinstance(fitted_osm_object, object_type):
|
412
409
|
raise ValueError("The fitted osm_object is not valid (probably splitted into parts).")
|
@@ -438,7 +435,27 @@ class Component:
|
|
438
435
|
return None
|
439
436
|
return info_layer_path
|
440
437
|
|
441
|
-
|
438
|
+
def get_infolayer_data(self, layer_name: str, layer_key: str) -> Any | None:
|
439
|
+
"""Reads the JSON file of the requested info layer and returns the value of the requested
|
440
|
+
key. If the layer or the key does not exist, None is returned.
|
441
|
+
|
442
|
+
Arguments:
|
443
|
+
layer_name (str): The name of the layer.
|
444
|
+
layer_key (str): The key to get the value of.
|
445
|
+
|
446
|
+
Returns:
|
447
|
+
Any | None: The value of the requested key or None if the layer or the key does not
|
448
|
+
exist.
|
449
|
+
"""
|
450
|
+
infolayer_path = self.get_infolayer_path(layer_name)
|
451
|
+
if not infolayer_path:
|
452
|
+
return None
|
453
|
+
|
454
|
+
with open(infolayer_path, "r", encoding="utf-8") as file:
|
455
|
+
data = json.load(file)
|
456
|
+
|
457
|
+
return data.get(layer_key)
|
458
|
+
|
442
459
|
def rotate_image(
|
443
460
|
self,
|
444
461
|
image_path: str,
|
@@ -460,7 +477,6 @@ class Component:
|
|
460
477
|
self.logger.warning("Image %s does not exist", image_path)
|
461
478
|
return
|
462
479
|
|
463
|
-
# pylint: disable=no-member
|
464
480
|
image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
|
465
481
|
if image is None:
|
466
482
|
self.logger.warning("Image %s could not be read", image_path)
|
@@ -0,0 +1,95 @@
|
|
1
|
+
"""Base class for all components that primarily used to work with XML files."""
|
2
|
+
|
3
|
+
import os
|
4
|
+
from xml.etree import ElementTree as ET
|
5
|
+
|
6
|
+
from maps4fs.generator.component.base.component import Component
|
7
|
+
|
8
|
+
|
9
|
+
class XMLComponent(Component):
|
10
|
+
"""Base class for all components that primarily used to work with XML files."""
|
11
|
+
|
12
|
+
xml_path: str | None = None
|
13
|
+
|
14
|
+
def get_tree(self, xml_path: str | None = None) -> ET.ElementTree:
|
15
|
+
"""Parses the XML file and returns the tree.
|
16
|
+
If the XML path is not provided, the class attribute is used.
|
17
|
+
|
18
|
+
Arguments:
|
19
|
+
xml_path (str, optional): The path to the XML file. Defaults to None.
|
20
|
+
|
21
|
+
Raises:
|
22
|
+
ValueError: If the XML path is not set as a class attribute nor provided as an
|
23
|
+
argument.
|
24
|
+
FileNotFoundError: If the XML file does not exist
|
25
|
+
|
26
|
+
Returns:
|
27
|
+
ET.ElementTree: The parsed XML tree.
|
28
|
+
"""
|
29
|
+
xml_path = xml_path or self.xml_path
|
30
|
+
if not xml_path:
|
31
|
+
raise ValueError(
|
32
|
+
"XML path was not set as a class attribute nor provided as an argument."
|
33
|
+
)
|
34
|
+
|
35
|
+
if not os.path.isfile(xml_path):
|
36
|
+
raise FileNotFoundError(f"XML file {xml_path} does not exist.")
|
37
|
+
|
38
|
+
return ET.parse(xml_path)
|
39
|
+
|
40
|
+
def save_tree(self, tree: ET.ElementTree, xml_path: str | None = None) -> None:
|
41
|
+
"""Saves the XML tree to the file.
|
42
|
+
If the XML path is not provided, the class attribute is used.
|
43
|
+
|
44
|
+
Arguments:
|
45
|
+
tree (ET.ElementTree): The XML tree to save.
|
46
|
+
xml_path (str, optional): The path to the XML file. Defaults to None.
|
47
|
+
|
48
|
+
Raises:
|
49
|
+
ValueError: If the XML path is not set as a class attribute nor provided as an
|
50
|
+
argument.
|
51
|
+
"""
|
52
|
+
xml_path = xml_path or self.xml_path
|
53
|
+
if not xml_path:
|
54
|
+
raise ValueError(
|
55
|
+
"XML path was not set as a class attribute nor provided as an argument."
|
56
|
+
)
|
57
|
+
|
58
|
+
tree.write(xml_path, encoding="utf-8", xml_declaration=True)
|
59
|
+
|
60
|
+
def get_and_update_element(self, root: ET.Element, path: str, data: dict[str, str]) -> None:
|
61
|
+
"""Finds the element by the path and updates it with the provided data.
|
62
|
+
|
63
|
+
Arguments:
|
64
|
+
root (ET.Element): The root element of the XML tree.
|
65
|
+
path (str): The path to the element.
|
66
|
+
data (dict[str, str]): The data to update the element with.
|
67
|
+
"""
|
68
|
+
element = root.find(path)
|
69
|
+
if element is not None:
|
70
|
+
self.update_element(element, data)
|
71
|
+
|
72
|
+
def update_element(self, element: ET.Element, data: dict[str, str]) -> None:
|
73
|
+
"""Updates the element with the provided data.
|
74
|
+
|
75
|
+
Arguments:
|
76
|
+
element (ET.Element): The element to update.
|
77
|
+
data (dict[str, str]): The data to update the element with.
|
78
|
+
"""
|
79
|
+
for key, value in data.items():
|
80
|
+
element.set(key, value)
|
81
|
+
|
82
|
+
def create_element(self, element_name: str, data: dict[str, str]) -> ET.Element:
|
83
|
+
"""Creates an element with the provided data.
|
84
|
+
|
85
|
+
Arguments:
|
86
|
+
element_name (str): The name of the element.
|
87
|
+
data (dict[str, str]): The data to set the element attributes to.
|
88
|
+
|
89
|
+
Returns:
|
90
|
+
ET.Element: The created element.
|
91
|
+
"""
|
92
|
+
element = ET.Element(element_name)
|
93
|
+
for key, value in data.items():
|
94
|
+
element.set(key, value)
|
95
|
+
return element
|
@@ -2,14 +2,11 @@
|
|
2
2
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
import
|
6
|
-
from xml.etree import ElementTree as ET
|
7
|
-
|
8
|
-
from maps4fs.generator.component import Component
|
5
|
+
from maps4fs.generator.component.base.component_xml import XMLComponent
|
9
6
|
|
10
7
|
|
11
8
|
# pylint: disable=R0903
|
12
|
-
class Config(
|
9
|
+
class Config(XMLComponent):
|
13
10
|
"""Component for map settings and configuration.
|
14
11
|
|
15
12
|
Arguments:
|
@@ -25,8 +22,7 @@ class Config(Component):
|
|
25
22
|
|
26
23
|
def preprocess(self) -> None:
|
27
24
|
"""Gets the path to the map XML file and saves it to the instance variable."""
|
28
|
-
self.
|
29
|
-
self.logger.debug("Map XML path: %s.", self._map_xml_path)
|
25
|
+
self.xml_path = self.game.map_xml_path(self.map_directory)
|
30
26
|
|
31
27
|
def process(self) -> None:
|
32
28
|
"""Sets the map size in the map.xml file."""
|
@@ -34,31 +30,20 @@ class Config(Component):
|
|
34
30
|
|
35
31
|
def _set_map_size(self) -> None:
|
36
32
|
"""Edits map.xml file to set correct map size."""
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
self.logger.debug("Map XML file loaded from: %s.", self._map_xml_path)
|
33
|
+
tree = self.get_tree()
|
34
|
+
if not tree:
|
35
|
+
raise FileNotFoundError(f"Map XML file not found: {self.xml_path}")
|
36
|
+
|
42
37
|
root = tree.getroot()
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
"Map size set to %sx%s in Map XML file.",
|
48
|
-
self.map_size,
|
49
|
-
self.map_size,
|
50
|
-
)
|
51
|
-
tree.write(self._map_xml_path)
|
52
|
-
self.logger.debug("Map XML file saved to: %s.", self._map_xml_path)
|
53
|
-
|
54
|
-
def previews(self) -> list[str]:
|
55
|
-
"""Returns a list of paths to the preview images (empty list).
|
56
|
-
The component does not generate any preview images so it returns an empty list.
|
38
|
+
data = {
|
39
|
+
"width": str(self.map_size),
|
40
|
+
"height": str(self.map_size),
|
41
|
+
}
|
57
42
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
43
|
+
for element in root.iter("map"):
|
44
|
+
self.update_element(element, data)
|
45
|
+
break
|
46
|
+
self.save_tree(tree)
|
62
47
|
|
63
48
|
def info_sequence(self) -> dict[str, dict[str, str | float | int]]:
|
64
49
|
"""Returns information about the component.
|