Add grid generation
@@ -3,11 +3,11 @@ from collections import Counter
|
||||
from typing import List, Union
|
||||
|
||||
import numpy as np
|
||||
from gdpc import Editor
|
||||
from PIL import Image, ImageDraw
|
||||
from skan.csr import skeleton_to_csgraph
|
||||
from skimage.morphology import skeletonize
|
||||
|
||||
from gdpc import Editor
|
||||
from networks.geometry.Point3D import Point3D
|
||||
|
||||
|
||||
def handle_import_image(image: Union[str, Image]) -> Image:
|
||||
@@ -16,6 +16,51 @@ def handle_import_image(image: Union[str, Image]) -> Image:
|
||||
return image
|
||||
|
||||
|
||||
def transpose_form_heightmap(heightmap: Union[str, Image], coordinates):
|
||||
heightmap = handle_import_image(heightmap).convert('L')
|
||||
|
||||
editor = Editor()
|
||||
xMin = (editor.getBuildArea().begin).x
|
||||
zMin = (editor.getBuildArea().begin).z
|
||||
|
||||
return (coordinates[0] + xMin, heightmap.getpixel(
|
||||
(coordinates[0], coordinates[-1])), coordinates[-1] + zMin)
|
||||
|
||||
|
||||
def simplify_coordinates(coordinates, epsilon):
|
||||
if len(coordinates) < 3:
|
||||
return coordinates
|
||||
|
||||
# Find the point with the maximum distance
|
||||
max_distance = 0
|
||||
max_index = 0
|
||||
end_index = len(coordinates) - 1
|
||||
|
||||
for i in range(1, end_index):
|
||||
distance = Point3D(coordinates[i][0], coordinates[i][1], coordinates[i][2]).distance(
|
||||
Point3D(coordinates[0][0], coordinates[0][1], coordinates[0][2]))
|
||||
if distance > max_distance:
|
||||
max_distance = distance
|
||||
max_index = i
|
||||
|
||||
simplified_coordinates = []
|
||||
|
||||
# If the maximum distance is greater than epsilon, recursively simplify
|
||||
if max_distance > epsilon:
|
||||
rec_results1 = simplify_coordinates(coordinates[:max_index+1], epsilon)
|
||||
rec_results2 = simplify_coordinates(coordinates[max_index:], epsilon)
|
||||
|
||||
# Combine the simplified sub-results
|
||||
simplified_coordinates.extend(rec_results1[:-1])
|
||||
simplified_coordinates.extend(rec_results2)
|
||||
else:
|
||||
# The maximum distance is less than epsilon, retain the endpoints
|
||||
simplified_coordinates.append(coordinates[0])
|
||||
simplified_coordinates.append(coordinates[end_index])
|
||||
|
||||
return simplified_coordinates
|
||||
|
||||
|
||||
class Skeleton:
|
||||
def __init__(self, data: np.ndarray = None):
|
||||
self.lines = []
|
||||
@@ -26,19 +71,6 @@ class Skeleton:
|
||||
if data is not None:
|
||||
self.set_skeleton(data)
|
||||
|
||||
def transpose_form_heightmap(heightmap: Union[str, Image], coordinates):
|
||||
|
||||
heightmap = handle_import_image(heightmap).convert('L')
|
||||
|
||||
editor = Editor()
|
||||
xMin = (editor.getBuildArea().begin).x
|
||||
zMin = (editor.getBuildArea().begin).z
|
||||
|
||||
coordinates_final = []
|
||||
|
||||
return coordinates_final(coordinates[0] + xMin, heightmap.getpixel(
|
||||
(coordinates[0], coordinates[2]))[0], coordinates[2] + zMin)
|
||||
|
||||
def set_skeleton(self, data: np.ndarray):
|
||||
print("[Skeleton] Start skeletonization...")
|
||||
binary_skeleton = skeletonize(data, method="lee")
|
||||
|
||||
|
Before Width: | Height: | Size: 396 B After Width: | Height: | Size: 344 B |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 707 B After Width: | Height: | Size: 843 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 750 B After Width: | Height: | Size: 876 B |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 900 B After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 813 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 2.4 KiB |
@@ -1,35 +1,43 @@
|
||||
from world_maker.World import World
|
||||
from PIL import Image
|
||||
from world_maker.data_analysis import (get_data,filter_negative, rectangle_2D_to_3D, skeleton_mountain_map, highway_map, filter_sobel, skeleton_highway_map, \
|
||||
smooth_sobel_water, subtract_map, detect_mountain)
|
||||
from world_maker.data_analysis import (get_data, filter_negative, rectangle_2D_to_3D, skeleton_mountain_map, highway_map, filter_sobel, skeleton_highway_map,
|
||||
smooth_sobel_water, subtract_map, detect_mountain)
|
||||
from world_maker.City import City
|
||||
from world_maker.Position import Position
|
||||
from random import randint
|
||||
from world_maker.pack_rectangle import generate_building
|
||||
|
||||
|
||||
def world_maker():
|
||||
world = World()
|
||||
heightmap, watermap, treemap = get_data(world)
|
||||
filter_sobel("./world_maker/data/heightmap.png").save('./world_maker/data/sobelmap.png')
|
||||
filter_sobel(
|
||||
"./world_maker/data/heightmap.png").save('./world_maker/data/sobelmap.png')
|
||||
smooth_sobel_water_map = smooth_sobel_water()
|
||||
skeleton_highway = skeleton_highway_map(highway_map())
|
||||
city = City()
|
||||
city.generate_district()
|
||||
city.loop_expend_district()
|
||||
city.district_draw_map()
|
||||
city.district_generate_road()
|
||||
road_grid = city.district_generate_road()
|
||||
image_mountain_map = city.get_district_mountain_map()
|
||||
road = city.draw_roads(4)
|
||||
road.save('./world_maker/data/roadmap.png')
|
||||
subtract_map(smooth_sobel_water_map, road).save('./world_maker/data/city_map.png')
|
||||
subtract_map('./world_maker/data/city_map.png', './world_maker/data/skeleton_highway_area.png').save('./world_maker/data/city_map.png')
|
||||
subtract_map('./world_maker/data/city_map.png', './world_maker/data/mountain_map.png').save('./world_maker/data/city_map.png')
|
||||
subtract_map(smooth_sobel_water_map, road).save(
|
||||
'./world_maker/data/city_map.png')
|
||||
subtract_map('./world_maker/data/city_map.png',
|
||||
'./world_maker/data/skeleton_highway_area.png').save('./world_maker/data/city_map.png')
|
||||
subtract_map('./world_maker/data/city_map.png',
|
||||
'./world_maker/data/mountain_map.png').save('./world_maker/data/city_map.png')
|
||||
rectangle_building = generate_building('./world_maker/data/city_map.png')
|
||||
rectangle_building = rectangle_2D_to_3D(rectangle_building)
|
||||
|
||||
skeleton_mountain = skeleton_mountain_map(image_mountain_map)
|
||||
subtract_map('./world_maker/data/mountain_map.png', './world_maker/data/skeleton_mountain_area.png').save('./world_maker/data/mountain_map.png')
|
||||
subtract_map(smooth_sobel_water_map, filter_negative('./world_maker/data/mountain_map.png')).save('./world_maker/data/mountain_map.png')
|
||||
rectangle_mountain = generate_building('./world_maker/data/mountain_map.png')
|
||||
subtract_map('./world_maker/data/mountain_map.png',
|
||||
'./world_maker/data/skeleton_mountain_area.png').save('./world_maker/data/mountain_map.png')
|
||||
subtract_map(smooth_sobel_water_map, filter_negative(
|
||||
'./world_maker/data/mountain_map.png')).save('./world_maker/data/mountain_map.png')
|
||||
rectangle_mountain = generate_building(
|
||||
'./world_maker/data/mountain_map.png')
|
||||
rectangle_mountain = rectangle_2D_to_3D(rectangle_mountain)
|
||||
return rectangle_mountain, rectangle_building, skeleton_highway, skeleton_mountain
|
||||
return rectangle_mountain, rectangle_building, skeleton_highway, skeleton_mountain, road_grid
|
||||
|
||||