maps4fs 1.8.231__py3-none-any.whl → 1.8.232__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.
@@ -13,6 +13,8 @@ from maps4fs.generator.component.base.component_image import ImageComponent
13
13
  from maps4fs.generator.component.base.component_xml import XMLComponent
14
14
  from maps4fs.generator.settings import Parameters
15
15
 
16
+ FARMLAND_ID_LIMIT = 254
17
+
16
18
 
17
19
  def plant_to_pixel_value(plant_name: str) -> int | None:
18
20
  """Returns the pixel value representation of the plant.
@@ -225,6 +227,13 @@ class GRLE(ImageComponent, XMLComponent):
225
227
 
226
228
  farmland_np = self.polygon_points_to_np(fitted_farmland, divide=2)
227
229
 
230
+ if farmland_id > FARMLAND_ID_LIMIT:
231
+ self.logger.warning(
232
+ "Farmland ID limit reached. Skipping the rest of the farmlands. "
233
+ "Giants Editor supports maximum 254 farmlands."
234
+ )
235
+ break
236
+
228
237
  try:
229
238
  cv2.fillPoly(image, [farmland_np], (float(farmland_id),))
230
239
  except Exception as e:
@@ -246,6 +255,10 @@ class GRLE(ImageComponent, XMLComponent):
246
255
 
247
256
  self.save_tree(tree)
248
257
 
258
+ # Replace all the zero values on the info layer image with 255.
259
+ if self.map.grle_settings.fill_empty_farmlands:
260
+ image[image == 0] = 255
261
+
249
262
  cv2.imwrite(info_layer_farmlands_path, image)
250
263
 
251
264
  self.preview_paths["farmlands"] = info_layer_farmlands_path
@@ -18,7 +18,6 @@ from maps4fs.generator.settings import Parameters
18
18
  NODE_ID_STARTING_VALUE = 2000
19
19
  SPLINES_NODE_ID_STARTING_VALUE = 5000
20
20
  TREE_NODE_ID_STARTING_VALUE = 10000
21
- TREES_DEFAULT_Z_VALUE = 400
22
21
 
23
22
  FIELDS_ATTRIBUTES = [
24
23
  ("angle", "integer", "0"),
@@ -132,17 +131,10 @@ class I3d(XMLComponent):
132
131
  self.logger.warning("Shapes or Scene node not found in I3D file.")
133
132
  return
134
133
 
135
- # Read the not resized DEM to obtain Z values for spline points.
136
- background_component = self.map.get_background_component()
137
- if not background_component:
138
- self.logger.warning("Background component not found.")
139
- return
140
-
141
- not_resized_dem = cv2.imread(background_component.not_resized_path, cv2.IMREAD_UNCHANGED)
134
+ not_resized_dem = self.get_not_resized_dem()
142
135
  if not_resized_dem is None:
143
136
  self.logger.warning("Not resized DEM not found.")
144
137
  return
145
- dem_x_size, dem_y_size = not_resized_dem.shape
146
138
 
147
139
  user_attributes_node = root.find(".//UserAttributes")
148
140
  if user_attributes_node is None:
@@ -201,11 +193,7 @@ class I3d(XMLComponent):
201
193
  cx, cy = point_ccs
202
194
  x, y = point
203
195
 
204
- x = max(0, min(int(x), dem_x_size - 1))
205
- y = max(0, min(int(y), dem_y_size - 1))
206
-
207
- z = not_resized_dem[y, x]
208
- z *= self.get_z_scaling_factor()
196
+ z = self.get_z_coordinate_from_dem(not_resized_dem, x, y)
209
197
 
210
198
  nurbs_curve_node.append(self.create_element("cv", {"c": f"{cx}, {z}, {cy}"}))
211
199
 
@@ -471,31 +459,41 @@ class I3d(XMLComponent):
471
459
  "TransformGroup",
472
460
  {
473
461
  "name": "trees",
474
- "translation": f"0 {TREES_DEFAULT_Z_VALUE} 0",
462
+ "translation": "0 0 0",
475
463
  "nodeId": str(node_id),
476
464
  },
477
465
  )
478
466
  node_id += 1
479
467
 
468
+ not_resized_dem = self.get_not_resized_dem()
469
+ if not_resized_dem is None:
470
+ self.logger.warning("Not resized DEM not found.")
471
+ return
472
+
480
473
  forest_image = cv2.imread(forest_image_path, cv2.IMREAD_UNCHANGED)
481
474
  for x, y in self.non_empty_pixels(forest_image, step=self.map.i3d_settings.forest_density):
482
- xcs, ycs = self.top_left_coordinates_to_center((x, y))
483
- node_id += 1
484
-
485
- rotation = randint(-180, 180)
486
- shifted_xcs, shifted_ycs = self.randomize_coordinates(
487
- (xcs, ycs),
475
+ shifted_x, shifted_y = self.randomize_coordinates(
476
+ (x, y),
488
477
  self.map.i3d_settings.forest_density,
489
478
  self.map.i3d_settings.trees_relative_shift,
490
479
  )
491
480
 
481
+ shifted_x, shifted_y = int(shifted_x), int(shifted_y)
482
+
483
+ z = self.get_z_coordinate_from_dem(not_resized_dem, shifted_x, shifted_y)
484
+
485
+ xcs, ycs = self.top_left_coordinates_to_center((shifted_x, shifted_y))
486
+ node_id += 1
487
+
488
+ rotation = randint(-180, 180)
489
+
492
490
  random_tree = choice(tree_schema)
493
491
  tree_name = random_tree["name"]
494
492
  tree_id = random_tree["reference_id"]
495
493
 
496
494
  data = {
497
495
  "name": tree_name,
498
- "translation": f"{shifted_xcs} 0 {shifted_ycs}",
496
+ "translation": f"{xcs} {z} {ycs}",
499
497
  "rotation": f"0 {rotation} 0",
500
498
  "referenceId": str(tree_id),
501
499
  "nodeId": str(node_id),
@@ -546,3 +544,43 @@ class I3d(XMLComponent):
546
544
  for x, value in enumerate(row[::step]):
547
545
  if value > 0:
548
546
  yield x * step, y * step
547
+
548
+ def get_not_resized_dem(self) -> np.ndarray | None:
549
+ """Reads the not resized DEM image from the background component.
550
+
551
+ Returns:
552
+ np.ndarray | None: The not resized DEM image or None if the image could not be read.
553
+ """
554
+ background_component = self.map.get_background_component()
555
+ if not background_component:
556
+ self.logger.warning("Background component not found.")
557
+ return None
558
+
559
+ if not background_component.not_resized_path:
560
+ self.logger.warning("Not resized DEM path not found.")
561
+ return None
562
+
563
+ not_resized_dem = cv2.imread(background_component.not_resized_path, cv2.IMREAD_UNCHANGED)
564
+
565
+ return not_resized_dem
566
+
567
+ def get_z_coordinate_from_dem(self, not_resized_dem: np.ndarray, x: int, y: int) -> float:
568
+ """Gets the Z coordinate from the DEM image for the given coordinates.
569
+
570
+ Arguments:
571
+ not_resized_dem (np.ndarray): The not resized DEM image.
572
+ x (int): The x coordinate.
573
+ y (int): The y coordinate.
574
+
575
+ Returns:
576
+ float: The Z coordinate.
577
+ """
578
+ dem_x_size, dem_y_size = not_resized_dem.shape
579
+
580
+ x = int(max(0, min(x, dem_x_size - 1)))
581
+ y = int(max(0, min(y, dem_y_size - 1)))
582
+
583
+ z = not_resized_dem[y, x]
584
+ z *= self.get_z_scaling_factor()
585
+
586
+ return z
@@ -175,6 +175,7 @@ class GRLESettings(SettingsModel):
175
175
  plants_island_vertex_count: int = 30
176
176
  plants_island_rounding_radius: int = 15
177
177
  plants_island_percent: int = 100
178
+ fill_empty_farmlands: bool = False
178
179
 
179
180
 
180
181
  class I3DSettings(SettingsModel):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: maps4fs
3
- Version: 1.8.231
3
+ Version: 1.8.232
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
@@ -628,6 +628,8 @@ You can also apply some advanced settings to the map generation process.<br>
628
628
 
629
629
  - Plants island percent - defines the relation between the map size and the number of islands of plants. For example, if set to 100% for map size of 2048 will be added 2048 islands of plants.
630
630
 
631
+ - Fill empty farmlands - if enabled, the empty (zero value) pixels of the farmlands image will be replaces with the value of 255.
632
+
631
633
  ### I3D Advanced settings
632
634
 
633
635
  - 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.
@@ -5,13 +5,13 @@ maps4fs/generator/dem.py,sha256=a9B3tatj7pzvvdLIyLw7BA3JoDTibFczpqiXJnx054U,1286
5
5
  maps4fs/generator/game.py,sha256=NZaxj5z7WzMiHzAvQyr-TvVjGoHgqGldM6ZsItuYyzA,11292
6
6
  maps4fs/generator/map.py,sha256=Tn33S8e7a2guvpjr1_GCpYIQFAz-ekkEUAobS02i6Xo,12669
7
7
  maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
8
- maps4fs/generator/settings.py,sha256=d3NaMpyFh-IZWtHV2UQMMqUfuPP76lv7mIN2d7mORqA,6747
8
+ maps4fs/generator/settings.py,sha256=DJCG--Z__JBEc-fllWOvnb4roYuNFv7bSkAclUZV2gE,6786
9
9
  maps4fs/generator/statistics.py,sha256=JfhiGDZf2-VoWZbL-Kikzv4_DqerYwKcseccVL9qzXo,1783
10
10
  maps4fs/generator/component/__init__.py,sha256=s01yVVVi8R2xxNvflu2D6wTd9I_g73AMM2x7vAC7GX4,490
11
11
  maps4fs/generator/component/background.py,sha256=7YkSFrbPHN_dTh4xB1lM60mloLJXOdXZw19T0Gs4x1k,18971
12
12
  maps4fs/generator/component/config.py,sha256=RitKgFDZPzjA1fi8GcEi1na75qqaueUvpcITHjBvCXc,3674
13
- maps4fs/generator/component/grle.py,sha256=kCx00SJdYEDr0tcHFvHC99928e9Eke2t_LwNxkqfvBg,18984
14
- maps4fs/generator/component/i3d.py,sha256=tUvN-nA0Zl-HMplvWJSuHI22aUSMZQqXMXYJFPnhnug,20146
13
+ maps4fs/generator/component/grle.py,sha256=C6wpYQrJBVRb3vVbEAY5BYTRYU9BaefmoWCXoPrVn2A,19454
14
+ maps4fs/generator/component/i3d.py,sha256=AKS3FS4pdsWR0GxCar1F9_jREfUH-7CqR7vxdiVmXao,21294
15
15
  maps4fs/generator/component/layer.py,sha256=QPcEzTv_8N9wYvHAZy8OezfATaVLG-YetSfCXf2lnFI,5892
16
16
  maps4fs/generator/component/satellite.py,sha256=oZBHjP_QY0ik1-Vk7JqMS__zIG8ffw2voeozB7-HUQc,4946
17
17
  maps4fs/generator/component/texture.py,sha256=GWOE7w2maydB2LDku-YEC1w1oc8kcnnZ1SPTL6b82H8,30966
@@ -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.231.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
57
- maps4fs-1.8.231.dist-info/METADATA,sha256=MxaS-z4S5AOoI7BRem0WBnxWpK7JlvijIcopSntdkeU,45770
58
- maps4fs-1.8.231.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
59
- maps4fs-1.8.231.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
60
- maps4fs-1.8.231.dist-info/RECORD,,
56
+ maps4fs-1.8.232.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
57
+ maps4fs-1.8.232.dist-info/METADATA,sha256=2R9A1R0ESS6QCB7LMcSpVUo6vSUOshtR7ZETKcVaVeI,45901
58
+ maps4fs-1.8.232.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
59
+ maps4fs-1.8.232.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
60
+ maps4fs-1.8.232.dist-info/RECORD,,