]> marstr Code Repo - marstr/orthographic.git/commitdiff
Code for Zoom Level 16, and Perlin-map based ortho generation. Not entirely complete...
authorMarcus Str. <marcus@marstr.online>
Sun, 26 Jan 2025 20:57:50 +0000 (21:57 +0100)
committerMarcus Str. <marcus@marstr.online>
Sun, 26 Jan 2025 20:57:50 +0000 (21:57 +0100)
colorizer.py [new file with mode: 0644]
defines.py
defines_zl18.py [new file with mode: 0644]
layergen.py
og.py
orthographic.py
perlin.py
photogen.py

diff --git a/colorizer.py b/colorizer.py
new file mode 100644 (file)
index 0000000..2e43393
--- /dev/null
@@ -0,0 +1,61 @@
+
+# -------------------------------------------------------------------
+# ORTHOGRAPHIC
+# Your personal aerial satellite. Always on. At any altitude.*
+# Developed by MarStrMind
+# License: Open Software License 3.0
+# Up to date version always on marstr.online
+# -------------------------------------------------------------------
+# colorizer.py
+# A class providing functions to adjust any image to a specific
+# background color. Similar to GIMP's colorize function.
+# -------------------------------------------------------------------
+
+
+from PIL import Image
+
+class mstr_colorizer:
+    def __init__(self, baseimg):
+        self._baseimg = baseimg
+        self._basepix = self._baseimg.load()
+        self._desaturate()
+
+    def _desaturate(self):
+        grs = Image.new("RGBA", (self._baseimg.width, self._baseimg.height))
+        pix = grs.load()
+        for y in range(0, self._baseimg.height):
+            for x in range(0, self._baseimg.width):
+                cl = self._basepix[x,y]
+                sum = cl[0]+cl[1]+cl[2]
+                gr = int(sum/3)
+                c = (gr,gr,gr,cl[3])
+                pix[x,y] = c
+
+        self._grs = grs
+
+
+    # img is the background, which can be larger than the image to colorize
+    # xpos and ypos is where the image should appear
+    def _colorizeToImage(self, img, xpos, ypos):
+        colorized = Image.new("RGBA", (self._grs.width, self._grs.height))
+        clrpix = colorized.load()
+        imgpix = img.load()
+        grs = self._grs.load()
+
+        for y in range(0, self._grs.height):
+            for x in range(0, self._grs.width):
+                if xpos+x >= 0 and xpos+x < img.width and ypos+y >= 0 and ypos+y < img.height:
+                    bgpx = imgpix[xpos+x, ypos+y]
+                    grpx = grs[x,y]
+                    gr = grpx[0]
+                    av = (gr/255) * 1.2
+
+                    r = bgpx[0] + int(av * bgpx[0])
+                    g = bgpx[1] + int(av * bgpx[1])
+                    b = bgpx[2] + int(av * bgpx[2])
+
+                    colrz = (r,g,b,grpx[3])
+                    clrpix[x,y] = colrz
+
+        return colorized
+                    
index 7e411beadca5d678c6196a9def6207742d779b3a..36aa7ce6ddc2fbbc8e892bf47ba9a6d5ceebcfd7 100644 (file)
@@ -46,7 +46,7 @@ mstr_clear_cache = True
 \r
 # Whether or not you want to see progress of the tool as it walks on.\r
 # High recommendation to leave this on.\r
-mstr_show_log = True\r
+mstr_show_log = False\r
 \r
 \r
 # Should a pseudo shadow be rendered on certain elements?\r
@@ -56,7 +56,7 @@ mstr_show_log = True
 # You can, however, disable the shadow rendering layer here.\r
 mstr_shadow_enabled  = True\r
 mstr_shadow_strength = 0.65\r
-mstr_shadow_shift    = 16\r
+mstr_shadow_shift    = 4\r
 mstr_shadow_floor_h  = 2.8 # 2.5m ceiling height + 30cm concrete per floor\r
 # The tags that cast shadows\r
 mstr_shadow_casters = [\r
@@ -132,9 +132,9 @@ mstr_ortho_layers = [
     ("barrier", "hedge", "natural", "heath"),\r
     ("landuse", "vineyard", "landuse", "meadow"),\r
     ("natural", "bare_rock", "natural", "bare_rock"),\r
-    ("highway", "track", 3),\r
-    ("highway", "path", 3),\r
-    ("highway", "footway", 4),\r
+    ("highway", "track", 1),\r
+    ("highway", "path", 1),\r
+    ("highway", "footway", 1),\r
     ("leisure", "park", "leisure", "green"),\r
     ("leisure", "dog_park", "leisure", "green"),\r
     ("leisure", "garden", "leisure", "green"),\r
@@ -145,20 +145,20 @@ mstr_ortho_layers = [
     ("landuse", "farmyard", "landuse", "farmland"),\r
     ("landuse", "military", "landuse", "residential-boundary"),\r
     # Z-Order 2\r
-    ("highway", "service", 6),\r
-    ("highway", "residential", 12),\r
-    ("highway", "primary", 25),\r
-    ("highway", "secondary", 13),\r
-    ("highway", "tertiary", 20),\r
-    ("highway", "unclassified", 17),\r
-    ("highway", "living_street", 12),\r
-    ("waterway", "stream", 2),\r
+    ("highway", "service", 2),\r
+    ("highway", "residential", 4),\r
+    ("highway", "primary", 6),\r
+    ("highway", "secondary", 3),\r
+    ("highway", "tertiary", 5),\r
+    ("highway", "unclassified", 4),\r
+    ("highway", "living_street", 3),\r
+    ("waterway", "stream", 1),\r
     ("amenity", "parking", "amenity", "parking"),\r
     ("amenity", "school", "amenity", "school"),\r
     ("leisure", "nature_reserve", "landuse", "forest"),\r
     ("landuse", "forest", "landuse", "forest"),\r
     ("natural", "wood", "natural", "wood"),\r
-    ("natural", "tree_row", 22),\r
+    ("natural", "tree_row", 5),\r
     ("natural", "wetland", "natural", "wetland"),\r
     ("natural", "scrub", "natural", "scrub"),\r
     ("natural", "heath", "natural", "heath"),\r
@@ -168,13 +168,13 @@ mstr_ortho_layers = [
     ("natural", "bay", "natural", "beach"),\r
     ("natural", "beach", "natural", "beach"),\r
     ("leisure", "swimming_pool", "natural", "water"),\r
-    ("highway", "pedestrian", 4),\r
+    ("highway", "pedestrian", 1),\r
     # Z-Order 4\r
-    ("highway", "motorway", 32),\r
-    ("railway", "rail", 5),\r
+    ("highway", "motorway", 8),\r
+    ("railway", "rail", 2),\r
     # Z-Order 5\r
-    ("aeroway", "taxiway", 42),\r
-    ("aeroway", "runway", 80),\r
+    ("aeroway", "taxiway", 11),\r
+    ("aeroway", "runway", 20),\r
     ("building", "detached", "building", "common"),\r
     ("building", "church", "building", "common"),\r
     ("building", "hotel", "building", "industrial"),\r
@@ -199,7 +199,7 @@ mstr_ortho_layers = [
     ("water", "pond", "natural", "water"),\r
     ("water", "river", "natural", "water"),\r
     ("natural", "water", "natural", "water"),\r
-    ("waterway", "river", 10),\r
+    ("waterway", "river", 3),\r
     ("place", "sea", "natural", "sea"),\r
     ("place", "ocean", "natural", "sea")\r
 ]\r
@@ -208,51 +208,51 @@ mstr_ortho_layers = [
 # Blur values for the single masks of the ortho layers\r
 mstr_mask_blur = [\r
     # Z-Order 0\r
-    ("landuse", "residential", 20),\r
-    ("boundary", "administrative", 20),\r
+    ("landuse", "residential", 5),\r
+    ("boundary", "administrative", 5),\r
     # Z-Order 1\r
-    ("landuse", "grass", 12),\r
-    ("landuse", "cemetery", 12),\r
-    ("landuse", "greenfield", 12),\r
-    ("landuse", "orchard", 12),\r
-    ("landuse", "meadow", 12),\r
-    ("landuse", "construction", 5),\r
+    ("landuse", "grass", 3),\r
+    ("landuse", "cemetery", 3),\r
+    ("landuse", "greenfield", 3),\r
+    ("landuse", "orchard", 3),\r
+    ("landuse", "meadow", 3),\r
+    ("landuse", "construction", 1),\r
     ("barrier", "hedge", 1),\r
-    ("landuse", "recreation_ground", 20),\r
-    ("landuse", "vineyard", 12),\r
-    ("natural", "grassland", 12),\r
-    ("natural", "wetland", 30),\r
-    ("natural", "scrub", 15),\r
-    ("natural", "heath", 15),\r
-    ("leisure", "park", 15),\r
-    ("leisure", "golf_course", 25),\r
-    ("leisure", "dog_park", 15),\r
-    ("leisure", "garden", 20),\r
-    ("leisure", "sports_centre", 5),\r
-    ("leisure", "pitch", 2),\r
+    ("landuse", "recreation_ground", 5),\r
+    ("landuse", "vineyard", 3),\r
+    ("natural", "grassland", 3),\r
+    ("natural", "wetland", 7),\r
+    ("natural", "scrub", 4),\r
+    ("natural", "heath", 4),\r
+    ("leisure", "park", 4),\r
+    ("leisure", "golf_course", 6),\r
+    ("leisure", "dog_park", 4),\r
+    ("leisure", "garden", 5),\r
+    ("leisure", "sports_centre", 2),\r
+    ("leisure", "pitch", 1),\r
     ("leisure", "playground", 2),\r
-    ("landuse", "farmland", 10),\r
-    ("landuse", "farmyard", 10),\r
+    ("landuse", "farmland", 3),\r
+    ("landuse", "farmyard", 3),\r
     # Z-Order 2\r
-    ("landuse", "forest", 12),\r
-    ("leisure", "nature_reserve", 12),\r
-    ("natural", "wood", 12),\r
-    ("natural", "tree_row", 12),\r
-    ("landuse", "military", 15),\r
+    ("landuse", "forest", 3),\r
+    ("leisure", "nature_reserve", 3),\r
+    ("natural", "wood", 3),\r
+    ("natural", "tree_row", 3),\r
+    ("landuse", "military", 4),\r
     # Z-Order 3\r
-    ("natural", "bare_rock", 25),\r
-    ("natural", "water", 4),\r
-    ("natural", "bay", 30),\r
-    ("natural", "beach", 30),\r
-    ("water", "lake", 10),\r
-    ("water", "pond", 10),\r
-    ("water", "river", 10),\r
-    ("leisure", "swimming_pool", 10),\r
-    ("waterway", "river", 10),\r
-    ("waterway", "stream", 4),\r
+    ("natural", "bare_rock", 6),\r
+    ("natural", "water", 1),\r
+    ("natural", "bay", 7),\r
+    ("natural", "beach", 7),\r
+    ("water", "lake", 3),\r
+    ("water", "pond", 3),\r
+    ("water", "river", 3),\r
+    ("leisure", "swimming_pool", 3),\r
+    ("waterway", "river", 3),\r
+    ("waterway", "stream", 2),\r
     ("amenity", "parking", 1),\r
     ("amenity", "school", 1),\r
-    ("highway", "pedestrian", 12),\r
+    ("highway", "pedestrian", 3),\r
     # Z-Order 4\r
     ("highway", "motorway", 0.5),\r
     ("highway", "primary", 0.5),\r
@@ -262,10 +262,10 @@ mstr_mask_blur = [
     ("highway", "living_street", 0.5),\r
     ("highway", "residential", 0.5),\r
     ("highway", "service", 0.5),\r
-    ("highway", "footway", 2),\r
-    ("highway", "track", 2),\r
-    ("highway", "path", 2),\r
-    ("railway", "rail", 2),\r
+    ("highway", "footway", 1),\r
+    ("highway", "track", 1),\r
+    ("highway", "path", 1),\r
+    ("railway", "rail", 1),\r
     # Z-Order 5\r
     ("aeroway", "taxiway", 2),\r
     ("aeroway", "runway", 2),\r
diff --git a/defines_zl18.py b/defines_zl18.py
new file mode 100644 (file)
index 0000000..31e6f07
--- /dev/null
@@ -0,0 +1,446 @@
+
+# -------------------------------------------------------------------
+# ORTHOGRAPHIC
+# Your personal aerial satellite. Always on. At any altitude.*
+# Developed by MarStrMind
+# License: Open Software License 3.0
+# Up to date version always on marstr.online
+# -------------------------------------------------------------------
+# defines.py
+# Variables we need in all functions. Each one is documented below.
+# -------------------------------------------------------------------
+
+# Your data folder - meaning where the cache is stored, and where the finished
+# tiles will go. This is also the folder where the image generation sources are
+# stored.
+#mstr_datafolder = "M:/Developer/Projects/orthographic/"
+mstr_datafolder = "D:/Developer/Projects/orthographic/"
+#mstr_datafolder = "/home/marcus/Developer/Projects/orthographic/"
+# Switched to Linux, so path is amended
+
+
+# API endpoint to acquire OSM data (bonus: I have my own)
+#mstr_osm_endpoint = "https://marstr.online/osm/v1/"
+mstr_osm_endpoint = "http://localhost/og.php"
+
+# Define the texture resolution you want to have your photos at.
+mstr_photores = 2048
+
+# Radius of zoom level 18 aerials around airports with ICAO code
+# Value is in tiles - not in km
+#
+# Value = 5:
+# #####
+# #####
+# ##X##
+# #####
+# #####
+#
+# The "X" is the tile with the airport
+mstr_airport_radius = 5
+
+# Clear cache after generating a complete tile?
+mstr_clear_cache = True
+# Removes the masks etc after a tile has been generated. Strong recommendation to set this
+# to True.
+
+# Whether or not you want to see progress of the tool as it walks on.
+# High recommendation to leave this on.
+mstr_show_log = False
+
+
+# Should a pseudo shadow be rendered on certain elements?
+# The sun is usually somewhere when a photo is taken during the day. Therefore,
+# some kind of shadow is cast in a direction, but this depends on a lot of factors.
+# We will simply things to achieve good-looking results.
+# You can, however, disable the shadow rendering layer here.
+mstr_shadow_enabled  = True
+mstr_shadow_strength = 0.65
+mstr_shadow_shift    = 16
+mstr_shadow_floor_h  = 2.8 # 2.5m ceiling height + 30cm concrete per floor
+# The tags that cast shadows
+mstr_shadow_casters = [
+    ("landuse", "forest"),
+    ("leisure", "nature_reserve"),
+    ("natural", "wood")
+]
+
+
+# Whether or not to generate X-Plane Scenery files
+mstr_xp_genscenery = True
+
+# Generate normal maps for X-Plane scenery?
+# Strong recommendation: yes
+mstr_xp_scn_normalmaps = True
+
+# Paths to required X-Plane scenery tools
+mstr_xp_meshtool = "/home/marcus/Developer/Projects/orthographic/bin/MeshTool"
+mstr_xp_ddstool = "/home/marcus/Developer/Projects/orthographic/bin/DDSTool"
+mstr_xp_dsftool = "/home/marcus/Developer/Projects/orthographic/bin/DSFTool"
+mstr_xp_xessrc = "https://dev.x-plane.com/update/misc/MeshTool/"
+mstr_xp_floor_height = 2.8 # 2.5m ceiling height + 30cm concrete per floor
+mstr_xp_ortho_location = "/home/marcus/Data/Sim/Simulator/orthographic/"
+
+# If you set the above to true, you can define for which features you
+# want to generate normal maps for. The below is my recommendation for
+# good-looking orthos in the simulator.
+mstr_xp_normal_maps = [
+    ("landuse", "farmland"),
+    ("landuse", "meadow"),
+    ("landuse", "orchard"),
+    ("landuse", "forest"),
+    ("natural", "wetland"),
+    ("natural", "bare_rock"),
+    ("natural", "scrub"),
+    ("natural", "heath"),
+    ("natural", "sand"),
+    ("natural", "desert"),
+    ("leisure", "nature_reserve"),
+    ("building", "*")
+]
+
+# How much of a tile we need for each zoom level. The higher
+# the zoom level, the smaller the area to generate a mask of - but also
+# higher detail.
+mstr_zl_16 = 0.064
+mstr_zl_17 = 0.048
+mstr_zl_18 = 0.016
+mstr_zl_19 = 0.008
+
+
+# The layers we will process, from bottom to top.
+# Tag, and value.
+# Strong recommendation NOT to alter this list -
+# generating the orthos depends on the pool of source
+# material I provide for these layers. If you add your own
+# OSM tag, and there is no source material, the script will
+# most likely crash.
+mstr_ortho_layers = [
+    # Z-Order 0
+    #("boundary", "administrative", "admin_level", ["8", "9", "10", "12"], "landuse", "residential-boundary"),
+    # Z-Order 1
+    ("landuse", "residential", "landuse", "residential-boundary"),
+    ("landuse", "grass", "landuse", "grass"),
+    ("landuse", "cemetery", "landuse", "grass"),
+    ("landuse", "recreation_ground", "landuse", "meadow"),
+    ("leisure", "golf_course", "leisure", "golf_course"),
+    ("landuse", "greenfield", "landuse", "grass"),
+    ("landuse", "orchard", "landuse", "meadow"),
+    ("landuse", "meadow", "landuse", "meadow"),
+    ("landuse", "construction", "landuse", "construction"),
+    ("natural", "grassland", "landuse", "meadow"),
+    ("barrier", "hedge", "natural", "heath"),
+    ("landuse", "vineyard", "landuse", "meadow"),
+    ("natural", "bare_rock", "natural", "bare_rock"),
+    ("highway", "track", 3),
+    ("highway", "path", 3),
+    ("highway", "footway", 4),
+    ("leisure", "park", "leisure", "green"),
+    ("leisure", "dog_park", "leisure", "green"),
+    ("leisure", "garden", "leisure", "green"),
+    ("leisure", "sports_centre", "leisure", "green"),
+    ("leisure", "pitch", "leisure", "green"),
+    ("leisure", "playground", "leisure", "green"),
+    ("landuse", "farmland", "landuse", "farmland"),
+    ("landuse", "farmyard", "landuse", "farmland"),
+    ("landuse", "military", "landuse", "residential-boundary"),
+    # Z-Order 2
+    ("highway", "service", 6),
+    ("highway", "residential", 12),
+    ("highway", "primary", 25),
+    ("highway", "secondary", 13),
+    ("highway", "tertiary", 20),
+    ("highway", "unclassified", 17),
+    ("highway", "living_street", 12),
+    ("waterway", "stream", 2),
+    ("amenity", "parking", "amenity", "parking"),
+    ("amenity", "school", "amenity", "school"),
+    ("leisure", "nature_reserve", "landuse", "forest"),
+    ("landuse", "forest", "landuse", "forest"),
+    ("natural", "wood", "natural", "wood"),
+    ("natural", "tree_row", 22),
+    ("natural", "wetland", "natural", "wetland"),
+    ("natural", "scrub", "natural", "scrub"),
+    ("natural", "heath", "natural", "heath"),
+    ("natural", "sand", "natural", "sand"),
+    ("natural", "desert", "natural", "desert"),
+    # Z-Order 3
+    ("natural", "bay", "natural", "beach"),
+    ("natural", "beach", "natural", "beach"),
+    ("leisure", "swimming_pool", "natural", "water"),
+    ("highway", "pedestrian", 4),
+    # Z-Order 4
+    ("highway", "motorway", 32),
+    ("railway", "rail", 5),
+    # Z-Order 5
+    ("aeroway", "taxiway", 42),
+    ("aeroway", "runway", 80),
+    ("building", "detached", "building", "common"),
+    ("building", "church", "building", "common"),
+    ("building", "hotel", "building", "industrial"),
+    ("building", "farm", "building", "industrial"),
+    ("building", "semidetached_house", "building", "common"),
+    ("building", "apartments", "building", "common"),
+    ("building", "civic", "building", "common"),
+    ("building", "garage", "building", "industrial"),
+    ("building", "office", "building", "office"),
+    ("building", "retail", "building", "industrial"),
+    ("building", "industrial", "building", "industrial"),
+    ("building", "house", "building", "house"),
+    ("building", "terrace", "building", "industrial"),
+    ("building", "hangar", "building", "industrial"),
+    ("building", "school", "building", "common"),
+    ("building", "kindergarten", "building", "kindergarten"),
+    ("building", "public", "building", "public"),
+    ("building", "commercial", "building", "commercial"),
+    ("building", "warehouse", "building", "warehouse"),
+    ("building", "yes", "building", "common"),
+    ("water", "lake", "natural", "water"),
+    ("water", "pond", "natural", "water"),
+    ("water", "river", "natural", "water"),
+    ("natural", "water", "natural", "water"),
+    ("waterway", "river", 10),
+    ("place", "sea", "natural", "sea"),
+    ("place", "ocean", "natural", "sea")
+]
+
+
+# Blur values for the single masks of the ortho layers
+mstr_mask_blur = [
+    # Z-Order 0
+    ("landuse", "residential", 20),
+    ("boundary", "administrative", 20),
+    # Z-Order 1
+    ("landuse", "grass", 12),
+    ("landuse", "cemetery", 12),
+    ("landuse", "greenfield", 12),
+    ("landuse", "orchard", 12),
+    ("landuse", "meadow", 12),
+    ("landuse", "construction", 5),
+    ("barrier", "hedge", 1),
+    ("landuse", "recreation_ground", 20),
+    ("landuse", "vineyard", 12),
+    ("natural", "grassland", 12),
+    ("natural", "wetland", 30),
+    ("natural", "scrub", 15),
+    ("natural", "heath", 15),
+    ("leisure", "park", 15),
+    ("leisure", "golf_course", 25),
+    ("leisure", "dog_park", 15),
+    ("leisure", "garden", 20),
+    ("leisure", "sports_centre", 5),
+    ("leisure", "pitch", 2),
+    ("leisure", "playground", 2),
+    ("landuse", "farmland", 10),
+    ("landuse", "farmyard", 10),
+    # Z-Order 2
+    ("landuse", "forest", 12),
+    ("leisure", "nature_reserve", 12),
+    ("natural", "wood", 12),
+    ("natural", "tree_row", 12),
+    ("landuse", "military", 15),
+    # Z-Order 3
+    ("natural", "bare_rock", 25),
+    ("natural", "water", 4),
+    ("natural", "bay", 30),
+    ("natural", "beach", 30),
+    ("water", "lake", 10),
+    ("water", "pond", 10),
+    ("water", "river", 10),
+    ("leisure", "swimming_pool", 10),
+    ("waterway", "river", 10),
+    ("waterway", "stream", 4),
+    ("amenity", "parking", 1),
+    ("amenity", "school", 1),
+    ("highway", "pedestrian", 12),
+    # Z-Order 4
+    ("highway", "motorway", 0.5),
+    ("highway", "primary", 0.5),
+    ("highway", "secondary", 0.5),
+    ("highway", "tertiary", 0.5),
+    ("highway", "unclassified", 0.5),
+    ("highway", "living_street", 0.5),
+    ("highway", "residential", 0.5),
+    ("highway", "service", 0.5),
+    ("highway", "footway", 2),
+    ("highway", "track", 2),
+    ("highway", "path", 2),
+    ("railway", "rail", 2),
+    # Z-Order 5
+    ("aeroway", "taxiway", 2),
+    ("aeroway", "runway", 2),
+    ("building", "detached", 1),
+    ("building", "church", 1),
+    ("building", "hotel", 1),
+    ("building", "farm", 1),
+    ("building", "semidetached_house", 1),
+    ("building", "apartments", 1),
+    ("building", "civic", 1),
+    ("building", "garage", 1),
+    ("building", "office", 1),
+    ("building", "retail", 1),
+    ("building", "industrial", 1),
+    ("building", "house", 1),
+    ("building", "terrace", 1),
+    ("building", "hangar", 1),
+    ("building", "school", 1),
+    ("building", "kindergarten", 1),
+    ("building", "public", 1),
+    ("building", "commercial", 1),
+    ("building", "warehouse", 1),
+    ("building", "yes", 0),
+    ("place", "sea", 1),
+    ("place", "ocean", 1)
+]
+
+
+# Base colors for different building types
+mstr_building_base_colors = [
+    ("detached", [
+        "#693333", "#592b2b", "#513434", "#4a1e1e", "#362626",
+        "#534136", "#4d3424", "#534b45", "#553724", "#574c45",
+        "#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
+        "#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
+        ]
+    ),
+    ("church", [
+        "#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
+        "#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
+        ]
+    ),
+    ("hotel", [
+        "#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
+        "#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
+        ]
+    ),
+    ("farm", [
+        "#693333", "#592b2b", "#513434", "#4a1e1e", "#362626",
+        "#534136", "#4d3424", "#534b45", "#553724", "#574c45"
+        ]
+    ),
+    ("semidetached_house", [
+        "#693333", "#592b2b", "#513434", "#4a1e1e", "#362626",
+        "#534136", "#4d3424", "#534b45", "#553724", "#574c45",
+        "#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
+        "#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
+        ]
+    ),
+    ("apartments", [
+        "#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
+        "#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
+        ]
+    ),
+    ("civic", [
+        "#7b848b", "#5d6d7b", "#5e646a", "#454d53", "#585b5e",
+        "#877a78", "#797372", "#797372", "#6f5550", "#7c7574"
+        ]
+    ),
+    ("garage", [
+        "#693333", "#592b2b", "#513434", "#4a1e1e", "#362626",
+        "#523731", "#46484e", "#33353a", "#3a3733", "#5d5a57"
+        ]
+    ),
+    ("office", [
+        "#403a33", "#4f4b46", "#413629", "#574c3f", "#3a2e21",
+        "#aaaeb6", "#939cac", "#8a919d", "#a0b9bf", "#8d999b",
+        "#49575a", "#273d43", "#313a3c", "#484f50", "#212d30"
+        ]
+    ),
+    ("retail", [
+        "#403a33", "#4f4b46", "#413629", "#574c3f", "#3a2e21",
+        "#aaaeb6", "#939cac", "#8a919d", "#a0b9bf", "#8d999b",
+        "#49575a", "#273d43", "#313a3c", "#484f50", "#212d30"
+        ]
+    ),
+    ("industrial", [
+        "#939fa2", "#728080", "#9eafaf", "#4f6061", "#96b2b6",
+        "#b2b398", "#878868", "#989888", "#bdb79c", "#959386"
+        ]
+    ),
+    ("house", [
+        "#693333", "#592b2b", "#513434", "#4a1e1e", "#362626",
+        "#534136", "#4d3424", "#534b45", "#553724", "#574c45",
+        "#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
+        "#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
+        ]
+    ),
+    ("terrace", [
+        "#86898c", "#5e656c", "#6d6868", "#6d6c68", "#46443d",
+        "#3d4546", "#6b7071", "#716b70", "#738684", "#868073"
+        ]
+    ),
+    ("hangar", [
+        "#403a33", "#4f4b46", "#413629", "#574c3f", "#3a2e21",
+        "#aaaeb6", "#939cac", "#8a919d", "#a0b9bf", "#8d999b",
+        "#49575a", "#273d43", "#313a3c", "#484f50", "#212d30"
+        ]
+    ),
+    ("school", [
+        "#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
+        "#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
+        ]
+    ),
+    ("kindergarten", [
+        "#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
+        "#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
+        ]
+    ),
+    ("public", [
+        "#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
+        "#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
+        ]
+    ),
+    ("commercial", [
+        "#403a33", "#4f4b46", "#413629", "#574c3f", "#3a2e21",
+        "#aaaeb6", "#939cac", "#8a919d", "#a0b9bf", "#8d999b",
+        "#49575a", "#273d43", "#313a3c", "#484f50", "#212d30"
+        ]
+    ),
+    ("yes", [
+        "#373942", "#40424a", "#363b4f", "#2c2d32", "#444651",
+        "#454545", "#39393b", "#4b4b4c", "#363638", "#525252"
+        ]
+    ),
+    ("warehouse", [
+        "#403a33", "#4f4b46", "#413629", "#574c3f", "#3a2e21",
+        "#aaaeb6", "#939cac", "#8a919d", "#a0b9bf", "#8d999b",
+        "#49575a", "#273d43", "#313a3c", "#484f50", "#212d30"
+        ]
+    ),
+]
+
+
+# Base colors to add some details to all kinds of buildings
+mstr_building_detail_colors = [
+    (136, 132, 86),  # Some kind of moss
+    (136, 90, 86),   # Some kind of rust or darkening
+    (154, 154, 154), # Other random details
+    (97, 97, 97)     # Square or line details, alpha-blended
+]
+
+
+mstr_completion_colors = [
+    ("+50+000", [
+        (48,63,34),
+        (81,95,64),
+        (105,100,64),
+        (91,105,72),
+        (78,69,41),
+        (116,113,78),
+        (90,94,69),
+        (58,68,40),
+        (57,72,41),
+        (93,103,76),
+        (139,142,111),
+        (92,102,73),
+        (71,86,55),
+        (103,105,91),
+        (96,78,56),
+        (143,141,113),
+        (107,108,74),
+        (41,56,34),
+        (51,63,41),
+        (137,137,107)
+        ]
+    )
+]
index ee4faba71fc0b67735178e990b89adaebf336bf2..60c6d33630c90e0898ff725413b6ba440df515be 100644 (file)
@@ -26,6 +26,7 @@ from tileinfo import *
 from osmxml import *\r
 from functions import *\r
 from resourcegen import *\r
+from colorizer import *\r
 \r
 ImageFile.LOAD_TRUNCATED_IMAGES = True\r
 \r
@@ -57,6 +58,10 @@ class mstr_layergen:
         self._maxlng = maxlatlng[1]\r
         mstr_msg("layergen", "Maximum latitude and longitude tile numbers received")\r
 \r
+    # Set zoom level\r
+    def set_zoomlevel(self, zl):\r
+        self._zoomlevel = zl\r
+\r
     # Set latlng folder\r
     def set_latlng_folder(self, latlngfld):\r
         self._latlngfld = latlngfld\r
@@ -248,6 +253,9 @@ class mstr_layergen:
                 nc = (tp[0] - diff, tp[1] - diff, tp[2] - diff, tp[3])\r
                 treepx[x, y] = nc\r
 \r
+        if self._zoomlevel == 16:\r
+            tree = tree.resize((int(tree.width/4), int(tree.height/4)), resample=Image.Resampling.BILINEAR)\r
+\r
         return tree\r
 \r
 \r
@@ -278,6 +286,11 @@ class mstr_layergen:
         # We need to differentiate that.\r
 \r
         if (self._isline == False and self._tag != "building") or (self._is_completion == True):\r
+\r
+            # The Perlin map\r
+            perlin_map = Image.open(mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/perlin/" + self._tag + "_" + self._value + ".png")\r
+            perlin_pix = perlin_map.load()\r
+\r
             # Determine where we get the source material from\r
             root_folder = mstr_datafolder + "textures/"\r
             for s in mstr_ortho_layers:\r
@@ -286,45 +299,6 @@ class mstr_layergen:
                     fld_sub  = len(s)-1\r
                     root_folder = root_folder + s[fld_main] + "/" + s[fld_sub]\r
 \r
-            # Determine which sources to use.\r
-            src = self.findLayerSource()\r
-            srcstr = ""\r
-            for s in range(len(src)):\r
-                srcstr = srcstr + str(src[s])\r
-                if s < len(src)-1:\r
-                    srcstr = srcstr + ","\r
-            \r
-            # Failsafe\r
-            if srcstr == "0":\r
-                srcstr = ""\r
-                numbers = list(range(1, 16))\r
-                src = random.sample(numbers, 5)\r
-                for s in range(len(src)):\r
-                    srcstr = srcstr + str(src[s])\r
-                    if s < len(src)-1:\r
-                        srcstr = srcstr + ","\r
-\r
-            # Patch and border sources. There can only be one for each.\r
-            brd_src = None\r
-            ptc_src = []\r
-\r
-            # Find this layer's predetermined contrast\r
-            lyr_contrast = self.findLayerContrast(srcstr)\r
-            if lyr_contrast != 0:\r
-                mstr_msg("layergen", "Applying contrast value: " + str(lyr_contrast))\r
-\r
-            # Should this not exist yet, we need to create it\r
-            #if os.path.isfile(gensrc_ptc) == False:\r
-            rg = mstr_resourcegen(self._tag, self._value, src)\r
-            rg.setLayerContrast(int(lyr_contrast))\r
-            lyr_res = rg.gensource()\r
-\r
-            # Open the images\r
-            ptc_src.append(lyr_res[0]) # Used to be an array, so let's keep it\r
-            brd_src = lyr_res[1]\r
-\r
-            mstr_msg("layergen", "Layer sources selected")\r
-            \r
             # Generate an edge mask from the original\r
             osm_edge = mask.filter(ImageFilter.FIND_EDGES)\r
             osm_edge = osm_edge.filter(ImageFilter.MaxFilter)\r
@@ -336,12 +310,17 @@ class mstr_layergen:
                 imgd = ImageDraw.Draw(mask)\r
 \r
                 # Walk through a grid of 100x100 - on the edge image\r
-                for y in range(0, mask.height, int(mask.height/100)):\r
-                    for x in range(0, mask.width, int(mask.width/100)):\r
+                fordiv = 100\r
+                if self._zoomlevel == 16: fordiv = 25\r
+                for y in range(0, mask.height, int(mask.height/fordiv)):\r
+                    for x in range(0, mask.width, int(mask.width/fordiv)):\r
                         px = epx[x,y]\r
                         if px[3] == 255:\r
                             rx = randrange(24,60)\r
                             ry = randrange(24,60)\r
+                            if self._zoomlevel == 16:\r
+                                rx = randrange(6, 15)\r
+                                ry = randrange(6, 15)\r
                             f = randrange(1,10)\r
 \r
                             # Randomize the found locations a little\r
@@ -368,22 +347,58 @@ class mstr_layergen:
                         mask = mask.filter(ImageFilter.BoxBlur(radius=i[2]))\r
                         break\r
             \r
+            # Find starting point in the Perlin map\r
+            prln_step = 0\r
+            if self._zoomlevel == 16: prln_step = 80\r
+            if self._zoomlevel == 18: prln_step = 20\r
+            prln_x = (self._lng_number-1) * prln_step\r
+            prln_y = perlin_map.height - (self._lat_number * prln_step) - 1\r
+\r
+            # First, fill the image with the base colors from the Perlin map,\r
+            # plus some variation\r
+            prln_pix_step = int(layer.width / prln_step)\r
+            for y in range(0, layer.height):\r
+                for x in range(0, layer.width):\r
+                    xp = prln_x + int(x/prln_pix_step)\r
+                    yp = prln_y + int(y/prln_pix_step)\r
+                    if xp == perlin_map.width:  xp = perlin_map.width - 1\r
+                    if yp == perlin_map.height: yp = perlin_map.height - 1\r
+                    pc = perlin_pix[xp,yp]\r
+                    df = randrange(0, 6)\r
+                    lc = (pc[0]+df, pc[1]+df, pc[2]+df, 255)\r
+                    #lc = (pc[0], pc[1], pc[2], 255)\r
+                    layer_pix[x,y] = lc\r
+            clrz_layer = layer.copy()\r
+\r
+            # ------------------------------------------\r
             # Begin producing a largely random image\r
-            samples = 250   # <- We need this in a moment\r
+            samples = 0\r
+            if self._zoomlevel == 18: samples = 250\r
+            if self._zoomlevel == 16: samples = 2000\r
+\r
+            txts = glob.glob(mstr_datafolder + "textures/" + self._tag + "/" + self._value + "/*.png")\r
+            ptc_src = Image.open(txts[randrange(0, len(txts))])\r
+            if self._zoomlevel == 16: ptc_src = ptc_src.resize((250,250), resample=Image.Resampling.BILINEAR)\r
+            clrz = mstr_colorizer(ptc_src)\r
+\r
+            tmp_layer = Image.new("RGBA", (self._imgsize, self._imgsize))\r
+\r
             for i in range(samples):\r
-                imgid = 0\r
-                if len(ptc_src) == 1: imgid = 0\r
-                if len(ptc_src) >= 2:\r
-                    imgid = randrange(1, len(ptc_src)+1) - 1\r
-                l = 0 - int(ptc_src[imgid].width / 2)\r
-                r = layer.width - int(ptc_src[imgid].width / 2)\r
-                t = 0 - int(ptc_src[imgid].height / 2)\r
-                b = layer.height - int(ptc_src[imgid].height / 2)\r
-                layer.alpha_composite( ptc_src[imgid], ( randrange(l, r), randrange(t, b) ) )\r
+                xp = randrange(-125, 1924)\r
+                yp = randrange(-125, 1924)\r
+                ptc = clrz._grs.rotate(randrange(0, 360), expand=True)\r
+                tmp_layer.alpha_composite(ptc, (xp,yp))\r
+\r
+            # Add the seamless border\r
+            brd = Image.open(mstr_datafolder + "textures/" + self._tag + "/" + self._value + "/brd.png")\r
+            brd_clrz = mstr_colorizer(brd)\r
+            tmp_layer.alpha_composite(brd_clrz._grs)\r
+\r
+            tmp_layer.putalpha(51)\r
+            layer.alpha_composite(tmp_layer)\r
             mstr_msg("layergen", "Layer image generated")\r
-\r
-            # We now need to add the seamless border\r
-            layer.alpha_composite( brd_src )\r
+            \r
+            #---------------------------------------------\r
 \r
             # Here we need to do some magic to make some features look more natural\r
             if (self._tag == "landuse" and self._value == "meadow") or (\r
@@ -391,7 +406,7 @@ class mstr_layergen:
                     self._tag == "natural" and self._value == "heath") or (\r
                     self._tag == "landuse" and self._value == "cemetery") or (\r
                     self._tag == "landuse" and self._value == "residential"):\r
-                amt = randrange(5, 21)\r
+                amt = randrange(150, 301)\r
                 masks = glob.glob(mstr_datafolder + "textures/tile/completion/*.png")\r
                 patchtags = [\r
                     ["landuse", "meadow"],\r
@@ -400,52 +415,14 @@ class mstr_layergen:
                     ["natural", "scrub"]\r
                 ]\r
                 for i in range(1, amt + 1):\r
-                    pick = randrange(0, len(masks))\r
-                    patchmask = Image.open(masks[pick])\r
-                    patchmask = patchmask.rotate(randrange(0, 360), expand=True)\r
-\r
-                    # Make sure patch is within bounds\r
-                    if patchmask.width > self._imgsize or patchmask.height > self._imgsize:\r
-                        patchmask = patchmask.resize((mstr_photores, mstr_photores), Image.Resampling.BILINEAR)\r
-\r
-                    patchpix = patchmask.load()\r
-                    # Pick from possible tags and values for the patches\r
-                    numbers = list(range(1, 16))\r
-                    src = random.sample(numbers, 5)\r
-\r
-                    patchpick = randrange(0, len(patchtags))\r
-                    ctr = randrange(1, 4)\r
-                    rg = mstr_resourcegen(patchtags[patchpick][0], patchtags[patchpick][1], src)\r
-                    rg.setLayerContrast(ctr)\r
-                    ptch = rg.gensource()\r
-\r
-                    # Generate a full size of the source\r
-                    ptc_full = Image.new("RGBA", (mstr_photores, mstr_photores))\r
-\r
-                    # Generate the source image\r
-                    for p in range(1, 201):\r
-                        rx = randrange(0 - int(ptch[0].width / 2), ptc_full.width - int(ptch[0].width / 2))\r
-                        ry = randrange(0 - int(ptch[0].height / 2), ptc_full.height - int(ptch[0].height / 2))\r
-                        ptc_full.alpha_composite(ptch[0], dest=(rx, ry))\r
-\r
-                    rg_img = ptc_full\r
-                    rg_pix = rg_img.load()\r
-\r
-                    # The patch to be used in the layer\r
-                    layerpatch = Image.new("RGBA", (patchmask.width, patchmask.height))\r
-                    lp_pix = layerpatch.load()\r
-                    for y in range(0, patchmask.height):\r
-                        for x in range(0, patchmask.width):\r
-                            ptc_msk = patchpix[x,y]\r
-                            if ptc_msk[3] > 0:\r
-                                oc = rg_pix[x,y]\r
-                                nc = ( oc[0], oc[1], oc[2], ptc_msk[3] )\r
-                                lp_pix[x,y] = nc\r
-\r
-                    #layerpatch = layerpatch.rotate(randrange(0, 360), expand=True)\r
-\r
-                    lx = randrange(self._imgsize - layerpatch.width)\r
-                    ly = randrange(self._imgsize - layerpatch.height)\r
+                    layerpatch = Image.open(mstr_datafolder + "textures/tile/completion_color/p" + str(randrange(1,14)) + ".png")\r
+                    if self._zoomlevel == 16:\r
+                        lpw = int(layerpatch.width/4)\r
+                        lph = int(layerpatch.height/4)\r
+                        layerpatch = layerpatch.resize((lpw,lph), resample=Image.Resampling.BILINEAR)\r
+                    layerpatch = layerpatch.rotate(randrange(0, 360), expand=True)\r
+                    lx = randrange(0, mstr_photores-layerpatch.width)\r
+                    ly = randrange(0, mstr_photores-layerpatch.height)\r
                     layer.alpha_composite(layerpatch, (lx, ly))\r
 \r
 \r
@@ -481,7 +458,6 @@ class mstr_layergen:
             # Layer complete\r
             mstr_msg("layergen", "Layer image completed.")\r
 \r
-\r
             # Let's try our hand at pseudo shadows\r
             if mstr_shadow_enabled == True:\r
                 if mstr_shadow_shift >= 2:\r
@@ -713,7 +689,10 @@ class mstr_layergen:
             ptc_src = []\r
 \r
             for p in range(0, len(res)):\r
-                ptc_src.append(Image.open(mstr_datafolder + "textures/" + self._tag + "/" + self._value + "/" + str(res[p]) + ".png"))\r
+                ptc_img = Image.open(mstr_datafolder + "textures/" + self._tag + "/" + self._value + "/" + str(res[p]) + ".png")\r
+                if self._zoomlevel == 16:\r
+                    ptc_img = ptc_img.resize((250,250), resample=Image.Resampling.BILINEAR)\r
+                ptc_src.append(ptc_img)\r
 \r
             # Set some contrast\r
             lyr_contrast = 0.85\r
@@ -724,7 +703,9 @@ class mstr_layergen:
             #brd_src = bldg_src[1]\r
 \r
             # Begin producing a largely random image\r
-            samples = 250  # <- We need this in a moment\r
+            samples = 0\r
+            if self._zoomlevel == 18: samples = 250\r
+            if self._zoomlevel == 16: samples = 2000  # <- We need this in a moment\r
             for i in range(samples):\r
                 imgid = 0\r
                 if len(ptc_src) == 1: imgid = 0\r
@@ -770,7 +751,9 @@ class mstr_layergen:
                     shadow = Image.open(fn)\r
 \r
             # Add some random trees\r
-            for t in range(0, 5000):\r
+            treeamt = 5000\r
+            if self._zoomlevel == 18: treeamt = 35000\r
+            for t in range(0, treeamt+1):\r
                 loc_x = randrange(0, self._imgsize)\r
                 loc_y = randrange(0, self._imgsize)\r
                 shf_val = 21\r
@@ -868,4 +851,4 @@ class mstr_layergen:
         if abs(numbers[1]) >= 10 and numbers[0] <= 99: fstr = fstr + "0" + str(numbers[1])\r
         if abs(numbers[1]) >= 100 : fstr = fstr + str(numbers[1])\r
 \r
-        return fstr\r
+        return fstr()\r
diff --git a/og.py b/og.py
index 53a5186d47aa82615ee802dda0c6d5fb8a5fad9a..ce483ba8183071070b8b5b4c42e49de933c6d336 100644 (file)
--- a/og.py
+++ b/og.py
@@ -46,36 +46,38 @@ cli = False
 pbf = False\r
 prep = False\r
 \r
-if len(sys.argv) == 4:\r
-    cli = True\r
+if __name__ == '__main__':\r
 \r
-# Only if we find enough arguments, proceed.\r
-if cli:\r
-    lat = int(sys.argv[1])\r
-    lng = int(sys.argv[2])\r
+    if len(sys.argv) == 4:\r
+        cli = True\r
 \r
-    mstr_msg("_main", "Beginning tile generation process.")\r
+    # Only if we find enough arguments, proceed.\r
+    if cli:\r
+        lat = int(sys.argv[1])\r
+        lng = int(sys.argv[2])\r
 \r
-    # Create the class and init values\r
-    og = mstr_orthographic(lat, lng, mstr_datafolder, os.getcwd(), prep)\r
+        mstr_msg("_main", "Beginning tile generation process.")\r
 \r
-    # Prepare a tile\r
-    if sys.argv[3] == "prepare":\r
-        og._prepareTile()\r
+        # Create the class and init values\r
+        og = mstr_orthographic(lat, lng, mstr_datafolder, os.getcwd(), prep)\r
 \r
-    # Generate orthos\r
-    if sys.argv[3] != "prepare" and sys.argv[3] != "xpscenery":\r
-        og._generateOrthos_mt(int(sys.argv[3]))\r
+        # Prepare a tile\r
+        if sys.argv[3] == "prepare":\r
+            og._prepareTile()\r
 \r
-    # Build the terrain mesh and assign ground textures\r
-    if sys.argv[3] == "xpscenery":\r
-        og.generate_xp_scenery()\r
+        # Generate orthos\r
+        if sys.argv[3] != "prepare" and sys.argv[3] != "xpscenery":\r
+            og._generateOrthos_mt(int(sys.argv[3]))\r
 \r
+        # Build the terrain mesh and assign ground textures\r
+        if sys.argv[3] == "xpscenery":\r
+            og.generate_xp_scenery()\r
 \r
 \r
-if cli == False and pbf == False:\r
-    mstr_msg("_main", "Please provide Latitude and Longitude. Exiting.")\r
-    print ("")\r
+\r
+    if cli == False and pbf == False:\r
+        mstr_msg("_main", "Please provide Latitude and Longitude. Exiting.")\r
+        print ("")\r
 \r
 \r
 \r
index 5c29ebd5fa986972badbc2e0a97d96fca6e06574..f2dda2cc9ba5339ab2793309fb7619f6ff226284 100644 (file)
@@ -32,6 +32,7 @@ class mstr_orthographic:
     # Constructor of class. Takes longitude and latitude.\r
     def __init__(self, lat, lng, outfolder, pwd, prep=False):\r
         self._zoomlevel = mstr_zl_16\r
+        self._zoomlevelfactor = 16\r
         self._lat  = lat\r
         self._long = lng\r
         self._output = outfolder\r
@@ -152,26 +153,103 @@ class mstr_orthographic:
                 top_lat = cur_tile_y\r
 \r
 \r
+    # Creste necessary folders\r
+    def _createFolders(self):\r
+        # Create the _cache folder, should it not exist.\r
+        # Temporary images for the ortho tile generation go here\r
+        if not os.path.exists(self._output + "/_cache"):\r
+            os.makedirs(self._output + "/_cache")\r
+            mstr_msg("orthographic", "Created _cache folder.")\r
+        \r
+        # Generate the Tiles/lat-lng folder for the finished tile\r
+        if not os.path.exists(self._output + "/z_orthographic"):\r
+            os.makedirs(self._output + "/z_orthographic")\r
+            mstr_msg("orthographic", "Created z_orthographic folder")\r
+\r
+        # Generate the orthos folder\r
+        if not os.path.exists(self._output + "/z_orthographic/orthos"):\r
+            os.makedirs(self._output + "/z_orthographic/orthos")\r
+            mstr_msg("orthographic", "Created tile orthos folder")\r
+        if not os.path.exists(self._output + "/z_orthographic/orthos" + self._latlngfld):\r
+            os.makedirs(self._output + "/z_orthographic/orthos/" + self._latlngfld, exist_ok=True)\r
+\r
+        # Generate the database folder\r
+        if not os.path.exists(self._output + "/z_orthographic/data"):\r
+            os.makedirs(self._output + "/z_orthographic/data")\r
+            mstr_msg("orthographic", "Created tile database folder")\r
+        if not os.path.exists(self._output + "/z_orthographic/data/" + self._latlngfld):\r
+            os.makedirs(self._output + "/z_orthographic/data/" + self._latlngfld)\r
+        if not os.path.exists(self._output + "/z_orthographic/data/" + self._latlngfld + "/osm"):\r
+            os.makedirs(self._output + "/z_orthographic/data/" + self._latlngfld + "/osm")\r
+        if not os.path.exists(self._output + "/z_orthographic/data/" + self._latlngfld + "/perlin"):\r
+            os.makedirs(self._output + "/z_orthographic/data/" + self._latlngfld + "/perlin")\r
+\r
+        # X-Plane specific\r
+        if mstr_xp_genscenery == True:\r
+            btnum = self.find_earthnavdata_number()\r
+            btstr = self.latlng_folder(btnum)\r
+            if not os.path.exists(self._output + "/z_orthographic/terrain"):\r
+                os.makedirs(self._output + "/z_orthographic/terrain")\r
+                mstr_msg("orthographic", "[X-Plane] Created terrain files folder")\r
+            if not os.path.exists(self._output + "/z_orthographic/terrain/" + self._latlngfld):\r
+                os.makedirs(self._output + "/z_orthographic/terrain/" + self._latlngfld)\r
+            if not os.path.exists(self._output + "/z_orthographic/Earth nav data"):\r
+                os.makedirs(self._output + "/z_orthographic/Earth nav data")\r
+                mstr_msg("orthographic", "[X-Plane] Created Earth nav folder")\r
+            if not os.path.exists(self._output + "/z_orthographic/Earth nav data/" + btstr):\r
+                os.makedirs(self._output + "/z_orthographic/Earth nav data/" + btstr)\r
+            if mstr_xp_scn_normalmaps == True:\r
+                if not os.path.exists(self._output + "/z_orthographic/normals"):\r
+                    os.makedirs(self._output + "/z_orthographic/normals")\r
+                    mstr_msg("orthographic", "[X-Plane] created tile normal maps folder")\r
+                if not os.path.exists(self._output + "/z_orthographic/normals/" + self._latlngfld):\r
+                    os.makedirs(self._output + "/z_orthographic/normals/" + self._latlngfld)\r
+\r
+\r
     # Start the multi-threaded build of all orthos\r
     # amtsmt = AmountSimultaneous - so how many orthos you want to\r
     # generate at the same time. You may need to fine tune this value\r
     # so that you don't overload your machine.\r
     def _generateOrthos_mt(self, amtsmt):\r
-        # Need to know maximum values first\r
+\r
+        # Step 1\r
+        # Determine values:\r
+        # We need to know the highest possible latitude and longitude tile numbers,\r
+        # in case we render at the edge\r
         bb_lat = self._lat\r
         bb_lng = self._long\r
         bb_lat_edge = self._lat+self._vstep\r
         bb_lng_edge = self._long+self._zoomlevel\r
+        cur_tile_x = 1\r
+        cur_tile_y = 1\r
         mlat = 1\r
         mlng = 1\r
         while bb_lat < self._lat + 1:\r
             bb_lat = bb_lat + self._vstep\r
+            if bb_lat >= self._lat + 1:\r
+                bb_lat = bb_lat - self._zoomlevel\r
+                break\r
             mlat = mlat+1\r
         while bb_lng < self._long + 1:\r
             bb_lng = bb_lng + self._zoomlevel\r
+            if bb_lng >= self._long + 1:\r
+                bb_lng = bb_lng - self._zoomlevel\r
+                break\r
             mlng = mlng+1\r
         mstr_msg("orthographic", "Max lat tile: " + str(mlat) + " - max lng tile: " + str(mlng))\r
-        maxlatlng = [ mlat, mlng ]\r
+\r
+        # Step 2\r
+        # Create folders and generate all perlin noise maps\r
+        self._createFolders()\r
+        """\r
+        for l in mstr_ortho_layers:\r
+            if l[0] != "highway" and l[0] != "building":\r
+                mstr_important_msg("orthographic", "Generating Perlin map for " + l[0] + ":" + l[1])\r
+                prln = mstr_perlin(l[0], l[1], mlat, mlng, 16)\r
+                pmap = prln._generatePerlinMap()\r
+                fn = mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/perlin/" + l[0] + "_" + l[1] + ".png"\r
+                pmap.save(fn)\r
+        """\r
 \r
         # For completion layers\r
         numbers = list(range(1, 16))\r
@@ -224,6 +302,7 @@ class mstr_orthographic:
                 bb_lng_edge = self._long + ((grid_lng-1)*self._zoomlevel) + self._zoomlevel\r
 \r
                 osmxml = mstr_osmxml()\r
+                osmxml.setLatLngFld(self._latlngfld)\r
                 osmxml.adjust_bbox(bb_lat, bb_lng, bb_lat_edge, bb_lng_edge)\r
                 osmxml.acquire_osm(grid_lat, grid_lng)\r
 \r
@@ -263,7 +342,8 @@ class mstr_orthographic:
                     lg = mstr_layergen(layer[0], layer[1], self._lat, grid_lat, self._long, grid_lng, layer[2])\r
                     lg.set_max_latlng_tile(maxlatlng)\r
                     lg.set_latlng_folder(self._latlngfld)\r
-                    lg.open_tile_info()\r
+                    lg.set_zoomlevel(self._zoomlevelfactor)\r
+                    #lg.open_tile_info()\r
                     lyr = lg.genlayer(mask, osmxml)\r
                     photolayers.append(lyr)\r
                     if (layer[0] == "natural" and layer[1] == "water") or (layer[0] == "water" and layer[1] == "lake") or (layer[0] == "water" and layer[1] == "pond") or (layer[0] == "water" and layer[1] == "river") or (layer[0] == "waterway" and layer[1] == "river"):\r
@@ -281,6 +361,7 @@ class mstr_orthographic:
                 mstr_msg("orthographic", "Generating ortho photo")\r
                 pg = mstr_photogen(self._lat, self._long, grid_lat, grid_lng,  maxlatlng[0], maxlatlng[1])\r
                 pg.setLayerNames(layers)\r
+                pg.setZoomLevel(self._zoomlevelfactor)\r
                 pg.genphoto(photolayers, waterlayers, cpl)\r
                 mstr_important_msg("orthographic", "Ortho photo " + str(grid_lat)+"_"+str(grid_lng)+" generated!")\r
 \r
@@ -497,7 +578,7 @@ class mstr_orthographic:
             mstr_important_msg("orthographic", "Generating Perlin map for " + l[0] + ":" + l[1])\r
             prln = mstr_perlin(l[0], l[1], mlat, mlng, 16)\r
             pmap = prln._generatePerlinMap()\r
-            fn = mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/perlin/perlin_" + l[0] + "_" + l[1] + ".png"\r
+            fn = mstr_datafolder + "z_orthographic/data/" + self._latlngfld + "/perlin/" + l[0] + "_" + l[1] + ".png"\r
             pmap.save(fn)\r
 \r
         \r
index a141f8845c0048ba4f6c92c90ab86b3cc7510948..799a953eb5047434f9ec3ee2752a48beed3858a5 100644 (file)
--- a/perlin.py
+++ b/perlin.py
@@ -90,7 +90,7 @@ class mstr_perlin:
     # Find base color depending on tag/value
     def _findBaseColor(self):
         idx = -1
-        for b in range(len(self._basecolors)):
+        for b in range(len(self._bc)):
             if self._bc[b][0] == self._tag and self._bc[b][1] == self._value:
                 idx = b
                 break
index 5b3f57396dfe2d7b0327ee47f587be936ffd19a0..df328993d7378373b8e35dbced58d8a19340079b 100644 (file)
@@ -45,6 +45,11 @@ class mstr_photogen:
     def setLayerNames(self, names):\r
         self._lyrnames = names\r
 \r
+\r
+    # Set zoomlevel\r
+    def setZoomLevel(self, zl):\r
+        self._zoomlevel = zl\r
+\r
     \r
     # This puts it all together. Bonus: AND saves it.\r
     def genphoto(self, layers, waterlayers, cpl):\r
@@ -205,6 +210,8 @@ class mstr_photogen:
         #self._tile = ImageEnhance.Contrast(self._tile).enhance(0.1)\r
 \r
         # This we can save accordingly.\r
+        self._tile.show()\r
+        exit()\r
         self._tile.save(mstr_datafolder + "z_orthographic/orthos/" + self._latlngfld + "/" + str(self._ty) + "_" + str(self._tx) + ".png")\r
 \r
         # Now we convert this into a DDS\r
@@ -324,6 +331,9 @@ class mstr_photogen:
                 nc = (tp[0] - diff, tp[1] - diff, tp[2] - diff, tp[3])\r
                 treepx[x, y] = nc\r
 \r
+        if self._zoomlevel == 16:\r
+            tree = tree.resize((int(tree.width/4), int(tree.height/4)), resample=Image.Resampling.BILINEAR)\r
+\r
         return tree\r
 \r
 \r
@@ -370,7 +380,8 @@ class mstr_photogen:
                     lyr[0] == "leisure" and lyr[1] == "park"):\r
                 trees = Image.new("RGBA", (self._imgsize, self._imgsize))\r
                 amt = 4000\r
-                if lyr[1] == "cemetery": amt = 20000\r
+                if self._zoomlevel == 16: amt = 60000\r
+                if lyr[1] == "cemetery": amt = 60000\r
                 lyrmask = layers[curlyr].load() # We can use the layer image as alpha mask\r
                 for i in range(1, amt + 1):\r
                     lx = randrange(0, self._imgsize)\r