Commit 650ca509 authored by jben's avatar jben

debut du front et corrections CC

parent cfa297d3
......@@ -21,10 +21,91 @@ node database::get_node(const unsigned long long & ull_id)
return(n_result);
}
unsigned int database::get_state(unsigned int jid)
{
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<unsigned int>());
}
void database::write_state(unsigned int jid, 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();
}
bool database::find_nodes(std::list< std::pair<double,double> > & l_points, std::list<unsigned long long> & lull_id)
void database::write_status(unsigned int jid, 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(unsigned int jid, std::list<instant> lI, double puissance)
{
pqxx::work txnw(dbw);
unsigned int rank=0;
char z_req[1024];
for(std::list<instant>::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,geom) VALUES (%u,%u,%f,%f,%f,%f,%f,%f,'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->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(unsigned int jid, std::list<unsigned long long> & 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<double,double> > l_points;
for(pqxx::result::iterator it=res.begin(); it!=res.end(); it++)
{
l_points.push_back(std::pair<double,double>(it[0].as<double>(),it[1].as<double>()));
}
// On trouve la cc
unsigned long long ull_begin, ull_end;
......@@ -157,6 +238,35 @@ bool database::find_one_node(std::pair<double,double> P, bool respect_cc, unsign
}
model database::get_model(unsigned int jid)
{
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>();
double d_masse=res[0][2].as<double>();
double d_Cr=res[0][3].as<double>();
double d_SCx=res[0][4].as<double>();
double d_rho_air=res[0][5].as<double>();
double d_vent_from_deg=res[0][6].as<double>();
double d_vent_VKMH=res[0][7].as<double>();
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<unsigned long long, unsigned int> database::get_edge(const unsigned long long & ull_from, const unsigned long long & ull_to)
{
......
......@@ -10,6 +10,8 @@
#include <list>
#include <math.h>
#include "node.h"
#include "model.h"
#include "instant.h"
#define PREC(N) std::setiosflags(std::ios::fixed) << std::setprecision(N) <<
......@@ -18,9 +20,11 @@ class database
public:
pqxx::connection db;
pqxx::work txn;
pqxx::read_transaction txn;
pqxx::connection dbw;
database(const std::string & s_filename) : db(s_filename),txn(db) {
database(const std::string & s_filename) : db(s_filename),txn(db),dbw(s_filename) {
db.prepare("get_node","SELECT ST_X(geom),ST_Y(geom),height FROM rv_nodes WHERE id=$1;")("bigint");
db.prepare("get_adj","SELECT to_id FROM rv_edges WHERE from_id=$1;")("bigint");
}
......@@ -37,7 +41,16 @@ class database
bool find_one_node(std::pair<double,double> P, bool respect_cc, unsigned long long ull_cc, unsigned long long & ull_result_id, unsigned long long & ull_result_cc, double & dist);
bool find_nodes(std::list< std::pair<double,double> > & l_points, std::list<unsigned long long> &);
bool find_nodes(unsigned int jid, std::list<unsigned long long> &);
model get_model(unsigned int jid);
unsigned int get_state(unsigned int jid);
void write_state(unsigned int jid, unsigned int state);
void write_status(unsigned int jid, double status);
void write_results(unsigned int jid, std::list<instant> lI, double puissance);
};
......
#include "route.h"
#include "model.h"
#include "database.h"
#include <getopt.h>
int main(int argc, char* argv[])
{
int c;
std::string s_db;
double d_VplatKMH=20;
double d_masse=80;
double d_SCx=.45;
double d_Cr=.008;
double d_rho_air=1.204;
double d_vent_from=0;
double d_vent_VKMH=0;
char mode='e';
printf("# init\n");
fflush(stdout);
while (1)
if(argc<3)
{
static struct option long_options[] = {
{"database",required_argument, 0, 'd' },
{"speedref",required_argument, 0, 's' },
{"mass", required_argument, 0, 'm' },
{"cr", required_argument, 0, 'C' },
{"scx", required_argument, 0, 'S' },
{"rho", required_argument, 0, 'r' },
{"winddir", required_argument, 0, 'w' },
{"windspeed",required_argument,0, 'W' },
{"criterion",required_argument,0, 'c' },
{0, 0, 0, 0 }
};
int option_index = 0;
c = getopt_long(argc, argv, "d:s:m:C:S:r:w:W:c:",
long_options, &option_index);
if (c == -1)
break;
switch (c)
{
case 0:
if (long_options[option_index].flag != 0)
break;
case 'd':
s_db = optarg;
break;
case 's':
d_VplatKMH = atof(optarg);
if(d_VplatKMH<=0)
abort();
break;
case 'm':
d_masse = atof(optarg);
if(d_masse<=0)
abort();
break;
case 'C':
d_Cr = atof(optarg);
if(d_Cr<0)
abort();
break;
case 'S':
d_SCx = atof(optarg);
if(d_SCx<0)
abort();
break;
case 'r':
d_rho_air = atof(optarg);
if(d_rho_air<0)
abort();
break;
case 'w':
d_vent_from = atof(optarg);
break;
case 'W':
d_vent_VKMH = atof(optarg);
break;
case 'c':
if(std::string(optarg)==std::string("energy"))
mode='e';
else if(std::string(optarg)==std::string("distance"))
mode='d';
else
abort();
break;
}
}
std::list< std::pair<double,double> > l_points;
bool lonoulat=false;
double lon,lat;
if (optind < argc)
{
while (optind < argc)
{
if(lonoulat)
{
lat=atof(argv[optind]);
l_points.push_back(std::pair<double,double>(lon,lat));
}
else
{
lon=atof(argv[optind]);
}
lonoulat=!lonoulat;
optind++;
}
}
if(l_points.size()<2)
{
printf("# fatal error: must have at least 2 points\n");
fflush(stdout);
fprintf(stderr,"Usage incorrect\n");
abort();
}
std::string s_db = argv[1];
database D_db(s_db);
unsigned int jid = atoi(argv[2]);
model m_model(mode,d_VplatKMH,d_masse,d_Cr,d_SCx,d_rho_air,d_vent_from,d_vent_VKMH);
if(D_db.get_state(jid)!=0)
return(1);
printf("# searching\n");
fflush(stdout);
model m_model = D_db.get_model(jid);
D_db.write_state(jid,1); // searching
double d_total_dist_min=0;
std::list<unsigned long long> l_id;
std::list<double> l_dists_min;
{ // to destroy database object
database D_db(s_db);
if(!D_db.find_nodes(l_points, l_id))
return 17;
if(!D_db.find_nodes(jid,l_id))
{
D_db.write_state(jid,17);
return(1);
}
unsigned long long previous=0;
unsigned long long previous=0;
// calcul des distances pour le status
for(std::list<unsigned long long>::iterator it_id=l_id.begin();it_id!=l_id.end();it_id++)
// calcul des distances pour le status
for(std::list<unsigned long long>::iterator it_id=l_id.begin();it_id!=l_id.end();it_id++)
{
if(it_id==l_id.begin())
{
if(it_id==l_id.begin())
{
previous=*it_id;
continue;
}
previous=*it_id;
continue;
}
double d_c=m_model.dist_node(D_db.get_node(*it_id),D_db.get_node(previous));
l_dists_min.push_back(d_c);
d_total_dist_min+=d_c;
double d_c=m_model.dist_node(D_db.get_node(*it_id),D_db.get_node(previous));
l_dists_min.push_back(d_c);
d_total_dist_min+=d_c;
previous=*it_id;
previous=*it_id;
}
}
printf("# routing\n");
fflush(stdout);
D_db.write_state(jid,2); // routing
unsigned long long previous=0;
previous=0;
etat_cycliste e_courant;
int troncon=0;
double d_status_offset=0;
std::list<instant> lI_globalres;
std::list<double>::iterator it_dist_min=l_dists_min.begin();
for(std::list<unsigned long long>::iterator it_id=l_id.begin();it_id!=l_id.end();it_id++)
{
......@@ -191,7 +78,7 @@ int main(int argc, char* argv[])
double d_status_echelle=(*it_dist_min++)/d_total_dist_min;
route r_route(s_db,m_model,previous,*it_id);
route r_route(&D_db,jid,m_model,previous,*it_id);
r_route.set_status(d_status_echelle,d_status_offset);
r_route.set_etat_init(e_courant);
......@@ -206,16 +93,8 @@ int main(int argc, char* argv[])
for(std::list<instant>::iterator it=lI_result.begin();it!=lI_result.end();it++)
{
printf("# node: ");
printf("%i\t",troncon);
printf("%llu\t",it->ull_id);
printf("%f\t%f\t%f\t",it->d_lon,it->d_lat,it->d_height);
printf("%llu\t%lu\t",it->ull_way_from_id,it->ull_way_from_rev);
printf("%f\t%f\t%f\t%f\t%f",it->d_V * 3.6,it->d_dist,it->d_deniv_pos,it->d_ET,it->d_ET/m_model.d_P);
printf("\n");
lI_globalres.push_back(*it);
}
printf("# section: %i\n",troncon);
fflush(stdout);
previous=*it_id;
......@@ -223,6 +102,9 @@ int main(int argc, char* argv[])
}
D_db.write_results(jid,lI_globalres,m_model.d_P);
D_db.write_state(jid,3); // finito
return(0);
}
......
#include "node_parcouru.h"
void node_parcouru::set(unsigned long long ull_id, database & D_db, const node & n_arrivee, const model & m_model)
void node_parcouru::set(unsigned long long ull_id, database* pD_db, const node & n_arrivee, const model & m_model)
{
n_node = D_db.get_node(ull_id);
lull_adj = D_db.get_adjoining(ull_id);
n_node = pD_db->get_node(ull_id);
lull_adj = pD_db->get_adjoining(ull_id);
d_cout_minimal_arrive = m_model.cout_minimal(n_node,n_arrivee);
d_dist_min_arrive = m_model.dist_node(n_node,n_arrivee);
......
......@@ -26,7 +26,7 @@ class node_parcouru
bool defined() {return b_defined;}
void set(unsigned long long ull_id, database & D_db, const node & n_arrivee, const model & m_model);
void set(unsigned long long ull_id, database* pD_db, const node & n_arrivee, const model & m_model);
};
......
......@@ -7,20 +7,20 @@ void route::go()
std::map<unsigned long long,node_parcouru> M_map;
// on aura besoin du node d'arrive
node n_arrivee = D_db.get_node(ull_arrivee);
node n_arrivee = pD_db->get_node(ull_arrivee);
// on commence par le noeud initial
node_parcouru & P_depart = M_map[ull_depart];
P_depart.set(ull_depart,D_db,n_arrivee,m_model);
P_depart.set(ull_depart,pD_db,n_arrivee,m_model);
P_depart.e_etat_cycliste_optimal = e_init;
P_depart.d_cout_minimal = m_model.cout_etat(P_depart.e_etat_cycliste_optimal);
P_depart.ull_from=0;
double d_dist_min_total = P_depart.d_dist_min_arrive;
double d_status;
double d_status=0;
S_queue.push(node_in_queue(ull_depart,P_depart.d_cout_minimal + P_depart.d_cout_minimal_arrive));
......@@ -41,16 +41,12 @@ void route::go()
{
d_status=d_nstatus;
double d_realstatus = .5*(d_status*d_status+d_status)*d_status_echelle+d_status_offset;
printf("# status: %.4f\n",d_realstatus);
fflush(stdout);
pD_db->write_status(jid,d_realstatus);
}
// Si on vient de geler le noeud de fin, on s'arrete la.
if(ull_en_cours == ull_arrivee)
{
// YEAH !
printf("# info : done\n");
fflush(stdout);
break;
}
......@@ -72,7 +68,7 @@ void route::go()
if(!P_voisin.defined())
{
// C'est la premiere fois qu'on touche ce noeud
P_voisin.set(ull_voisin,D_db,n_arrivee,m_model);
P_voisin.set(ull_voisin,pD_db,n_arrivee,m_model);
P_voisin.d_cout_minimal = INFINITY;
}
......@@ -101,8 +97,7 @@ void route::go()
if(!P_arrivee.b_frozen)
{
fprintf(stdout,"# fatal error : graphe non connexe\n");
fflush(stdout);
pD_db->write_state(jid,19);
abort();
}
......@@ -137,7 +132,7 @@ void route::go()
if(it!=lull_chemin.begin())
{
std::pair<unsigned long long,unsigned int> pair = D_db.get_edge(ull_previous_node,*it);
std::pair<unsigned long long,unsigned int> pair = pD_db->get_edge(ull_previous_node,*it);
I.ull_way_from_id=pair.first;
I.ull_way_from_rev=pair.second;
}
......
......@@ -11,12 +11,14 @@
class route
{
unsigned int jid;
unsigned long long ull_depart;
unsigned long long ull_arrivee;
model m_model;
database D_db;
database* pD_db;
std::list<instant> lI_result;
double d_dist_total;
......@@ -30,9 +32,10 @@ class route
double d_status_offset;
public:
route(const std::string & s_db, const model & m_model_i, const unsigned long long & ull_id_1, const unsigned long long & ull_id_2) :
route(database* pD_db_i, unsigned int jid_i, const model & m_model_i, const unsigned long long & ull_id_1, const unsigned long long & ull_id_2) :
jid(jid_i),
m_model(m_model_i),
D_db(s_db) ,
pD_db(pD_db_i) ,
d_dist_total(0),
d_deniv(0),
d_energie(0),
......
BEGIN;
-- rv_jobs
DROP TABLE IF EXISTS rv_jobs;
CREATE TABLE rv_jobs (jid SERIAL CONSTRAINT pk_rv_jobs PRIMARY KEY,
expire TIMESTAMP,
Cr FLOAT CHECK (Cr>0),
SCx FLOAT CHECK (SCx>0),
criterion CHAR(1),
mass FLOAT CHECK (mass>0),
rho FLOAT CHECK (rho>0),
speedref FLOAT CHECK (speedref>0),
winddir FLOAT,
windspeed FLOAT,
cum_elev FLOAT,
energy FLOAT,
dist FLOAT,
mean_speed FLOAT,
time FLOAT,
state INTEGER,
status FLOAT
);
-- rv_results
DROP TABLE IF EXISTS rv_results;
CREATE TABLE rv_results (jid INTEGER,
rank INTEGER,
height FLOAT,
speed FLOAT,
dist FLOAT,
cum_elev FLOAT,
energy FLOAT,
time FLOAT
);
SELECT AddGeometryColumn('rv_results', 'geom', 4326, 'POINT', 2);
ALTER TABLE rv_results ADD CONSTRAINT pk_rv_results PRIMARY KEY (jid,rank);
CREATE INDEX idx_rv_results_jid ON rv_results USING btree (jid);
-- rv_waypoints
DROP TABLE IF EXISTS rv_waypoints;
CREATE TABLE rv_waypoints (jid INTEGER,
rank INTEGER);
SELECT AddGeometryColumn('rv_waypoints', 'geom', 4326, 'POINT', 2);
ALTER TABLE rv_waypoints ADD CONSTRAINT pk_rv_waypoints PRIMARY KEY (jid,rank);
CREATE INDEX idx_rv_waypoints_jid ON rv_waypoints USING btree (jid);
COMMIT;
......@@ -2,7 +2,7 @@
BEGIN;
-- rv_ways
DROP TABLE IF EXISTS rv_ways;
CREATE TABLE rv_ways (id BIGINT, isolated BOOLEAN, cc BIGINT, ccprov BIGINT);
CREATE TABLE rv_ways (id BIGINT, cc BIGINT, ccprov BIGINT);
ALTER TABLE rv_ways ADD CONSTRAINT pk_rv_ways PRIMARY KEY (id);
CREATE INDEX idx_rv_ways_cc ON rv_ways USING btree (cc);
CREATE INDEX idx_rv_ways_ccprov ON rv_ways USING btree (ccprov) WHERE cc IS NULL;
......
......@@ -47,7 +47,6 @@ BEGIN
(
SELECT
ways.id AS id,
TRUE AS isolated,
NULL AS cc
FROM
ways
......@@ -144,24 +143,6 @@ BEGIN
DELETE FROM actions WHERE data_type='c';
-- on met à jour le flag isolated, c'est beaucoup plus rapide de chercher
-- quels sont les chemins isolés séprement et de faire le calcul de
-- composante connexes sur le reste, que de faire directement un calcul de
-- composantes connexes
UPDATE rv_ways SET isolated=TRUE;
UPDATE rv_ways
SET
isolated=FALSE
FROM
(
SELECT DISTINCT
id1 AS id
FROM
rv_way_way
) AS sub
WHERE
rv_ways.id=sub.id;
-- on labelise les cc qui ont été placés à NULL
SELECT etiqueter() INTO ccref;
......@@ -196,8 +177,6 @@ BEGIN
data_type='W'
AND
(action='C' OR action='M')
AND
NOT isolated
) AS sub;
-- rv_nodes
......@@ -272,8 +251,6 @@ BEGIN
data_type='N'
AND
(action='C' OR action='M')
AND
NOT rv_ways.isolated
) AS n
INNER JOIN
nodes ON nodes.id=n.id
......@@ -301,5 +278,8 @@ BEGIN
WHERE
sub.id=rv_nodes.id;
END;
$$ LANGUAGE plpgsql;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment