maps4fs 1.8.236__py3-none-any.whl → 1.8.238__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.
@@ -3,13 +3,13 @@ around the map."""
3
3
 
4
4
  from __future__ import annotations
5
5
 
6
- import json
7
6
  import os
8
7
  import shutil
9
8
  from copy import deepcopy
10
9
 
11
10
  import cv2
12
11
  import numpy as np
12
+ from tqdm import tqdm
13
13
 
14
14
  from maps4fs.generator.component.base.component_image import ImageComponent
15
15
  from maps4fs.generator.component.base.component_mesh import MeshComponent
@@ -101,6 +101,56 @@ class Background(MeshComponent, ImageComponent):
101
101
  if self.map.background_settings.generate_water:
102
102
  self.generate_water_resources_obj()
103
103
 
104
+ def create_foundations(self, dem_image: np.ndarray) -> np.ndarray:
105
+ """Creates foundations for buildings based on the DEM data.
106
+
107
+ Arguments:
108
+ dem_image (np.ndarray): The DEM data as a numpy array.
109
+
110
+ Returns:
111
+ np.ndarray: The DEM data with the foundations added.
112
+ """
113
+ buildings = self.get_infolayer_data(Parameters.TEXTURES, Parameters.BUILDINGS)
114
+ if not buildings:
115
+ self.logger.warning("Buildings data not found in textures info layer.")
116
+ return dem_image
117
+
118
+ self.logger.debug("Found %s buildings in textures info layer.", len(buildings))
119
+
120
+ for building in tqdm(buildings, desc="Creating foundations", unit="building"):
121
+ try:
122
+ fitted_building = self.fit_object_into_bounds(
123
+ polygon_points=building, angle=self.rotation
124
+ )
125
+ except ValueError as e:
126
+ self.logger.debug(
127
+ "Building could not be fitted into the map bounds with error: %s",
128
+ e,
129
+ )
130
+ continue
131
+
132
+ # 1. Read the pixel values from the DEM image.
133
+ # 2. Calculate the average pixel value of the building area.
134
+ # 3. Set the pixel values in the DEM to the average pixel value.
135
+
136
+ building_np = self.polygon_points_to_np(fitted_building)
137
+ mask = np.zeros(dem_image.shape, dtype=np.uint8)
138
+
139
+ try:
140
+ cv2.fillPoly(mask, [building_np], 255) # type: ignore
141
+ except Exception as e:
142
+ self.logger.debug("Could not create mask for building with error: %s", e)
143
+ continue
144
+
145
+ mean_value = cv2.mean(dem_image, mask=mask)[0]
146
+ mean_value = np.round(mean_value).astype(dem_image.dtype)
147
+ self.logger.info("Mean value of the building area: %s", mean_value)
148
+
149
+ # Set the pixel values in the DEM to the average pixel value.
150
+ dem_image[mask == 255] = mean_value
151
+
152
+ return dem_image
153
+
104
154
  def make_copy(self, dem_path: str, dem_name: str) -> None:
105
155
  """Copies DEM data to additional DEM file.
106
156
 
@@ -198,6 +248,9 @@ class Background(MeshComponent, ImageComponent):
198
248
  self.logger.debug("Not resized DEM saved: %s", save_path)
199
249
  return save_path
200
250
 
251
+ if self.map.dem_settings.add_foundations:
252
+ dem_data = self.create_foundations(dem_data)
253
+
201
254
  output_size = self.map_size + 1
202
255
 
203
256
  main_dem_path = self.game.dem_file_path(self.map_directory)
@@ -347,13 +400,11 @@ class Background(MeshComponent, ImageComponent):
347
400
 
348
401
  def create_background_textures(self) -> None:
349
402
  """Creates background textures for the map."""
350
- if not os.path.isfile(self.game.texture_schema):
351
- self.logger.warning("Texture schema file not found: %s", self.game.texture_schema)
403
+ layers_schema = self.map.texture_schema
404
+ if not layers_schema:
405
+ self.logger.warning("No texture schema found.")
352
406
  return
353
407
 
354
- with open(self.game.texture_schema, "r", encoding="utf-8") as f:
355
- layers_schema = json.load(f)
356
-
357
408
  background_layers = []
358
409
  for layer in layers_schema:
359
410
  if layer.get("background") is True:
maps4fs/generator/map.py CHANGED
@@ -184,6 +184,18 @@ class Map:
184
184
  except Exception as e:
185
185
  raise RuntimeError(f"Can not unpack map template due to error: {e}") from e
186
186
 
187
+ @property
188
+ def texture_schema(self) -> list[dict[str, Any]] | None:
189
+ """Return texture schema (custom if provided, default otherwise).
190
+
191
+ Returns:
192
+ list[dict[str, Any]] | None: Texture schema.
193
+ """
194
+ if self.texture_custom_schema:
195
+ return self.texture_custom_schema
196
+ with open(self.game.texture_schema, "r", encoding="utf-8") as file:
197
+ return json.load(file)
198
+
187
199
  def generate(self) -> Generator[str, None, None]:
188
200
  """Launch map generation using all components. Yield component names during the process.
189
201
 
@@ -13,6 +13,7 @@ class Parameters:
13
13
 
14
14
  FIELD = "field"
15
15
  FIELDS = "fields"
16
+ BUILDINGS = "buildings"
16
17
  TEXTURES = "textures"
17
18
  FOREST = "forest"
18
19
  ROADS_POLYLINES = "roads_polylines"
@@ -133,6 +134,7 @@ class DEMSettings(SettingsModel):
133
134
  ceiling: int = 0
134
135
  water_depth: int = 0
135
136
  blur_radius: int = 3
137
+ add_foundations: bool = False
136
138
 
137
139
 
138
140
  class BackgroundSettings(SettingsModel):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: maps4fs
3
- Version: 1.8.236
3
+ Version: 1.8.238
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
@@ -590,6 +590,8 @@ You can also apply some advanced settings to the map generation process.<br>
590
590
 
591
591
  - Water depth: Water depth value (in meters) will be subtracted from the DEM image, making the water deeper. The pixel value used for this is calculated based on the heightScale value for your map.
592
592
 
593
+ - Add foundations: If enabled the terrain under the buildings will be flattened to the average height of the building.
594
+
593
595
  ### Background terrain Advanced settings
594
596
 
595
597
  - 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.
@@ -3,12 +3,12 @@ maps4fs/logger.py,sha256=HQrDyj72mUjVYo25aR_-_SxVn2rfFjDCNbj-JKJdSnE,1488
3
3
  maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
4
4
  maps4fs/generator/dem.py,sha256=a9B3tatj7pzvvdLIyLw7BA3JoDTibFczpqiXJnx054U,12864
5
5
  maps4fs/generator/game.py,sha256=NZaxj5z7WzMiHzAvQyr-TvVjGoHgqGldM6ZsItuYyzA,11292
6
- maps4fs/generator/map.py,sha256=tgbpu3xxtFFWMualvaOnfnBXjDYWqAa_xIpu-OvcnbQ,12636
6
+ maps4fs/generator/map.py,sha256=9tQTEMYvh4RSC5ACp7fE7RhVDGa7Mc-P5W95h-Zineg,13069
7
7
  maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
8
- maps4fs/generator/settings.py,sha256=DJCG--Z__JBEc-fllWOvnb4roYuNFv7bSkAclUZV2gE,6786
8
+ maps4fs/generator/settings.py,sha256=-QdpmIoMiWXPeqYX5QQ5Pplz9xHk2OnyBdzRIc7aB44,6848
9
9
  maps4fs/generator/statistics.py,sha256=aynS3zbAtiwnU_YLKHPTiiaKW98_suvQUhy1SGBA6mc,2448
10
10
  maps4fs/generator/component/__init__.py,sha256=s01yVVVi8R2xxNvflu2D6wTd9I_g73AMM2x7vAC7GX4,490
11
- maps4fs/generator/component/background.py,sha256=7YkSFrbPHN_dTh4xB1lM60mloLJXOdXZw19T0Gs4x1k,18971
11
+ maps4fs/generator/component/background.py,sha256=RpEjOW7ray0h_Jd6Mf8XEzGjKtJeYPzze9bPT8M1fhA,21011
12
12
  maps4fs/generator/component/config.py,sha256=RitKgFDZPzjA1fi8GcEi1na75qqaueUvpcITHjBvCXc,3674
13
13
  maps4fs/generator/component/grle.py,sha256=C6wpYQrJBVRb3vVbEAY5BYTRYU9BaefmoWCXoPrVn2A,19454
14
14
  maps4fs/generator/component/i3d.py,sha256=yWGs5eBuBT7V4F6SbTNAmF-8fj2Zy4kcC5OKZ_XVICs,21329
@@ -53,8 +53,8 @@ maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,4
53
53
  maps4fs/toolbox/background.py,sha256=RclEqxEWLbMxuEkkegQP8jybzugwQ1_R3rdfDe0s21U,2104
54
54
  maps4fs/toolbox/custom_osm.py,sha256=X6ZlPqiOhNjkmdD_qVroIfdOl9Rb90cDwVSLDVYgx80,1892
55
55
  maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
56
- maps4fs-1.8.236.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
57
- maps4fs-1.8.236.dist-info/METADATA,sha256=mZfVF18tG8BlX96UWN_T35hCIGaveTOGUpAjwAXsIQY,46039
58
- maps4fs-1.8.236.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
59
- maps4fs-1.8.236.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
60
- maps4fs-1.8.236.dist-info/RECORD,,
56
+ maps4fs-1.8.238.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
57
+ maps4fs-1.8.238.dist-info/METADATA,sha256=5zXEOsIxjrknQLlwShN1CsM7Br62aJUMaDJ2F2UlGec,46159
58
+ maps4fs-1.8.238.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
59
+ maps4fs-1.8.238.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
60
+ maps4fs-1.8.238.dist-info/RECORD,,