We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello
I'm stuck in a logic problem with an ArrayList of Objects. Here's the deal. I'm coding a dataViz that maps the position of all the buses within the bus sistem. All the buses have a gps that constantly refresh it's coordinates and this data is distributed through an API. The api returns a JSON. The JSON contains an Array of Lines, and each Array of Lines("l") contains an Array of Active vehicles("vs") Initially i recive and parse the JSON and create an Object with each bus that is stored in an ArrayList of buses. it usually receives 11000 buses, in the rush hour increases to 15000 and in down times reduces to 4000. until now i was clearing the ArrayList at every cycle and ot was working fine.
now i need to step a little further. I need to store the X(using 10 now) last coordinates received from the system and display them on the screen. The data is inconsistent, at each cycle there's a little variation in the number of buses returned. I need help in dealing with this inconsistence, add the coordinates to active Buses, adding and removing Bus Objects to the ArrayList when needed. What i did right now just manages the objects built on creation.
Here is the code
import http.requests.*;
ArrayList<Onibus> buses;
PFont busfont;
//comm Variables
String baseURL="http://api.olhovivo.sptrans.com.br/v2.1";
String token="2bc28344ead24b3b5fe273ec7389d2e4d14abd2bad45abe6d8d774026193f894";
String route="7272";
String cookie="";
//storage
JSONObject JSONPosition;
//global Variables
int looper=0;
int ciclo=0;
int carros=0;
int jsonarraySize;
String timestamp="";
int canvasW=3000;
int canvasH=4500;
void setup() {
size(canvasW, canvasH);
frameRate(30);
smooth();
//fonts setup
busfont=createFont("ArialNarrow", 8);
textFont(busfont);
textAlign(CENTER);
//Buses
buses = new ArrayList<Onibus>();
//API Olho Vivo
authentication();
getLinha(route);
getPosition(route);
}
void draw() {
background(0);
for (int i=buses.size ()-1; i>=0; i--) {
Onibus o = buses.get(i);
o.run();
/*
if (o.isDead()) {
buses.remove(i);
}
*/
}
timer();
}
void authentication() {
String reqURL = "/Login/Autenticar?token=";
PostRequest post = new PostRequest(baseURL+reqURL+token);
post.send();
cookie = post.getHeader("Set-Cookie");
println("Reponse Content: " + post.getContent());
println("Cookie: " + cookie);
println("Reponse Content-Length Header: " + post.getHeader("Content-Length"));
}
void getLinha(String linha) {
String reqURL = "/Linha/Buscar?termosBusca=";
GetRequest get = new GetRequest(baseURL+reqURL+linha);
get.addHeader("Cookie", cookie);
get.send();
println("Reponse Content: " + get.getContent());
println("Reponse Content-Length Header: " + get.getHeader("Content-Length"));
}
void getPosition(String linha) {
String reqURL = "/Posicao?codigoLinha=";
GetRequest get = new GetRequest(baseURL+reqURL+linha);
get.addHeader("Content-Type", "application/json");
get.addHeader("Cookie", cookie);
get.send();
int contentSize=int(get.getHeader("Content-Length"));
println("Reponse Content-Length Header: " + contentSize);
timestamp();
//JSON com request
//check received JSON
if (contentSize > 4) {
JSONPosition = parseJSONObject(get.getContent());
processPosition(JSONPosition);
} else {
getPosition(route);
}
}
void processPosition(JSONObject json) {
jsonarraySize=0;
//request timestamp
String busTime = json.getString("hr");
//array de linhas encontradas
JSONArray lineData = json.getJSONArray("l");
//manipula dada obejto encontrado
for (int i=0; i<lineData.size (); i++) {
JSONObject entry = lineData.getJSONObject(i);
JSONArray busData = entry.getJSONArray("vs");
String c = entry.getString("c");
int sentido = entry.getInt("sl");
String lt0 = entry.getString("lt0");
String lt1 = entry.getString("lt1");
for (int j=0; j<busData.size (); j++) {
JSONObject bus=busData.getJSONObject(j);
String prefix= str(bus.getInt("p"));
float px = bus.getFloat("px");
float py = bus.getFloat("py");
PVector coord = new PVector(px, py);
//PROBLEM HERE
if (cycle>0) {
checkBus(c, sentido, lt0, lt1, prefix, busTime, coord);
} else {
createBus(c, sentido, lt0, lt1, prefix, busTime, coord);
}
jsonarraySize++;
}
}
cars=buses.size();
cycle++;
println("cycles: "+cycle);
println("jsonarray: "+jsonarraySize);
println("cars: "+cars);
}
//PROBLEM HERE
void checkBus(String c, int sentido, String lt0, String lt1, String prefix, String busTime, PVector coord) {
for (int i=buses.size ()-1; i>=0; i-- ) {
Onibus o = buses.get(i);
if (o.prefixo.equals(prefix)) {
o.coordenadas.add(coord);
} else if (o.prefixo.equals(null)) {
createBus(c, sentido, lt0, lt1, prefix, busTime, coord);
}
}
}
void createBus(String c, int sentido, String lt0, String lt1, String prefix, String busTime, PVector coord) {
buses.add(new Onibus(c, sentido, lt0, lt1, prefix, busTime, coord));
}
void timer() {
if (frameCount % 30==0) {
saves();
getPosition(route);
}
if (frameCount%1350==0) {
authentication();
}
}
String timestamp() {
String MM=str(month());
String DD=str(day());
String HH=str(hour());
String M=str(minute());
String SS=str(second());
return timestamp = MM+"_"+DD+" - "+HH+"_"+M+"_"+SS;
}
void saves() {
saveFrame("saves/timer/"+timestamp+".png");
}
and here is the Bus Object
class Onibus {
ArrayList<PVector> coordenadas;
String linha;
int sentido;
String letreiroDestino;
String letreiroOrigem;
String letreiro;
String prefixo;
String timestamp;
PVector coordenada;
color[] cor= {
#55AC42, #005792, #FFDD00, #E42A20, #005F49, #0083BB, #782138, #EB6E12, #C6C7C8, #A700FF
};
color linecolor;
boolean isVisible=false;
//limites Geográficos
float GeoNorte=-23.38;
float GeoSul=-24;
float GeoLeste=-46.38;
float GeoOeste=-46.8;
Onibus(String _linha, int _sentido, String lD, String lO, String prfx, String time, PVector _coordenada) {
coordenadas=new ArrayList<PVector>();
linha=_linha;
sentido=_sentido;
letreiroDestino=lD;
letreiroOrigem=lO;
prefixo=prfx;
timestamp = time;
coordenada=_coordenada;
coordenadas.add(coordenada);
}
void run() {
update();
display();
}
boolean isDead() {
if (coordenadas.size()>1) {
return true;
} else {
return false;
}
}
void update() {
if (coordenadas.size()>10) {
coordenadas.remove(0);
}
if (sentido==1) {
letreiro=letreiroDestino;
} else if (sentido==2) {
letreiro=letreiroOrigem;
}
char c=linha.charAt(0);
switch(c) {
case '1':
linecolor=cor[0];
break;
case '2':
linecolor=cor[1];
break;
case '3':
linecolor=cor[2];
break;
case '4':
linecolor=cor[3];
break;
case '5':
linecolor=cor[4];
break;
case '6':
linecolor=cor[5];
break;
case '7':
linecolor=cor[6];
break;
case '8':
linecolor=cor[7];
break;
case '9':
linecolor=cor[8];
break;
case 'N':
linecolor=cor[9];
break;
}
}
void display() {
float bw = textWidth(letreiro)+2;
float lon=0;
float lat=0;
//busão
pushMatrix();
for (PVector c : coordenadas) {
pushMatrix();
lon = map(c.x, GeoOeste, GeoLeste, 0, canvasW);
lat = map(c.y, GeoNorte, GeoSul, 0, canvasH);
noStroke();
fill(linecolor, 32);
translate(lon, lat);
ellipse(0, 0, 4, 4);
popMatrix();
}
if (isVisible) {
pushMatrix();
//rotateX(-HALF_PI);
//Infobox
fill(64,64);
noStroke();
rect(0, -13, bw, 22);
//text
textFont(busfont);
textSize(8);
fill(200);
noStroke();
text(linha, 0, -15);
text(letreiro, 0, -5);
popMatrix();
}
popMatrix();
}
}
thank you
Answers
I think a hashmap would be better than your ArrayList of buses. Use linha as the key. That way you get instant access to any bus. Might make things a bit simpler.
@koogs i'm trying to figure out how to deal with hashmaps in this case. i've never used it before in such complexity.