[postgis-commits] svn - r2670 - branches/gSoC2007_raster/pgraster

postgis-commits at postgis.refractions.net postgis-commits at postgis.refractions.net
Tue Jul 24 14:30:30 PDT 2007


Author: xingkth
Date: 2007-07-24 14:30:29 -0700 (Tue, 24 Jul 2007)
New Revision: 2670

Added:
   branches/gSoC2007_raster/pgraster/Makefile
   branches/gSoC2007_raster/pgraster/README.geotiff2pgraster
   branches/gSoC2007_raster/pgraster/TODO.TXT
   branches/gSoC2007_raster/pgraster/compat.h
   branches/gSoC2007_raster/pgraster/geotiff2pgraster.c
   branches/gSoC2007_raster/pgraster/getopt.c
   branches/gSoC2007_raster/pgraster/getopt.h
   branches/gSoC2007_raster/pgraster/pgraster2geotiff.c
   branches/gSoC2007_raster/pgraster/pgraster_types.h
   branches/gSoC2007_raster/pgraster/pgraster_utils.c
   branches/gSoC2007_raster/pgraster/pgraster_utils.h
   branches/gSoC2007_raster/pgraster/pgraster_version.h
   branches/gSoC2007_raster/pgraster/test.c
   branches/gSoC2007_raster/pgraster/wkb.c
   branches/gSoC2007_raster/pgraster/wkb.h
Modified:
   branches/gSoC2007_raster/pgraster/pgraster_tables.sql
Log:
Xing.Lin: GoogleSoC2007_PGRaster Update 20070724

Added: branches/gSoC2007_raster/pgraster/Makefile
===================================================================
--- branches/gSoC2007_raster/pgraster/Makefile	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/Makefile	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,47 @@
+include ../Makefile.config
+
+# Version handling:
+include ../Version.config
+POSTGIS_VERSION = $(REL_MAJOR_VERSION).$(REL_MINOR_VERSION).$(REL_MICRO_VERSION)
+
+#
+# PostGIS/PGRaster Loader Makefile
+#
+
+OBJS = pgraster_utils.o getopt.o wkb.o
+
+#---------------------------------------------------------------
+
+ifeq ($(USE_ICONV),1)
+	override CFLAGS += -DUSE_ICONV
+	override LDFLAGS += $(ICONV_LDFLAGS)
+endif
+
+override CFLAGS := -g -Wall -I.. $(CFLAGS) -DUSE_VERSION=$(USE_VERSION) -DPOSTGIS_VERSION='"$(POSTGIS_VERSION)"'
+
+all: geotiff2pgraster$(EXE) pgraster2geotiff$(EXE) 
+
+geotiff2pgraster.o: geotiff2pgraster.c
+	$(CC) $(CFLAGS) $(PGFEINCLUDES) -c $<
+
+pgraster2geotiff.o: pgraster2geotiff.c
+	$(CC) $(CFLAGS) $(PGFEINCLUDES) -c $<
+
+geotiff2pgraster$(EXE): $(OBJS) geotiff2pgraster.o
+	$(CC) $(CFLAGS) $(OBJS) geotiff2pgraster.o $(LDFLAGS) $(PGFELIBS) -o $@ 
+
+pgraster2geotiff$(EXE): $(OBJS) pgraster2geotiff.o
+	$(CC) $(CFLAGS) $(OBJS) pgraster2geotiff.o $(LDFLAGS) $(PGFELIBS) -o $@  
+
+install: all
+	@mkdir -p $(DESTDIR)$(bindir)
+	$(INSTALL_BIN) geotiff2pgraster$(EXE) $(DESTDIR)$(bindir)/geotiff2pgraster$(EXE)
+	$(INSTALL_BIN) pgraster2geotiff$(EXE) $(DESTDIR)$(bindir)/pgraster2geotiff$(EXE)
+
+uninstall:
+	rm -f $(DESTDIR)$(bindir)/pgraster2geotiff$(EXE)
+	rm -f $(DESTDIR)$(bindir)/geotiff2pgraster$(EXE)
+
+clean:
+	rm -f $(OBJS) geotiff2pgraster.o pgraster2geotiff.o pgraster2geotiff$(EXE) pgraster2geotiff$(EXE)
+

Added: branches/gSoC2007_raster/pgraster/README.geotiff2pgraster
===================================================================
--- branches/gSoC2007_raster/pgraster/README.geotiff2pgraster	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/README.geotiff2pgraster	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,145 @@
+geotiff2pgraster(1)                 PostGIS                geotiff2pgraster(1)
+
+
+
+NAME
+       geotiff2pgraster - geotiff to postgis/pgraster loader
+
+
+SYNTAX
+       geotiff2pgraster [options] geotiff-file [[schema.]table]
+
+
+DESCRIPTION
+       The  geotiff2pgraster  data loader converts GeoTIFF(georeferenced imag-
+	   es) directly into a PostGIS/PGRaster database.
+
+       Version: 0.0.1 (2007/07/22)
+
+REFERENCE
+	   This programe  learn  some  of  its  functionality  from  these similar 
+	   programs:
+
+	   1. psql - standard PostgreSQL client programe
+	   2. shp2pgsql/pgsql2shp - PostGIS loader programmes for Shape files.
+	   3. GDAL GeoTIFF - geotiff reader for GDAL programe.
+
+
+USAGE
+       The <geotiff-file> is the pathname of the geotiff file with the extens-
+	   ion of one the fours: .tiff, .tif, .geotif, .geotiff. You should always
+	   specify a full path for the desitinate geotiff file. Otherwise this pr-
+	   ogram will search for the file in the name you input in the current wo-
+	   rking directory.
+
+	   The <table>  is  the  (optionally  schema-qualified)  name  of  the
+       database table you want the data stored in in the database. Within cur-
+	   rent PostGIS/PGRaster schema, one single raster dataset will be stored
+	   seperately into two tables: PGRASTER_MEDATA and PGRASTER_DATA table.
+	   You can specify a name here for the PGRASTER_DATA table which will have
+	   the same structure with default template PGRASTER_DATA table. If this 
+	   option is ignored, the same table name as the input filename will be u-
+	   sed. For examples:
+
+	   geotiff2pgraster [options...] us_tm19900710.geotiff <blank>
+	   
+	   Then the us_tm19900710 will be adopted as the data table name to store
+	   raster data.
+
+	   (TO BE CONTINUE...)
+
+OPTIONS
+       The  loader  has  several operating modes distinguished by command line
+       flags:
+
+	   #######################  (NOT SUPPORTED YET)  #########################
+	   (Note that -a, -c, -d and -p are mutually exclusive.)
+
+	   -d     Drops the database table before creating a new  table  with  the
+              data in the geotiff file. 
+	   
+ 	   -a     Appends  data  from the geotiff file into the existing database 
+	   		  table. Although it is not recommended to store raw data of sever-
+			  ral raster dataset into one raster data table (sharing). But if 
+			  you insist, you can do it by this option.
+	  
+	   -c     Creates a new table and populates it from the geotiff file. This
+              is the default mode.
+
+       -p     Only produces the table creation SQL code,  without  adding  any
+              actual  data.   This can be used if you need to completely sepa-
+              rate the table creation and data loading steps.
+			  (NOT SUPPORTED YET)
+
+       -D     Use the PostgreSQL "dump" format for the output data.  This  can
+              be  combined  with -a, -c and -d. It is much faster to load than
+              the default "insert" SQL format. Use this for  very  large  data
+              sets. If this option is set, then the following options could be
+			  ignored.	   
+	   #######################  (NOT SUPPORTED YET)  #########################
+
+	   -h <host>
+              The database host to connect to. If ignored, the default address
+			  of host will be "localhost/127.0.0.1". If no database running on
+			  this host, the program will exit immediately with a error msg.
+
+       -p <port>
+              The port  to connect to  on the  database  host. If ignored, the
+			  standard port number of 5432 will be used.If no database running
+			  on this port, the program will exit immediately with a error msg.
+
+	   -d <database>
+	   		  The database to use when connecting. If ignored, the current  OS
+			  username will be used the name of database to login into. If this 
+			  database is refused to login, the program will exit immediately 
+			  with a error message.
+
+       -P <password>
+              The password to use when connecting to the database. This option
+			  can't be ignored. If this password is refused to login, the pro-
+			  gram will exit immediately with a error message.
+
+       -u <user>
+              The username to use when connecting to the database. If ignored,
+			  the current OS username will be used to login into the database.
+			  If this username  is  refused to login, the  program  will  exit 
+			  immediately with a error message.
+		
+	   -k     Keep idendifiers case (don't uppercase field names).				
+
+       -?/--help	
+	   		  Display version and usage information.
+
+INSTALLATION
+       To compile the program from source, simply run  "make"  in  the  source
+       directory.  Then copy the binary in your shell search path (or wherever
+       you like). This text is also available as a man page in the ../doc/man/
+       directory,  ready for copying it into the manual search path on unixoid
+       systems.
+
+
+EXAMPLES
+       An example session using the loader to create an input file and upload-
+       ing it might look like this:
+
+       # geotiff2pgraster -d -h localhost -p 5432 -u postgres -P "password" -k
+	                         "~/us_images/us_tm1990.tiff"
+
+AUTHORS
+       Originally written and maintained by Xing Lin <solo.lin at gmail.com>.
+       
+       <Declaration of some other functions>
+	   This  application  uses  functionality  from  shapelib  1.2.9  by Frank
+       Warmerdam <warmerda at gdal.velocet.ca> to read from ESRI Shape files.
+
+
+SEE ALSO
+       pgraster2geotiff(1)
+
+       More information is available at http://postgis.refractions.net
+
+	   Any problem with this programe, do contact xing <solo.lin at gmail.com>.
+
+
+
+                                                           geotiff2pgraster(1)

Added: branches/gSoC2007_raster/pgraster/TODO.TXT
===================================================================
--- branches/gSoC2007_raster/pgraster/TODO.TXT	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/TODO.TXT	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,19 @@
+// TO DO List
+
+1. libgeotiff functions
+
+2. libpq functions (x)
+
+3. create table and insert data.
+
+4. create datatypes / structure for PGRaster (x).
+
+5. byte order / big&little endian / network byte order
+
+6. ntohl() - network 32 bit integer to local byte order converter.
+
+7. pgraster and postgis share the same proj system. 
+
+8. UTF-8 Conversion
+
+9. Create functions in the server side using plpgsql (x). 

Added: branches/gSoC2007_raster/pgraster/compat.h
===================================================================
--- branches/gSoC2007_raster/pgraster/compat.h	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/compat.h	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,12 @@
+#ifndef _COMPAT_H
+#define _COMPAT_H 1
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#if USE_VERSION < 73
+unsigned char *PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen);
+#endif
+
+#endif /* ifndef _COMPAT_H */

Added: branches/gSoC2007_raster/pgraster/geotiff2pgraster.c
===================================================================
--- branches/gSoC2007_raster/pgraster/geotiff2pgraster.c	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/geotiff2pgraster.c	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,747 @@
+/**********************************************************************
+ * $Id: geotiff2pgraster.c 2007-07-22 XingLin $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2003 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ * 
+ **********************************************************************
+ *
+ * PGRaster - Raster/Coverage Model for PostgreSQL/PostGIS
+ *
+ **********************************************************************
+ * 
+ * File Name: 		geotiff2pgraster.c
+ *
+ * Author: 			Xing Lin <solo.lin at gmail.com>
+ *
+ * Create Date: 	2007-07-22
+ *
+ * Description: 	GeoTIFF to PGRaster Converter
+ *
+ * Original Author: Xing Lin <solo.lin at gmail.com>
+ *
+ * Maintainer:  	Xing Lin <solo.lin at gmail.com>
+ *
+ * Last Update: 	2007-07-22
+ *
+ **********************************************************************/
+
+static char rcsid[] =
+  "$Id: geotiff2pgraster.c 2007-07-22 Xing.Lin $";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <sys/types.h>
+/* Solaris9 does not provide stdint.h */
+/* #include <stdint.h> */
+#include <inttypes.h>
+#include "libpq-fe.h"
+#include "getopt.h"
+#include "pgraster_const.h"
+#include "pgraster_types.h"
+#include "pgraster_utils.h"
+#include "pgraster_version.h"
+#include "wkb.h"
+#include "compat.h"
+/* Used to help create tempate tables names */
+#include <sys/types.h> // for getpid()
+#include <unistd.h> // for getpid()
+
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+
+#ifdef __CYGWIN__
+#include <sys/param.h>       
+#endif
+
+/* Debug Control Flag */
+/* #define DEBUG 1 */
+
+/*
+ * Verbosity:
+ *   set to 1 to see record fetching progress
+ *   set to 2 to see also shapefile creation progress
+ *   set to 3 for debugging
+ */
+#define VERBOSE 1
+
+/* Global data */
+PGconn *conn;
+PGresult *res;
+int rowbuflen;
+char *table, *geotiff_file, *schema, *geotiff_filename;
+int keep_fieldname_case = 0;
+int big_endian = 0;
+int pgis_major_version;
+char *PG_VERSION = "8.2.4\0";
+PGRasterMetadata metadata;
+#ifdef USE_ICONV
+char	*encoding=NULL;
+#endif
+
+/* Prototypes */
+char * getTableOID(char *schema, char *table);
+void usage(char* me, int status, FILE* out);
+int parse_commandline(int ARGC, char **ARGV);
+static void parse_table(char *spec);
+static void parse_geotiffname(char *spec);
+static void exit_nicely(PGconn *conn, int code);
+int get_pgraster_version(void);
+int get_postgis_version(void);
+
+/* Functions for Data Loading */
+
+/* Step 1. Initialization*/
+void Initialization();
+
+/* Step 2. LoadData */
+void LoadData();
+
+/* Step 3. CreateIndex() */
+void CreateIndex();
+
+/* Step 4. LoadSRS */
+void LoadSRS();
+
+/* Step 5. UpdateMetadata */
+void UpdateMetadata();
+
+/* Step 6. Cleanup */
+void Cleanup();
+
+/* Step 7. PrintResultMessage */
+void PrintResultMessage();
+
+#ifdef USE_ICONV
+char *utf8(const char *fromcode, char *inputbuf);
+#endif
+
+void *safe_malloc(size_t size)
+{
+	void *ret = malloc(size);
+	if ( ! ret ) {
+		fprintf(stderr, "Out of virtual memory\n");
+		exit(1);
+	}
+	return ret;
+}
+
+#define malloc(x) safe_malloc(x)
+
+
+/* Main Programe */
+int main(int ARGC, char **ARGV)
+{
+	/* Definition and Initialization for local/global variables */
+	int 		row;
+	char		buf[256];
+
+	geotiff_file = NULL;
+	table = NULL;
+	schema = NULL;
+	geotiff_filename = NULL;
+	rowbuflen=100;
+	keep_fieldname_case = 0;
+	conn = NULL;
+	res = NULL;
+
+	// Initialize PGRasterMetadata Structure
+	initialize_metadata(&metadata);
+
+#ifdef DEBUG
+	FILE *debug;
+#endif
+
+	if ( getenv("ROWBUFLEN") ) rowbuflen=atoi(getenv("ROWBUFLEN"));
+	/*
+	 * Make sure dates are returned in ISO
+	 * style (YYYY-MM-DD).
+	 * This is to allow goodDBFValue() function 
+	 * to successfully extract YYYYMMDD format
+	 * expected in shapefile's dbf file.
+	 */
+	putenv("PGDATESTYLE=ISO");
+
+	if ( ! parse_commandline(ARGC, ARGV) ) {
+                printf("\n**ERROR** invalid option or command parameters\n\n");
+		usage(ARGV[0], 2, stderr);
+	}
+
+#ifdef DEBUG
+	if(	getenv("PGHOST") != NULL && getenv("PGUSER") != NULL && 
+		getenv("PGPORT") != NULL && getenv("PGDATABASE") != NULL && 
+		getenv("PGPASSWORD") != NULL
+		)
+		printf("PGHOST=%s PGPORT=%s PGDATABASE=%s PGUSER=%s PGPASSWORD=%s\n",
+				getenv("PGHOST"), getenv("PGPORT"), getenv("PGDATABASE"),
+				getenv("PGUSER"), getenv("PGPASSWORD"));
+	printf("SCHEMA=%s TABLE=%s geotiff_file=%s geotiff_filename=%s\n",schema,table,geotiff_file,geotiff_filename);
+#endif
+
+	/* Step 1. Initialization & Create PreparedStatement for Data Insert*/
+	Initialization();
+
+	/* Step 2. Read GeoTIFF Data & Insert into PGRaster via PreparedStatement */
+	LoadData();
+
+	/* Step 3. Run Build GiST Index Statement at the Server-Side */
+	CreateIndex();
+
+	/* Step 4. LoadSRS */
+	LoadSRS();
+
+	/* Step 5. UpdateMetadata */
+	UpdateMetadata();
+
+	/* Step 5. Cleanup & Close Connection*/
+	Cleanup();
+
+	/* Step 6. Function Successfully Return and Send Message To Terminal or Log */
+	PrintResultMessage();
+
+	return 1;
+}
+
+/******** Implementation of Functions ********/
+
+/* 
+ * Return allocate memory. Free after use.
+ */
+char * getTableOID(char *schema, char *table)
+{
+	PGresult *res3;
+	char *query;
+	char *ret;
+	size_t size;
+
+	size = strlen(table)+256;
+	if ( schema ) size += strlen(schema)+1;
+
+	query = (char *)malloc(size);
+
+	if ( schema )
+	{
+		sprintf(query, "SELECT oid FROM pg_class c, pg_namespace n WHERE c.relnamespace n.oid AND n.nspname = '%s' AND c.relname = '%s'", schema, table);
+	} else {
+		sprintf(query, "SELECT oid FROM pg_class WHERE relname = '%s'", table);
+	}
+
+	res3 = PQexec(conn, query);
+	free(query);
+	if ( ! res3 || PQresultStatus(res3) != PGRES_TUPLES_OK ) {
+		printf( "TableOID: %s", PQerrorMessage(conn));
+		exit_nicely(conn, 1);
+	}
+	if(PQntuples(res3) == 1 ){
+		ret = strdup(PQgetvalue(res3, 0, 0));
+	}else if(PQntuples(res3) == 0 ){
+		printf( "Cannot find relation OID (does table exist?).\n");
+		PQclear(res3);
+		return NULL;
+	}else{
+		ret = strdup(PQgetvalue(res3, 0, 0));
+		printf( "Warning: Multiple relations detected, the program will only dump the first relation.\n");
+	}	
+	PQclear(res3);
+	return ret;
+}
+
+/*
+ * Print the usage information to standard output destination (terminal, file or so on).
+ */
+void
+usage(char* me, int status, FILE* out)
+{
+    fprintf(out,"PostgreSQL Version: %s \\ PostGIS Version: %s\n", PG_VERSION, POSTGIS_VERSION);
+	fprintf(out,"RCSID: %s RELEASE: %s\n", rcsid, PGRASTER_VERSION);
+
+	fprintf(out,"USAGE: %s [<options>] geotiff-file [[<schema>.]<table>]\n", me);
+	
+	fprintf(out,"\n");
+
+	fprintf(out,"OPTIONS:\n");
+    
+	fprintf(out,"#######################  (NOT SUPPORTED YET)  #########################\n");
+    
+	fprintf(out,"(Note that -a, -c, -d and -p are mutually exclusive.)\n");	
+
+	fprintf(out," -d  Drops the database table before creating a new  table  with  the\n");
+    fprintf(out,"     data in the geotiff file.\n");
+
+	fprintf(out," -a  Appends  data  from the geotiff file into the existing database\n");
+    fprintf(out,"     table. Although it is not recommended to store raw data of sever-\n");
+	fprintf(out,"     ral raster dataset into one raster data table (sharing). But if\n");
+	fprintf(out,"     you insist, you can do it by this option\n");
+
+	fprintf(out," -c  Creates a new table and populates it from the geotiff file. This\n");
+    fprintf(out,"     is the default mode.\n");
+
+
+	fprintf(out," -p  Only produces the table creation SQL code,  without  adding  any\n");
+    fprintf(out,"     actual data. This can be used if you need to completely seperate\n");
+	fprintf(out,"     the table creation and data loading steps.\n");
+	fprintf(out,"     (NOT SUPPORTED YET)\n");
+	
+	fprintf(out," -D  Use the PostgreSQL \"dump\" format for the output data.  This  can\n");
+    fprintf(out,"     be  combined  with -a, -c and -d. It is much faster to load than\n");
+	fprintf(out,"     the default \"insert\" SQL format. Use this for  very  large  data\n");
+	fprintf(out,"     sets. If this option is set, then the following options could be\n");
+	fprintf(out,"     ignored.\n");
+	fprintf(out,"     (NOT SUPPORTED YET)\n");
+
+	fprintf(out,"#######################  (NOT SUPPORTED YET)  #########################\n");
+    
+	fprintf(out,"\n");
+
+	fprintf(out," -h <host>\n");
+	fprintf(out,"     The database host to connect to. If ignored, the default address\n");
+    fprintf(out,"     of host will be \"localhost/127.0.0.1\". If no database running on\n");
+	fprintf(out,"     this host, the program will exit immediately with a error msg.\n");
+
+	fprintf(out," -p <port>\n");
+	fprintf(out,"     The port  to connect to  on the  database  host. If ignored, the\n");
+    fprintf(out,"     standard port number of 5432 will be used.If no database running\n");
+	fprintf(out,"     on this port, the program will exit immediately with a error msg.\n");
+
+	fprintf(out," -d <database>\n");
+	fprintf(out,"     The database to use when connecting. If ignored, the current  OS\n");
+    fprintf(out,"     username will be used the name of database to login into. If this\n");
+	fprintf(out,"     database is refused to login, the program will exit immediately\n");
+	fprintf(out,"     with a error message.\n");
+	
+	fprintf(out," -P <password>\n");
+	fprintf(out,"     The password to use when connecting to the database. This option\n");
+    fprintf(out,"     can't be ignored. If this password is refused to login, the pro-\n");
+	fprintf(out,"     gram will exit immediately with a error message.\n");
+
+	
+	fprintf(out," -U <user>\n");
+	fprintf(out,"     The username to use when connecting to the database. If ignored,\n");
+    fprintf(out,"     the current OS username will be used to login into the database.\n");
+	fprintf(out,"     If this username  is  refused to login, the  program  will  exit\n");
+	fprintf(out,"     immediately with a error message.\n");
+	
+	fprintf(out," -k  			Keep postgresql identifiers case.\n");
+    fprintf(out," -?/--help 	Display this help screen.\n");
+
+    fprintf(out,"\n");
+    
+	exit (status);
+}
+
+/* Parse command line parameters */
+int parse_commandline(int ARGC, char **ARGV)
+{
+    if ( ARGC == 1 ) {
+		usage(ARGV[0], 0, stdout);
+    }
+
+	int c, curindex;
+	char buf[1024];
+
+	buf[1023] = '\0'; 
+
+	/* Parse command line */
+    while ((c = getopt(ARGC, ARGV, "h:d:U:p:P:rk")) != EOF){
+		switch (c) {
+			case 'h':
+				/*setenv("PGHOST", optarg, 1); */
+				snprintf(buf, 255, "PGHOST=%s", optarg);				
+				putenv(strdup(buf));
+				break;
+			case 'd':
+				/*setenv("PGHOST", optarg, 1); */
+				snprintf(buf, 255, "PGDATABASE=%s", optarg);
+				putenv(strdup(buf));
+				break;
+			case 'U':
+				/*setenv("PGUSER", optarg, 1); */
+				snprintf(buf, 255, "PGUSER=%s", optarg);
+				putenv(strdup(buf));
+				break;
+			case 'p':
+				/*setenv("PGPORT", optarg, 1); */
+				snprintf(buf, 255, "PGPORT=%s", optarg);
+				putenv(strdup(buf));
+				break;
+			case 'P':
+				/*setenv("PGPASSWORD", optarg, 1); */
+				snprintf(buf, 255, "PGPASSWORD=%s", optarg);
+				putenv(strdup(buf));
+				break;			
+			case 'k':
+				keep_fieldname_case = 1;
+				break;
+			case '?':
+                usage(ARGV[0], 0, stdout);
+			default:
+				return 0;
+		}
+    }
+
+    curindex=0;
+    for (; optind<ARGC; optind++){
+		if (curindex == 0) {
+	    	geotiff_file = ARGV[optind];
+			schema = "public\0";
+			parse_geotiffname(geotiff_file);
+			table = geotiff_filename;
+        }else if(curindex == 1){
+			parse_table(ARGV[optind]);
+		}
+		curindex++;		
+    }
+
+	/* 
+	 * Transform table name to lower case unless asked
+	 * to keep original case (we'll quote it later on)
+	 */
+	if (keep_fieldname_case == 1)
+	{
+		LowerCase(table);
+		if ( schema ) LowerCase(schema);
+	}
+
+	// could only have on operant of geotiff_file
+    if (curindex < 1) 
+		return 0;
+
+	return 1;
+}
+
+/*
+ * Get a table (and optionally a schema) if there  is any.
+ * The table option could be ommited if user choose to use
+ * the same table name as the input geotiff filename.
+ */
+static void parse_table(char *spec)
+{
+	char *ptr;
+    
+	table = spec;
+	if ( (ptr=strchr(table, '.')) )	
+	{
+			*ptr = '\0';
+			schema = table;
+			table = ptr+1; 
+			//Do it need to add '\0' after the input spec???
+	}
+}
+
+/*
+ * Parse the filename from geotiff_file path. Typical geotiff_file looks like:
+ * 1) /home/pgraster/data/usa_tm1990.tif
+ * 2) usa_tm1990.tif
+ */
+static void parse_geotiffname(char *spec)
+{
+	char	*ptr;
+	char	*strTemp;
+    int		nlen;
+	int 	nlen2;
+
+
+	if(spec == NULL)
+		return;
+
+	nlen = strlen(spec);
+
+	strTemp = (char*)malloc(sizeof(char)*nlen+1);
+	strTemp = strcpy(strTemp, spec);
+	strTemp[nlen-1]='\0';
+
+	if ( (ptr=strrchr(strTemp, '.')) )	
+	{
+			*ptr = '\0';
+			if( (ptr=strrchr(strTemp,92)) || (ptr=strrchr(strTemp,'/')) ) 
+				// how to deal with '/' and '\' different OS.
+			{
+				ptr = ptr+1;
+				nlen2 = strlen(ptr);
+				geotiff_filename = (char*)malloc(sizeof(char)*nlen2+1);
+				geotiff_filename = strcpy(geotiff_filename, ptr);
+			}
+			else
+			{
+				ptr = strTemp;
+				nlen2 = strlen(ptr);
+				geotiff_filename=(char*)malloc(sizeof(char)*nlen2+1);
+				geotiff_filename = strcpy(geotiff_filename, ptr);
+			}
+	}
+}
+
+/*
+ * Exit Nicely for PostgreSQL Client that uses libpq-fe.
+ */
+static void exit_nicely(PGconn *conn, int code)
+{
+	PQfinish(conn);
+	exit(code);
+}
+
+/*
+ * Get PostGIS Major Version.
+ */
+int get_postgis_major_version(void)
+{
+	PGresult *res;
+	char *version;
+	int ver;
+	char query[] = "SELECT postgis_version()";
+	res = PQexec(conn, query);
+
+	if ( ! res || PQresultStatus(res) != PGRES_TUPLES_OK ) {
+		printf( "Can't detect postgis version:\n");
+		printf( "PostgisVersionQuery: %s",
+			PQerrorMessage(conn));
+		exit(1);
+	}
+
+	version = PQgetvalue(res, 0, 0);
+	ver = atoi(version);
+	PQclear(res);
+	return ver;
+}
+
+/*
+ * Get PGRaster Major Version
+ */
+int get_pgraster_version(void)
+{
+	PGresult *res;
+	char *version;
+	int ver;
+	char query[] = "SELECT pgraster_version()";
+	res = PQexec(conn, query);
+
+	if ( ! res || PQresultStatus(res) != PGRES_TUPLES_OK ) {
+		printf( "Can't detect postgis version:\n");
+		printf( "PostgisVersionQuery: %s",
+			PQerrorMessage(conn));
+		exit(1);
+	}
+
+	version = PQgetvalue(res, 0, 0);
+	ver = atoi(version);
+	PQclear(res);
+	return ver;
+}
+
+/*
+ * Initialization - Create table and prepare metadata information for import.
+ *
+ * (To Be Finished...)
+ *
+ */
+int Initialize(void)
+{
+
+	PGresult *res;
+
+	res = NULL;
+
+	return 0;
+}
+
+
+/* make_good_string from shp_loader*/
+char * make_good_string(char *str)
+{
+	/*
+	 * find all the tabs and make them \<tab>s
+	 *
+	 * 1. find # of tabs
+	 * 2. make new string 
+	 *
+	 * we dont escape already escaped tabs
+	 */
+
+	char *result;
+	char *ptr, *optr;
+	int toescape = 0;
+	size_t size;
+#ifdef USE_ICONV
+	char *utf8str=NULL;
+
+	if ( encoding )
+	{
+		utf8str=utf8(encoding, str);
+		if ( ! utf8str ) exit(1);
+		str = utf8str; 
+	}
+#endif
+
+	ptr = str;
+
+	while (*ptr) {
+		if ( *ptr == '\t' || *ptr == '\\' ) toescape++;
+		ptr++;
+	}
+
+	if (toescape == 0) return str;
+
+	size = ptr-str+toescape+1;
+
+	result = calloc(1, size);
+
+	optr=result;
+	ptr=str;
+	while (*ptr) {
+		if ( *ptr == '\t' || *ptr == '\\' ) *optr++='\\';
+		*optr++=*ptr++;
+	}
+	*optr='\0';
+
+#ifdef USE_ICONV
+	if ( encoding ) free(str);
+#endif
+
+	return result;
+	
+}
+
+/* protect_quotes_string from shp_loader*/
+char * protect_quotes_string(char *str)
+{
+	/*
+	 * find all quotes and make them \quotes
+	 * find all '\' and make them '\\'
+	 * 	 
+	 * 1. find # of characters
+	 * 2. make new string 
+	 */
+
+	char	*result;
+	char	*ptr, *optr;
+	int	toescape = 0;
+	size_t size;
+#ifdef USE_ICONV
+	char *utf8str=NULL;
+
+	if ( encoding )
+	{
+		utf8str=utf8(encoding, str);
+		if ( ! utf8str ) exit(1);
+		str = utf8str; 
+	}
+#endif
+
+	ptr = str;
+
+	while (*ptr) {
+		if ( *ptr == '\'' || *ptr == '\\' ) toescape++;
+		ptr++;
+	}
+
+	if (toescape == 0) return str;
+	
+	size = ptr-str+toescape+1;
+
+	result = calloc(1, size);
+
+	optr=result;
+	ptr=str;
+	while (*ptr) {
+		if ( *ptr == '\'' || *ptr == '\\' ) *optr++='\\';
+		*optr++=*ptr++;
+	}
+	*optr='\0';
+
+#ifdef USE_ICONV
+	if ( encoding ) free(str);
+#endif
+
+	return result;
+}
+
+/* Functions for Data Loading */
+
+/* Step 1. Initialization*/
+void Initialization()
+{
+	/* Declare local variable */
+	char* metaInsert = NULL;
+	
+	/* Make a connection to the specified database, and exit on failure */
+	// All the necessary information is stored in OS Env-Variables
+	conn = PQconnectdb("");
+	if (PQstatus(conn) == CONNECTION_BAD) {
+		printf( "%s", PQerrorMessage(conn));
+		exit_nicely(conn, 1);
+	}
+
+#ifdef DEBUG
+	debug = fopen("/tmp/geotiff2pgraster.log", "w");
+	PQtrace(conn, debug);
+#endif	 /* DEBUG */
+
+	/*
+	 * Begin the transaction
+	 * (a cursor can only be defined inside a transaction block)
+	 */
+	res=PQexec(conn, "BEGIN");
+	if ( ! res || PQresultStatus(res) != PGRES_COMMAND_OK ) {
+		printf( "%s", PQerrorMessage(conn));
+		exit_nicely(conn, 1);
+	}
+	PQclear(res);
+
+	/* Insert a new record in the PGRASTER_METADATA table
+	 * If error, such as there is no PGRASTER_METADATA table exist,
+	 * this programe will exit abnormally.
+	 */
+	metaInsert = "";
+		
+
+}
+
+/* Step 2. LoadData */
+void LoadData()
+{
+
+}
+
+/* Step 3. CreateIndex() */
+void CreateIndex()
+{
+
+}
+
+/* Step 4. LoadSRS */
+void LoadSRS()
+{
+
+}
+
+/* Step 5. UpdateMetadata */
+void UpdateMetadata()
+{
+
+}
+
+/* Step 6. Cleanup */
+void Cleanup()
+{
+	/* end the transaction */
+	res = PQexec(conn, "END");
+	PQclear(res);
+
+	/* Close Connection*/
+	exit_nicely(conn,1);
+}
+
+/* Step 7. PrintResultMessage */
+void PrintResultMessage()
+{
+	
+}
+

Added: branches/gSoC2007_raster/pgraster/getopt.c
===================================================================
--- branches/gSoC2007_raster/pgraster/getopt.c	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/getopt.c	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,695 @@
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include <stdio.h>
+
+#include "getopt.h"
+
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg = 0;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* XXX 1003.2 says this must be 1 before any call.  */
+int optind = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+#define BAD_OPTION '\0'
+int optopt = BAD_OPTION;
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+#ifdef	__GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+
+#include <string.h>
+#define	my_index	strchr
+#define	my_strlen	strlen
+#else
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+#if __STDC__ || defined(PROTO)
+extern int  strcmp (const char *s1, const char *s2);
+extern int  strncmp(const char *s1, const char *s2, int n);
+
+static int my_strlen(const char *s);
+static char *my_index (const char *str, int chr);
+#endif
+
+static int
+my_strlen (str)
+     const char *str;
+{
+  int n = 0;
+  while (*str++)
+    n++;
+  return n;
+}
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+	return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+#endif				/* GNU C library.  */
+
+extern char *getenv(const char *name);
+
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.
+
+   To perform the swap, we first reverse the order of all elements. So
+   all options now come before all non options, but they are in the
+   wrong order. So we put back the options and non options in original
+   order by reversing them again. For example:
+       original input:      a b c -x -y
+       reverse all:         -y -x c b a
+       reverse options:     -x -y c b a
+       reverse non options: -x -y a b c
+*/
+
+#if __STDC__ || defined(PROTO)
+static void exchange (char **argv);
+#endif
+
+static void
+exchange (argv)
+     char **argv;
+{
+  char *temp, **first, **last;
+
+  /* Reverse all the elements [first_nonopt, optind) */
+  first = &argv[first_nonopt];
+  last  = &argv[optind-1];
+  while (first < last) {
+    temp = *first; *first = *last; *last = temp; first++; last--;
+  }
+  /* Put back the options in order */
+  first = &argv[first_nonopt];
+  first_nonopt += (optind - last_nonopt);
+  last  = &argv[first_nonopt - 1];
+  while (first < last) {
+    temp = *first; *first = *last; *last = temp; first++; last--;
+  }
+
+  /* Put back the non options in order */
+  first = &argv[first_nonopt];
+  last_nonopt = optind;
+  last  = &argv[last_nonopt-1];
+  while (first < last) {
+    temp = *first; *first = *last; *last = temp; first++; last--;
+  }
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns `EOF'.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return BAD_OPTION after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return BAD_OPTION.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  int option_index;
+
+  optarg = 0;
+
+  /* Initialize the internal data when the first call is made.
+     Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  if (optind == 0)
+    {
+      first_nonopt = last_nonopt = optind = 1;
+
+      nextchar = NULL;
+
+      /* Determine how to handle the ordering of options and nonoptions.  */
+
+      if (optstring[0] == '-')
+	{
+	  ordering = RETURN_IN_ORDER;
+	  ++optstring;
+	}
+      else if (optstring[0] == '+')
+	{
+	  ordering = REQUIRE_ORDER;
+	  ++optstring;
+	}
+      else if (getenv ("POSIXLY_CORRECT") != NULL)
+	ordering = REQUIRE_ORDER;
+      else
+	ordering = PERMUTE;
+    }
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      if (ordering == PERMUTE)
+	{
+	  /* If we have just processed some options following some non-options,
+	     exchange them so that the options come first.  */
+
+	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+	    exchange ((char **) argv);
+	  else if (last_nonopt != optind)
+	    first_nonopt = optind;
+
+	  /* Now skip any additional non-options
+	     and extend the range of non-options previously skipped.  */
+
+	  while (optind < argc
+		 && (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+		 && (longopts == NULL
+		     || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif				/* GETOPT_COMPAT */
+		 )
+	    optind++;
+	  last_nonopt = optind;
+	}
+
+      /* Special ARGV-element `--' means premature end of options.
+	 Skip it like a null option,
+	 then exchange with previous non-options as if it were an option,
+	 then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+	{
+	  optind++;
+
+	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+	    exchange ((char **) argv);
+	  else if (first_nonopt == last_nonopt)
+	    first_nonopt = optind;
+	  last_nonopt = argc;
+
+	  optind = argc;
+	}
+
+      /* If we have done all the ARGV-elements, stop the scan
+	 and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+	{
+	  /* Set the next-arg-index to point at the non-options
+	     that we previously skipped, so the caller will digest them.  */
+	  if (first_nonopt != last_nonopt)
+	    optind = first_nonopt;
+	  return EOF;
+	}
+
+      /* If we have come to a non-option and did not permute it,
+	 either stop the scan or describe it to the caller and pass it by.  */
+
+      if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
+#ifdef GETOPT_COMPAT
+	  && (longopts == NULL
+	      || argv[optind][0] != '+' || argv[optind][1] == '\0')
+#endif				/* GETOPT_COMPAT */
+	  )
+	{
+	  if (ordering == REQUIRE_ORDER)
+	    return EOF;
+	  optarg = argv[optind++];
+	  return 1;
+	}
+
+      /* We have found another option-ARGV-element.
+	 Start decoding its characters.  */
+
+      nextchar = (argv[optind] + 1
+		  + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  if (longopts != NULL
+      && ((argv[optind][0] == '-'
+	   && (argv[optind][1] == '-' || long_only))
+#ifdef GETOPT_COMPAT
+	  || argv[optind][0] == '+'
+#endif				/* GETOPT_COMPAT */
+	  ))
+    {
+      const struct option *p;
+      char *s = nextchar;
+      int exact = 0;
+      int ambig = 0;
+      const struct option *pfound = NULL;
+      int indfound = 0;
+
+      while (*s && *s != '=')
+	s++;
+
+      /* Test all options for either exact match or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name;
+	   p++, option_index++)
+	if (!strncmp (p->name, nextchar, s - nextchar))
+	  {
+	    if (s - nextchar == my_strlen (p->name))
+	      {
+		/* Exact match found.  */
+		pfound = p;
+		indfound = option_index;
+		exact = 1;
+		break;
+	      }
+	    else if (pfound == NULL)
+	      {
+		/* First nonexact match found.  */
+		pfound = p;
+		indfound = option_index;
+	      }
+	    else
+	      /* Second nonexact match found.  */
+	      ambig = 1;
+	  }
+
+      if (ambig && !exact)
+	{
+	  if (opterr)
+	    fprintf (stderr, "%s: option `%s' is ambiguous\n",
+		     argv[0], argv[optind]);
+	  nextchar += my_strlen (nextchar);
+	  optind++;
+	  return BAD_OPTION;
+	}
+
+      if (pfound != NULL)
+	{
+	  option_index = indfound;
+	  optind++;
+	  if (*s)
+	    {
+	      /* Don't test has_arg with >, because some C compilers don't
+		 allow it to be used on enums.  */
+	      if (pfound->has_arg)
+		optarg = s + 1;
+	      else
+		{
+		  if (opterr)
+		    {
+		      if (argv[optind - 1][1] == '-')
+			/* --option */
+			fprintf (stderr,
+				 "%s: option `--%s' doesn't allow an argument\n",
+				 argv[0], pfound->name);
+		      else
+			/* +option or -option */
+			fprintf (stderr,
+			     "%s: option `%c%s' doesn't allow an argument\n",
+			     argv[0], argv[optind - 1][0], pfound->name);
+		    }
+		  nextchar += my_strlen (nextchar);
+		  return BAD_OPTION;
+		}
+	    }
+	  else if (pfound->has_arg == 1)
+	    {
+	      if (optind < argc)
+		optarg = argv[optind++];
+	      else
+		{
+		  if (opterr)
+		    fprintf (stderr, "%s: option `%s' requires an argument\n",
+			     argv[0], argv[optind - 1]);
+		  nextchar += my_strlen (nextchar);
+		  return optstring[0] == ':' ? ':' : BAD_OPTION;
+		}
+	    }
+	  nextchar += my_strlen (nextchar);
+	  if (longind != NULL)
+	    *longind = option_index;
+	  if (pfound->flag)
+	    {
+	      *(pfound->flag) = pfound->val;
+	      return 0;
+	    }
+	  return pfound->val;
+	}
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+	 or the option starts with '--' or is not a valid short
+	 option, then it's an error.
+	 Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+#ifdef GETOPT_COMPAT
+	  || argv[optind][0] == '+'
+#endif				/* GETOPT_COMPAT */
+	  || my_index (optstring, *nextchar) == NULL)
+	{
+	  if (opterr)
+	    {
+	      if (argv[optind][1] == '-')
+		/* --option */
+		fprintf (stderr, "%s: unrecognized option `--%s'\n",
+			 argv[0], nextchar);
+	      else
+		/* +option or -option */
+		fprintf (stderr, "%s: unrecognized option `%c%s'\n",
+			 argv[0], argv[optind][0], nextchar);
+	    }
+	  nextchar = (char *) "";
+	  optind++;
+	  return BAD_OPTION;
+	}
+    }
+
+  /* Look at and handle the next option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+	if (opterr)
+	  {
+#if 0
+	    if (c < 040 || c >= 0177)
+	      fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+		       argv[0], c);
+	    else
+	      fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
+#else
+	    /* 1003.2 specifies the format of this message.  */
+	    fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+#endif
+	  }
+	optopt = c;
+	return BAD_OPTION;
+      }
+    if (temp[1] == ':')
+      {
+	if (temp[2] == ':')
+	  {
+	    /* This is an option that accepts an argument optionally.  */
+	    if (*nextchar != '\0')
+	      {
+		optarg = nextchar;
+		optind++;
+	      }
+	    else
+	      optarg = 0;
+	    nextchar = NULL;
+	  }
+	else
+	  {
+	    /* This is an option that requires an argument.  */
+	    if (*nextchar != '\0')
+	      {
+		optarg = nextchar;
+		/* If we end this ARGV-element by taking the rest as an arg,
+		   we must advance to the next element now.  */
+		optind++;
+	      }
+	    else if (optind == argc)
+	      {
+		if (opterr)
+		  {
+#if 0
+		    fprintf (stderr, "%s: option `-%c' requires an argument\n",
+			     argv[0], c);
+#else
+		    /* 1003.2 specifies the format of this message.  */
+		    fprintf (stderr, "%s: option requires an argument -- %c\n",
+			     argv[0], c);
+#endif
+		  }
+		optopt = c;
+		if (optstring[0] == ':')
+		  c = ':';
+		else
+		  c = BAD_OPTION;
+	      }
+	    else
+	      /* We already incremented `optind' once;
+		 increment it again when taking next ARGV-elt as argument.  */
+	      optarg = argv[optind++];
+	    nextchar = NULL;
+	  }
+      }
+    return c;
+  }
+}
+
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+			   (const struct option *) 0,
+			   (int *) 0,
+			   0);
+}
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* #endif	  _LIBC or not __GNU_LIBRARY__.  */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == EOF)
+	break;
+
+      switch (c)
+	{
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	  if (digit_optind != 0 && digit_optind != this_option_optind)
+	    printf ("digits occur in two different argv-elements.\n");
+	  digit_optind = this_option_optind;
+	  printf ("option %c\n", c);
+	  break;
+
+	case 'a':
+	  printf ("option a\n");
+	  break;
+
+	case 'b':
+	  printf ("option b\n");
+	  break;
+
+	case 'c':
+	  printf ("option c with value `%s'\n", optarg);
+	  break;
+
+	case BAD_OPTION:
+	  break;
+
+	default:
+	  printf ("?? getopt returned character code 0%o ??\n", c);
+	}
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+	printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */

Added: branches/gSoC2007_raster/pgraster/getopt.h
===================================================================
--- branches/gSoC2007_raster/pgraster/getopt.h	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/getopt.h	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,127 @@
+/* Declarations for getopt.
+   Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns EOF, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument		(or 0) if the option does not take an argument,
+   required_argument	(or 1) if the option requires an argument,
+   optional_argument 	(or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+#if	__STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define	no_argument		0
+#define required_argument	1
+#define optional_argument	2
+
+#if __STDC__ || defined(PROTO)
+#if defined(__GNU_LIBRARY__)
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#endif /* not __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+		        const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind,
+			     int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* not __STDC__ */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */

Added: branches/gSoC2007_raster/pgraster/pgraster2geotiff.c
===================================================================
--- branches/gSoC2007_raster/pgraster/pgraster2geotiff.c	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/pgraster2geotiff.c	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,97 @@
+/**********************************************************************
+ * $Id: pgraster2geotiff.c 2007-07-22 XingLin $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2003 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ * 
+ **********************************************************************
+ *
+ * PGRaster - Raster/Coverage Model for PostgreSQL/PostGIS
+ *
+ **********************************************************************
+ * 
+ * File Name: 		pgraster2geotiff.c
+ *
+ * Author: 			Xing Lin <solo.lin at gmail.com>
+ *
+ * Create Date: 	2007-07-22
+ *
+ * Description: 	PGRaster To GeoTIFF Converter Programe.
+ *
+ * Original Author: Xing Lin <solo.lin at gmail.com>
+ *
+ * Maintainer:  	Xing Lin <solo.lin at gmail.com>
+ *
+ * Last Update: 	2007-07-22
+ **********************************************************************/
+
+static char rcsid[] =
+  "$Id: pgraster2geotiff.c 2007-07-22 Xing.Lin $";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <sys/types.h>
+/* Solaris9 does not provide stdint.h */
+/* #include <stdint.h> */
+#include <inttypes.h>
+#include "libpq-fe.h"
+#include "getopt.h"
+#include "pgraster_const.h"
+#include "pgraster_types.h"
+#include "pgraster_utils.h"
+#include "compat.h"
+/* Used to help create tempate tables names */
+#include <sys/types.h> // for getpid()
+#include <unistd.h> // for getpid()
+
+#ifdef __CYGWIN__
+#include <sys/param.h>       
+#endif
+
+/* Debug Control Flag */
+#define DEBUG 1
+
+/*
+ * Verbosity:
+ *   set to 1 to see record fetching progress
+ *   set to 2 to see also shapefile creation progress
+ *   set to 3 for debugging
+ */
+#define VERBOSE 1
+
+/* Global data */
+
+
+
+/* Prototypes */
+
+  
+/* Main Programe */
+int main(int ARGC, char **ARGV)
+{
+	/* Definition for local variables */
+
+	/* Read User Input */
+
+	/* Initialization & Create PreparedStatement for Data Insert */
+
+	/* Read Metadata from PGRaster & Write into GeoTIFF header via libgeotiff*/
+
+	/* Read Data from PGRaster & Write into GeoTIFF via libgeotiff functions*/
+
+	/* Close Files, PGConn and Clear PGresult*/
+
+	/* Function Successfully Return and Send Message To Terminal or Log */
+
+	return -1;
+}
+
+/******** Implementation of Functions ********/
+

Modified: branches/gSoC2007_raster/pgraster/pgraster_tables.sql
===================================================================
--- branches/gSoC2007_raster/pgraster/pgraster_tables.sql	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/pgraster_tables.sql	2007-07-24 21:30:29 UTC (rev 2670)
@@ -139,6 +139,7 @@
 	rasterBandType 			SMALLINT NOT NULL DEFAULT -1 REFERENCES pgraster_types_bandtype (typeid),
 	rasterDataType 			SMALLINT NOT NULL DEFAULT -1 REFERENCES pgraster_types_datatype (typeid),
 	rasterValueType 		SMALLINT NOT NULL DEFAULT -1 REFERENCES pgraster_types_valuetype (typeid),
+	rasterSchema			TEXT NOT NULL DEFAULT 'PUBLIC',
 	rasterDataTable 		TEXT NOT NULL DEFAULT 'PGRASTER_DATA',
 	rasterBandCount 		INTEGER NOT NULL DEFAULT 0,
 	rasterRowCount 			INTEGER NOT NULL DEFAULT 0,

Added: branches/gSoC2007_raster/pgraster/pgraster_types.h
===================================================================
--- branches/gSoC2007_raster/pgraster/pgraster_types.h	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/pgraster_types.h	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,251 @@
+/**********************************************************************
+ * $Id: pgraster_utils.c 2007-07-22 XingLin $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2003 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ * 
+ **********************************************************************
+ *
+ * PGRaster - Raster/Coverage Model for PostgreSQL/PostGIS
+ *
+ **********************************************************************
+ * 
+ * File Name: 		pgraster_utils.c
+ *
+ * Author: 			Xing Lin <solo.lin at gmail.com>
+ *
+ * Create Date: 	2007-07-22
+ *
+ * Description: 	This file will include data types or structures that
+ * 					will be used in the loader/export program.
+ *
+ * Original Author: Xing Lin <solo.lin at gmail.com>
+ *
+ * Maintainer:  	Xing Lin <solo.lin at gmail.com>
+ *
+ * Last Update: 	2007-07-22
+ *
+ **********************************************************************/
+
+#ifndef PGRASTER_TYPES_H
+#define PGRASTER_TYPES_H 1
+
+#include "stdlib.h"
+#include "stdio.h"
+#include "wkb.h"
+#include <inttypes.h>
+
+#pragma pack(1)
+
+/*typedef unsigned long int uint32;*/
+
+//#include <float.H>
+#ifndef _BOOL
+#define _BOOL 1
+typedef unsigned char bool;
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#ifndef _BYTE
+#define _BYTE 1
+typedef unsigned char byte;
+#endif
+
+#ifndef _UINT32
+#define _UINT32 1
+typedef uint32_t uint32;
+#endif
+
+#ifndef _INT32
+#define _INT32 1
+typedef int int32;
+#endif
+
+#ifndef _INT16
+#define _INT16 1
+typedef short int16;
+#endif
+
+#ifndef _UINT16
+#define _UINT16 1
+typedef unsigned short uint16;
+#endif
+
+#ifndef _UINT64
+#define _UINT64 1
+typedef unsigned long uint64;
+#endif
+
+#ifndef _INT64
+#define _INT64 1
+typedef long int64;
+#endif
+
+/* Definition of ColorRGB*/
+typedef struct _pgrcolorrgb
+{
+	byte r;
+	byte g;
+	byte b;
+}PGRColorRGB;
+
+/* Definition of ColorRGB*/
+typedef struct _pgrcolorrgba
+{
+	byte r;
+	byte g;
+	byte b;
+	byte a;
+}PGRColorRGBA;
+
+/* Definition of PGRASTER_METADATA structure*/
+typedef struct _pgraster_metadata
+{
+	int64			rasterObjectID;
+	char*			name;
+	char* 			captureDate;
+	uint16 			rasterDimensions;
+	uint16 			rasterBandType;
+	uint16 			rasterDataType;
+	uint16			rasterValueType;
+	char*			rasterSchema;
+	char* 			rasterDataTable;
+	uint32 			rasterBandCount;
+	uint32 			rasterRowCount;
+	uint32			rasterColumnCount;
+	uint32 			rasterCellDepth;
+	bool			rasterPyramidEnabled;
+	uint32 			rasterPyramidDepth;
+	int32 			blockSizeBands;
+	int32 			blockSizeRows;
+	int32 			blockSizeColumns;
+	bool			blockPadding;
+ 	uint16 			blockBandInterleaving;
+	uint16 			blockCompression;
+	int32 			blockQuality;
+	double			nodataValue;
+	int32			SRID;
+	bool			geoReferenced;
+	WKBGeometry*	spatialExtent;
+}PGRasterMetadata;
+
+/* Definition of PGRASTER_DATA*/
+typedef struct _pgraster_data
+{
+	int64			rasterObjectID;
+	int32			pyramidLevel;
+	int32 			bandBlockNumber;
+	int32 			rowBlockNumber;
+	int32 			columnBlockNumber;
+	int32			blockBandSize;
+	int32			blockRowSize;		
+	int32			blockColumnSize;	
+	WKBGeometry*	blockMBR;			// how to deal with geometry in postgresql.
+	byte*			dataBlock;			// map byte* into bytea in PostgreSQL.
+	int32			nDataLength; 		// only length of data block.
+}PGRasterData;
+
+
+/* Definition of PGRASTER_GCP */
+typedef struct _pgraster_gcp
+{
+	int64		rasterObjectID;
+	int64 		gcpID;
+	double 		cellColumn;
+	double 		cellRow;
+	double 		cellHeight;
+	double 		groundX;
+	double 		groundY;
+	double 		groundZ;
+	double 		rmsError;
+}PGRasterGCP;
+
+
+/* Definition of PGRASTER_SRS*/
+typedef struct _pgraster_srs
+{
+	int64		rasterObjectID;
+	bool		isReferenced; 	  
+	bool	 	isOrthoRectified;  
+	int32		SRID;
+	double 		spatialResolutionX;
+	double 		spatialResolutionY;
+	double		spatialResolutionZ;
+	double		spatialTolerance;
+	int16		coordLocation;
+	double		rowOff;
+	double		columnOff;
+	double 		heightOff;
+	double		xOff;
+	double		yOff;
+	double		zOff;
+	double		rowScale; 		  
+	double		columnScale;
+	double		heightScale;
+	double		xScale;
+	double 		yScale;
+	double 		zScale;
+	double		columnRMS;
+	double		totalRMS;
+	double		*rowNumberator;
+	int32 		countRowNumberator;
+	double		*rowDenominator;
+	int32		countRowDenominator;
+	double		*columnNumerator;
+	int32		countColumnNumberator;
+	double		*columnDenominator;
+	int32		countColumnDenominator;
+}PGRasterSRS;
+
+
+/* Definition of PGRASTER_VAT */
+typedef struct _pgraster_vat
+{
+	int64 		rasterObjectID;
+	uint32		bandID;
+	double 		value;
+	char		*attribute;
+}PGRasterVAT;
+
+
+/* Definition of PGRASTER_STATISTICS */
+typedef struct _pgraster_stat
+{
+	int64		rasterObjectID;
+	uint32		bandID;
+	double 		maxValue;
+	double 		minValue;
+	double 		avgValue;
+	double 		modeValue;
+	double 		stdValue;
+	char		*lastUpdate; 	//How to use a timestamp in c language.
+}PGRasterStat;
+
+/* Definition of PGRASTER_HISTOGRAM */
+typedef struct _pgraster_histogram
+{
+	int64		rasterObjectID;
+	uint32		bandID;
+	double 		value;
+	double 		count;
+}PGRasterHistogram;
+
+/* Definition of PGRASTER_PALETTE */
+typedef struct _pgraster_palette
+{
+	int32 		id;
+	char		*name;
+	char		*description;
+	int32		colorNumber;
+	int32		colorDepth; 	// could be ColorRGB or ColorRGBA.
+	byte		*colorData;
+}PGRasterPalette;
+
+#pragma pack()
+
+#endif

Added: branches/gSoC2007_raster/pgraster/pgraster_utils.c
===================================================================
--- branches/gSoC2007_raster/pgraster/pgraster_utils.c	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/pgraster_utils.c	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,253 @@
+/**********************************************************************
+ * $Id: pgraster_utils.c 2007-07-22 XingLin $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2003 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ * 
+ **********************************************************************
+ *
+ * PGRaster - Raster/Coverage Model for PostgreSQL/PostGIS
+ *
+ **********************************************************************
+ * 
+ * File Name: 		pgraster_utils.c
+ *
+ * Author: 			Xing Lin <solo.lin at gmail.com>
+ *
+ * Create Date: 	2007-07-22
+ *
+ * Description: 	This file will include the implementation of utility 
+ * 					functions will be used in the loader/export program.
+ *
+ * Original Author: Xing Lin <solo.lin at gmail.com>
+ *
+ * Maintainer:  	Xing Lin <solo.lin at gmail.com>
+ *
+ * Last Update: 	2007-07-22
+ *
+ **********************************************************************/
+
+#include "pgraster_utils.h"
+#include "pgraster_types.h"
+#include "pgraster_const.h"
+
+/* Some byte data reading/seeking tools */
+void skipbyte(byte **c) {
+	*c+=1;
+}
+byte readbyte(byte *c) {
+	byte b=0;
+	memcpy(&b, c, 1);
+	return b;
+}
+byte popbyte(byte **c) {
+	return *((*c)++);
+}
+
+void skipchar(byte **c) {
+	*c+=1;
+}
+char readchar(byte *c) {
+	return *((char*)c);
+}
+char popchar(byte **c) {
+	return *((*c)++);
+}
+
+uint16 popuint16(byte **c) {
+	uint16 i=0;
+	memcpy(&i, *c, 2);
+	*c+=2;
+	return i;
+}
+uint16 readuint16(byte *c) {
+	uint16 i=0;
+	memcpy(&i, c, 2);
+	return i;
+}
+void skipuint16(byte **c) {
+	*c+=2;
+}
+
+int16 popint16(byte **c) {
+	int16 i=0;
+	memcpy(&i, *c, 2);
+	*c+=2;
+	return i;
+}
+int16 readint16(byte *c) {
+	int16 i=0;
+	memcpy(&i, c, 2);
+	return i;
+}
+void skipint16(byte **c) {
+	*c+=2;
+}
+
+uint32 popuint32(byte **c) {
+	uint32 i=0;
+	memcpy(&i, *c, 4);
+	*c+=4;
+	return i;
+}
+uint32 readuint32(byte *c) {
+	uint32 i=0;
+	memcpy(&i, c, 4);
+	return i;
+}
+void skipuint32(byte **c) {
+	*c+=4;
+}
+
+int32 popint32(byte **c) {
+	int32 i=0;
+	memcpy(&i, *c, 4);
+	*c+=4;
+	return i;
+}
+int32 readint32(byte *c) {
+	int32 i=0;
+	memcpy(&i, c, 4);
+	return i;
+}
+void skipint32(byte **c) {
+	*c+=4;
+}
+
+float popfloat(byte **c) {
+	float f=0.0;
+	memcpy(&f, *c, 4);
+	*c+=4;
+	return f;
+}
+float readfloat(byte *c)
+{
+	float f=0.0;
+	memcpy(&f, c, 4);
+	return f;
+}
+void skipfloat(byte **c) {
+	*c+=4;
+}
+
+double popdouble(byte **c) {
+	double d=0.0;
+	memcpy(&d, *c, 8);
+	*c+=8;
+	return d;
+}
+double readdouble(byte *c)
+{
+	double d=0.0;
+	memcpy(&d, c, 8);
+	return d;
+}
+void skipdouble(byte **c) {
+	*c+=8;
+}
+
+/*
+PGRColorRGB readColorRGB(byte *c);
+PGRColorRGB	popColorRGB(byte **c);
+void skipColorRGB(byte **c);
+
+PGRColorRGBA readColorRGBA(byte *c);
+PGRColorRGBA popColorRGBA(byte **c);
+void skipColorRGBA(byte **c);
+*/
+
+/*
+ * Test whether the client is in a big_endian or little_endian environment.
+ *
+ * Support for both big_endian and little_endian will come soon.
+ *
+ */
+int is_bigendian(void)
+{
+	int test = 1;
+
+	if ( (((char *)(&test))[0]) == 1)
+	{
+		return 0; /*NDR (little_endian) */
+	}
+	else
+	{
+		return 1; /*XDR (big_endian) */
+	}
+}
+
+/*
+ * Initialize PGRasterMetadata to Default Values
+ */
+void initialize_metadata(PGRasterMetadata *pgrMeta)
+{
+	// simply return for null pointer
+	if(pgrMeta == NULL)
+		return;
+	
+	pgrMeta->rasterObjectID = -1;
+	pgrMeta->name = NULL;
+	pgrMeta->captureDate = NULL; // DATE Format "YYYY-MM-DD"
+	pgrMeta->rasterDimensions = 0;
+	pgrMeta->rasterBandType = BT_UNKNOWN;
+	pgrMeta->rasterDataType = DT_UNKNOWN;
+	pgrMeta->rasterValueType = VT_UNKNOWN;
+	pgrMeta->rasterDataTable = "PGRASTER_DATA\0";
+	pgrMeta->rasterBandCount = 0;
+	pgrMeta->rasterRowCount = 0;
+	pgrMeta->rasterColumnCount = 0;
+	pgrMeta->rasterCellDepth = 0;
+	pgrMeta->rasterPyramidEnabled = TRUE;
+	pgrMeta->rasterPyramidDepth = 0;
+	pgrMeta->blockSizeBands = -1;
+	pgrMeta->blockSizeRows = 256;
+	pgrMeta->blockSizeColumns = 256;
+	pgrMeta->blockPadding = TRUE;
+	pgrMeta->blockBandInterleaving = BI_BSQ;
+	pgrMeta->blockCompression = CT_LZW;
+	pgrMeta->blockQuality = 100;
+	pgrMeta->nodataValue = -1;
+	pgrMeta->SRID = -1;
+	pgrMeta->geoReferenced = FALSE;
+	pgrMeta->spatialExtent = NULL;	
+}
+/*
+ * Initialize PGRasterData to Default Values
+ */
+void initialize_data(PGRasterData *pgrData)
+{
+	// simply return for null pointer
+	if(pgrData == NULL)
+		return;
+
+	pgrData->rasterObjectID = -1;
+	pgrData->pyramidLevel = -1;
+	pgrData->bandBlockNumber = -1;
+	pgrData->rowBlockNumber = -1;
+	pgrData->columnBlockNumber = -1;
+	pgrData->blockBandSize = 256;
+	pgrData->blockRowSize = 256;
+	pgrData->blockColumnSize = 256;	
+	pgrData->blockMBR = NULL;			
+	pgrData->dataBlock = NULL;
+	pgrData->nDataLength = 0; 
+}
+
+/* LowerCase */
+void LowerCase(char *s)
+{
+	int j;
+	for (j=0; j<strlen(s); j++) s[j] = tolower(s[j]);
+}
+
+/* UpperCase */
+void UpperCase(char *s)
+{
+	int j;
+	for (j=0; j<strlen(s); j++) s[j] = toupper(s[j]);
+}
+

Added: branches/gSoC2007_raster/pgraster/pgraster_utils.h
===================================================================
--- branches/gSoC2007_raster/pgraster/pgraster_utils.h	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/pgraster_utils.h	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,106 @@
+/**********************************************************************
+ * $Id: pgraster_utils.h 2007-07-22 XingLin $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2003 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ * 
+ **********************************************************************
+ *
+ * PGRaster - Raster/Coverage Model for PostgreSQL/PostGIS
+ *
+ **********************************************************************
+ * 
+ * File Name: 		pgraster_utils.h
+ *
+ * Author: 			Xing Lin <solo.lin at gmail.com>
+ *
+ * Create Date: 	2007-07-22
+ *
+ * Description: 	This file will include the declaration of utility 
+ * 					functions will be used in the loader/export program.
+ *
+ * Original Author: Xing Lin <solo.lin at gmail.com>
+ *
+ * Maintainer:  	Xing Lin <solo.lin at gmail.com>
+ *
+ * Last Update: 	2007-07-22
+ *
+ **********************************************************************/
+
+#ifndef PGRASTER_UTILS_H
+#define PGRASTER_UTILS_H 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <sys/types.h>
+/* Solaris9 does not provide stdint.h */
+/* #include <stdint.h> */
+#include <inttypes.h>
+#include "pgraster_types.h"
+
+
+/* 
+ * Test whether big_endian or little_endian is used under 
+ * client environment.
+ */
+int is_bigendian(void);
+
+/* byte data reading/seeking functions. */
+byte readbyte(byte *c);
+void skipbyte(byte **c);
+byte popbyte(byte **c);
+
+char readchar(byte *c);
+void skipchar(byte **c);
+char popchar(byte **c);
+
+uint16 popuint16(byte **c);
+uint16 readuint16(byte *c);
+void skipuint16(byte **c);
+
+int16 popint16(byte **c);
+int16 readint16(byte *c);
+void skipint16(byte **c);
+
+uint32 popuint32(byte **c);
+uint32 readuint32(byte *c);
+void skipuint32(byte **c);
+
+int32 popint32(byte **c);
+int32 readint32(byte *c);
+void skipint32(byte **c);
+
+float readfloat(byte *c);
+float popfloat(byte **c);
+void skipfloat(byte **c);
+
+double readdouble(byte *c);
+double popdouble(byte **c);
+void skipdouble(byte **c);
+
+PGRColorRGB readColorRGB(byte *c);
+PGRColorRGB	popColorRGB(byte **c);
+void skipColorRGB(byte **c);
+
+PGRColorRGBA readColorRGBA(byte *c);
+PGRColorRGBA popColorRGBA(byte **c);
+void skipColorRGBA(byte **c);
+
+/* Set Default Values to Data Structure */
+/* What about the date and geometry, set to null?? */
+void initialize_metadata(PGRasterMetadata *pgrMeta);
+void initialize_data(PGRasterData *pgrData);
+/* other initialization functions for other types. */
+
+/* Lowercase*/
+void LowerCase(char *s);
+void UpperCase(char *s);
+
+#endif

Added: branches/gSoC2007_raster/pgraster/pgraster_version.h
===================================================================
--- branches/gSoC2007_raster/pgraster/pgraster_version.h	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/pgraster_version.h	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,36 @@
+/**********************************************************************
+ * $Id: pgraster_version.h 2007-07-22 XingLin $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2003 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ * 
+ **********************************************************************
+ *
+ * PGRaster - Raster/Coverage Model for PostgreSQL/PostGIS
+ *
+ **********************************************************************
+ * 
+ * File Name: 		pgraster_version.h
+ *
+ * Author: 			Xing Lin <solo.lin at gmail.com>
+ *
+ * Create Date: 	2007-07-22
+ *
+ * Description: 	Hard coded PGRaster Versions.
+ *
+ * Original Author: Xing Lin <solo.lin at gmail.com>
+ *
+ * Maintainer:  	Xing Lin <solo.lin at gmail.com>
+ *
+ * Last Update: 	2007-07-22
+ **********************************************************************/
+
+#ifndef PGRASTER_VERSION
+
+#define PGRASTER_VERSION "0.0.1"
+
+#endif

Added: branches/gSoC2007_raster/pgraster/test.c
===================================================================
--- branches/gSoC2007_raster/pgraster/test.c	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/test.c	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,113 @@
+#include "stdlib.h"
+#include "stdio.h"
+#include "pgraster_types.h"
+#include "libpq-fe.h"
+
+static void
+exit_nicely(PGconn *conn)
+{
+	PQfinish(conn);
+	exit(1);
+}
+
+int main(int argc, char **argv)
+{
+	const char *conninfo;
+	PGconn	   *conn;
+	PGresult   *res;
+	int			nFields;
+	int			i,
+				j;
+
+	/*
+	 * If the user supplies a parameter on the command line, use it as the
+	 * conninfo string; otherwise default to setting dbname=postgres and using
+	 * environment variables or defaults for all other connection parameters.
+	 */
+	if (argc > 1)
+		conninfo = argv[1];
+	else
+		conninfo = "dbname=pgtest host=localhost user=postgres password=justdoit";
+
+	/* Make a connection to the database */
+	conn = PQconnectdb(conninfo);
+
+	/* Check to see that the backend connection was successfully made */
+	if (PQstatus(conn) != CONNECTION_OK)
+	{
+		fprintf(stderr, "Connection to database failed: %s",
+				PQerrorMessage(conn));
+		exit_nicely(conn);
+	}
+
+	/*
+	 * Our test case here involves using a cursor, for which we must be inside
+	 * a transaction block.  We could do the whole thing with a single
+	 * PQexec() of "select * from pg_database", but that's too trivial to make
+	 * a good example.
+	 */
+
+	/* Start a transaction block */
+	res = PQexec(conn, "BEGIN");
+	if (PQresultStatus(res) != PGRES_COMMAND_OK)
+	{
+		fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
+		PQclear(res);
+		exit_nicely(conn);
+	}
+
+	/*
+	 * Should PQclear PGresult whenever it is no longer needed to avoid memory
+	 * leaks
+	 */
+	PQclear(res);
+
+	/*
+	 * Fetch rows from pg_database, the system catalog of databases
+	 */
+	res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from testdate");
+	if (PQresultStatus(res) != PGRES_COMMAND_OK)
+	{
+		fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
+		PQclear(res);
+		exit_nicely(conn);
+	}
+	PQclear(res);
+
+	res = PQexec(conn, "FETCH ALL in myportal");
+	if (PQresultStatus(res) != PGRES_TUPLES_OK)
+	{
+		fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
+		PQclear(res);
+		exit_nicely(conn);
+	}
+
+	/* first, print out the attribute names */
+	nFields = PQnfields(res);
+	for (i = 0; i < nFields; i++)
+		printf("%-15s", PQfname(res, i));
+	printf("\n\n");
+
+	/* next, print out the rows */
+	for (i = 0; i < PQntuples(res); i++)
+	{
+		for (j = 0; j < nFields; j++)
+			printf("%-15s", PQgetvalue(res, i, j));
+		printf("\n");
+	}
+
+	PQclear(res);
+
+	/* close the portal ... we don't bother to check for errors ... */
+	res = PQexec(conn, "CLOSE myportal");
+	PQclear(res);
+
+	/* end the transaction */
+	res = PQexec(conn, "END");
+	PQclear(res);
+
+	/* close the connection to the database and cleanup */
+	PQfinish(conn);
+
+	return 0;
+}

Added: branches/gSoC2007_raster/pgraster/wkb.c
===================================================================
--- branches/gSoC2007_raster/pgraster/wkb.c	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/wkb.c	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,390 @@
+/**********************************************************************
+ * $Id: wkb.c 2007-07-22 XingLin $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2003 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ * 
+ **********************************************************************
+ *
+ * PGRaster - Raster/Coverage Model for PostgreSQL/PostGIS
+ *
+ **********************************************************************
+ * 
+ * File Name: 		wkb.c
+ *
+ * Author: 			Xing Lin <solo.lin at gmail.com>
+ *
+ * Create Date: 	2007-07-22
+ *
+ * Description: 	Implementation of WKB Functions.
+ * 
+ * Original Author: Xing Lin <solo.lin at gmail.com>
+ *
+ * Maintainer:  	Xing Lin <solo.lin at gmail.com>
+ *
+ * Last Update: 	2007-07-22
+ *
+ **********************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include "wkb.h"
+
+void* generic_alloc(size_t size)
+{
+	#ifdef POSTGRESQL_ALLOC 	
+		return palloc(size);	//PostgreSQL Alloc
+	#else
+		return (void*)malloc(size); // C Language Library Mallloc
+	#endif	
+}
+
+void generic_free(void* p)
+{
+	#ifdef POSTGRESQL_ALLOC 	
+		pfree(p);// PostgreSQL Free
+	#else
+		free(p);// C Language Library Free
+		return;
+	#endif	
+}
+
+
+
+long G_GetSize(const WKBGeometry *pObj)
+{
+	long	nSize = 0;
+	if (pObj==NULL)
+		return 0;
+	
+	switch(pObj->obj.wkbType)
+	{
+		// Calculation for Single Feature
+		case wkbPoint :
+			return sizeof(WKBPoint);
+		case wkbLineString :
+			return sizeof(WKBLineString) + pObj->linestring.numPoints*sizeof(WKSPoint);
+		case wkbPolygon :
+		{
+			WKSLinearRing	*pRing = G_SeekFirstRing(pObj);
+			uint32			i;
+			nSize = sizeof(WKBPolygon);
+
+			for (i = 0; i < pObj->polygon.numRings; i++)
+			{
+				long			nRingSize = sizeof(WKSLinearRing) + pRing->numPoints * sizeof(WKSPoint);
+				pRing = (WKSLinearRing *) ((byte*)pRing + nRingSize);
+				nSize += nRingSize;
+			}
+			return nSize;
+		}
+		
+		// MultiFeature and GeometryCollection. Calculate via recursion   
+		case wkbMultiLineString :
+		case wkbMultiPolygon :
+		case wkbGeometryCollection :
+		case wkbMultiPoint :
+		{
+			WKBGeometry		*pTraceObj = G_SeekFirstGeometry(pObj);
+			uint32			i;
+			nSize = sizeof(WKBGeometryCollection);
+			
+			for (i = 0; i < pObj->collection.num_wkbGeometries; i++)
+			{
+				long			nGmtSize = G_GetSize(pTraceObj);
+				pTraceObj = (WKBGeometry *) ((byte*)pTraceObj+ nGmtSize);
+				nSize += nGmtSize;
+			}
+			return nSize;
+		}
+		default :
+			break;
+	}
+
+	// Bad input pointer type. Not a real WKBGeometry pointer.
+	return 0;
+}
+
+WKBGeometry* G_Clone(const WKBGeometry *pObj)
+{
+	long			nSize = 0 ;
+	byte*			pNew = NULL;
+	byte*			pSrc = NULL;
+	
+	if(pObj == NULL)
+		return NULL;
+	
+	// Alloc Space
+	nSize = G_GetSize(pObj);
+	pNew = (byte*)generic_alloc(nSize*(sizeof(byte)));	
+	pSrc = (byte*)((long)pObj);
+
+	// Memcpy
+	memcpy(pNew, pSrc, nSize);
+
+	// Return
+	return G_ToGeometry(pNew);
+}
+
+void G_WKSPointCpy(const WKSPoint* ptSrc,WKSPoint* ptDest)
+{
+	if( ptSrc == NULL || ptDest == NULL)
+		return;
+
+	ptDest->X = ptSrc->X;
+	ptDest->Y = ptSrc->Y;
+}
+
+WKBGeometry* G_MBRToGeometry(const WKSEnvelope* pMbr)
+{
+	WKSPoint* 		wksPtArray	=	(WKSPoint*)NULL;
+	WKBGeometry*	pGeom 		=	(WKBGeometry*)NULL;
+	
+	if( pMbr == NULL)
+		return (WKBGeometry*)NULL;
+	
+	wksPtArray = (WKSPoint*)generic_alloc(sizeof(WKSPoint) * 5);
+	
+	wksPtArray[0].X = pMbr->minX;
+	wksPtArray[0].Y = pMbr->minY;
+	
+	wksPtArray[1].X = pMbr->maxX;
+	wksPtArray[1].Y = pMbr->minY;
+	
+	wksPtArray[2].X = pMbr->maxX;
+	wksPtArray[2].Y = pMbr->maxY;
+	
+	wksPtArray[3].X = pMbr->minX;
+	wksPtArray[3].Y = pMbr->maxY;
+
+	wksPtArray[4].X = pMbr->minX;
+	wksPtArray[4].Y = pMbr->minY;
+	
+	pGeom = G_CreatePolygon_Simple(5, wksPtArray);
+	
+	generic_free((void*)wksPtArray);
+	
+	return pGeom;
+	
+}
+
+WKBGeometry* G_CreatePolygon_Simple(long nCount, const WKSPoint *pPoints)
+{
+	uint32			nSize = sizeof(WKBPolygon);
+	byte*			p;
+	WKBPolygon*		pObj;
+	WKSLinearRing	*pRing;
+
+	if (T_DistanceSquare1(&pPoints[0], &pPoints[nCount-1]) > MATH_TOL2) 
+		nCount++;
+	
+	// Number of valid points shoudl be bigger than 2
+	if ( nCount < 2 )
+		return NULL;
+	
+	nSize += sizeof(WKSLinearRing) + nCount * sizeof(WKSPoint);
+	
+	p = (byte*)generic_alloc(nSize*sizeof(byte));
+	pObj = (WKBPolygon *)(p);
+
+	pObj->byteOrder  = wkbNDR;
+	pObj->wkbType    = wkbPolygon;
+	pObj->numRings   = 1;
+
+	
+	pRing = G_SeekFirstRing((WKBGeometry*)pObj);
+	pRing->numPoints = nCount;
+	if(pPoints != NULL)
+	{
+		memcpy(pRing->points, pPoints, (nCount-1) * sizeof(WKSPoint));
+		pRing->points[ nCount-1 ] = pRing->points[ 0 ];
+	}
+
+	return (WKBGeometry *)pObj;
+}
+
+void G_DestroyGeometry(WKBGeometry *pObj)
+{
+	generic_free(pObj);
+}
+
+WKSLinearRing* G_SeekFirstRing(const WKBGeometry *pObj)
+{
+	if (pObj == NULL || pObj->obj.wkbType != wkbPolygon)
+		return NULL;
+
+	return (WKSLinearRing *)((byte*)pObj + sizeof(WKBPolygon));
+}
+
+//checked
+double	T_DistanceSquare1(const WKSPoint* p1, const WKSPoint* p2)
+{	
+	double dx = p1->X-p2->X;
+	double dy = p1->Y-p2->Y;
+	return dx*dx+dy*dy;
+}
+
+WKBGeometry* G_ToGeometry(void *pVal)
+{
+	if (pVal == NULL)
+		return NULL;
+
+	else
+	{		
+		WKBGeometry* pResult = (WKBGeometry *)((long)pVal);
+		return pResult;
+	}
+}
+
+WKBGeometry *G_SeekFirstGeometry(const WKBGeometry *pObj)
+{
+	WKBGeometry* pSubObj;
+	
+	if(pObj == NULL)
+		return NULL;
+
+	if (!G_IsMultiGeometry(pObj))
+		return (WKBGeometry *)pObj;
+
+	pSubObj = (WKBGeometry *) ((byte*)pObj + sizeof(WKBGeometryCollection));
+
+	return pSubObj;
+}
+
+WKBGeometry* G_SeekNextGeometry(const WKBGeometry* pObj)
+{
+	long nObjSize = 0;
+
+	WKBGeometry *pSubObj = (WKBGeometry*) NULL;
+
+	if(pObj == NULL)
+		return NULL;
+
+	nObjSize = G_GetSize(pObj);
+
+	pSubObj = (WKBGeometry *) ((byte*)pObj + nObjSize);
+
+	return pSubObj;
+}
+
+void G_ReCalcMBR_WKBGeometry1(const WKBGeometry *pObj, WKSEnvelope *pMbr)
+{
+	
+	if(pMbr == NULL || pObj == NULL )
+		return;
+
+	switch (pObj->obj.wkbType)
+	{
+		case wkbPoint      : 
+			pMbr->minX = pMbr->maxX = pObj->point.point.X;
+			pMbr->minY = pMbr->maxY = pObj->point.point.Y;
+			break;
+
+		case wkbLineString :
+			G_ReCalcMBR_WKSPoint( pObj->linestring.numPoints, pObj->linestring.points, pMbr);
+			break;
+
+		case wkbPolygon :
+			G_ReCalcMBR_WKSLinearRing( G_SeekFirstRing(pObj), pMbr );
+			break;
+
+		case wkbMultiPoint      : 
+		case wkbMultiLineString :
+		case wkbMultiPolygon    :
+		case wkbGeometryCollection    :
+		{
+			uint32			i;
+			WKSEnvelope		mbr;
+			WKSEnvelope*		pMbrTemp;
+			WKBGeometry*	pSub = G_SeekFirstGeometry(pObj);
+
+			G_ReCalcMBR_WKBGeometry1(pSub, pMbr);
+
+			for (i = 1; i < pObj->collection.num_wkbGeometries; i++)
+			{
+				pSub = G_SeekNextGeometry(pSub);
+				G_ReCalcMBR_WKBGeometry1(pSub, &mbr);
+				pMbrTemp = G_ExpandEnvelope(&mbr, pMbr);
+				memcpy((byte*)pMbr,(byte*)pMbrTemp,sizeof(WKSEnvelope));
+				generic_free((byte*)pMbrTemp);
+				pMbrTemp = NULL;
+			}
+
+			break;
+		}
+	}
+}
+
+void G_ReCalcMBR_WKSPoint(long numPoints, const WKSPoint* points, WKSEnvelope* pMbr)
+{
+	long		i;
+
+	if(pMbr == NULL)
+		return;
+
+	if(numPoints <= 0 || points == NULL)
+	{
+		pMbr->maxX = 0 ;
+		pMbr->maxY = 0 ;
+		pMbr->minX = 0 ;
+		pMbr->minY = 0 ;
+		return;
+	}
+
+	pMbr->maxX = pMbr->minX = points[ 0 ].X;
+	pMbr->maxY = pMbr->minY = points[ 0 ].Y;
+
+	for (i = 1; i < numPoints; i++)
+	{
+		if (pMbr->minX > points[i].X) pMbr->minX = points[i].X;
+		if (pMbr->maxX < points[i].X) pMbr->maxX = points[i].X;
+		if (pMbr->minY > points[i].Y) pMbr->minY = points[i].Y;
+		if (pMbr->maxY < points[i].Y) pMbr->maxY = points[i].Y;
+	}
+}
+
+void G_ReCalcMBR_WKSLinearRing(const WKSLinearRing *pRing, WKSEnvelope *pMbr)
+{
+	G_ReCalcMBR_WKSPoint(pRing->numPoints, pRing->points, pMbr);
+}
+
+WKSEnvelope* G_ExpandEnvelope(const WKSEnvelope* mbr1, WKSEnvelope* mbr2)
+{
+	WKSEnvelope* embr = NULL;
+
+	if(mbr2 == NULL || mbr1 == NULL)
+		return NULL;
+
+	embr = (WKSEnvelope*)generic_alloc(sizeof(WKSEnvelope));
+
+	memcpy(embr,mbr1,sizeof(WKSEnvelope));
+
+	if (embr->minX > mbr2->minX)		embr->minX = mbr2->minX;
+	if (embr->maxX < mbr2->maxX)		embr->maxX = mbr2->maxX;
+	if (embr->minY > mbr2->minY)		embr->minY = mbr2->minY;
+	if (embr->maxY < mbr2->maxY)		embr->maxY = mbr2->maxY;
+
+	return embr;
+}
+
+int G_IsMultiGeometry( const WKBGeometry *pObj )
+{
+	if (pObj == NULL)
+		return 0;
+
+	switch (pObj->obj.wkbType)
+	{
+		case wkbMultiPoint :
+		case wkbMultiLineString :
+		case wkbMultiPolygon :
+		case wkbGeometryCollection :
+			return 1;
+	}
+	return 0;
+}
+

Added: branches/gSoC2007_raster/pgraster/wkb.h
===================================================================
--- branches/gSoC2007_raster/pgraster/wkb.h	2007-07-23 21:43:44 UTC (rev 2669)
+++ branches/gSoC2007_raster/pgraster/wkb.h	2007-07-24 21:30:29 UTC (rev 2670)
@@ -0,0 +1,244 @@
+/**********************************************************************
+ * $Id: wkb.h 2007-07-22 XingLin $
+ *
+ * PostGIS - Spatial Types for PostgreSQL
+ * http://postgis.refractions.net
+ * Copyright 2001-2003 Refractions Research Inc.
+ *
+ * This is free software; you can redistribute and/or modify it under
+ * the terms of the GNU General Public Licence. See the COPYING file.
+ * 
+ **********************************************************************
+ *
+ * PGRaster - Raster/Coverage Model for PostgreSQL/PostGIS
+ *
+ **********************************************************************
+ * 
+ * File Name: 		wkb.h
+ *
+ * Author: 			Xing Lin <solo.lin at gmail.com>
+ *
+ * Create Date: 	2007-07-22
+ *
+ * Description: 	WKB Structure Definition
+ *
+ * Original Author: Xing Lin <solo.lin at gmail.com>
+ *
+ * Maintainer:  	Xing Lin <solo.lin at gmail.com>
+ *
+ * Last Update: 	2007-07-22
+ *
+ **********************************************************************/
+
+#ifndef _WKB_H
+#define _WKB_H 1
+#include <inttypes.h>
+
+/*
+ * OGC WellKnownBinaryGeometry
+ */
+
+/*
+ * 3d geometries are encode as in OGR by adding WKB3DOFFSET to the type.  
+ */
+#define WKB3DOFFSET 0x80000000
+
+#ifndef _BYTE
+#define _BYTE 1
+typedef unsigned char byte;
+#endif
+
+#ifndef _UINT32
+#define _UINT32 1
+typedef uint32_t uint32;
+#endif
+
+#pragma pack(1)
+
+//#pragma warning(disable:4200)			// ignore zero-sized array in struct/union
+
+typedef struct tagWKSEnvelope
+{
+	double		maxX;
+	double		maxY;
+	double		minX;
+	double		minY;	
+} WKSEnvelope;
+
+typedef struct _tagWKSPoint
+{
+	double		X;
+	double		Y;
+} WKSPoint;
+
+typedef struct
+{
+	uint32	    numPoints;
+	WKSPoint	points[0];
+} WKSLinearRing;
+
+typedef struct
+{
+	byte		byteOrder;
+	uint32		wkbType;
+} WKBObject;
+
+typedef struct
+{
+	byte	    byteOrder;
+	uint32	    wkbType;
+	WKSPoint	point;
+} WKBPoint;
+
+typedef struct
+{
+	byte	    byteOrder;
+	uint32	    wkbType;
+	uint32	    numPoints;
+	WKSPoint	points[0];
+} WKBLineString;
+
+typedef struct
+{
+	byte	    byteOrder;
+	uint32	    wkbType;
+	uint32	    numRings;
+	//WKSLinearRing	rings[0];
+} WKBPolygon;
+
+typedef struct
+{
+	byte		byteOrder;
+	uint32		wkbType;
+	uint32		num_wkbPoints;
+	WKBPoint    WKBPoints[0];
+} WKBMultiPoint;
+
+typedef struct
+{
+	byte			byteOrder;
+	uint32			wkbType;
+	uint32			num_wkbLineStrings;
+//	WKBLineString   WKBLineStrings[0];
+} WKBMultiLineString;
+
+typedef struct
+{
+	byte		    byteOrder;
+	uint32		    wkbType;
+	uint32		    num_wkbPolygons;
+//	WKBPolygon		wkbPolygons[0];
+} WKBMultiPolygon;
+
+typedef struct
+{
+	byte		    byteOrder;
+	uint32		    wkbType;
+	uint32		    num_wkbGeometries;
+	//	WKBGeomertry    wkbGeometries[0];
+} WKBGeometryCollection;
+
+typedef struct tabWKBGeometry
+{
+	union
+	{
+		WKBObject               obj;
+		WKBPoint                point;
+		WKBLineString           linestring;
+		WKBPolygon              polygon;
+		WKBMultiPoint           mpoint;
+		WKBMultiLineString      mlinestring;
+		WKBMultiPolygon         mpolygon;
+		WKBGeometryCollection   collection;
+	};
+} WKBGeometry;
+
+//Buffer Size for WKT/WKB Transformation
+#ifndef WKT_BUFFER_SIZE
+#define WKT_UNIT_SIZE 	12
+#define WKT_BUFFER_SIZE 100000
+#endif
+
+#define MBRSIZE				sizeof(WKSEnvelope)
+#ifndef PI
+#define PI					3.14159265
+#endif
+
+//GeometryType
+typedef enum tagwkbGeometryType {
+    wkbNone					= 0,
+    wkbPoint				= 1,
+    wkbLineString			= 2, 
+    wkbPolygon				= 3, 
+    wkbMultiPoint			= 4, 
+    wkbMultiLineString		= 5, 
+    wkbMultiPolygon			= 6, 
+    wkbGeometryCollection	= 7,
+} wkbGeometryType;
+
+// wkbByteOrder
+enum wkbByteOrder {
+    wkbXDR = 0,				// Big Endian
+    wkbNDR = 1				// Little Endian
+};
+
+//MATH_ERROR_TOL
+#ifndef	MATH_ERROR_TOL
+#define	MATH_ERROR_TOL
+#define	MATH_TOL		0.0000001			// normal tollerance
+#define	MATH_TOL_SQ		0.0000001				// square root tol
+#define MATH_TOL_DIST	MATH_TOL_SQ			// square root tol
+#define MATH_TOL2		1.0e-12				// square tol (-16) 
+#define MATH_TOL0		1.0e-6				// is zero tol (-8)
+#define	MATH_TOL1_00	1.00000001			// 
+#define MATH_TOL0_99	0.99999999			// 
+#endif 
+
+/* Functions prototype */
+/* void dump_wkb(char *wkb); */
+
+/* Some necessary functions for Creating WKBGeometry*/
+
+// Calculate WKBGeometr's Size in Bytes
+long			G_GetSize(const WKBGeometry* pObj);
+
+// (Deep) Clone WKBGeometry Object
+WKBGeometry*	G_Clone(const WKBGeometry* pObj);
+
+// (Deep) Clone WKBPoint Object
+void			G_WKSPointCpy(const WKSPoint* point,WKSPoint* pt);
+
+// Change WKSEnvelope to WKBPolygon
+WKBGeometry*	G_MBRToGeometry(const WKSEnvelope* pMbr);
+
+// Create WKBPolygon::WKBGeometry from WKSPoints.
+WKBGeometry*	G_CreatePolygon_Simple(long numPoints, const WKSPoint* points);
+
+// (Deep) Free Space taken by WKBGeometry Objects.
+void			G_DestroyGeometry(WKBGeometry* pObj);
+
+WKSLinearRing*	G_SeekFirstRing(const WKBGeometry* pObj);
+
+WKBGeometry*	G_ToGeometry(void* pVal);
+
+WKBGeometry*	G_SeekFirstGeometry(const WKBGeometry* pObj);
+
+WKBGeometry*	G_SeekNextGeometry(const WKBGeometry* pObj);
+
+double			T_DistanceSquare1(const WKSPoint* p1, const WKSPoint* p2);
+
+void			G_ReCalcMBR_WKBGeometry1(const WKBGeometry* pObj, WKSEnvelope* pMbr);
+
+void			G_ReCalcMBR_WKSPoint(long numPoints, const WKSPoint* points, WKSEnvelope* pMbr);
+
+void			G_ReCalcMBR_WKSLinearRing(const WKSLinearRing* pRing, WKSEnvelope* pMbr);
+
+WKSEnvelope*	G_ExpandEnvelope(const WKSEnvelope* mbr1, WKSEnvelope* mbr2);
+
+int				G_IsMultiGeometry(const WKBGeometry* pObj);
+
+/* Might Need Some WKT/WKB Conversion Tools. */
+
+#pragma pack()
+
+#endif



More information about the postgis-commits mailing list