Hashtable cities = new Hashtable(); Hashtable countries = new Hashtable(); PImage outline; float lonMin, lonMax, latMin, latMax; PFont font, headline; int mapOffsetX, mapOffsetY; String currentCountry; String[] countryList; Flag[] allFlags; int lastMousePressX, lastMousePressY; void setup() { size(800, 600); smooth(); headline = loadFont("NeutraText-BookAlt-24.vlw"); font = loadFont("Verdana-10.vlw"); outline = loadImage("pa.png"); loadCities(); calcMinMaxLatLon(); loadFlags(); int randomCountryIndex = int(random(0, countryList.length)); currentCountry = countryList[randomCountryIndex]; } void draw() { background(240); textFont(headline, 24); fill(#0578AF); String maintitle = "Do you mean Pennsylvania or"; float maintitleLength = textWidth(maintitle); text(maintitle, 170, 50); fill(#E06D00); text(currentCountry + "?", 170 + maintitleLength + 5, 50); // background graphic mapOffsetX = 50; mapOffsetY = 25; image(outline, mapOffsetX, mapOffsetY); processCities(); processFlags(); } void loadCities() { // load datafile String url = "pamatches_clean_withlatlon.txt"; String[] lines = loadStrings(url); // create a hashtable with the structure [cityname][Location object] // and populate the Location objects from the datafile for (int i = 0; i < lines.length; i++) { String[] thisLine = lines[i].split("\t"); String cityName = thisLine[0]; float lat = float(thisLine[1]); float lon = float(thisLine[2]); String otherCity = thisLine[3]; String otherCountry = thisLine[4]; String other = otherCity + "\t" + otherCountry; Location where = (Location)cities.get(cityName); if (where == null) { // first reference, create a new Location obj cities.put(cityName, new Location(cityName, lat, lon, other)); } else { // additional reference, just add to the "other city" string where.addAnotherLocation(other); } String whereCountry = (String)countries.get(otherCountry); if (whereCountry == null) { countries.put(otherCountry, (String)"counted"); } } } // figure out the min and max for the data void calcMinMaxLatLon() { // first set the minimum arbitrarily high, and the max arbitrarily low. // that way, the first value will replace these values latMin = 100.0; latMax = 0.0; lonMin = 0.0; lonMax = -100.0; // enumerate through the hashtable Enumeration keys = cities.keys(); while ( keys.hasMoreElements() ) { String thisKey = (String)keys.nextElement(); Location thisLocation = (Location)cities.get( thisKey ); float[] latlon = thisLocation.getLatLon(); if (latlon[0] > latMax) latMax = latlon[0]; if (latlon[0] < latMin) latMin = latlon[0]; if (latlon[1] > lonMax) lonMax = latlon[1]; if (latlon[1] < lonMin) lonMin = latlon[1]; } } void loadFlags() { // dump the countres into an array (out of order from the hash) countryList = new String[countries.size()]; int i = 0; Enumeration keys = countries.keys(); while ( keys.hasMoreElements() ) { String thisKey = (String)keys.nextElement(); countryList[i] = thisKey; i++; } // make a sorted list of flag objects to work with in draw() allFlags = new Flag[countries.size()]; countryList = sort(countryList); for (int n=0; n 630) lat -= (textWidth(thisKey) + 8); text(thisKey, lat + 4, lon + 4); //println( thisKey + " " + latlon[0] + "(" + lat + ") ," + latlon[1]); } } } void processFlags() { int x; int y = 450; int w = 0; int multiplier = 0; int leftOffset = 60; int previousWidth = leftOffset; for (int n=0; n 670) { // new row previousWidth = leftOffset; x = 0; multiplier = 1; y += 35; allFlags[n].setPosition(previousWidth, y); allFlags[n].checkState(); allFlags[n].showFlag(previousWidth, y); } else { // continue in this row multiplier++; allFlags[n].setPosition(x, y); allFlags[n].checkState(); allFlags[n].showFlag(x, y); } } } class Flag { PImage flag; String country, flagfile; int x, y; boolean active = false; Flag (String c) { country = c; flagfile = "flags/" + c + ".png"; flag = loadImage(flagfile); } int getWidth() { return flag.width; } void setPosition(int xPos, int yPos) { x = xPos; y = yPos; } void checkState() { if (mouseX >= x && mouseX <= x + flag.width && mouseY >= y && mouseY <= y + flag.height) { if (mousePressed) currentCountry = country; active = true; //println("over: " + country); } else { active = false; } if (country.equals(currentCountry)) active = true; } void showFlag(int x, int y) { image(flag, x, y); if (!active) { fill(255, 180); rect(x, y, flag.width, flag.height); } } } class Location { String cityName; Hashtable otherPlaces = new Hashtable(); float[] latlon = new float[2]; Location (String name, float lat, float lon, String other) { cityName = name; this.addAnotherLocation(other); latlon[0] = lat; latlon[1] = lon; } void addAnotherLocation(String other) { String[] o = other.split("\t"); String otherCity = o[0]; String otherCountry = o[1]; otherPlaces.put(otherCountry, (String)otherCity); } float[] getLatLon() { return latlon; } Hashtable getOtherPlaces() { return otherPlaces; } boolean isInCountry(String c) { String where = (String)otherPlaces.get(c); if (where != null) { return true; } return false; } }