
/**********************************************************************
*  Project: sdf2ogr
* Purpose:   OGR Library  use Simple and Quick  Convert SDF file 
*  Author: t.nishioka
* file name :sdf_open.c
*discription : open SDF file and create Tab File.

 ******************************************************************************
 * Copyright (c) 2004 Takaaki Nishioka
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 ******************************************************************************
*

*easy to go 
#gcc -o sdf2ogr sdf_ogr.o sdf_read.o   `gdal-config --libs` `gdal-config --cflags`
 **********************************************************************/

#include "ogr_api.h"
#include "ogr_srs_api.h"
#include "sdf_ogr.h"
   
#ifdef USE_ICONV
#include <iconv.h>
#endif


#include <stdio.h>
#include  <dirent.h>
#include <sys/types.h>  /* open(2) */
#include <sys/stat.h>   /* open(2) */


/**********************************************************************
 *                      main()
 **********************************************************************/
int main( int nArgc, char ** papszArgv )
{
	int rtn,i;
	int iArg;
	char *Path = NULL;//検索用ディレクトリ名
	char *DistPath = NULL;//保存用ディクレクトリ
   OGRSpatialReferenceH sRef;

	const char distfileName[][DISTNATION_LENGTH] = {
		{"doro_arc.tab"},
		{"sankaku_pnt.tab"},
		{"gyousei_city_arc.tab"},
		{"gyousei_town_arc.tab"},
		{"gaiku_pgn.tab"},
		{"tatemono_pgn.tab"},
		{"eki_pnt.tab"},
		{"tetudou_arc.tab"},
		{"zyouti_pgn.tab"},
		{"mizu_pgn.tab"},
		{"mizu_arc.tab"}
	};
	char *rtnChar;
	char saveFilePath[DISTNATION_LENGTH];//保存用
	int flagDistinaton = 0;
	int removeTab =0;
   int iSrs = 0;
			
//	DistPath[0] = '\0';//連結用

	for(  iArg = 1; iArg < nArgc; iArg++ )
	{
		if( EQUAL(papszArgv[iArg],"-v") )
        {
			printf("sdf2ogr.0.1\n");
			exit(1);
		}
		else if( EQUAL(papszArgv[iArg],"-p") && iArg < nArgc-1)
		{
			Path = papszArgv[++iArg];
		}
		else if( EQUAL(papszArgv[iArg],"-s") && iArg < nArgc-1)
		{
			iSrs = atoi(papszArgv[++iArg]);
		}
		else if( EQUAL(papszArgv[iArg],"-d") && iArg < nArgc-1)
		{
			flagDistinaton = 1;
			DistPath = papszArgv[++iArg];

			i = 0;
			//ディレクトリのお尻に "/" がない場合は追加します.
			//!!!!!!!!たぶんWindowsでは "\"にしないといけない!!!!!!!!!!
			while(DistPath[i] != '\0' ){
			
				if( DistPath[i+1] == '\0' && DistPath[i] != '/'  && ( i+2 ) < DISTNATION_LENGTH){
					DistPath[i+1] = '/';
					DistPath[i+2] = '\0';
					break;
				}
				i++;
			}
		}
		else if( EQUAL(papszArgv[iArg],"-r") )
		{
			removeTab = 1;
		}
		else
		{
			Usage();
		}
	}
	//ファイルの削除
	if ( 1 ==  removeTab ){
		for(i =0;i<DATASOURCE_MAX;i++){
			if(flagDistinaton == 1 ) {
				saveFilePath[0] = '\0';
				rtnChar = strcat (saveFilePath,DistPath);
				rtnChar = strcat (saveFilePath,distfileName[i]);
				rtn = removeTabFile(rtnChar);
			}else
				rtn = removeTabFile(distfileName[i]);
		}
	}

//Set EPSG Val;
   if( iSrs > 2442 && iSrs < 2462 )
   {
      sRef = OSRNewSpatialReference(NULL);
	  OSRImportFromEPSG(sRef, 2449 );
   }else{
      sRef = NULL;
   }


	//TABオブジェクトの生成
	for( i = 0; i< DATASOURCE_MAX ; i++ ){
		if( 1 == flagDistinaton )//保存ファイルの指定がある場合
		{
			saveFilePath[0] = '\0';
			rtnChar = strcat (saveFilePath,DistPath);
			rtnChar = strcat (saveFilePath,distfileName[i]);
			sdfDatasource[i] = createDataSouce(sdfDatasource[i],rtnChar ,sRef);
		}
		else
				sdfDatasource[i] = createDataSouce(sdfDatasource[i],distfileName[i],sRef );
	}

	
	rtn =  readDir(Path);//SDFファイル検索開始
	
	//TABオブジェクトの保存
	for( i = 0; i< DATASOURCE_MAX ; i++ ){
		OGR_DS_Destroy( sdfDatasource[i] );
	}

   return 0;
}
/*------------------------------------------------------
*
*指定ディレクトリのseek、そして数値地図ディレクトリの発見する
*int readDir(char* argv)
-------------------------------------------------------*/
int readDir(char* argv)
{
   DIR   *dir;
   struct dirent  *dp;
   struct stat st;
   char  path[STR_MAX];
   char rpath[STR_MAX];
   int rtn;

   if(argv == NULL){
      strcpy(path,".");
   }
   else{
      strcpy(path,argv);
   }

   if((dir=opendir(path))==NULL){
      perror("opendir");
      exit(-1);
   }
//    printf("%s:\n",path);
   for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){
      if(  (strcmp(dp->d_name,".") != 0  )&&  (strcmp(dp->d_name,"..") != 0)){
			sprintf(rpath,"%s/%s",path,dp->d_name);
			
         if( stat(rpath,&st) ){
            perror("stat");
            exit(1);
			}
				
         if( S_ISDIR(st.st_mode )){
            if(strcmp(dp->d_name,"road") == 0 )
				rtn = createRoadObject(rpath);//道路データの呼び出し
            else if(strcmp(dp->d_name,"kijunten") == 0 )
				rtn = createSankakuObject(rpath);//基準点
			else if(strcmp(dp->d_name,"others") == 0 )
						rtn = createOthersObject(rpath);//eki,sonota
			else if(strcmp(dp->d_name,"gyousei") == 0 )
				rtn = createGyouseiObject(rpath);//市町村ポリゴン
			else if(strcmp(dp->d_name,"gaiku") == 0 )
				rtn = createGaikuObject(rpath);//街区ポリゴン
			else if(strcmp(dp->d_name,"mizu") == 0 )
				rtn = createWaterObject(rpath);//水域
			else if(strcmp(dp->d_name,"tatemono") == 0 )
				rtn = createTatemonoObject(rpath);//街区ポリゴン
            else
               readDir(rpath);
         }
      }
   }
	closedir(dir);

   return(0);
}
/*------------------------------------------------------
*
*道路の変換用
*int createRoadObject(char *Path)
-------------------------------------------------------*/
int createRoadObject(char *Path)
{
   DIR   *dir;
   struct dirent  *dp;
   struct stat st;
   char rpath[STR_MAX];
	char arcfile[STR_MAX];
	char attfile[STR_MAX];
   int atrFlag=0;
	int arcFlag=0;

   
   if((dir=opendir(Path))==NULL){
      perror("opendir");
      exit(-1);
   }
//    printf("%s:\n",path);
    for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){
    if(  (strcmp(dp->d_name,".") != 0  )&&  (strcmp(dp->d_name,"..") != 0)){
       sprintf(rpath,"%s/%s",Path,dp->d_name);
       if( stat(rpath,&st) ){
          perror("stat");
          exit(2);
      }
      if( strcmp(dp->d_name,"road.atr") == 0 )atrFlag=1;//atrファイルがある場合のラグ
      if( strcmp(dp->d_name,"roadntwk.arc") == 0 )arcFlag=1;//arcファイルがある場合のフラグ

      }
   }
   printf("%s\n",Path);
   //道路用のファイルがあることが確認する
	if( atrFlag == 1 && arcFlag == 1){
		sprintf(attfile,"%s/road.atr",Path);
//		atrP = readAtrFile(filename);
		sprintf(arcfile,"%s/roadntwk.arc",Path);
		readArcFile(sdfDatasource[DORO_ARC],arcfile,attfile);
#ifdef DEBUG
		printf("filename %s",arcfile);
#endif//debug
	}
	closedir(dir);
   return(0);
}
/*------------------------------------------------------
*
*基準点の変換用
*int createSankakuObject(char *Path)
-------------------------------------------------------*/
int createSankakuObject(char *Path)
{
   DIR   *dir;
   struct dirent  *dp;
   struct stat st;
   char rpath[STR_MAX];
	char pntfile[STR_MAX];
	char attfile[STR_MAX];
   int atrFlag=0;
	int arcFlag=0;

   
   if((dir=opendir(Path))==NULL){
      perror("opendir");
      exit(-1);
   }
    printf("%s:\n",Path);
    for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){
    if(  (strcmp(dp->d_name,".") != 0  )&&  (strcmp(dp->d_name,"..") != 0)){
       sprintf(rpath,"%s/%s",Path,dp->d_name);
       if( stat(rpath,&st) ){
          perror("stat");
          exit(2);
      }
      if( strcmp(dp->d_name,"sankaku.atr") == 0 )atrFlag=1;//atrファイルがある場合のラグ
      if( strcmp(dp->d_name,"sankaku.pnt") == 0 )arcFlag=1;//arcファイルがある場合のフラグ

      }
   }
   //三角点用のファイルがあることが確認する
	if( atrFlag == 1 && arcFlag == 1){
		sprintf(attfile,"%s/sankaku.atr",Path);
		sprintf(pntfile,"%s/sankaku.pnt",Path);
		readPntFile(sdfDatasource[SANKAKU_PNT],pntfile,attfile);
#ifdef DEBUG
		printf("filename %s",filename);
#endif//debug
	}
	closedir(dir);
   return(0);
}
/*------------------------------------------------------
*
*行政界データ、市界、町丁目界
*int createGyouseiObject(char *Path)
-------------------------------------------------------*/
int createGyouseiObject(char *Path)
{
   DIR   *dir;
   struct dirent  *dp;
   struct stat st;
	char rpath[STR_MAX];
	 char pgnfile[STR_MAX];
	char arcfile[STR_MAX];
	char attfile[STR_MAX];
	int atrCityFlag=0;
	int atrTownFlag=0;
	
	int arcFlag=0;
	int pgnTownFlag=0;
	int pgnCityFlag=0;

   
   if((dir=opendir(Path))==NULL){
      perror("opendir");
      exit(-1);
   }
    printf("%s:\n",Path);
    for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){
    if(  (strcmp(dp->d_name,".") != 0  )&&  (strcmp(dp->d_name,"..") != 0)){
       sprintf(rpath,"%s/%s",Path,dp->d_name);
       if( stat(rpath,&st) ){
          perror("stat");
          exit(2);
      }
		if( strcmp(dp->d_name,"si_tyo.atr") == 0 )atrCityFlag=1;
			//atrファイルがある場合のラグ
		if( strcmp(dp->d_name,"tyome.atr") == 0 )atrTownFlag=1;
			//arcファイルがある場合のフラグ
		if( strcmp(dp->d_name,"gyousei.arc") == 0 )arcFlag=1;
			//arcファイルがある場合のフラグ					
		if( strcmp(dp->d_name,"tyome.pgn") == 0 )pgnTownFlag=1;
			//arcファイルがある場合のフラグ			
		if( strcmp(dp->d_name,"si_tyo.pgn") == 0 )pgnCityFlag=1;
			//arcファイルがある場合のフラグ
      }
   }
   //市の行政界データのファイルがあることが確認する
	if( atrCityFlag == 1 && arcFlag == 1 && pgnCityFlag ==1){
		sprintf(attfile,"%s/si_tyo.atr",Path);
		sprintf(arcfile,"%s/gyousei.arc",Path);
		sprintf(pgnfile,"%s/si_tyo.pgn",Path);
		readPgnFile(sdfDatasource[GYOUSEI_CITY_PGN],pgnfile,arcfile,attfile);
	}
	//町丁目の行政界データのファイルがあることが確認する
	if( arcFlag == 1 && atrCityFlag == 1 && pgnTownFlag
			==1){
		sprintf(attfile,"%s/tyome.atr",Path);
		sprintf(arcfile,"%s/gyousei.arc",Path);
		sprintf(pgnfile,"%s/tyome.pgn",Path);
		readPgnFile(sdfDatasource[GYOUSEI_TOWN_PGN],pgnfile,arcfile,attfile);
	}
	closedir(dir);
   return(0);
}
/*------------------------------------------------------
*
*街区データ、
*int createGaikuObject(char *Path)
-------------------------------------------------------*/
int createGaikuObject(char *Path)
{
   DIR   *dir;
   struct dirent  *dp;
   struct stat st;
	char rpath[STR_MAX];
	 char pgnfile[STR_MAX];
	char arcfile[STR_MAX];
	char attfile[STR_MAX];
	
	int arcFlag=0;
	int pgnFlag=0;
	int atrFlag=0;

   
   if((dir=opendir(Path))==NULL){
      perror("opendir");
      exit(-1);
   }
    printf("%s:\n",Path);
    for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){
		if(  (strcmp(dp->d_name,".") != 0  )&&  (strcmp(dp->d_name,"..") != 0)){
			sprintf(rpath,"%s/%s",Path,dp->d_name);
			if( stat(rpath,&st) ){
				perror("stat");
				exit(2);
			}
			if( strcmp(dp->d_name,"gaiku.atr") == 0 )atrFlag=1;
			//atrファイルがある場合のラグ
			if( strcmp(dp->d_name,"gaiku.arc") == 0 )arcFlag=1;
			//arcファイルがある場合のフラグ
			if( strcmp(dp->d_name,"gaiku.pgn") == 0 )pgnFlag=1;
			//pgnファイルがある場合のフラグ					
		}
	}
   //街区データのファイルがあることが確認する
	if( atrFlag == 1 && arcFlag == 1 && pgnFlag ==1){
		sprintf(attfile,"%s/gaiku.atr",Path);
		sprintf(arcfile,"%s/gaiku.arc",Path);
		sprintf(pgnfile,"%s/gaiku.pgn",Path);
	
		readPgnFile(sdfDatasource[GAIKU_PGN],pgnfile,arcfile,attfile);
	}
	closedir(dir);

   return(0);
}
/*------------------------------------------------------
*
*建物データ、
*int createTatemonoObject(char *Path)
-------------------------------------------------------*/
int createTatemonoObject(char *Path)
{
   DIR   *dir;
   struct dirent  *dp;
   struct stat st;
	char rpath[STR_MAX];
	 char pgnfile[STR_MAX];
	char arcfile[STR_MAX];
	char attfile[STR_MAX];
	
	int arcFlag=0;
	int pgnFlag=0;
	int atrFlag=0;

   
   if((dir=opendir(Path))==NULL){
      perror("opendir");
      exit(-1);
   }
    printf("%s:\n",Path);
    for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){
		if(  (strcmp(dp->d_name,".") != 0  )&&  (strcmp(dp->d_name,"..") != 0)){
			sprintf(rpath,"%s/%s",Path,dp->d_name);
			if( stat(rpath,&st) ){
				perror("stat");
				exit(2);
			}
			if( strcmp(dp->d_name,"tatemono.atr") == 0 )atrFlag=1;
			//atrファイルがある場合のラグ
			if( strcmp(dp->d_name,"tatemono.arc") == 0 )arcFlag=1;
			//arcファイルがある場合のフラグ
			if( strcmp(dp->d_name,"tatemono.pgn") == 0 )pgnFlag=1;
			//pgnファイルがある場合のフラグ					
		}
	}
   //建物データのファイルがあることが確認する
	if( atrFlag == 1 && arcFlag == 1 && pgnFlag ==1){
		sprintf(attfile,"%s/tatemono.atr",Path);
		sprintf(arcfile,"%s/tatemono.arc",Path);
		sprintf(pgnfile,"%s/tatemono.pgn",Path);
	
		readPgnFile(sdfDatasource[TATEMONO_PGN],pgnfile,arcfile,attfile);
	}
	closedir(dir);

   return(0);
}
/*------------------------------------------------------
*
*水域データ
*水域データは、ポリゴンとラインが混在しているため
*将来的には
*ポリゴンで利用したArcデータは、ラインを出力する時に
出力しないような設定が必要と思われる。
*int createWaterObject(char *Path)
-------------------------------------------------------*/
int createWaterObject(char *Path)
{
   DIR   *dir;
   struct dirent  *dp;
   struct stat st;
	char rpath[STR_MAX];
	 char pgnfile[STR_MAX];
	char arcfile[STR_MAX];
	char attfile[STR_MAX];
	
	int arcFlag=0;
	int pgnFlag=0;
	int atrFlag=0;

   
   if((dir=opendir(Path))==NULL){
      perror("opendir");
      exit(-1);
   }
    printf("%s:\n",Path);
    for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){
		if(  (strcmp(dp->d_name,".") != 0  )&&  (strcmp(dp->d_name,"..") != 0)){
			sprintf(rpath,"%s/%s",Path,dp->d_name);
			if( stat(rpath,&st) ){
				perror("stat");
				exit(2);
			}
			if( strcmp(dp->d_name,"mizu.atr") == 0 )atrFlag=1;
			//atrファイルがある場合のラグ
			if( strcmp(dp->d_name,"mizu.arc") == 0 )arcFlag=1;
			//arcファイルがある場合のフラグ
			if( strcmp(dp->d_name,"mizu.pgn") == 0 )pgnFlag=1;
			//pgnファイルがある場合のフラグ					
		}
	}
   //街区データのファイルがあることが確認する
	if( atrFlag == 1 && arcFlag == 1 && pgnFlag ==1){
		sprintf(attfile,"%s/mizu.atr",Path);
		sprintf(arcfile,"%s/mizu.arc",Path);
		sprintf(pgnfile,"%s/mizu.pgn",Path);
	
		readPgnFile(sdfDatasource[MIZU_PGN],pgnfile,arcfile,attfile);
//		readArcFile(sdfDatasource[MIZU_ARC],arcfile,attfile);
	}
	closedir(dir);

   return(0);
}
/*------------------------------------------------------
*
*その他の変換用
引数　ディレクトリ名
*int createOthersObject(char *Path)
-------------------------------------------------------*/
int createOthersObject(char *Path)
{
   DIR   *dir;
   struct dirent  *dp;
   struct stat st;
   char rpath[STR_MAX];
	char pntfile[STR_MAX];
	char arcfile[STR_MAX];
	char pgnfile[STR_MAX];
	char attfile[STR_MAX];
	int ekiAtrFlag=0;
	int ekiPntFlag=0;
	int  othersArcFlag =0;
	int tetudouAtrFlag = 0;
	int zyoutiAtrFlag = 0;
	int zyoutiPgnFlag = 0;
   
   if((dir=opendir(Path))==NULL){
      perror("opendir");
      exit(-1);
   }
    printf("%s:\n",Path);
    for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){
    if(  (strcmp(dp->d_name,".") != 0  )&&  (strcmp(dp->d_name,"..") != 0)){
       sprintf(rpath,"%s/%s",Path,dp->d_name);
       if( stat(rpath,&st) ){
          perror("stat");
          exit(2);
      }
			if( strcmp(dp->d_name,"eki.atr") == 0 )ekiAtrFlag=1;//atrファイルがある場合のラグ
			if( strcmp(dp->d_name,"eki.pnt") == 0 )ekiPntFlag=1;//arcファイルがある場合のフラグ
			if( strcmp(dp->d_name,"others.arc") == 0 )othersArcFlag=1;//atrファイルがある場合のラグ
			if( strcmp(dp->d_name,"tetudou.atr") == 0 )tetudouAtrFlag=1;//arcファイルがある場合のフラグ
			if( strcmp(dp->d_name,"zyouti.atr") == 0 )zyoutiAtrFlag=1;//atrファイルがある場合のラグ
			if( strcmp(dp->d_name,"zyouti.pgn") == 0 )zyoutiPgnFlag=1;//arcファイルがある場合のフラグ
      }
   }
   //三角点用のファイルがあることが確認する
	if( ekiAtrFlag == 1 && ekiPntFlag == 1){
		sprintf(attfile,"%s/eki.atr",Path);
		sprintf(pntfile,"%s/eki.pnt",Path);
		readPntFile(sdfDatasource[EKI_PNT],pntfile,attfile);
#ifdef DEBUG
		printf("filename %s",pntfile);
#endif//debug
	}
   //場地用のファイルがあることが確認する
	if( zyoutiAtrFlag == 1 && zyoutiPgnFlag == 1 && othersArcFlag == 1){
		sprintf(attfile,"%s/zyouti.atr",Path);
		sprintf(pgnfile,"%s/zyouti.pgn",Path);
		sprintf(arcfile,"%s/others.arc",Path);
		readPgnFile(sdfDatasource[ZYOUTI_PGN],pgnfile,arcfile,attfile);
#ifdef DEBUG
		printf("filename %s",pgnfile);
#endif//debug
	}
   //鉄道用のファイルがあることが確認する
	if( zyoutiAtrFlag == 1 && othersArcFlag == 1){
		sprintf(attfile,"%s/tetudou.atr",Path);
		sprintf(arcfile,"%s/others.arc",Path);
		readAtrFile(sdfDatasource[TETUDOU_ARC],attfile,arcfile);
#ifdef DEBUG
		printf("filename %s",pgnfile);
#endif//debug
	}
	closedir(dir);
   return(0);
}
/*------------------------------------------------------
*
*Tabファイルを消す
*int removeTabFile(const char *DistPath,const char**distfileName);
-------------------------------------------------------*/
int removeTabFile(const char *removeFile)
{
	int rtn;
	
	if(  ( rtn  =remove(removeFile) ) != 0 )
	{
		printf("file %s is not removed \n",removeFile);
	}
	return (0);
}
/*------------------------------------------------------
*
*カンマをスペースに変換する
sscanfがカンマの読み込みに異常があるため
*void replaceSpace(char& *tmp)
-------------------------------------------------------*/
void replaceSpace(char *tmp){
	int i;
	for(i=0;i<strlen(tmp);i++){
		if (tmp[i]==44) { tmp[i]=32; }
	} 
}

/************************************************************************/
/*                               Usage()                                */
/************************************************************************/

static void Usage(void )
{
	printf("Usage: sdf2ogr [-rv] [-p sdf_file_path] [-d save_tab_dir]\n"
			"			-v : print version\n"
			"			-s : EPSG CODE(2443 - 2461)\n"
			"			-r : remove old tab file\n");
	exit(1);
}
