Sketch using data from an online XML-feed works in Processing, but not online

edited April 2017 in JavaScript Mode

Hi,

I made a sketch (based on Langton's ant) that uses some values from openweathermap to determine colours and framerate. Now, I've tried to run this sketch on my localhost (using processing.js), but it's not working at all, I just get a white page without anything on it.

I have tried to do the same thing with a different version of the sketch which doesn't use any external data and it works just fine.

Is it even possible to run a sketch online which uses data from an external online source, or is there just something wrong with my code? (it works fine when I run in it Processing). Could it have something to do with Same Origin Policy?

This is my code:

XML weather;

float temperature;
float temperaturemin;
float temperaturemax;
float humidity;

float R = map(temperature, -5, 30, 1, 255);
float B = map(temperaturemin, -10, 25, 1, 255);
float G = map(temperaturemax, -5, 35, 1, 255);

int red = int(R);
int blue = int(B);
int green = int(G);

int NORTH = 0;
int NORTHEAST = 1;
int EAST = 2;
int SOUTHEAST = 3;
int SOUTH = 4;
int SOUTHWEST = 5;
int WEST = 6;
int NORTHWEST = 7;
int direction = EAST;
int x, y;

void setup() {
  weather = loadXML("http://api.openweathermap.org/data/2.5/weather?q=Ghent&units=metric&mode=xml&APPID=a1733d89395ba83cdac17f9368ac6e97");

  XML temp = weather.getChild("temperature");
    temperature = temp.getFloat("value");
    temperaturemin = temp.getFloat("min");
    temperaturemax = temp.getFloat("max");

  XML humid = weather.getChild("humidity");
    humidity = humid.getFloat("value"); 

  String gent = "Huidige temperatuur in Gent:";
  String max = "Maximumtemperatuur:";
  String min = "Minimumtemperatuur:";
  String vocht = "Luchtvochtigheid:";
  String graden = "°C";
  String procent = "%";

  println(gent, temperature, graden);
  println(min, temperaturemin, graden);
  println(max, temperaturemax, graden);
  println(vocht, humidity, procent);

  //size(500, 300);
  x = width/2;
  y= height/2;
  background(0);
  fullScreen();
  noCursor();
}

void draw() {
  frameRate(humidity);
  color ON = color(red, blue, green);
  color UNDEAD = color(red, green, blue);
  if (direction == NORTH) {
    if (y == 0) {
      y = height-1;
     } else {
       y--;
     }
  } else if (direction == NORTHEAST) {
    x++;
      if (x == width) {
        x = 0;
      }
    if (y == 0) {
      y = height-1;
     } else {
       y--;
     }
  } else if (direction == EAST) {
    x++;
    if (x == width) {
      x = 0;
     }
  } else if (direction == SOUTHEAST) {
    x++;
      if (x == width) {
        x = 0;
       }
    y++;
      if (y == height) {
        y = 0;
      }
  } else if (direction == SOUTH) {
    y++;
    if (y == height) {
      y = 0;
    }
  } else if (direction == SOUTHWEST) {
    if (x == 0) {
      x = width-1;
    } else {
      x--;
    }
    y++;
      if (y == height) {
        y = 0;
      }
  } else if (direction == WEST) {
    if (x == 0) {
      x = width - 1;
    } else {
      x--;
    }
  } else if (direction == NORTHWEST) {
    if (x == 0) {
      x = width - 1;
    } else {
      x--;
    }
    if (y == 0) {
      y = height - 1;
    } else {
      y--;
    }
  }

  if (get(x, y) == ON) {
    set(x, y, UNDEAD);
      if (direction == NORTH) {
        direction = NORTHWEST;
      } else {
        direction--;
      }  
  } else {
    set (x, y, ON);
      if (direction == NORTHWEST) {
        direction = NORTH;
      } else {
        direction++;
      }
    }
  } 

Thanks!!

Answers

  • @Vulpix91 -- Do you get an error, and if so, what?

    Does Processing.js even support the Processing(Java) loadXML() function? When quickly checking the reference I found this instead:

  • I get an XML parsing error in my browser ("XML parsing error: not well formed"), as well as "TypeError: temp is null". Other than that, just a blank page.

    And yes, I tried that, but I get an error in Processing ("The class 'XMLElement' does not exist") and the code won't run.

  • And yes, I tried that, but I get an error in Processing

    Are you using "Javascript Mode" in Processing? What version of the Processing IDE, and what version of Javascript mode is installed?

    I'm not sure if it matters / should matter, but the XML file syntax is correct -- however it does not have a DTD:

  • Try this as a first kick. Remove the link line and load this data manually:

     String xdata="<current><city id=\"2797656\" name=\"Gent\"><coord lon=\"3.72\" lat=\"51.05\"/><country>BE</country><sun rise=\"2017-04-28T04:22:23\" set=\"2017-04-28T19:03:38\"/></city><temperature value=\"8.59\" min=\"8\" max=\"9\" unit=\"metric\"/><humidity value=\"61\" unit=\"%\"/><pressure value=\"1016\" unit=\"hPa\"/><wind><speed value=\"4.6\" name=\"Gentle Breeze\"/><gusts/><direction value=\"320\" code=\"NW\" name=\"Northwest\"/></wind><clouds value=\"20\" name=\"few clouds\"/><visibility value=\"10000\"/><precipitation mode=\"no\"/><weather number=\"801\" value=\"few clouds\" icon=\"02d\"/><lastupdate value=\"2017-04-28T18:25:00\"/></current>";
      weather = parseXML(xdata);
    

    However it seems the problem is parsing from the XML module. I am thinking you will need to load the data as text, format it properly and then use this code in this post to process it.

    It is Processing.js so there will be some try and error. I am not sure if it is getting any support atm.

    Kf

  • Try this as well. I find that using loadStrings returns a data of size 2. The first slot has the xml header. The second has the actual data. Not sure if putting it together is enough to provide the neede xml structure or if you are missing the tail.

    Notice you could also try json format. Another option to try.

    Kf

    String[] ss=loadStrings("http://"+"api.openweathermap.org/data/2.5/weather?q=Ghent&units=metric&mode=xml&APPID=a1733d89395ba83cdac17f9368ac6e97");
      println("Size is "+ss.length+"\n");  //Prints 2
      println(ss[0]);
      println(ss[1]);
    
      String jstr=join(ss, "");
      weather = parseXML(jstr);
    
  • @kfrajer -- I think that your String xdata example above doesn't quite match the file contents. You have to view source in a browser order to not miss the first line:

    <?xml version="1.0" encoding="UTF-8"?>
  • println(ss[0]); prints that line exactly. This is the reason why I used join() in my last comment. Using loadString is an alternative. He might need to use preload directive: http://processingjs.org/reference/preload/

    Kf

  • edited April 2017

    I have my doubts whether XMLElement is capable of loading remote files under Pjs. :-SS

    IMO, you're better off converting your Java/JS Mode sketch to p5.js and use its loadXML(): *-:)

    1. https://p5js.org/reference/#/p5/loadXML
    2. https://p5js.org/reference/#/p5.XML
    3. https://GitHub.com/processing/p5.js/wiki/Processing-transition
  • edited April 2017

    Are you using "Javascript Mode" in Processing? What version of the Processing IDE, and what version of Javascript mode is installed?

    I can't seem to install JavaScript Mode, as it's currently incompatible with the version of Processing IDE I'm running (3.3.1).

    Try this as well. I find that using loadStrings returns a data of size 2. The first slot has the xml header. The second has the actual data. Not sure if putting it together is enough to provide the neede xml structure or if you are missing the tail.

    Notice you could also try json format. Another option to try.

    Thanks! I'm trying to convert my sketch to p5.js now, if I can't make that work, I'm going to try using loadStrings or using JSON.

    IMO, you're better off converting your Java/JS Mode sketch to p5.js and use its loadXML()

    p5.js is giving me some trouble atm though. I'm trying first to just convert the basic sketch (the version doesn't use any data) into p5.js, but even that doesn't seem to work. I only get the black canvas when I run it. I've read all the resources on how to convert it, so I must be overlooking something. This is what I have right now:

        
    var x;
    var y;
    var ON;
    var UNDEAD;
    var direction;
    
    function setup() {
      createCanvas(1000, 500);
      background(0);
      x = width/2;
      y = height/2;  
      direction = 1;
      ON = color(255, 0, 0);
      UNDEAD = color(0, 255, 0);
    }
    
    function draw() {
      if (direction == 0) {
            if (y == 0) {
                y = height - 1;
            } else {
                y--;
            }
        } else if (direction == 1) {
            x++;
            if (x == width) {
                x = 0;
            }
            if (y == 0) {
                y = height - 1;
            } else {
                y--;
            }
        } else if (direction == 2) {
            x++;
            if (x == width) {
                x = 0;
            }
        } else if (direction == 3) {
            x++;
            if (x == width) {
                x = 0;
            }
            y++;
            if (y == height) {
                y = 0;
            }
        } else if (direction == 4) {
            y++;
            if (y == height) {
                y = 0;
            }
        } else if (direction == 5) {
            if (x == 0) {
                x = width - 1;
            } else {
                x--;
            }
            y++;
            if (y == height) {
                y = 0;
            }
        } else if (direction == 6) {
            if (x == 0) {
                x = width - 1;
            } else {
                x--;
            }
        } else if (direction == 7) {
            if (x == 0) {
                x = width - 1;
            } else {
                x--;
            }
            if (y == 0) {
                y = height - 1;
            } else {
                y--;
            }
        }
       
        if (get(x, y) == ON) {
            set(x, y, UNDEAD);
            if (direction == 0) {
                direction = 5;
            } else {
                direction--;
            }  
        } else {
            set(x, y, ON);
            if (direction == 5) {
                direction = 0;
            } else {
                direction++;
            }
        }
    }    
    
Sign In or Register to comment.