maps4fs 1.4.1__tar.gz → 1.5.7__tar.gz

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.
Files changed (30) hide show
  1. {maps4fs-1.4.1 → maps4fs-1.5.7}/PKG-INFO +48 -27
  2. {maps4fs-1.4.1 → maps4fs-1.5.7}/README.md +47 -26
  3. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/__init__.py +3 -2
  4. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/generator/background.py +74 -110
  5. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/generator/component.py +10 -0
  6. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/generator/dem.py +22 -106
  7. maps4fs-1.5.7/maps4fs/generator/dtm.py +333 -0
  8. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/generator/game.py +2 -1
  9. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/generator/grle.py +5 -0
  10. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/generator/i3d.py +27 -14
  11. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/generator/map.py +36 -118
  12. maps4fs-1.5.7/maps4fs/generator/satellite.py +92 -0
  13. maps4fs-1.5.7/maps4fs/generator/settings.py +150 -0
  14. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/generator/texture.py +14 -2
  15. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs.egg-info/PKG-INFO +48 -27
  16. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs.egg-info/SOURCES.txt +3 -0
  17. {maps4fs-1.4.1 → maps4fs-1.5.7}/pyproject.toml +1 -1
  18. {maps4fs-1.4.1 → maps4fs-1.5.7}/tests/test_generator.py +10 -1
  19. {maps4fs-1.4.1 → maps4fs-1.5.7}/LICENSE.md +0 -0
  20. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/generator/__init__.py +0 -0
  21. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/generator/config.py +0 -0
  22. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/generator/qgis.py +0 -0
  23. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/logger.py +0 -0
  24. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/toolbox/__init__.py +0 -0
  25. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/toolbox/background.py +0 -0
  26. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs/toolbox/dem.py +0 -0
  27. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs.egg-info/dependency_links.txt +0 -0
  28. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs.egg-info/requires.txt +0 -0
  29. {maps4fs-1.4.1 → maps4fs-1.5.7}/maps4fs.egg-info/top_level.txt +0 -0
  30. {maps4fs-1.4.1 → maps4fs-1.5.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: maps4fs
3
- Version: 1.4.1
3
+ Version: 1.5.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
@@ -45,6 +45,7 @@ Requires-Dist: pydantic
45
45
  <a href="#Overview-image">Overview image</a><br>
46
46
  <a href="#DDS-conversion">DDS conversion</a> •
47
47
  <a href="#Advanced-settings">Advanced settings</a> •
48
+ <a href="#Expert-settings">Expert settings</a> •
48
49
  <a href="#Resources">Resources</a> •
49
50
  <a href="#Bugs-and-feature-requests">Bugs and feature requests</a><br>
50
51
  <a href="#Special-thanks">Special thanks</a>
@@ -74,6 +75,8 @@ Requires-Dist: pydantic
74
75
  🌲 Automatically generates forests 🆕<br>
75
76
  🌊 Automatically generates water planes 🆕<br>
76
77
  📈 Automatically generates splines 🆕<br>
78
+ 🛰️ Automatically downloads high resolution satellite images 🆕<br>
79
+ 🏔️ Allows to use multiple DTM providers for elevation models 🆕<br>
77
80
  🌍 Based on real-world data from OpenStreetMap<br>
78
81
  🗺️ Supports [custom OSM maps](/docs/custom_osm.md)<br>
79
82
  🏞️ Generates height map using SRTM dataset<br>
@@ -256,18 +259,12 @@ Tools are divided into categories, which are listed below.
256
259
 
257
260
  ## Supported objects
258
261
  The project is based on the [OpenStreetMap](https://www.openstreetmap.org/) data. So, refer to [this page](https://wiki.openstreetmap.org/wiki/Map_Features) to understand the list below.
259
- - "building": True
260
- - "highway": ["motorway", "trunk", "primary"]
261
- - "highway": ["secondary", "tertiary", "road", "service"]
262
- - "highway": ["unclassified", "residential", "track"]
263
- - "natural": ["grassland", "scrub"]
264
- - "landuse": "farmland"
265
- - "natural": ["water"]
266
- - "waterway": True
267
- - "natural": ["wood", "tree_row"]
268
- - "railway": True
269
-
270
- The list will be updated as the project develops.
262
+
263
+ You can find the active schemas here:
264
+ - [FS25](/data/fs25-texture-schema.json)
265
+ - [FS22](/data/fs22-texture-schema.json)
266
+
267
+ Learn more how to work with the schema in the [Texture schema](#texture-schema) section. You can also use your own schema in the [Expert settings](#expert-settings) section.
271
268
 
272
269
  ## Generation info
273
270
  The script will generate the `generation_info.json` file in the `output` folder. It is split into different sections, which represent the components of the map generator. You may need this information to use some other tools and services to obtain additional data for your map.<br>
@@ -418,6 +415,10 @@ Let's have a closer look at the fields:
418
415
  - `priority` - the priority of the texture for overlapping. Textures with higher priorities will be drawn over the textures with lower priorities.
419
416
  ℹ️ The texture with 0 priority considers the base layer, which means that all empty areas will be filled with this texture.
420
417
  - `exclude_weight` - this is only used for the forestRockRoots texture from FS25. It just means that this texture has no `weight` postfix, that's all.
418
+ - `usage` - the usage of the texture. Mainly used to group different textures by the purpose. For example, the `grass`, `forest`, `drain`.
419
+ - `background` - set it to True for the textures, which should have impact on the Background Terrain, by default it's used to subtract the water depth from the DEM and background terrain.
420
+ - `info_layer` - if the layer is saving some data in JSON format, this section will describe it's name in the JSON file. Used to find the needed JSON data, for example for fields it will be `fields` and as a value - list of polygon coordinates.
421
+ - `invisible` - set it to True for the textures, which should not be drawn in the files, but only to save the data in the JSON file (related to the previous field).
421
422
 
422
423
  ## Background terrain
423
424
  The tool now supports the generation of the background terrain. If you don't know what it is, here's a brief explanation. The background terrain is the world around the map. It's important to create it because if you don't, the map will look like it's floating in the void. The background terrain is a simple plane that can (and should) be textured to look fine.<br>
@@ -478,40 +479,59 @@ You can also apply some advanced settings to the map generation process. Note th
478
479
 
479
480
  - 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.
480
481
 
481
- - 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.
482
+ - Plateau: 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.
482
483
 
483
484
  - Water depth: this value will be subtracted from each pixel of the DEM image, where water resources are located. Pay attention that it's not in meters, instead it in the pixel value of DEM, which is 16 bit image with possible values from 0 to 65535. When this value is set, the same value will be added to the plateau setting to avoid negative heights.
484
485
 
485
- ### Texture Advanced settings
486
+ ### Background terrain Advanced settings
486
487
 
487
- - 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.
488
+ - 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.
488
489
 
489
- - Texture dissolving - if enabled, the values from one layer will be splitted between different layers of texture, making it look more natural. By default, it's set to True. Can be turned of for faster processing.
490
+ - Generate water - if enabled, the water planes obj files 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.
490
491
 
491
- - Skip drains - if enabled, the tool will not generate the drains and ditches on the map. By default, it's set to False. Use this if you don't need the drains on the map.
492
+ - Resize factor - the factor by which the background terrain will be resized. It will be used as 1 / resize_factor while generating the models. Which means that the larger the value the more the terrain will be resized. The lowest value is 1, in this case background terrain will not be resized. Note, than low values will lead to long processing and enormous size of the obj files.
492
493
 
493
- ### Farmlands Advanced settings
494
+ ### GRLE Advanced settings
494
495
 
495
496
  - Farmlands margin - this value (in meters) will be applied to each farmland, making it bigger. You can use the value to adjust how much the farmland should be bigger than the actual field. By default, it's set to 3.
496
497
 
497
- ### Vegetation Advanced settings
498
+ - Random plants - when adding decorative foliage, enabling this option will add different species of plants to the map. If unchecked only basic grass (smallDenseMix) will be added. Defaults to True.
498
499
 
499
- - 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.
500
+ - 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.
500
501
 
501
- - Random plants - when adding decorative foliage, enabling this option will add different species of plants to the map. If unchecked only basic grass (smallDenseMix) will be added. Defaults to True.
502
+ ### I3D Advanced settings
502
503
 
503
- ### Background terrain Advanced settings
504
+ - 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.
504
505
 
505
- - 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.
506
+ ### Texture Advanced settings
506
507
 
507
- - Generate water - if enabled, the water planes obj files 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.
508
+ - Dissolve - if enabled, the values from one layer will be splitted between different layers of texture, making it look more natural. Warning: it's a time-consuming process, recommended to enable it, when you generating the final version of the map, not some test versions.
508
509
 
509
- - Resize factor - the factor by which the background terrain will be resized. It will be used as 1 / resize_factor while generating the models. Which means that the larger the value the more the terrain will be resized. The lowest value is 1, in this case background terrain will not be resized. Note, than low values will lead to long processing and enormous size of the obj files.
510
+ - 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.
511
+
512
+ - Skip drains - if enabled, the tool will not generate the drains and ditches on the map. By default, it's set to False. Use this if you don't need the drains on the map.
510
513
 
511
- ## Splines Advanced settings
514
+ ### Splines Advanced settings
512
515
 
513
516
  - Splines density - number of points, which will be added (interpolate) between each pair of existing points. The higher the value, the denser the spline will be. It can smooth the splines, but high values can in opposite make the splines look unnatural.
514
517
 
518
+ ### Satellite Advanced settings
519
+
520
+ - Download images - if enabled, the tool will download the satellite images for the background terrain and the overview image. If you already have the images, you can turn it off.
521
+ - Satellite margin - the margin around the map in meters. It's useful when you want to have some space around the map on the satellite images. By default, it's set to 100.
522
+ - Zoom level - the zoom level of the satellite images. The higher the value, the more detailed the images will be. By default, it's set to 14 and this option is disabled on a public version of the app.
523
+
524
+ ## Expert Settings
525
+ The tool also supports the expert settings. Do not use them until you read the documentation and understand what they do. Here's the list of the expert settings:
526
+
527
+ - Enable debug logs - if enabled, the tool will print the debug logs to the console. It can be useful if you're using with a custom OSM map, have some issues with it and want to know what's wrong.
528
+
529
+ - Upload custom OSM file - you'll be able to upload your own OSM file. Before using it, carefully read the [Custom OSM](docs/custom_osm.md) documentation, otherwise, the tool will not work as expected.
530
+
531
+ - Show raw configuration - you'll be able to change all the settings in a single JSON file. It's useful if you want to save the configuration and use it later, without changing the settings in the UI. Be extremely careful with this setting, because you can break the tool with incorrect settings.
532
+
533
+ - Show schemas - you'll be able to edit or define your own texture or tree schemas. It's useful if you want to add some custom textures or trees to the map. Refer to the [Texture schema](#texture-schema) section to learn more about the schema structure. Any incorrect value here will lead to the completely broken map.
534
+
515
535
  ## Resources
516
536
  In this section, you'll find a list of the resources that you need to create a map for the Farming Simulator.<br>
517
537
  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>
@@ -541,3 +561,4 @@ But also, I want to thank the people who helped me with the project in some way,
541
561
  - [Tox3](https://github.com/Tox3) - for the manual tests of the app.
542
562
  - [Lucandia](https://github.com/Lucandia) - for the awesome StreamLit [widget to preview STL files](https://github.com/Lucandia/streamlit_stl).
543
563
  - [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.
564
+ - [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.
@@ -19,6 +19,7 @@
19
19
  <a href="#Overview-image">Overview image</a><br>
20
20
  <a href="#DDS-conversion">DDS conversion</a> •
21
21
  <a href="#Advanced-settings">Advanced settings</a> •
22
+ <a href="#Expert-settings">Expert settings</a> •
22
23
  <a href="#Resources">Resources</a> •
23
24
  <a href="#Bugs-and-feature-requests">Bugs and feature requests</a><br>
24
25
  <a href="#Special-thanks">Special thanks</a>
@@ -48,6 +49,8 @@
48
49
  🌲 Automatically generates forests 🆕<br>
49
50
  🌊 Automatically generates water planes 🆕<br>
50
51
  📈 Automatically generates splines 🆕<br>
52
+ 🛰️ Automatically downloads high resolution satellite images 🆕<br>
53
+ 🏔️ Allows to use multiple DTM providers for elevation models 🆕<br>
51
54
  🌍 Based on real-world data from OpenStreetMap<br>
52
55
  🗺️ Supports [custom OSM maps](/docs/custom_osm.md)<br>
53
56
  🏞️ Generates height map using SRTM dataset<br>
@@ -230,18 +233,12 @@ Tools are divided into categories, which are listed below.
230
233
 
231
234
  ## Supported objects
232
235
  The project is based on the [OpenStreetMap](https://www.openstreetmap.org/) data. So, refer to [this page](https://wiki.openstreetmap.org/wiki/Map_Features) to understand the list below.
233
- - "building": True
234
- - "highway": ["motorway", "trunk", "primary"]
235
- - "highway": ["secondary", "tertiary", "road", "service"]
236
- - "highway": ["unclassified", "residential", "track"]
237
- - "natural": ["grassland", "scrub"]
238
- - "landuse": "farmland"
239
- - "natural": ["water"]
240
- - "waterway": True
241
- - "natural": ["wood", "tree_row"]
242
- - "railway": True
243
-
244
- The list will be updated as the project develops.
236
+
237
+ You can find the active schemas here:
238
+ - [FS25](/data/fs25-texture-schema.json)
239
+ - [FS22](/data/fs22-texture-schema.json)
240
+
241
+ Learn more how to work with the schema in the [Texture schema](#texture-schema) section. You can also use your own schema in the [Expert settings](#expert-settings) section.
245
242
 
246
243
  ## Generation info
247
244
  The script will generate the `generation_info.json` file in the `output` folder. It is split into different sections, which represent the components of the map generator. You may need this information to use some other tools and services to obtain additional data for your map.<br>
@@ -392,6 +389,10 @@ Let's have a closer look at the fields:
392
389
  - `priority` - the priority of the texture for overlapping. Textures with higher priorities will be drawn over the textures with lower priorities.
393
390
  ℹ️ The texture with 0 priority considers the base layer, which means that all empty areas will be filled with this texture.
394
391
  - `exclude_weight` - this is only used for the forestRockRoots texture from FS25. It just means that this texture has no `weight` postfix, that's all.
392
+ - `usage` - the usage of the texture. Mainly used to group different textures by the purpose. For example, the `grass`, `forest`, `drain`.
393
+ - `background` - set it to True for the textures, which should have impact on the Background Terrain, by default it's used to subtract the water depth from the DEM and background terrain.
394
+ - `info_layer` - if the layer is saving some data in JSON format, this section will describe it's name in the JSON file. Used to find the needed JSON data, for example for fields it will be `fields` and as a value - list of polygon coordinates.
395
+ - `invisible` - set it to True for the textures, which should not be drawn in the files, but only to save the data in the JSON file (related to the previous field).
395
396
 
396
397
  ## Background terrain
397
398
  The tool now supports the generation of the background terrain. If you don't know what it is, here's a brief explanation. The background terrain is the world around the map. It's important to create it because if you don't, the map will look like it's floating in the void. The background terrain is a simple plane that can (and should) be textured to look fine.<br>
@@ -452,40 +453,59 @@ You can also apply some advanced settings to the map generation process. Note th
452
453
 
453
454
  - 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.
454
455
 
455
- - 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.
456
+ - Plateau: 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.
456
457
 
457
458
  - Water depth: this value will be subtracted from each pixel of the DEM image, where water resources are located. Pay attention that it's not in meters, instead it in the pixel value of DEM, which is 16 bit image with possible values from 0 to 65535. When this value is set, the same value will be added to the plateau setting to avoid negative heights.
458
459
 
459
- ### Texture Advanced settings
460
+ ### Background terrain Advanced settings
460
461
 
461
- - 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.
462
+ - 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.
462
463
 
463
- - Texture dissolving - if enabled, the values from one layer will be splitted between different layers of texture, making it look more natural. By default, it's set to True. Can be turned of for faster processing.
464
+ - Generate water - if enabled, the water planes obj files 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.
464
465
 
465
- - Skip drains - if enabled, the tool will not generate the drains and ditches on the map. By default, it's set to False. Use this if you don't need the drains on the map.
466
+ - Resize factor - the factor by which the background terrain will be resized. It will be used as 1 / resize_factor while generating the models. Which means that the larger the value the more the terrain will be resized. The lowest value is 1, in this case background terrain will not be resized. Note, than low values will lead to long processing and enormous size of the obj files.
466
467
 
467
- ### Farmlands Advanced settings
468
+ ### GRLE Advanced settings
468
469
 
469
470
  - Farmlands margin - this value (in meters) will be applied to each farmland, making it bigger. You can use the value to adjust how much the farmland should be bigger than the actual field. By default, it's set to 3.
470
471
 
471
- ### Vegetation Advanced settings
472
+ - Random plants - when adding decorative foliage, enabling this option will add different species of plants to the map. If unchecked only basic grass (smallDenseMix) will be added. Defaults to True.
472
473
 
473
- - 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.
474
+ - 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.
474
475
 
475
- - Random plants - when adding decorative foliage, enabling this option will add different species of plants to the map. If unchecked only basic grass (smallDenseMix) will be added. Defaults to True.
476
+ ### I3D Advanced settings
476
477
 
477
- ### Background terrain Advanced settings
478
+ - 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.
478
479
 
479
- - 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.
480
+ ### Texture Advanced settings
480
481
 
481
- - Generate water - if enabled, the water planes obj files 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.
482
+ - Dissolve - if enabled, the values from one layer will be splitted between different layers of texture, making it look more natural. Warning: it's a time-consuming process, recommended to enable it, when you generating the final version of the map, not some test versions.
482
483
 
483
- - Resize factor - the factor by which the background terrain will be resized. It will be used as 1 / resize_factor while generating the models. Which means that the larger the value the more the terrain will be resized. The lowest value is 1, in this case background terrain will not be resized. Note, than low values will lead to long processing and enormous size of the obj files.
484
+ - 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.
485
+
486
+ - Skip drains - if enabled, the tool will not generate the drains and ditches on the map. By default, it's set to False. Use this if you don't need the drains on the map.
484
487
 
485
- ## Splines Advanced settings
488
+ ### Splines Advanced settings
486
489
 
487
490
  - Splines density - number of points, which will be added (interpolate) between each pair of existing points. The higher the value, the denser the spline will be. It can smooth the splines, but high values can in opposite make the splines look unnatural.
488
491
 
492
+ ### Satellite Advanced settings
493
+
494
+ - Download images - if enabled, the tool will download the satellite images for the background terrain and the overview image. If you already have the images, you can turn it off.
495
+ - Satellite margin - the margin around the map in meters. It's useful when you want to have some space around the map on the satellite images. By default, it's set to 100.
496
+ - Zoom level - the zoom level of the satellite images. The higher the value, the more detailed the images will be. By default, it's set to 14 and this option is disabled on a public version of the app.
497
+
498
+ ## Expert Settings
499
+ The tool also supports the expert settings. Do not use them until you read the documentation and understand what they do. Here's the list of the expert settings:
500
+
501
+ - Enable debug logs - if enabled, the tool will print the debug logs to the console. It can be useful if you're using with a custom OSM map, have some issues with it and want to know what's wrong.
502
+
503
+ - Upload custom OSM file - you'll be able to upload your own OSM file. Before using it, carefully read the [Custom OSM](docs/custom_osm.md) documentation, otherwise, the tool will not work as expected.
504
+
505
+ - Show raw configuration - you'll be able to change all the settings in a single JSON file. It's useful if you want to save the configuration and use it later, without changing the settings in the UI. Be extremely careful with this setting, because you can break the tool with incorrect settings.
506
+
507
+ - Show schemas - you'll be able to edit or define your own texture or tree schemas. It's useful if you want to add some custom textures or trees to the map. Refer to the [Texture schema](#texture-schema) section to learn more about the schema structure. Any incorrect value here will lead to the completely broken map.
508
+
489
509
  ## Resources
490
510
  In this section, you'll find a list of the resources that you need to create a map for the Farming Simulator.<br>
491
511
  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>
@@ -515,3 +535,4 @@ But also, I want to thank the people who helped me with the project in some way,
515
535
  - [Tox3](https://github.com/Tox3) - for the manual tests of the app.
516
536
  - [Lucandia](https://github.com/Lucandia) - for the awesome StreamLit [widget to preview STL files](https://github.com/Lucandia/streamlit_stl).
517
537
  - [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.
538
+ - [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.
@@ -1,11 +1,12 @@
1
1
  # pylint: disable=missing-module-docstring
2
+ from maps4fs.generator.dtm import DTMProvider
2
3
  from maps4fs.generator.game import Game
3
- from maps4fs.generator.map import (
4
+ from maps4fs.generator.map import Map
5
+ from maps4fs.generator.settings import (
4
6
  BackgroundSettings,
5
7
  DEMSettings,
6
8
  GRLESettings,
7
9
  I3DSettings,
8
- Map,
9
10
  SettingsModel,
10
11
  SplineSettings,
11
12
  TextureSettings,
@@ -57,36 +57,23 @@ class Background(Component):
57
57
  os.makedirs(self.background_directory, exist_ok=True)
58
58
  os.makedirs(self.water_directory, exist_ok=True)
59
59
 
60
- autoprocesses = [self.map.dem_settings.auto_process, False]
61
- self.output_paths = [
62
- os.path.join(self.background_directory, f"{name}.png") for name in ELEMENTS
63
- ]
60
+ self.output_path = os.path.join(self.background_directory, f"{FULL_NAME}.png")
64
61
  self.not_substracted_path = os.path.join(self.background_directory, "not_substracted.png")
65
62
  self.not_resized_path = os.path.join(self.background_directory, "not_resized.png")
66
63
 
67
- dems = []
68
-
69
- for name, autoprocess, output_path in zip(ELEMENTS, autoprocesses, self.output_paths):
70
- dem = DEM(
71
- self.game,
72
- self.map,
73
- self.coordinates,
74
- self.background_size,
75
- self.rotated_size,
76
- self.rotation,
77
- self.map_directory,
78
- self.logger,
79
- )
80
- dem.preprocess()
81
- dem.is_preview = self.is_preview(name) # type: ignore
82
- if dem.is_preview: # type: ignore
83
- dem.multiplier = 1
84
- dem.auto_process = autoprocess
85
- dem.set_output_resolution((self.rotated_size, self.rotated_size))
86
- dem.set_dem_path(output_path)
87
- dems.append(dem)
88
-
89
- self.dems = dems
64
+ self.dem = DEM(
65
+ self.game,
66
+ self.map,
67
+ self.coordinates,
68
+ self.background_size,
69
+ self.rotated_size,
70
+ self.rotation,
71
+ self.map_directory,
72
+ self.logger,
73
+ )
74
+ self.dem.preprocess()
75
+ self.dem.set_output_resolution((self.rotated_size, self.rotated_size))
76
+ self.dem.set_dem_path(self.output_path)
90
77
 
91
78
  def is_preview(self, name: str) -> bool:
92
79
  """Checks if the DEM is a preview.
@@ -104,21 +91,17 @@ class Background(Component):
104
91
  as a result the DEM files will be saved, then based on them the obj files will be
105
92
  generated."""
106
93
  self.create_background_textures()
94
+ self.dem.process()
107
95
 
108
- for dem in self.dems:
109
- dem.process()
110
- if not dem.is_preview: # type: ignore
111
- shutil.copyfile(dem.dem_path, self.not_substracted_path)
112
- self.cutout(dem.dem_path, save_path=self.not_resized_path)
96
+ shutil.copyfile(self.dem.dem_path, self.not_substracted_path)
97
+ self.cutout(self.dem.dem_path, save_path=self.not_resized_path)
113
98
 
114
99
  if self.map.dem_settings.water_depth:
115
100
  self.subtraction()
116
101
 
117
- for dem in self.dems:
118
- if not dem.is_preview: # type: ignore
119
- cutted_dem_path = self.cutout(dem.dem_path)
120
- if self.game.additional_dem_name is not None:
121
- self.make_copy(cutted_dem_path, self.game.additional_dem_name)
102
+ cutted_dem_path = self.cutout(self.dem.dem_path)
103
+ if self.game.additional_dem_name is not None:
104
+ self.make_copy(cutted_dem_path, self.game.additional_dem_name)
122
105
 
123
106
  if self.map.background_settings.generate_background:
124
107
  self.generate_obj_files()
@@ -149,19 +132,17 @@ class Background(Component):
149
132
  """
150
133
  self.qgis_sequence()
151
134
 
152
- dem = self.dems[0]
153
-
154
- north, south, east, west = dem.bbox
155
- epsg3857_string = dem.get_epsg3857_string()
156
- epsg3857_string_with_margin = dem.get_epsg3857_string(add_margin=True)
135
+ north, south, east, west = self.dem.bbox
136
+ epsg3857_string = self.dem.get_epsg3857_string()
137
+ epsg3857_string_with_margin = self.dem.get_epsg3857_string(add_margin=True)
157
138
 
158
139
  data = {
159
- "center_latitude": dem.coordinates[0],
160
- "center_longitude": dem.coordinates[1],
140
+ "center_latitude": self.dem.coordinates[0],
141
+ "center_longitude": self.dem.coordinates[1],
161
142
  "epsg3857_string": epsg3857_string,
162
143
  "epsg3857_string_with_margin": epsg3857_string_with_margin,
163
- "height": dem.map_size,
164
- "width": dem.map_size,
144
+ "height": self.dem.map_size,
145
+ "width": self.dem.map_size,
165
146
  "north": north,
166
147
  "south": south,
167
148
  "east": east,
@@ -171,10 +152,10 @@ class Background(Component):
171
152
 
172
153
  def qgis_sequence(self) -> None:
173
154
  """Generates QGIS scripts for creating bounding box layers and rasterizing them."""
174
- qgis_layer = (f"Background_{FULL_NAME}", *self.dems[0].get_espg3857_bbox())
155
+ qgis_layer = (f"Background_{FULL_NAME}", *self.dem.get_espg3857_bbox())
175
156
  qgis_layer_with_margin = (
176
157
  f"Background_{FULL_NAME}_margin",
177
- *self.dems[0].get_espg3857_bbox(add_margin=True),
158
+ *self.dem.get_espg3857_bbox(add_margin=True),
178
159
  )
179
160
  self.create_qgis_scripts([qgis_layer, qgis_layer_with_margin])
180
161
 
@@ -182,21 +163,20 @@ class Background(Component):
182
163
  """Iterates over all dems and generates 3D obj files based on DEM data.
183
164
  If at least one DEM file is missing, the generation will be stopped at all.
184
165
  """
185
- for dem in self.dems:
186
- if not os.path.isfile(dem.dem_path):
187
- self.logger.warning(
188
- "DEM file not found, generation will be stopped: %s", dem.dem_path
189
- )
190
- return
166
+ if not os.path.isfile(self.dem.dem_path):
167
+ self.logger.warning(
168
+ "DEM file not found, generation will be stopped: %s", self.dem.dem_path
169
+ )
170
+ return
191
171
 
192
- self.logger.debug("DEM file for found: %s", dem.dem_path)
172
+ self.logger.debug("DEM file for found: %s", self.dem.dem_path)
193
173
 
194
- filename = os.path.splitext(os.path.basename(dem.dem_path))[0]
195
- save_path = os.path.join(self.background_directory, f"{filename}.obj")
196
- self.logger.debug("Generating obj file in path: %s", save_path)
174
+ filename = os.path.splitext(os.path.basename(self.dem.dem_path))[0]
175
+ save_path = os.path.join(self.background_directory, f"{filename}.obj")
176
+ self.logger.debug("Generating obj file in path: %s", save_path)
197
177
 
198
- dem_data = cv2.imread(dem.dem_path, cv2.IMREAD_UNCHANGED) # pylint: disable=no-member
199
- self.plane_from_np(dem_data, save_path, is_preview=dem.is_preview) # type: ignore
178
+ dem_data = cv2.imread(self.dem.dem_path, cv2.IMREAD_UNCHANGED) # pylint: disable=no-member
179
+ self.plane_from_np(dem_data, save_path) # type: ignore
200
180
 
201
181
  # pylint: disable=too-many-locals
202
182
  def cutout(self, dem_path: str, save_path: str | None = None) -> str:
@@ -248,7 +228,6 @@ class Background(Component):
248
228
  self,
249
229
  dem_data: np.ndarray,
250
230
  save_path: str,
251
- is_preview: bool = False,
252
231
  include_zeros: bool = True,
253
232
  ) -> None:
254
233
  """Generates a 3D obj file based on DEM data.
@@ -256,7 +235,6 @@ class Background(Component):
256
235
  Arguments:
257
236
  dem_data (np.ndarray) -- The DEM data as a numpy array.
258
237
  save_path (str) -- The path where the obj file will be saved.
259
- is_preview (bool, optional) -- If True, the preview mesh will be generated.
260
238
  include_zeros (bool, optional) -- If True, the mesh will include the zero height values.
261
239
  """
262
240
  resize_factor = 1 / self.map.background_settings.resize_factor
@@ -315,25 +293,21 @@ class Background(Component):
315
293
  mesh.apply_transform(rotation_matrix_y)
316
294
  mesh.apply_transform(rotation_matrix_z)
317
295
 
318
- if is_preview:
296
+ # if not include_zeros:
297
+ z_scaling_factor = 1 / self.map.dem_settings.multiplier
298
+ self.logger.debug("Z scaling factor: %s", z_scaling_factor)
299
+ mesh.apply_scale([1 / resize_factor, 1 / resize_factor, z_scaling_factor])
300
+
301
+ mesh.export(save_path)
302
+ self.logger.debug("Obj file saved: %s", save_path)
303
+
304
+ if include_zeros:
319
305
  # Simplify the preview mesh to reduce the size of the file.
320
306
  mesh = mesh.simplify_quadric_decimation(face_count=len(mesh.faces) // 2**7)
321
307
 
322
308
  # Apply scale to make the preview mesh smaller in the UI.
323
309
  mesh.apply_scale([0.5, 0.5, 0.5])
324
310
  self.mesh_to_stl(mesh)
325
- else:
326
- if not include_zeros:
327
- multiplier = self.map.dem_settings.multiplier
328
- if multiplier != 1:
329
- z_scaling_factor = 1 / multiplier
330
- else:
331
- z_scaling_factor = 1 / 2**5
332
- self.logger.debug("Z scaling factor: %s", z_scaling_factor)
333
- mesh.apply_scale([1 / resize_factor, 1 / resize_factor, z_scaling_factor])
334
-
335
- mesh.export(save_path)
336
- self.logger.debug("Obj file saved: %s", save_path)
337
311
 
338
312
  def mesh_to_stl(self, mesh: trimesh.Trimesh) -> None:
339
313
  """Converts the mesh to an STL file and saves it in the previews directory.
@@ -358,25 +332,22 @@ class Background(Component):
358
332
  list[str] -- A list of paths to the previews.
359
333
  """
360
334
  preview_paths = self.dem_previews(self.game.dem_file_path(self.map_directory))
361
- for dem in self.dems:
362
- if dem.is_preview: # type: ignore
363
- background_dem_preview_path = os.path.join(
364
- self.previews_directory, "background_dem.png"
365
- )
366
- background_dem_preview_image = cv2.imread(dem.dem_path, cv2.IMREAD_UNCHANGED)
367
-
368
- background_dem_preview_image = cv2.resize(
369
- background_dem_preview_image, (0, 0), fx=1 / 4, fy=1 / 4
370
- )
371
- background_dem_preview_image = cv2.normalize( # type: ignore
372
- background_dem_preview_image, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U
373
- )
374
- background_dem_preview_image = cv2.cvtColor(
375
- background_dem_preview_image, cv2.COLOR_GRAY2BGR
376
- )
377
-
378
- cv2.imwrite(background_dem_preview_path, background_dem_preview_image)
379
- preview_paths.append(background_dem_preview_path)
335
+
336
+ background_dem_preview_path = os.path.join(self.previews_directory, "background_dem.png")
337
+ background_dem_preview_image = cv2.imread(self.dem.dem_path, cv2.IMREAD_UNCHANGED)
338
+
339
+ background_dem_preview_image = cv2.resize(
340
+ background_dem_preview_image, (0, 0), fx=1 / 4, fy=1 / 4
341
+ )
342
+ background_dem_preview_image = cv2.normalize( # type: ignore
343
+ background_dem_preview_image, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U
344
+ )
345
+ background_dem_preview_image = cv2.cvtColor(
346
+ background_dem_preview_image, cv2.COLOR_GRAY2BGR
347
+ )
348
+
349
+ cv2.imwrite(background_dem_preview_path, background_dem_preview_image)
350
+ preview_paths.append(background_dem_preview_path)
380
351
 
381
352
  if self.stl_preview_path:
382
353
  preview_paths.append(self.stl_preview_path)
@@ -525,18 +496,15 @@ class Background(Component):
525
496
  bool
526
497
  )
527
498
 
528
- for output_path in self.output_paths:
529
- if FULL_PREVIEW_NAME in output_path:
530
- continue
531
- dem_image = cv2.imread(output_path, cv2.IMREAD_UNCHANGED)
499
+ dem_image = cv2.imread(self.output_path, cv2.IMREAD_UNCHANGED)
532
500
 
533
- # Create a mask where water_resources_image is 255 (or not 0)
534
- # Subtract water_depth from dem_image where mask is True
535
- dem_image[mask] = dem_image[mask] - self.map.dem_settings.water_depth
501
+ # Create a mask where water_resources_image is 255 (or not 0)
502
+ # Subtract water_depth from dem_image where mask is True
503
+ dem_image[mask] = dem_image[mask] - self.map.dem_settings.water_depth
536
504
 
537
- # Save the modified dem_image back to the output path
538
- cv2.imwrite(output_path, dem_image)
539
- self.logger.debug("Water depth subtracted from DEM data: %s", output_path)
505
+ # Save the modified dem_image back to the output path
506
+ cv2.imwrite(self.output_path, dem_image)
507
+ self.logger.debug("Water depth subtracted from DEM data: %s", self.output_path)
540
508
 
541
509
  def generate_water_resources_obj(self) -> None:
542
510
  """Generates 3D obj files based on water resources data."""
@@ -550,9 +518,7 @@ class Background(Component):
550
518
  plane_water.astype(np.uint8), np.ones((5, 5), np.uint8), iterations=5
551
519
  ).astype(np.uint8)
552
520
  plane_save_path = os.path.join(self.water_directory, "plane_water.obj")
553
- self.plane_from_np(
554
- dilated_plane_water, plane_save_path, is_preview=False, include_zeros=False
555
- )
521
+ self.plane_from_np(dilated_plane_water, plane_save_path, include_zeros=False)
556
522
 
557
523
  # Single channeled 16 bit DEM image of terrain.
558
524
  background_dem = cv2.imread(self.not_substracted_path, cv2.IMREAD_UNCHANGED)
@@ -570,6 +536,4 @@ class Background(Component):
570
536
  elevated_water = np.where(mask, background_dem, elevated_water)
571
537
  elevated_save_path = os.path.join(self.water_directory, "elevated_water.obj")
572
538
 
573
- self.plane_from_np(
574
- elevated_water, elevated_save_path, is_preview=False, include_zeros=False
575
- )
539
+ self.plane_from_np(elevated_water, elevated_save_path, include_zeros=False)
@@ -68,6 +68,7 @@ class Component:
68
68
  os.makedirs(self.previews_directory, exist_ok=True)
69
69
  os.makedirs(self.scripts_directory, exist_ok=True)
70
70
  os.makedirs(self.info_layers_directory, exist_ok=True)
71
+ os.makedirs(self.satellite_directory, exist_ok=True)
71
72
 
72
73
  self.save_bbox()
73
74
  self.preprocess()
@@ -123,6 +124,15 @@ class Component:
123
124
  """
124
125
  return os.path.join(self.map_directory, "scripts")
125
126
 
127
+ @property
128
+ def satellite_directory(self) -> str:
129
+ """The directory where the satellite images are stored.
130
+
131
+ Returns:
132
+ str: The directory where the satellite images are stored.
133
+ """
134
+ return os.path.join(self.map_directory, "satellite")
135
+
126
136
  @property
127
137
  def generation_info_path(self) -> str:
128
138
  """The path to the generation info JSON file.