java.lang.NullPointerException
at processing.core.PGraphics.image(PGraphics.java:2829)
at de.fhpotsdam.unfolding.mapdisplay.ProcessingMapDisplay.draw(Unknown Source)
at de.fhpotsdam.unfolding.UnfoldingMap.draw(Unknown Source)
at studying_stream_05E.draw(studying_stream_05E.java:145)
at processing.core.PApplet.handleDraw(PApplet.java:1631)
at processing.core.PApplet.run(PApplet.java:1530)
at java.lang.Thread.run(Thread.java:680)
The offscreen renderer has already been set. Maybe you are calling beginDraw() again before endDraw()?
After some tweaking I start to think that the problem was not Unfolding, but the combination of twitter4j and Unfolding.
So I made a test with only Unfolding part of the code. Stressing the loading of tiles randomly. And bingo, no problem after at least an hour running.
So here is what i think is happening:
The listener of tweeter is a separated thread. I think it is interrupting the drawing of the map (a PGraphics I think) messing with the beginDraw() and endDraw() order. As the code needs some libraries and some keys to run, I'll try to explain how the things are happening:
1. A tweeter stream is created with a listener to tweets with geo location.
2. When a tweet mach, it is added to an ArrayList of a container class i made. This happens inside the listener thread.
3. In draw() I call map.daw() (map is a UnfoldingMap object).
4. Still in draw I'm drawing ellipses over the map at tweets locations, by traversing the ArrayList filled in listener thread.
5. That's pretty much all that is done.
Previously, i was using an image as map, and drawing over it (no Unfolding). Things were working fine. But adding UnfoldingMap, brought this issue.
Also when starting to fiddle with twitter listener a called some drawing stuff from listeners thread and everything went crazy! Kind of cool effects :-) even... But no freeze.
How can i handle this? I've never messed with threads before, but seems that time is up.
The code is below (same from old post, but simplified and cleaner). I have no luck in putting this online yet...
- import org.json.*;
- import processing.opengl.*;
- /// unfolding imports
- import codeanticode.glgraphics.*;
- import de.fhpotsdam.unfolding.*;
- import de.fhpotsdam.unfolding.geo.*;
- import de.fhpotsdam.unfolding.utils.*;
- import de.fhpotsdam.unfolding.providers.Microsoft;
- import de.fhpotsdam.unfolding.providers.OpenStreetMap;
- import de.fhpotsdam.unfolding.providers.Yahoo;
- /// Map
- de.fhpotsdam.unfolding.UnfoldingMap map;
- TwitterStream twitter;
- FilterQuery query;
- PFont font;
- double[][] boundingBox= {
- {
- -180, -90
- }
- , {
- 180, 90
- }
- }; /// whole world;
- float[] seno = new float[360];
- float[] coseno = new float[360];
- ArrayList
happy = new ArrayList (); - void setup() {
- size(1400, 800, GLConstants.GLGRAPHICS);
- smooth();
- font = createFont("Helvetica-bold", 48);
- ////unfolding map stuff
- map = new UnfoldingMap(this);
- map.zoomToLevel(2);
- MapUtils.createDefaultEventDispatcher(this, map);
- //// twitter4j stuff
- //// credentials
- ConfigurationBuilder cb = new ConfigurationBuilder();
- cb.setOAuthConsumerKey("keys here");
- cb.setOAuthConsumerSecret("keys here");
- cb.setOAuthAccessToken("keys here");
- cb.setOAuthAccessTokenSecret("keys here");
- cb.setDebugEnabled(true);
- TwitterStream twitter = new TwitterStreamFactory(cb.build()).getInstance();
- FilterQuery filtro = new FilterQuery();
- filtro.locations(boundingBox);
- twitter.addListener(listener);
- twitter.filter(filtro);
- for (int i = 0; i < seno.length; i++)
- {
- seno[i] = sin(radians(i));
- coseno[i] = cos(radians(i));
- }
- }
- void draw() {
- map.draw();
- fill(0, 120);
- noStroke();
- rect(0, 0, 200, height);
- rect(width - 200, 0, width, height);
- color hapC = color (255, 200, 50);
- for (int i = 0 ; i < happy.size(); i++)
- {
- if (happy.size() > 0)
- {
- fill(hapC);
- happy.get(i).displayGeo(hapC);
- }
- }
- }/// eof draw
- ////////***************************** TWETTER STATUS LISTNER ****************************///////
- StatusListener listener = new StatusListener() {
- public void onStatus(Status status) {
- if (status.getGeoLocation() != null)
- {
- if (status.getText().contains(":)"))
- {
- happy.add(new TweetContainer(status, 10));
- return;
- }
- }
- }
- public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {
- //System.out.println("Got a status deletion notice id:" + statusDeletionNotice.getStatusId());
- }
- public void onTrackLimitationNotice(int numberOfLimitedStatuses) {
- //System.out.print("!!!!!!!!!!!-Got track limitation notice:" + numberOfLimitedStatuses);
- //println(" running for "+ ((millis()-initialTime)/1000) + " seconds");
- }
- public void onScrubGeo(long userId, long upToStatusId) {
- //System.out.println("Got scrub_geo event userId:" + userId + " upToStatusId:" + upToStatusId);
- }
- public void onException(Exception ex) {
- ex.printStackTrace();
- }
- };
- /////////////************** CLASS TWEET CONTAINER ***************///////
- class TweetContainer
- {
- ///......///...... variables holding tw data
- double lat = 0.0;
- double lon = 0.0;
- int iterator = 0;
- float pos;
- TweetContainer(Status s, float _pos)
- {
- pos = _pos;
- GeoLocation g = s.getGeoLocation();
- if (g!=null)
- {
- lat = g.getLatitude();
- lon = g.getLongitude();
- }
- }
- void displayGeo(color c)
- {
- de.fhpotsdam.unfolding.geo.Location loc = new de.fhpotsdam.unfolding.geo.Location(lat, lon);
- PVector vec = map.getScreenPosition(loc);
- fill(255, 80, 30, 120);
- noStroke();
- iterator = (iterator + 5)%seno.length-1;
- int iterator2 = (180+iterator + 5)%seno.length-1;
- ellipse(vec.x + coseno[iterator]*2, vec.y + seno[iterator]*2, 4, 4);
- ellipse(vec.x + coseno[iterator2]*2, vec.y + seno[iterator2]*2, 4, 4);
- noFill();
- stroke(0, 80);
- ellipse(vec.x, vec.y, 10, 10);
- }
- }//.....eofTweetContainer