
Plotting Tweets
Since figuring out how to successfully access the public twitter stream, I’ve been working on importing the map background and plotting tweets on the map based on their individual longitude and latitude values. Initially I was planning on using the Unfolding Maps library, but encountered some problems working with it in combination with Twitter4j, so for the meantime I’ve opted for a jpg background.
Since I’m only using an image as the background, I had to figure out how to accurately plot the tweets onto the map. After a bit of research I found the map() function, which allows me to set the bounding longitude and latitude values of the map background. For example, the left side of the window now has the value of -123.45 instead of defaulting to 0, and the right side of the window has the value of -122.45 instead of the specified width.
By converting the longitude and latitude values from strings to float values, I was successfully able to plot them onto the map.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
//import twitter4j library import twitter4j.util.*; import twitter4j.*; import twitter4j.management.*; import twitter4j.api.*; import twitter4j.conf.*; import twitter4j.json.*; import twitter4j.auth.*; TwitterStream twitterStream; //declare twitterStream PImage mapBackground; //image of map --use until unfolding maps is working ArrayList points; //hold tweets //coordinates of background map in longitude and latitude float w_start = -123.45; // left side float w_end = -122.45;//right side float h_start = 49.49; //top float h_end = 48.99; //bottom //bounding box for vancouver (longitute and latitude) //used to filter twitter results double[][] boundingBox= { { -123.27, 49.195 } , { -123.020, 49.315 } }; Table table; //table to save twitter data to void setup() { size(732, 563); //set as same size as map background image noStroke(); mapBackground = loadImage("colorMap.png"); openTwitterStream(); //start streaming tweets points = new ArrayList(); //setup arraylist of points //format a new table to add twitter data to table = new Table(); table.addColumn("id"); table.addColumn("username"); table.addColumn("content"); table.addColumn("lat"); table.addColumn("lon"); } void draw() { image(mapBackground, 0, 0); //display map background plotPoints(); //plot points to map } void plotPoints() { for (int i=0; i<points.size (); i++) { //iterate through points array list Point p = (Point) points.get(i); float mappedLon = map(p.pLon, w_start, w_end, 0, width); //map longitude values to boundarys visible in map picture float mappedLat = map(p.pLat, h_start, h_end, 0, height); //map latitude values to map pic fill(255, 0, 0); //red fill ellipse(mappedLon, mappedLat, 5, 5); //dot to represent tweet plotted on map } } class Point { //class to hold tweets String pUse; String pCon; float pLat; float pLon; Point(String u, String c, float la, float lo) { pUse = u; pCon = c; pLat = la; pLon = lo; } }//close point class void openTwitterStream() { //codes to access twitter developer account ConfigurationBuilder cb = new ConfigurationBuilder(); cb.setOAuthConsumerKey("XXXXXXXXXXXXXXXXXXX"); //insert from twitter api cb.setOAuthConsumerSecret("XXXXXXXXXXXXXXXXXXX"); //insert cb.setOAuthAccessToken("XXXXXXXXXXXXXXXXXXX"); //insert cb.setOAuthAccessTokenSecret("XXXXXXXXXXXXXXXXXXX"); //insert //listen to twitter stream for incoming tweets TwitterStream twitterStream = new TwitterStreamFactory(cb.build()).getInstance(); twitterStream.addListener(listener); //filter tweets so that we only get ones within our specified area FilterQuery filter = new FilterQuery(); filter.locations(boundingBox); //filter tweets based on bounding box above twitterStream.filter(filter); println("connected"); } // Implementing StatusListener interface //listens for new tweet StatusListener listener = new StatusListener() { //@Override //if there's a tweet matching search query... public void onStatus(Status status) { //pull data from person who posted tweet User user = status.getUser(); GeoLocation loc = status.getGeoLocation(); String username = status.getUser().getScreenName(); String profileLocation = user.getLocation(); String content = status.getText(); //convert geolocation into 2 values --> longitude & latitude String myLon = Double.toString(loc.getLongitude()); String myLat = Double.toString(loc.getLatitude()); //convert longitude and latitude values from char strings to number values float lon = float(myLon); float lat = float(myLat); //if there is a location... if (loc!=null) { int hr = hour(); int mn = minute(); TableRow newRow = table.addRow(); //add a new row to hold this tweet newRow.setInt("id", table.getRowCount()-1); //assign the row an id --> increases each time if (username!=null) { //if username is available newRow.setString("username", username); //add username to username column in table } if (content!=null) { //if the tweet has a message newRow.setString("content", content); //add content to content column in table } newRow.setFloat("lat", lat); //add latitude to latitude column newRow.setFloat("lon", lon); //add longitude to longitude column points.add(new Point (username, content, lat, lon)); //add tweet to array saveTable(table, "data/data.csv"); //save data to table so it can be acccessed later, if needed }// close -- loc isn't null }//close status listener //@Override //print out note if a tweet is deleted public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) { System.out.println("Got a status deletion notice id:" + statusDeletionNotice.getStatusId()); } //@Override public void onTrackLimitationNotice(int numberOfLimitedStatuses) { System.out.println("Got track limitation notice:" + numberOfLimitedStatuses); } //@Override public void onScrubGeo(long userId, long upToStatusId) { System.out.println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId); } //@Override public void onStallWarning(StallWarning warning) { System.out.println("Got stall warning:" + warning); } //@Override public void onException(Exception ex) { ex.printStackTrace(); } }; |
Leave a Reply