Last active
July 10, 2020 12:39
-
-
Save thomascorrie/9378502 to your computer and use it in GitHub Desktop.
Redundant now that OpenPaths is no longer active. Processing script to create map from OpenPaths csv file using Ordnance Survey coordinates. Requires Jcoord 1.0 and Java SimpleDateFormat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// PREREQUISITES | |
// Requires Jcoord 1.0 http://www.jstott.me.uk/jcoord/api/1.0/ | |
// and Java SimpleDateFormat http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html | |
// Requires the following csv files | |
// openpaths.csv | |
// csv exported from OpenPaths | |
// select.csv | |
// Name Left Right Bottom Top Width | |
// London 520000 540000 174000 190000 1000 | |
// Britain 0 700000 0 1000000 700 | |
// Allows different areas to be selected. The coordinates are OS grid references measured in metres from the false origin. Width is width of desired image in pixels. | |
// omit.csv | |
// Simple list of openpath points to omit (for gps noise etc) in the A:A column. Can be empty but is required to exist | |
// Requires folder within sketch folder called "output" for saving final images | |
// Requires "background" folder containing background images for each of the select options, i.e. London.jpg for London setup | |
// SET VARIABLES | |
int selectNum = 1; //1 for London, 2 for Britain, 3 for South East etc | |
String[] select; | |
//DOTS OR LINES? | |
int format = 0; //0 for dots, 1 for lines between points | |
int mode = 0; //0 for normal, 1 for debug // Debug mode shows the gps point numbers and shows omitted points | |
//CHOOSE START AND END DATES | |
String dsStart = "2013-01-01 00:00:00"; //Start Date | |
String dsEnd = "2013-12-31 23:59:59"; //End Date | |
//CHOOSE COLOURS | |
color ln = color(240,240,240,40); //color(240,240,240,40); | |
color grid = color(255,0,0,50); //color(230,230,230,20); | |
color txt = color(220,220,220,255); //color(255,255,255,80); | |
color txtd = color(220,0,0,255); //color(255,255,255,80); | |
color back = color(100,100,100); //color(75,70,70); | |
//Import Utilities | |
import java.util.*; | |
import java.text.*; | |
import java.text.SimpleDateFormat; | |
//DATES | |
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |
Date dDate; | |
Date dStart; | |
Date dEnd; | |
int numFrame; | |
//Data | |
String[] data; | |
int[] omit; | |
//Image | |
PImage b; | |
//Map | |
float mapGeoLeft; | |
float mapGeoRight; | |
float mapGeoBottom; | |
float mapGeoTop; | |
float mapScreenWidth,mapScreenHeight; // Dimension of map in pixels. | |
String selectN; | |
//SETUP | |
void setup() { | |
//SELECT | |
select = loadStrings("select.csv"); //Load locations | |
String[] selectF = splitTokens(select[selectNum],","); | |
//Map Size | |
mapGeoLeft = int(selectF[1]); //Longitude West | |
mapGeoRight = int(selectF[2]); //Longitude East | |
mapGeoBottom = int(selectF[3]); //Latitude South | |
mapGeoTop = int(selectF[4]); //Latitude North | |
selectN = selectF[0]; | |
//DATES | |
try { | |
dStart = df.parse(dsStart); | |
println(dStart); | |
} | |
catch(ParseException e) { | |
println(e); | |
} | |
try { | |
dEnd = df.parse(dsEnd); | |
println(dEnd); | |
} | |
catch(ParseException e) { | |
println(e); | |
} | |
//Format Dates | |
String dStartY = new SimpleDateFormat("yy").format(dStart); | |
String dEndY = new SimpleDateFormat("yy").format(dEnd); | |
String dStartM = new SimpleDateFormat("MMM").format(dStart); | |
String dEndM = new SimpleDateFormat("MMM").format(dEnd); | |
String dStartD = new SimpleDateFormat("dd").format(dStart); | |
String dEndD = new SimpleDateFormat("dd").format(dEnd); | |
String dFormat; | |
if (dStartY.equals(dEndY) == true) { | |
if (dStartM.equals(dEndM) == true) { | |
if (dStartD.equals(dEndD) == true) { | |
dFormat = dEndD+" "+dEndM.toUpperCase()+" "+dEndY; //One Day | |
} else { | |
dFormat = dStartD+" - "+dEndD+" "+dEndM.toUpperCase()+" "+dEndY; //One Month | |
} | |
} else { | |
dFormat = dStartD+" "+dStartM.toUpperCase()+" - "+dEndD+" "+dEndM.toUpperCase()+" "+dEndY; //One Year | |
} | |
} else { | |
dFormat = dStartD+" "+dStartM.toUpperCase()+" "+dStartY+" - "+dEndD+" "+dEndM.toUpperCase()+" "+dEndY; | |
} | |
//Image Setup | |
int xWidth = int(selectF[5]); | |
int yHeight = int((xWidth/(mapGeoRight-mapGeoLeft))*(mapGeoTop-mapGeoBottom)); //int((mapGeoTop-mapGeoBottom)*scaleMap); | |
size(xWidth,yHeight); | |
smooth(); | |
background(back); | |
mapScreenWidth = width; | |
mapScreenHeight = height; | |
frameRate(30); | |
data = loadStrings("openpaths.csv"); //Load locations | |
omit = int(loadStrings("omit.csv")); //Load Omissions | |
numFrame = data.length; | |
b = loadImage("backgrounds/"+selectF[0]+".jpg"); | |
image(b, 0, 0); | |
//Fonts | |
PFont font; | |
font = loadFont("Pixel_Caps-8.vlw"); | |
fill(txt); | |
textFont(font); | |
text("MY MOVEMENT AROUND "+selectF[0].toUpperCase(), 5, 10, 400, 200); | |
text(dFormat, 5, 20, 400, 200); | |
text(str(int(mapGeoLeft))+" E", 5, height-20, 50, 200); | |
text(str(int(mapGeoBottom))+" N", 5, height-10, 50, 200); | |
textAlign(RIGHT); | |
text(str(int(mapGeoRight))+" E", width-5-50, 10, 50, 200); | |
text(str(int(mapGeoTop))+" N", width-5-50, 20, 50, 200); | |
text("BY THOMAS CORRIE / RECORDED USING OPENPATHS.CC / BUILT WITH PROCESSING", width-5-500, height-20, 500, 200); | |
text("CONTAINS ORDNANCE SURVEY DATA (C) CROWN COPYRIGHT AND DATABASE RIGHT 2011", width-5-500, height-10, 500, 200); | |
} | |
//DRAW | |
void draw() { | |
//Draw vectors | |
noFill(); | |
stroke(ln); | |
strokeWeight(2.0); | |
PVector p1 = new PVector(0,0); | |
PVector p2 = new PVector(0,0); | |
int omitSwitch = 0; | |
noLoop(); | |
int omitCount = 0; | |
int startCount = 0; | |
for (int i=1;i<numFrame;i++) { | |
String[] pieces2 = splitTokens(data[i],","); | |
try { | |
dDate = df.parse(pieces2[3]); | |
} | |
catch(ParseException e) { | |
println(e); | |
} | |
if(dDate.after(dStart) && dDate.before(dEnd)) { | |
if (startCount == 0) { | |
//Point 1 | |
String[] pieces1 = splitTokens(data[i-1],","); | |
float x1 = float(pieces1[1]); | |
float y1 = float(pieces1[0]); | |
p1 = geoToPixelOSGB(new PVector(x1,y1)); | |
if (i > omit[omit.length-1]) { | |
println(omit[omit.length-1]); | |
omitSwitch = 1; | |
} else if (i > omit[omitCount]) { | |
while (i > omit[omitCount] && omitCount < omit.length-1) { | |
omitCount++; | |
} | |
} | |
} | |
//Point 2 | |
float x2 = float(pieces2[1]); | |
float y2 = float(pieces2[0]); | |
p2 = geoToPixelOSGB(new PVector(x2,y2)); | |
if (omitSwitch == 1 || (omitCount+1 > omit.length) || i < omit[omitCount]) { | |
if (mode == 1) { //debug | |
textAlign(LEFT); | |
text(str(i), p2.x, p2.y, 400, 200); | |
} | |
if (format == 1) { | |
line(p1.x,p1.y,p2.x,p2.y); | |
} else { | |
noStroke(); | |
fill(ln); | |
ellipse(p2.x,p2.y,5,5); | |
} | |
p1 = new PVector(p2.x,p2.y); //Send this point to next | |
} else if (i == omit[omitCount]) { | |
omitCount += 1; | |
if (mode == 1 /*&& int(dHour) < 8*/) { //debug | |
textAlign(LEFT); | |
fill(txtd); | |
text(str(i), p2.x, p2.y, 400, 200); | |
fill(txt); | |
} | |
} | |
startCount += 1; | |
} | |
} | |
//Save image | |
if (format == 1) { | |
save("output/"+selectN+"_image_lines.gif"); //Save lines | |
} else { | |
save("output/"+selectN+"_image_dots.gif"); //Save dots | |
} | |
} | |
// Adapted from code posted to http://forum.processing.org/one/topic/using-a-world-map-in-processing.html | |
// Converts geographical coordinates into screen coordinates. | |
// Useful for drawing geographically referenced items on screen. | |
public PVector geoToPixel(PVector geoLocation) | |
{ | |
return new PVector(mapScreenWidth*(geoLocation.x-mapGeoLeft)/(mapGeoRight-mapGeoLeft), | |
mapScreenHeight - mapScreenHeight*(geoLocation.y-mapGeoBottom)/(mapGeoTop-mapGeoBottom)); | |
} | |
// Converts geographical coordinates from WGS84 to OS Ref and into screen coordinates. | |
public PVector geoToPixelOSGB(PVector geoLocation) | |
{ | |
LatLng LL = new LatLng(geoLocation.y,geoLocation.x); | |
LL.toOSGB36(); | |
OSRef OS = LL.toOSRef(); | |
return new PVector(mapScreenWidth*((float)OS.getEasting()-mapGeoLeft)/(mapGeoRight-mapGeoLeft), | |
mapScreenHeight - mapScreenHeight*((float)OS.getNorthing()-mapGeoBottom)/(mapGeoTop-mapGeoBottom)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment