Created
September 9, 2011 12:39
-
-
Save roryf/1206103 to your computer and use it in GitHub Desktop.
Processing code I used to generate http://vimeo.com/28706322
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
import org.json.*; | |
import java.net.*; | |
import java.util.Iterator; | |
import processing.video.*; | |
PImage bg; | |
MovieMaker mm; | |
JSONObject data; | |
double west = -3.414001; | |
double east = -3.017120; | |
double north = 56.002605; | |
double south = 55.882629; | |
double longDiff = east - west; | |
double latDiff = north - south; | |
int width = 720; | |
int height = 389; | |
int frameRate = 60; | |
int videoFrameRate = 30; | |
int minutesPerFrame = 5; | |
JSONObject pullJSON(String targetURL) { | |
String[] lines = loadStrings(targetURL); | |
try { | |
return new JSONObject(join(lines, "")); | |
} catch(JSONException ex) { | |
println(ex.getMessage()); | |
return null; | |
} | |
} | |
Map minutes = new LinkedHashMap(); | |
PFont font; | |
Date current = null; | |
long now = Long.MAX_VALUE; | |
void setup() { | |
frameRate(frameRate); | |
data = pullJSON("http://my.couchdb.server/festival/_design/output/_view/geo?startkey=1312758000&endkey=1315177200"); | |
bg = loadImage("wire-map.png"); | |
now = Calendar.getInstance().getTimeInMillis(); | |
font = loadFont("Digital-7Mono-48.vlw"); | |
textFont(font, 24); | |
size(width, height); | |
try { | |
JSONArray rows = data.getJSONArray("rows"); | |
for (int i = 0, l = rows.length(); i < l; i++) { | |
JSONObject row = rows.getJSONObject(i); | |
Date key = new Date(row.getLong("key")*1000); | |
JSONObject val = row.getJSONArray("value").getJSONObject(0); | |
if (minutes.containsKey(key)) { | |
((ArrayList)minutes.get(key)).add(val); | |
} else { | |
ArrayList vals = new ArrayList(); | |
vals.add(val); | |
minutes.put(key, vals); | |
} | |
if (current == null) { | |
current = key; | |
} | |
} | |
} catch(JSONException ex) { | |
println(ex.getMessage()); | |
} | |
mm = new MovieMaker(this, width, height, "output.mov", videoFrameRate, MovieMaker.VIDEO, MovieMaker.HIGH); | |
} | |
public class Spot { | |
private int x; | |
private int y; | |
private int colour; | |
private int size; | |
public Spot(int x, int y, int colour) { | |
this.x = x; | |
this.y = y; | |
this.colour = colour; | |
this.size = 15; | |
} | |
public void draw() { | |
radialGradient(x, y, colour, size); | |
size -= 1; | |
} | |
public boolean finished() { | |
return size == 0; | |
} | |
} | |
HashSet liveSpots = new HashSet(); | |
void loadSpots() { | |
ArrayList rows = (ArrayList)minutes.get(current); | |
if (rows != null) { | |
try { | |
for (int i = 0, l = rows.size(); i < l; i++) { | |
JSONObject val = (JSONObject)rows.get(i); | |
double lat = val.getDouble("lat"); | |
double lon = val.getDouble("lon"); | |
int x = (int)(((west - lon) / longDiff) * width) * -1; | |
int y = (int)(((north - lat) / latDiff) * height); | |
String source = val.getString("source"); | |
int colour = 0; | |
if (source.equals("twitter")) { | |
colour = 0xFF2AA9D4; | |
} else if (source.equals("gowalla")) { | |
colour = 0xFFF79120; | |
} else if (source.equals("flickr")) { | |
colour = 0xFFFF0084; | |
} | |
Spot newSpot = new Spot(x, y, colour); | |
liveSpots.add(newSpot); | |
} | |
} catch (JSONException ex) { | |
println(ex.getMessage()); | |
} | |
} | |
} | |
void incrementCurrentTime() { | |
Calendar calendar = Calendar.getInstance(); | |
calendar.setTime(current); | |
calendar.add(Calendar.MINUTE, 1); | |
current = calendar.getTime(); | |
} | |
void draw() { | |
background(bg); | |
Date frameStartTime = current; | |
for (int i = 0; i < minutesPerFrame; i++) { | |
loadSpots(); | |
incrementCurrentTime(); | |
} | |
Iterator spots = liveSpots.iterator(); | |
ArrayList toRemove = new ArrayList(); | |
while (spots.hasNext()) { | |
Spot spot = (Spot)spots.next(); | |
spot.draw(); | |
if (spot.finished()) { | |
toRemove.add(spot); | |
} | |
} | |
for (int i = 0, l = toRemove.size(); i < l; i++) { | |
liveSpots.remove(toRemove.get(i)); | |
} | |
text(frameStartTime.toString(), 50, 350); | |
mm.addFrame(); | |
if (liveSpots.size() == 0 && current.getTime() > (1315177200000L)) { | |
mm.finish(); | |
text("finished", 500, 300); | |
} | |
} | |
void keyPressed() { | |
if (key == ' ') { | |
mm.finish(); // Finish the movie if space bar is pressed! | |
} | |
} | |
void radialGradient(float x, float y, int c, int size) { | |
PGraphics pg = createGraphics(size, size, JAVA2D); | |
pg.beginDraw(); | |
pg.background(30, 0); | |
int halfsize = size / 2; | |
for (int i = 0; i <= size; i += 1) { | |
for (int j = 0; j <= size; j += 1) { | |
// calculate distance to center | |
//float distance = (float) Math.hypot(i - size / 2, j - size / 2) / (size / 2); | |
//float distance = (float) sqrt(sq(i-size/2) + sq(j-size/2)) / (size/2); | |
float xDist = i - halfsize; | |
float yDist = j - halfsize; | |
float distance = (float) Math.sqrt(xDist*xDist + yDist*yDist) / halfsize; | |
float scale = 1 - distance; | |
if (scale < 0 ) { | |
scale = 0; | |
} | |
float transparency = 255 * (scale * scale); | |
int thisColour = color(c, int(transparency)); | |
pg.set(i, j, thisColour); | |
} | |
} | |
pg.endDraw(); | |
imageMode(CENTER); | |
image(pg, x, y); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment