maps4fs 1.2.4__py3-none-any.whl → 1.5.0__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/__init__.py +10 -1
- maps4fs/generator/background.py +27 -29
- maps4fs/generator/component.py +80 -24
- maps4fs/generator/config.py +1 -1
- maps4fs/generator/dem.py +11 -13
- maps4fs/generator/game.py +1 -1
- maps4fs/generator/grle.py +18 -14
- maps4fs/generator/i3d.py +192 -35
- maps4fs/generator/map.py +219 -7
- maps4fs/generator/texture.py +108 -34
- {maps4fs-1.2.4.dist-info → maps4fs-1.5.0.dist-info}/METADATA +68 -35
- maps4fs-1.5.0.dist-info/RECORD +21 -0
- maps4fs-1.2.4.dist-info/RECORD +0 -21
- {maps4fs-1.2.4.dist-info → maps4fs-1.5.0.dist-info}/LICENSE.md +0 -0
- {maps4fs-1.2.4.dist-info → maps4fs-1.5.0.dist-info}/WHEEL +0 -0
- {maps4fs-1.2.4.dist-info → maps4fs-1.5.0.dist-info}/top_level.txt +0 -0
maps4fs/generator/texture.py
CHANGED
@@ -45,6 +45,9 @@ class Texture(Component):
|
|
45
45
|
exclude_weight (bool): Flag to exclude weight from the texture.
|
46
46
|
priority (int | None): Priority of the layer.
|
47
47
|
info_layer (str | None): Name of the corresnponding info layer.
|
48
|
+
usage (str | None): Usage of the layer.
|
49
|
+
background (bool): Flag to determine if the layer is a background.
|
50
|
+
invisible (bool): Flag to determine if the layer is invisible.
|
48
51
|
|
49
52
|
Attributes:
|
50
53
|
name (str): Name of the layer.
|
@@ -65,6 +68,7 @@ class Texture(Component):
|
|
65
68
|
info_layer: str | None = None,
|
66
69
|
usage: str | None = None,
|
67
70
|
background: bool = False,
|
71
|
+
invisible: bool = False,
|
68
72
|
):
|
69
73
|
self.name = name
|
70
74
|
self.count = count
|
@@ -76,6 +80,7 @@ class Texture(Component):
|
|
76
80
|
self.info_layer = info_layer
|
77
81
|
self.usage = usage
|
78
82
|
self.background = background
|
83
|
+
self.invisible = invisible
|
79
84
|
|
80
85
|
def to_json(self) -> dict[str, str | list[str] | bool]: # type: ignore
|
81
86
|
"""Returns dictionary with layer data.
|
@@ -93,6 +98,7 @@ class Texture(Component):
|
|
93
98
|
"info_layer": self.info_layer,
|
94
99
|
"usage": self.usage,
|
95
100
|
"background": self.background,
|
101
|
+
"invisible": self.invisible,
|
96
102
|
}
|
97
103
|
|
98
104
|
data = {k: v for k, v in data.items() if v is not None}
|
@@ -177,16 +183,10 @@ class Texture(Component):
|
|
177
183
|
]
|
178
184
|
|
179
185
|
def preprocess(self) -> None:
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
self.custom_schema: list[dict[str, str | dict[str, str] | int]] | None = self.kwargs.get(
|
185
|
-
"custom_schema"
|
186
|
-
)
|
187
|
-
|
188
|
-
if self.custom_schema:
|
189
|
-
layers_schema = self.custom_schema
|
186
|
+
"""Preprocesses the data before the generation."""
|
187
|
+
custom_schema = self.kwargs.get("texture_custom_schema")
|
188
|
+
if custom_schema:
|
189
|
+
layers_schema = custom_schema # type: ignore
|
190
190
|
self.logger.info("Custom schema loaded with %s layers.", len(layers_schema))
|
191
191
|
else:
|
192
192
|
if not os.path.isfile(self.game.texture_schema):
|
@@ -201,14 +201,14 @@ class Texture(Component):
|
|
201
201
|
raise ValueError(f"Error loading texture layers schema: {e}") from e
|
202
202
|
|
203
203
|
try:
|
204
|
-
self.layers = [self.Layer.from_json(layer) for layer in layers_schema]
|
204
|
+
self.layers = [self.Layer.from_json(layer) for layer in layers_schema] # type: ignore
|
205
205
|
self.logger.info("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
|
-
self.logger.
|
211
|
+
self.logger.debug("Base layer found: %s.", base_layer.name)
|
212
212
|
else:
|
213
213
|
self.logger.warning("No base layer found.")
|
214
214
|
|
@@ -307,6 +307,7 @@ class Texture(Component):
|
|
307
307
|
"bbox",
|
308
308
|
"map_height",
|
309
309
|
"map_width",
|
310
|
+
"rotation",
|
310
311
|
"minimum_x",
|
311
312
|
"minimum_y",
|
312
313
|
"maximum_x",
|
@@ -319,7 +320,7 @@ class Texture(Component):
|
|
319
320
|
|
320
321
|
for layer in self.layers:
|
321
322
|
self._generate_weights(layer)
|
322
|
-
self.logger.
|
323
|
+
self.logger.debug("Prepared weights for %s layers.", len(self.layers))
|
323
324
|
|
324
325
|
def _generate_weights(self, layer: Layer) -> None:
|
325
326
|
"""Generates weight files for textures. Each file is a numpy array of zeros and
|
@@ -378,7 +379,7 @@ class Texture(Component):
|
|
378
379
|
),
|
379
380
|
)
|
380
381
|
|
381
|
-
# pylint: disable=no-member
|
382
|
+
# pylint: disable=no-member, R0912
|
382
383
|
def draw(self) -> None:
|
383
384
|
"""Iterates over layers and fills them with polygons from OSM data."""
|
384
385
|
layers = self.layers_by_priority()
|
@@ -394,6 +395,9 @@ class Texture(Component):
|
|
394
395
|
info_layer_data = defaultdict(list)
|
395
396
|
|
396
397
|
for layer in layers:
|
398
|
+
if self.map.texture_settings.skip_drains and layer.usage == "drain":
|
399
|
+
self.logger.debug("Skipping layer %s because of the usage.", layer.name)
|
400
|
+
continue
|
397
401
|
if not layer.tags:
|
398
402
|
self.logger.debug("Layer %s has no tags, there's nothing to draw.", layer.name)
|
399
403
|
continue
|
@@ -412,26 +416,49 @@ class Texture(Component):
|
|
412
416
|
|
413
417
|
mask = cv2.bitwise_not(cumulative_image)
|
414
418
|
|
415
|
-
for polygon in self.
|
419
|
+
for polygon in self.objects_generator( # type: ignore
|
420
|
+
layer.tags, layer.width, layer.info_layer
|
421
|
+
):
|
416
422
|
if layer.info_layer:
|
417
|
-
info_layer_data[layer.info_layer].append(
|
418
|
-
|
423
|
+
info_layer_data[layer.info_layer].append(
|
424
|
+
self.np_to_polygon_points(polygon) # type: ignore
|
425
|
+
)
|
426
|
+
if not layer.invisible:
|
427
|
+
cv2.fillPoly(layer_image, [polygon], color=255) # type: ignore
|
428
|
+
|
429
|
+
if layer.info_layer == "roads":
|
430
|
+
for linestring in self.objects_generator(
|
431
|
+
layer.tags, layer.width, layer.info_layer, yield_linestrings=True
|
432
|
+
):
|
433
|
+
info_layer_data[f"{layer.info_layer}_polylines"].append(
|
434
|
+
linestring # type: ignore
|
435
|
+
)
|
419
436
|
|
420
437
|
output_image = cv2.bitwise_and(layer_image, mask)
|
421
438
|
|
422
439
|
cumulative_image = cv2.bitwise_or(cumulative_image, output_image)
|
423
440
|
|
424
441
|
cv2.imwrite(layer_path, output_image)
|
425
|
-
self.logger.
|
442
|
+
self.logger.debug("Texture %s saved.", layer_path)
|
426
443
|
|
427
444
|
# Save info layer data.
|
445
|
+
if os.path.isfile(self.info_layer_path):
|
446
|
+
self.logger.debug(
|
447
|
+
"File %s already exists, will update to avoid overwriting.", self.info_layer_path
|
448
|
+
)
|
449
|
+
with open(self.info_layer_path, "r", encoding="utf-8") as f:
|
450
|
+
info_layer_data.update(json.load(f))
|
451
|
+
|
428
452
|
with open(self.info_layer_path, "w", encoding="utf-8") as f:
|
429
453
|
json.dump(info_layer_data, f, ensure_ascii=False, indent=4)
|
454
|
+
self.logger.debug("Info layer data saved to %s.", self.info_layer_path)
|
430
455
|
|
431
456
|
if cumulative_image is not None:
|
432
457
|
self.draw_base_layer(cumulative_image)
|
433
458
|
|
434
|
-
if
|
459
|
+
if self.map.texture_settings.dissolve and self.game.code != "FS22":
|
460
|
+
# FS22 has textures splitted into 4 sublayers, which leads to a very
|
461
|
+
# long processing time when dissolving them.
|
435
462
|
self.dissolve()
|
436
463
|
else:
|
437
464
|
self.logger.debug("Skipping dissolve in light version of the map.")
|
@@ -485,8 +512,6 @@ class Texture(Component):
|
|
485
512
|
|
486
513
|
self.logger.info("Dissolved layer %s.", layer.name)
|
487
514
|
|
488
|
-
self.logger.info("Dissolving finished.")
|
489
|
-
|
490
515
|
def draw_base_layer(self, cumulative_image: np.ndarray) -> None:
|
491
516
|
"""Draws base layer and saves it into the png file.
|
492
517
|
Base layer is the last layer to be drawn, it fills the remaining area of the map.
|
@@ -500,7 +525,7 @@ class Texture(Component):
|
|
500
525
|
self.logger.debug("Drawing base layer %s.", layer_path)
|
501
526
|
img = cv2.bitwise_not(cumulative_image)
|
502
527
|
cv2.imwrite(layer_path, img)
|
503
|
-
self.logger.
|
528
|
+
self.logger.debug("Base texture %s saved.", layer_path)
|
504
529
|
|
505
530
|
def get_relative_x(self, x: float) -> int:
|
506
531
|
"""Converts UTM X coordinate to relative X coordinate in map image.
|
@@ -620,35 +645,84 @@ class Texture(Component):
|
|
620
645
|
converters = {"Polygon": self._skip, "LineString": self._sequence, "Point": self._sequence}
|
621
646
|
return converters.get(geom_type) # type: ignore
|
622
647
|
|
623
|
-
def
|
624
|
-
self,
|
625
|
-
|
648
|
+
def objects_generator(
|
649
|
+
self,
|
650
|
+
tags: dict[str, str | list[str] | bool],
|
651
|
+
width: int | None,
|
652
|
+
info_layer: str | None = None,
|
653
|
+
yield_linestrings: bool = False,
|
654
|
+
) -> Generator[np.ndarray, None, None] | Generator[list[tuple[int, int]], None, None]:
|
626
655
|
"""Generator which yields numpy arrays of polygons from OSM data.
|
627
656
|
|
628
657
|
Arguments:
|
629
658
|
tags (dict[str, str | list[str]]): Dictionary of tags to search for.
|
630
659
|
width (int | None): Width of the polygon in meters (only for LineString).
|
660
|
+
info_layer (str | None): Name of the corresponding info layer.
|
661
|
+
yield_linestrings (bool): Flag to determine if the LineStrings should be yielded.
|
631
662
|
|
632
663
|
Yields:
|
633
|
-
Generator[np.ndarray, None, None]
|
664
|
+
Generator[np.ndarray, None, None] | Generator[list[tuple[int, int]], None, None]:
|
665
|
+
Numpy array of polygon points or list of point coordinates.
|
634
666
|
"""
|
635
|
-
is_fieds = "
|
667
|
+
is_fieds = info_layer == "fields"
|
636
668
|
try:
|
637
|
-
|
669
|
+
if self.map.custom_osm is not None:
|
670
|
+
objects = ox.features_from_xml(self.map.custom_osm, tags=tags)
|
671
|
+
else:
|
672
|
+
objects = ox.features_from_bbox(bbox=self.new_bbox, tags=tags)
|
638
673
|
except Exception as e: # pylint: disable=W0718
|
639
|
-
self.logger.
|
640
|
-
self.logger.warning(e)
|
674
|
+
self.logger.debug("Error fetching objects for tags: %s. Error: %s.", tags, e)
|
641
675
|
return
|
642
676
|
objects_utm = ox.projection.project_gdf(objects, to_latlong=False)
|
643
677
|
self.logger.debug("Fetched %s elements for tags: %s.", len(objects_utm), tags)
|
644
678
|
|
679
|
+
method = self.linestrings_generator if yield_linestrings else self.polygons_generator
|
680
|
+
|
681
|
+
yield from method(objects_utm, width, is_fieds)
|
682
|
+
|
683
|
+
def linestrings_generator(
|
684
|
+
self, objects_utm: pd.core.frame.DataFrame, *args, **kwargs
|
685
|
+
) -> Generator[list[tuple[int, int]], None, None]:
|
686
|
+
"""Generator which yields lists of point coordinates which represent LineStrings from OSM.
|
687
|
+
|
688
|
+
Arguments:
|
689
|
+
objects_utm (pd.core.frame.DataFrame): Dataframe with OSM objects in UTM format.
|
690
|
+
|
691
|
+
Yields:
|
692
|
+
Generator[list[tuple[int, int]], None, None]: List of point coordinates.
|
693
|
+
"""
|
645
694
|
for _, obj in objects_utm.iterrows():
|
646
|
-
|
695
|
+
geometry = obj["geometry"]
|
696
|
+
if isinstance(geometry, shapely.geometry.linestring.LineString):
|
697
|
+
points = [
|
698
|
+
(self.get_relative_x(x), self.get_relative_y(y)) for x, y in geometry.coords
|
699
|
+
]
|
700
|
+
yield points
|
701
|
+
|
702
|
+
def polygons_generator(
|
703
|
+
self, objects_utm: pd.core.frame.DataFrame, width: int | None, is_fieds: bool
|
704
|
+
) -> Generator[np.ndarray, None, None]:
|
705
|
+
"""Generator which yields numpy arrays of polygons from OSM data.
|
706
|
+
|
707
|
+
Arguments:
|
708
|
+
objects_utm (pd.core.frame.DataFrame): Dataframe with OSM objects in UTM format.
|
709
|
+
width (int | None): Width of the polygon in meters (only for LineString).
|
710
|
+
is_fieds (bool): Flag to determine if the fields should be padded.
|
711
|
+
|
712
|
+
Yields:
|
713
|
+
Generator[np.ndarray, None, None]: Numpy array of polygon points.
|
714
|
+
"""
|
715
|
+
for _, obj in objects_utm.iterrows():
|
716
|
+
try:
|
717
|
+
polygon = self._to_polygon(obj, width)
|
718
|
+
except Exception as e: # pylint: disable=W0703
|
719
|
+
self.logger.warning("Error converting object to polygon: %s.", e)
|
720
|
+
continue
|
647
721
|
if polygon is None:
|
648
722
|
continue
|
649
723
|
|
650
|
-
if is_fieds and self.fields_padding > 0:
|
651
|
-
padded_polygon = polygon.buffer(-self.fields_padding)
|
724
|
+
if is_fieds and self.map.texture_settings.fields_padding > 0:
|
725
|
+
padded_polygon = polygon.buffer(-self.map.texture_settings.fields_padding)
|
652
726
|
|
653
727
|
if not isinstance(padded_polygon, shapely.geometry.polygon.Polygon):
|
654
728
|
self.logger.warning("The padding value is too high, field will not padded.")
|
@@ -712,5 +786,5 @@ class Texture(Component):
|
|
712
786
|
preview_path = os.path.join(self.previews_directory, "textures_osm.png")
|
713
787
|
|
714
788
|
cv2.imwrite(preview_path, merged) # type: ignore
|
715
|
-
self.logger.
|
789
|
+
self.logger.debug("Preview saved to %s.", preview_path)
|
716
790
|
return preview_path
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: maps4fs
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.5.0
|
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
|
@@ -22,6 +22,7 @@ Requires-Dist: trimesh
|
|
22
22
|
Requires-Dist: imageio
|
23
23
|
Requires-Dist: tifffile
|
24
24
|
Requires-Dist: pympler
|
25
|
+
Requires-Dist: pydantic
|
25
26
|
|
26
27
|
<div align="center" markdown>
|
27
28
|
<a href="https://discord.gg/Sj5QKKyE42">
|
@@ -44,6 +45,7 @@ Requires-Dist: pympler
|
|
44
45
|
<a href="#Overview-image">Overview image</a><br>
|
45
46
|
<a href="#DDS-conversion">DDS conversion</a> •
|
46
47
|
<a href="#Advanced-settings">Advanced settings</a> •
|
48
|
+
<a href="#Expert-settings">Expert settings</a> •
|
47
49
|
<a href="#Resources">Resources</a> •
|
48
50
|
<a href="#Bugs-and-feature-requests">Bugs and feature requests</a><br>
|
49
51
|
<a href="#Special-thanks">Special thanks</a>
|
@@ -60,7 +62,8 @@ Requires-Dist: pympler
|
|
60
62
|
[](https://mypy-lang.org/)
|
61
63
|
[](https://github.com/iwatkot/maps4fs/actions)
|
62
64
|
[](https://codeclimate.com/github/iwatkot/maps4fs/test_coverage)
|
63
|
-
[](https://github.com/iwatkot/maps4fs/stargazers)
|
65
|
+
[](https://github.com/iwatkot/maps4fs/stargazers)<br>
|
66
|
+
[](https://github.com/iwatkot/maps4fs)
|
64
67
|
|
65
68
|
</div>
|
66
69
|
|
@@ -71,7 +74,9 @@ Requires-Dist: pympler
|
|
71
74
|
🌿 Automatically generates decorative foliage 🆕<br>
|
72
75
|
🌲 Automatically generates forests 🆕<br>
|
73
76
|
🌊 Automatically generates water planes 🆕<br>
|
77
|
+
📈 Automatically generates splines 🆕<br>
|
74
78
|
🌍 Based on real-world data from OpenStreetMap<br>
|
79
|
+
🗺️ Supports [custom OSM maps](/docs/custom_osm.md)<br>
|
75
80
|
🏞️ Generates height map using SRTM dataset<br>
|
76
81
|
📦 Provides a ready-to-use map template for the Giants Editor<br>
|
77
82
|
🚜 Supports Farming Simulator 22 and 25<br>
|
@@ -79,7 +84,6 @@ Requires-Dist: pympler
|
|
79
84
|
📄 Generates scripts to download high-resolution satellite images from [QGIS](https://qgis.org/download/) in one click<br>
|
80
85
|
📕 Detailed [documentation](/docs) and tutorials <br>
|
81
86
|
🧰 Modder Toolbox to help you with various tasks <br>
|
82
|
-
|
83
87
|
<p align="center">
|
84
88
|
<img src="https://github.com/user-attachments/assets/cf8f5752-9c69-4018-bead-290f59ba6976"><br>
|
85
89
|
🌎 Detailed terrain based on real-world data.<br><br>
|
@@ -93,6 +97,8 @@ Requires-Dist: pympler
|
|
93
97
|
🌲 Automatically generates forests.<br><br>
|
94
98
|
<img src="https://github.com/user-attachments/assets/cce7d4e0-cba2-4dd2-b22d-03137fb2e860"><br>
|
95
99
|
🌊 Automatically generates water planes.<br><br>
|
100
|
+
<img src="https://github.com/user-attachments/assets/0b05b511-a595-48e7-a353-8298081314a4"><br>
|
101
|
+
📈 Automatically generates splines.<br><br>
|
96
102
|
<img src="https://github.com/user-attachments/assets/80e5923c-22c7-4dc0-8906-680902511f3a"><br>
|
97
103
|
🗒️ True-to-life blueprints for fast and precise modding.<br><br>
|
98
104
|
<img width="480" src="https://github.com/user-attachments/assets/1a8802d2-6a3b-4bfa-af2b-7c09478e199b"><br>
|
@@ -110,14 +116,7 @@ Requires-Dist: pympler
|
|
110
116
|
## Quick Start
|
111
117
|
There are several ways to use the tool. You obviously need the **first one**, but you can choose any of the others depending on your needs.<br>
|
112
118
|
### 🚜 For most users
|
113
|
-
**Option 1:** Open the [maps4fs](https://maps4fs.
|
114
|
-
<i>Note, that StreamLit community hosting has some limitations, such as: <br>
|
115
|
-
1. Maximum map size is 4096x4096 meters. <br>
|
116
|
-
2. Advanced settings are disabled. <br>
|
117
|
-
3. Texture dissolving is disabled (they will look worse). </i><br>
|
118
|
-
|
119
|
-
If you run the application locally, you won't have any of these limitations and will be able to generate maps of any size with any settings you want and nice looking textures.<br>
|
120
|
-
So, jump to [Docker version](#option-2-docker-version) to launch the tool with one command and get the full experience.<br>
|
119
|
+
**Option 1:** Open the [maps4fs](https://maps4fs.xyz) and generate a map template in a few clicks.<br>
|
121
120
|
|
122
121
|

|
123
122
|
|
@@ -165,13 +164,13 @@ Don't know where to start? Don't worry, just follow this [step-by-step guide](do
|
|
165
164
|
|
166
165
|
## How-To-Run
|
167
166
|
|
168
|
-
### Option 1:
|
169
|
-
🟢 Recommended for all users.
|
167
|
+
### Option 1: Public version
|
168
|
+
🟢 Recommended for all users.
|
170
169
|
🛠️ Don't need to install anything.
|
171
|
-
🗺️ Supported map sizes: 2x2, 4x4 km.
|
172
|
-
⚙️ Advanced settings:
|
173
|
-
🖼️ Texture dissolving:
|
174
|
-
Using the [
|
170
|
+
🗺️ Supported map sizes: 2x2, 4x4, 8x8 km.
|
171
|
+
⚙️ Advanced settings: enabled.
|
172
|
+
🖼️ Texture dissolving: enabled.
|
173
|
+
Using the public version on [maps4fs.xyz](https://maps4fs.xyz) is the easiest way to generate a map template. Just open the link and follow the instructions.
|
175
174
|
Note: due to CPU and RAM limitations of the hosting, the generation may take some time. If you need faster processing, use the [Docker version](#option-2-docker-version).<br>
|
176
175
|
|
177
176
|
Using it is easy and doesn't require any guides. Enjoy!
|
@@ -258,18 +257,12 @@ Tools are divided into categories, which are listed below.
|
|
258
257
|
|
259
258
|
## Supported objects
|
260
259
|
The project is based on the [OpenStreetMap](https://www.openstreetmap.org/) data. So, refer to [this page](https://wiki.openstreetmap.org/wiki/Map_Features) to understand the list below.
|
261
|
-
|
262
|
-
|
263
|
-
-
|
264
|
-
-
|
265
|
-
|
266
|
-
-
|
267
|
-
- "natural": ["water"]
|
268
|
-
- "waterway": True
|
269
|
-
- "natural": ["wood", "tree_row"]
|
270
|
-
- "railway": True
|
271
|
-
|
272
|
-
The list will be updated as the project develops.
|
260
|
+
|
261
|
+
You can find the active schemas here:
|
262
|
+
- [FS25](/data/fs25-texture-schema.json)
|
263
|
+
- [FS22](/data/fs22-texture-schema.json)
|
264
|
+
|
265
|
+
Learn more how to work with the schema in the [Texture schema](#texture-schema) section. You can also use your own schema in the [Expert settings](#expert-settings) section.
|
273
266
|
|
274
267
|
## Generation info
|
275
268
|
The script will generate the `generation_info.json` file in the `output` folder. It is split into different sections, which represent the components of the map generator. You may need this information to use some other tools and services to obtain additional data for your map.<br>
|
@@ -420,6 +413,10 @@ Let's have a closer look at the fields:
|
|
420
413
|
- `priority` - the priority of the texture for overlapping. Textures with higher priorities will be drawn over the textures with lower priorities.
|
421
414
|
ℹ️ The texture with 0 priority considers the base layer, which means that all empty areas will be filled with this texture.
|
422
415
|
- `exclude_weight` - this is only used for the forestRockRoots texture from FS25. It just means that this texture has no `weight` postfix, that's all.
|
416
|
+
- `usage` - the usage of the texture. Mainly used to group different textures by the purpose. For example, the `grass`, `forest`, `drain`.
|
417
|
+
- `background` - set it to True for the textures, which should have impact on the Background Terrain, by default it's used to subtract the water depth from the DEM and background terrain.
|
418
|
+
- `info_layer` - if the layer is saving some data in JSON format, this section will describe it's name in the JSON file. Used to find the needed JSON data, for example for fields it will be `fields` and as a value - list of polygon coordinates.
|
419
|
+
- `invisible` - set it to True for the textures, which should not be drawn in the files, but only to save the data in the JSON file (related to the previous field).
|
423
420
|
|
424
421
|
## Background terrain
|
425
422
|
The tool now supports the generation of the background terrain. If you don't know what it is, here's a brief explanation. The background terrain is the world around the map. It's important to create it because if you don't, the map will look like it's floating in the void. The background terrain is a simple plane that can (and should) be textured to look fine.<br>
|
@@ -476,27 +473,58 @@ You can also apply some advanced settings to the map generation process. Note th
|
|
476
473
|
|
477
474
|
### DEM Advanced settings
|
478
475
|
|
476
|
+
- Auto process: the tool will automatically try to find suitable multiplier. As a result, the DEM image WILL not match real world values. If this option is disabled, you'll probably see completely black DEM image, but it's not empty. It's just you can't see the values of 16-bit image by eye, because they're too small. Learn more what's DEM image and how to work with it in [docs](docs/dem.md). By default, it's set to True.
|
477
|
+
|
479
478
|
- Multiplier: the height of the map is multiplied by this value. So the DEM map is just a 16-bit grayscale image, which means that the maximum available value there is 65535, while the actual difference between the deepest and the highest point on Earth is about 20 km. Just note that this setting mostly does not matter, because you can always adjust it in the Giants Editor, learn more about the DEM file and the heightScale parameter in [docs](docs/dem.md). By default, it's set to 1.
|
480
479
|
|
481
480
|
- Blur radius: the radius of the Gaussian blur filter applied to the DEM map. By default, it's set to 21. This filter just makes the DEM map smoother, so the height transitions will be more natural. You can set it to 1 to disable the filter, but it will result in a Minecraft-like map.
|
482
481
|
|
483
|
-
- Plateau
|
482
|
+
- Plateau: this value will be added to each pixel of the DEM image, making it "higher". It's useful when you want to add some negative heights on the map, that appear to be in a "low" place. By default, it's set to 0.
|
484
483
|
|
485
484
|
- Water depth: this value will be subtracted from each pixel of the DEM image, where water resources are located. Pay attention that it's not in meters, instead it in the pixel value of DEM, which is 16 bit image with possible values from 0 to 65535. When this value is set, the same value will be added to the plateau setting to avoid negative heights.
|
486
485
|
|
487
|
-
###
|
486
|
+
### Background terrain Advanced settings
|
488
487
|
|
489
|
-
-
|
488
|
+
- Generate background - if enabled, the obj files for the background terrain will be generated. You can turn it off if you already have those files or don't need them. By default, it's set to True.
|
489
|
+
|
490
|
+
- Generate water - if enabled, the water planes obj files will be generated. You can turn it off if you already have those files or don't need them. By default, it's set to True.
|
491
|
+
|
492
|
+
- Resize factor - the factor by which the background terrain will be resized. It will be used as 1 / resize_factor while generating the models. Which means that the larger the value the more the terrain will be resized. The lowest value is 1, in this case background terrain will not be resized. Note, than low values will lead to long processing and enormous size of the obj files.
|
490
493
|
|
491
|
-
###
|
494
|
+
### GRLE Advanced settings
|
492
495
|
|
493
496
|
- Farmlands margin - this value (in meters) will be applied to each farmland, making it bigger. You can use the value to adjust how much the farmland should be bigger than the actual field. By default, it's set to 3.
|
494
497
|
|
495
|
-
|
498
|
+
- Random plants - when adding decorative foliage, enabling this option will add different species of plants to the map. If unchecked only basic grass (smallDenseMix) will be added. Defaults to True.
|
499
|
+
|
500
|
+
- Add Farmyards - if enabled, the tool will create farmlands from the regions that are marked as farmyards in the OSM data. Those farmlands will not have fields and also will not be drawn on textures. By default, it's turned off.
|
501
|
+
|
502
|
+
### I3D Advanced settings
|
496
503
|
|
497
504
|
- 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.
|
498
505
|
|
499
|
-
|
506
|
+
### Texture Advanced settings
|
507
|
+
|
508
|
+
- 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.
|
509
|
+
|
510
|
+
- Fields padding - this value (in meters) will be applied to each field, making it smaller. It's useful when the fields are too close to each other and you want to make them smaller. By default, it's set to 0.
|
511
|
+
|
512
|
+
- Skip drains - if enabled, the tool will not generate the drains and ditches on the map. By default, it's set to False. Use this if you don't need the drains on the map.
|
513
|
+
|
514
|
+
## Splines Advanced settings
|
515
|
+
|
516
|
+
- Splines density - number of points, which will be added (interpolate) between each pair of existing points. The higher the value, the denser the spline will be. It can smooth the splines, but high values can in opposite make the splines look unnatural.
|
517
|
+
|
518
|
+
## Expert Settings
|
519
|
+
The tool also supports the expert settings. Do not use them until you read the documentation and understand what they do. Here's the list of the expert settings:
|
520
|
+
|
521
|
+
- Enable debug logs - if enabled, the tool will print the debug logs to the console. It can be useful if you're using with a custom OSM map, have some issues with it and want to know what's wrong.
|
522
|
+
|
523
|
+
- Upload custom OSM file - you'll be able to upload your own OSM file. Before using it, carefully read the [Custom OSM](docs/custom_osm.md) documentation, otherwise, the tool will not work as expected.
|
524
|
+
|
525
|
+
- Show raw configuration - you'll be able to change all the settings in a single JSON file. It's useful if you want to save the configuration and use it later, without changing the settings in the UI. Be extremely careful with this setting, because you can break the tool with incorrect settings.
|
526
|
+
|
527
|
+
- Show schemas - you'll be able to edit or define your own texture or tree schemas. It's useful if you want to add some custom textures or trees to the map. Refer to the [Texture schema](#texture-schema) section to learn more about the schema structure. Any incorrect value here will lead to the completely broken map.
|
500
528
|
|
501
529
|
## Resources
|
502
530
|
In this section, you'll find a list of the resources that you need to create a map for the Farming Simulator.<br>
|
@@ -522,3 +550,8 @@ But also, I want to thank the people who helped me with the project in some way,
|
|
522
550
|
- [Ka5tis](https://github.com/Ka5tis) - for investigating the issue with a "spiky terrain" and finding a solution - changing the `DisplacementLayer` size to a higher value.
|
523
551
|
- [Kalderone](https://www.youtube.com/@Kalderone_FS22) - for useful feedback, suggestions, expert advice on the map-making process and highlihting some important settings in the Giants Editor.
|
524
552
|
- [OneSunnySunday](https://www.artstation.com/onesunnysunday) - for expert advice on Blender, help in processing background terrain, and compiling detailed tutorials on how to prepare the OBJ files for use in Giants Editor.
|
553
|
+
- [BFernaesds](https://github.com/BFernaesds) - for the manual tests of the app.
|
554
|
+
- [gamerdesigns](https://github.com/gamerdesigns) - for the manual tests of the app.
|
555
|
+
- [Tox3](https://github.com/Tox3) - for the manual tests of the app.
|
556
|
+
- [Lucandia](https://github.com/Lucandia) - for the awesome StreamLit [widget to preview STL files](https://github.com/Lucandia/streamlit_stl).
|
557
|
+
- [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.
|
@@ -0,0 +1,21 @@
|
|
1
|
+
maps4fs/__init__.py,sha256=LMzzORK3Q3OjXmmRJ03CpS2SMP6zTwKNnUUei3P7s40,300
|
2
|
+
maps4fs/logger.py,sha256=B-NEYpMjPAAqlV4VpfTi6nbBFnEABVtQOaYe6nMpidg,1489
|
3
|
+
maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
4
|
+
maps4fs/generator/background.py,sha256=ySABP9HLji8R0aXi1BwjUQtP2uDqZPkrlmugowa9Gkk,22836
|
5
|
+
maps4fs/generator/component.py,sha256=58UQgdR-7KlWHTfwLesNNK76BTRsiVngRa6B64OKjhc,20065
|
6
|
+
maps4fs/generator/config.py,sha256=0QmK052B8bxyHVhg3jzCORLfOBMMmqVfhhbqXKf6OMk,4383
|
7
|
+
maps4fs/generator/dem.py,sha256=MZf3ZjawJ977TxqB1q9nNpvPZUNwfmm2EaJDtVU-eCU,15939
|
8
|
+
maps4fs/generator/game.py,sha256=jjo7CTwHHSkRpeD_QgRXkhR_NxI09C4kMxz-nYOTM4A,7931
|
9
|
+
maps4fs/generator/grle.py,sha256=u8ZwSs313PIOkH_0B_O2tVTaZ-eYNkc30eKGtBxWzTM,17846
|
10
|
+
maps4fs/generator/i3d.py,sha256=qeZYqfuhbhRPlSAuQHXaq6RmIO7314oMN68Ivebp1YQ,24786
|
11
|
+
maps4fs/generator/map.py,sha256=jIdekpiymhHqKx4FaAwjtq3hMnRdKYo6TvJLX1fSD0k,12814
|
12
|
+
maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
|
13
|
+
maps4fs/generator/texture.py,sha256=sErusfv1AqQfP-veMrZ921Tz8DnGEhfB4ucggMmKrD4,31231
|
14
|
+
maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
15
|
+
maps4fs/toolbox/background.py,sha256=9BXWNqs_n3HgqDiPztWylgYk_QM4YgBpe6_ZNQAWtSc,2154
|
16
|
+
maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
|
17
|
+
maps4fs-1.5.0.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
|
18
|
+
maps4fs-1.5.0.dist-info/METADATA,sha256=JZXcCZU91J0GD2q1YKooz_52UeA8DeCgbuv2zRrnTsQ,35026
|
19
|
+
maps4fs-1.5.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
20
|
+
maps4fs-1.5.0.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
|
21
|
+
maps4fs-1.5.0.dist-info/RECORD,,
|
maps4fs-1.2.4.dist-info/RECORD
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
maps4fs/__init__.py,sha256=da4jmND2Ths9AffnkAKgzLHNkvKFOc_l21gJisPXqWY,155
|
2
|
-
maps4fs/logger.py,sha256=B-NEYpMjPAAqlV4VpfTi6nbBFnEABVtQOaYe6nMpidg,1489
|
3
|
-
maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
4
|
-
maps4fs/generator/background.py,sha256=21xB-xn2A6QGdX9UVWqvzoW-L6JWPAZOqCcIhR8nxKU,22689
|
5
|
-
maps4fs/generator/component.py,sha256=SeI1xfwo9I4lrkcOcHyjxMffHsG8OXc80-mNsR2zpPw,17748
|
6
|
-
maps4fs/generator/config.py,sha256=b7qY0luC-_WM_c72Ohtlf4FrB37X5cALInbestSdUsw,4382
|
7
|
-
maps4fs/generator/dem.py,sha256=rc7ADzjvlZzStOqagsWW0Vrm9-X86aPpoR1RhBF_-OE,16025
|
8
|
-
maps4fs/generator/game.py,sha256=ZQeYzPzPB3CG41avdhNCyTZpHEeedqNBuAbNevTZuXg,7931
|
9
|
-
maps4fs/generator/grle.py,sha256=3hcr5e2YLXemFi-_x2cLHWbMVb06591k0PZxaBVovH8,17600
|
10
|
-
maps4fs/generator/i3d.py,sha256=oK5pKjzvT-gydma5Q6CcDYTVODGxK7MIGajLrAV9JkU,18370
|
11
|
-
maps4fs/generator/map.py,sha256=lA1MNAcMwsDtsYxbwwm7DjwP3zraHKnri_xnLUu30j0,5326
|
12
|
-
maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
|
13
|
-
maps4fs/generator/texture.py,sha256=vgiwJNIl14JABhNOBGh_W8SBkAUNQN3TjNJayR76va0,27468
|
14
|
-
maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
|
15
|
-
maps4fs/toolbox/background.py,sha256=9BXWNqs_n3HgqDiPztWylgYk_QM4YgBpe6_ZNQAWtSc,2154
|
16
|
-
maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
|
17
|
-
maps4fs-1.2.4.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
|
18
|
-
maps4fs-1.2.4.dist-info/METADATA,sha256=cR3704tYCx9AaL8NW5cLrkMijvDNyWdxT7CpCaTv9NE,30600
|
19
|
-
maps4fs-1.2.4.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
20
|
-
maps4fs-1.2.4.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
|
21
|
-
maps4fs-1.2.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|