maps4fs 1.6.6__py3-none-any.whl → 1.6.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.

Potentially problematic release.


This version of maps4fs might be problematic. Click here for more details.

@@ -393,29 +393,6 @@ class Background(Component):
393
393
  mesh.apply_scale([0.5, 0.5, 0.5])
394
394
  self.mesh_to_stl(mesh)
395
395
 
396
- def get_z_scaling_factor(self) -> float:
397
- """Calculates the scaling factor for the Z axis based on the map settings.
398
-
399
- Returns:
400
- float -- The scaling factor for the Z axis.
401
- """
402
-
403
- scaling_factor = 1 / self.map.dem_settings.multiplier
404
- self.logger.debug("Z scaling factor including DEM multiplier: %s", scaling_factor)
405
-
406
- if self.map.shared_settings.height_scale_multiplier:
407
- scaling_factor *= self.map.shared_settings.height_scale_multiplier
408
- self.logger.debug(
409
- "Z scaling factor including height scale multiplier: %s", scaling_factor
410
- )
411
- if self.map.shared_settings.mesh_z_scaling_factor:
412
- scaling_factor *= 1 / self.map.shared_settings.mesh_z_scaling_factor
413
- self.logger.debug(
414
- "Z scaling factor including mesh z scaling factor: %s", scaling_factor
415
- )
416
-
417
- return scaling_factor
418
-
419
396
  def mesh_to_stl(self, mesh: trimesh.Trimesh) -> None:
420
397
  """Converts the mesh to an STL file and saves it in the previews directory.
421
398
  Uses powerful simplification to reduce the size of the file since it will be used
@@ -535,3 +535,26 @@ class Component:
535
535
  interpolated_polyline.append(polyline[-1])
536
536
 
537
537
  return interpolated_polyline
538
+
539
+ def get_z_scaling_factor(self) -> float:
540
+ """Calculates the scaling factor for the Z axis based on the map settings.
541
+
542
+ Returns:
543
+ float -- The scaling factor for the Z axis.
544
+ """
545
+
546
+ scaling_factor = 1 / self.map.dem_settings.multiplier
547
+ self.logger.debug("Z scaling factor including DEM multiplier: %s", scaling_factor)
548
+
549
+ if self.map.shared_settings.height_scale_multiplier:
550
+ scaling_factor *= self.map.shared_settings.height_scale_multiplier
551
+ self.logger.debug(
552
+ "Z scaling factor including height scale multiplier: %s", scaling_factor
553
+ )
554
+ if self.map.shared_settings.mesh_z_scaling_factor:
555
+ scaling_factor *= 1 / self.map.shared_settings.mesh_z_scaling_factor
556
+ self.logger.debug(
557
+ "Z scaling factor including mesh z scaling factor: %s", scaling_factor
558
+ )
559
+
560
+ return scaling_factor
maps4fs/generator/game.py CHANGED
@@ -40,7 +40,7 @@ class Game:
40
40
  _tree_schema: str | None = None
41
41
 
42
42
  # Order matters! Some components depend on others.
43
- components = [Texture, GRLE, Background, I3d, Config, Satellite]
43
+ components = [Texture, Background, GRLE, I3d, Config, Satellite]
44
44
 
45
45
  def __init__(self, map_template_path: str | None = None):
46
46
  if map_template_path:
maps4fs/generator/grle.py CHANGED
@@ -10,13 +10,26 @@ import numpy as np
10
10
  from shapely.geometry import Polygon # type: ignore
11
11
 
12
12
  from maps4fs.generator.component import Component
13
- from maps4fs.generator.texture import Texture
13
+ from maps4fs.generator.texture import PREVIEW_MAXIMUM_SIZE, Texture
14
14
 
15
- ISLAND_SIZE_MIN = 10
16
- ISLAND_SIZE_MAX = 200
17
15
  ISLAND_DISTORTION = 0.3
18
- ISLAND_VERTEX_COUNT = 30
19
- ISLAND_ROUNDING_RADIUS = 15
16
+
17
+
18
+ def plant_to_pixel_value(plant_name: str) -> int | None:
19
+ """Returns the pixel value representation of the plant.
20
+ If not found, returns None.
21
+
22
+ Arguments:
23
+ plant_name (str): name of the plant
24
+
25
+ Returns:
26
+ int | None: pixel value of the plant or None if not found.
27
+ """
28
+ plants = {
29
+ "smallDenseMix": 33,
30
+ "meadow": 131,
31
+ }
32
+ return plants.get(plant_name)
20
33
 
21
34
 
22
35
  # pylint: disable=W0223
@@ -39,6 +52,7 @@ class GRLE(Component):
39
52
  def preprocess(self) -> None:
40
53
  """Gets the path to the map I3D file from the game instance and saves it to the instance
41
54
  attribute. If the game does not support I3D files, the attribute is set to None."""
55
+ self.preview_paths: dict[str, str] = {}
42
56
 
43
57
  try:
44
58
  grle_schema_path = self.game.grle_schema
@@ -89,6 +103,7 @@ class GRLE(Component):
89
103
  else:
90
104
  self.logger.warning("Adding plants it's not supported for the %s.", self.game.code)
91
105
 
106
+ # pylint: disable=no-member
92
107
  def previews(self) -> list[str]:
93
108
  """Returns a list of paths to the preview images (empty list).
94
109
  The component does not generate any preview images so it returns an empty list.
@@ -96,7 +111,57 @@ class GRLE(Component):
96
111
  Returns:
97
112
  list[str]: An empty list.
98
113
  """
99
- return []
114
+ preview_paths = []
115
+ for preview_name, preview_path in self.preview_paths.items():
116
+ save_path = os.path.join(self.previews_directory, f"{preview_name}.png")
117
+ # Resize the preview image to the maximum size allowed for previews.
118
+ image = cv2.imread(preview_path, cv2.IMREAD_GRAYSCALE)
119
+ if image.shape[0] > PREVIEW_MAXIMUM_SIZE or image.shape[1] > PREVIEW_MAXIMUM_SIZE:
120
+ image = cv2.resize(image, (PREVIEW_MAXIMUM_SIZE, PREVIEW_MAXIMUM_SIZE))
121
+ image_normalized = np.empty_like(image)
122
+ cv2.normalize(image, image_normalized, 0, 255, cv2.NORM_MINMAX)
123
+ image_colored = cv2.applyColorMap(image_normalized, cv2.COLORMAP_JET)
124
+ cv2.imwrite(save_path, image_colored)
125
+ preview_paths.append(save_path)
126
+
127
+ with_fields_save_path = os.path.join(
128
+ self.previews_directory, f"{preview_name}_with_fields.png"
129
+ )
130
+ image_with_fields = self.overlay_fields(image_colored)
131
+ if image_with_fields is None:
132
+ continue
133
+ cv2.imwrite(with_fields_save_path, image_with_fields) # pylint: disable=no-member
134
+ preview_paths.append(with_fields_save_path)
135
+
136
+ return preview_paths
137
+
138
+ def overlay_fields(self, farmlands_np: np.ndarray) -> np.ndarray | None:
139
+ """Overlay fields on the farmlands preview image.
140
+
141
+ Arguments:
142
+ farmlands_np (np.ndarray): The farmlands preview image.
143
+
144
+ Returns:
145
+ np.ndarray | None: The farmlands preview image with fields overlayed on top of it.
146
+ """
147
+ texture_component: Texture | None = self.map.get_component("Texture") # type: ignore
148
+ if not texture_component:
149
+ self.logger.warning("Texture component not found in the map.")
150
+ return None
151
+
152
+ fields_layer = texture_component.get_layer_by_usage("field")
153
+ fields_layer_path = fields_layer.get_preview_or_path( # type: ignore
154
+ self.game.weights_dir_path(self.map_directory)
155
+ )
156
+ if not fields_layer_path or not os.path.isfile(fields_layer_path):
157
+ self.logger.warning("Fields layer not found in the texture component.")
158
+ return None
159
+ fields_np = cv2.imread(fields_layer_path)
160
+ # Resize fields_np to the same size as farmlands_np.
161
+ fields_np = cv2.resize(fields_np, (farmlands_np.shape[1], farmlands_np.shape[0]))
162
+
163
+ # use fields_np as base layer and overlay farmlands_np on top of it with 50% alpha blending.
164
+ return cv2.addWeighted(fields_np, 0.5, farmlands_np, 0.5, 0)
100
165
 
101
166
  # pylint: disable=R0801, R0914
102
167
  def _add_farmlands(self) -> None:
@@ -155,7 +220,7 @@ class GRLE(Component):
155
220
  angle=self.rotation,
156
221
  )
157
222
  except ValueError as e:
158
- self.logger.warning(
223
+ self.logger.debug(
159
224
  "Farmland %s could not be fitted into the map bounds with error: %s",
160
225
  farmland_id,
161
226
  e,
@@ -180,7 +245,7 @@ class GRLE(Component):
180
245
  try:
181
246
  cv2.fillPoly(image, [field_np], farmland_id) # type: ignore
182
247
  except Exception as e: # pylint: disable=W0718
183
- self.logger.warning(
248
+ self.logger.debug(
184
249
  "Farmland %s could not be added to the InfoLayer PNG file with error: %s",
185
250
  farmland_id,
186
251
  e,
@@ -204,6 +269,8 @@ class GRLE(Component):
204
269
  "Farmlands added to the InfoLayer PNG file: %s.", info_layer_farmlands_path
205
270
  )
206
271
 
272
+ self.preview_paths["farmlands"] = info_layer_farmlands_path # type: ignore
273
+
207
274
  # pylint: disable=R0915
208
275
  def _add_plants(self) -> None:
209
276
  """Adds plants to the InfoLayer PNG file."""
@@ -270,10 +337,13 @@ class GRLE(Component):
270
337
  grass_image[forest_image != 0] = 255
271
338
 
272
339
  # B and G channels remain the same (zeros), while we change the R channel.
273
- possible_R_values = [33, 65, 97, 129, 161, 193, 225] # pylint: disable=C0103
340
+ possible_R_values = [65, 97, 129, 161, 193, 225] # pylint: disable=C0103
274
341
 
275
- # 1st approach: Change the non zero values in the base image to 33 (for debug).
276
- # And use the base image as R channel in the density map.
342
+ base_layer_pixel_value = plant_to_pixel_value(
343
+ self.map.grle_settings.base_grass # type:ignore
344
+ )
345
+ if not base_layer_pixel_value:
346
+ base_layer_pixel_value = 131
277
347
 
278
348
  # pylint: disable=no-member
279
349
  def create_island_of_plants(image: np.ndarray, count: int) -> np.ndarray:
@@ -290,23 +360,20 @@ class GRLE(Component):
290
360
  # Randomly choose the value for the island.
291
361
  plant_value = choice(possible_R_values)
292
362
  # Randomly choose the size of the island.
293
- island_size = randint(ISLAND_SIZE_MIN, ISLAND_SIZE_MAX)
363
+ island_size = randint(
364
+ self.map.grle_settings.plants_island_minimum_size, # type:ignore
365
+ self.map.grle_settings.plants_island_maximum_size, # type:ignore
366
+ )
294
367
  # Randomly choose the position of the island.
295
- # x = np.random.randint(0, image.shape[1] - island_size)
296
- # y = np.random.randint(0, image.shape[0] - island_size)
297
368
  x = randint(0, image.shape[1] - island_size)
298
369
  y = randint(0, image.shape[0] - island_size)
299
370
 
300
- # Randomly choose the shape of the island.
301
- # shapes = ["circle", "ellipse", "polygon"]
302
- # shape = choice(shapes)
303
-
304
371
  try:
305
372
  polygon_points = get_rounded_polygon(
306
- num_vertices=ISLAND_VERTEX_COUNT,
373
+ num_vertices=self.map.grle_settings.plants_island_vertex_count,
307
374
  center=(x + island_size // 2, y + island_size // 2),
308
375
  radius=island_size // 2,
309
- rounding_radius=ISLAND_ROUNDING_RADIUS,
376
+ rounding_radius=self.map.grle_settings.plants_island_rounding_radius,
310
377
  )
311
378
  if not polygon_points:
312
379
  continue
@@ -355,16 +422,16 @@ class GRLE(Component):
355
422
  grass_image_copy = grass_image.copy()
356
423
  if forest_image is not None:
357
424
  # Add the forest layer to the base image, to merge the masks.
358
- grass_image_copy[forest_image != 0] = 33
359
- # Set all the non-zero values to 33.
360
- grass_image_copy[grass_image != 0] = 33
425
+ grass_image_copy[forest_image != 0] = base_layer_pixel_value
426
+
427
+ grass_image_copy[grass_image != 0] = base_layer_pixel_value
361
428
 
362
429
  # Add islands of plants to the base image.
363
- island_count = self.map_size
430
+ island_count = int(self.map_size * self.map.grle_settings.plants_island_percent // 100)
364
431
  self.logger.debug("Adding %s islands of plants to the base image.", island_count)
365
432
  if self.map.grle_settings.random_plants:
366
433
  grass_image_copy = create_island_of_plants(grass_image_copy, island_count)
367
- self.logger.debug("Islands of plants added to the base image.")
434
+ self.logger.info("Added %s islands of plants to the base image.", island_count)
368
435
 
369
436
  # Sligtly reduce the size of the grass_image, that we'll use as mask.
370
437
  kernel = np.ones((3, 3), np.uint8)
@@ -380,7 +447,6 @@ class GRLE(Component):
380
447
  grass_image_copy[:, 0] = 0 # Left side
381
448
  grass_image_copy[:, -1] = 0 # Right side
382
449
 
383
- # Value of 33 represents the base grass plant.
384
450
  # After painting it with base grass, we'll create multiple islands of different plants.
385
451
  # On the final step, we'll remove all the values which in pixels
386
452
  # where zerons in the original base image (so we don't paint grass where it should not be).
maps4fs/generator/i3d.py CHANGED
@@ -15,12 +15,9 @@ from maps4fs.generator.component import Component
15
15
  from maps4fs.generator.texture import Texture
16
16
 
17
17
  DISPLACEMENT_LAYER_SIZE_FOR_BIG_MAPS = 32768
18
- DEFAULT_MAX_LOD_DISTANCE = 10000
19
- DEFAULT_MAX_LOD_OCCLUDER_DISTANCE = 10000
20
18
  NODE_ID_STARTING_VALUE = 2000
21
19
  SPLINES_NODE_ID_STARTING_VALUE = 5000
22
20
  TREE_NODE_ID_STARTING_VALUE = 10000
23
- DEFAULT_FOREST_DENSITY = 10
24
21
 
25
22
 
26
23
  # pylint: disable=R0903
@@ -197,7 +194,7 @@ class I3d(Component):
197
194
  linestring_points=road, angle=self.rotation
198
195
  )
199
196
  except ValueError as e:
200
- self.logger.warning(
197
+ self.logger.debug(
201
198
  "Road %s could not be fitted into the map bounds with error: %s",
202
199
  road_id,
203
200
  e,
@@ -248,7 +245,7 @@ class I3d(Component):
248
245
  y = max(0, min(y, dem_y_size - 1))
249
246
 
250
247
  z = not_resized_dem[y, x]
251
- z /= 32 # Yes, it's a magic number here.
248
+ z *= self.get_z_scaling_factor() # type: ignore
252
249
 
253
250
  cv_node = ET.Element("cv")
254
251
  cv_node.set("c", f"{cx}, {z}, {cy}")
@@ -322,7 +319,7 @@ class I3d(Component):
322
319
  polygon_points=field, angle=self.rotation
323
320
  )
324
321
  except ValueError as e:
325
- self.logger.warning(
322
+ self.logger.debug(
326
323
  "Field %s could not be fitted into the map bounds with error: %s",
327
324
  field_id,
328
325
  e,
@@ -336,7 +333,7 @@ class I3d(Component):
336
333
  try:
337
334
  cx, cy = self.get_polygon_center(field_ccs)
338
335
  except Exception as e: # pylint: disable=W0718
339
- self.logger.warning(
336
+ self.logger.debug(
340
337
  "Field %s could not be fitted into the map bounds.", field_id
341
338
  )
342
339
  self.logger.debug("Error: %s", e)
maps4fs/generator/map.py CHANGED
@@ -146,6 +146,7 @@ class Map:
146
146
 
147
147
  self.tree_custom_schema = kwargs.get("tree_custom_schema", None)
148
148
  if self.tree_custom_schema:
149
+ self.logger.info("Custom tree schema contains %s trees", len(self.tree_custom_schema))
149
150
  save_path = os.path.join(self.map_directory, "tree_custom_schema.json")
150
151
  with open(save_path, "w", encoding="utf-8") as file:
151
152
  json.dump(self.tree_custom_schema, file, indent=4)
@@ -42,18 +42,28 @@ class SettingsModel(BaseModel):
42
42
  return all_settings
43
43
 
44
44
  @classmethod
45
- def all_settings_from_json(cls, data: dict) -> dict[str, SettingsModel]:
45
+ def all_settings_from_json(
46
+ cls, data: dict, flattening: bool = True
47
+ ) -> dict[str, SettingsModel]:
46
48
  """Create settings instances from JSON data.
47
49
 
48
50
  Arguments:
49
51
  data (dict): JSON data.
52
+ flattening (bool): if set to True will flattet iterables to use the first element
53
+ of it.
50
54
 
51
55
  Returns:
52
56
  dict[str, Type[SettingsModel]]: Dictionary with settings instances.
53
57
  """
54
58
  settings = {}
55
59
  for subclass in cls.__subclasses__():
56
- settings[subclass.__name__] = subclass(**data[subclass.__name__])
60
+ subclass_data = data[subclass.__name__]
61
+ if flattening:
62
+ for key, value in subclass_data.items():
63
+ if isinstance(value, (list, tuple)):
64
+ subclass_data[key] = value[0]
65
+
66
+ settings[subclass.__name__] = subclass(**subclass_data)
57
67
 
58
68
  return settings
59
69
 
@@ -121,6 +131,12 @@ class GRLESettings(SettingsModel):
121
131
  farmland_margin: int = 0
122
132
  random_plants: bool = True
123
133
  add_farmyards: bool = False
134
+ base_grass: tuple | str = ("smallDenseMix", "meadow")
135
+ plants_island_minimum_size: int = 10
136
+ plants_island_maximum_size: int = 200
137
+ plants_island_vertex_count: int = 30
138
+ plants_island_rounding_radius: int = 15
139
+ plants_island_percent: int = 100
124
140
 
125
141
 
126
142
  class I3DSettings(SettingsModel):
@@ -6,6 +6,7 @@ import json
6
6
  import os
7
7
  import re
8
8
  import shutil
9
+ import warnings
9
10
  from collections import defaultdict
10
11
  from typing import Any, Callable, Generator, Optional
11
12
 
@@ -327,8 +328,6 @@ class Texture(Component):
327
328
  output_height=self.map_size,
328
329
  output_width=self.map_size,
329
330
  )
330
- else:
331
- self.logger.warning("Layer path %s not found.", layer_path)
332
331
  else:
333
332
  self.logger.debug(
334
333
  "Skipping rotation of layer %s because it has no tags.", layer.name
@@ -717,7 +716,9 @@ class Texture(Component):
717
716
  is_fieds = info_layer == "fields"
718
717
  try:
719
718
  if self.map.custom_osm is not None:
720
- objects = ox.features_from_xml(self.map.custom_osm, tags=tags)
719
+ with warnings.catch_warnings():
720
+ warnings.simplefilter("ignore", FutureWarning)
721
+ objects = ox.features_from_xml(self.map.custom_osm, tags=tags)
721
722
  else:
722
723
  objects = ox.features_from_bbox(bbox=self.new_bbox, tags=tags)
723
724
  except Exception as e: # pylint: disable=W0718
@@ -776,6 +777,8 @@ class Texture(Component):
776
777
 
777
778
  if not isinstance(padded_polygon, shapely.geometry.polygon.Polygon):
778
779
  self.logger.warning("The padding value is too high, field will not padded.")
780
+ elif not list(padded_polygon.exterior.coords):
781
+ self.logger.warning("The padding value is too high, field will not padded.")
779
782
  else:
780
783
  polygon = padded_polygon
781
784
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: maps4fs
3
- Version: 1.6.6
3
+ Version: 1.6.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
@@ -255,6 +255,10 @@ The tool now has a Modder Toolbox, which is a set of tools to help you with vari
255
255
 
256
256
  ### Tool Categories
257
257
  Tools are divided into categories, which are listed below.
258
+
259
+ #### For custom schemas
260
+ - **Tree Schema Editor** - allows you to view all the supported trees models and select the ones you need on your map. After it, you should click the Show updated schema button and copy the JSON schema to the clipboard. Then you can use it in the Expert settings to generate the map with the selected trees.
261
+
258
262
  #### For Textures and DEM
259
263
  - **GeoTIFF windowing** - allows you to upload your GeoTIFF file and select the region of interest to extract it from the image. It's useful when you have high-resolution DEM data and want to create a height map using it.
260
264
 
@@ -508,6 +512,18 @@ decimation will be, which means the higher it will affect the geometry. It's not
508
512
 
509
513
  - 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.
510
514
 
515
+ - Base grass - you can select which plant will be used as a base grass on the map.
516
+
517
+ - Plants island minimum size - when random plants are enabled, the generator will add islands of differents plants to the map and choose the random size of those island between the minimum and maximum values. This one is the minimum size of the island in meters.
518
+
519
+ - Plants island maximum size - it's the same as above, but for the maximum size of the island in meters.
520
+
521
+ - Plants island vertex count - the number of vertices in the island. The higher the value, the more detailed the island will be. Note, that high values will turn the smoothed island into geometric madness.
522
+
523
+ - Plants insland rounding radius - used to round the vertices of the island. The higher the value, the more rounded the island will be.
524
+
525
+ - 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.
526
+
511
527
  ### I3D Advanced settings
512
528
 
513
529
  - 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.
@@ -582,3 +598,4 @@ But also, I want to thank the people who helped me with the project in some way,
582
598
  - [Lucandia](https://github.com/Lucandia) - for the awesome StreamLit [widget to preview STL files](https://github.com/Lucandia/streamlit_stl).
583
599
  - [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.
584
600
  - [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.
601
+ - [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.
@@ -1,18 +1,18 @@
1
1
  maps4fs/__init__.py,sha256=WbT36EzJ_74GN0RUUrLIYECdSdtRiZaxKl17KUt7pjA,492
2
2
  maps4fs/logger.py,sha256=B-NEYpMjPAAqlV4VpfTi6nbBFnEABVtQOaYe6nMpidg,1489
3
3
  maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
4
- maps4fs/generator/background.py,sha256=K2HSYENPtJNSlG9M3XGkvUjtYyyI3oWwLMNYPpY3IBQ,25824
5
- maps4fs/generator/component.py,sha256=GrTI7803gOQFhqocdjFG-wh0HOkC6HWoyKr8pR2Xp28,20409
4
+ maps4fs/generator/background.py,sha256=tV4UXvtkNN-OSvv6ujp4jFWRU1xGBgEvSakVGZ1H4nc,24877
5
+ maps4fs/generator/component.py,sha256=vn_ThQw3OTcloqYuJWC7vghAvIAnwJsybEm7qMwvsZk,21356
6
6
  maps4fs/generator/config.py,sha256=0QmK052B8bxyHVhg3jzCORLfOBMMmqVfhhbqXKf6OMk,4383
7
7
  maps4fs/generator/dem.py,sha256=20gx0dzX0LyO6ipvDitst-BwGfcKogFqgQf9Q2qMH5U,10933
8
- maps4fs/generator/game.py,sha256=QHgVnyGYvEnfwGZ84-u-dpbCRr3UeVVqBbrwr5WG8dE,7992
9
- maps4fs/generator/grle.py,sha256=rU84Q1PBHr-V-JzdHJ7BXLHC_LztGw6Z1FS2w_1HIF0,17848
10
- maps4fs/generator/i3d.py,sha256=D1QBHCFygTkml6GZmLRlUagWEVQb0tNeyZ-MAY-Uf0Q,24945
11
- maps4fs/generator/map.py,sha256=P8wHrCLhLcv2W5zJmMGjpM1TAMR8c7yVFzm_n-5ZTHQ,10084
8
+ maps4fs/generator/game.py,sha256=Nf5r2ubV4YVAVHGzJyhbF2GnOC0qV3HlHYIZBCWciHs,7992
9
+ maps4fs/generator/grle.py,sha256=hcbVBJ4j_Zr2QvEVo2cYNh2jARVXp_X3onifBtp9Zxs,20922
10
+ maps4fs/generator/i3d.py,sha256=pUyHKWKcw43xVCf3Y8iabtbQba05LYxMHi8vziGksIA,24843
11
+ maps4fs/generator/map.py,sha256=a50KQEr1XZKjS_WKXywGwh4OC3gyjY6M8FTc0eNcxpg,10183
12
12
  maps4fs/generator/qgis.py,sha256=Es8hLuqN_KH8lDfnJE6He2rWYbAKJ3RGPn-o87S6CPI,6116
13
13
  maps4fs/generator/satellite.py,sha256=_7RcuNmR1mjxEJWMDsjnzKUIqWxnGUn50XtjB7HmSPg,3661
14
- maps4fs/generator/settings.py,sha256=TGavqPG-sULpB7_SeOzFZ5mWZUq8d2sHfVu5aBbmx5E,5011
15
- maps4fs/generator/texture.py,sha256=jWorYVOzBI-plzy_mh42O2NZuB13M5yDaCOfrpX6Dck,33836
14
+ maps4fs/generator/settings.py,sha256=3ASf3hW1nkGt8_3IOvKIKNUd6XAHYTAA8FquuhpSUlU,5668
15
+ maps4fs/generator/texture.py,sha256=gIXCHU1vT3evbkaXAV9gLUrgI1wH3xJLgWAtZgFruj0,34013
16
16
  maps4fs/generator/dtm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
17
  maps4fs/generator/dtm/dtm.py,sha256=azy-RWsc5PgenKDtgG0lrddMwWEw1hYzdng9V8zphMk,9167
18
18
  maps4fs/generator/dtm/srtm.py,sha256=2-pX6bWrJX6gr8IM7ueX6mm_PW7_UQ58MtdzDHae2OQ,9030
@@ -20,8 +20,8 @@ maps4fs/generator/dtm/usgs.py,sha256=ZTi10RNDA3EBrsVg2ZoYrdN4uqiG1Jvk7FzdcKdgNkU
20
20
  maps4fs/toolbox/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
21
21
  maps4fs/toolbox/background.py,sha256=9BXWNqs_n3HgqDiPztWylgYk_QM4YgBpe6_ZNQAWtSc,2154
22
22
  maps4fs/toolbox/dem.py,sha256=z9IPFNmYbjiigb3t02ZenI3Mo8odd19c5MZbjDEovTo,3525
23
- maps4fs-1.6.6.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
24
- maps4fs-1.6.6.dist-info/METADATA,sha256=REJVmAJBVXkg5_Gk-3BpU4JbEol1pewc4_AZeWsb6fw,37687
25
- maps4fs-1.6.6.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
26
- maps4fs-1.6.6.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
27
- maps4fs-1.6.6.dist-info/RECORD,,
23
+ maps4fs-1.6.8.dist-info/LICENSE.md,sha256=pTKD_oUexcn-yccFCTrMeLkZy0ifLRa-VNcDLqLZaIw,10749
24
+ maps4fs-1.6.8.dist-info/METADATA,sha256=78O4a90z42h5w1OENMVLyB9rAZ1CBSjRM7tMqiIEB3k,39160
25
+ maps4fs-1.6.8.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
26
+ maps4fs-1.6.8.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
27
+ maps4fs-1.6.8.dist-info/RECORD,,