[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [3122] contrib/py/scripts/addons/ io_scene_open_street_map.py: Open Street Map - originally by Michael Anthrax Schlachter, updated to work as an addon, and for the bmesh API by me.

Campbell Barton ideasman42 at gmail.com
Thu Mar 15 19:33:09 CET 2012


Revision: 3122
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=3122
Author:   campbellbarton
Date:     2012-03-15 18:32:58 +0000 (Thu, 15 Mar 2012)
Log Message:
-----------
Open Street Map - originally by Michael Anthrax Schlachter, updated to work as an addon, and for the bmesh API by me.

Port requested for work on mango.blender.org

Notes:
- all lines import as a single object (could use curves/polylines instead)
- at the moment we are scaling by 1.5 on an axis, which seems odd, need to look into this.
- no face-filling happens at the moment could use BMesh ngons for this.
- theres probably more data that could be imported from these OSM/XML files.

Added Paths:
-----------
    contrib/py/scripts/addons/io_scene_open_street_map.py

Added: contrib/py/scripts/addons/io_scene_open_street_map.py
===================================================================
--- contrib/py/scripts/addons/io_scene_open_street_map.py	                        (rev 0)
+++ contrib/py/scripts/addons/io_scene_open_street_map.py	2012-03-15 18:32:58 UTC (rev 3122)
@@ -0,0 +1,209 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+
+# <pep8 compliant>
+
+bl_info = {
+    "name": "Open Street Map (.osm)",
+    "author": "Michael Anthrax Schlachter",
+    "version": (0, 1),
+    "blender": (2, 6, 3),
+    "location": "File > Import",
+    "description": "Load Open Street Map File",
+    "wiki_url": "",
+    "tracker_url": "",
+    "category": "Import-Export"}
+
+# originally written for blender 2.4x by (manthrax _at_ hotmail.com),
+# updated by for blender 2.6x by ideasman42
+# If you use it for something cool, send me an email and let me know!
+
+import bpy
+from mathutils import Vector, Matrix
+
+
+def parseBranch(nodes, bm, nmap, scale=100.0):
+    tidx = 0
+    inNode = 0
+    dlat = dlong = clat = clong = minlat = maxlat = minlong = maxlong = 0.0
+    for node in nodes:
+        if node.localName == "bounds":
+            if node.hasAttributes():
+                for i in range(node.attributes.length):
+                    at = node.attributes.item(i)
+                    if at.name == "minlat":
+                        minlat = float(at.nodeValue)
+                    elif at.name == "minlon":
+                        minlong = float(at.nodeValue)
+                    elif at.name == "maxlat":
+                        maxlat = float(at.nodeValue)
+                    elif at.name == "maxlon":
+                        maxlong = float(at.nodeValue)
+                dlat = maxlat - minlat
+                dlong = maxlong - minlong
+                clat = (maxlat + minlat) * 0.5
+                clong = (maxlong + minlong) * 0.5
+
+                print(dlat, dlong, clat, clong)
+
+        if node.localName == "way":
+            nid = None
+            refs = []
+            '''
+            if node.hasAttributes():
+                for i in range(node.attributes.length):
+                    at=node.attributes.item(i)
+                    print(at.name)
+            '''
+
+            for ch in node.childNodes:
+                if ch.localName == "nd":
+                    for i in range(ch.attributes.length):
+                        at = ch.attributes.item(i)
+                        #print(at.name)
+                        if at.name == "ref":
+                            refs.append(int(at.nodeValue))
+
+            first = 1
+            for r in refs:
+                if first == 0:
+                    edge = bm.edges.get((nmap[pr], nmap[r]))
+                    if edge is None:
+                        edge = bm.edges.new((nmap[pr], nmap[r]))
+                    del edge  # don't actually use it
+                else:
+                    first = 0
+                pr = r
+
+        if node.localName == "node":
+            if node.hasAttributes():
+                nid = None
+                nlong = None
+                nlat = None
+                logged = 0
+                for i in range(node.attributes.length):
+                    at = node.attributes.item(i)
+                    #print(at.name)
+                    if at.name == "id":
+                        nid = at.nodeValue
+                    elif at.name == "lon":
+                        nlong = at.nodeValue
+                    elif at.name == "lat":
+                        nlat = at.nodeValue
+
+                    if (nid is not None) and (nlat is not None) and (nlong is not None):
+                        fla = (float(nlat) - clat) * scale / dlat
+                        flo = (float(nlong) - clong) * scale / dlat
+                        vert = bm.verts.new((fla, flo, 0.0))
+                        nmap[int(nid)] = vert
+                        logged = 1
+                        break
+        tidx += 1
+        #if tidx > 1000:
+        #    break
+        tidx += parseBranch(node.childNodes, bm, nmap)
+
+    return tidx
+
+
+def read(context, filepath, scale=100.0):
+    import bmesh
+    from xml.dom import minidom
+
+    xmldoc = minidom.parse(filepath)
+
+    print("Starting parse: %r..." % filepath)
+    bm = bmesh.new()
+
+    nmap = {}
+    tidx = parseBranch(xmldoc.childNodes, bm, nmap)
+
+    # create mesh
+    name = bpy.path.display_name_from_filepath(filepath)
+    me = bpy.data.meshes.new(name)
+    bm.to_mesh(me)
+    obj = bpy.data.objects.new(name, me)
+
+    # scale by 1.5 is odd, need to look into that
+    global_matrix = Matrix(((+0.0, +1.0, +0.0, +0.0),
+                            (+1.5, -0.0, +0.0, +0.0),
+                            (+0.0, -0.0, -1.0, +0.0),
+                            (+0.0, +0.0, +0.0, +1.0)))
+    me.transform(global_matrix)
+
+    # create the object in the scene
+    scene = context.scene
+    scene.objects.link(obj)
+    scene.objects.active = obj
+    obj.select = True
+
+    print("Parse done... %d" % tidx)
+
+    return {'FINISHED'}
+
+## for testing
+#if __name__ == "__main__":
+#    read("/data/downloads/osm_parser/map.osm", bpy.context)
+
+
+# ----------------------------------------------------------------------------
+# blender integration
+
+from bpy.types import Operator
+from bpy_extras.io_utils import ImportHelper
+
+from bpy.props import StringProperty, FloatProperty
+
+
+class ImportOSM(Operator, ImportHelper):
+    '''Import OSM'''
+    bl_idname = "import.open_street_map"
+    bl_label = "Import OpenStreetMap (.osm)"
+
+    # ExportHelper mixin class uses this
+    filename_ext = ".osm"
+
+    filter_glob = StringProperty(
+            default="*.osm",
+            options={'HIDDEN'},
+            )
+
+    # List of operator properties, the attributes will be assigned
+    # to the class instance from the operator settings before calling.
+    scale = FloatProperty(
+            name="Scale",
+            default=100.0,
+            )
+
+    def execute(self, context):
+        return read(context, self.filepath, self.scale)
+
+
+# Only needed if you want to add into a dynamic menu
+def menu_func_export(self, context):
+    self.layout.operator(ImportOSM.bl_idname)
+
+
+def register():
+    bpy.utils.register_class(ImportOSM)
+    bpy.types.INFO_MT_file_import.append(menu_func_export)
+
+
+def unregister():
+    bpy.utils.unregister_class(ImportOSM)
+    bpy.types.INFO_MT_file_import.remove(menu_func_export)


Property changes on: contrib/py/scripts/addons/io_scene_open_street_map.py
___________________________________________________________________
Added: svn:eol-style
   + native



More information about the Bf-extensions-cvs mailing list