maps4fs 1.0.7__py3-none-any.whl → 1.0.8__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.
@@ -184,6 +184,7 @@ class Background(Component):
184
184
  dem_data = cv2.imread(tile.dem_path, cv2.IMREAD_UNCHANGED) # pylint: disable=no-member
185
185
  self.plane_from_np(tile.code, dem_data, save_path) # type: ignore
186
186
 
187
+ # pylint: disable=too-many-locals
187
188
  def cutout(self, dem_path: str) -> str:
188
189
  """Cuts out the center of the DEM (the actual map) and saves it as a separate file.
189
190
 
@@ -205,20 +206,40 @@ class Background(Component):
205
206
 
206
207
  output_size = self.map_height + 1
207
208
 
208
- # pylint: disable=no-member
209
- dem_data = cv2.resize(dem_data, (output_size, output_size), interpolation=cv2.INTER_LINEAR)
210
-
211
209
  main_dem_path = self.game.dem_file_path(self.map_directory)
210
+ dem_directory = os.path.dirname(main_dem_path)
212
211
 
213
212
  try:
214
213
  os.remove(main_dem_path)
215
214
  except FileNotFoundError:
216
215
  pass
217
216
 
218
- cv2.imwrite(main_dem_path, dem_data) # pylint: disable=no-member
219
- self.logger.info("DEM cutout saved: %s", main_dem_path)
217
+ # pylint: disable=no-member
218
+ resized_dem_data = cv2.resize(
219
+ dem_data, (output_size, output_size), interpolation=cv2.INTER_LINEAR
220
+ )
221
+
222
+ # Giant Editor contains a bug for large maps, where the DEM should not match
223
+ # the UnitsPerPixel value. For example, for map 8192x8192, without bug
224
+ # the DEM image should be 8193x8193, but it does not work, so we need to
225
+ # resize the DEM to 4097x4097.
226
+ if self.map_height > 4096:
227
+ correct_dem_path = os.path.join(dem_directory, "correct_dem.png")
228
+ save_path = correct_dem_path
229
+
230
+ output_size = self.map_height // 2 + 1
231
+ bugged_dem_data = cv2.resize(
232
+ dem_data, (output_size, output_size), interpolation=cv2.INTER_LINEAR
233
+ )
234
+ # pylint: disable=no-member
235
+ cv2.imwrite(main_dem_path, bugged_dem_data)
236
+ else:
237
+ save_path = main_dem_path
238
+
239
+ cv2.imwrite(save_path, resized_dem_data) # pylint: disable=no-member
240
+ self.logger.info("DEM cutout saved: %s", save_path)
220
241
 
221
- return main_dem_path
242
+ return save_path
222
243
 
223
244
  # pylint: disable=too-many-locals
224
245
  def plane_from_np(self, tile_code: str, dem_data: np.ndarray, save_path: str) -> None:
maps4fs/generator/i3d.py CHANGED
@@ -34,6 +34,8 @@ class I3d(Component):
34
34
  def preprocess(self) -> None:
35
35
  """Gets the path to the map I3D file from the game instance and saves it to the instance
36
36
  attribute. If the game does not support I3D files, the attribute is set to None."""
37
+ self.auto_process = self.kwargs.get("auto_process", False)
38
+
37
39
  try:
38
40
  self._map_i3d_path = self.game.i3d_file_path(self.map_directory)
39
41
  self.logger.debug("Map I3D path: %s.", self._map_i3d_path)
@@ -69,22 +71,16 @@ class I3d(Component):
69
71
  root = tree.getroot()
70
72
  for map_elem in root.iter("Scene"):
71
73
  for terrain_elem in map_elem.iter("TerrainTransformGroup"):
72
- terrain_elem.set("heightScale", str(DEFAULT_HEIGHT_SCALE))
73
- self.logger.debug(
74
- "heightScale attribute set to %s in TerrainTransformGroup element.",
75
- DEFAULT_HEIGHT_SCALE,
76
- )
77
- terrain_elem.set("maxLODDistance", str(DEFAULT_MAX_LOD_DISTANCE))
78
- self.logger.debug(
79
- "maxLODDistance attribute set to %s in TerrainTransformGroup element.",
80
- DEFAULT_MAX_LOD_DISTANCE,
81
- )
82
-
83
- terrain_elem.set("occMaxLODDistance", str(DEFAULT_MAX_LOD_OCCLUDER_DISTANCE))
84
- self.logger.debug(
85
- "occMaxLODDistance attribute set to %s in TerrainTransformGroup element.",
86
- DEFAULT_MAX_LOD_OCCLUDER_DISTANCE,
87
- )
74
+ if self.auto_process:
75
+ terrain_elem.set("heightScale", str(DEFAULT_HEIGHT_SCALE))
76
+ self.logger.debug(
77
+ "heightScale attribute set to %s in TerrainTransformGroup element.",
78
+ DEFAULT_HEIGHT_SCALE,
79
+ )
80
+ else:
81
+ self.logger.debug(
82
+ "Auto process is disabled, skipping the heightScale attribute update."
83
+ )
88
84
 
89
85
  self.logger.debug("TerrainTransformGroup element updated in I3D file.")
90
86
 
@@ -159,6 +159,7 @@ class Texture(Component):
159
159
 
160
160
  def preprocess(self) -> None:
161
161
  self.light_version = self.kwargs.get("light_version", False)
162
+ self.fields_padding = self.kwargs.get("fields_padding", 0)
162
163
  self.logger.debug("Light version: %s.", self.light_version)
163
164
 
164
165
  if not os.path.isfile(self.game.texture_schema):
@@ -476,7 +477,9 @@ class Texture(Component):
476
477
  pairs = list(zip(xs, ys))
477
478
  return np.array(pairs, dtype=np.int32).reshape((-1, 1, 2))
478
479
 
479
- def _to_polygon(self, obj: pd.core.series.Series, width: int | None) -> np.ndarray | None:
480
+ def _to_polygon(
481
+ self, obj: pd.core.series.Series, width: int | None
482
+ ) -> shapely.geometry.polygon.Polygon:
480
483
  """Converts OSM object to numpy array of polygon points.
481
484
 
482
485
  Arguments:
@@ -484,7 +487,7 @@ class Texture(Component):
484
487
  width (int | None): Width of the polygon in meters.
485
488
 
486
489
  Returns:
487
- np.ndarray | None: Numpy array of polygon points.
490
+ shapely.geometry.polygon.Polygon: Polygon geometry.
488
491
  """
489
492
  geometry = obj["geometry"]
490
493
  geometry_type = geometry.geom_type
@@ -498,7 +501,7 @@ class Texture(Component):
498
501
  self,
499
502
  geometry: shapely.geometry.linestring.LineString | shapely.geometry.point.Point,
500
503
  width: int | None,
501
- ) -> np.ndarray:
504
+ ) -> shapely.geometry.polygon.Polygon:
502
505
  """Converts LineString or Point geometry to numpy array of polygon points.
503
506
 
504
507
  Arguments:
@@ -507,10 +510,23 @@ class Texture(Component):
507
510
  width (int | None): Width of the polygon in meters.
508
511
 
509
512
  Returns:
510
- np.ndarray: Numpy array of polygon points.
513
+ shapely.geometry.polygon.Polygon: Polygon geometry.
511
514
  """
512
515
  polygon = geometry.buffer(width)
513
- return self._to_np(polygon)
516
+ return polygon
517
+
518
+ def _skip(
519
+ self, geometry: shapely.geometry.polygon.Polygon, *args, **kwargs
520
+ ) -> shapely.geometry.polygon.Polygon:
521
+ """Returns the same geometry.
522
+
523
+ Arguments:
524
+ geometry (shapely.geometry.polygon.Polygon): Polygon geometry.
525
+
526
+ Returns:
527
+ shapely.geometry.polygon.Polygon: Polygon geometry.
528
+ """
529
+ return geometry
514
530
 
515
531
  def _converters(
516
532
  self, geom_type: str
@@ -523,7 +539,7 @@ class Texture(Component):
523
539
  Returns:
524
540
  Callable[[shapely.geometry, int | None], np.ndarray]: Converter function.
525
541
  """
526
- converters = {"Polygon": self._to_np, "LineString": self._sequence, "Point": self._sequence}
542
+ converters = {"Polygon": self._skip, "LineString": self._sequence, "Point": self._sequence}
527
543
  return converters.get(geom_type) # type: ignore
528
544
 
529
545
  def polygons(
@@ -538,6 +554,7 @@ class Texture(Component):
538
554
  Yields:
539
555
  Generator[np.ndarray, None, None]: Numpy array of polygon points.
540
556
  """
557
+ is_fieds = "farmland" in tags.values()
541
558
  try:
542
559
  objects = ox.features_from_bbox(bbox=self.new_bbox, tags=tags)
543
560
  except Exception as e: # pylint: disable=W0718
@@ -551,7 +568,17 @@ class Texture(Component):
551
568
  polygon = self._to_polygon(obj, width)
552
569
  if polygon is None:
553
570
  continue
554
- yield polygon
571
+
572
+ if is_fieds and self.fields_padding > 0:
573
+ padded_polygon = polygon.buffer(-self.fields_padding)
574
+
575
+ if not isinstance(padded_polygon, shapely.geometry.polygon.Polygon):
576
+ self.logger.warning("The padding value is too high, field will not padded.")
577
+ else:
578
+ polygon = padded_polygon
579
+
580
+ polygon_np = self._to_np(polygon)
581
+ yield polygon_np
555
582
 
556
583
  def previews(self) -> list[str]:
557
584
  """Invokes methods to generate previews. Returns list of paths to previews.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: maps4fs
3
- Version: 1.0.7
3
+ Version: 1.0.8
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
@@ -452,20 +452,26 @@ The tool supports the custom size of the map. To use this feature select `Custom
452
452
 
453
453
  ⛔️ Do not use this feature, if you don't know what you're doing. In most cases, the Giants Editor will just crash on opening the file, because you need to enter specific values for the map size.<br><br>
454
454
 
455
- ![Advanced settings](https://github.com/user-attachments/assets/e7406adf-6b82-41a0-838a-13dd8877bebf)
455
+ ![Advanced settings](https://github.com/user-attachments/assets/9e8e178a-58d9-4aa6-aefd-4ed53408701d)
456
456
 
457
457
  You can also apply some advanced settings to the map generation process. Note that they're ADVANCED, so you don't need to use them if you're not sure what they do.<br>
458
458
 
459
- Here's the list of the advanced settings:
459
+ ### DEM Advanced settings
460
460
 
461
- - DEM 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.
461
+ - 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.
462
462
 
463
- - DEM 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.
463
+ - 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.
464
464
 
465
- - DEM Plateau height: 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.
465
+ - Plateau height: 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.
466
+
467
+ ### Background Terrain Advanced settings
466
468
 
467
469
  - Background Terrain Generate only full tiles: if checked (by default) the small tiles (N, NE, E, and so on) will not be generated, only the full tile will be created. It's useful when you don't want to work with separate tiles, but with one big file. Since the new method of cutting the map from the background terrain added to the documentation, and now it's possible to perfectly align the map with the background terrain, this option will remain just as a legacy one.
468
470
 
471
+ ### Texture Advanced settings
472
+
473
+ - 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.
474
+
469
475
  ## Resources
470
476
  In this section, you'll find a list of the resources that you need to create a map for the Farming Simulator.<br>
471
477
  To create a basic map, you only need the Giants Editor. But if you want to create a background terrain - the world around the map, so it won't look like it's floating in the void - you also need Blender and the Blender Exporter Plugins. To create realistic textures for the background terrain, the QGIS is required to obtain high-resolution satellite images.<br>
@@ -1,23 +1,23 @@
1
1
  maps4fs/__init__.py,sha256=da4jmND2Ths9AffnkAKgzLHNkvKFOc_l21gJisPXqWY,155
2
2
  maps4fs/logger.py,sha256=B-NEYpMjPAAqlV4VpfTi6nbBFnEABVtQOaYe6nMpidg,1489
3
3
  maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
4
- maps4fs/generator/background.py,sha256=99fcsEF05G8iZAxsEXnhL_sLQ1FaXfxABYc1j4ECw_c,13116
4
+ maps4fs/generator/background.py,sha256=ogd5TmAWL5zhZtTCOH8YHGKqc0SGQqOsWuVg3AaZO0I,14015
5
5
  maps4fs/generator/component.py,sha256=swOocaEOP3XtZgHfgDJ0ROALWoLgCJwMq8ubl0d2WrI,11085
6
6
  maps4fs/generator/config.py,sha256=kspXIT2o-_28EU0RQsROHCjkgQdqQnvreAKP5QAC5Ws,4279
7
7
  maps4fs/generator/dem.py,sha256=cCJLE20-XKaQx5lwIFNEgmQ5kfhE24QmVrAyMVwsU_A,16459
8
8
  maps4fs/generator/game.py,sha256=4I6edxTeZf41Vgvx6BaucEflMEHomRRvdMZRJAPm0d4,7450
9
9
  maps4fs/generator/grle.py,sha256=qy1tGxDNCBql1dxYBwN2Iu0g4XFFPCDvlvx9bEUoXWM,3090
10
- maps4fs/generator/i3d.py,sha256=1z1SuFCg2lmfJl10CuhWstflm44hjL6ldQ7nwbMndZc,14219
10
+ maps4fs/generator/i3d.py,sha256=0rZyVLQBn1R0orIOfVvZewGMVWR-mAoqwqa6vebypZQ,13952
11
11
  maps4fs/generator/map.py,sha256=gDZUZ2wimoeA8mHVOCnZvrIBeK7b99OIWFd_LjruqBc,4677
12
12
  maps4fs/generator/path_steps.py,sha256=twhoP0KOYWOpOJfYrSWPHygtIeM-r5cIlePg1SHVyHk,3589
13
13
  maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
14
- maps4fs/generator/texture.py,sha256=BZjJIHwGEQMoRULAhvTPyKx8k7jlot5voVk82_TsXgg,23668
14
+ maps4fs/generator/texture.py,sha256=2c2x99xnqKZoXDB4fdQBESFMPMiGrbx_fADFTdx4ZGY,24638
15
15
  maps4fs/generator/tile.py,sha256=z1-xEVjgFNf2WzLkgwoGGq8nREJpjPljeC9lmb5xPKA,1997
16
16
  maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
17
17
  maps4fs/toolbox/background.py,sha256=9BXWNqs_n3HgqDiPztWylgYk_QM4YgBpe6_ZNQAWtSc,2154
18
18
  maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
19
- maps4fs-1.0.7.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
20
- maps4fs-1.0.7.dist-info/METADATA,sha256=KMUvKfYQNMi4N8VOdoWM0cQ0ti4TjK7fYFtCphpCC4E,27580
21
- maps4fs-1.0.7.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
22
- maps4fs-1.0.7.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
23
- maps4fs-1.0.7.dist-info/RECORD,,
19
+ maps4fs-1.0.8.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
20
+ maps4fs-1.0.8.dist-info/METADATA,sha256=IOBr8g1SaorXmDjL1DR33Lm431WpWb8j5PLCUfxXNUk,27836
21
+ maps4fs-1.0.8.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
22
+ maps4fs-1.0.8.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
23
+ maps4fs-1.0.8.dist-info/RECORD,,