Skip to content

Commit

Permalink
Refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikolai Janakiev committed Feb 26, 2018
1 parent 1b1ab04 commit f24777d
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 55 deletions.
82 changes: 53 additions & 29 deletions render_osm_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from matplotlib import cm
from bpy.app.handlers import persistent
import utils
import load_osm_data
import utils_osm
from math import sin, cos, pi
TAU = 2*pi

Expand All @@ -32,7 +32,7 @@ def normalize_points(points):
return data


def heatmap_grid(data, sigmaSq=0.0001, n=20, m=2):
def heatmap_grid(data, sigma_sq=0.0001, n=20, m=2):
"""Create n by n grid with heatmap from data with gaussian distribution of input data set"""

X = np.ndarray((n, n), dtype=object)
Expand All @@ -56,7 +56,7 @@ def heatmap_grid(data, sigmaSq=0.0001, n=20, m=2):
if X[i, j] is not None:
for x, y in X[i, j]:
grid[i0][j0] += np.exp(- ((x0 - x)**2)/
(2*sigmaSq) - ((y0 - y)**2)/(2*sigmaSq))
(2*sigma_sq) - ((y0 - y)**2)/(2*sigma_sq))

return grid

Expand Down Expand Up @@ -98,11 +98,11 @@ def heatmap_barplot(grid, h=4, width=10, bar_scale=0.9, num_colors=10, colormap=
objList = []
for i, bm in enumerate(bmList):
# Create object
obj = utils.bmeshToObject(bm)
obj = utils.bmesh_to_object(bm)

# Create material with colormap
color = colormap(i / num_colors)
mat = utils.simpleMaterial(color[:3])
mat = utils.simple_material(color[:3])
obj.data.materials.append(mat)
objList.append(obj)

Expand All @@ -113,17 +113,23 @@ def heatmap_barplot(grid, h=4, width=10, bar_scale=0.9, num_colors=10, colormap=

if __name__ == '__main__':
# Settings
iso_a2, tag_key, tag_value = 'DE', 'amenity', 'biergarten'
res_x, res_y = 768, 432
iso_a2, tag_key, tag_value = 'GB', 'amenity', 'pub'
#res_x, res_y = 768, 432
#res_x, res_y = 600, 600
#res_x, res_y = 640, 480
#res_x, res_y = 640, 360
#res_x, res_y = 1280, 720
num_frames = 40
res_x, res_y = 1280, 720

animation = False
#r, camera_z = 10, 7
r, camera_z = 12, 10
target_z = 0.1
#target_z = 0.8
num_frames = 40

#camera_position, target_position = (3, -10, 8), (0.3, -1.8, 0.5) # DE
#camera_position, target_position = (3, -10, 8), (0.3, 0.0, 0.5) # AT
#camera_position, target_position = (3, -10, 8), (-0.1, -0.4, 1.0) # CH
camera_position, target_position = (-2, -10, 8), (0.0, -2.6, 1.0) # GB

#camera_type, ortho_scale = 'ORTHO', 15
camera_type, ortho_scale = 'PERSP', 18
render_idx = 0
Expand All @@ -134,11 +140,11 @@ def heatmap_barplot(grid, h=4, width=10, bar_scale=0.9, num_colors=10, colormap=
bpy.ops.object.delete(use_global=False)

# Create scene
target = utils.createTarget((0, 0, target_z))
camera = utils.createCamera(target=target,
target = utils.create_target(target_position)
camera = utils.create_camera(camera_position, target=target,
camera_type=camera_type, ortho_scale=ortho_scale, lens=28)
#type='ORTHO', ortho_scale=12)
sun = utils.createLamp((-5, 5, 10), 'SUN', target=target)
sun = utils.create_lamp((-5, 5, 10), 'SUN', target=target)

# Set background color
bpy.context.scene.world.horizon_color = (0.7, 0.7, 0.7)
Expand All @@ -147,28 +153,46 @@ def heatmap_barplot(grid, h=4, width=10, bar_scale=0.9, num_colors=10, colormap=
bpy.context.scene.world.light_settings.use_ambient_occlusion = True
bpy.context.scene.world.light_settings.samples = 8

# Load points from geojson
# Load points from existing geojson file or load them with Overpass API
filepath = 'data/points_{}_{}_{}.json'.format(iso_a2, tag_key, tag_value)
points, names = load_osm_data.load_points(filepath)
if os.path.exists(filepath):
points, names = utils_osm.load_points(filepath)
else:
points, names = utils_osm.overpass_load_points(
iso_a2, tag_key, tag_value)
if not os.path.exists('data'): os.mkdir('data')
utils_osm.save_points(filepath, points, names)

print("Number of points : {}".format(len(points)))

# Project points into Mercator projection
p = Proj(init="epsg:3785") # Popular Visualisation CRS / Mercator
points = np.apply_along_axis(lambda x : p(*x), 1, points)

# Create heatmap barplot
data = normalize_points(points)
hist = heatmap_grid(data, sigmaSq=0.00005, n=80)
heatmap_barplot(hist)

print("Number of points : {}".format(points.shape[0]))
#hist = heatmap_grid(data, sigma_sq=0.00005, n=80)
hist = heatmap_grid(data, sigma_sq=0.00002, n=100)
#heatmap_barplot(hist, colormap=cm.Wistia)
heatmap_barplot(hist, colormap=cm.viridis)
#heatmap_barplot(hist, colormap=cm.YlGn_r)
#heatmap_barplot(hist, colormap=cm.summer_r)

# Animate rotation of camera
for frame in range(1, num_frames):
t = frame / num_frames
x, y = r*cos(TAU*t), r*sin(TAU*t)
camera.location = (x, y, camera_z)
camera.keyframe_insert(data_path="location", index=-1, frame=frame)
if animation:
for frame in range(1, num_frames):
t = frame / num_frames
x, y = r*cos(TAU*t), r*sin(TAU*t)
camera.location = (x, y, camera_z)
camera.keyframe_insert(data_path="location", index=-1, frame=frame)

render_folder = '{}_{}_{}_{}_{}_{}_{:0>3}'.format(
iso_a2, tag_key, tag_value, camera_type, res_x, res_y, render_idx)
render_name = 'render'
else:
render_folder = 'render'
render_name = '{}_{}_{}_{}_{}_{}_{:0>3}'.format(
iso_a2, tag_key, tag_value, camera_type, res_x, res_y, render_idx)

# Render result
frames_folder = '{}_{}_{}_{}_{}_{}_{:0>3}'.format(
iso_a2, tag_key, tag_value, camera_type, res_x, res_y, render_idx)

utils.renderToFolder(frames_folder, res_x=res_x, res_y=res_y, animation=True, frame_end=num_frames, render_opengl=False)
utils.render_to_folder(render_folder, render_name, res_x=res_x, res_y=res_y, animation=animation, frame_end=num_frames, render_opengl=False)
5 changes: 3 additions & 2 deletions run_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@
file = os.path.join(cwd, scriptFile)

# Reload the previously imported modules
import utils, utils_osm
if 'utils' in locals():
importlib.reload(utils)
if 'load_osm_data' in locals():
importlib.reload(load_osm_data)
if 'utils_osm' in locals():
importlib.reload(utils_osm)

exec(compile(open(file).read(), scriptFile, 'exec'))
41 changes: 22 additions & 19 deletions utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import bmesh


def simpleMaterial(diffuse_color):
def simple_material(diffuse_color):
mat = bpy.data.materials.new('Material')

# Diffuse
Expand All @@ -16,7 +16,7 @@ def simpleMaterial(diffuse_color):

return mat

def bmeshToObject(bm, name='Object'):
def bmesh_to_object(bm, name='Object'):
mesh = bpy.data.meshes.new(name+'Mesh')
bm.to_mesh(mesh)
bm.free()
Expand All @@ -27,20 +27,20 @@ def bmeshToObject(bm, name='Object'):

return obj

def trackToConstraint(obj, target):
def track_to_constraint(obj, target):
constraint = obj.constraints.new('TRACK_TO')
constraint.target = target
constraint.track_axis = 'TRACK_NEGATIVE_Z'
constraint.up_axis = 'UP_Y'

def createTarget(origin=(0,0,0)):
def create_target(origin=(0,0,0)):
tar = bpy.data.objects.new('Target', None)
bpy.context.scene.objects.link(tar)
tar.location = origin

return tar

def createCamera(origin=(0,0,0), target=None, lens=35, clip_start=0.1, clip_end=200, camera_type='PERSP', ortho_scale=6):
def create_camera(origin=(0,0,0), target=None, lens=35, clip_start=0.1, clip_end=200, camera_type='PERSP', ortho_scale=6):
# Create object and camera
camera = bpy.data.cameras.new("Camera")
camera.lens = lens
Expand All @@ -56,48 +56,51 @@ def createCamera(origin=(0,0,0), target=None, lens=35, clip_start=0.1, clip_end=
bpy.context.scene.objects.link(obj)
bpy.context.scene.camera = obj # Make this the current camera

if target: trackToConstraint(obj, target)
if target: track_to_constraint(obj, target)
return obj

def createLamp(origin, type='POINT', energy=1, color=(1,1,1), target=None):
def create_lamp(origin, type='POINT', energy=1, color=(1,1,1), target=None):
# Lamp types: 'POINT', 'SUN', 'SPOT', 'HEMI', 'AREA'
bpy.ops.object.add(type='LAMP', location=origin)
obj = bpy.context.object
obj.data.type = type
obj.data.energy = energy
obj.data.color = color

if target: trackToConstraint(obj, target)
if target: track_to_constraint(obj, target)
return obj

def renderToFolder(renderFolder='rendering', renderName='render', res_x=800, res_y=800, res_percentage=100, animation=False, frame_end=None, render_opengl=False):
def render_to_folder(render_folder='render', render_name='render', res_x=800, res_y=800, res_percentage=100, animation=False, frame_end=None, render_opengl=False):
print('renderToFolder called')
scn = bpy.context.scene
scn.render.resolution_x = res_x
scn.render.resolution_y = res_y
scn.render.resolution_percentage = res_percentage
print('render_folder : {}'.format(render_folder))
print('render_name : {}'.format(render_name))

scene = bpy.context.scene
scene.render.resolution_x = res_x
scene.render.resolution_y = res_y
scene.render.resolution_percentage = res_percentage
if frame_end:
scn.frame_end = frame_end
scene.frame_end = frame_end

# Check if script is executed inside Blender
if (bpy.context.space_data is None) or render_opengl:
# Specify folder to save rendering and check if it exists
render_folder = os.path.join(os.getcwd(), renderFolder)
render_folder = os.path.join(os.getcwd(), render_folder)
if(not os.path.exists(render_folder)):
os.mkdir(render_folder)

if animation:
# Render animation
scn.render.filepath = os.path.join(render_folder,
renderName)
scene.render.filepath = os.path.join(render_folder,
render_name)
if render_opengl:
bpy.ops.render.opengl(animation=True, view_context=False)
else:
bpy.ops.render.render(animation=True)
else:
# Render still frame
scn.render.filepath = os.path.join(render_folder,
renderName + '.png')
scene.render.filepath = os.path.join(render_folder,
render_name + '.png')
if render_opengl:
bpy.ops.render.opengl(write_still=True, view_context=False)
else:
Expand Down
10 changes: 5 additions & 5 deletions load_osm_data.py → utils_osm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import json


def load_overpass_points(iso_a2, tag_key='amenity', tag_value='cafe'):
def overpass_load_points(iso_a2, tag_key='amenity', tag_value='cafe'):
"""Load points from OSM with overpy"""

api = overpy.Overpass()
Expand Down Expand Up @@ -53,7 +53,7 @@ def save_points(filepath, coords, names=None, wgs84=True):
feature['type'] = 'Feature'
feature['geometry'] = {}
feature['geometry']['type'] = 'Point'
feature['geometry']['coords'] = coord
feature['geometry']['coordinates'] = coord

if names is not None and name is not None:
feature['properties'] = {}
Expand All @@ -80,11 +80,11 @@ def load_points(filepath):
with open(filepath, 'r') as f:
data = json.load(f)
if data['type'] == 'MultiPoint':
coords = data['coords']
coords = data['coordinates']
names = [None] * len(coords)
elif data['type'] == 'FeatureCollection':
for feature in data['features']:
coords.append(feature['geometry']['coords'])
coords.append(feature['geometry']['coordinates'])
if 'properties' in feature and 'name' in feature['properties']:
names.append(feature['properties']['name'])
else:
Expand All @@ -99,7 +99,7 @@ def load_points(filepath):
iso_a2, tag_key, tag_value = 'DE', 'amenity', 'biergarten'
print(iso_a2, tag_key, tag_value)

coords, names = load_overpass_points(iso_a2, tag_key, tag_value)
coords, names = overpass_load_points(iso_a2, tag_key, tag_value)
print('Number of points : {}'.format(len(coords)))

filepath = 'data/points_{}_{}_{}.json'.format(iso_a2, tag_key, tag_value)
Expand Down

0 comments on commit f24777d

Please sign in to comment.