maps4fs 0.9.3__py3-none-any.whl → 0.9.7__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.
@@ -10,13 +10,18 @@ import numpy as np
10
10
  import trimesh # type: ignore
11
11
 
12
12
  from maps4fs.generator.component import Component
13
+ from maps4fs.generator.dem import (
14
+ DEFAULT_BLUR_RADIUS,
15
+ DEFAULT_MULTIPLIER,
16
+ DEFAULT_PLATEAU,
17
+ )
13
18
  from maps4fs.generator.path_steps import DEFAULT_DISTANCE, PATH_FULL_NAME, get_steps
14
19
  from maps4fs.generator.tile import Tile
15
20
  from maps4fs.logger import timeit
16
21
 
17
22
  RESIZE_FACTOR = 1 / 4
18
23
  SIMPLIFY_FACTOR = 10
19
- FULL_RESIZE_FACTOR = 1 / 4
24
+ FULL_RESIZE_FACTOR = 1 / 8
20
25
  FULL_SIMPLIFY_FACTOR = 20
21
26
 
22
27
 
@@ -58,9 +63,9 @@ class Background(Component):
58
63
  logger=self.logger,
59
64
  tile_code=path_step.code,
60
65
  auto_process=False,
61
- blur_radius=self.kwargs.get("blur_radius"),
62
- multiplier=self.kwargs.get("multiplier", 1),
63
- plateau=self.kwargs.get("plateau", 0),
66
+ blur_radius=self.kwargs.get("blur_radius", DEFAULT_BLUR_RADIUS),
67
+ multiplier=self.kwargs.get("multiplier", DEFAULT_MULTIPLIER),
68
+ plateau=self.kwargs.get("plateau", DEFAULT_PLATEAU),
64
69
  )
65
70
 
66
71
  # Update the origin for the next tile.
@@ -95,11 +100,13 @@ class Background(Component):
95
100
  for tile in self.tiles:
96
101
  north, south, east, west = tile.bbox
97
102
  epsg3857_string = tile.get_epsg3857_string()
103
+ epsg3857_string_with_margin = tile.get_epsg3857_string(add_margin=True)
98
104
 
99
105
  tile_entry = {
100
106
  "center_latitude": tile.coordinates[0],
101
107
  "center_longitude": tile.coordinates[1],
102
108
  "epsg3857_string": epsg3857_string,
109
+ "epsg3857_string_with_margin": epsg3857_string_with_margin,
103
110
  "height": tile.map_height,
104
111
  "width": tile.map_width,
105
112
  "north": north,
@@ -115,10 +122,16 @@ class Background(Component):
115
122
  def qgis_sequence(self) -> None:
116
123
  """Generates QGIS scripts for creating bounding box layers and rasterizing them."""
117
124
  qgis_layers = [
118
- (f"Background_bbox_{tile.code}", *tile.get_espg3857_bbox()) for tile in self.tiles
125
+ (f"Background_{tile.code}", *tile.get_espg3857_bbox()) for tile in self.tiles
119
126
  ]
127
+ qgis_layers_with_margin = [
128
+ (f"Background_{tile.code}_margin", *tile.get_espg3857_bbox(add_margin=True))
129
+ for tile in self.tiles
130
+ ]
131
+
132
+ layers = qgis_layers + qgis_layers_with_margin
120
133
 
121
- self.create_qgis_scripts(qgis_layers) # type: ignore
134
+ self.create_qgis_scripts(layers)
122
135
 
123
136
  def generate_obj_files(self) -> None:
124
137
  """Iterates over all tiles and generates 3D obj files based on DEM data.
@@ -209,9 +222,28 @@ class Background(Component):
209
222
  mesh = mesh.simplify_quadric_decimation(face_count=len(faces) // simplify_factor)
210
223
  self.logger.debug("Mesh simplified to %s faces", len(mesh.faces))
211
224
 
225
+ if tile_code == PATH_FULL_NAME:
226
+ self.mesh_to_stl(mesh)
227
+
212
228
  mesh.export(save_path)
213
229
  self.logger.info("Obj file saved: %s", save_path)
214
230
 
231
+ def mesh_to_stl(self, mesh: trimesh.Trimesh) -> None:
232
+ """Converts the mesh to an STL file and saves it in the previews directory.
233
+ Uses powerful simplification to reduce the size of the file since it will be used
234
+ only for the preview.
235
+
236
+ Arguments:
237
+ mesh (trimesh.Trimesh) -- The mesh to convert to an STL file.
238
+ """
239
+ preview_path = os.path.join(self.previews_directory, "background_dem.stl")
240
+ mesh = mesh.simplify_quadric_decimation(percent=0.05)
241
+ mesh.export(preview_path)
242
+
243
+ self.logger.info("STL file saved: %s", preview_path)
244
+
245
+ self.stl_preview_path = preview_path # pylint: disable=attribute-defined-outside-init
246
+
215
247
  def previews(self) -> list[str]:
216
248
  """Generates a preview by combining all tiles into one image.
217
249
  NOTE: The map itself is not included in the preview, so it will be empty.
@@ -230,6 +262,8 @@ class Background(Component):
230
262
 
231
263
  for tile in self.tiles:
232
264
  # pylint: disable=no-member
265
+ if tile.code == PATH_FULL_NAME:
266
+ continue
233
267
  tile_image = cv2.imread(tile.dem_path, cv2.IMREAD_UNCHANGED)
234
268
 
235
269
  self.logger.debug(
@@ -289,7 +323,7 @@ class Background(Component):
289
323
  image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR) # type: ignore
290
324
  cv2.imwrite(preview_path, image)
291
325
 
292
- return [preview_path]
326
+ return [preview_path, self.stl_preview_path]
293
327
 
294
328
 
295
329
  # Creates tiles around the map.
@@ -10,7 +10,7 @@ from typing import TYPE_CHECKING, Any
10
10
  import osmnx as ox # type: ignore
11
11
  from pyproj import Transformer
12
12
 
13
- from maps4fs.generator.qgis import get_bbox_template, get_rasterize_template
13
+ from maps4fs.generator.qgis import save_scripts
14
14
 
15
15
  if TYPE_CHECKING:
16
16
  from maps4fs.generator.game import Game
@@ -214,16 +214,17 @@ class Component:
214
214
  return west, south, east, north
215
215
 
216
216
  def get_espg3857_bbox(
217
- self, bbox: tuple[int, int, int, int] | None = None
218
- ) -> tuple[int, int, int, int]:
217
+ self, bbox: tuple[float, float, float, float] | None = None, add_margin: bool = False
218
+ ) -> tuple[float, float, float, float]:
219
219
  """Converts the bounding box to EPSG:3857.
220
220
  If the bounding box is not provided, the instance variable is used.
221
221
 
222
222
  Args:
223
- bbox (tuple[int, int, int, int], optional): The bounding box to convert.
223
+ bbox (tuple[float, float, float, float], optional): The bounding box to convert.
224
+ add_margin (bool, optional): Whether to add a margin to the bounding box.
224
225
 
225
226
  Returns:
226
- tuple[int, int, int, int]: The bounding box in EPSG:3857.
227
+ tuple[float, float, float, float]: The bounding box in EPSG:3857.
227
228
  """
228
229
  bbox = bbox or self.bbox
229
230
  north, south, east, west = bbox
@@ -231,19 +232,29 @@ class Component:
231
232
  epsg3857_north, epsg3857_west = transformer.transform(north, west)
232
233
  epsg3857_south, epsg3857_east = transformer.transform(south, east)
233
234
 
235
+ if add_margin:
236
+ MARGIN = 500 # pylint: disable=C0103
237
+ epsg3857_north = int(epsg3857_north - MARGIN)
238
+ epsg3857_south = int(epsg3857_south + MARGIN)
239
+ epsg3857_east = int(epsg3857_east - MARGIN)
240
+ epsg3857_west = int(epsg3857_west + MARGIN)
241
+
234
242
  return epsg3857_north, epsg3857_south, epsg3857_east, epsg3857_west
235
243
 
236
- def get_epsg3857_string(self, bbox: tuple[int, int, int, int] | None = None) -> str:
244
+ def get_epsg3857_string(
245
+ self, bbox: tuple[float, float, float, float] | None = None, add_margin: bool = False
246
+ ) -> str:
237
247
  """Converts the bounding box to EPSG:3857 string.
238
248
  If the bounding box is not provided, the instance variable is used.
239
249
 
240
250
  Args:
241
- bbox (tuple[int, int, int, int], optional): The bounding box to convert.
251
+ bbox (tuple[float, float, float, float], optional): The bounding box to convert.
252
+ add_margin (bool, optional): Whether to add a margin to the bounding box.
242
253
 
243
254
  Returns:
244
255
  str: The bounding box in EPSG:3857 string.
245
256
  """
246
- north, south, east, west = self.get_espg3857_bbox(bbox)
257
+ north, south, east, west = self.get_espg3857_bbox(bbox, add_margin=add_margin)
247
258
  return f"{north},{south},{east},{west} [EPSG:3857]"
248
259
 
249
260
  def create_qgis_scripts(
@@ -259,17 +270,4 @@ class Component:
259
270
  create scripts for.
260
271
  """
261
272
  class_name = self.__class__.__name__.lower()
262
-
263
- script_files = [
264
- (f"{class_name}_bbox.py", get_bbox_template),
265
- (f"{class_name}_rasterize.py", get_rasterize_template),
266
- ]
267
-
268
- for script_file, process_function in script_files:
269
- script_path = os.path.join(self.scripts_directory, script_file)
270
- script_content = process_function(qgis_layers) # type: ignore
271
-
272
- with open(script_path, "w", encoding="utf-8") as file:
273
- file.write(script_content)
274
-
275
- self.logger.info("QGIS script saved: %s", script_path)
273
+ save_scripts(qgis_layers, class_name, self.scripts_directory)
@@ -70,11 +70,13 @@ class Config(Component):
70
70
  bbox = self.get_bbox(height_distance=self.map_height, width_distance=self.map_width)
71
71
  south, west, north, east = bbox
72
72
  epsg3857_string = self.get_epsg3857_string(bbox=bbox)
73
+ epsg3857_string_with_margin = self.get_epsg3857_string(bbox=bbox, add_margin=True)
73
74
 
74
75
  self.qgis_sequence()
75
76
 
76
77
  overview_data = {
77
78
  "epsg3857_string": epsg3857_string,
79
+ "epsg3857_string_with_margin": epsg3857_string_with_margin,
78
80
  "south": south,
79
81
  "west": west,
80
82
  "north": north,
@@ -93,7 +95,11 @@ class Config(Component):
93
95
  """Generates QGIS scripts for creating bounding box layers and rasterizing them."""
94
96
  bbox = self.get_bbox(height_distance=self.map_height, width_distance=self.map_width)
95
97
  espg3857_bbox = self.get_espg3857_bbox(bbox=bbox)
98
+ espg3857_bbox_with_margin = self.get_espg3857_bbox(bbox=bbox, add_margin=True)
96
99
 
97
100
  qgis_layers = [("Overview_bbox", *espg3857_bbox)]
101
+ qgis_layers_with_margin = [("Overview_bbox_with_margin", *espg3857_bbox_with_margin)]
98
102
 
99
- self.create_qgis_scripts(qgis_layers) # type: ignore
103
+ layers = qgis_layers + qgis_layers_with_margin
104
+
105
+ self.create_qgis_scripts(layers)
maps4fs/generator/dem.py CHANGED
@@ -13,8 +13,9 @@ import requests
13
13
  from maps4fs.generator.component import Component
14
14
 
15
15
  SRTM = "https://elevation-tiles-prod.s3.amazonaws.com/skadi/{latitude_band}/{tile_name}.hgt.gz"
16
- DEFAULT_MULTIPLIER = 1
16
+ DEFAULT_MULTIPLIER = 1.0
17
17
  DEFAULT_BLUR_RADIUS = 35
18
+ DEFAULT_PLATEAU = 0
18
19
 
19
20
 
20
21
  # pylint: disable=R0903, R0902
@@ -134,6 +135,16 @@ class DEM(Component):
134
135
  else:
135
136
  self.logger.debug("Auto processing is disabled, DEM data will not be normalized.")
136
137
  resampled_data = resampled_data * self.multiplier
138
+ # Clip values to 16-bit unsigned integer range.
139
+ resampled_data = np.clip(resampled_data, 0, 65535)
140
+ resampled_data = resampled_data.astype("uint16")
141
+ self.logger.debug(
142
+ "DEM data was multiplied by %s and clipped to 16-bit unsigned integer range. "
143
+ "Min: %s, max: %s.",
144
+ self.multiplier,
145
+ resampled_data.min(),
146
+ resampled_data.max(),
147
+ )
137
148
 
138
149
  self.logger.debug(
139
150
  "DEM data was resampled. Shape: %s, dtype: %s. Min: %s, max: %s.",
maps4fs/generator/qgis.py CHANGED
@@ -1,11 +1,13 @@
1
1
  """This module contains templates for generating QGIS scripts."""
2
2
 
3
+ import os
4
+
3
5
  BBOX_TEMPLATE = """
4
6
  layers = [
5
7
  {layers}
6
8
  ]
7
9
  for layer in layers:
8
- name = layer[0]
10
+ name = "Bounding_Box_" + layer[0]
9
11
  north, south, east, west = layer[1:]
10
12
 
11
13
  # Create a rectangle geometry from the bounding box.
@@ -34,6 +36,42 @@ for layer in layers:
34
36
  layer.triggerRepaint()
35
37
  """
36
38
 
39
+ POINT_TEMPLATE = """
40
+ layers = [
41
+ {layers}
42
+ ]
43
+ for layer in layers:
44
+ name = "Points_" + layer[0]
45
+ north, south, east, west = layer[1:]
46
+
47
+ top_left = QgsPointXY(north, west)
48
+ top_right = QgsPointXY(north, east)
49
+ bottom_right = QgsPointXY(south, east)
50
+ bottom_left = QgsPointXY(south, west)
51
+
52
+ points = [top_left, top_right, bottom_right, bottom_left, top_left]
53
+
54
+ # Create a new layer
55
+ layer = QgsVectorLayer('Point?crs=EPSG:3857', name, 'memory')
56
+ provider = layer.dataProvider()
57
+
58
+ # Add fields
59
+ provider.addAttributes([QgsField("id", QVariant.Int)])
60
+ layer.updateFields()
61
+
62
+ # Create and add features for each point
63
+ for i, point in enumerate(points):
64
+ feature = QgsFeature()
65
+ feature.setGeometry(QgsGeometry.fromPointXY(point))
66
+ feature.setAttributes([i + 1])
67
+ provider.addFeature(feature)
68
+
69
+ layer.updateExtents()
70
+
71
+ # Add the layer to the project
72
+ QgsProject.instance().addMapLayer(layer)
73
+ """
74
+
37
75
  RASTERIZE_TEMPLATE = """
38
76
  import processing
39
77
 
@@ -74,17 +112,18 @@ for layer in layers:
74
112
  """
75
113
 
76
114
 
77
- def get_bbox_template(layers: list[tuple[str, float, float, float, float]]) -> str:
78
- """Returns a template for creating bounding box layers in QGIS.
115
+ def _get_template(layers: list[tuple[str, float, float, float, float]], template: str) -> str:
116
+ """Returns a template for creating layers in QGIS.
79
117
 
80
118
  Args:
81
119
  layers (list[tuple[str, float, float, float, float]]): A list of tuples containing the
82
120
  layer name and the bounding box coordinates.
121
+ template (str): The template for creating layers in QGIS.
83
122
 
84
123
  Returns:
85
- str: The template for creating bounding box layers in QGIS.
124
+ str: The template for creating layers in QGIS.
86
125
  """
87
- return BBOX_TEMPLATE.format(
126
+ return template.format(
88
127
  layers=",\n ".join(
89
128
  [
90
129
  f'("{name}", {north}, {south}, {east}, {west})'
@@ -94,6 +133,32 @@ def get_bbox_template(layers: list[tuple[str, float, float, float, float]]) -> s
94
133
  )
95
134
 
96
135
 
136
+ def get_bbox_template(layers: list[tuple[str, float, float, float, float]]) -> str:
137
+ """Returns a template for creating bounding box layers in QGIS.
138
+
139
+ Args:
140
+ layers (list[tuple[str, float, float, float, float]]): A list of tuples containing the
141
+ layer name and the bounding box coordinates.
142
+
143
+ Returns:
144
+ str: The template for creating bounding box layers in QGIS.
145
+ """
146
+ return _get_template(layers, BBOX_TEMPLATE)
147
+
148
+
149
+ def get_point_template(layers: list[tuple[str, float, float, float, float]]) -> str:
150
+ """Returns a template for creating point layers in QGIS.
151
+
152
+ Args:
153
+ layers (list[tuple[str, float, float, float, float]]): A list of tuples containing the
154
+ layer name and the bounding box coordinates.
155
+
156
+ Returns:
157
+ str: The template for creating point layers in QGIS.
158
+ """
159
+ return _get_template(layers, POINT_TEMPLATE)
160
+
161
+
97
162
  def get_rasterize_template(layers: list[tuple[str, float, float, float, float]]) -> str:
98
163
  """Returns a template for rasterizing bounding box layers in QGIS.
99
164
 
@@ -104,11 +169,28 @@ def get_rasterize_template(layers: list[tuple[str, float, float, float, float]])
104
169
  Returns:
105
170
  str: The template for rasterizing bounding box layers in QGIS.
106
171
  """
107
- return RASTERIZE_TEMPLATE.format(
108
- layers=",\n ".join(
109
- [
110
- f'("{name}", {north}, {south}, {east}, {west})'
111
- for name, north, south, east, west in layers
112
- ]
113
- )
114
- )
172
+ return _get_template(layers, RASTERIZE_TEMPLATE)
173
+
174
+
175
+ def save_scripts(
176
+ layers: list[tuple[str, float, float, float, float]], file_prefix: str, save_directory: str
177
+ ) -> None:
178
+ """Saves QGIS scripts for creating bounding box, point, and raster layers.
179
+
180
+ Args:
181
+ layers (list[tuple[str, float, float, float, float]]): A list of tuples containing the
182
+ layer name and the bounding box coordinates.
183
+ save_dir (str): The directory to save the scripts.
184
+ """
185
+ script_files = [
186
+ (f"{file_prefix}_bbox.py", get_bbox_template),
187
+ (f"{file_prefix}_rasterize.py", get_rasterize_template),
188
+ (f"{file_prefix}_point.py", get_point_template),
189
+ ]
190
+
191
+ for script_file, process_function in script_files:
192
+ script_path = os.path.join(save_directory, script_file)
193
+ script_content = process_function(layers) # type: ignore
194
+
195
+ with open(script_path, "w", encoding="utf-8") as file:
196
+ file.write(script_content)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: maps4fs
3
- Version: 0.9.3
3
+ Version: 0.9.7
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
@@ -23,12 +23,15 @@ Requires-Dist: imageio
23
23
  Requires-Dist: tifffile
24
24
 
25
25
  <div align="center" markdown>
26
- <img src="https://github.com/iwatkot/maps4fs/assets/118521851/ffd7f0a3-e317-4c3f-911f-2c2fb736fbfa">
26
+ <a href="https://discord.gg/Sj5QKKyE42">
27
+ <img src="https://github.com/user-attachments/assets/37043333-d6ef-4ca3-9f3c-81323d9d0b71">
28
+ </a>
27
29
 
28
30
  <p align="center">
29
31
  <a href="#Quick-Start">Quick Start</a> •
30
32
  <a href="#Overview">Overview</a> •
31
- <a href="#How-To-Run">How-To-Run</a><br>
33
+ <a href="#How-To-Run">How-To-Run</a>
34
+ <a href="tutorials/FAQ.md">FAQ</a><br>
32
35
  <a href="#Supported-objects">Supported objects</a> •
33
36
  <a href="#Generation-info">Generation info</a> •
34
37
  <a href="#Texture-schema">Texture schema</a> •
@@ -41,6 +44,7 @@ Requires-Dist: tifffile
41
44
  </p>
42
45
 
43
46
 
47
+ [![Join Discord](https://img.shields.io/badge/join-discord-blue)](https://discord.gg/Sj5QKKyE42)
44
48
  [![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/iwatkot/maps4fs)](https://github.com/iwatkot/maps4fs/releases)
45
49
  [![PyPI - Version](https://img.shields.io/pypi/v/maps4fs)](https://pypi.org/project/maps4fs)
46
50
  [![Docker Pulls](https://img.shields.io/docker/pulls/iwatkot/maps4fs)](https://hub.docker.com/repository/docker/iwatkot/maps4fs/general)
@@ -78,7 +82,7 @@ There are several ways to use the tool. You obviously need the **first one**, bu
78
82
  ### 🚜 For most users
79
83
  **Option 1:** open the [maps4fs](https://maps4fs.streamlit.app) on StreamLit and generate a map template in a few clicks.<br>
80
84
 
81
- ![Basic WebUI](https://github.com/user-attachments/assets/14620044-9e92-47ae-8531-d61460740f58)
85
+ ![Basic WebUI](https://github.com/user-attachments/assets/52f499cc-f28a-4da3-abef-0e818abe8dbe)
82
86
 
83
87
  ### 😎 For advanced users
84
88
  **Option 2:** run the Docker version in your browser. Launch the following command in your terminal:
@@ -406,7 +410,7 @@ The tool supports the custom size of the map. To use this feature select `Custom
406
410
 
407
411
  ⛔️ 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 a specific values for the map size.<br><br>
408
412
 
409
- ![Advanced settings](https://github.com/user-attachments/assets/0446cdf2-f093-49ba-ba8f-9bef18a58b47)
413
+ ![Advanced settings](https://github.com/user-attachments/assets/e7406adf-6b82-41a0-838a-13dd8877bebf)
410
414
 
411
415
  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>
412
416
 
@@ -426,6 +430,9 @@ To create a basic map, you only need the Giants Editor. But if you want to creat
426
430
  2. [Blender](https://www.blender.org/download/) - the open-source 3D modeling software that you can use to create models for the Farming Simulator.
427
431
  3. [Blender Exporter Plugins](https://gdn.giants-software.com/downloads.php) - the official plugins for exporting models from Blender to i3d format (the format used in the Farming Simulator).
428
432
  4. [QGIS](https://qgis.org/download/) - the open-source GIS software that you can use to obtain high-resolution satellite images for your map.
433
+ 5. [CompressPngCom](https://www.compresspng.com/) - the online tool to compress the PNG images. May be useful to reduce the size of the satellite images.
434
+ 6. [AnyConv](https://anyconv.com/png-to-dds-converter/) - the online tool to convert the PNG images to the DDS format. You'll need this format for the textures, icons, overview and preview images.
429
435
 
430
436
  ## Bugs and feature requests
437
+ ➡️ Please, before creating an issue or asking some questions, check the [FAQ](tutorials/FAQ.md) section.<br>
431
438
  If you find a bug or have an idea for a new feature, please create an issue [here](https://github.com/iwatkot/maps4fs/issues) or contact me directly on [Telegram](https://t.me/iwatkot) or on Discord: `iwatkot`.
@@ -1,19 +1,19 @@
1
1
  maps4fs/__init__.py,sha256=da4jmND2Ths9AffnkAKgzLHNkvKFOc_l21gJisPXqWY,155
2
2
  maps4fs/logger.py,sha256=8oZzAKJllilYrVp452LX0zx-dNFwpS6UngbTrI6KfwA,2148
3
3
  maps4fs/generator/__init__.py,sha256=zZMLEkGzb4z0xql650gOtGSvcgX58DnJ2yN3vC2daRk,43
4
- maps4fs/generator/background.py,sha256=M43VNwiAnL4-1iUGAFwwwl5lV5EVy4luvZZmsuGO_Co,12642
5
- maps4fs/generator/component.py,sha256=tLjjbrFn3v4CrUrUOgH9s8NuJhmQcBs74ShefkNg1VE,10584
6
- maps4fs/generator/config.py,sha256=JL7leQv8C06JQOXIbgQ-jve2re7cNsx8vKa8dfbnxPM,3896
7
- maps4fs/generator/dem.py,sha256=p7THncPUdYWtNR2HrTXe0bCuJ8psUV8rRpYPJkzL2gA,15220
4
+ maps4fs/generator/background.py,sha256=AP-Z3F-4I9achvA9xsaXAAoA6IHtmPLxb1RkUsVYdbg,14036
5
+ maps4fs/generator/component.py,sha256=ZEDjChPnvqAsgnBu2f2YBOlwGOlfax4VaAYBcJerLIQ,10684
6
+ maps4fs/generator/config.py,sha256=ZO5BWDU-S3p0-ndKDSFa8Oin3YcYy0iH8B4lqEA_07Q,4275
7
+ maps4fs/generator/dem.py,sha256=XLpzjJMPZCxjrF-AhwTeEb-OQoCHEtYdK0b8z3Gb-is,15712
8
8
  maps4fs/generator/game.py,sha256=94HjPNOyy6XSSOnBp-uxrkBglKyC-X3ULIrrucfdlKw,6825
9
9
  maps4fs/generator/i3d.py,sha256=UuQiQRusPQ2f6PvGKxJ_UZeXsx3uG15efmy8Ysnm3F8,3597
10
10
  maps4fs/generator/map.py,sha256=v8OOLmhAkgqq64tQgEDbV6DmbgOVm3NXJBDDy0nJf60,4226
11
11
  maps4fs/generator/path_steps.py,sha256=yeN6hmOD8O2LMozUf4HcQMIy8WJ5sHF5pGQT_s2FfOw,3147
12
- maps4fs/generator/qgis.py,sha256=k19miPEFyOdu_ogBFHmFVfYQ-IgF38ufJZ5DM5NSHBQ,3400
12
+ maps4fs/generator/qgis.py,sha256=R5Iv3ovyLXkhAL5Oy41u3ZLNOSEbc1byLetzPootO7o,6091
13
13
  maps4fs/generator/texture.py,sha256=CwaXZfAG4e3D3YR7yVR2MC677EHpbUWTboCS3G6jkhk,17723
14
14
  maps4fs/generator/tile.py,sha256=3vmfjQiPiiUZKPuIo5tg2rOKkgcP1NRVkMGK-Vo10-A,2138
15
- maps4fs-0.9.3.dist-info/LICENSE.md,sha256=-JY0v7p3dwXze61EbYiK7YEJ2aKrjaFZ8y2xYEOrmRY,1068
16
- maps4fs-0.9.3.dist-info/METADATA,sha256=0iPJEUJXeSqgNXqhcD2BM5lqkvX7YBK2O-UFWY5HxvM,23996
17
- maps4fs-0.9.3.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
18
- maps4fs-0.9.3.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
19
- maps4fs-0.9.3.dist-info/RECORD,,
15
+ maps4fs-0.9.7.dist-info/LICENSE.md,sha256=-JY0v7p3dwXze61EbYiK7YEJ2aKrjaFZ8y2xYEOrmRY,1068
16
+ maps4fs-0.9.7.dist-info/METADATA,sha256=dhMICyAhvj7SiKMKyK_-ewOb07j38R574o9SMezErYE,24635
17
+ maps4fs-0.9.7.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
18
+ maps4fs-0.9.7.dist-info/top_level.txt,sha256=Ue9DSRlejRQRCaJueB0uLcKrWwsEq9zezfv5dI5mV1M,8
19
+ maps4fs-0.9.7.dist-info/RECORD,,