thePyFactor 3.0
Return to list

CAUTION:: This fails in recent builds of Blender. 

There is still useful info in how to build add-ons for Blender. If anyone has time to track down the issue that causes this to fail and fix it, feel free to do so and share the results.

This is sample code, not a supported script. 

A rudimentary Python (3.x) script for Blender (2.5+) to import GPS Visualizer text files. This is the first importer I wrote for Blender. Sometimes it will only work once without restarting Blender. 

To use: copy the script's text, open Blender's Text Editor, select Create Text Block from the Text menu, and paste the script into the Text Editor, click the Run Script button.

An option, GPS Visualizer Text File, will appear in Blender's File:Import menu list. Select that menu item, locate & select the GPS Visualizer text file and click the Import button. When imported, the text file from the GPS Visualizer web site will be built into (as written) a NURBS curve.

Other options for curve types: BSPLINE,  POLY and  BEZIER. The resulting curve can be used for a guide to create a track surface.

If someone wants to improve this script, please feel free to do so. Should you improve the script, I'd be glad to post the script or the URL where you have posted the improved script. Acknowledgement for this basic script is always appreciated (rlong at thePyFactor).

The GPS Visualizer web site imports a number of different GPS file formats, as well as KML files from Google Earth, and exports a text file containing altitude (if you so choose). That exported file is what this importer understands. The exported file from GPS Visualizer takes the following format:

type latitude longitude altitude (m) name desc
T 38.9854349 -94.8092168 265.8    
T 38.9821951 -94.8105555 266.0    
T  38.9819787  -94.8106462  269.1    
T  38.9818966  -94.8106837  270.4    
T  38.9817971  -94.8107251  271.9    
T  38.9817343  -94.8107491  272.6    
T 38.9816895 -94.8107647 273.2    
T 38.9816531 -94.8107695 273.7    

 

The code:

 


import bpy
import math

from mathutils import Vector 

class ImportSomeData(bpy.types.Operator):
    """Lat-Lon-Alt file importer"""
    bl_idname = "import.some_data"
    bl_label = "import Some Data"

    filepath = bpy.props.StringProperty(subtype="FILE_PATH")

    @classmethod
    def poll(cls, context):
        return context.object is not None

    def execute(self, context):
        line_cnt = 0
        file = open(self.filepath, 'r')

        line = file.readline()          # read the header
        line_cnt = line_cnt+1           # skip the header
        
        lat1 = 0.0
        lon1 = 0.0
        lat2 = 0.0
        lon2 = 0.0
        earth_radius_km = 6371
        DtoR = math.pi/180.0
        alt = 0.0
        start_lon = 0
        start_lat = 0
        center_line_array = []
        
        while line:
            line = file.readline()
            line_array = line.split()

            for index, item in enumerate(line_array):
                if item == 'T':
                    continue

                if index == 1:
                    lat2 = float(item)
                if index == 2:
                    lon2 = float(item)
                if index == 3:
                    alt = float(item)
            
            
            #  =========================================
            #	NOTE::: this is hardwired to a particular latitude
            #		to get the correct meters per degree, there are
            #		a number of web sites that provide appropriate 
            #           meters per degree.
            #		One of them is:
            #		   http://www.csgnetwork.com/degreelenllavcalc.html
            #			
            # meters in one degree @ 38.9854349 lat = 111015.168617521
            meters_per_degree_lat = 111015.168617521
            meters_per_degree_lon = 86644.6602414198
            
            meters_per_degree_lat_times_current_lat = lat2 * meters_per_degree_lat
            meters_per_degree_lon_times_current_lon = lon2 * meters_per_degree_lon
            
            if line_cnt == 1:
                start_lat = meters_per_degree_lat_times_current_lat
                start_lon = meters_per_degree_lon_times_current_lon
                start_alt = alt
                
            offset_lat = (meters_per_degree_lat_times_current_lat - start_lat) * -1.0
            offset_lon = meters_per_degree_lon_times_current_lon - start_lon
            offset_alt = alt - start_alt
            
            center_line_array.append((offset_lat, offset_lon, offset_alt))
                        
            lat1 = lat2
            lon1 = lon2
            line_cnt = line_cnt+1   
		
		
        # ====================================================================
        # the following produces a curve from the GPS/KML/Google data 
        # run through gpsvisualizer.com web app
        
        w = 1       # weight
        
        curvedata = bpy.data.curves.new(name='Curve', type='CURVE')
        curvedata.dimensions = '3D'

        objectdata = bpy.data.objects.new("CenterLine", curvedata)      # ObjCurve
        objectdata.location = (0,0,0)                                   # object origin
        bpy.context.scene.objects.link(objectdata)

        polyline = curvedata.splines.new('NURBS')       #options:: BSPLINE  POLY  BEZIER  NURBS
        polyline.points.add(len(center_line_array)-1)
        for num in range(len(center_line_array)):
            x, y, z = center_line_array[num]
            polyline.points[num].co = (x, y, z, w)
                
        return {'FINISHED'}

    def invoke(self, context, event):
        context.window_manager.fileselect_add(self)
        return {'RUNNING_MODAL'}


# Only needed if you want to add into a dynamic menu
def menu_func(self, context):
    self.layout.operator_context = 'INVOKE_DEFAULT'
    self.layout.operator(ImportSomeData.bl_idname, text="GPS Visualizer Text File")


# Register and add to the file selector
bpy.utils.register_class(ImportSomeData)
bpy.types.INFO_MT_file_import.append(menu_func)