WIP Calistoga Speedway

4

42Cliff

has anyone explored using a database or find/replace in a spreadsheet? its all text afterall.

getting a new computer soon, 6 gigs of memory should smash the uselessness of several hundred meg text files.

updates await the completion of the new Comp.
 
4

42Cliff

trying to figure out how to use the old heightfield script with full res data ...

since its in python and gdal is in python how would I go about getting the script to use gdal instead of pil as the datasource..

http://www.gdal.org/gdal_tutorial.html
vs.
http://www.pythonware.com/products/pil/




Code:
#!/usr/bin/python

from heightField import *

btb = btbFile('roughTerrain.xml', htScale = 1./1024.)
btb. writeNewFile()
Code:
#!/usr/bin/python
import urllib
import re
import math
import os
import Image

class HtFld(object):
    '''Contains a grid of points'''
    def __init__(self, imageFileName, htScale = None):
        self.img = Image.open(imageFileName)
        self.img.load()
        
        self.width, self.height = self.img.size
        self.scale = (1,1,1)
        self.pos = (0,0,0)
        
        if htScale:
            self.htScale = htScale
        else:
            self.htScale = 1./1024.
        
        
        
    def getElev(self,x,z):
        # '%d %d && %d %d'%(self.scale[0], self.scale[2], self.pos[0], self.pos[2])
        '''return smoothed elevation (and slope?)'''
        nx = x - self.pos[0]        
        nz = z - self.pos[2]        
        #print '%d %d -> %d %d'%(x,z,nx,nz)
        
        nx *= self.width/self.scale[0]
        nz *= self.height/self.scale[2]
        
        nx = min(max(0, nx),self.width-1)
        nz = min(max(0, nz),self.height-1)
        #print '%d %d -> %d %d'%(x,z,nx,nz)
        elev =  self.img.getpixel((nx,nz))
        elev *= self.htScale
        return elev
        

class btbFile(object):
    def __init__(self, filename, htFldImage = None, htScale = None):
        '''htfldImage= None means use the first image you find'''
        self.htFldImage, self.filename, self.htScale = htFldImage, filename, htScale
        self.htFld = None

    def writeNewFile(self, alterTracks = None, outfilename = None):
        if not outfilename:
#            bits = os.path.split(outfilename)
#            bits[-1] = 'new_'+bits[-1]
#            outfilename = os.path.join(bits)
            outfilename = 'new_'+self.filename
            
        '''cheap-ass xml alterer. Changes only list tracks if dict is provided'''
        ''' not at all tolerant of human edited files'''
        re_inbg  = re.compile(r'.*<[Bb]ackgroundImage[\s>]+')
        re_outbg = re.compile(r'.*</[Bb]ackgroundImage[\s>]+')
        re_pathbg = re.compile(r'<Path PathType=".*">([^<]+)</Path>')
        
        re_intrack  = re.compile(r'.*<[Tt]rack[\s>]+')
        re_outtrack = re.compile(r'.*</[Tt]rack[\s>]+')
        
        re_interrain  = re.compile(r'.*<[Tt]errain[Aa]nchor[\s>]+')
        re_outterrain = re.compile(r'.*</[Tt]errain[Aa]nchor[\s>]+')
        
        re_innode  = re.compile(r'.*<[Nn]ode[\s]+[Nn]odeId\s*=\s*"([0-9]+)')
        re_outnode  = re.compile(r'.*</[Nn]ode[\s>]+')
        
        re_name = re.compile(r'.*<[Nn]ame>([^<]+)</')
        re_pos = re.compile(r'.*<Position x="([e\-\.0-9]+)" y="([e\-\.0-9]+)" z="([e\-\.0-9]+)" />')
        re_scale = re.compile(r'.*<Scale x="([e\-\.0-9]+)" y="([e\-\.0-9]+)" z="([e\-\.0-9]+)" />')
        re_buildpos = re.compile(r'(.*<Position\s+x="[e\-\.0-9]+"\s+y=")([e\-\.0-9]+)("\s+z="[e\-\.0-9]+" />.*)')
        print 'Opening '+self.filename
        readfile = open(self.filename,'r')
        print 'Will write to '+outfilename
        writefile = open(outfilename,'w')
        
        inTrack = False
        inNode = False
        inTerrain = False
        inBg = False
        bgPos = None
        bgScale = None
        bgPath = None
        name = None
        nodeId = None
        doAlter = False
        
        npositions = 0
        naltered = 0
        
        for line in readfile.readlines():
            if  re_inbg.search(line):
                #print 'in bg '+line
                inBg = True
                writefile.write(line)
                continue #fast assumption that only one node per line
            
            if  re_outbg.search(line):
                #update the htFiled as we exit the def for it
                bits = os.path.split(bgPath)
                print 'out bg '+bgPath+' '+line
                #make this the htfld if it is the first one we encountered and the user didn;t ask forone
                if (self.htFldImage == None and self.htFld == None) or bits[-1] == self.htFldImage:
                    self.htFld = HtFld(bgPath, htScale = self.htScale)
                    self.htFld.pos = bgPos
                    self.htFld.scale = bgScale
                    
                    
                inBg = False
                bgPath = None
                writefile.write(line)
                continue
                
            if inBg:
                match = re_pathbg.search(line)        
                if match:
                    bgPath = match.group(1)
                    print 'pathbg '+bgPath
                    writefile.write(line)
                    continue
                match = re_pos.search(line)
                if match:
                    x = float(match.group(1))
                    y = float(match.group(2))
                    z = float(match.group(3))
                    bgPos = (x,y,z)
                    #print 'path pos: %f %f %f'%(x,y,z)
                    writefile.write(line)
                    continue
                    
                match = re_scale.search(line)
                if match:
                    x = float(match.group(1))
                    y = float(match.group(2))
                    z = float(match.group(3))
                    bgScale = (x,y,z)
                    #print 'path scale: %f %f %f'%(x,y,z)
                    writefile.write(line)
                    continue        
                    
            if  re_intrack.search(line):
                #print 'in track '+line
                inTrack = True
                writefile.write(line)
                continue #fast assumption that only one node per line
            
            if  re_outtrack.search(line):
                print 'out track '+name+' '+line
                inTrack = False
                name = None
                writefile.write(line)
                continue
            if  re_interrain.search(line):
                #print 'in terrain '+line
                inTerrain = True
                writefile.write(line)
                continue #fast assumption that only one node per line
            
            if  re_outterrain.search(line):
                #print 'out terrain '+line
                inTerrain = False
                writefile.write(line)
                continue
                
            if name == None and inTrack: #only if we are looking for a name
                match = re_name.search(line)
                if match:
                    name = match.group(1)
                    #print 'name: "'+name+'"'
                    writefile.write(line)
                    continue    
                    
            match = re_innode.search(line)        
            if match:
                nodeId = match.group(1)
                #print 'in node '+nodeId
                inNode = True
                writefile.write(line)
                continue #fast assumption that only one node per line
                    
            if  re_outnode.search(line):
                #print 'out node'
                nodeId = None
                inNode = False
                writefile.write(line)
                continue
                        
            if not (inTrack and inNode) and not inTerrain:
                writefile.write(line)
                continue #not interested in any more data until we get in a track and node
                
            match = re_pos.search(line)
            if match:
                x = float(match.group(1))
                y = float(match.group(2))
                z = float(match.group(3))
                
                y = self.htFld.getElev(x,z)
                #print 'new pos: %f %f %f'%(x,y,z)
                npositions += 1
                naltered += 1
                rematch = re_buildpos.search(line)
                newline = '%s%f%s\n'%(rematch.group(1),y,rematch.group(3))
                writefile.write(newline)
                continue
            
            #if nothing else
            writefile.write(line)
                
        writefile.close()
        print 'Found %d positons, altered %d'%(npositions,naltered)
        print 'Wrote to '+outfilename
would also like to modify surfaces with that script but that needs some extra work.. workaround by making parallel tracks and set the surfaces manually in a newer version to match the node heights ..

the other PITA workaround is to use the script as is with terrain where the road is then set the surfaces manually in a newer version to match the node heights ..but untill gdal is the datasource the track has to be made in short segments of elevation change to get the height steps small enough to be worth the bother ..

or someone can figure out how to export a 16bit floating point .png .. for some reason I can't get any programs to export it floating point - though gdal is supposed to be able to do that .. I suppose I'm missing some obscure command line or something.. Oh well .. next month some time the new comp arrives and I'll give it another shot.

I guess I'll try brute force... find and replace or something in a spreadsheet and set it to work till its done ..