///////////////////////////////////////// // // これはサービス利用者とサービス提供者の例 // // とりあえず、適当な地図を作って、自動車を走らせよう // // // /* gcc -g -I"D:\PostgreSQL\pg96\include" test.cpp -o test.exe -L"D:\PostgreSQL\pg96\lib" -llibpq -lwsock32 -lws2_32 */ #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <sys/types.h> #include <math.h> #include "libpq-fe.h" struct PASSENGER{ double a1,a2; double d1,d2; double arrival_CS(double); // 到着時刻に関する満足度関数 double departure_CS(double); // 出発時刻に対する満足度関数 }; double PASSENGER::arrival_CS(double time){ double ret; if (time < a1){ ret = 1.0; } else if (time > a2){ ret = 0.0; } else { ret = 1.0 / (a1 - a2) * ( time - a2); } return ret; } double PASSENGER::departure_CS(double time){ double ret; if (time < d1){ ret = 1.0; } else if (time > d2){ ret = 0.0; } else { ret = 1.0 / (d1 - d2) * ( time - d2); } return ret; } struct DRIVER{ // ここではタクシードライバを想定する // タクシードライバは、遅れてくる客が嫌い // タクシードライバは、待っていてくれる客は好き double w1; double w2; double waiting_CS(double); }; double DRIVER::waiting_CS(double time){ double ret; if (time < w1){ ret = 1.0; } else if (time > w2){ ret = 0.0; } else { ret = 1.0 / (w1 - w2) * ( time - w2); } return ret; } #define rad2deg(a) ((a)/M_PI * 180.0) /* rad を deg に換算するマクロ関数 */ #define deg2rad(a) ((a)/180.0 * M_PI) /* deg を rad に換算するマクロ関数 */ //double distance_km(LOCATION* A, LOCATION* B, double *rad_up) double distance_km(double a_longitude, double a_latitude, double b_longitude, double b_latitude, double *rad_up) { double earth_r = 6378.137; double loRe = deg2rad(b_longitude - a_longitude); // 東西 経度は135度 double laRe = deg2rad(b_latitude - a_latitude); // 南北 緯度は34度39分 double EWD = cos(deg2rad(a_latitude))*earth_r*loRe; // 東西距離 double NSD = earth_r*laRe; //南北距離 double distance = sqrt(pow(NSD,2)+pow(EWD,2)); *rad_up = atan2(NSD, EWD); return distance; } double diff_longitude(double diff_p_x, double latitude) { double earth_r = 6378.137; // ↓ これが正解だけど、 double loRe = diff_p_x / earth_r / cos(deg2rad(latitude)); // 東西 // 面倒なので、これで統一しよう(あまり差が出ないしね) //double loRe = diff_p_x / earth_r / cos(deg2rad(35.700759)); // 東西 double diff_lo = rad2deg(loRe); // 東西 return diff_lo; // 東西 } double diff_latitude(double diff_p_y) { double earth_r = 6378.137; double laRe = diff_p_y / earth_r; // 南北 double diff_la = rad2deg(laRe); // 南北 return diff_la; // 南北 } int main (){ double time = 2.7; // 構造体定義名の前に「struct」がいらない(C++にあってCにない規定らしい) PASSENGER passenger1; PASSENGER passenger2; // 以下が、マインド(心)変数 passenger1.a1 = 1; passenger1.a2 = 3; passenger1.d1 = 2; passenger1.d2 = 4; double aa1 = passenger1.arrival_CS(time); double bb1 = passenger1.departure_CS(time); passenger2.a1 = 0; passenger2.a2 = 2; passenger2.d1 = 3; passenger2.d2 = 5; double aa2 = passenger2.arrival_CS(time); double bb2 = passenger2.departure_CS(time); DRIVER driver1; DRIVER driver2; driver1.w1 = 0; driver1.w2 = 5; double cc1 = driver1.waiting_CS(time); driver2.w1 = 2; driver2.w2 = 7; double cc2 = driver2.waiting_CS(time); printf("time = %f, aa1 = %f, bb1 = %f, cc1 = %f\n", time, aa1, bb1, cc1); printf("time = %f, aa2 = %f, bb2 = %f, cc2 = %f\n", time, aa2, bb2, cc2); ////////////////////////////////////////////////// int bus_stop_num[] = {115,104, 3, 62, 277,48, 213, 208, -1}; const char *conninfo = "host=localhost user=postgres password=c-anemone dbname=city_routing"; // データベースとの接続を確立する PGconn *conn = PQconnectdb(conninfo); PGresult *res; // バックエンドとの接続確立に成功したかを確認する if (PQstatus(conn) != CONNECTION_OK){ fprintf(stderr, "Connection to database failed: %s", PQerrorMessage(conn)); } int cnt = 0; while (bus_stop_num[cnt] != -1){ printf("%d\n", bus_stop_num[cnt]); // テーブルオープン char stringSQL[1024] = {0}; // sprintf(stringSQL, "SELECT seq, node, edge, cost FROM pgr_dijkstra('SELECT gid as id, source, target, cost_s As cost, reverse_cost_s AS reverse_cost FROM ways', %d, %d, true );",bus_stop_num[cnt], bus_stop_num[cnt+1]); sprintf(stringSQL, "SELECT node FROM pgr_dijkstra('SELECT gid as id, source, target, cost_s As cost, reverse_cost_s AS reverse_cost FROM ways', %d, %d, true );",bus_stop_num[cnt], bus_stop_num[cnt+1]); res = PQexec(conn, stringSQL); if (res == NULL){ fprintf(stderr, "failed: %s", PQerrorMessage(conn)); } // SELECTの場合戻り値は PGRES_TUPLES_OK. これを確認しておく if (PQresultStatus(res) != PGRES_TUPLES_OK){ PQerrorMessage(conn); } int nFields = PQnfields(res); // まず属性名を表示する。 /* for (int i = 0; i < nFields; i++){ printf("%-15s", PQfname(res, i)); } printf("\n\n"); */ // そして行を表示する。 for (int i = 0; i < PQntuples(res) -1 ; i++) { for (int j = 0; j < nFields; j++) { //printf("%d %d ", i, j); //printf("%-15s", PQgetvalue(res, i, j)); //printf("\n"); if (j == 0){ printf("%-15s", PQgetvalue(res, i, j)); char stringSQL2[1024] = {0}; sprintf(stringSQL2, "SELECT x1,y1,x2,y2 from ways where source = %s;", PQgetvalue(res, i, j)); PGresult *res2 = PQexec(conn, stringSQL2); int nFields2 = PQnfields(res2); double loc[4] = {0.0}; //for (int i2 = 0; i2 < PQntuples(res2); i2++) { for (int j2 = 0; j2 < nFields2; j2++) { printf("%-15s", PQgetvalue(res2, 0, j2)); loc[j2] = atof(PQgetvalue(res2, 0, j2)); } //} //未来のパスのベクトルを計算する double rad_up1; distance_km(loc[0], loc[1], loc[2], loc[3], &rad_up1); printf("%-15f", rad_up1); // 値セットが無い場合でも必ず結果をクリアする PQclear(res2); } // j == 1 } printf("\n"); } // 値セットが無い場合でも必ず結果をクリアする PQclear(res); cnt += 1; } // 最後必ずデータベースとの接続を閉じる PQfinish(conn); return 0; }