forked from vvoovv/blosm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathio_import_scene_osm_dev.py
142 lines (116 loc) · 4.33 KB
/
io_import_scene_osm_dev.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
bl_info = {
"name": "Import OpenStreetMap (.osm)",
"author": "Vladimir Elistratov <[email protected]>",
"version": (1, 0, 0),
"blender": (2, 6, 9),
"location": "File > Import > OpenStreetMap (.osm)",
"description": "Import a file in the OpenStreetMap format (.osm)",
"warning": "",
"wiki_url": "https://github.com/vvoovv/blender-geo/wiki/Import-OpenStreetMap-(.osm)",
"tracker_url": "https://github.com/vvoovv/blender-geo/issues",
"support": "COMMUNITY",
"category": "Import-Export",
}
import bpy, bmesh
# ImportHelper is a helper class, defines filename and invoke() function which calls the file selector
from bpy_extras.io_utils import ImportHelper
import sys, os
sys.path.append("D:\\projects\\blender\\blender-geo")
from transverse_mercator import TransverseMercator
from osm_parser import OsmParser
from osm_import_handlers import buildings
import utils
class ImportOsm(bpy.types.Operator, ImportHelper):
"""Import a file in the OpenStreetMap format (.osm)"""
bl_idname = "import_scene.osm" # important since its how bpy.ops.import_scene.osm is constructed
bl_label = "Import OpenStreetMap"
bl_options = {"UNDO"}
# ImportHelper mixin class uses this
filename_ext = ".osm"
filter_glob = bpy.props.StringProperty(
default="*.osm",
options={"HIDDEN"},
)
ignoreGeoreferencing = bpy.props.BoolProperty(
name="Ignore existing georeferencing",
description="Ignore existing georeferencing and make a new one",
default=False,
)
singleMesh = bpy.props.BoolProperty(
name="Import as a single mesh",
description="Import OSM objects as a single mesh instead of separate Blender objects",
default=False,
)
thickness = bpy.props.FloatProperty(
name="Thickness",
description="Set thickness to make OSM objects extruded",
default=0,
)
def execute(self, context):
# setting active object if there is no active object
if not context.scene.objects.active:
context.scene.objects.active = context.scene.objects[0]
bpy.ops.object.mode_set(mode="OBJECT")
bpy.ops.object.select_all(action="DESELECT")
name = os.path.basename(self.filepath)
if self.singleMesh:
self.bm = bmesh.new()
else:
self.bm = None
# create an empty object to parent all imported OSM objects
bpy.ops.object.empty_add(type="PLAIN_AXES", location=(0, 0, 0))
parentObject = context.active_object
self.parentObject = parentObject
parentObject.name = name
#parentObject.hide = True
#parentObject.hide_select = True
parentObject.hide_render = True
self.read_osm_file(context)
if self.singleMesh:
bm = self.bm
# extrude
if self.thickness>0:
utils.extrudeMesh(bm, self.thickness)
bm.normal_update()
mesh = bpy.data.meshes.new(name)
bm.to_mesh(mesh)
obj = bpy.data.objects.new(name, mesh)
bpy.context.scene.objects.link(obj)
bpy.context.scene.update()
else:
# perform parenting
context.scene.objects.active = parentObject
bpy.ops.object.parent_set()
bpy.ops.object.select_all(action="DESELECT")
return {"FINISHED"}
def read_osm_file(self, context):
scene = context.scene
osm = OsmParser(self.filepath,
# possible values for wayHandlers and nodeHandlers list elements:
# 1) a string name for the module containing classes (all classes from the modules will be used as handlers)
# 2) a python variable representing the module containing classes (all classes from the modules will be used as handlers)
# 3) a python variable representing the class
wayHandlers = [buildings] #[handlers.buildings] #[handlers] #["handlers"]
)
if "latitude" in scene and "longitude" in scene and not self.ignoreGeoreferencing:
lat = scene["latitude"]
lon = scene["longitude"]
else:
lat = (osm.minLat + osm.maxLat)/2
lon = (osm.minLon + osm.maxLon)/2
scene["latitude"] = lat
scene["longitude"] = lon
osm.parse(
projection = TransverseMercator(lat=lat, lon=lon),
thickness = self.thickness,
bm = self.bm # if present, indicates the we need to create as single mesh
)
# Only needed if you want to add into a dynamic menu
def menu_func_import(self, context):
self.layout.operator(ImportOsm.bl_idname, text="OpenStreetMap (.osm)")
def register():
bpy.utils.register_class(ImportOsm)
bpy.types.INFO_MT_file_import.append(menu_func_import)
def unregister():
bpy.utils.unregister_class(ImportOsm)
bpy.types.INFO_MT_file_import.remove(menu_func_import)