* the terms of the GNU General Public Licence. See the COPYING file.
*
**********************************************************************
- * $Log$
- * Revision 1.55 2004/09/20 14:14:43 strk
- * Fixed a bug in popbyte. Trapped WKB endiannes errors.
- *
- * Revision 1.54 2004/09/20 13:49:27 strk
- * Postgis-1.x support (LWGEOM) added.
- * postgis version detected at runtime.
- * Endiannes unchecked ... TODO.
- *
- * Revision 1.53 2004/08/05 16:53:29 strk
- * schema support patches sent by Mark
- *
- * Revision 1.52 2004/06/16 13:42:05 strk
- * Added schema support in getMaxFieldSize.
- * Added direct support for TIMESTAMP field types (thanks to Steffen Macke).
- *
- * Revision 1.51 2004/05/13 12:24:15 strk
- * Transformed NULL numeric values to 0 as it was before the introduction
- * of bigint bug workaround.
- *
- * Revision 1.50 2004/05/13 12:13:01 strk
- * Used DBFWriteAttributeDirectly interface for writing attributes.
- * This way we are not affected by shapelib long-integer bug.
- *
- * Revision 1.49 2004/05/13 12:07:13 strk
- * Other fix in 3d handling - you should now be able to dump as 2d or 3d any 2d or 3d object
- *
- * Revision 1.48 2004/05/13 11:59:08 strk
- * Fixed bug in 3d features handling.
- *
- * Revision 1.47 2004/04/21 09:13:15 strk
- * Attribute names escaping mechanism added. You should now
- * be able to dump a shapefile equal to the one loaded.
- *
- * Revision 1.46 2004/04/21 07:38:34 strk
- * Memory allocated for main_scan_query was not enough when using binary cursor. Fixed
- *
- * Revision 1.45 2004/03/29 10:20:48 strk
- * Fixed a bug in WKB parsing for Multipoints.
- * Fixed a bug in -d handling for WKB.
- * Added point->multipoint fluffing capabilities.
- *
- * Revision 1.44 2004/03/10 18:46:07 strk
- * Fixed a bug reducing the output shapes from Multipolygon tables.
- *
- * Revision 1.43 2004/03/06 17:43:06 strk
- * Added RCSID string in usage output
- *
- * Revision 1.42 2004/02/09 18:49:23 strk
- * byte endiannes detected empirically
- *
- * Revision 1.41 2004/02/06 08:26:02 strk
- * updated wkb reading funx to reflect changes made by pramsey in postgis_inout.c to be nicer with solaris
- *
- * Revision 1.40 2003/12/27 13:30:23 strk
- * Added schema specification support
- *
- * Revision 1.39 2003/12/19 18:55:46 strk
- * substituted setenv() calls with putenv() for Solaris support
- *
- * Revision 1.38 2003/12/04 19:11:56 strk
- * code cleanup (removed useless and leaking malloc calls)
- *
- * Revision 1.37 2003/11/26 18:54:22 strk
- * fixed bug in HexDecoder, made WKB parsing the default
- *
- * Revision 1.36 2003/11/26 18:14:11 strk
- * binary cursor implemented
- *
- * Revision 1.35 2003/11/26 17:21:00 strk
- * Made HEXWKB parsing settable at compile time
- *
- * Revision 1.34 2003/11/26 16:40:41 strk
- * Handled NULLS in wkb parsing, reduced functions args
- *
- * Revision 1.33 2003/11/26 15:45:53 strk
- * wkb support for all geom types
- *
- * Revision 1.32 2003/11/26 14:31:20 strk
- * WKB start to work
- *
- * Revision 1.31 2003/11/25 17:28:03 strk
- * hardly trying to get WKB parsing work
- *
- * Revision 1.30 2003/11/24 17:36:28 strk
- * Removed useless BYTE_ORDER checks
- *
- * Revision 1.29 2003/11/21 23:51:14 pramsey
- * Added Cygwin endian definition include to fix windows compile.
- *
- * Revision 1.28 2003/11/20 18:01:26 strk
- * patch from m.spring@gmx.de
- *
- * Revision 1.27 2003/11/20 15:27:20 strk
- * Removed some useless strdups.
- * Removed pgtype 22 (int2vector) from the list of integer DBF field types.
- * Added pgtype 1700 (numeric) in DBF doubles list.
- *
- * Revision 1.26 2003/11/18 14:58:47 strk
- * default row buffer lenght set to 100
- *
- * Revision 1.25 2003/11/18 14:39:26 strk
- * Some more structuring. Initialization routine moved out of main loop.
- * Preparing dumper for WKB parsing.
- *
- * Revision 1.24 2003/11/16 00:27:46 strk
- * Huge code re-organization. More structured code, more errors handled,
- * cursor based iteration, less code lines.
- *
- * Revision 1.23 2003/11/14 22:04:51 strk
- * Used environment vars to pass libpq connection options (less error prone,
- * easier to read). Printed clearer error message on query error.
*
- * Revision 1.22 2003/09/10 22:44:56 jeffloun
- * got rid of warning...
- *
- * Revision 1.21 2003/09/10 22:40:11 jeffloun
- * changed it to make the field names in the dbf file capital letters
- *
- * Revision 1.20 2003/09/10 21:36:04 jeffloun
- * fixed a bug in is_clockwise...
- *
- * Revision 1.19 2003/07/01 18:30:55 pramsey
- * Added CVS revision headers.
- *
- * Revision 1.18 2003/02/04 21:39:20 pramsey
- * Added CVS substitution strings for logging.
+ * PostGIS to Shapefile converter
*
**********************************************************************/
SHPHandle shp;
int geotype;
int outshptype;
-int is3d;
+int ndims;
int includegid;
int unescapedattrs;
int binary;
int num_lines(char *str);
char *scan_to_same_level(char *str);
int points_per_sublist( char *str, int *npoints, long max_lists);
-int reverse_points(int num_points,double *x,double *y,double *z);
+int reverse_points(int num_points, double *x, double *y, double *z, double *m);
int is_clockwise(int num_points,double *x,double *y,double *z);
int is_bigendian(void);
SHPObject * shape_creator_wrapper_WKB(byte *str, int idx);
int get_postgis_major_version(void);
/* WKB functions */
-SHPObject * create_polygon3D_WKB(byte *wkb, int shape_id);
-SHPObject * create_polygon2D_WKB(byte *wkb, int shape_id);
-SHPObject * create_multipoint2D_WKB(byte *wkb, int shape_id);
-SHPObject * create_multipoint3D_WKB(byte *wkb, int shape_id);
-SHPObject * create_point2D_WKB(byte *wkb, int shape_id);
-SHPObject * create_point3D_WKB(byte *wkb, int shape_id);
-SHPObject * create_multiline3D_WKB (byte *wkb, int shpid);
-SHPObject * create_multiline2D_WKB (byte *wkb, int shpid);
-SHPObject * create_line2D_WKB(byte *wkb, int shape_id);
-SHPObject * create_line3D_WKB(byte *wkb, int shape_id);
-SHPObject * create_multipolygon2D_WKB(byte *wkb, int shpid);
-SHPObject * create_multipolygon3D_WKB(byte *wkb, int shpid);
+SHPObject * create_polygon2D_WKB(byte *wkb);
+SHPObject * create_polygon3D_WKB(byte *wkb);
+SHPObject * create_polygon4D_WKB(byte *wkb);
+SHPObject * create_multipoint2D_WKB(byte *wkb);
+SHPObject * create_multipoint3D_WKB(byte *wkb);
+SHPObject * create_multipoint4D_WKB(byte *wkb);
+SHPObject * create_point2D_WKB(byte *wkb);
+SHPObject * create_point3D_WKB(byte *wkb);
+SHPObject * create_point4D_WKB(byte *wkb);
+SHPObject * create_multiline2D_WKB (byte *wkb);
+SHPObject * create_multiline3D_WKB (byte *wkb);
+SHPObject * create_multiline4D_WKB (byte *wkb);
+SHPObject * create_line2D_WKB(byte *wkb);
+SHPObject * create_line3D_WKB(byte *wkb);
+SHPObject * create_line4D_WKB(byte *wkb);
+SHPObject * create_multipolygon2D_WKB(byte *wkb);
+SHPObject * create_multipolygon3D_WKB(byte *wkb);
+SHPObject * create_multipolygon4D_WKB(byte *wkb);
byte getbyte(byte *c);
void skipbyte(byte **c);
byte popbyte(byte **c);
void dump_wkb(byte *wkb);
byte * HexDecode(byte *hex);
#define WKB3DOFFSET 0x80000000
+#define WKB4DOFFSET 0x40000000
static void exit_nicely(PGconn *conn){
shp_file = NULL;
main_scan_query = NULL;
rowbuflen=100;
- is3d = 0;
+ ndims = 2;
includegid=0;
unescapedattrs=0;
binary = 0;
{
byte *ptr = str;
uint32 type;
- int is3d;
+ int ndims = 2;
int wkb_big_endian;
// skip byte order
// get type
type = getint(ptr);
- is3d = type&WKB3DOFFSET;
+ if ( type&WKB3DOFFSET ) ndims = 3;
+ if ( type&WKB4DOFFSET ) ndims = 4;
+
type &= ~WKB3DOFFSET;
+ type &= ~WKB4DOFFSET;
switch(type)
{
case MULTILINETYPE:
- if ( is3d )
- return create_multiline3D_WKB(str, idx);
- else
- return create_multiline2D_WKB(str, idx);
+ if ( ndims == 2 )
+ return create_multiline2D_WKB(str);
+ else if ( ndims == 3 )
+ return create_multiline3D_WKB(str);
+ else if ( ndims == 4 )
+ return create_multiline4D_WKB(str);
case LINETYPE:
- if ( is3d )
- return create_line3D_WKB(str, idx);
- else
- return create_line2D_WKB(str, idx);
+ if ( ndims == 2 )
+ return create_line2D_WKB(str);
+ else if ( ndims == 3 )
+ return create_line3D_WKB(str);
+ else if ( ndims == 4 )
+ return create_line4D_WKB(str);
+
case POLYGONTYPE:
- if ( is3d )
- return create_polygon3D_WKB(str, idx);
- else
- return create_polygon2D_WKB(str, idx);
+ if ( ndims == 2 )
+ return create_polygon2D_WKB(str);
+ else if ( ndims == 3 )
+ return create_polygon3D_WKB(str);
+ else if ( ndims == 4 )
+ return create_polygon4D_WKB(str);
+
case MULTIPOLYGONTYPE:
- if ( is3d )
- return create_multipolygon3D_WKB(str, idx);
- else
- return create_multipolygon2D_WKB(str, idx);
+ if ( ndims == 2 )
+ return create_multipolygon2D_WKB(str);
+ else if ( ndims == 3 )
+ return create_multipolygon3D_WKB(str);
+ else if ( ndims == 4 )
+ return create_multipolygon4D_WKB(str);
case POINTTYPE:
- if ( is3d )
- return create_point3D_WKB(str, idx);
- else
- return create_point2D_WKB(str, idx);
+ if ( ndims == 2 )
+ return create_point2D_WKB(str);
+ else if ( ndims == 3 )
+ return create_point3D_WKB(str);
+ else if ( ndims == 4 )
+ return create_point4D_WKB(str);
case MULTIPOINTTYPE:
- if ( is3d )
- return create_multipoint3D_WKB(str, idx);
- else
- return create_multipoint2D_WKB(str, idx);
+ if ( ndims == 2 )
+ return create_multipoint2D_WKB(str);
+ else if ( ndims == 3 )
+ return create_multipoint3D_WKB(str);
+ else if ( ndims == 4 )
+ return create_multipoint4D_WKB(str);
default:
fprintf(stderr, "Unknown WKB type (%8.8lx) - (%s:%d)\n",
}
SHPObject *
-create_multiline3D_WKB (byte *wkb, int shape_id)
+create_multiline3D_WKB (byte *wkb)
{
SHPObject *obj;
double *x=NULL, *y=NULL, *z=NULL;
totpoints += npoints;
}
- obj = SHPCreateObject(outshptype, shape_id, nparts,
+ obj = SHPCreateObject(outshptype, -1, nparts,
part_index, NULL, totpoints,
x, y, z, NULL);
}
SHPObject *
-create_multiline2D_WKB (byte *wkb, int shape_id)
+create_multiline4D_WKB (byte *wkb)
+{
+ SHPObject *obj;
+ double *x=NULL, *y=NULL, *z=NULL, *m=NULL;
+ int nparts=0, *part_index=NULL, totpoints=0, nlines=0;
+ int li;
+
+ // skip byteOrder and type
+ skipbyte(&wkb); skipint(&wkb);
+
+ /*
+ * Scan all lines in multiline
+ */
+ nlines=popint(&wkb); // num_wkbLineStrings
+#if VERBOSE > 2
+ printf("Multiline with %d lines\n", nlines);
+#endif
+
+ part_index = (int *)malloc(sizeof(int)*(nlines));
+ for (li=0; li<nlines; li++)
+ {
+ int npoints, pn;
+
+ // skip byteOrder and wkbType
+ skipbyte(&wkb); skipint(&wkb);
+
+ npoints = popint(&wkb);
+
+#if VERBOSE > 2
+ printf("Line %d has %d points\n", li, npoints);
+#endif
+
+ x = realloc(x, sizeof(double)*(totpoints+npoints));
+ y = realloc(y, sizeof(double)*(totpoints+npoints));
+ z = realloc(z, sizeof(double)*(totpoints+npoints));
+ m = realloc(z, sizeof(double)*(totpoints+npoints));
+
+ /* wkb now points at first point */
+ for (pn=0; pn<npoints; pn++)
+ {
+ x[totpoints+pn] = popdouble(&wkb);
+ y[totpoints+pn] = popdouble(&wkb);
+ z[totpoints+pn] = popdouble(&wkb);
+ m[totpoints+pn] = popdouble(&wkb);
+ }
+
+ part_index[li] = totpoints;
+ totpoints += npoints;
+ }
+
+ obj = SHPCreateObject(outshptype, -1, nparts,
+ part_index, NULL, totpoints,
+ x, y, z, m);
+
+ free(part_index); free(x); free(y); free(z); free(m);
+
+ return obj;
+}
+
+SHPObject *
+create_multiline2D_WKB (byte *wkb)
{
double *x=NULL, *y=NULL;
int nparts=0, *part_index=NULL, totpoints=0, nlines=0;
}
- obj = SHPCreateObject(outshptype, shape_id, nparts,
+ obj = SHPCreateObject(outshptype, -1, nparts,
part_index, NULL, totpoints,
x, y, NULL, NULL);
}
SHPObject *
-create_line3D_WKB (byte *wkb, int shape_id)
+create_line4D_WKB (byte *wkb)
+{
+ double *x=NULL, *y=NULL, *z=NULL, *m=NULL;
+ uint32 npoints=0, pn;
+ SHPObject *obj;
+
+ // skip byteOrder and type
+ skipbyte(&wkb); skipint(&wkb);
+
+ npoints = popint(&wkb);
+
+#if VERBOSE > 2
+ printf("Line has %lu points\n", npoints);
+#endif
+
+ x = malloc(sizeof(double)*(npoints));
+ y = malloc(sizeof(double)*(npoints));
+ z = malloc(sizeof(double)*(npoints));
+ m = malloc(sizeof(double)*(npoints));
+
+ /* wkb now points at first point */
+ for (pn=0; pn<npoints; pn++)
+ {
+ x[pn] = popdouble(&wkb);
+ y[pn] = popdouble(&wkb);
+ z[pn] = popdouble(&wkb);
+ m[pn] = popdouble(&wkb);
+ }
+
+ obj = SHPCreateObject(outshptype, -1, 0, NULL, NULL,
+ npoints, x, y, z, m);
+ free(x); free(y); free(z); free(m);
+
+ return obj;
+}
+
+SHPObject *
+create_line3D_WKB (byte *wkb)
{
double *x=NULL, *y=NULL, *z=NULL;
uint32 npoints=0, pn;
}
SHPObject *
-create_line2D_WKB (byte *wkb, int shape_id)
+create_line2D_WKB (byte *wkb)
{
double *x=NULL, *y=NULL, *z=NULL;
uint32 npoints=0, pn;
return obj;
}
+SHPObject *
+create_point4D_WKB(byte *wkb)
+{
+ SHPObject *obj;
+ double x, y, z, m;
+
+ // skip byteOrder and wkbType
+ skipbyte(&wkb); skipint(&wkb);
+
+ x = popdouble(&wkb);
+ y = popdouble(&wkb);
+ z = popdouble(&wkb);
+ m = popdouble(&wkb);
+
+ obj = SHPCreateObject(outshptype, -1, 0, NULL, NULL,
+ 1, &x, &y, &z, &m);
+
+ return obj;
+}
SHPObject *
-create_point3D_WKB(byte *wkb, int shape_id)
+create_point3D_WKB(byte *wkb)
{
SHPObject *obj;
double x, y, z;
}
SHPObject *
-create_point2D_WKB(byte *wkb, int shape_id)
+create_point2D_WKB(byte *wkb)
{
SHPObject *obj;
double x, y;
}
SHPObject *
-create_multipoint3D_WKB(byte *wkb, int shape_id)
+create_multipoint4D_WKB(byte *wkb)
{
SHPObject *obj;
- double *x=NULL, *y=NULL, *z=NULL;
+ double *x=NULL, *y=NULL, *z=NULL, *m=NULL;
int npoints;
int pn;
x = (double *)malloc(sizeof(double)*npoints);
y = (double *)malloc(sizeof(double)*npoints);
z = (double *)malloc(sizeof(double)*npoints);
+ m = (double *)malloc(sizeof(double)*npoints);
for (pn=0; pn<npoints; pn++)
{
x[pn]=popdouble(&wkb);
y[pn]=popdouble(&wkb);
z[pn]=popdouble(&wkb);
+ m[pn]=popdouble(&wkb);
}
- obj = SHPCreateSimpleObject(outshptype,npoints,x,y,z);
- free(x); free(y); free(z);
+ obj = SHPCreateObject(outshptype, -1, 0, NULL, NULL,
+ npoints, x, y, z, m);
+
+ free(x); free(y); free(z); free(m);
return obj;
}
SHPObject *
-create_multipoint2D_WKB(byte *wkb, int shape_id)
+create_multipoint3D_WKB(byte *wkb)
{
SHPObject *obj;
- double *x=NULL, *y=NULL;
- uint32 npoints;
- uint32 pn;
+ double *x=NULL, *y=NULL, *z=NULL;
+ int npoints;
+ int pn;
// skip byteOrder and type
skipbyte(&wkb); skipint(&wkb);
x = (double *)malloc(sizeof(double)*npoints);
y = (double *)malloc(sizeof(double)*npoints);
+ z = (double *)malloc(sizeof(double)*npoints);
for (pn=0; pn<npoints; pn++)
{
- skipbyte(&wkb); // byteOrder
- skipint(&wkb); // wkbType
x[pn]=popdouble(&wkb);
y[pn]=popdouble(&wkb);
+ z[pn]=popdouble(&wkb);
}
- obj = SHPCreateSimpleObject(outshptype,npoints,x,y,NULL);
- free(x); free(y);
+ obj = SHPCreateSimpleObject(outshptype,npoints,x,y,z);
+ free(x); free(y); free(z);
return obj;
}
SHPObject *
-create_polygon2D_WKB(byte *wkb, int shape_id)
+create_multipoint2D_WKB(byte *wkb)
{
SHPObject *obj;
- int ri, nrings, totpoints=0, *part_index=NULL;
- double *x=NULL, *y=NULL, *z=NULL;
-
- // skip byteOrder and type
- skipbyte(&wkb); skipint(&wkb);
-
+ double *x=NULL, *y=NULL;
+ uint32 npoints;
+ uint32 pn;
+
+ // skip byteOrder and type
+ skipbyte(&wkb); skipint(&wkb);
+
+ npoints = popint(&wkb);
+
+ x = (double *)malloc(sizeof(double)*npoints);
+ y = (double *)malloc(sizeof(double)*npoints);
+
+ for (pn=0; pn<npoints; pn++)
+ {
+ skipbyte(&wkb); // byteOrder
+ skipint(&wkb); // wkbType
+ x[pn]=popdouble(&wkb);
+ y[pn]=popdouble(&wkb);
+ }
+
+ obj = SHPCreateSimpleObject(outshptype,npoints,x,y,NULL);
+ free(x); free(y);
+
+ return obj;
+}
+
+SHPObject *
+create_polygon2D_WKB(byte *wkb)
+{
+ SHPObject *obj;
+ int ri, nrings, totpoints=0, *part_index=NULL;
+ double *x=NULL, *y=NULL, *z=NULL;
+
+ // skip byteOrder and type
+ skipbyte(&wkb); skipint(&wkb);
+
/*
* Scan all rings
*/
printf("Forcing CW\n");
#endif
reverse_points(npoints, x+totpoints,
- y+totpoints, NULL);
+ y+totpoints, NULL, NULL);
}
} else {
if ( is_clockwise(npoints, x+totpoints,
printf("Forcing CCW\n");
#endif
reverse_points(npoints, x+totpoints,
- y+totpoints, NULL);
+ y+totpoints, NULL, NULL);
}
}
totpoints += npoints;
}
- obj = SHPCreateObject(outshptype, shape_id, nrings,
+ obj = SHPCreateObject(outshptype, -1, nrings,
part_index, NULL, totpoints,
x, y, z, NULL);
}
SHPObject *
-create_polygon3D_WKB(byte *wkb, int shape_id)
+create_polygon4D_WKB(byte *wkb)
+{
+ SHPObject *obj;
+ int ri, nrings, totpoints=0, *part_index=NULL;
+ double *x=NULL, *y=NULL, *z=NULL, *m=NULL;
+
+ // skip byteOrder and type
+ skipbyte(&wkb); skipint(&wkb);
+
+ /*
+ * Scan all rings
+ */
+ nrings = popint(&wkb);
+#if VERBOSE > 2
+ printf("Polygon with %d rings\n", nrings);
+#endif
+ part_index = (int *)malloc(sizeof(int)*nrings);
+ for (ri=0; ri<nrings; ri++)
+ {
+ int pn;
+ int npoints = popint(&wkb);
+
+ x = realloc(x, sizeof(double)*(totpoints+npoints));
+ y = realloc(y, sizeof(double)*(totpoints+npoints));
+ z = realloc(z, sizeof(double)*(totpoints+npoints));
+ m = realloc(z, sizeof(double)*(totpoints+npoints));
+
+ for (pn=0; pn<npoints; pn++)
+ {
+ x[totpoints+pn] = popdouble(&wkb);
+ y[totpoints+pn] = popdouble(&wkb);
+ z[totpoints+pn] = popdouble(&wkb);
+ m[totpoints+pn] = popdouble(&wkb);
+ }
+
+ /*
+ * First ring should be clockwise,
+ * other rings should be counter-clockwise
+ */
+ if ( !ri ) {
+ if ( ! is_clockwise(npoints, x+totpoints,
+ y+totpoints, z+totpoints) ) {
+#if VERBOSE > 2
+ printf("Forcing CW\n");
+#endif
+ reverse_points(npoints, x+totpoints,
+ y+totpoints, z+totpoints, m+totpoints);
+ }
+ } else {
+ if ( is_clockwise(npoints, x+totpoints,
+ y+totpoints, z+totpoints) ) {
+#if VERBOSE > 2
+ printf("Forcing CCW\n");
+#endif
+ reverse_points(npoints, x+totpoints,
+ y+totpoints, z+totpoints, m+totpoints);
+ }
+ }
+
+ part_index[ri] = totpoints;
+ totpoints += npoints;
+ }
+
+ obj = SHPCreateObject(outshptype, -1, nrings,
+ part_index, NULL, totpoints,
+ x, y, z, m);
+
+ free(part_index);
+ free(x); free(y); free(z); free(m);
+
+ return obj;
+}
+
+SHPObject *
+create_polygon3D_WKB(byte *wkb)
{
SHPObject *obj;
int ri, nrings, totpoints=0, *part_index=NULL;
printf("Forcing CW\n");
#endif
reverse_points(npoints, x+totpoints,
- y+totpoints, z+totpoints);
+ y+totpoints, z+totpoints, NULL);
}
} else {
if ( is_clockwise(npoints, x+totpoints,
printf("Forcing CCW\n");
#endif
reverse_points(npoints, x+totpoints,
- y+totpoints, z+totpoints);
+ y+totpoints, z+totpoints, NULL);
}
}
totpoints += npoints;
}
- obj = SHPCreateObject(outshptype, shape_id, nrings,
+ obj = SHPCreateObject(outshptype, -1, nrings,
part_index, NULL, totpoints,
x, y, z, NULL);
}
SHPObject *
-create_multipolygon2D_WKB(byte *wkb, int shape_id)
+create_multipolygon2D_WKB(byte *wkb)
{
SHPObject *obj;
uint32 nrings, nparts;
printf("Forcing CW\n");
#endif
reverse_points(npoints, x+totpoints,
- y+totpoints, NULL);
+ y+totpoints, NULL, NULL);
}
} else {
if (is_clockwise(npoints, x+totpoints,
printf("Forcing CCW\n");
#endif
reverse_points(npoints, x+totpoints,
- y+totpoints, NULL);
+ y+totpoints, NULL, NULL);
}
}
printf("End of polygons\n");
#endif
- obj = SHPCreateObject(outshptype, shape_id, nparts,
+ obj = SHPCreateObject(outshptype, -1, nparts,
part_index, NULL, totpoints,
x, y, NULL, NULL);
}
SHPObject *
-create_multipolygon3D_WKB(byte *wkb, int shape_id)
+create_multipolygon3D_WKB(byte *wkb)
{
SHPObject *obj;
int nrings, nparts;
*/
if ( !ri ) {
if (!is_clockwise(npoints, x+totpoints,
- y+totpoints, NULL))
+ y+totpoints, z+totpoints))
{
#if VERBOSE > 2
printf("Forcing CW\n");
#endif
reverse_points(npoints, x+totpoints,
- y+totpoints, NULL);
+ y+totpoints, z+totpoints, NULL);
}
} else {
if (is_clockwise(npoints, x+totpoints,
- y+totpoints, NULL))
+ y+totpoints, z+totpoints))
{
#if VERBOSE > 2
printf("Forcing CCW\n");
#endif
reverse_points(npoints, x+totpoints,
- y+totpoints, NULL);
+ y+totpoints, z+totpoints, NULL);
}
}
printf("End of polygons\n");
#endif
- obj = SHPCreateObject(outshptype, shape_id, nparts,
+ obj = SHPCreateObject(outshptype, -1, nparts,
part_index, NULL, totpoints,
x, y, z, NULL);
return obj;
}
+SHPObject *
+create_multipolygon4D_WKB(byte *wkb)
+{
+ SHPObject *obj;
+ int nrings, nparts;
+ uint32 npolys;
+ int totpoints=0;
+ int *part_index=NULL;
+ int pi;
+ double *x=NULL, *y=NULL, *z=NULL, *m=NULL;
+
+ // skip byteOrder and type
+ //printf("byteOrder is %d\n", popbyte(&wkb));
+ //printf("Type is %d", popint(&wkb));
+ skipbyte(&wkb); skipint(&wkb);
+
+ /*
+ * Scan all polygons in multipolygon
+ */
+ nparts = 0;
+ npolys = popint(&wkb); // num_wkbPolygons
+#if VERBOSE > 2
+ printf("Multipolygon with %lu polygons\n", npolys);
+#endif
+
+ /*
+ * Now wkb points to a WKBPolygon structure
+ */
+ for (pi=0; pi<npolys; pi++)
+ {
+ int ri; // ring index
+
+ // skip byteOrder and wkbType
+ skipbyte(&wkb); skipint(&wkb);
+
+ /*
+ * Find total number of points and
+ * fill part index
+ */
+
+ nrings = popint(&wkb);
+ part_index = (int *)realloc(part_index,
+ sizeof(int)*(nparts+nrings));
+
+#if VERBOSE > 2
+ printf("Polygon %d has %d rings\n", pi, nrings);
+#endif
+
+ // wkb now points at first ring
+ for (ri=0; ri<nrings; ri++)
+ {
+ int pn; // point number
+ int npoints;
+
+ npoints = popint(&wkb);
+
+#if VERBOSE > 2
+ printf("Ring %d has %d points\n", ri, npoints);
+#endif
+
+ x = realloc(x, sizeof(double)*(totpoints+npoints));
+ y = realloc(y, sizeof(double)*(totpoints+npoints));
+ z = realloc(z, sizeof(double)*(totpoints+npoints));
+ m = realloc(z, sizeof(double)*(totpoints+npoints));
+
+ /* wkb now points at first point */
+ for (pn=0; pn<npoints; pn++)
+ {
+ x[totpoints+pn] = popdouble(&wkb);
+ y[totpoints+pn] = popdouble(&wkb);
+ z[totpoints+pn] = popdouble(&wkb);
+ m[totpoints+pn] = popdouble(&wkb);
+#if VERBOSE > 3
+ printf("Point%d (%f,%f)\n", pn, x[totpoints+pn], y[totpoints+pn]);
+#endif
+ }
+
+ /*
+ * First ring should be clockwise,
+ * other rings should be counter-clockwise
+ */
+ if ( !ri ) {
+ if (!is_clockwise(npoints, x+totpoints,
+ y+totpoints, z+totpoints))
+ {
+#if VERBOSE > 2
+ printf("Forcing CW\n");
+#endif
+ reverse_points(npoints, x+totpoints,
+ y+totpoints, z+totpoints, m+totpoints);
+ }
+ } else {
+ if (is_clockwise(npoints, x+totpoints,
+ y+totpoints, z+totpoints))
+ {
+#if VERBOSE > 2
+ printf("Forcing CCW\n");
+#endif
+ reverse_points(npoints, x+totpoints,
+ y+totpoints, z+totpoints, m+totpoints);
+ }
+ }
+
+ part_index[nparts+ri] = totpoints;
+ totpoints += npoints;
+ }
+#if VERBOSE > 2
+ printf("End of rings\n");
+#endif
+ nparts += nrings;
+ }
+
+#if VERBOSE > 2
+ printf("End of polygons\n");
+#endif
+
+ obj = SHPCreateObject(outshptype, -1, nparts,
+ part_index, NULL, totpoints,
+ x, y, z, m);
+
+#if VERBOSE > 2
+ printf("Object created\n");
+#endif
+
+ free(part_index);
+ free(x); free(y); free(z); free(m);
+
+ return obj;
+}
+
//Reverse the clockwise-ness of the point list...
-int reverse_points(int num_points,double *x,double *y,double *z){
+int
+reverse_points(int num_points, double *x, double *y, double *z, double *m)
+{
int i,j;
double temp;
z[i] = temp;
}
+ if ( m )
+ {
+ temp = m[j];
+ m[j] = m[i];
+ m[i] = temp;
+ }
+
j--;
}
return 1;
}
//return 1 if the points are in clockwise order
-int is_clockwise(int num_points,double *x,double *y,double *z){
+int is_clockwise(int num_points, double *x, double *y, double *z)
+{
int i;
double x_change,y_change,area;
double *x_new, *y_new; //the points, translated to the origin for safer accuracy
putenv(strdup(buf));
break;
case 'd':
- is3d = 1;
+ if ( ++ndims > 4 ) ndims = 4;
break;
case 'r':
includegid = 1;
{
case MULTILINETYPE:
case LINETYPE:
- if ( is3d ) outshptype=SHPT_ARCZ;
- else outshptype=SHPT_ARC;
+ if ( ndims == 2 ) outshptype=SHPT_ARC;
+ else if ( ndims == 3 ) outshptype=SHPT_ARCM;
+ else if ( ndims == 4 ) outshptype=SHPT_ARCZ;
break;
case POLYGONTYPE:
case MULTIPOLYGONTYPE:
- if ( is3d ) outshptype=SHPT_POLYGONZ;
- else outshptype=SHPT_POLYGON;
+ if ( ndims == 2 ) outshptype=SHPT_POLYGON;
+ else if ( ndims == 3 ) outshptype=SHPT_POLYGONM;
+ else if ( ndims == 4 ) outshptype=SHPT_POLYGONZ;
break;
case POINTTYPE:
- if ( is3d ) outshptype=SHPT_POINTZ;
- else outshptype=SHPT_POINT;
+ if ( ndims == 2 ) outshptype=SHPT_POINT;
+ else if ( ndims == 3 ) outshptype=SHPT_POINTM;
+ else if ( ndims == 4 ) outshptype=SHPT_POINTZ;
break;
case MULTIPOINTTYPE:
- if ( is3d ) outshptype=SHPT_MULTIPOINTZ;
- else outshptype=SHPT_MULTIPOINT;
+ if ( ndims == 2 ) outshptype=SHPT_MULTIPOINT;
+ else if ( ndims == 3 ) outshptype=SHPT_MULTIPOINTM;
+ else if ( ndims == 4 ) outshptype=SHPT_MULTIPOINTZ;
break;
*c+=8;
}
-//--------------------------- OLD CODE
-
-#ifdef KEEP_OLD_CODE
-
-SHPObject *create_lines(char *str,int shape_id, SHPHandle shp,int dims);
-SHPObject *create_multilines(char *str,int shape_id, SHPHandle shp,int dims);
-SHPObject *create_points(char *str,int shape_id, SHPHandle shp,int dims);
-SHPObject *create_multipoints(char *str,int shape_id, SHPHandle shp,int dims);
-SHPObject *create_polygons(char *str,int shape_id, SHPHandle shp,int dims);
-SHPObject *create_multipolygons(char *str,int shape_id, SHPHandle shp,int dims);
-
-
-SHPObject *
-create_lines(char *str,int shape_id, SHPHandle shp,int dims)
-{
- int points;
- int *part_index;
- int notnull;
-
- double *x,
- *y,
- *z;
- SHPObject *obj;
-
- notnull =1;
- part_index = (int *)malloc(sizeof(int)); //we know lines only have 1 part so make the array of size 1
- part_index[0] = 0;
-
- points = num_points(str);
- x = (double *)malloc(sizeof(double) * points);
- y = (double *)malloc(sizeof(double) * points);
- z = (double *)malloc(sizeof(double) * points);
-
- notnull = parse_points(str,points,x,y,z);
-
- if(dims == 0){
- if(notnull > 0){
- obj = SHPCreateObject(SHPT_ARC,shape_id,1,part_index,NULL,points,x,y,z,NULL);
- }else{
- obj = SHPCreateObject(SHPT_NULL,shape_id,1,part_index,NULL,points,x,y,z,NULL);
- }
- }else{
- if(notnull > 0){
- obj = SHPCreateObject(SHPT_ARCZ,shape_id,1,part_index,NULL,points,x,y,z,NULL);
- }else{
- obj = SHPCreateObject(SHPT_NULL,shape_id,1,part_index,NULL,points,x,y,z,NULL);
- }
- }
- free(part_index);
- free(x); free(y); free(z);
-
- return obj;
-}
-
-SHPObject *
-create_multilines(char *str,int shape_id, SHPHandle shp,int dims)
-{
- int lines,i,j,max_points,index;
- int *points;
- int *part_index;
- int notnull;
-
- double *x;
- double *y;
- double *z;
-
- double *totx;
- double *toty;
- double *totz;
- SHPObject *obj;
-
- notnull=1;
- lines = num_lines(str);
-
- points = (int *)malloc(sizeof(int) * lines);
-
- if(points_per_sublist(str, points, lines) ==0){
- printf("error - points_per_sublist failed");
- }
- max_points = 0;
- for(j=0;j<lines;j++){
- max_points += points[j];
- }
-
- part_index = (int *)malloc(sizeof(int) * lines);
- totx = (double *)malloc(sizeof(double) * max_points);
- toty = (double *)malloc(sizeof(double) * max_points);
- totz = (double *)malloc(sizeof(double) * max_points);
-
- index=0;
-
- if(lines == 0 ){
- notnull = 0;
- }
- for(i=0;i<lines;i++){
- str = strchr(str,'(') ;
-
-
- if(str[0] =='(' && str[1] == '('){
- str++;
- }
-
- x = (double *)malloc(sizeof(double) * points[i]);
- y = (double *)malloc(sizeof(double) * points[i]);
- z = (double *)malloc(sizeof(double) * points[i]);
-
- notnull = parse_points(str,points[i],x,y,z);
- str = scan_to_same_level(str);
- part_index[i] = index;
- for(j=0;j<points[i];j++){
- totx[index] = x[j];
- toty[index] = y[j];
- totz[index] = z[j];
- index++;
- }
- free(x);
- free(y);
- free(z);
- }
-
-
- if(dims == 0){
- if(notnull > 0){
- obj = SHPCreateObject(SHPT_ARC,shape_id,lines,part_index,NULL,max_points,totx,toty,totz,NULL);
- }else{
- obj = SHPCreateObject(SHPT_NULL,shape_id,lines,part_index,NULL,max_points,totx,toty,totz,NULL);
- }
- }else{
- if(notnull > 0){
- obj = SHPCreateObject(SHPT_ARCZ,shape_id,lines,part_index,NULL,max_points,totx,toty,totz,NULL);
- }else{
- obj = SHPCreateObject(SHPT_NULL,shape_id,lines,part_index,NULL,max_points,totx,toty,totz,NULL);
- }
- }
- free(part_index); free(points);
- free(totx); free(toty); free(totz);
-
- return obj;
-}
-
-SHPObject *
-create_points(char *str, int shape_id, SHPHandle shp, int is3d)
-{
-
- double *x,
- *y,
- *z;
- SHPObject *obj;
- int notnull;
- int outtype;
-
- notnull = 1;
-
- x = (double *)malloc(sizeof(double));
- y = (double *)malloc(sizeof(double));
- z = (double *)malloc(sizeof(double));
-
- notnull = parse_points(str,1,x,y,z);
-
- if ( ! notnull )
- {
- outtype = SHPT_NULL;
- }
- else if ( geotype == POINTTYPE )
- {
- outtype = is3d ? SHPT_POINTZ : SHPT_POINT;
- }
- else if ( geotype == MULTIPOINTTYPE )
- {
- //fprintf(stderr, "create_points: fluffing to MULTIPOINT\n");
- outtype = is3d ? SHPT_MULTIPOINTZ : SHPT_MULTIPOINT;
- }
- else
- {
- fprintf(stderr, "create_points called with wrong geometry type (%d)\n", geotype);
- return NULL;
- }
-
- obj = SHPCreateSimpleObject(outtype,1,x,y,z);
- free(x); free(y); free(z);
-
- return obj;
-}
-
-SHPObject *
-create_multipoints(char *str,int shape_id, SHPHandle shp,int dims)
-{
- int points;
-
- double *x,
- *y,
- *z;
- SHPObject *obj;
- int notnull;
- notnull=1;
-
- points = num_points(str);
- x = (double *)malloc(sizeof(double)*points);
- y = (double *)malloc(sizeof(double)*points);
- z = (double *)malloc(sizeof(double)*points);
-
- notnull = parse_points(str,points,x,y,z);
-
- if(dims == 0){
- if(notnull > 0){
- obj = SHPCreateSimpleObject(SHPT_MULTIPOINT ,points,x,y,z);
- }else{
- obj = SHPCreateSimpleObject(SHPT_NULL ,points,x,y,z);
- }
- }else{
- if(notnull > 0){
- obj = SHPCreateSimpleObject(SHPT_MULTIPOINTZ ,points,x,y,z);
- }else{
- obj = SHPCreateSimpleObject(SHPT_NULL ,points,x,y,z);
- }
- }
-
- free(x); free(y); free(z);
-
- return obj;
-}
-
-SHPObject *
-create_polygons(char *str,int shape_id, SHPHandle shp,int dims)
-{
- int rings,i,j,max_points,index;
- int *points;
- int *part_index;
- int notnull;
-
- double *x;
- double *y;
- double *z;
-
- double *totx;
- double *toty;
- double *totz;
- SHPObject *obj;
-
- notnull = 1;
-
- rings = num_lines(str); //the number of rings in the polygon
- points = (int *)malloc(sizeof(int) * rings);
-
- if(points_per_sublist(str, points, rings) ==0){
- printf("error - points_per_sublist failed");
- }
- max_points = 0;
- for(j=0;j<rings;j++){
- max_points += points[j];
- }
-
- part_index = (int *)malloc(sizeof(int) * rings);
- totx = (double *)malloc(sizeof(double) * max_points);
- toty = (double *)malloc(sizeof(double) * max_points);
- totz = (double *)malloc(sizeof(double) * max_points);
-
- index=0;
- if (rings == 0){
- notnull = 0;
- }
- for(i=0;i<rings;i++){
- str = strchr(str,'(') ;
-
-
- if(str[0] =='(' && str[1] == '('){
- str++;
- }
-
- x = (double *)malloc(sizeof(double) * points[i]);
- y = (double *)malloc(sizeof(double) * points[i]);
- z = (double *)malloc(sizeof(double) * points[i]);
-
- notnull = parse_points(str,points[i],x,y,z);
-
- str = scan_to_same_level(str);
- part_index[i] = index;
-
- //if this the first ring it should be clockwise, other rings are holes and should be counter-clockwise
- if(i ==0){
- if(is_clockwise(points[i],x,y,z) == 0){
- reverse_points(points[i],x,y,z);
- }
- }else{
- if(is_clockwise(points[i],x,y,z) == 1){
- reverse_points(points[i],x,y,z);
- }
- }
-
- for(j=0;j<points[i];j++){
- totx[index] = x[j];
- toty[index] = y[j];
- totz[index] = z[j];
- index++;
- }
-// free(x);
-// free(y);
-// free(z);
- }
-
- if(dims == 0){
- if(notnull > 0){
- obj = SHPCreateObject(SHPT_POLYGON,shape_id,rings,part_index,NULL,max_points,totx,toty,totz,NULL);
- }else{
- obj = SHPCreateObject(SHPT_NULL,shape_id,rings,part_index,NULL,max_points,totx,toty,totz,NULL);
- }
- }else{
- if(notnull > 0){
- obj = SHPCreateObject(SHPT_POLYGONZ,shape_id,rings,part_index,NULL,max_points,totx,toty,totz,NULL);
- }else{
- obj = SHPCreateObject(SHPT_NULL,shape_id,rings,part_index,NULL,max_points,totx,toty,totz,NULL);
- }
- }
- free(part_index);
- free(points);
- free(totx);
- free(toty);
- free(totz);
-
- return obj;
-}
-
-SHPObject *
-create_multipolygons(char *str,int shape_id, SHPHandle shp,int dims)
-{
- int polys,rings,i,j,k,max_points;
- int index,indexk,index2part,tot_rings,final_max_points;
- int *points;
- int *part_index;
- int *final_part_index;
- int notnull;
-
- char *temp;
- char *temp_addr;
-
- double *x;
- double *y;
- double *z;
-
- double *totx;
- double *toty;
- double *totz;
-
- double *finalx;
- double *finaly;
- double *finalz;
-
- SHPObject *obj;
-
- points=0;
- notnull = 1;
-
- polys = num_lines(str); //the number of rings in the polygon
- final_max_points =0;
-
- temp_addr = (char *)malloc(strlen(str) +1 );
- temp = temp_addr; //keep original pointer to free the mem later
- strcpy(temp,str);
- tot_rings=0;
- index2part=0;
- indexk=0;
-
-
- for(i=0;i<polys;i++){
- temp = strstr(temp,"((") ;
- if(temp[0] =='(' && temp[1] == '(' && temp[2] =='('){
- temp++;
- }
- rings = num_lines(temp);
- points = (int *)malloc(sizeof(int) * rings);
- points_per_sublist(temp, points, rings);
- tot_rings += rings;
- for(j=0;j<rings;j++){
- final_max_points += points[j];
- }
-
- temp+= 2;
- }
- free(points);
- temp= temp_addr;
-
- final_part_index = (int *)malloc(sizeof(int) * tot_rings);
- finalx = (double *)malloc(sizeof(double) * final_max_points);
- finaly = (double *)malloc(sizeof(double) * final_max_points);
- finalz = (double *)malloc(sizeof(double) * final_max_points);
-
- if(polys == 0){
- notnull = 0;
- }
-
- for(k=0;k<polys ; k++){ //for each polygon
-
- str = strstr(str,"((") ;
- if(strlen(str) >2 && str[0] =='(' && str[1] == '(' && str[2] =='('){
- str++;
- }
-
- rings = num_lines(str);
- points = (int *)malloc(sizeof(int) * rings);
-
- if(points_per_sublist(str, points, rings) ==0){
- printf("error - points_per_sublist failed");
- }
- max_points = 0;
- for(j=0;j<rings;j++){
- max_points += points[j];
- }
-
- part_index = (int *)malloc(sizeof(int) * rings);
- totx = (double *)malloc(sizeof(double) * max_points);
- toty = (double *)malloc(sizeof(double) * max_points);
- totz = (double *)malloc(sizeof(double) * max_points);
-
- index=0;
- for(i=0;i<rings;i++){
- str = strchr(str,'(') ;
- if(str[0] =='(' && str[1] == '('){
- str++;
- }
-
- x = (double *)malloc(sizeof(double) * points[i]);
- y = (double *)malloc(sizeof(double) * points[i]);
- z = (double *)malloc(sizeof(double) * points[i]);
-
- notnull = parse_points(str,points[i],x,y,z);
- str = scan_to_same_level(str);
- part_index[i] = index;
-
- //if this the first ring it should be clockwise, other rings are holes and should be counter-clockwise
- if(i ==0){
- if(is_clockwise(points[i],x,y,z) == 0){
- reverse_points(points[i],x,y,z);
- }
- }else{
- if(is_clockwise(points[i],x,y,z) == 1){
- reverse_points(points[i],x,y,z);
- }
- }
-
- for(j=0;j<points[i];j++){
- totx[index] = x[j];
- toty[index] = y[j];
- totz[index] = z[j];
- index++;
- }
- free(x);
- free(y);
- free(z);
- }
- for(j=0;j<i;j++){
- final_part_index[index2part] = part_index[j]+indexk ;
- index2part++;
- }
-
- for(j=0;j<index;j++){
- finalx[indexk] = totx[j];
- finaly[indexk] = toty[j];
- finalz[indexk] = totz[j];
- indexk++;
- }
-
- free(points);
- free(part_index);
- free(totx);
- free(toty);
- free(totz);
- str -= 1;
- }//end for (k < polys... loop
-
-
- if(dims == 0){
- if(notnull > 0){
- obj = SHPCreateObject(SHPT_POLYGON,shape_id,tot_rings,final_part_index,NULL,final_max_points,finalx,finaly,finalz,NULL);
- }else{
- obj = SHPCreateObject(SHPT_NULL,shape_id,tot_rings,final_part_index,NULL,final_max_points,finalx,finaly,finalz,NULL);
- }
- }else{
- if(notnull > 0){
- obj = SHPCreateObject(SHPT_POLYGONZ,shape_id,tot_rings,final_part_index,NULL,final_max_points,finalx,finaly,finalz,NULL);
- }else{
- obj = SHPCreateObject(SHPT_NULL,shape_id,tot_rings,final_part_index,NULL,final_max_points,finalx,finaly,finalz,NULL);
- }
- }
-
- free(final_part_index);
- free(finalx);
- free(finaly);
- free(finalz);
-
- return obj;
-}
-
-
-#endif // KEEP_OLD_CODE
+/**********************************************************************
+ * $Log$
+ * Revision 1.56 2004/09/20 16:33:05 strk
+ * Added 4d geometries support.
+ * Changelog section moved at bottom file.
+ *
+ * Revision 1.55 2004/09/20 14:14:43 strk
+ * Fixed a bug in popbyte. Trapped WKB endiannes errors.
+ *
+ * Revision 1.54 2004/09/20 13:49:27 strk
+ * Postgis-1.x support (LWGEOM) added.
+ * postgis version detected at runtime.
+ * Endiannes unchecked ... TODO.
+ *
+ * Revision 1.53 2004/08/05 16:53:29 strk
+ * schema support patches sent by Mark
+ *
+ * Revision 1.52 2004/06/16 13:42:05 strk
+ * Added schema support in getMaxFieldSize.
+ * Added direct support for TIMESTAMP field types (thanks to Steffen Macke).
+ *
+ * Revision 1.51 2004/05/13 12:24:15 strk
+ * Transformed NULL numeric values to 0 as it was before the introduction
+ * of bigint bug workaround.
+ *
+ * Revision 1.50 2004/05/13 12:13:01 strk
+ * Used DBFWriteAttributeDirectly interface for writing attributes.
+ * This way we are not affected by shapelib long-integer bug.
+ *
+ * Revision 1.49 2004/05/13 12:07:13 strk
+ * Other fix in 3d handling - you should now be able to dump as 2d or 3d any 2d or 3d object
+ *
+ * Revision 1.48 2004/05/13 11:59:08 strk
+ * Fixed bug in 3d features handling.
+ *
+ * Revision 1.47 2004/04/21 09:13:15 strk
+ * Attribute names escaping mechanism added. You should now
+ * be able to dump a shapefile equal to the one loaded.
+ *
+ * Revision 1.46 2004/04/21 07:38:34 strk
+ * Memory allocated for main_scan_query was not enough when using binary cursor. Fixed
+ *
+ * Revision 1.45 2004/03/29 10:20:48 strk
+ * Fixed a bug in WKB parsing for Multipoints.
+ * Fixed a bug in -d handling for WKB.
+ * Added point->multipoint fluffing capabilities.
+ *
+ * Revision 1.44 2004/03/10 18:46:07 strk
+ * Fixed a bug reducing the output shapes from Multipolygon tables.
+ *
+ * Revision 1.43 2004/03/06 17:43:06 strk
+ * Added RCSID string in usage output
+ *
+ * Revision 1.42 2004/02/09 18:49:23 strk
+ * byte endiannes detected empirically
+ *
+ * Revision 1.41 2004/02/06 08:26:02 strk
+ * updated wkb reading funx to reflect changes made by pramsey in postgis_inout.c to be nicer with solaris
+ *
+ * Revision 1.40 2003/12/27 13:30:23 strk
+ * Added schema specification support
+ *
+ * Revision 1.39 2003/12/19 18:55:46 strk
+ * substituted setenv() calls with putenv() for Solaris support
+ *
+ * Revision 1.38 2003/12/04 19:11:56 strk
+ * code cleanup (removed useless and leaking malloc calls)
+ *
+ * Revision 1.37 2003/11/26 18:54:22 strk
+ * fixed bug in HexDecoder, made WKB parsing the default
+ *
+ * Revision 1.36 2003/11/26 18:14:11 strk
+ * binary cursor implemented
+ *
+ * Revision 1.35 2003/11/26 17:21:00 strk
+ * Made HEXWKB parsing settable at compile time
+ *
+ * Revision 1.34 2003/11/26 16:40:41 strk
+ * Handled NULLS in wkb parsing, reduced functions args
+ *
+ * Revision 1.33 2003/11/26 15:45:53 strk
+ * wkb support for all geom types
+ *
+ * Revision 1.32 2003/11/26 14:31:20 strk
+ * WKB start to work
+ *
+ * Revision 1.31 2003/11/25 17:28:03 strk
+ * hardly trying to get WKB parsing work
+ *
+ * Revision 1.30 2003/11/24 17:36:28 strk
+ * Removed useless BYTE_ORDER checks
+ *
+ * Revision 1.29 2003/11/21 23:51:14 pramsey
+ * Added Cygwin endian definition include to fix windows compile.
+ *
+ * Revision 1.28 2003/11/20 18:01:26 strk
+ * patch from m.spring@gmx.de
+ *
+ * Revision 1.27 2003/11/20 15:27:20 strk
+ * Removed some useless strdups.
+ * Removed pgtype 22 (int2vector) from the list of integer DBF field types.
+ * Added pgtype 1700 (numeric) in DBF doubles list.
+ *
+ * Revision 1.26 2003/11/18 14:58:47 strk
+ * default row buffer lenght set to 100
+ *
+ * Revision 1.25 2003/11/18 14:39:26 strk
+ * Some more structuring. Initialization routine moved out of main loop.
+ * Preparing dumper for WKB parsing.
+ *
+ * Revision 1.24 2003/11/16 00:27:46 strk
+ * Huge code re-organization. More structured code, more errors handled,
+ * cursor based iteration, less code lines.
+ *
+ * Revision 1.23 2003/11/14 22:04:51 strk
+ * Used environment vars to pass libpq connection options (less error prone,
+ * easier to read). Printed clearer error message on query error.
+ *
+ * Revision 1.22 2003/09/10 22:44:56 jeffloun
+ * got rid of warning...
+ *
+ * Revision 1.21 2003/09/10 22:40:11 jeffloun
+ * changed it to make the field names in the dbf file capital letters
+ *
+ * Revision 1.20 2003/09/10 21:36:04 jeffloun
+ * fixed a bug in is_clockwise...
+ *
+ * Revision 1.19 2003/07/01 18:30:55 pramsey
+ * Added CVS revision headers.
+ *
+ * Revision 1.18 2003/02/04 21:39:20 pramsey
+ * Added CVS substitution strings for logging.
+ *
+ **********************************************************************/