2011|08|
2013|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|05|06|07|08|09|10|11|12|
2016|01|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|

2018-10-26 postGISを使ったシミュレータのテストプログラム [長年日記]

/////////////////////////////////////////
// 
// これはサービス利用者とサービス提供者の例
//
// とりあえず、適当な地図を作って、自動車を走らせよう
// 
//
//
 
 
 
/*
 
 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;
}
syntax2html