Friday, December 28, 2012

Plotting Some Coordinates

Right, now we have a few bits working we can now move onto doing something half useful.

What we are going to do today is read from a CSV (Comma Separated Value) file that will hold a list of lat and lon coordinates and them plot them on the screen.

The format of the file is

Header row contains the column titles. So
Lat,Lon
Then each line will have lat and lon coordinates from a GPS. So something like


51.89563,-0.161115
51.894412,-0.160428
51.893975,-0.159377
51.894068,-0.157746
51.894121,-0.156845
51.895511,-0.157424
51.897007,-0.158647
51.897961,-0.15942
51.898437,-0.159956
51.898186,-0.1609
51.897669,-0.161952
51.897021,-0.162274
51.896491,-0.161995
51.896107,-0.161544
51.89563,-0.161115

To create the file I just used google maps and plotted a little course round a couple of roads near me and noted down the lat and lon coordinates of each point back to where it started.

Or if you have your RasPi up and running (or your doing this on a laptop) you could use the logger program in a previous post to generate it by firing it up and driving around for a bit. But as mine is stationary at the moment i manually created something.

ok first bit of code gets the libraries we need and sets some variables

#! /usr/bin/python
# Plotting test using pygame
import pygame, sys, os, csv   # Import the pygame, sys and os libraries
from pygame.locals import * # Get pygame constants
pygame.init() # Initialise pygame
screenx = 640 # Size of window
screeny = 480
offsetx = screenx/2 # middle of window
offsety = screeny/2
firstrow = True
          scale = 40000
Next bit sets up our drawing surface, window title and opens the file to get our data

surface=pygame.display.set_mode((screenx,screeny)) # Create a surface to draw on
pygame.display.set_caption('pygame drawng test')# Set the window caption
screen = pygame.display.get_surface()
gps_file = open('gps_test_data.csv','rt') # Open a file to read data from 
 Next bit is where all the magic happens


try: # Read all the lines in
    reader = csv.DictReader(gps_file)
    for row in reader:
        while firstrow: # if this is the firstrow use coords for center
             firstx = int(float(row['lat'])*scale) 
            firsty = int(float(row['lon'])*scale) 
            firstrow = False
            lastx=offsetx
            lasty=offsety
       else:
            x = int(float(row['lat']) * scale)-firstx + offsetx     # make this point middle of the screen
            y = int(float(row['lon']) * scale)-firsty + offsety
            print firstx,firsty, lastx,lasty,x,y
            pygame.draw.line(surface, (0,0,255),(lastx,lasty),(x,y)) # Draw a line
            pygame.display.flip()
            lastx = x
            lasty = y


So bit of explanation is due
reader = csv.DictReader(gps_file)
for row in reader: 
These lines creates a reader object to get data from our file. It uses the csv.DictReader to put the data into a dictionary object. Have a read up in Python about them. The for part loops through the file and executes the next set of statements on them.

        while firstrow: # if this is the firstrow use coords for center
             firstx = int(float(row['lat'])*scale) 
            firsty = int(float(row['lon'])*scale) 
            firstrow = False
            lastx=offsetx
            lasty=offsety
Right the next bit will only execute on the first set of coordinates because we need to get the start point for our first line. To get usable x and y coords in the window range (640x480) we need to multiply the coordinates by our scale. You might need to adjust the scale depending on how far apart your coords are. We also assume that our first coords will be plotted in the middle of the screen, lastx/y.

 else:
            x = int(float(row['lat']) * scale)-firstx + offsetx     # make this point middle of the screen
            y = int(float(row['lon']) * scale)-firsty + offsety
            pygame.draw.line(surface, (0,0,255),(lastx,lasty),(x,y)) # Draw a line
            pygame.display.flip()
            lastx = x
            lasty = y
So, here's what we do for the rest of the lines. We calculate the next x and y coordinates, draw a line from our last coordinates to the new coordinates, display the line on the screen and then we set lastx\y to remember our new last coordinates. And we keep looping round until all the coordinates are plotted. Simples.


Finally:
    gps_file.close()
def input(events): # Function to process pygame events
    for event in events:
        if event.type == QUIT: # If we click ALT+F4 programme will quit
            sys.exit(0)
     
while True: # Keep looping getting events
    input(pygame.event.get())
This last part of the script closes the file when all the coordinates are plotted. Also has the function for the event handler which will loop until we get a quit and then closes the program down.

The full source code can be found on the source code pages.

So if all is working, and you used my test data you should get something like this



 
     



No comments:

Post a Comment