Wednesday, 27 February 2019

Python Scripting [3B]: Layer Fractional Segments for NZ Rail Maps 2

Yesterday we looked at how to collect command line parameters easily in a Python script. Today we need to turn the parameters into filenames and then read their contents to memory.

First thing is to get the arguments into variables we can refer to and manipulate. This is pretty simple as the arguments are stored in the args object which as we can see argparse provides us with.

basename = args.base
rightname = args.right
downname = args.down
counter = args.counter
pixelsize = args.pixelsize

We are using a fixed directory for all the files so it's defined here:
rootpath = "/home/patrick/Sources/Segments/"

Then we test the source files exist. I changed my filespec to assume the user has typed in the full file name. They only need to put the name because the directory is fixed and defined above.

basefilename = rootpath + basename
rightfilename = rootpath + rightname
downfilename = rootpath + downname

Then for each file we can read all the contents straight into an object using readlines

basefile = open(basefilename,"r")
basedata = basefile.readlines()
basefile.close()

repeating the same pattern for the other two files. 
In this example basedata is now a list object containing the lines (6 in total) read from the jgw file. The spec of this file is as follows:
  • Line 1: A: x-component of the pixel width (x-scale)
  • Line 2: D: y-component of the pixel width (y-skew)
  • Line 3: B: x-component of the pixel height (x-skew)
  • Line 4: E: y-component of the pixel height (y-scale), typically negative
  • Line 5: C: x-coordinate of the center of the original image's upper left pixel transformed to the map
  • Line 6: F: y-coordinate of the center of the original image's upper left pixel transformed to the map
We write out our target jgw files in the same way. Lines 2 and 3 are copied straight from the base file. Lines 1 and 4 are the pixelsize parameter (which in line 4 has to have a - in front of it). Lines 5 and 6 are generated by our calculations in the script (in part 3 we will look at these calculations).

The result of the readlines() call is to put all the lines in the file into a type of object called a list. A list object is referenced like an array, so I can get the first line in basedata by referencing it like this:

x = basedata[0]

Zero is the number of the first item in the list, so we look at 6 items numbered 0 to 5 in this case.

So far the complete script looks like this:

import argparse

parser = argparse.ArgumentParser(prog='segments')
parser.add_argument('-b', '--base', required=True)
parser.add_argument('-r', '--right', required=True)
parser.add_argument('-d', '--down', required=True)
parser.add_argument('-c', '--counter', type=int, default=4)
parser.add_argument('-p', '--pixelsize', type=float, default=0.1)

args = parser.parse_args()
basename = args.base
rightname = args.right
downname = args.down
counter = args.counter
pixelsize = args.pixelsize

rootpath = "/home/patrick/Sources/Segments/"
basefilename = rootpath + basename
rightfilename = rootpath + rightname
downfilename = rootpath + downname

basefile = open(basefilename, "r")
basedata = basefile.readlines()
basefile.close()
rightfile = open(rightfilename, "r")
rightdata = rightfile.readlines()
rightfile.close()
downfile = open(downfilename, "r")
downdata = downfile.readlines()
downfile.close() 


Part 3 will look at the calculations we need to do in order to get the coordinates of each segment.