#include "database.h" #include node database::get_node(const unsigned long long & ull_id) { pqxx::result r=txn.prepared("get_node")(ull_id).exec(); if(r.size()==0) { fprintf(stdout,"\n# fatal error: missing node %llu\n",ull_id); fflush(stdout); write_state(21); abort(); } double d_lon = r[0][0].as(); double d_lat = r[0][1].as(); double d_height = r[0][2].as(); node n_result(ull_id,d_lon,d_lat,d_height); return(n_result); } unsigned int database::get_state() { char z_req[1024]; snprintf(z_req,1024,"SELECT state FROM rv_jobs WHERE jid=%u;",jid); pqxx::result res=txn.exec(z_req); return(res[0][0].as()); } void database::write_state(unsigned int state) { pqxx::work txnw(dbw); char z_req[1024]; snprintf(z_req,1024,"UPDATE rv_jobs SET state=%u WHERE jid=%u;",state,jid); txnw.exec(z_req); txnw.commit(); } void database::write_pid() { pqxx::work txnw(dbw); char z_req[1024]; snprintf(z_req,1024,"UPDATE rv_jobs SET pid=%u WHERE jid=%u;",getpid(),jid); txnw.exec(z_req); txnw.commit(); } void database::write_status(double status) { pqxx::work txnw(dbw); char z_req[1024]; snprintf(z_req,1024,"UPDATE rv_jobs SET status=%f WHERE jid=%u;",status,jid); txnw.exec(z_req); txnw.commit(); } void database::write_results(std::list lI, double puissance) { pqxx::work txnw(dbw); unsigned int rank=0; char z_req[1024]; for(std::list::iterator it=lI.begin(); it!=lI.end(); it++) { snprintf(z_req,1024,"INSERT INTO rv_results (jid,rank,height,speed,dist,cum_elev,energy,time,node_id,way_id,geom) VALUES (%u,%u,%f,%f,%f,%f,%f,%f,%u,%u,'SRID=4326;POINT(%.8f %.8f)'::geometry);", jid, rank++, it->d_height, it->d_V, it->d_dist, it->d_deniv_pos, it->d_ET, it->d_ET/puissance, it->ull_id, it->ull_way_from_id, it->d_lon, it->d_lat); txnw.exec(z_req); } instant If = *(lI.rbegin()); snprintf(z_req,1024,"UPDATE rv_jobs SET (cum_elev,energy,dist,mean_speed,time)=(%f,%f,%f,%f,%f) WHERE jid=%u;", If.d_deniv_pos, If.d_ET, If.d_dist, If.d_dist*puissance/If.d_ET, If.d_ET/puissance, jid); txnw.exec(z_req); txnw.commit(); } bool database::find_nodes(std::list & lull_id) { char z_req[1024]; snprintf(z_req,1024,"SELECT ST_X(geom),ST_Y(geom) FROM rv_waypoints WHERE jid=%u ORDER BY rank;",jid); pqxx::result res = txn.exec(z_req); std::list< std::pair > l_points; for(pqxx::result::iterator it=res.begin(); it!=res.end(); it++) { l_points.push_back(std::pair(it[0].as(),it[1].as())); } // On trouve la cc unsigned long long ull_begin, ull_end; unsigned long long ull_begin_cc, ull_end_cc; double dist_begin, dist_end; unsigned long long ull_cc; if(!find_one_node(*(l_points.begin()),false,0,ull_begin,ull_begin_cc,dist_begin)) return false; if(!find_one_node(*(l_points.rbegin()),false,0,ull_end,ull_end_cc,dist_end)) return false; if(ull_begin_cc==ull_end_cc) { ull_cc=ull_begin_cc; } else { unsigned long long ull_begin_oth, ull_end_oth; double dist_begin_oth, dist_end_oth; unsigned long long ull_cc_poubelle; bool b1, b2; b1=find_one_node(*(l_points.begin()),true,ull_end_cc,ull_begin_oth,ull_cc_poubelle,dist_begin_oth); b2=find_one_node(*(l_points.rbegin()),true,ull_begin_cc,ull_end_oth,ull_cc_poubelle,dist_end_oth); if(b1) { if(b2) { if(dist_begin+dist_end_oth < dist_begin_oth+dist_end) { ull_cc = ull_begin_cc; ull_end = ull_end_oth; } else { ull_cc = ull_end_cc; ull_begin = ull_begin_oth; } } else { ull_cc = ull_end_cc; ull_begin = ull_begin_oth; } } else { if(b2) { ull_cc = ull_begin_cc; ull_end = ull_end_oth; } else { return false; } } } std::list< std::pair >::iterator it=l_points.begin(); while(it!=l_points.end()) { unsigned long long id; std::pair & P = *it; bool ok=false; if(it==l_points.begin()) { id=ull_begin; ok=true; } it++; if(it==l_points.end()) { id=ull_end; ok=true; } if(!ok) { double dist_poubelle; unsigned long long ull_cc_poubelle; if(!find_one_node(P,true,ull_cc,id,ull_cc_poubelle,dist_poubelle)) return(false); } lull_id.push_back(id); } return(true); } bool database::find_one_node(std::pair P, bool respect_cc, unsigned long long ull_cc, unsigned long long & ull_result_id, unsigned long long & ull_result_cc, double & dist) { double diam = 0.013; double & d_lon = P.first; double & d_lat = P.second; char z_req[1024]; if(respect_cc) snprintf(z_req,1024,"SELECT id,cc,ST_Distance(geom,'POINT(%.8f %.8f)'::geography) AS d FROM rv_nodes WHERE geom && ST_Expand('SRID=4326;POINT(%.8f %.8f)'::geometry,%f) AND cc=%llu ORDER BY d LIMIT 1;",d_lon,d_lat,d_lon,d_lat,diam,ull_cc); else snprintf(z_req,1024,"SELECT id,cc,ST_Distance(geom,'POINT(%.8f %.8f)'::geography) AS d FROM rv_nodes WHERE geom && ST_Expand('SRID=4326;POINT(%.8f %.8f)'::geometry,%f) ORDER BY d LIMIT 1;",d_lon,d_lat,d_lon,d_lat,diam); pqxx::result res = txn.exec(z_req); if(res.size()>0) { ull_result_id = res[0][0].as(); ull_result_cc = res[0][1].as(); dist = res[0][2].as(); return true; } return false; } model database::get_model() { char z_req[1024]; snprintf(z_req,1024,"SELECT criterion,speedref,mass,cr,scx,rho,winddir,windspeed FROM rv_jobs WHERE jid=%u LIMIT 1;",jid); pqxx::result res = txn.exec(z_req); if(res.size()==0) { fprintf(stderr,"jid %u not found\n",jid); abort(); } char c_model_type=(res[0][0].c_str())[0]; double d_VplatKMH=res[0][1].as(); double d_masse=res[0][2].as(); double d_Cr=res[0][3].as(); double d_SCx=res[0][4].as(); double d_rho_air=res[0][5].as(); double d_vent_from_deg=res[0][6].as(); double d_vent_VKMH=res[0][7].as(); return model(c_model_type,d_VplatKMH,d_masse,d_Cr,d_SCx,d_rho_air,d_vent_from_deg,d_vent_VKMH); } std::pair database::get_edge(const unsigned long long & ull_from, const unsigned long long & ull_to) { char z_req[1024]; snprintf(z_req,1024,"SELECT way_id,version FROM rv_edges INNER JOIN ways ON ways.id=rv_edges.way_id WHERE from_id=%lld AND to_id=%lld;",ull_from,ull_to); pqxx::result r=txn.exec(z_req); if(r.size()==0) { fprintf(stdout,"\n# fatal error: missing edge (%llu,%llu)\n",ull_from,ull_to); fflush(stdout); write_state(22); abort(); } unsigned long long ull_id_way = r[0][0].as(); unsigned int ui_rev = r[0][1].as(); return(std::pair(ull_id_way,ui_rev)); } std::list database::get_adjoining(const unsigned long long & ull_id) { pqxx::result r=txn.prepared("get_adj")(ull_id).exec(); std::list lull_adj; for(pqxx::result::iterator it=r.begin();it!=r.end();it++) { lull_adj.push_back(it[0].as()); } return(lull_adj); }