/**********************************************************************
 * $Id: testogr.c,v 1.1.1.1 2004/09/13 13:11:57 nishioka_takaaki Exp $
 **********************************************************************
 *
 * Test the OGR C API (ogr_api.h)
 *
 * Compile using:
 *
 * gcc -g testogr.c `gdal-config --libs` `gdal-config --cflags` -o ogr_capi_test
 *
 **********************************************************************
 * $Log: testogr.c,v $
 * Revision 1.1.1.1  2004/09/13 13:11:57  nishioka_takaaki
 *
 * Convert GSI SDF file to OGR datasource.
 * USING gdal library.
 *
 * Revision 1.2  2003/02/19 03:43:11  danmo
 * Added cvs log, etc.
 *
 */

#include "ogr_api.h"

#define STR_MAX 256
#define POINT_MAX 256 /*--座標点列の最大値--*/


struct arcH{
				char FH[2];/*--FH--*/
				char zumei[30];/*--図名--*/
				char filename[40];/*--ファイル名--*/
				int recordC;/*--レコード総数--*/
				int fieldC;/*--要素の総数--*/
				int CoordFlag;/*--座標系フラグ--*/
				int Coordinate;/*--座標系番号--*/
				int kubun;/*--数値化区分--*/
				double llx;/*--左下--*/
				double lly;/*--左下--*/
				double rux;/*--右上--*/
				double ruy;/*--右上--*/
				double lux;/*--左上--*/
				double luy;/*--左上--*/
				double rlx;/*--右下--*/
				double rly;/*--右下--*/
	 };/*--ファイルヘッダーレコードの構造体--*/

typedef struct arcIDRec arc_P;
struct arcIDRec{
				char code[10];/*--図式分類コード--*/
				int  lineTag;/*--線種タグ--*/
				int  pubKey;/*--個別情報--*/
				int  count;/*--当該アークを構成する座標レコードの数--*/
				double pX[POINT_MAX];/*--座標点列X--*/
				double pY[POINT_MAX];/*--座標点列Y--*/
        arc_P *next;/*-- 次のポインター --*/
	 };/*--アークIDレコード--*/
typedef struct pgnIDRec pgn_P;
struct pgnIDRec{
				char code[10];/*--図式分類コード--*/
				int  pubKey;/*--個別情報--*/
				int  count;/*--当該ポリゴンを構成するアーク指定レコードの数--*/
				double pX;/*--代表点のX座標--*/
				double pY;/*--代表点のY座標--*/
        pgn_P *next;/*-- 次のポインター --*/
	 };/*--ポリゴンのIDレコード--*/

typedef struct atrIDRec atr_P;
struct atrIDRec{
		 		char code[10];/*--図式分類コード--*/
				char  field1[STR_MAX];/*--個別情報--*/
				char  field2[STR_MAX];/*--個別情報--*/
				char  field3[STR_MAX];/*--個別情報--*/
				char  field4[STR_MAX];/*--個別情報--*/
				char  field5[STR_MAX];/*--個別情報--*/
        atr_P *next;/*-- 次のポインター --*/
}

int OGRCDump(const char *pszFname);
int OGRCCreate(const char *pszFname);
int OGRCMake(const char *pszFname);
int OGRCRead( OGRLayerH layer, OGRFeatureDefnH layerDefn );
int readPgnFile(struct arcIDRec *arIR );
struct atrIDRec readAtrFile(const char *pszFname );
struct arcIDRec *checkArcIDRecord(struct arcIDRec *arIR,int oNum);
struct arcIDRec *createData(void);
int freeData(struct arcIDRec *arIDRec );
struct pgnIDRec *createPgnData(void);
int freePgnData(struct pgnIDRec *pgnR );
/**********************************************************************
 *                      main()
 **********************************************************************/
int main(int argc, char *argv[])
{

    if (argc == 3 && EQUAL(argv[1], "dump"))
    {
        return OGRCDump(argv[2]);
    }
    else if (argc == 3 && EQUAL(argv[1], "create"))
    {
        return OGRCCreate(argv[2]);
    }
	 else if (argc == 3 && EQUAL(argv[1], "make"))
    {
        return OGRCMake(argv[2]);
    }
    else
    {
        printf("Usage: ogr_capi_test <command> <filename>\n");
    }

    return 0;
}

/**********************************************************************
 *                      OGRCDump()
 *
 * Open a dataset using OGR and dump all its layers.
 *
 **********************************************************************/

int OGRCDump(const char *pszFname)
{
    OGRDataSourceH datasource;
    int i, numLayers;

    /* Register all OGR drivers */
    OGRRegisterAll();

    /* Open data source */
    datasource = OGROpen(pszFname, 0 /* bUpdate */, NULL);

    if (datasource == NULL)
    {
        printf("Unable to open %s\n", pszFname);
        return -1;
    }

    /* Loop through layers and dump their contents */

    numLayers = OGR_DS_GetLayerCount(datasource);
    for(i=0; i<numLayers; i++)
    {
        OGRLayerH layer;
        int j, numFields;
        OGRFeatureH feature;
        OGRFeatureDefnH layerDefn;

        layer = OGR_DS_GetLayer( datasource, i );

        /* Dump info about this layer */
        layerDefn = OGR_L_GetLayerDefn( layer );
        numFields = OGR_FD_GetFieldCount( layerDefn );

        printf("\n===================\n");
        printf("Layer %d: '%s'\n\n", i, OGR_FD_GetName(layerDefn));

        for(j=0; j<numFields; j++)
        {
            OGRFieldDefnH fieldDefn;

            fieldDefn = OGR_FD_GetFieldDefn( layerDefn, j );
            printf(" Field %d: %s (%s)\n", 
                   j, OGR_Fld_GetNameRef(fieldDefn), 
                   OGR_GetFieldTypeName(OGR_Fld_GetType(fieldDefn)) );
        }
        printf("\n");

        /* And dump each feature individually */
        while( (feature = OGR_L_GetNextFeature( layer )) != NULL )
        {
            OGR_F_DumpReadable( feature, stdout );
            OGR_F_Destroy( feature );
        }

        /* No need to free layer handle, it belongs to the datasource */
    }

    /* Close data source */
    OGR_DS_Destroy( datasource );

    return 0;
}

/**********************************************************************
 *                      OGRCCreate()
 *
 * Create a new dataset using OGR C API with a few features in it.
 *
 **********************************************************************/

int OGRCCreate(const char *pszFname)
{
    OGRSFDriverH    driver;
    int             i, numDrivers;
    OGRDataSourceH  datasource;
    OGRLayerH       layer;
    OGRFeatureDefnH layerDefn;
    OGRFieldDefnH   fieldDefn;
    OGRFeatureH     feature;
    OGRGeometryH    geometry, ring;

    /* Register all OGR drivers */
    OGRRegisterAll();

    /* Fetch MITAB driver - we want to create a TAB file */
    numDrivers = OGRGetDriverCount();
    for(i=0; i<numDrivers; i++)
    {
        driver = OGRGetDriver(i);
        printf("%d/%d  %s\n",i,numDrivers, OGR_Dr_GetName(driver));
//        if (EQUAL("DGN", OGR_Dr_GetName(driver)))
        if (EQUAL("MapInfo File", OGR_Dr_GetName(driver)))
            break;  /* Found it! */
        driver = NULL;
    }

    if (!driver)
    {
        printf("Driver not found!\n");
        return -1;
    }

    /* Create new file using this driver */
    datasource = OGR_Dr_CreateDataSource(driver, pszFname, NULL);

    if (datasource == NULL)
    {
        printf("Unable to create %s\n", pszFname);
        return -1;
    }

    /* MapInfo data sources are created with one empty layer.
       Fetch the layer handle */
    layer = OGR_DS_GetLayer(datasource, 0);

    if (layer == NULL)
    {
        printf("Unable to create new layer in %s\n", pszFname);
        return -1;
    }

    /* Add a few fields to the layer defn */
    fieldDefn = OGR_Fld_Create( "id", OFTInteger );
    OGR_L_CreateField(layer, fieldDefn, 0);

    fieldDefn = OGR_Fld_Create( "area", OFTReal );
    OGR_L_CreateField(layer, fieldDefn, 0);

    fieldDefn = OGR_Fld_Create( "tax", OFTString );
    OGR_L_CreateField(layer, fieldDefn, 0);

    fieldDefn = OGR_Fld_Create( "name1", OFTString );
    OGR_L_CreateField(layer, fieldDefn, 0);
	 

    /* We'll need the layerDefn handle to create new features in this layer */
    layerDefn = OGR_L_GetLayerDefn( layer );

    /* Create a new point */
    feature = OGR_F_Create( layerDefn );
    OGR_F_SetFieldInteger( feature, 0, 1);
    OGR_F_SetFieldDouble( feature, 1, 123.45);
    OGR_F_SetFieldString( feature, 2, "aaa #1");
    OGR_F_SetFieldString( feature, 3, "西岡");

    geometry = OGR_G_CreateGeometry( wkbPoint );
    OGR_G_SetPoint(geometry, 0, 123.45, 456.78, 0);

    OGR_F_SetGeometryDirectly(feature, geometry);

    OGR_L_CreateFeature( layer, feature );

    /* Create a new line */
    feature = OGR_F_Create( layerDefn );
    OGR_F_SetFieldInteger( feature, 0, 2);
    OGR_F_SetFieldDouble( feature, 1, 42.45);
    OGR_F_SetFieldString( feature, 2, "西岡 #2");
    OGR_F_SetFieldString( feature, 3, "西岡");

    geometry = OGR_G_CreateGeometry( wkbLineString );
    OGR_G_AddPoint(geometry, 123.45, 456.78, 0);
    OGR_G_AddPoint(geometry, 12.34,  45.67, 0);

    OGR_F_SetGeometryDirectly(feature, geometry);
 
    OGR_L_CreateFeature( layer, feature );

    /* Create a new polygon (square) */
    feature = OGR_F_Create( layerDefn );
    OGR_F_SetFieldInteger( feature, 0, 3);
    OGR_F_SetFieldDouble( feature, 1, 49.71);
    OGR_F_SetFieldString( feature, 2, "Feature #1１");
    OGR_F_SetFieldString( feature, 3, "西岡");

    geometry = OGR_G_CreateGeometry( wkbPolygon );
    ring = OGR_G_CreateGeometry( wkbLinearRing );
    OGR_G_AddPoint(ring, 123.45, 456.78, 0);
    OGR_G_AddPoint(ring, 12.34,  456.78, 0);
    OGR_G_AddPoint(ring, 12.34,  45.67, 0);
    OGR_G_AddPoint(ring, 123.45, 45.67, 0);
    OGR_G_AddPoint(ring, 123.45, 456.78, 0);
    OGR_G_AddGeometryDirectly(geometry, ring);

    OGR_F_SetGeometryDirectly(feature, geometry);
 
    OGR_L_CreateFeature( layer, feature );

    /* Close data source */
    OGR_DS_Destroy( datasource );

    return 0;
}


/**********************************************************************
 *                      OGRCMake()
 *
 * Create a new dataset using OGR C API with a few features in it.
 *
 **********************************************************************/

int OGRCMake(const char *pszFname){
   char str[128];
	double ix,iy ;
	
    OGRSFDriverH    driver;
    int             i,rtn, numDrivers;
    OGRDataSourceH  datasource;
    OGRLayerH       layer;
    OGRFeatureDefnH layerDefn;
    OGRFieldDefnH   fieldDefn;
    OGRFeatureH     feature;
    OGRGeometryH    geometry, ring;

	     /* Register all OGR drivers */
    OGRRegisterAll();

    /* Fetch MITAB driver - we want to create a TAB file */
    numDrivers = OGRGetDriverCount();
    for(i=0; i<numDrivers; i++)
    {
        driver = OGRGetDriver(i);
//        printf("%d/%d  %s\n",i,numDrivers, OGR_Dr_GetName(driver));
//        if (EQUAL("DGN", OGR_Dr_GetName(driver)))
        if (EQUAL("MapInfo File", OGR_Dr_GetName(driver)))
            break;  /* Found it! */
        driver = NULL;
    }

    if (!driver)
    {
        printf("Driver not found!\n");
        return -1;
    }

    /* Create new file using this driver */
    datasource = OGR_Dr_CreateDataSource(driver, pszFname, NULL);

    if (datasource == NULL)
    {
        printf("Unable to create %s\n", pszFname);
        return -1;
    }
    /* MapInfo data sources are created with one empty layer.
       Fetch the layer handle */
    layer = OGR_DS_GetLayer(datasource, 0);

    if (layer == NULL)
    {
        printf("Unable to create new layer in %s\n", pszFname);
        return -1;
    }


    /* Add a few fields to the layer defn */
    fieldDefn = OGR_Fld_Create("zumen", OFTString );
    OGR_L_CreateField(layer, fieldDefn, 0);
    fieldDefn = OGR_Fld_Create("kobetu", OFTString );
    OGR_L_CreateField(layer, fieldDefn, 1);

    /* We'll need the layerDefn handle to create new features in this layer */
    layerDefn = OGR_L_GetLayerDefn( layer );

    /* Create a new point */


	 rtn = OGRCRead(layer,layerDefn);
	 /*--数値地図データの読み込み--*/

 
    /* Close data source */
    OGR_DS_Destroy( datasource );


    return 0;
}

/**********************************************************************
 *                      OGRCRead()
 *
 * Create a new dataset using OGR C API with a few features in it.
 *数値地図の読み込みテスト
 **********************************************************************/

int OGRCRead(OGRLayerH layer,OGRFeatureDefnH  layerDefn){

	 int i, ri,j,k;
    FILE *fp,*afp;
    char fname[80];
	 char buff[STR_MAX], *pp;
	 OGRFeatureH     feature;
    OGRGeometryH    geometry;
	 double pX,pY;
	 struct arcH ah;/*--ファイルヘッダーレコードの構造体--*/
	 struct arcIDRec *arIR ,*new , *head ;/*--アークIDレコード--*/

	 fp = fopen("./23105/07MD933/gaiku/gaiku.arc","r");
	 if( fp == NULL ){
				printf("ファイルがオープンできません\n");
				exit(1);
    }
	j=0;

	//ヘッダーファイルの読み込み
	if(fgets(buff, STR_MAX, fp) != NULL){
      ri = sscanf(buff,"%2[^,],%30[^,],%40[^,],%d,%d,%d,%d,%d,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf",ah.FH,ah.zumei,ah.filename,&ah.recordC,&ah.fieldC,&ah.CoordFlag,&ah.Coordinate,&ah.kubun,&ah.llx,&ah.lly,&ah.rux,&ah.ruy,&ah.lux,&ah.luy,&ah.rlx,&ah.rly);
      printf("header:%s %d %d %d %d %f\n",ah.filename,ah.recordC,ah.fieldC,ah.Coordinate,ah.kubun,ah.rly);
//   	if( ri==16)break;
	}

	/*--構造体の確保--*/

    head  = createData();
	 arIR = head;
    while(fgets(buff, STR_MAX, fp) != NULL){        /* 永久ループ */
		 //オブジェクトヘッダーの解析

      k=0;
      ri = sscanf(buff,"%10[^,],%d,%d,%d",arIR->code,&arIR->lineTag,&arIR->pubKey,&arIR->count);
//      printf("re  %d/%d %s",k,j,buff);
		feature = OGR_F_Create( layerDefn );
	   OGR_F_SetFieldString( feature, 0, ah.zumei);
	   OGR_F_SetFieldString( feature, 1, arIR->code);

      geometry = OGR_G_CreateGeometry( wkbLineString );
		
      while(fgets(buff, STR_MAX, fp) != NULL ){  
			pX = 0;pY = 0;
//		   printf("%s",buff);
         ri = sscanf(buff,"%lf,%lf",&pY,&pX);
			arIR->pX[k] = ah.llx + pX;
			arIR->pY[k] = ah.lly + pY;
         OGR_G_AddPoint(geometry, pX, pY, 0);
          k++;
         if( k == arIR->count   ){
            break;
         }
		 }
       OGR_F_SetGeometryDirectly(feature, geometry);
	    OGR_L_CreateFeature( layer, feature );
	 	 j++;
	/*--構造体の確保--*/
       new = createData();
       arIR->next = new;
       arIR = new;
   }
    fclose(fp);    /* ファイルクローズ */
/*--属性ファイルの読み込み--*/
	 atr = readAtrFile();
/*--ポリゴンファイルの読み込み--*/
    readPgnFile(head);
	 
	 /*--メモリの開放--*/
	 freeData(head);
    return(0);

}


/**********************************************************************
 *                     ReadAtrFile()
 *
 * Create a new dataset using OGR C API with a few features in it.
 *数値地図の読み込みテスト
 **********************************************************************/

struct atrIDRec readAtrFile(const char *pszFname ){
		      char fname[80];
	 int i, ri,j,k;
    FILE *fp,*afp;
	 struct atrIDRec atrIR;

	 return(atrIDrec);
}




/**********************************************************************
 *                     ReadPgnFile()
 *
 * Create a new dataset using OGR C API with a few features in it.
 *数値地図の読み込みテスト
 **********************************************************************/



int readPgnFile(struct arcIDRec *arIR )
{
    char str[128];
	
    OGRSFDriverH    driver;
    int             i,rtn, numDrivers;
    OGRDataSourceH  datasource;
    OGRLayerH       layer;
    OGRFeatureDefnH layerDefn;
    OGRFieldDefnH   fieldDefn;
    OGRFeatureH     feature;
    OGRGeometryH    geometry, ring;

	 int  ri,j,k;
    FILE *fp,*afp;
    char fname[80];
	 char buff[STR_MAX], *pp;
	 double pX,pY;
	 int oNum;/*--アーク指定コード--*/
	 struct arcH ah;/*--ファイルヘッダーレコードの構造体--*/
	 struct pgnIDRec *pgnR;
	 struct arcIDRec *pgn2arc , *head ;/*--アークIDレコード--*/
	 char *pszFname = "testpgn.tab";

	     /* Register all OGR drivers */
    OGRRegisterAll();

    /* Fetch MITAB driver - we want to create a TAB file */
    numDrivers = OGRGetDriverCount();
    for(i=0; i<numDrivers; i++)
    {
        driver = OGRGetDriver(i);
//        printf("%d/%d  %s\n",i,numDrivers, OGR_Dr_GetName(driver));
//        if (EQUAL("DGN", OGR_Dr_GetName(driver)))
        if (EQUAL("MapInfo File", OGR_Dr_GetName(driver)))
            break;  /* Found it! */
        driver = NULL;
    }

    if (!driver)
    {
        printf("Driver not found!\n");
        return -1;
    }

    /* Create new file using this driver */
    datasource = OGR_Dr_CreateDataSource(driver, pszFname, NULL);

    if (datasource == NULL)
    {
        printf("Unable to create %s\n", pszFname);
        return -1;
    }
    /* MapInfo data sources are created with one empty layer.
       Fetch the layer handle */
    layer = OGR_DS_GetLayer(datasource, 0);

    if (layer == NULL)
    {
        printf("Unable to create new layer in %s\n", pszFname);
        return -1;
    }


    /* Add a few fields to the layer defn */
    fieldDefn = OGR_Fld_Create("zumen", OFTString );
    OGR_L_CreateField(layer, fieldDefn, 0);
    fieldDefn = OGR_Fld_Create("kobetu", OFTString );
    OGR_L_CreateField(layer, fieldDefn, 1);

    /* We'll need the layerDefn handle to create new features in this layer */
    layerDefn = OGR_L_GetLayerDefn( layer );

    /* Create a new point */

	 fp = fopen("./23105/07MD933/gaiku/gaiku.pgn","r");
	 if( fp == NULL ){
				printf("ファイルがオープンできません\n");
				exit(1);
    }

	j=0;
   pgnR = createPgnData();
	//ヘッダーファイルの読み込み
	if(fgets(buff, STR_MAX, fp) != NULL){
      ri = sscanf(buff,"%2[^,],%30[^,],%40[^,],%d,%d,%d,%d,%d,%lf,%lf,%lf,%lf,%lf,%lf,%lf,%lf",ah.FH,ah.zumei,ah.filename,&ah.recordC,&ah.fieldC,&ah.CoordFlag,&ah.Coordinate,&ah.kubun,&ah.llx,&ah.lly,&ah.rux,&ah.ruy,&ah.lux,&ah.luy,&ah.rlx,&ah.rly);
      printf("header:%s %d %d %d %d %f\n",ah.filename,ah.recordC,ah.fieldC,ah.Coordinate,ah.kubun,ah.rly);
//   	if( ri==16)break;
	}
     while(fgets(buff, STR_MAX, fp) != NULL){        /* 永久ループ */
		 //オブジェクトヘッダーの解析

      k=0;
      ri = sscanf(buff,"%10[^,],%d,%d,%d,%d",pgnR->code,&pgnR->pubKey,&pgnR->count,&pgnR->pX,&pgnR->pY);
		feature = OGR_F_Create( layerDefn );
	   OGR_F_SetFieldString( feature, 0, "a");
	   OGR_F_SetFieldString( feature, 1, "b");

	   geometry = OGR_G_CreateGeometry( wkbPolygon );
      ring = OGR_G_CreateGeometry( wkbLinearRing );
		
      while(fgets(buff, STR_MAX, fp) != NULL ){  
			pX = 0;pY = 0;
         ri = sscanf(buff,"%d",&oNum);
			pgn2arc = checkArcIDRecord(arIR,abs(oNum));
			
			if( oNum > 0 ){
					  for( i=0;i<pgn2arc->count;i++){
                    OGR_G_AddPoint(ring, pgn2arc->pX[i], pgn2arc->pY[i], 0);
				     }
			}else{
				  	  for( i=pgn2arc->count;i>0;i--){
                    OGR_G_AddPoint(ring, pgn2arc->pX[i-1], pgn2arc->pY[i-1], 0);
				     }
			}
          k++;
         if( k == pgnR->count   ){
            break;
         }
		 }
       OGR_G_AddGeometryDirectly(geometry, ring);
       OGR_F_SetGeometryDirectly(feature, geometry);
	    OGR_L_CreateFeature( layer, feature );
	 	 j++;
	/*--構造体の確保--*/
   }

    fclose(fp);    /* ファイルクローズ */
    /* Close data source */
    OGR_DS_Destroy( datasource );

		  return(0);
}
/*--
 *該当するアーク指定レコードの構造体を取り出す。
 --*/
struct arcIDRec *checkArcIDRecord(struct arcIDRec *arIR,int oNum){


		 if( arIR->pubKey == oNum){
		    return(arIR);
		 }else if( arIR->next == NULL ){
					printf("異常発生 %d %d\n",oNum,arIR->pubKey);
					exit(1);
		 }else{//再帰的呼び出し
		    checkArcIDRecord(arIR->next,oNum);
	    }
}



/*******************************************
*--
 *構造体の確保
 --******************************************* */

struct arcIDRec *createData(void)
{
       struct arcIDRec *data;

       data = (struct arcIDRec *)malloc(sizeof(struct arcIDRec));
       if(data == NULL) { exit(1); }

       data -> next = NULL;

       return data;
}
/*******************************************
 * メモリの開放
 ******************************************/

int freeData(struct arcIDRec *arIR ){

        struct arcIDRec *next;
		  next = arIR->next;
		  
		  free(arIR);

		  if( next == NULL ){/*--終りについたら--*/
		      return(0);/*--かいほうの終了--*/
		  }else{
					 freeData(next);/*--再帰的呼び出し--*/
		  }
}
/*--
 *構造体の確保
 --*/
struct pgnIDRec *createPgnData(void)
{
       struct pgnIDRec *data;

       data = (struct pgnIDRec *)malloc(sizeof(struct pgnIDRec));
       if(data == NULL) { exit(1); }

       data -> next = NULL;

       return data;
}
/*******************************************
 * メモリの開放
 ******************************************/

int freePgnData(struct pgnIDRec *pgnR ){

        struct pgnIDRec *next;
		  next = pgnR->next;
		  
		  free(pgnR);

		  if( next == NULL ){/*--終りについたら--*/
		      return(0);/*--かいほうの終了--*/
		  }else{
					 freePgnData(next);/*--再帰的呼び出し--*/
		  }
}
