./shapelib-1.2.10/0040755000076500001440000000000007644273462013267 5ustar warmerdausers./shapelib-1.2.10/contrib/0040755000076500001440000000000007644273440014723 5ustar warmerdausers./shapelib-1.2.10/contrib/doc/0040755000076500001440000000000007644274052015470 5ustar warmerdausers./shapelib-1.2.10/contrib/doc/shpproj.txt0100644000076500001440000000452407644273432017721 0ustar warmerdausers shpproj using the projection tools proj and invproj we have implemented a shapefile projection utility shpproj shp_file new_shp ( -i=in_proj_file | -i="in_params" | -i=geographic ) ( -o=out_info_file | -o="out_params" | -o=geographic ) INPUT Input can come from one of three sources. A projection parameter file, directly through parameters or geographic. If the shapefile has an associated prj file, name the same as the shapefile but ending in ".prj" it will be used by default ignoring all other parameters. If input is omitted it defaults to geographic, unless the default prj file exists.. OUTPUT Output can come from one of three sources. A projection parameter file, directly through parameters or geographic. If output is omitted it defaults to geographic. PROJECTION PARAMETER FILE This file MUST end with the extension ".prj". It has the form of one projection parameter per line. Parameters can be in any order. PROJECTION PARAMETERS Are the same as used by proj and invproj. use proj -lP to see available projections proj -lu to see available units proj -le to see available ellipsoid USAGE the following example projects file rowtest to row3, moving data from Stateplane NAD83 zone 1002 to utm zone 16 in meters shpproj rowtest row -i="init=nad83:1002 units=us-ft" -o="proj=utm zone=16 units=m" shpproj rowtest row3 -o="proj=utm zone=18 units=m" -i="zone=16 proj=utm units=us-ft" shpproj rowtest row3 -o="proj=utm zone=18 units=m" shpproj rowtest row3 -i=myfile.prj -o=geographic shpproj rowtest row3 -is=myfile.prj Datums Stateplane data can be accessed by the init function init=nad83:1003 which is of the form datum:FIPSzone To move from NAD27 to NAD83 or otherwise the shpproj utility moves to geographic coordinates and the back to the desired datum. proj can handle direct datum to datum conversions but it is umimplemented here. for a complete listing of FIPSZones by datum read nad/nad.lst in the PROJ4 library CAUTION It is possible to get very poor results for projection values when using coordinates VERY far away from the intended scope of the projection. An example of a poor projection choice would be to move from nad83:1002 (Georgia West) for data in California into utm. The resulting data will be much less accurate than if it had started as geographic. ./shapelib-1.2.10/contrib/.cvsignore0100644000076500001440000000010507644273432016715 0ustar warmerdausersshpdxf dbfinfo shpcentrd shpdata shpwkb dbfcat shpinfo shpfix shpcat ./shapelib-1.2.10/contrib/Makefile0100644000076500001440000000304307644273432016361 0ustar warmerdausers #LINKOPT = /usr/local/lib/libdbmalloc.a #CFLAGS = -g # Endian: define either _LITTLE_ENDIAN or _BIG_ENDIAN ENDIAN = -D_LITTLE_ENDIAN CFLAGS = -g -I.. -DPROJ4 $(ENDIAN) -DDEBUG -DDEBUG2 SHPOBJ = ../shpopen.o ../dbfopen.o SHPGOBJ = ../shpopen.o ../dbfopen.o shpgeo.o GEOOBJ = ./shpgeo.o -lm -lproj default: all all: shpdxf shpproj dbfinfo shpcentrd shpdata shpwkb dbfinfo dbfcat shpinfo shpfix shpcat clean: rm -f shpdxf shpproj dbfinfo shpcentrd shpdata shpwkb dbfcat dbfinfo shpinfo shpfix shpcat *.o shpgeo.o: shpgeo.c shpgeo.h $(CC) $(CFLAGS) -c shpgeo.c shpdxf: shpdxf.c $(SHPOBJ) $(CC) $(CFLAGS) shpdxf.c ${SHPOBJ} $(LINKOPT) -o shpdxf shpcentrd: shpcentrd.c $(SHPGOBJ) $(CC) $(CFLAGS) shpcentrd.c ${SHPOBJ} $(LINKOPT) $(GEOOBJ) -o shpcentrd shpdata: shpdata.c $(SHPGOBJ) $(CC) $(CFLAGS) shpdata.c ${SHPOBJ} $(LINKOPT) $(GEOOBJ) -o shpdata shpinfo: shpinfo.c $(SHPOBJ) $(CC) $(CFLAGS) shpinfo.c ${SHPOBJ} $(LINKOPT) $(GEOOBJ) -o shpinfo shpfix: shpfix.c $(SHPOBJ) $(CC) $(CFLAGS) shpfix.c ${SHPOBJ} $(LINKOPT) -o shpfix shpcat: shpcat.c $(SHPOBJ) $(CC) $(CFLAGS) shpcat.c ${SHPOBJ} $(LINKOPT) -o shpcat shpwkb: shpwkb.c $(SHPGOBJ) $(CC) $(CFLAGS) shpwkb.c ${SHPOBJ} $(LINKOPT) $(GEOOBJ) -o shpwkb shpproj: shpproj.c $(SHPGOBJ) $(CC) $(CFLAGS) shpproj.c $(SHPOBJ) $(GEOOBJ) -lm -lproj $(LINKOPT) -o shpproj dbfinfo: dbfinfo.c $(SHPOBJ) $(CC) $(CFLAGS) dbfinfo.c $(SHPOBJ) $(LINKOPT) -o dbfinfo dbfcat: dbfcat.c $(SHPOBJ) $(CC) $(CFLAGS) dbfcat.c $(SHPOBJ) $(LINKOPT) -o dbfcat check: testproj testproj: tests/shpproj.sh ./shapelib-1.2.10/contrib/ShapeFileII.pas0100644000076500001440000002545007644273432017516 0ustar warmerdausers{ /****************************************************************************** * $Id: ShapeFileII.pas,v 1.2 2002/01/21 14:09:26 warmerda Exp $ * * Project: Shapelib * Purpose: Delphi Pascal interface to Shapelib. * Author: Kevin Meyer (Kevin@CyberTracker.co.za) * ****************************************************************************** * Copyright (c) 2002, Keven Meyer (Kevin@CyberTracker.co.za) * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: ShapeFileII.pas,v $ * Revision 1.2 2002/01/21 14:09:26 warmerda * Fixed name. * * Revision 1.1 2002/01/17 14:30:37 warmerda * New * */ } unit ShapeFileII; interface //uses { uses clause } // ; { Set compiler to pack on byte boundaries only } {$ALIGN OFF} {$OVERFLOWCHECKS OFF} {$J-} const SHPT_NULL = 0; SHPT_POINT = 1; SHPT_ARC = 3; SHPT_POLYGON = 5; SHPT_MULTIPOINT = 8; SHPT_POINTZ = 11; SHPT_ARCZ = 13; SHPT_POLYGONZ = 15; SHPT_MULTIPOINTZ = 18; SHPT_POINTM = 21; SHPT_ARCM = 23; SHPT_POLYGONM = 25; SHPT_MULTIPOINTM = 28; SHPT_MULTIPATCH = 31; XBASE_FLDHDR_SZ = 32; szAccessBRW = 'rb+'; // *********************** SHP support ************************ type SHPObject = record nSHPType, nShapeId, nParts : LongWord; panPartStart, panPartType : array of LongWord; nVertices : LongWord; padfX, padfY, padfZ, padfM : array of double; dfXMin, dfYMin, dfZMin, dfMMin : double; dfXMax, dfYMax, dfZMax, dfMMax : double; end; SHPObjectHandle = ^SHPObject; SHPBoundsArr = double; SHPInfo = record fpSHP, fpSHX : FILE; nShapeType, nFileSize, nRecords, nMaxRecords : LongWord; panRecOffset, panRecSize : array of LongWord; adBoundsMin, adBoundsMax : SHPBoundsArr; bUpdated : LongWord; end; SHPHandle = ^SHPInfo; // *********************** DBF support ************************ DBFInfo = record fp : FILE; nRecords, nRecordLength, nHeaderLength, nFields : LongWord; panFieldOffset, panFieldSize, panFieldDecimals : array of LongWord; pachFieldType : LongWord; pszHeader : PChar; nCurrentRecord, bCurrentRecordModified : LongWord; pszCurrentRecord : PChar; bNoHeader, bUpdated : LongWord; end; DBFHandle = ^DBFInfo; DBFFieldType = (DBFTString, DBFTInteger, DBFTDouble, DBFTInvalid) ; // *********************** SHP func declarations ************************ {$ALIGN ON} function SHPOpen(pszShapeFile, pszAccess : PChar) : SHPHandle;cdecl; procedure SHPGetInfo(hSHP : SHPHandle; var pnEntities, pnShapeType : LongWord; var padfMinBoud, padfMaxBound : SHPBoundsArr);cdecl; procedure SHPClose(hSHP : SHPHandle);cdecl; function SHPReadObject(hSHP : SHPHandle; iShape : LongWord): SHPObjectHandle;cdecl; function SHPCreate(pszShapeFile : PChar; nShapeType : LongWord):SHPHandle;cdecl; function SHPWriteObject(hSHP : SHPHandle; iShape : LongWord; psObject : SHPObjectHandle): LongWord;cdecl; function SHPCreateSimpleObject(nSHPType, nVertices : LongWord; var padfX, padfY, padfZ : double):SHPObjectHandle;cdecl; procedure SHPDestroy(psObject : SHPObjectHandle);cdecl; procedure SHPComputeExtents(psObject : SHPObjectHandle);cdecl; function SHPCreateObject(nSHPType, iShape, nParts : LongWord; var panPartStart, panPartType : LongWord; nVertices : LongWord; var padfX, padfY, padfZ, padfM : SHPBoundsArr): SHPObjectHandle;cdecl; function SHPTypeStr(pnShapeType : LongWord): string; // *********************** DBF func declarations ************************ function DBFOpen(pszDBFFile, pszAccess : PChar): DBFHandle;cdecl; function DBFCreate(pszDBFFile : PChar): DBFHandle ;cdecl; function DBFGetFieldCount(hDBF : DBFHandle) : LongWord ;cdecl; function DBFGetRecordCount(hDBF : DBFHandle) : LongWord;cdecl; function DBFGetFieldIndex(hDBF: DBFHandle; pszFieldName : PChar): LongWord;cdecl; function DBFGetFieldInfo(hDBF : DBFHandle; iField : LongWord; pszFieldName : PChar; var pnWidth, pnDecimals : LongWord): DBFFieldType;cdecl; function DBFAddField(hDBF : DBFHandle; pszFieldName : PChar; eType : DBFFieldType; nWidth, nDecimals : LongWord): LongWord;cdecl; function DBFReadIntegerAttribute(hDBF : DBFHandle;iShape, iField : LongWord ): LongWord;cdecl; function DBFReadDoubleAttribute(hDBF : DBFHandle; iShape, iField : LongWord ):double;cdecl; function DBFReadStringAttribute(hDBF : DBFHandle; iShape, iField : LongWord ) : pchar;cdecl; function DBFIsAttributeNULL(hDBF : DBFHandle; iShape, iField : LongWord ): LongWord;cdecl; function DBFWriteIntegerAttribute(hDBF : DBFHandle;iShape, iField, nFieldValue : LongWord): LongWord;cdecl; function DBFWriteDoubleAttribute(hDBF : DBFHandle;iShape, iField : LongWord; dFieldValue : double): LongWord ;cdecl; function DBFWriteStringAttribute(hDBF : DBFHandle;iShape, iField : LongWord; pszFieldValue : PChar): LongWord ;cdecl; function DBFWriteNULLAttribute(hDBF : DBFHandle; iShape, iField : LongWord ) : LongWord;cdecl; procedure DBFClose(hDBF : DBFHandle);cdecl; function DBFGetNativeFieldType(hDBF : DBFHandle; iField : LongWord) : Char;cdecl; // *********************** SHP implementation ************************ implementation // ***************************************************************************** function SHPCreateSimpleObject(nSHPType, nVertices : LongWord; var padfX, padfY, padfZ : double):SHPObjectHandle;external 'shapelib.dll' name 'SHPCreateSimpleObject'; function SHPOpen(pszShapeFile, pszAccess : PChar) : SHPHandle; external 'shapelib.dll' name 'SHPOpen'; procedure SHPGetInfo(hSHP : SHPHandle; var pnEntities, pnShapeType : LongWord; var padfMinBoud, padfMaxBound : SHPBoundsArr);external 'shapelib.dll' name 'SHPGetInfo'; procedure SHPClose(hSHP : SHPHandle);external 'shapelib.dll' name 'SHPClose'; function SHPReadObject(hSHP : SHPHandle; iShape : LongWord) : SHPObjectHandle;external 'shapelib.dll' name 'SHPReadObject'; function SHPCreate(pszShapeFile : PChar; nShapeType : LongWord):SHPHandle;external 'shapelib.dll' name 'SHPCreate'; function SHPWriteObject(hSHP : SHPHandle; iShape : LongWord; psObject : SHPObjectHandle): LongWord;cdecl;external 'shapelib.dll' name 'SHPWriteObject'; procedure SHPDestroy(psObject : SHPObjectHandle);external 'shapelib.dll' name 'SHPDestroyObject'; procedure SHPComputeExtents(psObject : SHPObjectHandle);external 'shapelib.dll' name 'SHPComputeExtents'; function SHPCreateObject(nSHPType, iShape, nParts : LongWord; var panPartStart, panPartType : LongWord; nVertices : LongWord; var padfX, padfY, padfZ, padfM : SHPBoundsArr): SHPObjectHandle;external 'shapelib.dll' name 'SHPCreateObject'; // ***************************************************************************** function SHPTypeStr(pnShapeType : LongWord): string; begin case pnShapeType of SHPT_NULL : result := 'NULL'; SHPT_POINT : result := 'POINT'; SHPT_ARC : result := 'ARC'; SHPT_POLYGON : result := 'POLYGON'; SHPT_MULTIPOINT : result := 'MULTIPOINT'; SHPT_POINTZ : result := 'POINTZ'; SHPT_ARCZ : result := 'ARCZ'; SHPT_POLYGONZ : result := 'POLYGONZ'; SHPT_MULTIPOINTZ : result := 'MULTIPOINTZ'; SHPT_POINTM : result := 'POINTM'; SHPT_ARCM : result := 'ARCM'; SHPT_POLYGONM : result := 'POLYGONM'; SHPT_MULTIPOINTM : result := 'MULTIPOINTM'; SHPT_MULTIPATCH : result := 'MULTIPATCH'; else result := '--unknown--'; end; end; // ***************************************************************************** // ***************************************************************************** function DBFOpen(pszDBFFile, pszAccess : PChar): DBFHandle;external 'shapelib.dll'; function DBFCreate(pszDBFFile : PChar): DBFHandle ;external 'shapelib.dll'; function DBFGetFieldCount(hDBF : DBFHandle) : LongWord ;external 'shapelib.dll'; function DBFGetRecordCount(hDBF : DBFHandle) : LongWord;external 'shapelib.dll'; function DBFGetFieldIndex(hDBF: DBFHandle; pszFieldName : PChar): LongWord;external 'shapelib.dll'; function DBFGetFieldInfo(hDBF : DBFHandle; iField : LongWord; pszFieldName : PChar; var pnWidth, pnDecimals : LongWord): DBFFieldType;external 'shapelib.dll'; function DBFAddField(hDBF : DBFHandle; pszFieldName : PChar; eType : DBFFieldType; nWidth, nDecimals : LongWord): LongWord;external 'shapelib.dll'; function DBFReadIntegerAttribute(hDBF : DBFHandle;iShape, iField : LongWord ): LongWord;external 'shapelib.dll'; function DBFReadDoubleAttribute(hDBF : DBFHandle; iShape, iField : LongWord ):double;external 'shapelib.dll'; function DBFReadStringAttribute(hDBF : DBFHandle; iShape, iField : LongWord ) : pchar;external 'shapelib.dll'; function DBFIsAttributeNULL(hDBF : DBFHandle; iShape, iField : LongWord ): LongWord;external 'shapelib.dll'; function DBFWriteIntegerAttribute(hDBF : DBFHandle;iShape, iField, nFieldValue : LongWord): LongWord;external 'shapelib.dll'; function DBFWriteDoubleAttribute(hDBF : DBFHandle;iShape, iField : LongWord; dFieldValue : double): LongWord ;external 'shapelib.dll'; function DBFWriteStringAttribute(hDBF : DBFHandle;iShape, iField : LongWord; pszFieldValue : PChar): LongWord ;external 'shapelib.dll'; function DBFWriteNULLAttribute(hDBF : DBFHandle; iShape, iField : LongWord ) : LongWord;external 'shapelib.dll'; procedure DBFClose(hDBF : DBFHandle);external 'shapelib.dll'; function DBFGetNativeFieldType(hDBF : DBFHandle; iField : LongWord) : Char;external 'shapelib.dll'; // ***************************************************************************** end. ./shapelib-1.2.10/contrib/dbfcat.c0100644000076500001440000001034507644273432016313 0ustar warmerdausers/* * Copyright (c) 1995 Frank Warmerdam * * This code is in the public domain. * * $Log: dbfcat.c,v $ * Revision 1.1 1999/05/26 02:56:31 candrsn * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo * * Revision 1.3 1995/10/21 03:15:01 warmerda * Changed to use binary file access. * * Revision 1.2 1995/08/04 03:16:22 warmerda * Added header. * */ static char rcsid[] = "$Id: dbfcat.c,v 1.1 1999/05/26 02:56:31 candrsn Exp $"; #include "shapefil.h" int main( int argc, char ** argv ) { DBFHandle hDBF; int *panWidth, i, iRecord; char szFormat[32], szField[1024]; char cTitle[32], nTitle[32]; int nWidth, nDecimals; int cnWidth, cnDecimals; DBFHandle cDBF; DBFFieldType hType,cType; int ci, ciRecord; char tfile[160]; int hflds, j, cflds; int verbose = 0; int force = 0; int mismatch = 0; int matches = 0; char fld_m[256]; int shift = 0; char type_names[4][15] = {"integer", "string", "double", "double"}; if( argc < 3 ) { printf( "dbfcat [-v] [-f] from_DBFfile to_DBFfile\n" ); exit( 1 ); } if ( strcmp ("-v", argv[1] ) == 0 ) { shift = 1; verbose = 1; } if ( strcmp ("-f", argv[1 + shift] ) == 0 ) { shift ++; force = 1; } if ( strcmp ("-v", argv[1 + shift] ) == 0 ) { shift ++; verbose = 1; } strcpy (tfile, argv[1 + shift]); strcat (tfile, ".dbf"); hDBF = DBFOpen( tfile, "rb" ); if( hDBF == NULL ) { printf( "DBFOpen(%s.dbf,\"r\") failed for From_DBF.\n", tfile ); exit( 2 ); } strcpy (tfile, argv[2 + shift]); strcat (tfile, ".dbf"); cDBF = DBFOpen( tfile, "rb+" ); if( cDBF == NULL ) { printf( "DBFOpen(%s.dbf,\"rb+\") failed for To_DBF.\n", tfile ); exit( 2 ); } if( DBFGetFieldCount(hDBF) == 0 ) { printf( "There are no fields in this table!\n" ); exit( 3 ); } hflds = DBFGetFieldCount(hDBF); cflds = DBFGetFieldCount(cDBF); matches = 0; for( i = 0; i < hflds; i++ ) { char szTitle[18]; char cname[18]; int j; hType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals ); fld_m[i] = -1; for ( j = 0; j < cflds; j ++ ) { cType = DBFGetFieldInfo( cDBF, j, cname, &cnWidth, &cnDecimals ); if ( strcmp (cname, szTitle) == 0 ) { if ( hType != cType ) { printf ("Incompatible fields %s(%s) != %s(%s),\n", type_names[hType],nTitle,type_names[cType],cTitle); mismatch = 1; } fld_m[i] = j; if ( verbose ) { printf("%s %s(%d,%d) <- %s %s(%d,%d)\n", cname, type_names[cType], cnWidth, cnDecimals, szTitle, type_names[hType], nWidth, nDecimals); } j = cflds; matches = 1; } } } if ( (matches == 0 ) && !force ) { printf ("ERROR: No field names match for tables, cannot proceed\n use -f to force processing using blank records\n"); exit(-1); } if ( mismatch && !force ) { printf ("ERROR: field type mismatch cannot proceed\n use -f to force processing using attempted conversions\n"); exit(-1); } for( iRecord = 0; iRecord < DBFGetRecordCount(hDBF); iRecord++ ) { ciRecord = DBFGetRecordCount( cDBF ); for ( i = 0; i < hflds;i ++ ) { double cf; ci = fld_m[i]; if ( ci != -1 ) { cType = DBFGetFieldInfo( cDBF, ci, cTitle, &cnWidth, &cnDecimals ); hType = DBFGetFieldInfo( hDBF, i, nTitle, &nWidth, &nDecimals ); switch( cType ) { case FTString: DBFWriteStringAttribute(cDBF, ciRecord, ci, (char *) DBFReadStringAttribute( hDBF, iRecord, i ) ); break; case FTInteger: DBFWriteIntegerAttribute(cDBF, ciRecord, ci, (int) DBFReadIntegerAttribute( hDBF, iRecord, i ) ); break; case FTDouble: /* cf = DBFReadDoubleAttribute( hDBF, iRecord, i ); printf ("%s <- %s (%f)\n", cTitle, nTitle, cf); */ DBFWriteDoubleAttribute(cDBF, ciRecord, ci, (double) DBFReadDoubleAttribute( hDBF, iRecord, i ) ); break; } } } /* fields names match */ } if ( verbose ) { printf (" %d records appended \n\n", iRecord); } DBFClose( hDBF ); DBFClose( cDBF ); return( 0 ); } ./shapelib-1.2.10/contrib/dbfinfo.c0100644000076500001440000000533107644273432016476 0ustar warmerdausers/* * Copyright (c) 1999 Carl Anderson * * This code is in the public domain. * * This code is based in part on the earlier work of Frank Warmerdam * * requires shapelib 1.2 * gcc dbfinfo dbfopen.o dbfinfo * * * $Log: dbfinfo.c,v $ * Revision 1.2 1999/05/26 02:56:31 candrsn * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo * * */ #include "shapefil.h" int main( int argc, char ** argv ) { DBFHandle hDBF; int *panWidth, i, iRecord; char szFormat[32], szField[1024]; char ftype[15], cTitle[32], nTitle[32]; int nWidth, nDecimals; int cnWidth, cnDecimals; DBFHandle cDBF; DBFFieldType hType,cType; int ci, ciRecord; /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc != 2 ) { printf( "dbfinfo xbase_file\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ hDBF = DBFOpen( argv[1], "rb" ); if( hDBF == NULL ) { printf( "DBFOpen(%s,\"r\") failed.\n", argv[1] ); exit( 2 ); } printf ("Info for %s\n",argv[1]); /* -------------------------------------------------------------------- */ /* If there is no data in this file let the user know. */ /* -------------------------------------------------------------------- */ i = DBFGetFieldCount(hDBF); printf ("%ld Columns, %ld Records in file\n",i,DBFGetRecordCount(hDBF)); /* -------------------------------------------------------------------- */ /* Compute offsets to use when printing each of the field */ /* values. We make each field as wide as the field title+1, or */ /* the field value + 1. */ /* -------------------------------------------------------------------- */ panWidth = (int *) malloc( DBFGetFieldCount( hDBF ) * sizeof(int) ); for( i = 0; i < DBFGetFieldCount(hDBF); i++ ) { char szTitle[12]; DBFFieldType eType; switch ( DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals )) { case FTString: strcpy (ftype, "string");; break; case FTInteger: strcpy (ftype, "integer"); break; case FTDouble: strcpy (ftype, "float"); break; case FTInvalid: strcpy (ftype, "invalid/unsupported"); break; default: strcpy (ftype, "unknown"); break; } printf ("%15.15s\t%15s (%d,%d)\n",szTitle, ftype, nWidth, nDecimals); } DBFClose( hDBF ); return( 0 ); } ./shapelib-1.2.10/contrib/makefile.vc0100644000076500001440000000131507644273432017030 0ustar warmerdausersPROJ_DIR = D:\warmerda\proj CFLAGS = /I.. /I$(PROJ_DIR)\src /D_LITTLE_ENDIAN -DPROJ4 LINKARGS = shpgeo.obj ..\shpopen.obj ..\dbfopen.obj \ D:\warmerda\proj\src\proj_i.lib default: all all: shpcat.exe shpcentrd.exe shpdxf.exe shpinfo.exe shpproj.exe shpcat.exe: shpcat.obj shpgeo.obj $(CC) $(CFLAGS) shpcat.obj $(LINKARGS) shpcentrd.exe: shpcentrd.obj shpgeo.obj $(CC) $(CFLAGS) shpcentrd.obj $(LINKARGS) shpproj.exe: shpproj.obj shpgeo.obj $(CC) $(CFLAGS) shpproj.obj $(LINKARGS) shpdxf.exe: shpdxf.obj shpgeo.obj $(CC) $(CFLAGS) shpdxf.obj $(LINKARGS) shpinfo.exe: shpinfo.obj shpgeo.obj $(CC) $(CFLAGS) shpinfo.obj $(LINKARGS) clean: del *.obj *.exe ./shapelib-1.2.10/contrib/my_nan.h0100644000076500001440000000275607644273432016365 0ustar warmerdausers/* `NAN' constant for IEEE 754 machines. Copyright (C) 1992, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _GNU_NAN_H #define _GNU_NAN_H 1 /* hacked to define NAN on Solaris 2.7 if it wasn't defined */ /* IEEE Not A Number. */ #ifdef _BIG_ENDIAN # define __nan_bytes { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 } #endif #ifdef _LITTLE_ENDIAN # define __nan_bytes { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f } #endif #ifdef __GNUC__ # define NAN \ (__extension__ ((union { unsigned char __c[8]; \ double __d; }) \ { __nan_bytes }).__d) #else /* Not GCC. */ static const char __nan[8] = __nan_bytes; # define NAN (*(const double *) __nan) #endif #endif /* gnu_nan.h */ ./shapelib-1.2.10/contrib/shpcat.c0100644000076500001440000000665007644273432016356 0ustar warmerdausers/****************************************************************************** * Copyright (c) 1999, Carl Anderson * * This code is based in part on the earlier work of Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * shpcat * * gcc shpcat.c ../shpopen.o -o shpcat * * Utility program to concatenate two shapefiles * Must be used in concert with dbfcat * */ #include "shapefil.h" int dbfcat_main( int argc, char ** argv ); int main( int argc, char ** argv ) { SHPHandle hSHP, cSHP; int nShapeType, i, nEntities, nShpInFile; SHPObject *shape; /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc != 3 ) { printf( "shpcat from_shpfile to_shpfile\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( argv[1], "rb" ); if( hSHP == NULL ) { printf( "Unable to open:%s\n", argv[1] ); exit( 1 ); } SHPGetInfo( hSHP, &nEntities, &nShapeType, NULL, NULL ); fprintf(stderr,"Opened From File %s, with %d shapes\n",argv[1],nEntities); /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ cSHP = SHPOpen( argv[2], "rb+" ); if( cSHP == NULL ) { printf( "Unable to open:%s\n", argv[2] ); exit( 1 ); } SHPGetInfo( cSHP, &nShpInFile, NULL, NULL, NULL ); fprintf(stderr,"Opened to file %s with %d shapes, ready to add %d\n", argv[2],nShpInFile,nEntities); /* -------------------------------------------------------------------- */ /* Skim over the list of shapes, printing all the vertices. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nEntities; i++ ) { shape = SHPReadObject( hSHP, i ); SHPWriteObject( cSHP, -1, shape ); SHPDestroyObject ( shape ); } SHPClose( hSHP ); SHPClose( cSHP ); exit( 0 ); } ./shapelib-1.2.10/contrib/shpcentrd.c0100644000076500001440000001075507644273432017067 0ustar warmerdausers/****************************************************************************** * Copyright (c) 1999, Carl Anderson * * this code is based in part on the earlier work of Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * shpcentrd.c - compute XY centroid for complex shapes * and create a new SHPT_PT file of then * specifically undo compound objects but not complex ones * * * $Log: shpcentrd.c,v $ * Revision 1.2 1999/05/26 02:56:31 candrsn * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo * * * */ /* the centroid is defined as * * Cx = sum (x dArea ) / Total Area * and * Cy = sum (y dArea ) / Total Area */ #include "shapefil.h" #include "shpgeo.h" int main( int argc, char ** argv ) { SHPHandle old_SHP, new_SHP; DBFHandle old_DBF, new_DBF; int nShapeType, nEntities, nVertices, nParts, *panParts, i, iPart; double *padVertices, adBounds[4]; const char *pszPlus; DBFFieldType idfld_type; int idfld, nflds; char kv[257] = ""; char idfldName[120] = ""; char fldName[120] = ""; char shpFileName[120] = ""; char dbfFileName[120] = ""; double apeture[4]; char *DBFRow = NULL; int Cpan[2] = { 0,0 }; int byRing = 1; PT Centrd; SHPObject *psCShape, *cent_pt; if( argc < 3 ) { printf( "shpcentrd shp_file new_shp_file\n" ); exit( 1 ); } old_SHP = SHPOpen (argv[1], "rb" ); old_DBF = DBFOpen (argv[1], "rb"); if( old_SHP == NULL || old_DBF == NULL ) { printf( "Unable to open old files:%s\n", argv[1] ); exit( 1 ); } SHPGetInfo( old_SHP, &nEntities, &nShapeType, NULL, NULL ); new_SHP = SHPCreate ( argv[2], SHPT_POINT ); new_DBF = DBFCloneEmpty (old_DBF, argv[2]); if( new_SHP == NULL || new_DBF == NULL ) { printf( "Unable to create new files:%s\n", argv[2] ); exit( 1 ); } DBFRow = (char *) malloc ( (old_DBF->nRecordLength) + 15 ); #ifdef DEBUG printf ("ShpCentrd using shpgeo \n"); #endif for( i = 0; i < nEntities; i++ ) { int res ; psCShape = SHPReadObject( old_SHP, i ); if ( byRing == 1 ) { int ring; for ( ring = 0; ring < psCShape->nParts; ring ++ ) { SHPObject *psO; psO = SHPClone ( psCShape, ring, ring + 1 ); Centrd = SHPCentrd_2d ( psO ); cent_pt = SHPCreateSimpleObject ( SHPT_POINT, 1, (double*) &(Centrd.x), (double*) &(Centrd.y), NULL ); SHPWriteObject ( new_SHP, -1, cent_pt ); memcpy ( DBFRow, DBFReadTuple ( old_DBF, i ), old_DBF->nRecordLength ); DBFWriteTuple ( new_DBF, new_DBF->nRecords, DBFRow ); SHPDestroyObject ( cent_pt ); SHPDestroyObject ( psO ); } } else { Centrd = SHPCentrd_2d ( psCShape ); cent_pt = SHPCreateSimpleObject ( SHPT_POINT, 1, (double*) &(Centrd.x), (double*) &(Centrd.y), NULL ); SHPWriteObject ( new_SHP, -1, cent_pt ); memcpy ( DBFRow, DBFReadTuple ( old_DBF, i ), old_DBF->nRecordLength ); DBFWriteTuple ( new_DBF, new_DBF->nRecords, DBFRow ); SHPDestroyObject ( cent_pt ); } } SHPClose( old_SHP ); SHPClose( new_SHP ); DBFClose( old_DBF ); DBFClose( new_DBF ); printf ("\n"); } ./shapelib-1.2.10/contrib/shpdata.c0100644000076500001440000001022107644273432016505 0ustar warmerdausers/****************************************************************************** * Copyright (c) 1999, Carl Anderson * * this code is based in part on the earlier work of Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * shpdata.c - utility program for testing elements of the libraries * * * $Log: shpdata.c,v $ * Revision 1.2 1999/05/26 02:56:31 candrsn * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo * * * */ #include "shapefil.h" #include "shpgeo.h" int main( int argc, char ** argv ) { SHPHandle old_SHP, new_SHP; DBFHandle old_DBF, new_DBF; int nShapeType, nEntities, nVertices, nParts, *panParts, i, iPart; double *padVertices, adBounds[4]; const char *pszPlus; DBFFieldType idfld_type; int idfld, nflds; char kv[257] = ""; char idfldName[120] = ""; char fldName[120] = ""; char shpFileName[120] = ""; char dbfFileName[120] = ""; char *DBFRow = NULL; int Cpan[2] = { 0,0 }; int byRing = 1; PT oCentrd, ringCentrd; SHPObject *psCShape, *cent_pt; double oArea = 0.0, oLen = 0.0; if( argc < 2 ) { printf( "shpdata shp_file \n" ); exit( 1 ); } old_SHP = SHPOpen (argv[1], "rb" ); old_DBF = DBFOpen (argv[1], "rb"); if( old_SHP == NULL || old_DBF == NULL ) { printf( "Unable to open old files:%s\n", argv[1] ); exit( 1 ); } SHPGetInfo( old_SHP, &nEntities, &nShapeType, NULL, NULL ); for( i = 0; i < nEntities; i++ ) { int res ; psCShape = SHPReadObject( old_SHP, i ); if ( byRing == 1 ) { int ring, prevStart, ringDir; double ringArea; prevStart = psCShape->nVertices; for ( ring = (psCShape->nParts - 1); ring >= 0; ring-- ) { SHPObject *psO; int j, numVtx, rStart; rStart = psCShape->panPartStart[ring]; if ( ring == (psCShape->nParts -1) ) { numVtx = psCShape->nVertices - rStart; } else { numVtx = psCShape->panPartStart[ring+1] - rStart; } printf ("(shpdata) Ring(%d) (%d for %d) \n", ring, rStart, numVtx); psO = SHPClone ( psCShape, ring, ring + 1 ); ringDir = SHPRingDir_2d ( psO, 0 ); ringArea = RingArea_2d (psO->nVertices,(double*) psO->padfX, (double*) psO->padfY); RingCentroid_2d ( psO->nVertices, (double*) psO->padfX, (double*) psO->padfY, &ringCentrd, &ringArea); printf ("(shpdata) Ring %d, %f Area %d dir \n", ring, ringArea, ringDir ); SHPDestroyObject ( psO ); printf ("(shpdata) End Ring \n"); } /* (ring) [0,nParts */ } /* by ring */ oArea = SHPArea_2d ( psCShape ); oLen = SHPLength_2d ( psCShape ); oCentrd = SHPCentrd_2d ( psCShape ); printf ("(shpdata) Part (%d) %f Area %f length, C (%f,%f)\n", i, oArea, oLen, oCentrd.x, oCentrd.y ); } SHPClose( old_SHP ); DBFClose( old_DBF ); printf ("\n"); } ./shapelib-1.2.10/contrib/shpdxf.c0100644000076500001440000002231307644273432016362 0ustar warmerdausers/****************************************************************************** * Copyright (c) 1999, Carl Anderson * * This code is based in part on the earlier work of Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * shp2dxf.c * * derived from a ESRI Avenue Script * and DXF specification from AutoCad 3 (yes 1984) * * modifications Carl Andrson 11/96 * modifications Carl Andrson 3/97 * * converted to C code 12/98 * * requires shapelib 1.2 * gcc shpdxf.c shpopen.o dbfopen.o -o shpdxf * */ #include "shapefil.h" #define FLOAT_PREC "%16.5f\r\n" void dxf_hdr (x1,y1,x2,y2,df) double x1,y1,x2,y2; FILE *df; { /* Create HEADER section */ fprintf( df, " 0\r\n"); fprintf( df, "SECTION\r\n"); fprintf( df, " 2\r\n" ); fprintf( df, "HEADER\r\n" ); fprintf( df, " 9\r\n" ); fprintf( df, "$EXTMAX\r\n" ); fprintf( df, " 10\r\n" ); fprintf( df, FLOAT_PREC, x2 ); fprintf( df, " 20\r\n" ); fprintf( df, FLOAT_PREC, y2 ); fprintf( df, " 9\r\n" ); fprintf( df, "$EXTMIN\r\n" ); fprintf( df, " 10\r\n" ); fprintf( df, FLOAT_PREC, x1 ); fprintf( df, " 20\r\n" ); fprintf( df, FLOAT_PREC, y1 ); fprintf( df, " 9\r\n" ); fprintf( df, "$LUPREC\r\n" ); fprintf( df, " 70\r\n" ); fprintf( df, " 14\r\n" ); fprintf( df, " 0\r\n" ); fprintf( df, "ENDSEC\r\n" ); /* ' Create TABLES section */ fprintf( df, " 0\r\n" ); fprintf( df, "SECTION\r\n" ); fprintf( df, " 2\r\n" ); fprintf( df, "TABLES\r\n" ); /* ' Table 1 - set up line type */ fprintf( df, " 0\r\n" ); fprintf( df, "TABLE\r\n" ); fprintf( df, " 2\r\n" ); fprintf( df, "LTYPE\r\n" ); fprintf( df, " 70\r\n" ); fprintf( df, "2\r\n" ); /* ' Entry 1 of Table 1 */ fprintf( df, " 0\r\n" ); fprintf( df, "LTYPE\r\n" ); fprintf( df, " 2\r\n" ); fprintf( df, "CONTINUOUS\r\n" ); fprintf( df, " 70\r\n" ); fprintf( df, "64\r\n" ); fprintf( df, " 3\r\n" ); fprintf( df, "Solid line\r\n" ); fprintf( df, " 72\r\n" ); fprintf( df, "65\r\n" ); fprintf( df, " 73\r\n" ); fprintf( df, "0\r\n" ); fprintf( df, " 40\r\n" ); fprintf( df, "0.0\r\n" ); fprintf( df, " 0\r\n" ); fprintf( df, "ENDTAB\r\n" ); /* End of TABLES section */ fprintf( df, " 0\r\n" ); fprintf( df, "ENDSEC\r\n" ); /* Create BLOCKS section */ fprintf( df, " 0\r\n" ); fprintf( df, "SECTION\r\n" ); fprintf( df, " 2\r\n" ); fprintf( df, "BLOCKS\r\n" ); fprintf( df, " 0\r\n" ); fprintf( df, "ENDSEC\r\n" ); fprintf( df, " 0\r\n" ); fprintf( df, "SECTION\r\n" ); fprintf( df, " 2\r\n" ); fprintf( df, "ENTITIES\r\n" ); } void dxf_ent_preamble (dxf_type, id, df) int dxf_type; char *id; FILE *df; { fprintf( df, " 0\r\n" ); switch (dxf_type) { case SHPT_POLYGON: case SHPT_ARC: fprintf (df, "POLYLINE\r\n"); break; default: fprintf(df, "POINT\r\n"); } fprintf( df, " 8\r\n", df); fprintf( df, "%s\r\n", id ); switch ( dxf_type ) { case SHPT_ARC: fprintf( df, " 6\r\n" ); fprintf( df, "CONTINUOUS\r\n" ); fprintf( df, " 66\r\n" ); fprintf( df, "1\r\n" ); break; case SHPT_POLYGON: fprintf( df, " 6\r\n" ); fprintf( df, "CONTINUOUS\r\n" ); fprintf( df, " 66\r\n" ); fprintf( df, "1\r\n" ); fprintf( df, " 70\r\n"); fprintf (df, "1\r\n"); default: break; } } void dxf_ent (id, x, y, z, dxf_type, df) char *id; double x,y,z; int dxf_type; FILE *df; { if ((dxf_type == SHPT_ARC) || ( dxf_type == SHPT_POLYGON)) { fprintf( df, " 0\r\n"); fprintf( df, "VERTEX\r\n"); fprintf( df, " 8\r\n"); fprintf( df, "%s\r\n", id); } fprintf( df, " 10\r\n" ); fprintf( df, FLOAT_PREC, x ); fprintf( df, " 20\r\n" ); fprintf( df, FLOAT_PREC, y ); fprintf( df, " 30\r\n" ); if ( z != 0 ) fprintf( df, FLOAT_PREC, z ); else fprintf( df, "0.0\r\n" ); } void dxf_ent_postamble (dxf_type, df) int dxf_type; FILE *df; { if ((dxf_type == SHPT_ARC) || ( dxf_type == SHPT_POLYGON)) fprintf( df, " 0\r\nSEQEND\r\n 8\r\n0\r\n", df); } int main (int argc, char **argv) { char shpFileName[80] = "", dbfFileName[80] = ""; char dxfFileName[80] = ""; char idfldName[15]; char zfldName[6] = "ELEV"; char fldName[15]; char id[255]; double elev; int parts, *panParts, nParts, nVertices; FILE *dxf; SHPHandle shp; DBFHandle dbf; DBFFieldType idfld_type; double adfBoundsMin[4], adfBoundsMax[4]; int vrtx, shp_type, shp_numrec, zfld, idfld, nflds, recNum, part; unsigned int MaxElem = -1; if ( argc < 2 ) { printf ("usage: shpdxf shapefile {idfield}\r\n"); exit (-1); } strcpy (shpFileName,argv[1]); strncpy (dbfFileName, shpFileName, strlen(shpFileName)-3); strcat (dbfFileName,"dbf"); strncpy (dxfFileName, shpFileName,strlen(shpFileName)-3); strcat( dxfFileName, "dxf"); shp = SHPOpen (shpFileName, "rb"); dbf = DBFOpen (dbfFileName, "rb"); dxf = fopen( dxfFileName, "w"); printf("Starting conversion %s(%s) -> %s\r\n", shpFileName,dbfFileName,dxfFileName); SHPGetInfo (shp, &shp_numrec, &shp_type, adfBoundsMin, adfBoundsMax ); printf ("file has %d objects\r\n", shp_numrec); dxf_hdr(adfBoundsMin[0], adfBoundsMin[1], adfBoundsMax[0], adfBoundsMax[1], dxf); /* Before proceeding, allow the user to specify the ID field to use or default to the record number.... */ if ( argc > 3 ) MaxElem = atoi(argv[3]); nflds = DBFGetFieldCount(dbf); if ( argc > 2 ) { strcpy (idfldName, argv[2]); for ( idfld=0; idfld < nflds; idfld++ ) { idfld_type = DBFGetFieldInfo( dbf, idfld, fldName, NULL, NULL); if (!strcmp (idfldName, fldName )) break; } if ( idfld >= nflds ) { printf ("Id field %s not found, using default\r\n",idfldName); idfld = -1; } else printf ("proceeding with field %s for LayerNames\r\n",fldName); } else idfld = -1; for ( zfld=0; zfld < nflds; zfld++ ) { DBFGetFieldInfo( dbf, zfld, fldName, NULL, NULL); if (!strcmp (zfldName, fldName )) break; } if ( zfld >= nflds ) zfld = -1; // printf ("proceeding with id = %d, elevation = %d\r\n",idfld, zfld); /* Proceed to process data..... */ for ( recNum = 0; (recNum < shp_numrec) && (recNum < MaxElem); recNum++) { SHPObject *shape; if ( idfld >= 0 ) switch (idfld_type) { case FTString: sprintf (id, "lvl_%s",DBFReadStringAttribute ( dbf, recNum, idfld )); break; default: sprintf(id, "%-20.0lf", DBFReadDoubleAttribute (dbf, recNum, idfld)); } else sprintf (id,"lvl_%-20d",(recNum +1 )); if ( zfld >= 0 ) elev = 0; else elev = DBFReadDoubleAttribute ( dbf, recNum, zfld ); #ifdef DEBUG printf("\r\nworking on obj %d", recNum); #endif shape = SHPReadObject( shp, recNum ); nVertices = shape->nVertices; nParts = shape->nParts; panParts = shape->panPartStart; part = 0; for (vrtx=0; vrtx < nVertices; vrtx ++ ) { #ifdef DEBUG printf("\rworking on part %d, vertex %d", part,vrtx); #endif if ( panParts[part] == vrtx ) { #ifdef DEBUG printf ("object preamble\r\n"); #endif dxf_ent_preamble (shp_type, id, dxf); } dxf_ent (id, shape->padfX[vrtx], shape->padfY[vrtx], elev, shp_type, dxf); if ((panParts[part] == (vrtx + 1))|| (vrtx == (nVertices -1)) ) { dxf_ent_postamble (shp_type, dxf); part ++; } } SHPDestroyObject( shape ); } /* close out DXF file */ fprintf( dxf, "0\r\n" ); fprintf( dxf, "ENDSEC\r\n" ); fprintf( dxf, "0\r\n" ); fprintf( dxf, "EOF\r\n" ); SHPClose (shp); DBFClose (dbf); fclose (dxf); } ./shapelib-1.2.10/contrib/shpfix.c0100644000076500001440000000705007644273432016370 0ustar warmerdausers/****************************************************************************** * Copyright (c) 1999, Carl Anderson * * This code is based in part on the earlier work of Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * shpfix * * * gcc -c shpfix.c shpopen.c -o shpfix * * Utility program to fix nulls and inconsistencies in Shapefiles * as happens from time to time * * Simply load and rewrite each record, parameter fixrex allow user to null * a particularly nasty record if needed * */ #include "shapefil.h" int main( int argc, char ** argv ) { SHPHandle hSHP, cSHP; int nShapeType, cShapeType, nEntities, i; double adBounds[4]; SHPObject *shape; int fix_rec; /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc <= 3 ) { printf( "shpfix shpfile new_file \n" ); exit( 1 ); } fix_rec = atoi (argv[3]); fix_rec --; /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( argv[1], "rb+" ); if( hSHP == NULL ) { printf( "Unable to open:%s\n", argv[1] ); exit( 1 ); } SHPGetInfo( hSHP, &nEntities, &nShapeType, NULL, NULL ); /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ cSHP = SHPCreate( argv[2], nShapeType ); if( cSHP == NULL ) { printf( "Unable to open:%s\n", argv[2] ); exit( 1 ); } SHPGetInfo( cSHP, NULL, &cShapeType, &(adBounds[0]), &(adBounds[2]) ); /* -------------------------------------------------------------------- */ /* Skim over the list of shapes, printing all the vertices. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nEntities; i++ ) { shape = SHPReadObject( hSHP, i ); if ( i == fix_rec ) { shape->nParts = 0; shape->nVertices = 0; } SHPWriteObject( cSHP, -1, shape ); SHPDestroyObject ( shape ); } SHPClose ( hSHP ); SHPClose ( cSHP ); } ./shapelib-1.2.10/contrib/shpgeo.c0100644000076500001440000014174007644273432016361 0ustar warmerdausers/****************************************************************************** * Copyright (c) 1999, Carl Anderson * * This code is based in part on the earlier work of Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * requires shapelib 1.2 * gcc shpproj shpopen.o dbfopen.o -lm -lproj -o shpproj * * this may require linking with the PROJ4 projection library available from * * http://www.remotesensing.org/proj * * use -DPROJ4 to compile in Projection support * * $Log: shpgeo.c,v $ * Revision 1.8 2002/01/15 14:36:56 warmerda * upgrade to use proj_api.h * * Revision 1.7 2002/01/11 15:22:04 warmerda * fix many warnings. Lots of this code is cruft. * * Revision 1.6 2001/08/30 13:42:31 warmerda * avoid use of auto initialization of PT for VC++ * * Revision 1.5 2000/04/26 13:24:06 warmerda * made projUV handling safer * * Revision 1.4 2000/04/26 13:17:15 warmerda * check if projUV or UV * * Revision 1.3 2000/03/17 14:15:16 warmerda * Don't try to use system nan.h ... doesn't always exist. * * Revision 1.2 1999/05/26 02:56:31 candrsn * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo * */ #include "shapefil.h" #ifndef NAN #include "my_nan.h" #endif #include "shpgeo.h" /* I'm using some shorthand throughout this file * R+ is a Clockwise Ring and is the positive portion of an object * R- is a CounterClockwise Ring and is a hole in a R+ * A complex object is one having at least one R- * A compound object is one having more than one R+ * A simple object has one and only one element (R+ or R-) * * The closed ring constraint is for polygons and assumed here * Arcs or LineStrings I am calling Rings (generically open or closed) * Point types are vertices or lists of vertices but not Rings * * SHPT_POLYGON, SHPT_POLYGONZ, SHPT_POLYGONM and SHPT_MULTIPATCH * can have SHPObjects that are compound as well as complex * * SHP_POINT and its Z and M derivatives are strictly simple * MULTI_POINT, SHPT_ARC and their derivatives may be simple or compound * */ /* ************************************************************************** * asFileName * * utility function, toss part of filename after last dot * * **************************************************************************/ char * asFileName ( const char *fil, char *ext ) { char pszBasename[120]; static char pszFullname[120]; int i; /* -------------------------------------------------------------------- */ /* Compute the base (layer) name. If there is any extension */ /* on the passed in filename we will strip it off. */ /* -------------------------------------------------------------------- */ // pszFullname = (char*) malloc(( strlen(fil)+5 )); // pszBasename = (char *) malloc(strlen(fil)+5); strcpy( pszBasename, fil ); for( i = strlen(pszBasename)-1; i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' && pszBasename[i] != '\\'; i-- ) {} if( pszBasename[i] == '.' ) pszBasename[i] = '\0'; /* -------------------------------------------------------------------- */ /* Note that files pulled from */ /* a PC to Unix with upper case filenames won't work! */ /* -------------------------------------------------------------------- */ // pszFullname = (char *) malloc(strlen(pszBasename) + 5); sprintf( pszFullname, "%s.%s", pszBasename, ext ); return ( pszFullname ); } /************************************************************************/ /* SfRealloc() */ /* */ /* A realloc cover function that will access a NULL pointer as */ /* a valid input. */ /************************************************************************/ /* copied directly from shpopen.c -- maybe expose this in shapefil.h */ static void * SfRealloc( void * pMem, int nNewSize ) { if( pMem == NULL ) return( (void *) malloc(nNewSize) ); else return( (void *) realloc(pMem,nNewSize) ); } /* ************************************************************************** * SHPPRoject * * Project points using projection handles, for use with PROJ4.3 * * act as a wrapper to protect against library changes in PROJ * * **************************************************************************/ int SHPProject ( SHPObject *psCShape, projPJ inproj, projPJ outproj ) { #ifdef PROJ4 int j; projUV p; /* struct { double u, double v } */ /* for each vertex project it and stuff the projeted point back into */ /* same SHPObject. Proj assumes data is in radians so convert it. */ /* Proj will convert Geographic -> and -> Geographic */ /* so -> requires bouncing though geographic */ for ( j=0; j < psCShape->nVertices; j++ ) { p.u = psCShape->padfX[j]; p.v = psCShape->padfY[j]; if ( inproj ) p = pj_inv ( p, inproj ); else { p.u *= DEG_TO_RAD; p.v *= DEG_TO_RAD; } if ( outproj ) p = pj_fwd ( p, outproj ); else { p.u *= RAD_TO_DEG; p.v *= RAD_TO_DEG; } psCShape->padfX[j] = p.u; psCShape->padfY[j] = p.v; } /* Recompute new Extents of projected Object */ SHPComputeExtents ( psCShape ); #endif return ( 1 ); } /* ************************************************************************** * SHPSetProjection * * establish a projection handle for use with PROJ4.3 * * act as a wrapper to protect against library changes in PROJ * * **************************************************************************/ projPJ SHPSetProjection ( int param_cnt, char **params ) { #ifdef PROJ4 projPJ *p = NULL; if ( param_cnt > 0 && params[0] ) { p = pj_init ( param_cnt, params ); } return ( p ); #else return ( NULL ); #endif } /* ************************************************************************** * SHPFreeProjection * * release a projection handle for use with PROJ4.3 * * act as a wrapper to protect against library changes in PROJ * * **************************************************************************/ int SHPFreeProjection ( projPJ p) { #ifdef PROJ4 if ( p ) pj_free ( p ); #endif return ( 1 ); } /* ************************************************************************** * SHPOGisType * * Convert Both ways from and to OGIS Geometry Types * * **************************************************************************/ int SHPOGisType ( int GeomType, int toOGis) { if ( toOGis == 0 ) /* connect OGis -> SHP types */ switch (GeomType) { case (OGIST_POINT): return ( SHPT_POINT ); break; case (OGIST_LINESTRING): return ( SHPT_ARC ); break; case (OGIST_POLYGON): return ( SHPT_POLYGON ); break; case (OGIST_MULTIPOINT): return ( SHPT_MULTIPOINT ); break; case (OGIST_MULTILINE): return ( SHPT_ARC ); break; case (OGIST_MULTIPOLYGON): return ( SHPT_POLYGON ); break; } else /* ok so its SHP->OGis types */ switch (GeomType) { case (SHPT_POINT): return ( OGIST_POINT ); break; case (SHPT_POINTM): return ( OGIST_POINT ); break; case (SHPT_POINTZ): return ( OGIST_POINT ); break; case (SHPT_ARC): return ( OGIST_LINESTRING );break; case (SHPT_ARCZ): return ( OGIST_LINESTRING );break; case (SHPT_ARCM): return ( OGIST_LINESTRING );break; case (SHPT_POLYGON): return ( OGIST_MULTIPOLYGON );break; case (SHPT_POLYGONZ): return ( OGIST_MULTIPOLYGON );break; case (SHPT_POLYGONM): return ( OGIST_MULTIPOLYGON );break; case (SHPT_MULTIPOINT): return ( OGIST_MULTIPOINT );break; case (SHPT_MULTIPOINTZ): return ( OGIST_MULTIPOINT );break; case (SHPT_MULTIPOINTM): return ( OGIST_MULTIPOINT );break; case (SHPT_MULTIPATCH): return ( OGIST_GEOMCOLL ); break; } return 0; } /* ************************************************************************** * SHPReadSHPStream * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ int SHPReadSHPStream ( SHPObject *psCShape, char *stream_obj) { int obj_storage; int my_order, need_swap =0, GeoType ; int use_Z = 0; int use_M = 0; need_swap = stream_obj[0]; my_order = 1; my_order = ((char*) (&my_order))[0]; need_swap = need_swap & my_order; if ( need_swap ) swapW (stream_obj, (void*) &GeoType, sizeof (GeoType) ); else memcpy (stream_obj, &GeoType, sizeof (GeoType) ); if ( need_swap ) { } else { memcpy (stream_obj, &(psCShape->nSHPType), sizeof (psCShape->nSHPType) ); memcpy (stream_obj, &(psCShape->nShapeId), sizeof (psCShape->nShapeId) ); memcpy (stream_obj, &(psCShape->nVertices), sizeof (psCShape->nVertices) ); memcpy (stream_obj, &(psCShape->nParts), sizeof (psCShape->nParts) ); memcpy (stream_obj, &(psCShape->dfXMin), sizeof (psCShape->dfXMin) ); memcpy (stream_obj, &(psCShape->dfYMin), sizeof (psCShape->dfYMin) ); memcpy (stream_obj, &(psCShape->dfXMax), sizeof (psCShape->dfXMax) ); memcpy (stream_obj, &(psCShape->dfYMax), sizeof (psCShape->dfYMax) ); if ( use_Z ) { memcpy (stream_obj, &(psCShape->dfZMin), sizeof (psCShape->dfZMin) ); memcpy (stream_obj, &(psCShape->dfZMax), sizeof (psCShape->dfZMax) ); } memcpy (stream_obj, psCShape->panPartStart, psCShape->nParts * sizeof (int) ); memcpy (stream_obj, psCShape->panPartType, psCShape->nParts * sizeof (int) ); /* get X and Y coordinate arrarys */ memcpy (stream_obj, psCShape->padfX, psCShape->nVertices * 2 * sizeof (double) ); /* get Z coordinate array if used */ if ( use_Z ) memcpy (stream_obj, psCShape->padfZ, psCShape->nVertices * 2 * sizeof (double) ); /* get Measure coordinate array if used */ if ( use_M ) memcpy (stream_obj, psCShape->padfM, psCShape->nVertices * 2 * sizeof (double) ); } /* end put data without swap */ return (0); } /* ************************************************************************** * SHPWriteSHPStream * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ int SHPWriteSHPStream ( WKBStreamObj *stream_obj, SHPObject *psCShape ) { int obj_storage = 0; int need_swap = 0, my_order, GeoType; int use_Z = 0; int use_M = 0; need_swap = 1; need_swap = ((char*) (&need_swap))[0]; realloc (stream_obj, obj_storage ); if ( need_swap ) { } else { memcpy (stream_obj, psCShape, 4 * sizeof (int) ); memcpy (stream_obj, psCShape, 4 * sizeof (double) ); if ( use_Z ) memcpy (stream_obj, psCShape, 2 * sizeof (double) ); if ( use_M ) memcpy (stream_obj, psCShape, 2 * sizeof (double) ); memcpy (stream_obj, psCShape, psCShape->nParts * 2 * sizeof (int) ); memcpy (stream_obj, psCShape, psCShape->nVertices * 2 * sizeof (double) ); if ( use_Z ) memcpy (stream_obj, psCShape, psCShape->nVertices * 2 * sizeof (double) ); if ( use_M ) memcpy (stream_obj, psCShape, psCShape->nVertices * 2 * sizeof (double) ); } return (0); } /* ************************************************************************** * WKBStreamWrite * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ int WKBStreamWrite ( WKBStreamObj* wso, void* this, int tcount, int tsize ) { if ( wso->NeedSwap ) SwapG ( &(wso->wStream[wso->StreamPos]), this, tcount, tsize ); else memcpy ( &(wso->wStream[wso->StreamPos]), this, tsize * tcount ); wso->StreamPos += tsize; return 0; } /* ************************************************************************** * WKBStreamRead * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ int WKBStreamRead ( WKBStreamObj* wso, void* this, int tcount, int tsize ) { if ( wso->NeedSwap ) SwapG ( this, &(wso->wStream[wso->StreamPos]), tcount, tsize ); else memcpy ( this, &(wso->wStream[wso->StreamPos]), tsize * tcount ); wso->StreamPos += tsize; return 0; } /* ************************************************************************** * SHPReadOGisWKB * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ SHPObject* SHPReadOGisWKB ( WKBStreamObj *stream_obj) { SHPObject *psCShape; char WKB_order; int need_swap = 0, my_order, GeoType = 0; int use_Z = 0, use_M = 0; int nSHPType, thisDim; WKBStreamRead ( stream_obj, &WKB_order, 1, sizeof(char)); my_order = 1; my_order = ((char*) (&my_order))[0]; stream_obj->NeedSwap = !(WKB_order & my_order); /* convert OGis Types to SHP types */ nSHPType = SHPOGisType ( GeoType, 0 ); WKBStreamRead ( stream_obj, &GeoType, 1, sizeof(int)); thisDim = SHPDimension ( nSHPType ); if ( thisDim && SHPD_AREA ) { psCShape = SHPReadOGisPolygon ( stream_obj ); } else { if ( thisDim && SHPD_LINE ) { psCShape = SHPReadOGisLine ( stream_obj ); } else { if ( thisDim && SHPD_POINT ) { psCShape = SHPReadOGisPoint ( stream_obj ); } } } return (0); } /* ************************************************************************** * SHPWriteOGisWKB * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ int SHPWriteOGisWKB ( WKBStreamObj* stream_obj, SHPObject *psCShape ) { int need_swap = 0, my_order, GeoType, thisDim; int use_Z = 0, use_M = 0; char LSB = 1; /* indicate that this WKB is in LSB Order */ /* OGis WKB can handle either byte order, but if I get to choose I'd /* rather have it predicatable system-to-system */ if ( stream_obj ) { if ( stream_obj->wStream ) free ( stream_obj->wStream ); } else { stream_obj = calloc ( 3, sizeof (int ) ); } /* object size needs to be 9 bytes for the wrapper, and for each polygon */ /* another 9 bytes all plus twice the total number of vertices */ /* times the sizeof (double) and just pad with 10 more chars for fun */ stream_obj->wStream = calloc (1, (9 * (psCShape->nParts + 1)) + ( sizeof(double) * 2 * psCShape->nVertices ) + 10 ); #ifdef DEBUG2 printf (" I just allocated %d bytes to wkbObj \n", sizeof (int) + sizeof (int) + sizeof(int) + ( sizeof(int) * psCShape->nParts + 1 ) + ( sizeof(double) * 2 * psCShape->nVertices ) + 10 ); #endif my_order = 1; my_order = ((char*) (&my_order))[0]; /* Need to swap if this system is not LSB (Intel Order) */ stream_obj->NeedSwap = ( my_order != LSB ); stream_obj->StreamPos = 0; #ifdef DEBUG2 printf ("this system is (%d) LSB recorded as needSwap %d\n",my_order, stream_obj->NeedSwap); #endif WKBStreamWrite ( stream_obj, & LSB, 1, sizeof(char) ); #ifdef DEBUG2 printf ("this system in (%d) LSB \n"); #endif /* convert SHP Types to OGis types */ GeoType = SHPOGisType ( psCShape->nSHPType, 1 ); WKBStreamWrite ( stream_obj, &GeoType, 1, sizeof(int) ); thisDim = SHPDimension ( psCShape->nSHPType ); if ( thisDim && SHPD_AREA ) { SHPWriteOGisPolygon ( stream_obj, psCShape ); } else { if ( thisDim && SHPD_LINE ) { SHPWriteOGisLine ( stream_obj, psCShape ); } else { if ( thisDim && SHPD_POINT ) { SHPWriteOGisPoint ( stream_obj, psCShape ); } } } #ifdef DEBUG2 printf("(SHPWriteOGisWKB) outta here when stream pos is %d \n", stream_obj->StreamPos); #endif return (0); } /* ************************************************************************** * SHPWriteOGisPolygon * * for this pass code to more generic OGis MultiPolygon Type * later add support for OGis Polygon Type * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ int SHPWriteOGisPolygon ( WKBStreamObj *stream_obj, SHPObject *psCShape ) { SHPObject **ppsC; SHPObject *psC; int rPart, ring, rVertices, cpart, cParts, nextring, i, j; char Flag = 1; int GeoType = OGIST_POLYGON; /* cant have more than nParts complex objects in this object */ ppsC = calloc ( psCShape->nParts, sizeof(int) ); nextring = 0; cParts=0; while ( nextring >= 0 ) { (SHPObject*) ppsC[cParts] = SHPUnCompound ( psCShape, &nextring ); cParts++; } #ifdef DEBUG2 printf ("(SHPWriteOGisPolygon) Uncompounded into %d parts \n", cParts); #endif WKBStreamWrite ( stream_obj, &cParts, 1, sizeof(int) ); for ( cpart = 0; cpart < cParts; cpart++) { WKBStreamWrite ( stream_obj, & Flag, 1, sizeof(char) ); WKBStreamWrite ( stream_obj, & GeoType, 1, sizeof(int) ); psC = (SHPObject*) ppsC[cpart]; WKBStreamWrite ( stream_obj, &(psC->nParts), 1, sizeof(int) ); for ( ring = 0; (ring < (psC->nParts)) && (psC->nParts > 0); ring ++) { if ( ring < (psC->nParts-2) ) { rVertices = psC->panPartStart[ring+1] - psC->panPartStart[ring]; } else { rVertices = psC->nVertices - psC->panPartStart[ring]; } #ifdef DEBUG2 printf ("(SHPWriteOGisPolygon) scanning part %d, ring %d %d vtxs \n", cpart, ring, rVertices); #endif rPart = psC->panPartStart[ring]; WKBStreamWrite ( stream_obj, &rVertices, 1, sizeof(int) ); for ( j=rPart; j < (rPart + rVertices); j++ ) { WKBStreamWrite ( stream_obj, &(psC->padfX[j]), 1, sizeof(double) ); WKBStreamWrite ( stream_obj, &(psC->padfY[j]), 1, sizeof(double) ); } /* for each vertex */ } /* for each ring */ } /* for each complex part */ #ifdef DEBUG2 printf ("(SHPWriteOGisPolygon) outta here \n"); #endif return (1); } /* ************************************************************************** * SHPWriteOGisLine * * for this pass code to more generic OGis MultiXXXXXXX Type * later add support for OGis LineString Type * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ int SHPWriteOGisLine ( WKBStreamObj *stream_obj, SHPObject *psCShape ) { return ( SHPWriteOGisPolygon( stream_obj, psCShape )); } /* ************************************************************************** * SHPWriteOGisPoint * * for this pass code to more generic OGis MultiPoint Type * later add support for OGis Point Type * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ int SHPWriteOGisPoint ( WKBStreamObj *stream_obj, SHPObject *psCShape ) { int j; WKBStreamWrite ( stream_obj, &(psCShape->nVertices), 1, sizeof(int) ); for ( j=0; j < psCShape->nVertices; j++ ) { WKBStreamWrite ( stream_obj, &(psCShape->padfX[j]), 1, sizeof(double) ); WKBStreamWrite ( stream_obj, &(psCShape->padfY[j]), 1, sizeof(double) ); } /* for each vertex */ return (1); } /* ************************************************************************** * SHPReadOGisPolygon * * for this pass code to more generic OGis MultiPolygon Type * later add support for OGis Polygon Type * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ SHPObject* SHPReadOGisPolygon ( WKBStreamObj *stream_obj ) { SHPObject **ppsC; SHPObject *psC; int rPart, ring, rVertices, cpart, cParts, nextring, i, j; int totParts, totVertices, pRings, nParts; psC = SHPCreateObject ( SHPT_POLYGON, -1, 0, NULL, NULL, 0, NULL, NULL, NULL, NULL ); /* initialize a blank SHPObject */ WKBStreamRead ( stream_obj, &cParts, 1, sizeof(char) ); totParts = cParts; totVertices = 0; SfRealloc ( psC->panPartStart, cParts * sizeof(int)); SfRealloc ( psC->panPartType, cParts * sizeof(int)); for ( cpart = 0; cpart < cParts; cpart++) { WKBStreamRead ( stream_obj, &nParts, 1, sizeof(int) ); pRings = nParts; /* pRings is the number of rings prior to the Ring loop below */ if ( nParts > 1 ) { totParts += nParts - 1; SfRealloc ( psC->panPartStart, totParts * sizeof(int)); SfRealloc ( psC->panPartType, totParts * sizeof(int)); } rPart = 0; for ( ring = 0; ring < (nParts - 1); ring ++) { WKBStreamRead ( stream_obj, &rVertices, 1, sizeof(int) ); totVertices += rVertices; psC->panPartStart[ring+pRings] = rPart; if ( ring == 0 ) { psC->panPartType[ring + pRings] = SHPP_OUTERRING; } else { psC->panPartType[ring + pRings] = SHPP_INNERRING; } SfRealloc ( psC->padfX, totVertices * sizeof (double)); SfRealloc ( psC->padfY, totVertices * sizeof (double)); for ( j=rPart; j < (rPart + rVertices); j++ ) { WKBStreamRead ( stream_obj, &(psC->padfX[j]), 1, sizeof(double) ); WKBStreamRead ( stream_obj, &(psC->padfY[j]), 1, sizeof(double) ); } /* for each vertex */ rPart += rVertices; } /* for each ring */ } /* for each complex part */ return ( psC ); } /* ************************************************************************** * SHPReadOGisLine * * for this pass code to more generic OGis MultiLineString Type * later add support for OGis LineString Type * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ SHPObject* SHPReadOGisLine ( WKBStreamObj *stream_obj ) { SHPObject **ppsC; SHPObject *psC; int rPart, ring, rVertices, cpart, cParts, nextring, i, j; int totParts, totVertices, pRings, nParts; psC = SHPCreateObject ( SHPT_ARC, -1, 0, NULL, NULL, 0, NULL, NULL, NULL, NULL ); /* initialize a blank SHPObject */ WKBStreamRead ( stream_obj, &cParts, 1, sizeof(int) ); totParts = cParts; totVertices = 0; SfRealloc ( psC->panPartStart, cParts * sizeof(int)); SfRealloc ( psC->panPartType, cParts * sizeof(int)); for ( cpart = 0; cpart < cParts; cpart++) { WKBStreamRead ( stream_obj, &nParts, 1, sizeof(int) ); pRings = totParts; /* pRings is the number of rings prior to the Ring loop below */ if ( nParts > 1 ) { totParts += nParts - 1; SfRealloc ( psC->panPartStart, totParts * sizeof(int)); SfRealloc ( psC->panPartType, totParts * sizeof(int)); } rPart = 0; for ( ring = 0; ring < (nParts - 1); ring ++) { WKBStreamRead ( stream_obj, &rVertices, 1, sizeof(int) ); totVertices += rVertices; psC->panPartStart[ring+pRings] = rPart; if ( ring == 0 ) { psC->panPartType[ring + pRings] = SHPP_OUTERRING; } else { psC->panPartType[ring + pRings] = SHPP_INNERRING; } SfRealloc ( psC->padfX, totVertices * sizeof (double)); SfRealloc ( psC->padfY, totVertices * sizeof (double)); for ( j=rPart; j < (rPart + rVertices); j++ ) { WKBStreamRead ( stream_obj, &(psC->padfX[j]), 1, sizeof(double) ); WKBStreamRead ( stream_obj, &(psC->padfY[j]), 1, sizeof(double) ); } /* for each vertex */ rPart += rVertices; } /* for each ring */ } /* for each complex part */ return ( psC ); } /* ************************************************************************** * SHPReadOGisPoint * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ SHPObject* SHPReadOGisPoint ( WKBStreamObj *stream_obj ) { SHPObject *psC; int nVertices, j; psC = SHPCreateObject ( SHPT_MULTIPOINT, -1, 0, NULL, NULL, 0, NULL, NULL, NULL, NULL ); /* initialize a blank SHPObject */ WKBStreamRead ( stream_obj, &nVertices, 1, sizeof(int) ); SfRealloc ( psC->padfX, nVertices * sizeof (double)); SfRealloc ( psC->padfY, nVertices * sizeof (double)); for ( j=0; j < nVertices; j++ ) { WKBStreamRead ( stream_obj, &(psC->padfX[j]), 1, sizeof(double) ); WKBStreamRead ( stream_obj, &(psC->padfY[j]), 1, sizeof(double) ); } /* for each vertex */ return ( psC ); } /* ************************************************************************** * RingReadOGisWKB * * this accepts OGisLineStrings which are basic building blocks * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ int RingReadOgisWKB ( SHPObject *psCShape, char *stream_obj) { return 0; } /* ************************************************************************** * RingWriteOGisWKB * * this emits OGisLineStrings which are basic building blocks * * Encapsulate entire SHPObject for use with Postgresql * * **************************************************************************/ int RingWriteOgisWKB ( SHPObject *psCShape, char *stream_obj) { return 0; } /* ************************************************************************** * SHPDimension * * Return the Dimensionality of the SHPObject * a handy utility function * * **************************************************************************/ int SHPDimension ( int SHPType ) { int dimension; dimension = 0; switch ( SHPType ) { case SHPT_POINT : dimension = SHPD_POINT ; case SHPT_ARC : dimension = SHPD_LINE; case SHPT_POLYGON : dimension = SHPD_AREA; case SHPT_MULTIPOINT : dimension = SHPD_POINT; case SHPT_POINTZ : dimension = SHPD_POINT | SHPD_Z; case SHPT_ARCZ : dimension = SHPD_LINE | SHPD_Z; case SHPT_POLYGONZ : dimension = SHPD_AREA | SHPD_Z; case SHPT_MULTIPOINTZ : dimension = SHPD_POINT | SHPD_Z; case SHPT_POINTM : dimension = SHPD_POINT | SHPD_MEASURE; case SHPT_ARCM : dimension = SHPD_LINE | SHPD_MEASURE; case SHPT_POLYGONM : dimension = SHPD_AREA | SHPD_MEASURE; case SHPT_MULTIPOINTM : dimension = SHPD_POINT | SHPD_MEASURE; case SHPT_MULTIPATCH : dimension = SHPD_AREA; } return ( dimension ); } /* ************************************************************************** * SHPPointinPoly_2d * * Return a Point inside an R+ of a potentially * complex/compound SHPObject suitable for labelling * return only one point even if if is a compound object * * reject non area SHP Types * * **************************************************************************/ PT SHPPointinPoly_2d ( SHPObject *psCShape ) { PT *sPT, rPT; if ( !(SHPDimension (psCShape->nSHPType) & SHPD_AREA) ) { rPT.x = NAN; rPT.y = NAN; return rPT; } sPT = SHPPointsinPoly_2d ( psCShape ); if ( sPT ) { rPT.x = sPT[0].x; rPT.y = sPT[0].y; } else { rPT.x = NAN; rPT.y = NAN; } return ( rPT ); } /* ************************************************************************** * SHPPointsinPoly_2d * * Return a Point inside each R+ of a potentially * complex/compound SHPObject suitable for labelling * return one point for each R+ even if it is a compound object * * reject non area SHP Types * * **************************************************************************/ PT* SHPPointsinPoly_2d ( SHPObject *psCShape ) { PT *PIP = NULL; int cRing; SHPObject *psO, *psInt, *CLine; double *CLx, *CLy; int *CLstt, *CLst, nPIP, ring, rMpart, ring_vtx, ring_nVertices; double rLen, rLenMax; if ( !(SHPDimension (psCShape->nSHPType) & SHPD_AREA) ) return ( NULL ); while ( psO = SHPUnCompound (psCShape, &cRing)) { CLx = calloc ( 4, sizeof(double)); CLy = calloc ( 4, sizeof(double)); CLst = calloc ( 2, sizeof(int)); CLstt = calloc ( 2, sizeof(int)); /* a horizontal & vertical compound line though the middle of the */ /* extents */ CLx [0] = psO->dfXMin; CLy [0] = (psO->dfYMin + psO->dfYMax ) * 0.5; CLx [1] = psO->dfXMax; CLy [1] = (psO->dfYMin + psO->dfYMax ) * 0.5; CLx [2] = (psO->dfXMin + psO->dfXMax ) * 0.5; CLy [2] = psO->dfYMin; CLx [3] = (psO->dfXMin + psO->dfXMax ) * 0.5; CLy [3] = psO->dfYMax; CLst[0] = 0; CLst[1] = 2; CLstt[0] = SHPP_RING; CLstt[1] = SHPP_RING; CLine = SHPCreateObject ( SHPT_POINT, -1, 2, CLst, CLstt, 4, CLx, CLy, NULL, NULL ); /* with the H & V centrline compound object, intersect it with the OBJ */ psInt = SHPIntersect_2d ( CLine, psO ); /* return SHP type is lowest common dimensionality of the input types */ /* find the longest linestring returned by the intersection */ ring_vtx = psInt->nVertices ; for ( ring = (psInt->nParts - 1); ring >= 0; ring-- ) { ring_nVertices = ring_vtx - psInt->panPartStart[ring]; rLen += RingLength_2d ( ring_nVertices, (double*) &(psInt->padfX [psInt->panPartStart[ring]]), (double*) &(psInt->padfY [psInt->panPartStart[ring]]) ); if ( rLen > rLenMax ) { rLenMax = rLen; rMpart = psInt->panPartStart[ring]; } ring_vtx = psInt->panPartStart[ring]; } /* add the centerpoint of the longest ARC of the intersection to the */ /* PIP list */ nPIP ++; SfRealloc ( PIP, sizeof(double) * 2 * nPIP); PIP[nPIP].x = (psInt ->padfX [rMpart] + psInt ->padfX [rMpart]) * 0.5; PIP[nPIP].y = (psInt ->padfY [rMpart] + psInt ->padfY [rMpart]) * 0.5; SHPDestroyObject ( psO ); SHPDestroyObject ( CLine ); /* does SHPCreateobject use preallocated memory or does it copy the */ /* contents. To be safe conditionally release CLx, CLy, CLst, CLstt */ if ( CLx ) free ( CLx ); if ( CLy ) free ( CLy ); if ( CLst ) free ( CLst ); if ( CLstt ) free ( CLstt ); } return ( PIP ); } /* ************************************************************************** * SHPCentrd_2d * * Return the single mathematical / geometric centroid of a potentially * complex/compound SHPObject * * reject non area SHP Types * * **************************************************************************/ PT SHPCentrd_2d ( SHPObject *psCShape ) { int ring, ringPrev, ring_nVertices, rStart; double Area, ringArea; PT ringCentrd, C; if ( !(SHPDimension (psCShape->nSHPType) & SHPD_AREA) ) { C.x = NAN; C.y = NAN; return C; } #ifdef DEBUG printf ("for Object with %d vtx, %d parts [ %d, %d] \n", psCShape->nVertices, psCShape->nParts, psCShape->panPartStart[0],psCShape->panPartStart[1]); #endif Area = 0; C.x = 0.0; C.y = 0.0; /* for each ring in compound / complex object calc the ring cntrd */ ringPrev = psCShape->nVertices; for ( ring = (psCShape->nParts - 1); ring >= 0; ring-- ) { rStart = psCShape->panPartStart[ring]; ring_nVertices = ringPrev - rStart; RingCentroid_2d ( ring_nVertices, (double*) &(psCShape->padfX [rStart]), (double*) &(psCShape->padfY [rStart]), &ringCentrd, &ringArea); #ifdef DEBUG printf ("(SHPCentrd_2d) Ring %d, vtxs %d, area: %f, ring centrd %f, %f \n", ring, ring_nVertices, ringArea, ringCentrd.x, ringCentrd.y); #endif /* use Superposition of these rings to build a composite Centroid */ /* sum the ring centrds * ringAreas, at the end divide by total area */ C.x += ringCentrd.x * ringArea; C.y += ringCentrd.y * ringArea; Area += ringArea; ringPrev = rStart; } /* hold on the division by AREA until were at the end */ C.x = C.x / Area; C.y = C.y / Area; #ifdef DEBUG printf ("SHPCentrd_2d) Overall Area: %f, Centrd %f, %f \n", Area, C.x, C.y); #endif return ( C ); } /* ************************************************************************** * RingCentroid_2d * * Return the mathematical / geometric centroid of a single closed ring * * **************************************************************************/ int RingCentroid_2d ( int nVertices, double *a, double *b, PT *C, double *Area ) { int iv,jv; int sign_x, sign_y; double dy_Area, dx_Area, Cx_accum, Cy_accum, ppx, ppy; double x_base, y_base, x, y; /* the centroid of a closed Ring is defined as * * Cx = sum (cx * dArea ) / Total Area * and * Cy = sum (cy * dArea ) / Total Area */ x_base = a[0]; y_base = b[0]; Cy_accum = 0.0; Cx_accum = 0.0; ppx = a[1] - x_base; ppy = b[1] - y_base; *Area = 0; /* Skip the closing vector */ for ( iv = 2; iv <= nVertices - 2; iv++ ) { x = a[iv] - x_base; y = b[iv] - y_base; /* calc the area and centroid of triangle built out of an arbitrary */ /* base_point on the ring and each successive pair on the ring */ /* Area of a triangle is the cross product of its defining vectors */ /* Centroid of a triangle is the average of its vertices */ dx_Area = ((x * ppy) - (y * ppx)) * 0.5; *Area += dx_Area; Cx_accum += ( ppx + x ) * dx_Area; Cy_accum += ( ppy + y ) * dx_Area; #ifdef DEBUG2 printf("(ringcentrd_2d) Pp( %f, %f), P(%f, %f)\n", ppx, ppy, x, y); printf("(ringcentrd_2d) dA: %f, sA: %f, Cx: %f, Cy: %f \n", dx_Area, *Area, Cx_accum, Cy_accum); #endif ppx = x; ppy = y; } #ifdef DEBUG2 printf("(ringcentrd_2d) Cx: %f, Cy: %f \n", ( Cx_accum / ( *Area * 3) ), ( Cy_accum / (*Area * 3) )); #endif /* adjust back to world coords */ C->x = ( Cx_accum / ( *Area * 3)) + x_base; C->y = ( Cy_accum / ( *Area * 3)) + y_base; return ( 1 ); } /* ************************************************************************** * SHPRingDir_2d * * Test Polygon for CW / CCW ( R+ / R- ) * * return 1 for R+ * return -1 for R- * return 0 for error * **************************************************************************/ int SHPRingDir_2d ( SHPObject *psCShape, int Ring ) { int i, ti, last_vtx; double tX; double *a, *b; double dx0, dx1, dy0, dy1, v1, v2 ,v3; tX = 0.0; a = psCShape->padfX; b = psCShape->padfY; if ( Ring >= psCShape->nParts ) return ( 0 ); if ( Ring >= psCShape->nParts -1 ) { last_vtx = psCShape->nVertices; } else { last_vtx = psCShape->panPartStart[Ring + 1]; } /* All vertices at the corners of the extrema (rightmost lowest, leftmost lowest, */ /* topmost rightest, ...) must be less than pi wide. If they werent they couldnt be */ /* extrema. */ /* of course the following will fail if the Extents are even a little wrong */ for ( i = psCShape->panPartStart[Ring]; i < last_vtx; i++ ) { if ( b[i] == psCShape->dfYMax && a[i] > tX ) { ti = i; } } #ifdef DEBUG2 printf ("(shpgeo:SHPRingDir) highest Rightmost Pt is vtx %d (%f, %f)\n", ti, a[ti], b[ti]); #endif /* cross product */ /* the sign of the cross product of two vectors indicates the right or left half-plane */ /* which we can use to indicate Ring Dir */ if ( ti > psCShape->panPartStart[Ring] & ti < last_vtx ) { dx0 = a[ti-1] - a[ti]; dx1 = a[ti+1] - a[ti]; dy0 = b[ti-1] - b[ti]; dy1 = b[ti+1] - b[ti]; } else /* if the tested vertex is at the origin then continue from 0 */ { dx1 = a[1] - a[0]; dx0 = a[last_vtx] - a[0]; dy1 = b[1] - b[0]; dy0 = b[last_vtx] - b[0]; } // v1 = ( (dy0 * 0) - (0 * dy1) ); // v2 = ( (0 * dx1) - (dx0 * 0) ); /* these above are always zero so why do the math */ v3 = ( (dx0 * dy1) - (dx1 * dy0) ); #ifdef DEBUG2 printf ("(shpgeo:SHPRingDir) cross product for vtx %d was %f \n", ti, v3); #endif if ( v3 > 0 ) { return (1); } else { return (-1); } } /* ************************************************************************** * SHPArea_2d * * Calculate the XY Area of Polygon ( can be compound / complex ) * * **************************************************************************/ double SHPArea_2d ( SHPObject *psCShape ) { double cArea; int ring, ring_vtx, ringDir, ring_nVertices; cArea = 0; if ( !(SHPDimension (psCShape->nSHPType) & SHPD_AREA) ) return ( -1 ); /* Walk each ring adding its signed Area, R- will return a negative */ /* area, so we don't have to test for them */ /* I just start at the last ring and work down to the first */ ring_vtx = psCShape->nVertices ; for ( ring = (psCShape->nParts - 1); ring >= 0; ring-- ) { ring_nVertices = ring_vtx - psCShape->panPartStart[ring]; #ifdef DEBUG2 printf("(shpgeo:SHPArea_2d) part %d, vtx %d \n", ring, ring_nVertices); #endif cArea += RingArea_2d ( ring_nVertices, (double*) &(psCShape->padfX [psCShape->panPartStart[ring]]), (double*) &(psCShape->padfY [psCShape->panPartStart[ring]]) ); ring_vtx = psCShape->panPartStart[ring]; } #ifdef DEBUG2 printf ("(shpgeo:SHPArea_2d) Area = %f \n", cArea); #endif /* Area is signed, negative Areas are R- */ return ( cArea ); } /* ************************************************************************** * SHPLength_2d * * Calculate the Planar ( XY ) Length of Polygon ( can be compound / complex ) * or Polyline ( can be compound ). Length on Polygon is its Perimeter * * **************************************************************************/ double SHPLength_2d ( SHPObject *psCShape ) { double Length; int i, j; double dx, dy; if ( !(SHPDimension (psCShape->nSHPType) & (SHPD_AREA || SHPD_LINE)) ) return ( (double) -1 ); Length = 0; j = 1; for ( i = 1; i < psCShape->nVertices; i++ ) { if ( psCShape->panPartStart[j] == i ) { j ++; } /* skip the moves with "pen up" from ring to ring */ else { dx = psCShape->padfX[i] - psCShape->padfX[i-1]; dy = psCShape->padfY[i] - psCShape->padfY[i-1]; Length += sqrt ( ( dx * dx ) + ( dy * dy ) ); } /* simplify this equation */ } return ( Length ); } /* ************************************************************************** * RingLength_2d * * Calculate the Planar ( XY ) Length of Polygon ( can be compound / complex ) * or Polyline ( can be compound ). Length of Polygon is its Perimeter * * **************************************************************************/ double RingLength_2d ( int nVertices, double *a, double *b ) { double Length; int i, j; double dx, dy; Length = 0; j = 1; for ( i = 1; i < nVertices; i++ ) { dx = a[i] - b[i-1]; dy = b[i] - b[i-1]; Length += sqrt ( ( dx * dx ) + ( dy * dy ) ); /* simplify this equation */ } return ( Length ); } /* ************************************************************************** * RingArea_2d * * Calculate the Planar Area of a single closed ring * * **************************************************************************/ double RingArea_2d ( int nVertices, double *a, double *b ) { int iv,jv; double ppx, ppy; static double Area; double dx_Area; double x_base, y_base, x, y; x_base = a[0]; y_base = b[0]; ppx = a[1] - x_base; ppy = b[1] - y_base; Area = 0.0; #ifdef DEBUG2 printf("(shpgeo:RingArea) %d vertices \n", nVertices); #endif for ( iv = 2; iv <= ( nVertices - 1 ); iv++ ) { x = a[iv] - x_base; y = b[iv] - y_base; /* Area of a triangle is the cross product of its defining vectors */ dx_Area = ((x * ppy) - (y * ppx)) * 0.5; Area += dx_Area; #ifdef DEBUG2 printf ("(shpgeo:RingArea) dxArea %f sArea %f for pt(%f, %f)\n", dx_Area, Area, x, y); #endif ppx = x; ppy = y; } #ifdef DEBUG2 printf ("(shpgeo:RingArea) total RingArea %f \n", Area); #endif return ( Area ); } /* ************************************************************************** * SHPUnCompound * * ESRI calls this function explode * Return a non compound ( possibly complex ) object * * ring_number is R+ number corresponding to object * * * ignore complexity in Z dimension for now * * **************************************************************************/ SHPObject* SHPUnCompound ( SHPObject *psCShape, int * ringNumber ) { int ringDir, ring, lRing; if ( (*ringNumber >= psCShape->nParts) || *ringNumber == -1 ) { *ringNumber = -1; return (NULL); } if ( *ringNumber == (psCShape->nParts - 1) ) { *ringNumber = -1; return ( SHPClone(psCShape, (psCShape->nParts - 1), -1) ); } lRing = *ringNumber; ringDir = -1; for ( ring = (lRing + 1); (ring < psCShape->nParts) && ( ringDir < 0 ); ring ++) ringDir = SHPRingDir_2d ( psCShape, ring); if ( ring == psCShape->nParts ) *ringNumber = -1; else *ringNumber = ring; /* I am strictly assuming that all R- parts of a complex object * directly follow their R+, so when we hit a new R+ its a * new part of a compound object * a SHPClean may be needed to enforce this as it is not part * of ESRI's definition of a SHPfile */ #ifdef DEBUG2 printf ("(SHPUnCompound) asked for ring %d, lastring is %d \n", lRing, ring); #endif return ( SHPClone(psCShape, lRing, ring ) ); } /* ************************************************************************** * SHPIntersect_2d * * * prototype only for now * * return object with lowest common dimensionality of objects * * **************************************************************************/ SHPObject* SHPIntersect_2d ( SHPObject* a, SHPObject* b ) { SHPObject *C; if ( (SHPDimension(a->nSHPType) && SHPD_POINT) || ( SHPDimension(b->nSHPType) && SHPD_POINT ) ) return ( NULL ); /* there is no intersect function like this for points */ C = SHPClone ( a, 0 , -1 ); return ( C); } /* ************************************************************************** * SHPClean * * Test and fix normalization problems in shapes * Different tests need to be implemented for different SHPTypes * SHPT_POLYGON check ring directions CW / CCW ( R+ / R- ) * put all R- after the R+ they are members of * i.e. each complex object is completed before the * next object is started * check for closed rings * ring must not intersect itself, even on edge * * no other types implemented yet * * not sure why but return object in place * use for object casting and object verification * **************************************************************************/ int SHPClean ( SHPObject *psCShape ) { return (0); } /* ************************************************************************** * SHPClone * * Clone a SHPObject, replicating all data * * **************************************************************************/ SHPObject* SHPClone ( SHPObject *psCShape, int lowPart, int highPart ) { SHPObject *psObject; int newParts, newVertices; #ifdef DEBUG int i; #endif if ( highPart >= psCShape->nParts || highPart == -1 ) highPart = psCShape->nParts ; #ifdef DEBUG printf (" cloning SHP (%d parts) from ring %d upto ring %d \n", psCShape->nParts, lowPart, highPart); #endif newParts = highPart - lowPart; if ( newParts == 0 ) { return ( NULL ); } psObject = (SHPObject *) calloc(1,sizeof(SHPObject)); psObject->nSHPType = psCShape->nSHPType; psObject->nShapeId = psCShape->nShapeId; psObject->nParts = newParts; if ( psCShape->padfX ) { psObject->panPartStart = (int*) calloc (newParts, sizeof (int)); memcpy ( psObject->panPartStart, psCShape->panPartStart, newParts * sizeof (int) ); } if ( psCShape->padfX ) { psObject->panPartType = (int*) calloc (newParts, sizeof (int)); memcpy ( psObject->panPartType, (int *) &(psCShape->panPartType[lowPart]), newParts * sizeof (int) ); } if ( highPart != psCShape->nParts ) { newVertices = psCShape->panPartStart[highPart] - psCShape->panPartStart[lowPart]; } else { newVertices = psCShape->nVertices - psCShape->panPartStart[lowPart]; } #ifdef DEBUG if ( highPart = psCShape->nParts ) i = psCShape->nVertices; else i = psCShape->panPartStart[highPart]; printf (" from part %d (%d) to %d (%d) is %d vertices \n", lowPart, psCShape->panPartStart[lowPart], highPart, i, newVertices); #endif psObject->nVertices = newVertices; if ( psCShape->padfX ) { psObject->padfX = (double*) calloc (newVertices, sizeof (double)); memcpy ( psObject->padfX, (double *) &(psCShape->padfX[psCShape->panPartStart[lowPart]]), newVertices * sizeof (double) ); } if ( psCShape->padfY ) { psObject->padfY = (double*) calloc (newVertices, sizeof (double)); memcpy ( psObject->padfY, (double *) &(psCShape->padfY[psCShape->panPartStart[lowPart]]), newVertices * sizeof (double) ); } if ( psCShape->padfZ ) { psObject->padfZ = (double*) calloc (newVertices, sizeof (double)); memcpy ( psObject->padfZ, (double *) &(psCShape->padfZ[psCShape->panPartStart[lowPart]]), newVertices * sizeof (double) ); } if ( psCShape->padfM ) { psObject->padfM = (double*) calloc (newVertices, sizeof (double)); memcpy ( psObject->padfM, (double *) &(psCShape->padfM[psCShape->panPartStart[lowPart]]), newVertices * sizeof (double) ); } psObject->dfXMin = psCShape->dfXMin; psObject->dfYMin = psCShape->dfYMin; psObject->dfZMin = psCShape->dfZMin; psObject->dfMMin = psCShape->dfMMin; psObject->dfXMax = psCShape->dfXMax; psObject->dfYMax = psCShape->dfYMax; psObject->dfZMax = psCShape->dfZMax; psObject->dfMMax = psCShape->dfMMax; SHPComputeExtents ( psObject ); return ( psObject ); } /************************************************************************/ /* SwapG */ /* */ /* Swap a 2, 4 or 8 byte word. */ /************************************************************************/ void SwapG( void *so, void *in, int this_cnt, int this_size ) { int i, j; unsigned char temp; /* return to a new pointer otherwise it would invalidate existing data */ /* as prevent further use of it */ for( j=0; j < this_cnt; j++ ) { for( i=0; i < this_size/2; i++ ) { ((unsigned char *) so)[i] = ((unsigned char *) in)[this_size-i-1]; ((unsigned char *) so)[this_size-i-1] = ((unsigned char *) in)[i]; } } } /* ************************************************************************** * SwapW * * change byte order on an array of 16 bit words * need to change this over to shapelib, Frank Warmerdam's functions * * **************************************************************************/ void swapW (void *so, unsigned char *in, long bytes) { int i, j; unsigned char map[4] = {3,2,1,0}; unsigned char *out; out = so; for (i=0; i <= (bytes/4); i++) for (j=0; j < 4; j++) out[(i*4)+map[j]] = in[(i*4)+j]; } /* ************************************************************************** * SwapD * * change byte order on an array of (double) 32 bit words * need to change this over to shapelib, Frank Warmerdam's functons * * **************************************************************************/ void swapD (void *so, unsigned char *in, long bytes) { int i, j; unsigned char map[8] = {7,6,5,4,3,2,1,0}; unsigned char *out; out = so; for (i=0; i <= (bytes/8); i++) for (j=0; j < 8; j++) out[(i*8)+map[j]] = in[(i*8)+j]; } ./shapelib-1.2.10/contrib/shpgeo.h0100644000076500001440000001223507644273432016362 0ustar warmerdausers/****************************************************************************** * Copyright (c) 1999, Carl Anderson * * This code is based in part on the earlier work of Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * shpgeo.h * * support for geometric and other additions to shapelib * * * $Log: shpgeo.h,v $ * Revision 1.3 2002/01/15 14:36:56 warmerda * upgrade to use proj_api.h * * Revision 1.2 1999/05/26 02:56:31 candrsn * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo * * */ /* I'm using some shorthand throughout this file * R+ is a Clockwise Ring and is the positive portion of an object * R- is a CounterClockwise Ring and is a hole in a R+ * A complex object is one having at least one R- * A compound object is one having more than one R+ * A simple object has one and only one element (R+ or R-) * * The closed ring constraint is for polygons and assumed here * Arcs or LineStrings I am calling Rings (generically open or closed) * Point types are vertices or lists of vertices but not Rings * * SHPT_POLYGON, SHPT_POLYGONZ, SHPT_POLYGONM and SHPT_MULTIPATCH * can have SHPObjects that are compound as well as complex * * SHP_POINT and its Z and M derivatives are strictly simple * MULTI_POINT, SHPT_ARC and their derivatives may be simple or compound * */ #ifndef SHPGEO_H #define SHPGEO_H #ifdef __cplusplus extern "C" { #endif #include "proj_api.h" #define SHPD_POINT 1 #define SHPD_LINE 2 #define SHPD_AREA 4 #define SHPD_Z 8 #define SHPD_MEASURE 16 /* move these into a ogis header file ogis.h */ #define OGIST_UNKNOWN 0 #define OGIST_POINT 1 #define OGIST_LINESTRING 2 #define OGIST_POLYGON 3 #define OGIST_MULTIPOINT 4 #define OGIST_MULTILINE 5 #define OGIST_MULTIPOLYGON 6 #define OGIST_GEOMCOLL 7 typedef struct { int StreamPos; int NeedSwap; char *wStream; } WKBStreamObj; typedef struct { double x; double y; } PT; typedef struct { int cParts; SHPObject *SHPObj; } SHPObjectList; #define LSB_ORDER (int) 1 extern char * asFileName ( const char *fil, char *ext ); extern int SHPProject ( SHPObject *psCShape, projPJ inproj, projPJ outproj ); extern projPJ SHPSetProjection ( int param_cnt, char **params ); extern int SHPFreeProjection ( projPJ p); extern int SHPDimension ( int SHPType ); extern double SHPArea_2d ( SHPObject *psCShape ); extern int SHPRingDir_2d ( SHPObject *psCShape, int Ring ); extern double SHPLength_2d ( SHPObject *psCShape ); extern PT SHPCentrd_2d ( SHPObject *psCShape ); extern PT SHPPointinPoly_2d ( SHPObject *psCShape ); extern PT* SHPPointsinPoly_2d ( SHPObject *psCShape ); extern int RingCentroid_2d ( int nVertices, double *a, double *b, PT *C, double *Area ); extern double RingLength_2d ( int nVertices, double *a, double *b ); extern int RingDir_2d ( int nVertices, double *a, double *b ); extern double RingArea_2d ( int nVertices, double *a, double *b ); extern SHPObject* SHPClone ( SHPObject *psCShape, int lowPart, int highPart ); extern SHPObject* SHPUnCompound ( SHPObject *psCShape, int * ringNumber ); extern SHPObject* SHPIntersect_2d ( SHPObject* a, SHPObject* b ); extern int SHPWriteOGisWKB ( WKBStreamObj *stream_obj, SHPObject *psCShape ); extern SHPObject* SHPReadOGisWKB ( WKBStreamObj *stream_obj ); int SHPWriteOGisPolygon ( WKBStreamObj *stream_obj, SHPObject *psCShape ); int SHPWriteOGisLine ( WKBStreamObj *stream_obj, SHPObject *psCShape ); int SHPWriteOGisPoint ( WKBStreamObj *stream_obj, SHPObject *psCShape ); SHPObject* SHPReadOGisPolygon ( WKBStreamObj *stream_obj ); SHPObject* SHPReadOGisLine ( WKBStreamObj *stream_obj ); SHPObject* SHPReadOGisPoint ( WKBStreamObj *stream_obj ); extern int SHPClean ( SHPObject *psCShape ); extern int SHPOGisType ( int GeomType, int toOGis); void swapD (void *so, unsigned char *in, long bytes); void swapW (void *so, unsigned char *in, long bytes); void SwapG( void *so, void *in, int this_cnt, int this_size ); #ifdef __cplusplus } #endif #endif /* ndef SHPGEO_H */ ./shapelib-1.2.10/contrib/shpinfo.c0100644000076500001440000000730107644273432016534 0ustar warmerdausers/****************************************************************************** * Copyright (c) 1999, Carl Anderson * * This code is based in part on the earlier work of Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * requires shapelib 1.2 * gcc shpinfoj shpopen.o -o shpinfo * * * $Log: shpinfo.c,v $ * Revision 1.3 2002/04/15 21:33:03 warmerda * Avoid dereference arrays. * * Revision 1.2 2002/04/15 18:40:31 warmerda * Fixed size of adfBnds{Min,Max} as per bug from David Fowler. * * Revision 1.1 1999/05/26 02:56:31 candrsn * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo * * */ #include "shapefil.h" int main( int argc, char ** argv ) { SHPHandle hSHP, cSHP; int nShapeType, nEntities, nVertices, nParts, *panParts, i, iPart; double *padVertices, adfBndsMin[4], adfBndsMax[4]; const char *pszPlus; int cShapeType, cEntities, cVertices, cParts, *cpanParts, ci, cPart; double *cpadVertices, cadBounds[4]; const char *cpszPlus; char sType [15]= ""; /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc != 2 ) { printf( "shpinfo shp_file\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( argv[1], "rb" ); if( hSHP == NULL ) { printf( "Unable to open:%s\n", argv[1] ); exit( 1 ); } SHPGetInfo( hSHP, &nEntities, &nShapeType, adfBndsMin, adfBndsMax ); switch ( nShapeType ) { case SHPT_POINT: strcpy(sType,"Point"); break; case SHPT_ARC: strcpy(sType,"Polyline"); break; case SHPT_POLYGON: strcpy(sType,"Polygon"); break; case SHPT_MULTIPOINT: strcpy(sType,"MultiPoint"); break; } /* -------------------------------------------------------------------- */ printf ("Info for %s\n",argv[1]); printf ("%s(%d), %ld Records in file\n",sType,nShapeType,nEntities); /* -------------------------------------------------------------------- */ /* Print out the file bounds. */ /* -------------------------------------------------------------------- */ printf( "File Bounds: (%15.10lg,%15.10lg)\n\t(%15.10lg,%15.10lg)\n", adfBndsMin[0], adfBndsMin[1], adfBndsMax[0], adfBndsMax[1] ); SHPClose( hSHP ); } ./shapelib-1.2.10/contrib/shpproj.c0100644000076500001440000001652707644273432016565 0ustar warmerdausers/****************************************************************************** * Copyright (c) 1999, Carl Anderson * * This code is based in part on the earlier work of Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ******************************************************************************* * * requires shapelib 1.2 * gcc shpproj ../shpopen.o ../dbfopen.o shpgeo.o -lm -lproj -o shpproj * * this requires linking with the PROJ4.3 projection library available from * * ftp://kai.er.usgs.gov/ftp/PROJ.4 * * * SHPGeo must be compiled with -DPROJ4 support * * $Log: shpproj.c,v $ * Revision 1.9 2002/01/15 14:37:08 warmerda * upgrade to use proj_api.h * * Revision 1.8 2002/01/11 15:47:26 warmerda * several fixes * * Revision 1.7 2002/01/11 15:23:28 warmerda * use text mode reading and writing .prj files * * Revision 1.6 1999/05/26 02:56:31 candrsn * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo * * Revision 1.2 1999/05/13 19:30:52 warmerda * Removed libgen.h, added url for PROJ.4, and corrected unsafe return of * local variable in asFileName(). * */ #include "shapefil.h" #include "shpgeo.h" #include int main( int argc, char ** argv ) { SHPHandle old_SHP, new_SHP; DBFHandle old_DBF, new_DBF; int nShapeType, nEntities, nVertices, nParts, *panParts, i, iPart, j; double *padVertices, adBounds[4]; const char *pszPlus; DBFFieldType idfld_type; SHPObject *psCShape; FILE *ifp = NULL; int idfld, nflds; char kv[257] = ""; char idfldName[120] = ""; char fldName[120] = ""; char shpFileName[120] = ""; char dbfFileName[120] = ""; char prjFileName[120] = ""; char parg[80]; double apeture[4]; int inarg, outarg; char *DBFRow = NULL; /* for testing only char *in_args[] = { "init=nad83:1002", "units=us-ft" }; char *out_args[] = { "proj=utm", "zone=16", "units=m" }; */ char *in_args[16]; char *out_args[16]; int in_argc = 0 , out_argc = 0, outf_arg; char *arglst; projPJ orig_prj, new_prj; va_list myargs, moargs; if( argc < 4) { printf( "shpproj shp_file new_shp ( -i=in_proj_file | -i=\"in_params\" | -i=geographic ) ( -o=out_info_file | -o=\"out_params\" | -o=geographic ) \n" ); exit( 1 ); } old_SHP = SHPOpen( argv[1], "rb" ); old_DBF = DBFOpen( argv[1], "rb" ); if( old_SHP == NULL || old_DBF == NULL ) { printf( "Unable to open old files:%s\n", argv[1] ); exit( 1 ); } outf_arg = 2; inarg = 0; outarg = 0; for ( i = 3; i < argc; i++ ) { if ( !strncmp ("-i=", argv[i], 3 )) inarg = i; if ( !strncmp ("-o=", argv[i], 3 )) outarg = i; } /* if shapefile has a prj component then use that else try for a file then read args as list */ if( inarg == 0 ) { strcpy( prjFileName, argv[1] ); ifp = fopen( asFileName ( prjFileName, "prj" ),"rt"); } else { ifp = fopen( asFileName ( argv[inarg] + 3, "prj" ),"rt"); } i = 0; if ( ifp ) { if( inarg == 0 ) printf ("using default file proj params from <- %s\n", asFileName ( prjFileName, "prj" ) ); else printf ("using file proj params from <- %s\n", asFileName ( argv[inarg] + 3, "prj" ) ); while( fscanf( ifp, "%s", parg) != EOF ) { in_args[i] = malloc ( strlen(parg)+1 ); strcpy ( in_args[i], parg); i++; } in_argc = i; fclose (ifp); } else { if ( inarg > 0 ) { arglst = argv[inarg] + 3; j = 0; i = 0; while ( j < strlen (arglst) ) { in_argc += sscanf ( arglst + j, "%s", parg); in_args[i] = malloc( strlen (parg)+1); strcpy (in_args[i], parg); i++; j += strlen (parg) +1; if ( arglst[j] + 1 == 0 ) j = strlen (argv[inarg]); } } } i = 0; if ( outarg > 0 ) ifp = fopen( asFileName ( argv[outarg] + 3, "prj" ),"rt"); if ( ifp ) { while( fscanf( ifp, "%s", parg) != EOF ) { out_args[i] = malloc ( strlen(parg)); strcpy ( out_args[i], parg); i++; } out_argc = i; fclose (ifp); } else { if ( outarg > 0 ) { arglst = argv[outarg] + 3; j = 0; i = 0; while ( j < strlen (arglst) ) { out_argc += sscanf ( arglst + j, "%s", parg); out_args[i] = malloc( strlen (parg)+1); strcpy (out_args[i], parg); i++; j += strlen (parg) +1; if ( arglst[j] + 1 == 0 ) j = strlen (argv[outarg]); } } } if ( !strcmp( argv[inarg], "-i=geographic" )) in_argc = 0; if ( !strcmp( argv[outarg], "-o=geographic" )) out_argc = 0; orig_prj = SHPSetProjection ( in_argc, in_args ); new_prj = SHPSetProjection ( out_argc, out_args ); if ( !(( (!in_argc) || orig_prj) && ( (!out_argc) || new_prj) )) { fprintf (stderr, "unable to process projection, exiting...\n"); exit(1); } SHPGetInfo( old_SHP, &nEntities, &nShapeType, NULL, NULL); new_SHP = SHPCreate ( argv[outf_arg], nShapeType ); new_DBF = DBFCloneEmpty (old_DBF, argv[outf_arg]); if( new_SHP == NULL || new_DBF == NULL ) { printf( "Unable to create new files:%s\n", argv[outf_arg] ); exit( 1 ); } DBFRow = (char *) malloc ( (old_DBF->nRecordLength) + 15 ); for( i = 0; i < nEntities; i++ ) { int j; psCShape = SHPReadObject ( old_SHP, i ); SHPProject (psCShape, orig_prj, new_prj ); SHPWriteObject ( new_SHP, -1, psCShape ); SHPDestroyObject ( psCShape ); memcpy ( DBFRow, DBFReadTuple ( old_DBF, i ), old_DBF->nRecordLength ); DBFWriteTuple ( new_DBF, new_DBF->nRecords, DBFRow ); } SHPFreeProjection ( orig_prj ); SHPFreeProjection ( new_prj ); /* store projection params into prj file */ ifp = fopen( asFileName ( argv[outf_arg], "prj" ),"wt"); if ( ifp ) { if ( out_argc == 0 ) { fprintf( ifp, "proj=geographic\n" ); } else { for ( i = 0; i < out_argc; i++ ) fprintf( ifp, "%s\n", out_args[i]); } fclose (ifp); } SHPClose( old_SHP ); SHPClose( new_SHP ); DBFClose( old_DBF ); DBFClose( new_DBF ); printf ("\n"); } ./shapelib-1.2.10/contrib/shpwkb.c0100644000076500001440000000763507644273432016376 0ustar warmerdausers/****************************************************************************** * Copyright (c) 1999, Carl Anderson * * this code is based in part on the earlier work of Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * shpwkb.c - test WKB binary Input / Output * * * $Log: shpwkb.c,v $ * Revision 1.1 1999/05/26 02:29:36 candrsn * OGis Well Known Binary test program (output only) * * * */ #include "shapefil.h" #include "shpgeo.h" int main( int argc, char ** argv ) { SHPHandle old_SHP, new_SHP; DBFHandle old_DBF, new_DBF; int nShapeType, nEntities, nVertices, nParts, *panParts, i, iPart; double *padVertices, adBounds[4]; const char *pszPlus; DBFFieldType idfld_type; int idfld, nflds; char kv[257] = ""; char idfldName[120] = ""; char fldName[120] = ""; char shpFileName[120] = ""; char dbfFileName[120] = ""; char *DBFRow = NULL; int Cpan[2] = { 0,0 }; int byRing = 0; PT oCentrd, ringCentrd; SHPObject *psCShape, *cent_pt; double oArea = 0.0, oLen = 0.0; WKBStreamObj *wkbObj = NULL; FILE *wkb_file = NULL; if( argc < 3 ) { printf( "shpwkb shp_file wkb_file\n" ); exit( 1 ); } old_SHP = SHPOpen (argv[1], "rb" ); old_DBF = DBFOpen (argv[1], "rb"); if( old_SHP == NULL || old_DBF == NULL ) { printf( "Unable to open old files:%s\n", argv[1] ); exit( 1 ); } wkb_file = fopen ( argv[2], "wb"); wkbObj = calloc ( 3, sizeof (int) ); SHPGetInfo( old_SHP, &nEntities, &nShapeType, NULL, NULL ); for( i = 0; i < nEntities; i++ ) { int res ; psCShape = SHPReadObject( old_SHP, i ); if ( byRing == 1 ) { int ring, prevStart, ringDir; double ringArea; prevStart = psCShape->nVertices; for ( ring = (psCShape->nParts - 1); ring >= 0; ring-- ) { SHPObject *psO; int j, numVtx, rStart; rStart = psCShape->panPartStart[ring]; if ( ring == (psCShape->nParts -1) ) { numVtx = psCShape->nVertices - rStart; } else { numVtx = psCShape->panPartStart[ring+1] - rStart; } printf ("(shpdata) Ring(%d) (%d for %d) \n", ring, rStart, numVtx); psO = SHPClone ( psCShape, ring, ring + 1 ); SHPDestroyObject ( psO ); printf ("(shpdata) End Ring \n"); } /* (ring) [0,nParts */ } /* by ring */ printf ("gonna build a wkb \n"); res = SHPWriteOGisWKB ( wkbObj, psCShape ); printf ("gonna write a wkb that is %d bytes long \n", wkbObj->StreamPos ); fwrite ( (void*) wkbObj->wStream, 1, wkbObj->StreamPos, wkb_file ); } free ( wkbObj ); SHPClose( old_SHP ); DBFClose( old_DBF ); if ( wkb_file ) fclose ( wkb_file ); printf ("\n"); } ./shapelib-1.2.10/contrib/tests/0040755000076500001440000000000007644274052016065 5ustar warmerdausers./shapelib-1.2.10/contrib/tests/shpproj.sh0100755000076500001440000000136207644273432020111 0ustar warmerdausers#!/bin/sh cd tests rm test* shpcreate test point shpadd test -83.54949956 34.992401 shpadd test -83.52162155 34.99276748 shpadd test -84.01681518 34.67275985 shpadd test -84.15596023 34.64862437 shpadd test -83.61951463 34.54927047 dbfcreate test -s 30 fd dbfadd test "1" dbfadd test "2" dbfadd test "3" dbfadd test "4" dbfadd test "5" ../shpproj test test_1 -i=geographic -o="init=nad83:1002 units=us-ft" ../shpproj test_1 test_2 -o="proj=utm zone=16 units=m" ../shpproj test_2 test_3 -o=geographic shpdump test > test.out shpdump test_3 > test_3.out result=`diff test.out test_3.out` if [ -z "${result}" ]; then echo success... else echo failure... fi rm test* cd .../shapelib-1.2.10/.cvsignore0100644000076500001440000000013107644273432015254 0ustar warmerdausersshpcreate shpadd shpdump dbfcreate dbfadd dbfdump shptest shptreedump shputils shprewind ./shapelib-1.2.10/ChangeLog0100644000076500001440000001366407644273432015045 0ustar warmerdausers2003-04-07 Frank Warmerdam * Issue 1.2.10 Release. 2003-03-10 Frank Warmerdam * dbfopen.c: modified DBFWriteAttribute call so that it returns FALSE if it has to truncate the input value. 2003-01-28 Frank Warmerdam * shptree.c: avoid build warnings. 2002-05-07 Frank Warmerdam * dbfopen.c: Added DBFWriteAttributeDirectly() from the AVCE00 distribution to simplify AVC integration in GDAL. * shptree.c: added use of qsort() in place of bubble sort as submitted by Bernhard Herzog. 2002-04-10 Frank Warmerdam * shpopen.c: Added SHPRewindObject() to correct ring winding. * shprewind.c: New utility program. 2002-03-12 Frank Warmerdam * shapelib.def: added DBFWriteNULLAttribute. 2002-01-17 Frank Warmerdam * contrib/ShapeFileII.pas: Contributed Delphi Pascal interface to Shapelib. 2002-01-15 Frank Warmerdam * shapelib.h: Added support for SHAPELIB_DLLEXPORT macro, and write up material attempting to explain the use of SHPAPI_CALL macros. * dbfopen.c: Compute nHeaderLength in DBFCloneEmpty() instead of copying it from the source file so we don't have quirks when copying from files with extra bytes of spacers in the header that don't themselves get copied properly. 2001-12-07 Frank Warmerdam * shpopen.c: Fix fclose() of SHX file if SHX file fails to open. Should be closing SHP file. Reported by Ben Discoe. 2001-11-28 Frank Warmerdam * dbfopen.c: two fixes for compiler warnings as suggested by Richard Hash. 2001-11-01 Frank Warmerdam * shpopen.c/shapefil.h: Move record buffer into SHPInfo so that different threads can safely access separate files. Other threading issues may remain. 2001-08-28 Frank Warmerdam * Issue Shapelib 1.2.9 * shputils.c: DBFAddField() call should check for -1 return value for failure. 2001-07-03 Frank Warmerdam * shpopen.c: cleanup better if SHX missing, provided by Riccardo Cohen. 2001-06-21 Frank Warmerdam * dbfopen.c: Fixed NULL support with patches from Jim Matthews. * shpopen.c: Be more careful of establishing initial file bounds in face of possible NULL shapes. 2001-06-01 Frank Warmerdam * dbfopen.c: ensure binary mode open. 2001-05-31 Frank Warmerdam * shpopen.c: Add support for writing null shapes. * dbfopen.c: added DBFGetFieldIndex(), contributed by Jim Matthews. * dbfopen.c/shapefil.h/dbf_api.h: added support for NULL fields in .dbf files. 2001-05-28 Frank Warmerdam * shpopen.c: add some checking on the record count to ensure it is reasonable. 2001-05-23 Frank Warmerdam * shapefile.h, shpopen.c, dbfopen.c, shptree.c: added the SHPAPI_CALL macro to allow compilation with _stdcall conventions. 2001-02-06 Frank Warmerdam * Fixed a few memory leaks when SHPOpen() fails. 2000-12-05 Frank Warmerdam * Fix from Craig Bruce (Cubewerx) for DBFReadAttribute() for the white space trimming code to avoid reading outside allocated memory. 2000-11-02 Frank Warmerdam * Checked in upgraded shputils.c from Bill Miller. 2000-10-05 Frank Warmerdam * Fixed DBFWriteAttribute() to ensure we can't overwrite the end of the szSField buffer even if the width is set large. Bug report by Kirk Benell . 2000-09-25 Frank Warmerdam * Added DBFGetNativeFieldType() (contributed by Daniel) to dbfopen.c. 2000-07-18 Frank Warmerdam * added better enforcement of -1 for append in SHPWriteObject(). 2000-07-07 Frank Warmerdam * Added stdlib.h and string.h where needed, and removed lots of unused variables, mainly from example mainlines at the suggestion of Bill Hughes. 2000-05-24 Frank Warmerdam * Added logic to shpadd to grow vertex lists at the suggestion of Santiago Nullo . 2000-05-23 Frank Warmerdam * Added checks in dbfopen.c on return result of fseek() and fread(). * Avoid crashing in DBReadIntegerAttribute() or DBFReadDoubleAttribte() if the field or record are out of range. 2000-03-28 Frank Warmerdam * Release as 1.2.8. * Incorporated a -version-info fix and added mkinstalldirs from Jan. 2000-03-17 Frank Warmerdam * Added shared library hack to Makefile. * Fixed up test scripts to look in ./ for executables. Wed Feb 16 11:20:29 2000 Frank Warmerdam * Release 1.2.7. * Modified SHPReadObject() so that will return NULL (type 0) shapes in a sort of sensible way. Wed Dec 15 08:49:53 1999 Frank Warmerdam * Fixed record size written at beginning of records in .shp file. It was 4 bytes to long (thanks to Mikko Syrja of 3D-system Oy) * Use atof() instead of sscanf() in dbfopen.c, and add stdlib.h. Mon Dec 13 12:29:01 1999 Frank Warmerdam * Added support for uppercase .DBF extention c/o Dennis Christopher Fri Nov 5 09:12:31 1999 Frank Warmerdam * Updated license headers to include the option of use of the code under the LGPL. 1999-09-15 * Added shapelib.dll target to makefile.vc. Mon May 10 23:19:42 1999 Frank Warmerdam * Added candrsn's improvements to extension handling in dbfopen.c * Added ``raw tuple'' api to dbfopen.c, still not in dbf_api.html. From candrsn. Tue May 4 11:04:31 1999 Frank Warmerdam * Prepare 1.2.5 release. * Added support for 'F' fields. ./shapelib-1.2.10/LICENSE.LGPL0100644000076500001440000006126307644273432015033 0ustar warmerdausers GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! ./shapelib-1.2.10/Makefile0100644000076500001440000001321307644273432014721 0ustar warmerdausers #LINKOPT = /usr/local/lib/libdbmalloc.a CFLAGS = -g default: all all: shpcreate shpadd shpdump shprewind dbfcreate dbfadd dbfdump shptest shpopen.o: shpopen.c shapefil.h $(CC) $(CFLAGS) -c shpopen.c shptree.o: shptree.c shapefil.h $(CC) $(CFLAGS) -c shptree.c dbfopen.o: dbfopen.c shapefil.h $(CC) $(CFLAGS) -c dbfopen.c shpcreate: shpcreate.c shpopen.o $(CC) $(CFLAGS) shpcreate.c shpopen.o $(LINKOPT) -o shpcreate shpadd: shpadd.c shpopen.o $(CC) $(CFLAGS) shpadd.c shpopen.o $(LINKOPT) -o shpadd shpdump: shpdump.c shpopen.o $(CC) $(CFLAGS) shpdump.c shpopen.o $(LINKOPT) -o shpdump shprewind: shprewind.c shpopen.o $(CC) $(CFLAGS) shprewind.c shpopen.o $(LINKOPT) -o shprewind dbfcreate: dbfcreate.c dbfopen.o $(CC) $(CFLAGS) dbfcreate.c dbfopen.o $(LINKOPT) -o dbfcreate dbfadd: dbfadd.c dbfopen.o $(CC) $(CFLAGS) dbfadd.c dbfopen.o $(LINKOPT) -o dbfadd dbfdump: dbfdump.c dbfopen.o $(CC) $(CFLAGS) dbfdump.c dbfopen.o $(LINKOPT) -o dbfdump shptest: shptest.c shpopen.o $(CC) $(CFLAGS) shptest.c shpopen.o $(LINKOPT) -o shptest shputils: shputils.c shpopen.o dbfopen.o $(CC) $(CFLAGS) shputils.c shpopen.o dbfopen.o $(LINKOPT) -o shputils shptreedump: shptreedump.c shptree.o shpopen.o $(CC) $(CFLAGS) shptreedump.c shptree.o shpopen.o $(LINKOPT) \ -o shptreedump clean: rm -f *.o dbfdump dbfcreate dbfadd shpdump shpcreate shpadd shputils rm -f shptreedump rm -rf *.lo *.la .libs rm -f shptest test: test2 test3 # # Note this stream only works if example data is accessable. # Fetch ftp://gdal.velocet.ca/pub/outgoing/shape_eg_data.zip # test1: @./stream1.sh > s1.out @if test "`diff s1.out stream1.out`" = '' ; then \ echo "******* Stream 1 Succeeded *********"; \ rm s1.out; \ else \ echo "******* Stream 1 Failed *********"; \ diff s1.out stream1.out; \ fi test2: @./stream2.sh > s2.out @if test "`diff s2.out stream2.out`" = '' ; then \ echo "******* Stream 2 Succeeded *********"; \ rm s2.out; \ rm test*.s??; \ else \ echo "******* Stream 2 Failed *********"; \ diff s2.out stream2.out; \ fi test3: @./makeshape.sh > s3.out @if test "`diff s3.out stream3.out`" = '' ; then \ echo "******* Stream 3 Succeeded *********"; \ rm s3.out; \ rm test.*; \ else \ echo "******* Stream 3 Failed *********"; \ diff s3.out stream3.out; \ fi # ----------------------------------------------------------------------------- # The following is contributed by Jan-Oliver Wagner, and should allow for # creating shared libraries on most platforms with gcc, and libtool installed. SHPLIB_VERSION=1.2.9 LIBSHP_VERSION=1.0.1 # still once to be changed manually (see for 1:1:0), sorry lib: /bin/sh ./libtool --mode=compile gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c shpopen.c gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c -fPIC -DPIC shpopen.c -o .libs/shpopen.lo gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c shpopen.c -o shpopen.o >/dev/null 2>&1 mv -f .libs/shpopen.lo shpopen.lo /bin/sh ./libtool --mode=compile gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c shptree.c rm -f .libs/shptree.lo gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c -fPIC -DPIC shptree.c -o .libs/shptree.lo gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c shptree.c -o shptree.o >/dev/null 2>&1 mv -f .libs/shptree.lo shptree.lo /bin/sh ./libtool --mode=compile gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c dbfopen.c rm -f .libs/dbfopen.lo gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c -fPIC -DPIC dbfopen.c -o .libs/dbfopen.lo gcc -DPACKAGE=\"libshp\" -DVERSION=\"$(SHPLIB_VERSION)\" -DSTDC_HEADERS=1 -I. -I. -I/usr/local/include -g -O2 -c dbfopen.c -o dbfopen.o >/dev/null 2>&1 mv -f .libs/dbfopen.lo dbfopen.lo /bin/sh ./libtool --mode=link gcc -g -O2 -o libshp.la -rpath /usr/local/lib -version-info 1:1:0 shpopen.lo shptree.lo dbfopen.lo rm -fr .libs/libshp.la .libs/libshp.* .libs/libshp.* rm -fr .libs/libshp.lax mkdir .libs/libshp.lax /usr/bin/ld -G -h libshp.so.1 -o .libs/libshp.so.$(LIBSHP_VERSION) shpopen.lo shptree.lo dbfopen.lo -lc (cd .libs && rm -f libshp.so.1 && ln -s libshp.so.$(LIBSHP_VERSION) libshp.so.1) (cd .libs && rm -f libshp.so && ln -s libshp.so.$(LIBSHP_VERSION) libshp.so) ar cru .libs/libshp.a shpopen.o shptree.o dbfopen.o ranlib .libs/libshp.a rm -fr .libs/libshp.lax (cd .libs && rm -f libshp.la && ln -s ../libshp.la libshp.la) lib_install: cp .libs/libshp.la .libs/libshp.lai /bin/sh ./mkinstalldirs /usr/local/lib /bin/sh ./libtool --mode=install /usr/bin/install -c libshp.la /usr/local/lib/libshp.la /usr/bin/install -c .libs/libshp.so.$(LIBSHP_VERSION) /usr/local/lib/libshp.so.$(LIBSHP_VERSION) (cd /usr/local/lib && rm -f libshp.so.1 && ln -s libshp.so.$(LIBSHP_VERSION) libshp.so.1) (cd /usr/local/lib && rm -f libshp.so && ln -s libshp.so.$(LIBSHP_VERSION) libshp.so) chmod +x /usr/local/lib/libshp.so.$(LIBSHP_VERSION) /usr/bin/install -c .libs/libshp.la /usr/local/lib/libshp.la /usr/bin/install -c .libs/libshp.a /usr/local/lib/libshp.a ranlib /usr/local/lib/libshp.a chmod 644 /usr/local/lib/libshp.a /bin/sh ./mkinstalldirs /usr/local/include/libshp /usr/bin/install -c -m 644 shapefil.h /usr/local/include/libshp/shapefil.h ./shapelib-1.2.10/README0100755000076500001440000000132107644273432014141 0ustar warmerdausers Please read shapelib.html. Building on Unix ---------------- 1) Edit Makefile, and set CFLAGS, and CC macros as required for the target system. Often the defaults will work fine. 2) "type make" The result should be: Core shapelib support. shpopen.o dbfopen.o Utility/demonstration programs: shpcreate, shpdump, shpadd, dbfcreate, dbfdump, dbfadd To test type: make test Building on Windows ------------------- If you have run the VC++ VCVARS32.BAT, you should be able to type the following in a command window to build the code and executables: C:> nmake /f makefile.vc Otherwise create your own VC++ project. There aren't many files to deal with here! ./shapelib-1.2.10/README.tree0100644000076500001440000001547007644273432015106 0ustar warmerdausersVenkat, I have completed the planned Shapefile quadtree mechanism. The additions to the traditional Shapelib are found in shptree.c (functions supporting quad tree searching and query). There are also some new prototypes for the tree stuff in shapefil.h ... including some prototypes for functions you don't require and hence that I haven't implemented at this time. I have also prepared a demonstration program using the API. That is the ``shpdumptree'' program, with the source code in shpdumptree.c. The shpdumptree program has two functions. One is to dump an ASCII rendering of the internal quadtree, and the other is example use of a quad tree searching function. Dumping the Tree ---------------- The tree dumping is done as shown below. The "-maxdepth" commandline switch can be used to control the maximum depth, otherwise it internally computes a ``reasonable depth'' to use based on the number of structures in the shapefile. warmerda@gdal[207]% shptreedump -maxdepth 6 eg_data/polygon.shp ( SHPTreeNode Min = (471127.19,4751545.00) Max = (489292.31,4765610.50) Shapes(0): ( SHPTreeNode Min = (471127.19,4751545.00) Max = (481118.01,4765610.50) Shapes(0): ( SHPTreeNode Min = (471127.19,4751545.00) Max = (481118.01,4759281.03) Shapes(0): ( SHPTreeNode Min = (471127.19,4751545.00) Max = (476622.14,4759281.03) Shapes(0): ( SHPTreeNode Min = (471127.19,4751545.00) Max = (476622.14,4755799.81) Shapes(0): ( SHPTreeNode Min = (471127.19,4751545.00) Max = (474149.41,4755799.81) Shapes(6): 395 397 402 404 405 422 ) ( SHPTreeNode Min = (473599.92,4751545.00) Max = (476622.14,4755799.81) Shapes(10): 392 394 403 413 414 417 426 433 434 447 ) ) ... A structure like the following represents one node in the tree. In this case it cover the region of 473599.92 < X < 476622.14,and 4751545.0 < Y < 4755799.81. There are ten shapes within this region who's shapeids are 392, 394 ... 447. This node has no children nodes. ( SHPTreeNode Min = (473599.92,4751545.00) Max = (476622.14,4755799.81) Shapes(10): 392 394 403 413 414 417 426 433 434 447 ) The heirarchy of indentation is intended to show the parent, child relationship between nodes, with the tree being deeper the further to the right you go. The `-v' flag to the program can be used to expand the report to include the full information about shapes, not just their shapeid. This can result in a report looking more like this: ... ( SHPTreeNode Min = (478095.78,4751545.00) Max = (481118.01,4755799.81) Shapes(3): ( Shape ShapeId = 448 Min = (479988.09,4753300.00) Max = (480705.59,4754236.50) Vertex[0] = (480136.59,4754174.50) Vertex[1] = (480229.97,4754182.00) Vertex[2] = (480370.09,4754200.50) Vertex[3] = (480695.12,4754236.50) Vertex[4] = (480687.97,4754129.50) Vertex[5] = (480650.47,4754075.50) Vertex[6] = (480520.62,4753948.00) Vertex[7] = (480490.00,4753900.00) Vertex[8] = (480499.78,4753840.50) Vertex[9] = (480500.97,4753820.50) Vertex[10] = (480534.75,4753660.50) Vertex[11] = (480560.00,4753565.00) Vertex[12] = (480574.91,4753550.50) ... While it is possible to part the output of the shptreedump program, and insert it into your database, my intention was that the shptreedump program would serve as an example of how to pre-order traversal of the quad tree, and collect the information you will need to insert into your database. I would then expect you to write a new program based on shptreedump that calls a C API for your database to insert objects instead of printing them out. Alternatively there may be an ASCII format for loading tables that you could modify the program to output. Searching --------- The other thing that you can do with the shptreedump program is to perform a search on the quadtree. For instance the following shows searching on a small region. % shptreedump -search 471127 4751545 476622 4759281 eg_data/polygon.shp Shape 17: not in area of interest, but fetched. Shape 31: not in area of interest, but fetched. Shape 52: not in area of interest, but fetched. Shape 76: not in area of interest, but fetched. Shape 82: not in area of interest, but fetched. Shape 104: not in area of interest, but fetched. Shape 124: not in area of interest, but fetched. Shape 134: not in area of interest, but fetched. Shape 139: not in area of interest, but fetched. Shape 154: not in area of interest, but fetched. Shape 175: not in area of interest, but fetched. Shape 177: not in area of interest, but fetched. Shape 185: not in area of interest, but fetched. Shape 192: not in area of interest, but fetched. Shape 196: appears to be in area of interest. .... I have included this capability (and the SHPTreeFindLikelyShapes() function) so that you can see a working example of how to search this quad tree. Note that searching is a multi-stage affair. First a pass is made over the quadtree, collecting the shapeids of all shapes contained in a quadtree node for which the bounding rectangle overlaps the search rectangle. This is all accomplished by SHPTreeFindLikelyShapes() in shptree.c. The second phase is to fetch the actual shapes, and verify if their bounding box falls within the area of interest. This is necessary because the shape will tend to have a significantly smaller bounding rectangle than the tree node in which it is found. This can result ``false positives'' on the first phase search, as indicated by teh ``not in area of interest, but fetched'' messages above. This stage is done in the SHPTreeNodeSearchAndDump() function in shptreedump.c. A possible third phase is to verify that the actualy line segments in the shape actually cross the area of interest. I don't both with this as it is complicated, and assuming that the drawing engine takes care of clipping it is quite a bit easier to let it fall through. Building -------- I have added a makefile.vc to the shapelib distribution. After you have unpacked the shapefile you should have a shapelib subdirectory. If you cd to that directory, and enter ``nmake -f makefile.vc'' in a DOS window you should be able to build everything with VC++ (assuming it is properly installed and in your path). You can also create a project in VC just including the files shpopen.c, shptree.c and shptreedump.c, building as a Win32 console application. For your convenience I am including prebuild .obj files, and .exe files in the distribution. ./shapelib-1.2.10/dbf_api.html0100644000076500001440000003513507644273432015542 0ustar warmerdausers Attribute (.DBF) API

Attribute (.DBF) API

The Attribute (DBF) API uses DBFHandle to represent a handle for access to one .dbf file. The contents of the DBFHandle are visible (see shapefil.h) but should be ignored by the application. It is intended that all information be accessed by API functions. Note that there should be exactly one record in the .dbf file for each shape in the .shp/.shx files. This constraint must be maintained by the application.

DBFOpen()

DBFHandle DBFOpen( const char * pszDBFFile, const char * pszAccess );

  pszDBFFile:		The name of the xBase (.dbf) file to access.

  pszAccess:		The fopen() style access string.  At this time only
			"rb" (read-only binary) and "rb+" (read/write binary) 
		        should be used.
The DBFOpen() function should be used to establish access to an existing xBase format table file. The returned DBFHandle is passed to other access functions, and DBFClose() should be invoked to recover resources, and flush changes to disk when complete. The DBFCreate() function should called to create new xBase files. As a convenience, DBFOpen() can be called with the name of a .shp or .shx file, and it will figure out the name of the related .dbf file.

DBFCreate()

DBFHandle DBFCreate( const char * pszDBFFile );

  pszDBFFile:		The name of the xBase (.dbf) file to create.
The DBFCreate() function creates a new xBase format file with the given name, and returns an access handle that can be used with other DBF functions. The newly created file will have no fields, and no records. Fields should be added with DBFAddField() before any records add written.

DBFGetFieldCount()

int DBFGetFieldCount( DBFHandle hDBF );

  hDBF:		The access handle for the file to be queried, as returned
                by DBFOpen(), or DBFCreate().
The DBFGetFieldCount() function returns the number of fields currently defined for the indicated xBase file.

DBFGetRecordCount()

int DBFGetRecordCount( DBFHandle hDBF );

  hDBF:		The access handle for the file to be queried, as returned by
		DBFOpen(), or DBFCreate().
The DBFGetRecordCount() function returns the number of records that exist on the xBase file currently. Note that with shape files one xBase record exists for each shape in the .shp/.shx files.

DBFGetFieldIndex()

int DBFGetFieldIndex( DBFHandle hDBF, const char *pszFieldName );

  hDBF:		The access handle for the file to be queried, as returned by
		DBFOpen(), or DBFCreate().

  pszFieldName: Name of the field to search for.
Returns the index of the field matching this name, or -1 on failure. The comparison is case insensitive. However, lengths must match exactly.

DBFGetFieldInfo()

DBFFieldType DBFGetFieldInfo( DBFHandle hDBF, int iField, char * pszFieldName,
                              int * pnWidth, int * pnDecimals );

  hDBF:		The access handle for the file to be queried, as returned by
		DBFOpen(), or DBFCreate().

  iField:	The field to be queried.  This should be a number between 
                0 and n-1, where n is the number fields on the file, as
                returned by DBFGetFieldCount().

  pszFieldName:	If this pointer is not NULL the name of the requested field
		will be written to this location.  The pszFieldName buffer 
                should be at least 12 character is size in order to hold
		the longest possible field name of 11 characters plus a 
                terminating zero character.

  pnWidth:	If this pointer is not NULL, the width of the requested field
		will be returned in the int pointed to by pnWidth.  This is
                the width in characters.  

  pnDecimals:	If this pointer is not NULL, the number of decimal places
                precision defined for the field will be returned.  This is
                zero for integer fields, or non-numeric fields.
The DBFGetFieldInfo() returns the type of the requested field, which is one of the DBFFieldType enumerated values. As well, the field name, and field width information can optionally be returned. The field type returned does not correspond one to one with the xBase field types. For instance the xBase field type for Date will just be returned as being FTInteger.

    typedef enum {
      FTString,			/* fixed length string field 		*/
      FTInteger,		/* numeric field with no decimals 	*/
      FTDouble,			/* numeric field with decimals 		*/
      FTLogical,		/* logical field.                       */
      FTInvalid                 /* not a recognised field type 		*/
    } DBFFieldType;

DBFAddField()

int DBFAddField( DBFHandle hDBF, const char * pszFieldName, 
                 DBFFieldType eType, int nWidth, int nDecimals );

  hDBF:		The access handle for the file to be updated, as returned by
		DBFOpen(), or DBFCreate().

  pszFieldName:	The name of the new field.  At most 11 character will be used.
                In order to use the xBase file in some packages it may be
                necessary to avoid some special characters in the field names
                such as spaces, or arithmetic operators.

  eType:	One of FTString, FTInteger or FTDouble in order to establish
                the type of the new field.  Note that some valid xBase field
                types cannot be created such as date fields.

  nWidth:	The width of the field to be created.  For FTString fields this
                establishes the maximum length of string that can be stored.
                For FTInteger this establishes the number of digits of the
                largest number that can
                be represented.  For FTDouble fields this in combination
                with the nDecimals value establish the size, and precision
                of the created field.

  nDecimals:    The number of decimal places to reserve for FTDouble fields.
                For all other field types this should be zero.  For instance
                with nWidth=7, and nDecimals=3 numbers would be formatted
                similarly to `123.456'.
The DBFAddField() function is used to add new fields to an existing xBase file opened with DBFOpen(), or created with DBFCreate(). Note that fields can only be added to xBase files with no records, though this is limitation of this API, not of the file format.

The DBFAddField() return value is the field number of the new field, or -1 if the addition of the field failed.

DBFReadIntegerAttribute()

int DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField );
  
  hDBF:		The access handle for the file to be queried, as returned by
		DBFOpen(), or DBFCreate().

  iShape:	The record number (shape number) from which the field value
                should be read.

  iField:	The field within the selected record that should be read.
The DBFReadIntegerAttribute() will read the value of one field and return it as an integer. This can be used even with FTString fields, though the returned value will be zero if not interpretable as a number.

DBFReadDoubleAttribute()

double DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField );
  
  hDBF:		The access handle for the file to be queried, as returned by
		DBFOpen(), or DBFCreate().

  iShape:	The record number (shape number) from which the field value
                should be read.

  iField:	The field within the selected record that should be read.
The DBFReadDoubleAttribute() will read the value of one field and return it as a double. This can be used even with FTString fields, though the returned value will be zero if not interpretable as a number.

DBFReadStringAttribute()

const char *DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
  
  hDBF:		The access handle for the file to be queried, as returned by
		DBFOpen(), or DBFCreate().

  iShape:	The record number (shape number) from which the field value
                should be read.

  iField:	The field within the selected record that should be read.
The DBFReadStringAttribute() will read the value of one field and return it as a string. This function may be used on any field type (including FTInteger and FTDouble) and will return the string representation stored in the .dbf file. The returned pointer is to an internal buffer which is only valid untill the next DBF function call. It's contents may be copied with normal string functions such as strcpy(), or strdup(). If the TRIM_DBF_WHITESPACE macro is defined in shapefil.h (it is by default) then all leading and trailing space (ASCII 32) characters will be stripped before the string is returned.

DBFIsAttributeNULL()

int DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField );
  
  hDBF:		The access handle for the file to be queried, as returned by
		DBFOpen(), or DBFCreate().

  iShape:	The record number (shape number) from which the field value
                should be read.

  iField:	The field within the selected record that should be read.
This function will return TRUE if the indicated field is NULL valued otherwise FALSE. Note that NULL fields are represented in the .dbf file as having all spaces in the field. Reading NULL fields will result in a value of 0.0 or an empty string with the other DBFRead*Attribute() functions.

DBFWriteIntegerAttribute

int DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField,
                              int nFieldValue );

  hDBF:		The access handle for the file to be written, as returned by
		DBFOpen(), or DBFCreate().

  iShape:	The record number (shape number) to which the field value
                should be written.

  iField:	The field within the selected record that should be written.

  nFieldValue:	The integer value that should be written.
The DBFWriteIntegerAttribute() function is used to write a value to a numeric field (FTInteger, or FTDouble). If the write succeeds the value TRUE will be returned, otherwise FALSE will be returned. If the value is too large to fit in the field, it will be truncated and FALSE returned.

DBFWriteDoubleAttribute()

int DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField,
                             double dFieldValue );

  hDBF:		The access handle for the file to be written, as returned by
		DBFOpen(), or DBFCreate().

  iShape:	The record number (shape number) to which the field value
                should be written.

  iField:	The field within the selected record that should be written.

  dFieldValue:	The floating point value that should be written.
The DBFWriteDoubleAttribute() function is used to write a value to a numeric field (FTInteger, or FTDouble). If the write succeeds the value TRUE will be returned, otherwise FALSE will be returned. If the value is too large to fit in the field, it will be truncated and FALSE returned.

DBFWriteStringAttribute()

int DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField,
                             const char * pszFieldValue );

  hDBF:		The access handle for the file to be written, as returned by
		DBFOpen(), or DBFCreate().

  iShape:	The record number (shape number) to which the field value
                should be written.

  iField:	The field within the selected record that should be written.

  pszFieldValue: The string to be written to the field.
The DBFWriteStringAttribute() function is used to write a value to a string field (FString). If the write succeeds the value TRUE willbe returned, otherwise FALSE will be returned. If the value is too large to fit in the field, it will be truncated and FALSE returned.

DBFWriteNULLAttribute()

int DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField );

  hDBF:		The access handle for the file to be written, as returned by
		DBFOpen(), or DBFCreate().

  iShape:	The record number (shape number) to which the field value
                should be written.

  iField:	The field within the selected record that should be written.
The DBFWriteNULLAttribute() function is used to clear the indicated field to a NULL value. In the .dbf file this is represented by setting the entire field to spaces. If the write succeeds the value TRUE willbe returned, otherwise FALSE will be returned.

DBFClose()

void DBFClose( DBFHandle hDBF );

  hDBF:		The access handle for the file to be closed.
The DBFClose() function will close the indicated xBase file (opened with DBFOpen(), or DBFCreate()), flushing out all information to the file on disk, and recovering any resources associated with having the file open. The file handle (hDBF) should not be used again with the DBF API after calling DBFClose().

DBFGetNativeFieldType()

char DBFGetNativeFieldType( DBFHandle hDBF, int iField );

  hDBF:		The access handle for the file.
  iField:       The field index to query.
  
This function returns the DBF type code of the indicated field. It will be one of:

  • 'C' (String)
  • 'D' (Date)
  • 'F' (Float)
  • 'N' (Numeric, with or without decimal)
  • 'L' (Logical)
  • 'M' (Memo: 10 digits .DBT block ptr)
  • ' ' (field out of range)
./shapelib-1.2.10/dbfadd.c0100644000076500001440000001046207644273432014634 0ustar warmerdausers/****************************************************************************** * $Id: dbfadd.c,v 1.7 2002/01/15 14:36:07 warmerda Exp $ * * Project: Shapelib * Purpose: Sample application for adding a record to an existing .dbf file. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: dbfadd.c,v $ * Revision 1.7 2002/01/15 14:36:07 warmerda * updated email address * * Revision 1.6 2001/05/31 18:15:40 warmerda * Added support for NULL fields in DBF files * * Revision 1.5 1999/11/05 14:12:04 warmerda * updated license terms * * Revision 1.4 1998/12/03 16:36:06 warmerda * Added stdlib.h and math.h to get atof() prototype. * * Revision 1.3 1995/10/21 03:13:23 warmerda * Use binary mode.. * * Revision 1.2 1995/08/04 03:15:59 warmerda * Added header. * */ static char rcsid[] = "$Id: dbfadd.c,v 1.7 2002/01/15 14:36:07 warmerda Exp $"; #include "shapefil.h" #include #include int main( int argc, char ** argv ) { DBFHandle hDBF; int i, iRecord; /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc < 3 ) { printf( "dbfadd xbase_file field_values\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Create the database. */ /* -------------------------------------------------------------------- */ hDBF = DBFOpen( argv[1], "r+b" ); if( hDBF == NULL ) { printf( "DBFOpen(%s,\"rb+\") failed.\n", argv[1] ); exit( 2 ); } /* -------------------------------------------------------------------- */ /* Do we have the correct number of arguments? */ /* -------------------------------------------------------------------- */ if( DBFGetFieldCount( hDBF ) != argc - 2 ) { printf( "Got %d fields, but require %d\n", argc - 2, DBFGetFieldCount( hDBF ) ); exit( 3 ); } iRecord = DBFGetRecordCount( hDBF ); /* -------------------------------------------------------------------- */ /* Loop assigning the new field values. */ /* -------------------------------------------------------------------- */ for( i = 0; i < DBFGetFieldCount(hDBF); i++ ) { if( strcmp( argv[i+2], "" ) == 0 ) DBFWriteNULLAttribute(hDBF, iRecord, i ); else if( DBFGetFieldInfo( hDBF, i, NULL, NULL, NULL ) == FTString ) DBFWriteStringAttribute(hDBF, iRecord, i, argv[i+2] ); else DBFWriteDoubleAttribute(hDBF, iRecord, i, atof(argv[i+2]) ); } /* -------------------------------------------------------------------- */ /* Close and cleanup. */ /* -------------------------------------------------------------------- */ DBFClose( hDBF ); return( 0 ); } ./shapelib-1.2.10/dbfcreate.c0100644000076500001440000001002607644273432015343 0ustar warmerdausers/****************************************************************************** * $Id: dbfcreate.c,v 1.6 2002/01/15 14:36:07 warmerda Exp $ * * Project: Shapelib * Purpose: Sample application for creating a new .dbf file. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: dbfcreate.c,v $ * Revision 1.6 2002/01/15 14:36:07 warmerda * updated email address * * Revision 1.5 2000/07/07 13:39:45 warmerda * removed unused variables, and added system include files * * Revision 1.4 1999/11/05 14:12:04 warmerda * updated license terms * * Revision 1.3 1999/04/01 18:47:44 warmerda * Fixed DBFAddField() call convention. * * Revision 1.2 1995/08/04 03:17:11 warmerda * Added header. * */ static char rcsid[] = "$Id: dbfcreate.c,v 1.6 2002/01/15 14:36:07 warmerda Exp $"; #include #include #include "shapefil.h" int main( int argc, char ** argv ) { DBFHandle hDBF; int i; /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc < 2 ) { printf( "dbfcreate xbase_file [[-s field_name width],[-n field_name width decimals]]...\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Create the database. */ /* -------------------------------------------------------------------- */ hDBF = DBFCreate( argv[1] ); if( hDBF == NULL ) { printf( "DBFCreate(%s) failed.\n", argv[1] ); exit( 2 ); } /* -------------------------------------------------------------------- */ /* Loop over the field definitions adding new fields. */ /* -------------------------------------------------------------------- */ for( i = 2; i < argc; i++ ) { if( strcmp(argv[i],"-s") == 0 && i < argc-2 ) { if( DBFAddField( hDBF, argv[i+1], FTString, atoi(argv[i+2]), 0 ) == -1 ) { printf( "DBFAddField(%s,FTString,%d,0) failed.\n", argv[i+1], atoi(argv[i+2]) ); exit( 4 ); } i = i + 2; } else if( strcmp(argv[i],"-n") == 0 && i < argc-3 ) { if( DBFAddField( hDBF, argv[i+1], FTDouble, atoi(argv[i+2]), atoi(argv[i+3]) ) == -1 ) { printf( "DBFAddField(%s,FTDouble,%d,%d) failed.\n", argv[i+1], atoi(argv[i+2]), atoi(argv[i+3]) ); exit( 4 ); } i = i + 3; } else { printf( "Argument incomplete, or unrecognised:%s\n", argv[i] ); exit( 3 ); } } DBFClose( hDBF ); return( 0 ); } ./shapelib-1.2.10/dbfdump.c0100644000076500001440000002307307644273432015053 0ustar warmerdausers/****************************************************************************** * $Id: dbfdump.c,v 1.9 2002/01/15 14:36:07 warmerda Exp $ * * Project: Shapelib * Purpose: Sample application for dumping .dbf files to the terminal. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: dbfdump.c,v $ * Revision 1.9 2002/01/15 14:36:07 warmerda * updated email address * * Revision 1.8 2001/05/31 18:15:40 warmerda * Added support for NULL fields in DBF files * * Revision 1.7 2000/09/20 13:13:55 warmerda * added break after default: * * Revision 1.6 2000/07/07 13:39:45 warmerda * removed unused variables, and added system include files * * Revision 1.5 1999/11/05 14:12:04 warmerda * updated license terms * * Revision 1.4 1998/12/31 15:30:13 warmerda * Added -m, -r, and -h commandline options. * * Revision 1.3 1995/10/21 03:15:01 warmerda * Changed to use binary file access. * * Revision 1.2 1995/08/04 03:16:22 warmerda * Added header. * */ static char rcsid[] = "$Id: dbfdump.c,v 1.9 2002/01/15 14:36:07 warmerda Exp $"; #include #include #include "shapefil.h" int main( int argc, char ** argv ) { DBFHandle hDBF; int *panWidth, i, iRecord; char szFormat[32], *pszFilename = NULL; int nWidth, nDecimals; int bHeader = 0; int bRaw = 0; int bMultiLine = 0; char szTitle[12]; /* -------------------------------------------------------------------- */ /* Handle arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if( strcmp(argv[i],"-h") == 0 ) bHeader = 1; else if( strcmp(argv[i],"-r") == 0 ) bRaw = 1; else if( strcmp(argv[i],"-m") == 0 ) bMultiLine = 1; else pszFilename = argv[i]; } /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( pszFilename == NULL ) { printf( "dbfdump [-h] [-r] [-m] xbase_file\n" ); printf( " -h: Write header info (field descriptions)\n" ); printf( " -r: Write raw field info, numeric values not reformatted\n" ); printf( " -m: Multiline, one line per field.\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ hDBF = DBFOpen( pszFilename, "rb" ); if( hDBF == NULL ) { printf( "DBFOpen(%s,\"r\") failed.\n", argv[1] ); exit( 2 ); } /* -------------------------------------------------------------------- */ /* If there is no data in this file let the user know. */ /* -------------------------------------------------------------------- */ if( DBFGetFieldCount(hDBF) == 0 ) { printf( "There are no fields in this table!\n" ); exit( 3 ); } /* -------------------------------------------------------------------- */ /* Dump header definitions. */ /* -------------------------------------------------------------------- */ if( bHeader ) { for( i = 0; i < DBFGetFieldCount(hDBF); i++ ) { DBFFieldType eType; const char *pszTypeName; eType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals ); if( eType == FTString ) pszTypeName = "String"; else if( eType == FTInteger ) pszTypeName = "Integer"; else if( eType == FTDouble ) pszTypeName = "Double"; else if( eType == FTInvalid ) pszTypeName = "Invalid"; printf( "Field %d: Type=%s, Title=`%s', Width=%d, Decimals=%d\n", i, pszTypeName, szTitle, nWidth, nDecimals ); } } /* -------------------------------------------------------------------- */ /* Compute offsets to use when printing each of the field */ /* values. We make each field as wide as the field title+1, or */ /* the field value + 1. */ /* -------------------------------------------------------------------- */ panWidth = (int *) malloc( DBFGetFieldCount( hDBF ) * sizeof(int) ); for( i = 0; i < DBFGetFieldCount(hDBF) && !bMultiLine; i++ ) { DBFFieldType eType; eType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals ); if( strlen(szTitle) > nWidth ) panWidth[i] = strlen(szTitle); else panWidth[i] = nWidth; if( eType == FTString ) sprintf( szFormat, "%%-%ds ", panWidth[i] ); else sprintf( szFormat, "%%%ds ", panWidth[i] ); printf( szFormat, szTitle ); } printf( "\n" ); /* -------------------------------------------------------------------- */ /* Read all the records */ /* -------------------------------------------------------------------- */ for( iRecord = 0; iRecord < DBFGetRecordCount(hDBF); iRecord++ ) { if( bMultiLine ) printf( "Record: %d\n", iRecord ); for( i = 0; i < DBFGetFieldCount(hDBF); i++ ) { DBFFieldType eType; eType = DBFGetFieldInfo( hDBF, i, szTitle, &nWidth, &nDecimals ); if( bMultiLine ) { printf( "%s: ", szTitle ); } /* -------------------------------------------------------------------- */ /* Print the record according to the type and formatting */ /* information implicit in the DBF field description. */ /* -------------------------------------------------------------------- */ if( !bRaw ) { if( DBFIsAttributeNULL( hDBF, iRecord, i ) ) { if( eType == FTString ) sprintf( szFormat, "%%-%ds", nWidth ); else sprintf( szFormat, "%%%ds", nWidth ); printf( szFormat, "(NULL)" ); } else { switch( eType ) { case FTString: sprintf( szFormat, "%%-%ds", nWidth ); printf( szFormat, DBFReadStringAttribute( hDBF, iRecord, i ) ); break; case FTInteger: sprintf( szFormat, "%%%dd", nWidth ); printf( szFormat, DBFReadIntegerAttribute( hDBF, iRecord, i ) ); break; case FTDouble: sprintf( szFormat, "%%%d.%dlf", nWidth, nDecimals ); printf( szFormat, DBFReadDoubleAttribute( hDBF, iRecord, i ) ); break; default: break; } } } /* -------------------------------------------------------------------- */ /* Just dump in raw form (as formatted in the file). */ /* -------------------------------------------------------------------- */ else { sprintf( szFormat, "%%-%ds", nWidth ); printf( szFormat, DBFReadStringAttribute( hDBF, iRecord, i ) ); } /* -------------------------------------------------------------------- */ /* Write out any extra spaces required to pad out the field */ /* width. */ /* -------------------------------------------------------------------- */ if( !bMultiLine ) { sprintf( szFormat, "%%%ds", panWidth[i] - nWidth + 1 ); printf( szFormat, "" ); } if( bMultiLine ) printf( "\n" ); fflush( stdout ); } printf( "\n" ); } DBFClose( hDBF ); return( 0 ); } ./shapelib-1.2.10/dbfopen.c0100644000076500001440000014550107644273432015050 0ustar warmerdausers/****************************************************************************** * $Id: dbfopen.c,v 1.48 2003/03/10 14:51:27 warmerda Exp $ * * Project: Shapelib * Purpose: Implementation of .dbf access API documented in dbf_api.html. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: dbfopen.c,v $ * Revision 1.48 2003/03/10 14:51:27 warmerda * DBFWrite* calls now return FALSE if they have to truncate * * Revision 1.47 2002/11/20 03:32:22 warmerda * Ensure field name in DBFGetFieldIndex() is properly terminated. * * Revision 1.46 2002/10/09 13:10:21 warmerda * Added check that width is positive. * * Revision 1.45 2002/09/29 00:00:08 warmerda * added FTLogical and logical attribute read/write calls * * Revision 1.44 2002/05/07 13:46:11 warmerda * Added DBFWriteAttributeDirectly(). * * Revision 1.43 2002/02/13 19:39:21 warmerda * Fix casting issues in DBFCloneEmpty(). * * Revision 1.42 2002/01/15 14:36:07 warmerda * updated email address * * Revision 1.41 2002/01/15 14:31:49 warmerda * compute rather than copying nHeaderLength in DBFCloneEmpty() * * Revision 1.40 2002/01/09 04:32:35 warmerda * fixed to read correct amount of header * * Revision 1.39 2001/12/11 22:41:03 warmerda * improve io related error checking when reading header * * Revision 1.38 2001/11/28 16:07:31 warmerda * Cleanup to avoid compiler warnings as suggested by Richard Hash. * * Revision 1.37 2001/07/04 05:18:09 warmerda * do last fix properly * * Revision 1.36 2001/07/04 05:16:09 warmerda * fixed fieldname comparison in DBFGetFieldIndex * * Revision 1.35 2001/06/22 02:10:06 warmerda * fixed NULL shape support with help from Jim Matthews * * Revision 1.33 2001/05/31 19:20:13 warmerda * added DBFGetFieldIndex() * * Revision 1.32 2001/05/31 18:15:40 warmerda * Added support for NULL fields in DBF files * * Revision 1.31 2001/05/23 13:36:52 warmerda * added use of SHPAPI_CALL * * Revision 1.30 2000/12/05 14:43:38 warmerda * DBReadAttribute() white space trimming bug fix * * Revision 1.29 2000/10/05 14:36:44 warmerda * fix bug with writing very wide numeric fields * * Revision 1.28 2000/09/25 14:18:07 warmerda * Added some casts of strlen() return result to fix warnings on some * systems, as submitted by Daniel. * * Revision 1.27 2000/09/25 14:15:51 warmerda * added DBFGetNativeFieldType() * * Revision 1.26 2000/07/07 13:39:45 warmerda * removed unused variables, and added system include files * * Revision 1.25 2000/05/29 18:19:13 warmerda * avoid use of uchar, and adding casting fix * * Revision 1.24 2000/05/23 13:38:27 warmerda * Added error checks on return results of fread() and fseek(). * * Revision 1.23 2000/05/23 13:25:49 warmerda * Avoid crashing if field or record are out of range in dbfread*attribute(). * * Revision 1.22 1999/12/15 13:47:24 warmerda * Added stdlib.h to ensure that atof() is prototyped. * * Revision 1.21 1999/12/13 17:25:46 warmerda * Added support for upper case .DBF extention. * * Revision 1.20 1999/11/30 16:32:11 warmerda * Use atof() instead of sscanf(). * * Revision 1.19 1999/11/05 14:12:04 warmerda * updated license terms * * Revision 1.18 1999/07/27 00:53:28 warmerda * ensure that whole old field value clear on write of string * * Revision 1.1 1999/07/05 18:58:07 warmerda * New * * Revision 1.17 1999/06/11 19:14:12 warmerda * Fixed some memory leaks. * * Revision 1.16 1999/06/11 19:04:11 warmerda * Remoted some unused variables. * * Revision 1.15 1999/05/11 03:19:28 warmerda * added new Tuple api, and improved extension handling - add from candrsn * * Revision 1.14 1999/05/04 15:01:48 warmerda * Added 'F' support. * * Revision 1.13 1999/03/23 17:38:59 warmerda * DBFAddField() now actually does return the new field number, or -1 if * it fails. * * Revision 1.12 1999/03/06 02:54:46 warmerda * Added logic to convert shapefile name to dbf filename in DBFOpen() * for convenience. * * Revision 1.11 1998/12/31 15:30:34 warmerda * Improved the interchangability of numeric and string attributes. Add * white space trimming option for attributes. * * Revision 1.10 1998/12/03 16:36:44 warmerda * Use r+b instead of rb+ for binary access. * * Revision 1.9 1998/12/03 15:34:23 warmerda * Updated copyright message. * * Revision 1.8 1997/12/04 15:40:15 warmerda * Added newline character after field definitions. * * Revision 1.7 1997/03/06 14:02:10 warmerda * Ensure bUpdated is initialized. * * Revision 1.6 1996/02/12 04:54:41 warmerda * Ensure that DBFWriteAttribute() returns TRUE if it succeeds. * * Revision 1.5 1995/10/21 03:15:12 warmerda * Changed to use binary file access, and ensure that the * field name field is zero filled, and limited to 10 chars. * * Revision 1.4 1995/08/24 18:10:42 warmerda * Added use of SfRealloc() to avoid pre-ANSI realloc() functions such * as on the Sun. * * Revision 1.3 1995/08/04 03:15:16 warmerda * Fixed up header. * * Revision 1.2 1995/08/04 03:14:43 warmerda * Added header. */ static char rcsid[] = "$Id: dbfopen.c,v 1.48 2003/03/10 14:51:27 warmerda Exp $"; #include "shapefil.h" #include #include #include #include #ifndef FALSE # define FALSE 0 # define TRUE 1 #endif static int nStringFieldLen = 0; static char * pszStringField = NULL; /************************************************************************/ /* SfRealloc() */ /* */ /* A realloc cover function that will access a NULL pointer as */ /* a valid input. */ /************************************************************************/ static void * SfRealloc( void * pMem, int nNewSize ) { if( pMem == NULL ) return( (void *) malloc(nNewSize) ); else return( (void *) realloc(pMem,nNewSize) ); } /************************************************************************/ /* DBFWriteHeader() */ /* */ /* This is called to write out the file header, and field */ /* descriptions before writing any actual data records. This */ /* also computes all the DBFDataSet field offset/size/decimals */ /* and so forth values. */ /************************************************************************/ static void DBFWriteHeader(DBFHandle psDBF) { unsigned char abyHeader[XBASE_FLDHDR_SZ]; int i; if( !psDBF->bNoHeader ) return; psDBF->bNoHeader = FALSE; /* -------------------------------------------------------------------- */ /* Initialize the file header information. */ /* -------------------------------------------------------------------- */ for( i = 0; i < XBASE_FLDHDR_SZ; i++ ) abyHeader[i] = 0; abyHeader[0] = 0x03; /* memo field? - just copying */ /* date updated on close, record count preset at zero */ abyHeader[8] = psDBF->nHeaderLength % 256; abyHeader[9] = psDBF->nHeaderLength / 256; abyHeader[10] = psDBF->nRecordLength % 256; abyHeader[11] = psDBF->nRecordLength / 256; /* -------------------------------------------------------------------- */ /* Write the initial 32 byte file header, and all the field */ /* descriptions. */ /* -------------------------------------------------------------------- */ fseek( psDBF->fp, 0, 0 ); fwrite( abyHeader, XBASE_FLDHDR_SZ, 1, psDBF->fp ); fwrite( psDBF->pszHeader, XBASE_FLDHDR_SZ, psDBF->nFields, psDBF->fp ); /* -------------------------------------------------------------------- */ /* Write out the newline character if there is room for it. */ /* -------------------------------------------------------------------- */ if( psDBF->nHeaderLength > 32*psDBF->nFields + 32 ) { char cNewline; cNewline = 0x0d; fwrite( &cNewline, 1, 1, psDBF->fp ); } } /************************************************************************/ /* DBFFlushRecord() */ /* */ /* Write out the current record if there is one. */ /************************************************************************/ static void DBFFlushRecord( DBFHandle psDBF ) { int nRecordOffset; if( psDBF->bCurrentRecordModified && psDBF->nCurrentRecord > -1 ) { psDBF->bCurrentRecordModified = FALSE; nRecordOffset = psDBF->nRecordLength * psDBF->nCurrentRecord + psDBF->nHeaderLength; fseek( psDBF->fp, nRecordOffset, 0 ); fwrite( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); } } /************************************************************************/ /* DBFOpen() */ /* */ /* Open a .dbf file. */ /************************************************************************/ DBFHandle SHPAPI_CALL DBFOpen( const char * pszFilename, const char * pszAccess ) { DBFHandle psDBF; unsigned char *pabyBuf; int nFields, nHeadLen, nRecLen, iField, i; char *pszBasename, *pszFullname; /* -------------------------------------------------------------------- */ /* We only allow the access strings "rb" and "r+". */ /* -------------------------------------------------------------------- */ if( strcmp(pszAccess,"r") != 0 && strcmp(pszAccess,"r+") != 0 && strcmp(pszAccess,"rb") != 0 && strcmp(pszAccess,"rb+") != 0 && strcmp(pszAccess,"r+b") != 0 ) return( NULL ); if( strcmp(pszAccess,"r") == 0 ) pszAccess = "rb"; if( strcmp(pszAccess,"r+") == 0 ) pszAccess = "rb+"; /* -------------------------------------------------------------------- */ /* Compute the base (layer) name. If there is any extension */ /* on the passed in filename we will strip it off. */ /* -------------------------------------------------------------------- */ pszBasename = (char *) malloc(strlen(pszFilename)+5); strcpy( pszBasename, pszFilename ); for( i = strlen(pszBasename)-1; i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' && pszBasename[i] != '\\'; i-- ) {} if( pszBasename[i] == '.' ) pszBasename[i] = '\0'; pszFullname = (char *) malloc(strlen(pszBasename) + 5); sprintf( pszFullname, "%s.dbf", pszBasename ); psDBF = (DBFHandle) calloc( 1, sizeof(DBFInfo) ); psDBF->fp = fopen( pszFullname, pszAccess ); if( psDBF->fp == NULL ) { sprintf( pszFullname, "%s.DBF", pszBasename ); psDBF->fp = fopen(pszFullname, pszAccess ); } free( pszBasename ); free( pszFullname ); if( psDBF->fp == NULL ) { free( psDBF ); return( NULL ); } psDBF->bNoHeader = FALSE; psDBF->nCurrentRecord = -1; psDBF->bCurrentRecordModified = FALSE; /* -------------------------------------------------------------------- */ /* Read Table Header info */ /* -------------------------------------------------------------------- */ pabyBuf = (unsigned char *) malloc(500); if( fread( pabyBuf, 32, 1, psDBF->fp ) != 1 ) { fclose( psDBF->fp ); free( pabyBuf ); free( psDBF ); return NULL; } psDBF->nRecords = pabyBuf[4] + pabyBuf[5]*256 + pabyBuf[6]*256*256 + pabyBuf[7]*256*256*256; psDBF->nHeaderLength = nHeadLen = pabyBuf[8] + pabyBuf[9]*256; psDBF->nRecordLength = nRecLen = pabyBuf[10] + pabyBuf[11]*256; psDBF->nFields = nFields = (nHeadLen - 32) / 32; psDBF->pszCurrentRecord = (char *) malloc(nRecLen); /* -------------------------------------------------------------------- */ /* Read in Field Definitions */ /* -------------------------------------------------------------------- */ pabyBuf = (unsigned char *) SfRealloc(pabyBuf,nHeadLen); psDBF->pszHeader = (char *) pabyBuf; fseek( psDBF->fp, 32, 0 ); if( fread( pabyBuf, nHeadLen-32, 1, psDBF->fp ) != 1 ) { fclose( psDBF->fp ); free( pabyBuf ); free( psDBF ); return NULL; } psDBF->panFieldOffset = (int *) malloc(sizeof(int) * nFields); psDBF->panFieldSize = (int *) malloc(sizeof(int) * nFields); psDBF->panFieldDecimals = (int *) malloc(sizeof(int) * nFields); psDBF->pachFieldType = (char *) malloc(sizeof(char) * nFields); for( iField = 0; iField < nFields; iField++ ) { unsigned char *pabyFInfo; pabyFInfo = pabyBuf+iField*32; if( pabyFInfo[11] == 'N' || pabyFInfo[11] == 'F' ) { psDBF->panFieldSize[iField] = pabyFInfo[16]; psDBF->panFieldDecimals[iField] = pabyFInfo[17]; } else { psDBF->panFieldSize[iField] = pabyFInfo[16] + pabyFInfo[17]*256; psDBF->panFieldDecimals[iField] = 0; } psDBF->pachFieldType[iField] = (char) pabyFInfo[11]; if( iField == 0 ) psDBF->panFieldOffset[iField] = 1; else psDBF->panFieldOffset[iField] = psDBF->panFieldOffset[iField-1] + psDBF->panFieldSize[iField-1]; } return( psDBF ); } /************************************************************************/ /* DBFClose() */ /************************************************************************/ void SHPAPI_CALL DBFClose(DBFHandle psDBF) { /* -------------------------------------------------------------------- */ /* Write out header if not already written. */ /* -------------------------------------------------------------------- */ if( psDBF->bNoHeader ) DBFWriteHeader( psDBF ); DBFFlushRecord( psDBF ); /* -------------------------------------------------------------------- */ /* Update last access date, and number of records if we have */ /* write access. */ /* -------------------------------------------------------------------- */ if( psDBF->bUpdated ) { unsigned char abyFileHeader[32]; fseek( psDBF->fp, 0, 0 ); fread( abyFileHeader, 32, 1, psDBF->fp ); abyFileHeader[1] = 95; /* YY */ abyFileHeader[2] = 7; /* MM */ abyFileHeader[3] = 26; /* DD */ abyFileHeader[4] = psDBF->nRecords % 256; abyFileHeader[5] = (psDBF->nRecords/256) % 256; abyFileHeader[6] = (psDBF->nRecords/(256*256)) % 256; abyFileHeader[7] = (psDBF->nRecords/(256*256*256)) % 256; fseek( psDBF->fp, 0, 0 ); fwrite( abyFileHeader, 32, 1, psDBF->fp ); } /* -------------------------------------------------------------------- */ /* Close, and free resources. */ /* -------------------------------------------------------------------- */ fclose( psDBF->fp ); if( psDBF->panFieldOffset != NULL ) { free( psDBF->panFieldOffset ); free( psDBF->panFieldSize ); free( psDBF->panFieldDecimals ); free( psDBF->pachFieldType ); } free( psDBF->pszHeader ); free( psDBF->pszCurrentRecord ); free( psDBF ); if( pszStringField != NULL ) { free( pszStringField ); pszStringField = NULL; nStringFieldLen = 0; } } /************************************************************************/ /* DBFCreate() */ /* */ /* Create a new .dbf file. */ /************************************************************************/ DBFHandle SHPAPI_CALL DBFCreate( const char * pszFilename ) { DBFHandle psDBF; FILE *fp; char *pszFullname, *pszBasename; int i; /* -------------------------------------------------------------------- */ /* Compute the base (layer) name. If there is any extension */ /* on the passed in filename we will strip it off. */ /* -------------------------------------------------------------------- */ pszBasename = (char *) malloc(strlen(pszFilename)+5); strcpy( pszBasename, pszFilename ); for( i = strlen(pszBasename)-1; i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' && pszBasename[i] != '\\'; i-- ) {} if( pszBasename[i] == '.' ) pszBasename[i] = '\0'; pszFullname = (char *) malloc(strlen(pszBasename) + 5); sprintf( pszFullname, "%s.dbf", pszBasename ); free( pszBasename ); /* -------------------------------------------------------------------- */ /* Create the file. */ /* -------------------------------------------------------------------- */ fp = fopen( pszFullname, "wb" ); if( fp == NULL ) return( NULL ); fputc( 0, fp ); fclose( fp ); fp = fopen( pszFullname, "rb+" ); if( fp == NULL ) return( NULL ); free( pszFullname ); /* -------------------------------------------------------------------- */ /* Create the info structure. */ /* -------------------------------------------------------------------- */ psDBF = (DBFHandle) malloc(sizeof(DBFInfo)); psDBF->fp = fp; psDBF->nRecords = 0; psDBF->nFields = 0; psDBF->nRecordLength = 1; psDBF->nHeaderLength = 33; psDBF->panFieldOffset = NULL; psDBF->panFieldSize = NULL; psDBF->panFieldDecimals = NULL; psDBF->pachFieldType = NULL; psDBF->pszHeader = NULL; psDBF->nCurrentRecord = -1; psDBF->bCurrentRecordModified = FALSE; psDBF->pszCurrentRecord = NULL; psDBF->bNoHeader = TRUE; return( psDBF ); } /************************************************************************/ /* DBFAddField() */ /* */ /* Add a field to a newly created .dbf file before any records */ /* are written. */ /************************************************************************/ int SHPAPI_CALL DBFAddField(DBFHandle psDBF, const char * pszFieldName, DBFFieldType eType, int nWidth, int nDecimals ) { char *pszFInfo; int i; /* -------------------------------------------------------------------- */ /* Do some checking to ensure we can add records to this file. */ /* -------------------------------------------------------------------- */ if( psDBF->nRecords > 0 ) return( -1 ); if( !psDBF->bNoHeader ) return( -1 ); if( eType != FTDouble && nDecimals != 0 ) return( -1 ); if( nWidth < 1 ) return -1; /* -------------------------------------------------------------------- */ /* SfRealloc all the arrays larger to hold the additional field */ /* information. */ /* -------------------------------------------------------------------- */ psDBF->nFields++; psDBF->panFieldOffset = (int *) SfRealloc( psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ); psDBF->panFieldSize = (int *) SfRealloc( psDBF->panFieldSize, sizeof(int) * psDBF->nFields ); psDBF->panFieldDecimals = (int *) SfRealloc( psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ); psDBF->pachFieldType = (char *) SfRealloc( psDBF->pachFieldType, sizeof(char) * psDBF->nFields ); /* -------------------------------------------------------------------- */ /* Assign the new field information fields. */ /* -------------------------------------------------------------------- */ psDBF->panFieldOffset[psDBF->nFields-1] = psDBF->nRecordLength; psDBF->nRecordLength += nWidth; psDBF->panFieldSize[psDBF->nFields-1] = nWidth; psDBF->panFieldDecimals[psDBF->nFields-1] = nDecimals; if( eType == FTLogical ) psDBF->pachFieldType[psDBF->nFields-1] = 'L'; else if( eType == FTString ) psDBF->pachFieldType[psDBF->nFields-1] = 'C'; else psDBF->pachFieldType[psDBF->nFields-1] = 'N'; /* -------------------------------------------------------------------- */ /* Extend the required header information. */ /* -------------------------------------------------------------------- */ psDBF->nHeaderLength += 32; psDBF->bUpdated = FALSE; psDBF->pszHeader = (char *) SfRealloc(psDBF->pszHeader,psDBF->nFields*32); pszFInfo = psDBF->pszHeader + 32 * (psDBF->nFields-1); for( i = 0; i < 32; i++ ) pszFInfo[i] = '\0'; if( (int) strlen(pszFieldName) < 10 ) strncpy( pszFInfo, pszFieldName, strlen(pszFieldName)); else strncpy( pszFInfo, pszFieldName, 10); pszFInfo[11] = psDBF->pachFieldType[psDBF->nFields-1]; if( eType == FTString ) { pszFInfo[16] = nWidth % 256; pszFInfo[17] = nWidth / 256; } else { pszFInfo[16] = nWidth; pszFInfo[17] = nDecimals; } /* -------------------------------------------------------------------- */ /* Make the current record buffer appropriately larger. */ /* -------------------------------------------------------------------- */ psDBF->pszCurrentRecord = (char *) SfRealloc(psDBF->pszCurrentRecord, psDBF->nRecordLength); return( psDBF->nFields-1 ); } /************************************************************************/ /* DBFReadAttribute() */ /* */ /* Read one of the attribute fields of a record. */ /************************************************************************/ static void *DBFReadAttribute(DBFHandle psDBF, int hEntity, int iField, char chReqType ) { int nRecordOffset; unsigned char *pabyRec; void *pReturnField = NULL; static double dDoubleField; /* -------------------------------------------------------------------- */ /* Verify selection. */ /* -------------------------------------------------------------------- */ if( hEntity < 0 || hEntity >= psDBF->nRecords ) return( NULL ); if( iField < 0 || iField >= psDBF->nFields ) return( NULL ); /* -------------------------------------------------------------------- */ /* Have we read the record? */ /* -------------------------------------------------------------------- */ if( psDBF->nCurrentRecord != hEntity ) { DBFFlushRecord( psDBF ); nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; if( fseek( psDBF->fp, nRecordOffset, 0 ) != 0 ) { fprintf( stderr, "fseek(%d) failed on DBF file.\n", nRecordOffset ); return NULL; } if( fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ) != 1 ) { fprintf( stderr, "fread(%d) failed on DBF file.\n", psDBF->nRecordLength ); return NULL; } psDBF->nCurrentRecord = hEntity; } pabyRec = (unsigned char *) psDBF->pszCurrentRecord; /* -------------------------------------------------------------------- */ /* Ensure our field buffer is large enough to hold this buffer. */ /* -------------------------------------------------------------------- */ if( psDBF->panFieldSize[iField]+1 > nStringFieldLen ) { nStringFieldLen = psDBF->panFieldSize[iField]*2 + 10; pszStringField = (char *) SfRealloc(pszStringField,nStringFieldLen); } /* -------------------------------------------------------------------- */ /* Extract the requested field. */ /* -------------------------------------------------------------------- */ strncpy( pszStringField, ((const char *) pabyRec) + psDBF->panFieldOffset[iField], psDBF->panFieldSize[iField] ); pszStringField[psDBF->panFieldSize[iField]] = '\0'; pReturnField = pszStringField; /* -------------------------------------------------------------------- */ /* Decode the field. */ /* -------------------------------------------------------------------- */ if( chReqType == 'N' ) { dDoubleField = atof(pszStringField); pReturnField = &dDoubleField; } /* -------------------------------------------------------------------- */ /* Should we trim white space off the string attribute value? */ /* -------------------------------------------------------------------- */ #ifdef TRIM_DBF_WHITESPACE else { char *pchSrc, *pchDst; pchDst = pchSrc = pszStringField; while( *pchSrc == ' ' ) pchSrc++; while( *pchSrc != '\0' ) *(pchDst++) = *(pchSrc++); *pchDst = '\0'; while( pchDst != pszStringField && *(--pchDst) == ' ' ) *pchDst = '\0'; } #endif return( pReturnField ); } /************************************************************************/ /* DBFReadIntAttribute() */ /* */ /* Read an integer attribute. */ /************************************************************************/ int SHPAPI_CALL DBFReadIntegerAttribute( DBFHandle psDBF, int iRecord, int iField ) { double *pdValue; pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' ); if( pdValue == NULL ) return 0; else return( (int) *pdValue ); } /************************************************************************/ /* DBFReadDoubleAttribute() */ /* */ /* Read a double attribute. */ /************************************************************************/ double SHPAPI_CALL DBFReadDoubleAttribute( DBFHandle psDBF, int iRecord, int iField ) { double *pdValue; pdValue = (double *) DBFReadAttribute( psDBF, iRecord, iField, 'N' ); if( pdValue == NULL ) return 0.0; else return( *pdValue ); } /************************************************************************/ /* DBFReadStringAttribute() */ /* */ /* Read a string attribute. */ /************************************************************************/ const char SHPAPI_CALL1(*) DBFReadStringAttribute( DBFHandle psDBF, int iRecord, int iField ) { return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'C' ) ); } /************************************************************************/ /* DBFReadLogicalAttribute() */ /* */ /* Read a logical attribute. */ /************************************************************************/ const char SHPAPI_CALL1(*) DBFReadLogicalAttribute( DBFHandle psDBF, int iRecord, int iField ) { return( (const char *) DBFReadAttribute( psDBF, iRecord, iField, 'L' ) ); } /************************************************************************/ /* DBFIsAttributeNULL() */ /* */ /* Return TRUE if value for field is NULL. */ /* */ /* Contributed by Jim Matthews. */ /************************************************************************/ int SHPAPI_CALL DBFIsAttributeNULL( DBFHandle psDBF, int iRecord, int iField ) { const char *pszValue; pszValue = DBFReadStringAttribute( psDBF, iRecord, iField ); switch(psDBF->pachFieldType[iField]) { case 'N': case 'F': /* NULL numeric fields have value "****************" */ return pszValue[0] == '*'; case 'D': /* NULL date fields have value "00000000" */ return strncmp(pszValue,"00000000",8) == 0; case 'L': /* NULL boolean fields have value "?" */ return pszValue[0] == '?'; default: /* empty string fields are considered NULL */ return strlen(pszValue) == 0; } } /************************************************************************/ /* DBFGetFieldCount() */ /* */ /* Return the number of fields in this table. */ /************************************************************************/ int SHPAPI_CALL DBFGetFieldCount( DBFHandle psDBF ) { return( psDBF->nFields ); } /************************************************************************/ /* DBFGetRecordCount() */ /* */ /* Return the number of records in this table. */ /************************************************************************/ int SHPAPI_CALL DBFGetRecordCount( DBFHandle psDBF ) { return( psDBF->nRecords ); } /************************************************************************/ /* DBFGetFieldInfo() */ /* */ /* Return any requested information about the field. */ /************************************************************************/ DBFFieldType SHPAPI_CALL DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName, int * pnWidth, int * pnDecimals ) { if( iField < 0 || iField >= psDBF->nFields ) return( FTInvalid ); if( pnWidth != NULL ) *pnWidth = psDBF->panFieldSize[iField]; if( pnDecimals != NULL ) *pnDecimals = psDBF->panFieldDecimals[iField]; if( pszFieldName != NULL ) { int i; strncpy( pszFieldName, (char *) psDBF->pszHeader+iField*32, 11 ); pszFieldName[11] = '\0'; for( i = 10; i > 0 && pszFieldName[i] == ' '; i-- ) pszFieldName[i] = '\0'; } if ( psDBF->pachFieldType[iField] == 'L' ) return( FTLogical); else if( psDBF->pachFieldType[iField] == 'N' || psDBF->pachFieldType[iField] == 'F' || psDBF->pachFieldType[iField] == 'D' ) { if( psDBF->panFieldDecimals[iField] > 0 ) return( FTDouble ); else return( FTInteger ); } else { return( FTString ); } } /************************************************************************/ /* DBFWriteAttribute() */ /* */ /* Write an attribute record to the file. */ /************************************************************************/ static int DBFWriteAttribute(DBFHandle psDBF, int hEntity, int iField, void * pValue ) { int nRecordOffset, i, j, nRetResult = TRUE; unsigned char *pabyRec; char szSField[400], szFormat[20]; /* -------------------------------------------------------------------- */ /* Is this a valid record? */ /* -------------------------------------------------------------------- */ if( hEntity < 0 || hEntity > psDBF->nRecords ) return( FALSE ); if( psDBF->bNoHeader ) DBFWriteHeader(psDBF); /* -------------------------------------------------------------------- */ /* Is this a brand new record? */ /* -------------------------------------------------------------------- */ if( hEntity == psDBF->nRecords ) { DBFFlushRecord( psDBF ); psDBF->nRecords++; for( i = 0; i < psDBF->nRecordLength; i++ ) psDBF->pszCurrentRecord[i] = ' '; psDBF->nCurrentRecord = hEntity; } /* -------------------------------------------------------------------- */ /* Is this an existing record, but different than the last one */ /* we accessed? */ /* -------------------------------------------------------------------- */ if( psDBF->nCurrentRecord != hEntity ) { DBFFlushRecord( psDBF ); nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; fseek( psDBF->fp, nRecordOffset, 0 ); fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); psDBF->nCurrentRecord = hEntity; } pabyRec = (unsigned char *) psDBF->pszCurrentRecord; psDBF->bCurrentRecordModified = TRUE; psDBF->bUpdated = TRUE; /* -------------------------------------------------------------------- */ /* Translate NULL value to valid DBF file representation. */ /* */ /* Contributed by Jim Matthews. */ /* -------------------------------------------------------------------- */ if( pValue == NULL ) { switch(psDBF->pachFieldType[iField]) { case 'N': case 'F': /* NULL numeric fields have value "****************" */ memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '*', psDBF->panFieldSize[iField] ); break; case 'D': /* NULL date fields have value "00000000" */ memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '0', psDBF->panFieldSize[iField] ); break; case 'L': /* NULL boolean fields have value "?" */ memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '?', psDBF->panFieldSize[iField] ); break; default: /* empty string fields are considered NULL */ memset( (char *) (pabyRec+psDBF->panFieldOffset[iField]), '\0', psDBF->panFieldSize[iField] ); break; } return TRUE; } /* -------------------------------------------------------------------- */ /* Assign all the record fields. */ /* -------------------------------------------------------------------- */ switch( psDBF->pachFieldType[iField] ) { case 'D': case 'N': case 'F': if( psDBF->panFieldDecimals[iField] == 0 ) { int nWidth = psDBF->panFieldSize[iField]; if( sizeof(szSField)-2 < nWidth ) nWidth = sizeof(szSField)-2; sprintf( szFormat, "%%%dd", nWidth ); sprintf(szSField, szFormat, (int) *((double *) pValue) ); if( (int)strlen(szSField) > psDBF->panFieldSize[iField] ) { szSField[psDBF->panFieldSize[iField]] = '\0'; nRetResult = FALSE; } strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), szSField, strlen(szSField) ); } else { int nWidth = psDBF->panFieldSize[iField]; if( sizeof(szSField)-2 < nWidth ) nWidth = sizeof(szSField)-2; sprintf( szFormat, "%%%d.%df", nWidth, psDBF->panFieldDecimals[iField] ); sprintf(szSField, szFormat, *((double *) pValue) ); if( (int) strlen(szSField) > psDBF->panFieldSize[iField] ) { szSField[psDBF->panFieldSize[iField]] = '\0'; nRetResult = FALSE; } strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), szSField, strlen(szSField) ); } break; case 'L': if (psDBF->panFieldSize[iField] >= 1 && (*(char*)pValue == 'F' || *(char*)pValue == 'T')) *(pabyRec+psDBF->panFieldOffset[iField]) = *(char*)pValue; break; default: if( (int) strlen((char *) pValue) > psDBF->panFieldSize[iField] ) { j = psDBF->panFieldSize[iField]; nRetResult = FALSE; } else { memset( pabyRec+psDBF->panFieldOffset[iField], ' ', psDBF->panFieldSize[iField] ); j = strlen((char *) pValue); } strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), (char *) pValue, j ); break; } return( nRetResult ); } /************************************************************************/ /* DBFWriteAttributeDirectly() */ /* */ /* Write an attribute record to the file, but without any */ /* reformatting based on type. The provided buffer is written */ /* as is to the field position in the record. */ /************************************************************************/ int DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField, void * pValue ) { int nRecordOffset, i, j; unsigned char *pabyRec; /* -------------------------------------------------------------------- */ /* Is this a valid record? */ /* -------------------------------------------------------------------- */ if( hEntity < 0 || hEntity > psDBF->nRecords ) return( FALSE ); if( psDBF->bNoHeader ) DBFWriteHeader(psDBF); /* -------------------------------------------------------------------- */ /* Is this a brand new record? */ /* -------------------------------------------------------------------- */ if( hEntity == psDBF->nRecords ) { DBFFlushRecord( psDBF ); psDBF->nRecords++; for( i = 0; i < psDBF->nRecordLength; i++ ) psDBF->pszCurrentRecord[i] = ' '; psDBF->nCurrentRecord = hEntity; } /* -------------------------------------------------------------------- */ /* Is this an existing record, but different than the last one */ /* we accessed? */ /* -------------------------------------------------------------------- */ if( psDBF->nCurrentRecord != hEntity ) { DBFFlushRecord( psDBF ); nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; fseek( psDBF->fp, nRecordOffset, 0 ); fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); psDBF->nCurrentRecord = hEntity; } pabyRec = (unsigned char *) psDBF->pszCurrentRecord; /* -------------------------------------------------------------------- */ /* Assign all the record fields. */ /* -------------------------------------------------------------------- */ if( (int)strlen((char *) pValue) > psDBF->panFieldSize[iField] ) j = psDBF->panFieldSize[iField]; else { memset( pabyRec+psDBF->panFieldOffset[iField], ' ', psDBF->panFieldSize[iField] ); j = strlen((char *) pValue); } strncpy((char *) (pabyRec+psDBF->panFieldOffset[iField]), (char *) pValue, j ); psDBF->bCurrentRecordModified = TRUE; psDBF->bUpdated = TRUE; return( TRUE ); } /************************************************************************/ /* DBFWriteDoubleAttribute() */ /* */ /* Write a double attribute. */ /************************************************************************/ int SHPAPI_CALL DBFWriteDoubleAttribute( DBFHandle psDBF, int iRecord, int iField, double dValue ) { return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) ); } /************************************************************************/ /* DBFWriteIntegerAttribute() */ /* */ /* Write a integer attribute. */ /************************************************************************/ int SHPAPI_CALL DBFWriteIntegerAttribute( DBFHandle psDBF, int iRecord, int iField, int nValue ) { double dValue = nValue; return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) &dValue ) ); } /************************************************************************/ /* DBFWriteStringAttribute() */ /* */ /* Write a string attribute. */ /************************************************************************/ int SHPAPI_CALL DBFWriteStringAttribute( DBFHandle psDBF, int iRecord, int iField, const char * pszValue ) { return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) pszValue ) ); } /************************************************************************/ /* DBFWriteNULLAttribute() */ /* */ /* Write a string attribute. */ /************************************************************************/ int SHPAPI_CALL DBFWriteNULLAttribute( DBFHandle psDBF, int iRecord, int iField ) { return( DBFWriteAttribute( psDBF, iRecord, iField, NULL ) ); } /************************************************************************/ /* DBFWriteLogicalAttribute() */ /* */ /* Write a logical attribute. */ /************************************************************************/ int SHPAPI_CALL DBFWriteLogicalAttribute( DBFHandle psDBF, int iRecord, int iField, const char lValue) { return( DBFWriteAttribute( psDBF, iRecord, iField, (void *) (&lValue) ) ); } /************************************************************************/ /* DBFWriteTuple() */ /* */ /* Write an attribute record to the file. */ /************************************************************************/ int SHPAPI_CALL DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple ) { int nRecordOffset, i; unsigned char *pabyRec; /* -------------------------------------------------------------------- */ /* Is this a valid record? */ /* -------------------------------------------------------------------- */ if( hEntity < 0 || hEntity > psDBF->nRecords ) return( FALSE ); if( psDBF->bNoHeader ) DBFWriteHeader(psDBF); /* -------------------------------------------------------------------- */ /* Is this a brand new record? */ /* -------------------------------------------------------------------- */ if( hEntity == psDBF->nRecords ) { DBFFlushRecord( psDBF ); psDBF->nRecords++; for( i = 0; i < psDBF->nRecordLength; i++ ) psDBF->pszCurrentRecord[i] = ' '; psDBF->nCurrentRecord = hEntity; } /* -------------------------------------------------------------------- */ /* Is this an existing record, but different than the last one */ /* we accessed? */ /* -------------------------------------------------------------------- */ if( psDBF->nCurrentRecord != hEntity ) { DBFFlushRecord( psDBF ); nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; fseek( psDBF->fp, nRecordOffset, 0 ); fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); psDBF->nCurrentRecord = hEntity; } pabyRec = (unsigned char *) psDBF->pszCurrentRecord; memcpy ( pabyRec, pRawTuple, psDBF->nRecordLength ); psDBF->bCurrentRecordModified = TRUE; psDBF->bUpdated = TRUE; return( TRUE ); } /************************************************************************/ /* DBFReadTuple() */ /* */ /* Read one of the attribute fields of a record. */ /************************************************************************/ const char SHPAPI_CALL1(*) DBFReadTuple(DBFHandle psDBF, int hEntity ) { int nRecordOffset; unsigned char *pabyRec; static char *pReturnTuple = NULL; static int nTupleLen = 0; /* -------------------------------------------------------------------- */ /* Have we read the record? */ /* -------------------------------------------------------------------- */ if( hEntity < 0 || hEntity >= psDBF->nRecords ) return( NULL ); if( psDBF->nCurrentRecord != hEntity ) { DBFFlushRecord( psDBF ); nRecordOffset = psDBF->nRecordLength * hEntity + psDBF->nHeaderLength; fseek( psDBF->fp, nRecordOffset, 0 ); fread( psDBF->pszCurrentRecord, psDBF->nRecordLength, 1, psDBF->fp ); psDBF->nCurrentRecord = hEntity; } pabyRec = (unsigned char *) psDBF->pszCurrentRecord; if ( nTupleLen < psDBF->nRecordLength) { nTupleLen = psDBF->nRecordLength; pReturnTuple = (char *) SfRealloc(pReturnTuple, psDBF->nRecordLength); } memcpy ( pReturnTuple, pabyRec, psDBF->nRecordLength ); return( pReturnTuple ); } /************************************************************************/ /* DBFCloneEmpty() */ /* */ /* Read one of the attribute fields of a record. */ /************************************************************************/ DBFHandle SHPAPI_CALL DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename ) { DBFHandle newDBF; newDBF = DBFCreate ( pszFilename ); if ( newDBF == NULL ) return ( NULL ); newDBF->pszHeader = (char *) malloc ( 32 * psDBF->nFields ); memcpy ( newDBF->pszHeader, psDBF->pszHeader, 32 * psDBF->nFields ); newDBF->nFields = psDBF->nFields; newDBF->nRecordLength = psDBF->nRecordLength; newDBF->nHeaderLength = 32 * (psDBF->nFields+1); newDBF->panFieldOffset = (int *) malloc ( sizeof(int) * psDBF->nFields ); memcpy ( newDBF->panFieldOffset, psDBF->panFieldOffset, sizeof(int) * psDBF->nFields ); newDBF->panFieldSize = (int *) malloc ( sizeof(int) * psDBF->nFields ); memcpy ( newDBF->panFieldSize, psDBF->panFieldSize, sizeof(int) * psDBF->nFields ); newDBF->panFieldDecimals = (int *) malloc ( sizeof(int) * psDBF->nFields ); memcpy ( newDBF->panFieldDecimals, psDBF->panFieldDecimals, sizeof(int) * psDBF->nFields ); newDBF->pachFieldType = (char *) malloc ( sizeof(int) * psDBF->nFields ); memcpy ( newDBF->pachFieldType, psDBF->pachFieldType, sizeof(int) * psDBF->nFields ); newDBF->bNoHeader = TRUE; newDBF->bUpdated = TRUE; DBFWriteHeader ( newDBF ); DBFClose ( newDBF ); newDBF = DBFOpen ( pszFilename, "rb+" ); return ( newDBF ); } /************************************************************************/ /* DBFGetNativeFieldType() */ /* */ /* Return the DBase field type for the specified field. */ /* */ /* Value can be one of: 'C' (String), 'D' (Date), 'F' (Float), */ /* 'N' (Numeric, with or without decimal), */ /* 'L' (Logical), */ /* 'M' (Memo: 10 digits .DBT block ptr) */ /************************************************************************/ char SHPAPI_CALL DBFGetNativeFieldType( DBFHandle psDBF, int iField ) { if( iField >=0 && iField < psDBF->nFields ) return psDBF->pachFieldType[iField]; return ' '; } /************************************************************************/ /* str_to_upper() */ /************************************************************************/ static void str_to_upper (char *string) { int len; short i = -1; len = strlen (string); while (++i < len) if (isalpha(string[i]) && islower(string[i])) string[i] = toupper ((int)string[i]); } /************************************************************************/ /* DBFGetFieldIndex() */ /* */ /* Get the index number for a field in a .dbf file. */ /* */ /* Contributed by Jim Matthews. */ /************************************************************************/ int SHPAPI_CALL DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName) { char name[12], name1[12], name2[12]; int i; strncpy(name1, pszFieldName,11); name1[11] = '\0'; str_to_upper(name1); for( i = 0; i < DBFGetFieldCount(psDBF); i++ ) { DBFGetFieldInfo( psDBF, i, name, NULL, NULL ); strncpy(name2,name,11); str_to_upper(name2); if(!strncmp(name1,name2,10)) return(i); } return(-1); } ./shapelib-1.2.10/libtool0100755000076500001440000034121607644273432014662 0ustar warmerdausers#! /bin/sh # libtool - Provide generalized library-building support services. # Generated automatically by ltconfig (GNU libtool 1.3 (1.385.2.117 1999/04/29 13:07:13)) # NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh. # # Copyright (C) 1996-1999 Free Software Foundation, Inc. # Gordon Matzigkeit , 1996 # # 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 of the License, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="sed -e s/^X//" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi ### BEGIN LIBTOOL CONFIG # Libtool was configured as follows, on host cs46980-c: # # CC="gcc" CFLAGS="-g -O2" CPPFLAGS="" \ # LD="/usr/bin/ld" LDFLAGS="" LIBS="" \ # NM="/usr/bin/nm -B" RANLIB="ranlib" LN_S="ln -s" \ # DLLTOOL="" OBJDUMP="" AS="" \ # ./ltconfig --cache-file=./config.cache --with-gcc --with-gnu-ld --no-verify ./ltmain.sh i586-pc-linux-gnu # # Compiler and other test output produced by ltconfig, useful for # debugging ltconfig, is in ./config.log if it exists. # The version of ltconfig that generated this script. LTCONFIG_VERSION="1.3" # Shell to use when invoking shell scripts. SHELL="/bin/sh" # Whether or not to build shared libraries. build_libtool_libs=yes # Whether or not to build static libraries. build_old_libs=yes # Whether or not to optimize for fast installation. fast_install=yes # The host system. host_alias=i586-pc-linux-gnu host=i586-pc-linux-gnu # An echo program that does not interpret backslashes. echo="echo" # The archiver. AR="ar" # The default C compiler. CC="gcc" # The linker used to build libraries. LD="/usr/bin/ld" # Whether we need hard or soft links. LN_S="ln -s" # A BSD-compatible nm program. NM="/usr/bin/nm -B" # Used on cygwin: DLL creation program. DLLTOOL="dlltool" # Used on cygwin: object dumper. OBJDUMP="objdump" # Used on cygwin: assembler. AS="as" # The name of the directory that contains temporary libtool files. objdir=.libs # How to create reloadable object files. reload_flag=" -r" reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs" # How to pass a linker flag through the compiler. wl="-Wl," # Object file suffix (normally "o"). objext="o" # Old archive suffix (normally "a"). libext="a" # Additional compiler flags for building library objects. pic_flag=" -fPIC" # Does compiler simultaneously support -c and -o options? compiler_c_o="yes" # Can we write directly to a .lo ? compiler_o_lo="yes" # Must we lock files when doing compilation ? need_locks="no" # Do we need the lib prefix for modules? need_lib_prefix=no # Do we need a version for libraries? need_version=no # Whether dlopen is supported. dlopen=unknown # Whether dlopen of programs is supported. dlopen_self=unknown # Whether dlopen of statically linked programs is supported. dlopen_self_static=unknown # Compiler flag to prevent dynamic linking. link_static_flag="-static" # Compiler flag to turn off builtin functions. no_builtin_flag=" -fno-builtin -fno-rtti -fno-exceptions" # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec="\${wl}--export-dynamic" # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive" # Compiler flag to generate thread-safe objects. thread_safe_flag_spec="" # Library versioning type. version_type=linux # Format of library name prefix. libname_spec="lib\$name" # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME. library_names_spec="\${libname}\${release}.so\$versuffix \${libname}\${release}.so\$major \$libname.so" # The coded name of the library, if different from the real name. soname_spec="\${libname}\${release}.so\$major" # Commands used to build and install an old-style archive. RANLIB="ranlib" old_archive_cmds="\$AR cru \$oldlib\$oldobjs~\$RANLIB \$oldlib" old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib" old_postuninstall_cmds="" # Create an old-style archive from a shared archive. old_archive_from_new_cmds="" # Commands used to build and install a shared archive. archive_cmds="\$CC -shared \$libobjs \$deplibs \$linkopts \${wl}-soname \$wl\$soname -o \$lib" archive_expsym_cmds="\$CC -shared \$libobjs \$deplibs \$linkopts \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib" postinstall_cmds="" postuninstall_cmds="" # Method to check whether dependent libraries are shared objects. deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )" # Command to use when deplibs_check_method == file_magic. file_magic_cmd="/usr/bin/file" # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag="" # Flag that forces no undefined symbols. no_undefined_flag="" # Commands used to finish a libtool library installation in a directory. finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir" # Same as above, but a single script fragment to be evaled but not shown. finish_eval="" # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGISTW]\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'" # Transform the output of nm in a proper C declaration global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern char \\1;/p'" # This is the shared library runtime path variable. runpath_var=LD_RUN_PATH # This is the shared library path variable. shlibpath_var=LD_LIBRARY_PATH # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=no # How to hardcode a shared library path into an executable. hardcode_action=immediate # Flag to hardcode $libdir into a binary during linking. # This must work even if $libdir does not exist. hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir" # Whether we need a single -rpath flag with a separated argument. hardcode_libdir_separator="" # Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the # resulting binary. hardcode_direct=no # Set to yes if using the -LDIR flag during linking hardcodes DIR into the # resulting binary. hardcode_minus_L=no # Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into # the resulting binary. hardcode_shlibpath_var=unsupported # Compile-time system search path for libraries sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" # Run-time system search path for libraries sys_lib_dlsearch_path_spec="/lib /usr/lib" # Fix the shell variable $srcfile for the compiler. fix_srcfile_path="" # Set to yes if exported symbols are required. always_export_symbols=no # The commands to list exported symbols. export_symbols_cmds="\$NM \$libobjs | \$global_symbol_pipe | sed 's/.* //' | sort | uniq > \$export_symbols" # Symbols that should not be listed in the preloaded symbols. exclude_expsyms="_GLOBAL_OFFSET_TABLE_" # Symbols that must always be exported. include_expsyms="" ### END LIBTOOL CONFIG # ltmain.sh - Provide generalized library-building support services. # NOTE: Changing this file will not affect anything until you rerun ltconfig. # # Copyright (C) 1996-1999 Free Software Foundation, Inc. # Originally by Gordon Matzigkeit , 1996 # # 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 of the License, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Check that we have a working $echo. if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then # Yippee, $echo works! : else # Restart under the correct shell, and then maybe $echo will work. exec $SHELL "$0" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat <&2 echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit 1 fi if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then echo "$modename: not configured to build any kind of library" 1>&2 echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit 1 fi # Global variables. mode=$default_mode nonopt= prev= prevopt= run= show="$echo" show_help= execute_dlfiles= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" # Parse our command line options once, thoroughly. while test $# -gt 0 do arg="$1" shift case "$arg" in -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac # If the previous option needs an argument, assign it. if test -n "$prev"; then case "$prev" in execute_dlfiles) eval "$prev=\"\$$prev \$arg\"" ;; *) eval "$prev=\$arg" ;; esac prev= prevopt= continue fi # Have we seen a non-optional argument yet? case "$arg" in --help) show_help=yes ;; --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" exit 0 ;; --config) sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0 exit 0 ;; --debug) echo "$progname: enabling shell trace mode" set -x ;; --dry-run | -n) run=: ;; --features) echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit 0 ;; --finish) mode="finish" ;; --mode) prevopt="--mode" prev=mode ;; --mode=*) mode="$optarg" ;; --quiet | --silent) show=: ;; -dlopen) prevopt="-dlopen" prev=execute_dlfiles ;; -*) $echo "$modename: unrecognized option \`$arg'" 1>&2 $echo "$help" 1>&2 exit 1 ;; *) nonopt="$arg" break ;; esac done if test -n "$prevopt"; then $echo "$modename: option \`$prevopt' requires an argument" 1>&2 $echo "$help" 1>&2 exit 1 fi if test -z "$show_help"; then # Infer the operation mode. if test -z "$mode"; then case "$nonopt" in *cc | *++ | gcc* | *-gcc*) mode=link for arg do case "$arg" in -c) mode=compile break ;; esac done ;; *db | *dbx | *strace | *truss) mode=execute ;; *install*|cp|mv) mode=install ;; *rm) mode=uninstall ;; *) # If we have no mode, but dlfiles were specified, then do execute mode. test -n "$execute_dlfiles" && mode=execute # Just use the default operation mode. if test -z "$mode"; then if test -n "$nonopt"; then $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 else $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 fi fi ;; esac fi # Only execute mode is allowed to have -dlopen flags. if test -n "$execute_dlfiles" && test "$mode" != execute; then $echo "$modename: unrecognized option \`-dlopen'" 1>&2 $echo "$help" 1>&2 exit 1 fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$modename --help --mode=$mode' for more information." # These modes are in order of execution frequency so that they run quickly. case "$mode" in # libtool compile mode compile) modename="$modename: compile" # Get the compilation command and the source file. base_compile= lastarg= srcfile="$nonopt" suppress_output= user_target=no for arg do # Accept any command-line options. case "$arg" in -o) if test "$user_target" != "no"; then $echo "$modename: you cannot specify \`-o' more than once" 1>&2 exit 1 fi user_target=next ;; -static) build_old_libs=yes continue ;; esac case "$user_target" in next) # The next one is the -o target name user_target=yes continue ;; yes) # We got the output file user_target=set libobj="$arg" continue ;; esac # Accept the current argument as the source file. lastarg="$srcfile" srcfile="$arg" # Aesthetically quote the previous argument. # Backslashify any backslashes, double quotes, and dollar signs. # These are the only characters that are still specially # interpreted inside of double-quoted scrings. lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` # Double-quote args containing other shell metacharacters. # Many Bourne shells cannot handle close brackets correctly in scan # sets, so we specify it separately. case "$lastarg" in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) lastarg="\"$lastarg\"" ;; esac # Add the previous argument to base_compile. if test -z "$base_compile"; then base_compile="$lastarg" else base_compile="$base_compile $lastarg" fi done case "$user_target" in set) ;; no) # Get the name of the library object. libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` ;; *) $echo "$modename: you must specify a target with \`-o'" 1>&2 exit 1 ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo xform='[cCFSfmso]' case "$libobj" in *.ada) xform=ada ;; *.adb) xform=adb ;; *.ads) xform=ads ;; *.asm) xform=asm ;; *.c++) xform=c++ ;; *.cc) xform=cc ;; *.cpp) xform=cpp ;; *.cxx) xform=cxx ;; *.f90) xform=f90 ;; *.for) xform=for ;; esac libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` case "$libobj" in *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; *) $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 exit 1 ;; esac if test -z "$base_compile"; then $echo "$modename: you must specify a compilation command" 1>&2 $echo "$help" 1>&2 exit 1 fi # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $libobj" else removelist="$libobj" fi $run $rm $removelist trap "$run $rm $removelist; exit 1" 1 2 15 # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext} lockfile="$output_obj.lock" removelist="$removelist $output_obj $lockfile" trap "$run $rm $removelist; exit 1" 1 2 15 else need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until ln "$0" "$lockfile" 2>/dev/null; do $show "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then echo "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit 1 fi echo $srcfile > "$lockfile" fi if test -n "$fix_srcfile_path"; then eval srcfile=\"$fix_srcfile_path\" fi # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile # All platforms use -DPIC, to notify preprocessed assembler code. command="$base_compile $pic_flag -DPIC $srcfile" if test "$build_old_libs" = yes; then lo_libobj="$libobj" dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` if test "X$dir" = "X$libobj"; then dir="$objdir" else dir="$dir/$objdir" fi libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` if test -d "$dir"; then $show "$rm $libobj" $run $rm $libobj else $show "$mkdir $dir" $run $mkdir $dir status=$? if test $status -ne 0 && test ! -d $dir; then exit $status fi fi fi if test "$compiler_o_lo" = yes; then output_obj="$libobj" command="$command -o $output_obj" elif test "$compiler_c_o" = yes; then output_obj="$obj" command="$command -o $output_obj" fi $show "$command" if $run eval "$command"; then : else test -n "$output_obj" && $run $rm $removelist exit 1 fi if test "$need_locks" = warn && test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then echo "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit 1 fi # Just move the object if needed, then go on to compile the next one if test x"$output_obj" != x"$libobj"; then $show "$mv $output_obj $libobj" if $run $mv $output_obj $libobj; then : else error=$? $run $rm $removelist exit $error fi fi # If we have no pic_flag, then copy the object into place and finish. if test -z "$pic_flag" && test "$build_old_libs" = yes; then # Rename the .lo from within objdir to obj if test -f $obj; then $show $rm $obj $run $rm $obj fi $show "$mv $libobj $obj" if $run $mv $libobj $obj; then : else error=$? $run $rm $removelist exit $error fi # Now arrange that obj and lo_libobj become the same file $show "$LN_S $obj $lo_libobj" if $run $LN_S $obj $lo_libobj; then exit 0 else error=$? $run $rm $removelist exit $error fi fi # Allow error messages only from the first compilation. suppress_output=' >/dev/null 2>&1' fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then command="$base_compile $srcfile" if test "$compiler_c_o" = yes; then command="$command -o $obj" output_obj="$obj" fi # Suppress compiler output if we already did a PIC compilation. command="$command$suppress_output" $show "$command" if $run eval "$command"; then : else $run $rm $removelist exit 1 fi if test "$need_locks" = warn && test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then echo "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $run $rm $removelist exit 1 fi # Just move the object if needed if test x"$output_obj" != x"$obj"; then $show "$mv $output_obj $obj" if $run $mv $output_obj $obj; then : else error=$? $run $rm $removelist exit $error fi fi # Create an invalid libtool object if no PIC, so that we do not # accidentally link it into a program. if test "$build_libtool_libs" != yes; then $show "echo timestamp > $libobj" $run eval "echo timestamp > \$libobj" || exit $? else # Move the .lo from within objdir $show "$mv $libobj $lo_libobj" if $run $mv $libobj $lo_libobj; then : else error=$? $run $rm $removelist exit $error fi fi fi # Unlock the critical section if it was locked if test "$need_locks" != no; then $rm "$lockfile" fi exit 0 ;; # libtool link mode link) modename="$modename: link" C_compiler="$CC" # save it, to compile generated C sources CC="$nonopt" case "$host" in *-*-cygwin* | *-*-mingw* | *-*-os2*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invokation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes # This is a source program that is used to create dlls on Windows # Don't remove nor modify the starting and closing comments # /* ltdll.c starts here */ # #define WIN32_LEAN_AND_MEAN # #include # #undef WIN32_LEAN_AND_MEAN # #include # # #ifdef __cplusplus # extern "C" { # #endif # BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); # #ifdef __cplusplus # } # #endif # # #include # DECLARE_CYGWIN_DLL( DllMain ); # HINSTANCE __hDllInstance_base; # # BOOL APIENTRY # DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) # { # __hDllInstance_base = hInst; # return TRUE; # } # /* ltdll.c ends here */ # This is a source program that is used to create import libraries # on Windows for dlls which lack them. Don't remove nor modify the # starting and closing comments # /* impgen.c starts here */ # /* Copyright (C) 1999 Free Software Foundation, Inc. # # This file is part of GNU libtool. # # 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 of the License, 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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # */ # # #include /* for printf() */ # #include /* for open(), lseek(), read() */ # #include /* for O_RDONLY, O_BINARY */ # #include /* for strdup() */ # # static unsigned int # pe_get16 (fd, offset) # int fd; # int offset; # { # unsigned char b[2]; # lseek (fd, offset, SEEK_SET); # read (fd, b, 2); # return b[0] + (b[1]<<8); # } # # static unsigned int # pe_get32 (fd, offset) # int fd; # int offset; # { # unsigned char b[4]; # lseek (fd, offset, SEEK_SET); # read (fd, b, 4); # return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); # } # # static unsigned int # pe_as32 (ptr) # void *ptr; # { # unsigned char *b = ptr; # return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); # } # # int # main (argc, argv) # int argc; # char *argv[]; # { # int dll; # unsigned long pe_header_offset, opthdr_ofs, num_entries, i; # unsigned long export_rva, export_size, nsections, secptr, expptr; # unsigned long name_rvas, nexp; # unsigned char *expdata, *erva; # char *filename, *dll_name; # # filename = argv[1]; # # dll = open(filename, O_RDONLY|O_BINARY); # if (!dll) # return 1; # # dll_name = filename; # # for (i=0; filename[i]; i++) # if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') # dll_name = filename + i +1; # # pe_header_offset = pe_get32 (dll, 0x3c); # opthdr_ofs = pe_header_offset + 4 + 20; # num_entries = pe_get32 (dll, opthdr_ofs + 92); # # if (num_entries < 1) /* no exports */ # return 1; # # export_rva = pe_get32 (dll, opthdr_ofs + 96); # export_size = pe_get32 (dll, opthdr_ofs + 100); # nsections = pe_get16 (dll, pe_header_offset + 4 +2); # secptr = (pe_header_offset + 4 + 20 + # pe_get16 (dll, pe_header_offset + 4 + 16)); # # expptr = 0; # for (i = 0; i < nsections; i++) # { # char sname[8]; # unsigned long secptr1 = secptr + 40 * i; # unsigned long vaddr = pe_get32 (dll, secptr1 + 12); # unsigned long vsize = pe_get32 (dll, secptr1 + 16); # unsigned long fptr = pe_get32 (dll, secptr1 + 20); # lseek(dll, secptr1, SEEK_SET); # read(dll, sname, 8); # if (vaddr <= export_rva && vaddr+vsize > export_rva) # { # expptr = fptr + (export_rva - vaddr); # if (export_rva + export_size > vaddr + vsize) # export_size = vsize - (export_rva - vaddr); # break; # } # } # # expdata = (unsigned char*)malloc(export_size); # lseek (dll, expptr, SEEK_SET); # read (dll, expdata, export_size); # erva = expdata - export_rva; # # nexp = pe_as32 (expdata+24); # name_rvas = pe_as32 (expdata+32); # # printf ("EXPORTS\n"); # for (i = 0; i&2 fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi else if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi fi build_libtool_libs=no build_old_libs=yes prefer_static_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test $# -gt 0; do arg="$1" shift # If the previous option needs an argument, assign it. if test -n "$prev"; then case "$prev" in output) compile_command="$compile_command @OUTPUT@" finalize_command="$finalize_command @OUTPUT@" ;; esac case "$prev" in dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. compile_command="$compile_command @SYMFILE@" finalize_command="$finalize_command @SYMFILE@" preload=yes fi case "$arg" in *.la | *.lo) ;; # We handle these cases below. self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" else dlprefiles="$dlprefiles $arg" fi prev= ;; esac ;; expsyms) export_symbols="$arg" if test ! -f "$arg"; then $echo "$modename: symbol file \`$arg' does not exist" exit 1 fi prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case "$arg" in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 exit 1 ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath="$rpath $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath="$xrpath $arg" ;; esac fi prev= continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi prevarg="$arg" case "$arg" in -all-static) if test -n "$link_static_flag"; then compile_command="$compile_command $link_static_flag" finalize_command="$finalize_command $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 continue ;; -avoid-version) avoid_version=yes continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then $echo "$modename: not more than one -exported-symbols argument allowed" exit 1 fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -L*) dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` # We need an absolute path. case "$dir" in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 exit 1 fi dir="$absdir" ;; esac case " $deplibs " in *" $arg "*) ;; *) deplibs="$deplibs $arg";; esac case " $lib_search_path " in *" $dir "*) ;; *) lib_search_path="$lib_search_path $dir";; esac case "$host" in *-*-cygwin* | *-*-mingw* | *-*-os2*) dllsearchdir=`cd "$dir" && pwd || echo "$dir"` case ":$dllsearchpath:" in ::) dllsearchpath="$dllsearchdir";; *":$dllsearchdir:"*) ;; *) dllsearchpath="$dllsearchpath:$dllsearchdir";; esac ;; esac ;; -l*) if test "$arg" = "-lc"; then case "$host" in *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) # These systems don't actually have c library (as such) continue ;; esac elif test "$arg" = "-lm"; then case "$host" in *-*-cygwin* | *-*-beos*) # These systems don't actually have math library (as such) continue ;; esac fi deplibs="$deplibs $arg" ;; -module) module=yes continue ;; -no-undefined) allow_undefined=no continue ;; -o) prev=output ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` # We need an absolute path. case "$dir" in [\\/]* | [A-Za-z]:[\\/]*) ;; *) $echo "$modename: only absolute run-paths are allowed" 1>&2 exit 1 ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac continue ;; -static) # If we have no pic_flag, then this is the same as -all-static. if test -z "$pic_flag" && test -n "$link_static_flag"; then compile_command="$compile_command $link_static_flag" finalize_command="$finalize_command $link_static_flag" fi continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; # Some other compiler flag. -* | +*) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case "$arg" in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) arg="\"$arg\"" ;; esac ;; *.o | *.obj | *.a | *.lib) # A standard object. objs="$objs $arg" ;; *.lo) # A library object. if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` prev= fi libobjs="$libobjs $arg" ;; *.la) # A libtool-controlled library. dlname= libdir= library_names= old_library= # Check to see that this really is a libtool archive. if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2 exit 1 fi # If the library was installed with an old release of libtool, # it will not redefine variable installed. installed=yes # Read the .la file # If there is no directory component, then add one. case "$arg" in */* | *\\*) . $arg ;; *) . ./$arg ;; esac # Get the name of the library we link against. linklib= for l in $old_library $library_names; do linklib="$l" done if test -z "$linklib"; then $echo "$modename: cannot find name of link library for \`$arg'" 1>&2 exit 1 fi # Find the relevant object directory and library name. name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'` if test "X$installed" = Xyes; then dir="$libdir" else dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` if test "X$dir" = "X$arg"; then dir="$objdir" else dir="$dir/$objdir" fi fi if test -n "$dependency_libs"; then # Extract -R from dependency_libs temp_deplibs= for deplib in $dependency_libs; do case "$deplib" in -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'` case " $rpath $xrpath " in *" $temp_xrpath "*) ;; *) xrpath="$xrpath $temp_xrpath";; esac;; -L*) case "$compile_command $temp_deplibs " in *" $deplib "*) ;; *) temp_deplibs="$temp_deplibs $deplib";; esac;; *) temp_deplibs="$temp_deplibs $deplib";; esac done dependency_libs="$temp_deplibs" fi if test -z "$libdir"; then # It is a libtool convenience library, so add in its objects. convenience="$convenience $dir/$old_library" old_convenience="$old_convenience $dir/$old_library" deplibs="$deplibs$dependency_libs" compile_command="$compile_command $dir/$old_library$dependency_libs" finalize_command="$finalize_command $dir/$old_library$dependency_libs" continue fi # This library was specified with -dlopen. if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking statically, # we need to preload. prev=dlprefiles else # We should not create a dependency on this library, but we # may need any libraries it requires. compile_command="$compile_command$dependency_libs" finalize_command="$finalize_command$dependency_libs" prev= continue fi fi # The library was specified with -dlpreopen. if test "$prev" = dlprefiles; then # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then dlprefiles="$dlprefiles $dir/$old_library" else dlprefiles="$dlprefiles $dir/$linklib" fi prev= fi if test -n "$library_names" && { test "$prefer_static_libs" = no || test -z "$old_library"; }; then link_against_libtool_libs="$link_against_libtool_libs $arg" if test -n "$shlibpath_var"; then # Make sure the rpath contains only unique directories. case "$temp_rpath " in *" $dir "*) ;; *) temp_rpath="$temp_rpath $dir" ;; esac fi # We need an absolute path. case "$dir" in [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 exit 1 fi ;; esac # This is the magic to use -rpath. # Skip directories that are in the system default run-time # search path, unless they have been requested with -R. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac lib_linked=yes case "$hardcode_action" in immediate | unsupported) if test "$hardcode_direct" = no; then compile_command="$compile_command $dir/$linklib" deplibs="$deplibs $dir/$linklib" case "$host" in *-*-cygwin* | *-*-mingw* | *-*-os2*) dllsearchdir=`cd "$dir" && pwd || echo "$dir"` if test -n "$dllsearchpath"; then dllsearchpath="$dllsearchpath:$dllsearchdir" else dllsearchpath="$dllsearchdir" fi ;; esac elif test "$hardcode_minus_L" = no; then case "$host" in *-*-sunos*) compile_shlibpath="$compile_shlibpath$dir:" ;; esac case "$compile_command " in *" -L$dir "*) ;; *) compile_command="$compile_command -L$dir";; esac compile_command="$compile_command -l$name" deplibs="$deplibs -L$dir -l$name" elif test "$hardcode_shlibpath_var" = no; then case ":$compile_shlibpath:" in *":$dir:"*) ;; *) compile_shlibpath="$compile_shlibpath$dir:";; esac compile_command="$compile_command -l$name" deplibs="$deplibs -l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes; then compile_command="$compile_command $absdir/$linklib" deplibs="$deplibs $absdir/$linklib" elif test "$hardcode_minus_L" = yes; then case "$compile_command " in *" -L$absdir "*) ;; *) compile_command="$compile_command -L$absdir";; esac compile_command="$compile_command -l$name" deplibs="$deplibs -L$absdir -l$name" elif test "$hardcode_shlibpath_var" = yes; then case ":$compile_shlibpath:" in *":$absdir:"*) ;; *) compile_shlibpath="$compile_shlibpath$absdir:";; esac compile_command="$compile_command -l$name" deplibs="$deplibs -l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then $echo "$modename: configuration error: unsupported hardcode properties" exit 1 fi # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes; then finalize_command="$finalize_command $libdir/$linklib" elif test "$hardcode_minus_L" = yes; then case "$finalize_command " in *" -L$libdir "*) ;; *) finalize_command="$finalize_command -L$libdir";; esac finalize_command="$finalize_command -l$name" elif test "$hardcode_shlibpath_var" = yes; then case ":$finalize_shlibpath:" in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:";; esac finalize_command="$finalize_command -l$name" else # We cannot seem to hardcode it, guess we'll fake it. case "$finalize_command " in *" -L$dir "*) ;; *) finalize_command="$finalize_command -L$libdir";; esac finalize_command="$finalize_command -l$name" fi else # Transform directly to old archives if we don't build new libraries. if test -n "$pic_flag" && test -z "$old_library"; then $echo "$modename: cannot find static library for \`$arg'" 1>&2 exit 1 fi # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_command="$compile_command $dir/$linklib" finalize_command="$finalize_command $dir/$linklib" else case "$compile_command " in *" -L$dir "*) ;; *) compile_command="$compile_command -L$dir";; esac compile_command="$compile_command -l$name" case "$finalize_command " in *" -L$dir "*) ;; *) finalize_command="$finalize_command -L$dir";; esac finalize_command="$finalize_command -l$name" fi fi # Add in any libraries that this one depends upon. compile_command="$compile_command$dependency_libs" finalize_command="$finalize_command$dependency_libs" continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case "$arg" in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) arg="\"$arg\"" ;; esac ;; esac # Now actually substitute the argument into the commands. if test -n "$arg"; then compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi done if test -n "$prev"; then $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 $echo "$help" 1>&2 exit 1 fi if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" compile_command="$compile_command $arg" finalize_command="$finalize_command $arg" fi oldlibs= # calculate the name of the file, without its directory outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` libobjs_save="$libobjs" case "$output" in "") $echo "$modename: you must specify an output file" 1>&2 $echo "$help" 1>&2 exit 1 ;; *.a | *.lib) if test -n "$link_against_libtool_libs"; then $echo "$modename: error: cannot link libtool libraries into archives" 1>&2 exit 1 fi if test -n "$deplibs"; then $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 fi if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 fi if test -n "$rpath"; then $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 fi if test -n "$xrpath"; then $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 fi if test -n "$export_symbols" || test -n "$export_symbols_regex"; then $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 fi # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" ;; *.la) # Make sure we only generate libraries of the form `libNAME.la'. case "$outputname" in lib*) name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` eval libname=\"$libname_spec\" ;; *) if test "$module" = no; then $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 $echo "$help" 1>&2 exit 1 fi if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` eval libname=\"$libname_spec\" else libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` fi ;; esac output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` if test "X$output_objdir" = "X$output"; then output_objdir="$objdir" else output_objdir="$output_objdir/$objdir" fi if test -n "$objs"; then $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1 exit 1 fi # How the heck are we supposed to write a wrapper for a shared library? if test -n "$link_against_libtool_libs"; then $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2 exit 1 fi if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2 fi set dummy $rpath if test $# -gt 2; then $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 fi install_libdir="$2" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. libext=al oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi dependency_libs="$deplibs" if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 fi else # Parse the version information argument. IFS="${IFS= }"; save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 IFS="$save_ifs" if test -n "$8"; then $echo "$modename: too many parameters to \`-version-info'" 1>&2 $echo "$help" 1>&2 exit 1 fi current="$2" revision="$3" age="$4" # Check that each of the things are valid numbers. case "$current" in 0 | [1-9] | [1-9][0-9]*) ;; *) $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit 1 ;; esac case "$revision" in 0 | [1-9] | [1-9][0-9]*) ;; *) $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit 1 ;; esac case "$age" in 0 | [1-9] | [1-9][0-9]*) ;; *) $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit 1 ;; esac if test $age -gt $current; then $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 $echo "$modename: \`$vinfo' is not valid version information" 1>&2 exit 1 fi # Calculate the version variables. major= versuffix= verstring= case "$version_type" in none) ;; irix) major=`expr $current - $age + 1` versuffix="$major.$revision" verstring="sgi$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test $loop != 0; do iface=`expr $revision - $loop` loop=`expr $loop - 1` verstring="sgi$major.$iface:$verstring" done ;; linux) major=.`expr $current - $age` versuffix="$major.$age.$revision" ;; osf) major=`expr $current - $age` versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test $loop != 0; do iface=`expr $current - $loop` loop=`expr $loop - 1` verstring="$verstring:${iface}.0" done # Make executables depend on our current version. verstring="$verstring:${current}.0" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current"; ;; windows) # Like Linux, but with '-' rather than '.', since we only # want one extension on Windows 95. major=`expr $current - $age` versuffix="-$major-$age-$revision" ;; *) $echo "$modename: unknown library version type \`$version_type'" 1>&2 echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 exit 1 ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= verstring="0.0" if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi dependency_libs="$deplibs" case "$host" in *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) # these systems don't actually have a c library (as such)! ;; *) # Add libc to deplibs on all other systems. deplibs="$deplibs -lc" ;; esac fi # Create the output directory, or remove our outputs if we need to. if test -d $output_objdir; then $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* else $show "$mkdir $output_objdir" $run $mkdir $output_objdir status=$? if test $status -ne 0 && test ! -d $output_objdir; then exit $status fi fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs="$oldlibs $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi if test "$build_libtool_libs" = yes; then # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case "$deplibs_check_method" in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behaviour. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $rm conftest.c cat > conftest.c </dev/null` for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potlib" 2>/dev/null \ | grep " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | sed 's/.* -> //'` case "$potliblink" in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ | sed 10q \ | egrep "$file_magic_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done if test -n "$a_deplib" ; then droppeddeps=yes echo echo "*** Warning: This library needs some functionality provided by $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." fi else # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" fi done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | grep . >/dev/null; then echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes fi ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" echo "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." fi fi # Done checking deplibs! deplibs=$newdeplibs fi # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Get the real and link names of the library. eval library_names=\"$library_names_spec\" set dummy $library_names realname="$2" shift; shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi lib="$output_objdir/$realname" for link do linknames="$linknames $link" done # Ensure that we have .o objects for linkers which dislike .lo # (e.g. aix) incase we are running --disable-static for obj in $libobjs; do oldobj=`$echo "X$obj" | $Xsed -e "$lo2o"` if test ! -f $oldobj; then $show "${LN_S} $obj $oldobj" $run ${LN_S} $obj $oldobj || exit $? fi done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` if test -n "$whole_archive_flag_spec"; then if test -n "$convenience"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" fi else gentop="$output_objdir/${outputname}x" $show "${rm}r $gentop" $run ${rm}r "$gentop" $show "mkdir $gentop" $run mkdir "$gentop" status=$? if test $status -ne 0 && test ! -d "$gentop"; then exit $status fi generated="$generated $gentop" for xlib in $convenience; do # Extract the objects. case "$xlib" in [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; *) xabs=`pwd`"/$xlib" ;; esac xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` xdir="$gentop/$xlib" $show "${rm}r $xdir" $run ${rm}r "$xdir" $show "mkdir $xdir" $run mkdir "$xdir" status=$? if test $status -ne 0 && test ! -d "$xdir"; then exit $status fi $show "(cd $xdir && $AR x $xabs)" $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` done fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linkopts="$linkopts $flag" fi # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then $show "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $run $rm $export_symbols eval cmds=\"$export_symbols_cmds\" IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" if test -n "$export_symbols_regex"; then $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' $show "$mv \"${export_symbols}T\" \"$export_symbols\"" $run eval '$mv "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' fi # Do each of the archive commands. if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval cmds=\"$archive_expsym_cmds\" else eval cmds=\"$archive_cmds\" fi IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; *.lo | *.o | *.obj) if test -n "$link_against_libtool_libs"; then $echo "$modename: error: cannot link libtool libraries into objects" 1>&2 exit 1 fi if test -n "$deplibs"; then $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 fi if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 fi if test -n "$rpath"; then $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 fi if test -n "$xrpath"; then $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 fi if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 fi case "$output" in *.lo) if test -n "$objs"; then $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 exit 1 fi libobj="$output" obj=`$echo "X$output" | $Xsed -e "$lo2o"` ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $run $rm $obj $libobj # Create the old-style object. reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` output="$obj" eval cmds=\"$reload_cmds\" IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" # Exit if we aren't doing a library object file. test -z "$libobj" && exit 0 if test "$build_libtool_libs" != yes; then # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. $show "echo timestamp > $libobj" $run eval "echo timestamp > $libobj" || exit $? exit 0 fi if test -n "$pic_flag"; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs" output="$libobj" eval cmds=\"$reload_cmds\" IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" else # Just create a symlink. $show $rm $libobj $run $rm $libobj $show "$LN_S $obj $libobj" $run $LN_S $obj $libobj || exit $? fi exit 0 ;; # Anything else should be a program. *) if test -n "$vinfo"; then $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 fi if test -n "$release"; then $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 fi if test "$preload" = yes; then if test "$dlopen" = unknown && test "$dlopen_self" = unknown && test "$dlopen_self_static" = unknown; then $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." fi fi if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$compile_rpath " in *" $libdir "*) ;; *) compile_rpath="$compile_rpath $libdir" ;; esac case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` if test "X$output_objdir" = "X$output"; then output_objdir="$objdir" else output_objdir="$output_objdir/$objdir" fi # Create the binary in the object directory, then wrap it. if test ! -d $output_objdir; then $show "$mkdir $output_objdir" $run $mkdir $output_objdir status=$? if test $status -ne 0 && test ! -d $output_objdir; then exit $status fi fi if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` fi dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" = yes; then if test -n "$NM" && test -n "$global_symbol_pipe"; then dlsyms="${outputname}S.c" else $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 fi fi if test -n "$dlsyms"; then case "$dlsyms" in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${outputname}.nm" $show "$rm $nlist ${nlist}S ${nlist}T" $run $rm "$nlist" "${nlist}S" "${nlist}T" # Parse the name list into a source file. $show "creating $output_objdir/$dlsyms" test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ /* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ /* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ #ifdef __cplusplus extern \"C\" { #endif /* Prevent the only kind of declaration conflicts we can make. */ #define lt_preloaded_symbols some_other_symbol /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then $show "generating symbol list for \`$output'" test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for arg in $progfiles; do $show "extracting global C symbols from \`$arg'" $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi if test -n "$export_symbols_regex"; then $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' $run eval '$mv "$nlist"T "$nlist"' fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$output.exp" $run $rm $export_symbols $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' else $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' $run eval 'mv "$nlist"T "$nlist"' fi fi for arg in $dlprefiles; do $show "extracting global C symbols from \`$arg'" name=`echo "$arg" | sed -e 's%^.*/%%'` $run eval 'echo ": $name " >> "$nlist"' $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" done if test -z "$run"; then # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $mv "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then : else grep -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' else echo '/* NONE */' >> "$output_objdir/$dlsyms" fi $echo >> "$output_objdir/$dlsyms" "\ #undef lt_preloaded_symbols #if defined (__STDC__) && __STDC__ # define lt_ptr_t void * #else # define lt_ptr_t char * # define const #endif /* The mapping between symbol names and symbols. */ const struct { const char *name; lt_ptr_t address; } lt_preloaded_symbols[] = {\ " sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \ -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \ < "$nlist" >> "$output_objdir/$dlsyms" $echo >> "$output_objdir/$dlsyms" "\ {0, (lt_ptr_t) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " fi pic_flag_for_symtable= case "$host" in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2*|*-*-freebsd3.0*) case "$compile_command " in *" -static "*) ;; *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; esac esac # Now compile the dynamic symbol file. $show "(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" $run eval '(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? # Clean up the generated files. $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" # Transform the symbol file into the correct name. compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` ;; *) $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 exit 1 ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then # Replace the output file specification. compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. $show "$link_command" $run eval "$link_command" status=$? # Delete the generated files. if test -n "$dlsyms"; then $show "$rm $output_objdir/${outputname}S.${objext}" $run $rm "$output_objdir/${outputname}S.${objext}" fi exit $status fi if test -n "$shlibpath_var"; then # We should set the shlibpath_var rpath= for dir in $temp_rpath; do case "$dir" in [\\/]* | [A-Za-z]:[\\/]*) # Absolute path. rpath="$rpath$dir:" ;; *) # Relative path: add a thisdir entry. rpath="$rpath\$thisdir/$dir:" ;; esac done temp_rpath="$rpath" fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do rpath="$rpath$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 $echo "$modename: \`$output' will be relinked during installation" 1>&2 else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname $show "$link_command" $run eval "$link_command" || exit $? # Now create the wrapper script. $show "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $echo for shipping. if test "X$echo" = "X$SHELL $0 --fallback-echo"; then case "$0" in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; *) qecho="$SHELL `pwd`/$0 --fallback-echo";; esac qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` else qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` fi # Only actually do things if our run command is non-null. if test -z "$run"; then # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) output=`echo $output|sed 's,.exe$,,'` ;; esac $rm $output trap "$rm $output; exit 1" 1 2 15 $echo > $output "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='sed -e 1s/^X//' sed_quote_subst='$sed_quote_subst' # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variable: link_against_libtool_libs='$link_against_libtool_libs' else # When we are sourced in execute mode, \$file and \$echo are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then echo=\"$qecho\" file=\"\$0\" # Make sure echo works. if test \"X\$1\" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then # Yippee, \$echo works! : else # Restart under the correct shell, and then maybe \$echo will work. exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} fi fi\ " $echo >> $output "\ # Find the directory that this script lives in. thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` done # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then echo >> $output "\ program=lt-'$outputname' progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || \\ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $mkdir \"\$progdir\" else $rm \"\$progdir/\$file\" fi" echo >> $output "\ # relink executable if necessary if test -n \"\$relink_command\"; then if (cd \"\$thisdir\" && eval \$relink_command); then : else $rm \"\$progdir/\$file\" exit 1 fi fi $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $rm \"\$progdir/\$program\"; $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } $rm \"\$progdir/\$file\" fi" else echo >> $output "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi echo >> $output "\ if test -f \"\$progdir/\$program\"; then" # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $echo >> $output "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var " fi # fixup the dll searchpath if we need to. if test -n "$dllsearchpath"; then $echo >> $output "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi $echo >> $output "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " case $host in *-*-cygwin* | *-*-mingw | *-*-os2*) # win32 systems need to use the prog path for dll # lookup to work $echo >> $output "\ exec \$progdir\\\\\$program \${1+\"\$@\"} " ;; *) $echo >> $output "\ # Export the path to the program. PATH=\"\$progdir:\$PATH\" export PATH exec \$program \${1+\"\$@\"} " ;; esac $echo >> $output "\ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" exit 1 fi else # The program doesn't exist. \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 \$echo \"This script is just a wrapper for \$program.\" 1>&2 echo \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " chmod +x $output fi exit 0 ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" $show "${rm}r $gentop" $run ${rm}r "$gentop" $show "mkdir $gentop" $run mkdir "$gentop" status=$? if test $status -ne 0 && test ! -d "$gentop"; then exit $status fi generated="$generated $gentop" # Add in members from convenience archives. for xlib in $addlibs; do # Extract the objects. case "$xlib" in [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; *) xabs=`pwd`"/$xlib" ;; esac xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` xdir="$gentop/$xlib" $show "${rm}r $xdir" $run ${rm}r "$xdir" $show "mkdir $xdir" $run mkdir "$xdir" status=$? if test $status -ne 0 && test ! -d "$xdir"; then exit $status fi $show "(cd $xdir && $AR x $xabs)" $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` done fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then eval cmds=\"$old_archive_from_new_cmds\" else # Ensure that we have .o objects in place incase we decided # not to build a shared library, and have fallen back to building # static libs even though --disable-static was passed! for oldobj in $oldobjs; do if test ! -f $oldobj; then obj=`$echo "X$oldobj" | $Xsed -e "$o2lo"` $show "${LN_S} $obj $oldobj" $run ${LN_S} $obj $oldobj || exit $? fi done eval cmds=\"$old_archive_cmds\" fi IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" done if test -n "$generated"; then $show "${rm}r$generated" $run ${rm}r$generated fi # Now create the libtool archive. case "$output" in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" $show "creating $output" if test -n "$xrpath"; then temp_xrpath= for libdir in $xrpath; do temp_xrpath="$temp_xrpath -R$libdir" done dependency_libs="$temp_xrpath $dependency_libs" fi # Only create the output if not a dry run. if test -z "$run"; then for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i fi $rm $output $echo > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$dlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Directory that this library needs to be installed in: libdir='$install_libdir'\ " done fi # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $? ;; esac exit 0 ;; # libtool install mode install) modename="$modename: install" # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then # Aesthetically quote it. arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` case "$arg" in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) arg="\"$arg\"" ;; esac install_prog="$arg " arg="$1" shift else install_prog= arg="$nonopt" fi # The real first argument should be the name of the installation program. # Aesthetically quote it. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case "$arg" in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) arg="\"$arg\"" ;; esac install_prog="$install_prog$arg" # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= for arg do if test -n "$dest"; then files="$files $dest" dest="$arg" continue fi case "$arg" in -d) isdir=yes ;; -f) prev="-f" ;; -g) prev="-g" ;; -m) prev="-m" ;; -o) prev="-o" ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then prev= else dest="$arg" continue fi ;; esac # Aesthetically quote the argument. arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` case "$arg" in *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) arg="\"$arg\"" ;; esac install_prog="$install_prog $arg" done if test -z "$install_prog"; then $echo "$modename: you must specify an install program" 1>&2 $echo "$help" 1>&2 exit 1 fi if test -n "$prev"; then $echo "$modename: the \`$prev' option requires an argument" 1>&2 $echo "$help" 1>&2 exit 1 fi if test -z "$files"; then if test -z "$dest"; then $echo "$modename: no file or destination specified" 1>&2 else $echo "$modename: you must specify a destination" 1>&2 fi $echo "$help" 1>&2 exit 1 fi # Strip any trailing slash from the destination. dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` test "X$destdir" = "X$dest" && destdir=. destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` # Not a directory, so check to see that there is only one file specified. set dummy $files if test $# -gt 2; then $echo "$modename: \`$dest' is not a directory" 1>&2 $echo "$help" 1>&2 exit 1 fi fi case "$destdir" in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case "$file" in *.lo) ;; *) $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 $echo "$help" 1>&2 exit 1 ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case "$file" in *.a | *.lib) # Do the static libraries later. staticlibs="$staticlibs $file" ;; *.la) # Check to see that this really is a libtool archive. if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 exit 1 fi library_names= old_library= # If there is no directory component, then add one. case "$file" in */* | *\\*) . $file ;; *) . ./$file ;; esac # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) current_libdirs="$current_libdirs $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs="$future_libdirs $libdir" ;; esac fi dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/" test "X$dir" = "X$file/" && dir= dir="$dir$objdir" # See the names of the shared library. set dummy $library_names if test -n "$2"; then realname="$2" shift shift # Install the shared library and build the symlinks. $show "$install_prog $dir/$realname $destdir/$realname" $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $? test "X$dlname" = "X$realname" && dlname= if test $# -gt 0; then # Delete the old symlinks, and create new ones. for linkname do test "X$dlname" = "X$linkname" && dlname= if test "$linkname" != "$realname"; then $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" fi done fi if test -n "$dlname"; then # Install the dynamically-loadable library. $show "$install_prog $dir/$dlname $destdir/$dlname" $run eval "$install_prog $dir/$dlname $destdir/$dlname" || exit $? fi # Do each command in the postinstall commands. lib="$destdir/$realname" eval cmds=\"$postinstall_cmds\" IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" fi # Install the pseudo-library for information purposes. name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` instname="$dir/$name"i $show "$install_prog $instname $destdir/$name" $run eval "$install_prog $instname $destdir/$name" || exit $? # Maybe install the static library, too. test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case "$destfile" in *.lo) staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` ;; *.o | *.obj) staticdest="$destfile" destfile= ;; *) $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 $echo "$help" 1>&2 exit 1 ;; esac # Install the libtool object if requested. if test -n "$destfile"; then $show "$install_prog $file $destfile" $run eval "$install_prog $file $destfile" || exit $? fi # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` $show "$install_prog $staticobj $staticdest" $run eval "$install_prog \$staticobj \$staticdest" || exit $? fi exit 0 ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` destfile="$destdir/$destfile" fi # Do a test to see if this is really a libtool program. if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then link_against_libtool_libs= relink_command= # If there is no directory component, then add one. case "$file" in */* | *\\*) . $file ;; *) . ./$file ;; esac # Check the variables that should have been set. if test -z "$link_against_libtool_libs"; then $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 exit 1 fi finalize=yes for lib in $link_against_libtool_libs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then # If there is no directory component, then add one. case "$lib" in */* | *\\*) . $lib ;; *) . ./$lib ;; esac fi libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`" if test -n "$libdir" && test ! -f "$libfile"; then $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 finalize=no fi done outputname= if test "$fast_install" = no && test -n "$relink_command"; then if test "$finalize" = yes && test -z "$run"; then tmpdir="/tmp" test -n "$TMPDIR" && tmpdir="$TMPDIR" tmpdir="$tmpdir/libtool-$$" if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : else $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 continue fi outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` $show "$relink_command" if $run eval "$relink_command"; then : else $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 ${rm}r "$tmpdir" continue fi file="$outputname" else $echo "$modename: warning: cannot relink \`$file'" 1>&2 fi else # Install the binary that we compiled earlier. file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` fi fi $show "$install_prog$stripme $file $destfile" $run eval "$install_prog\$stripme \$file \$destfile" || exit $? test -n "$outputname" && ${rm}r "$tmpdir" ;; esac done for file in $staticlibs; do name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` # Set up the ranlib parameters. oldlib="$destdir/$name" $show "$install_prog $file $oldlib" $run eval "$install_prog \$file \$oldlib" || exit $? # Do each command in the postinstall commands. eval cmds=\"$old_postinstall_cmds\" IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || exit $? done IFS="$save_ifs" done if test -n "$future_libdirs"; then $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 fi if test -n "$current_libdirs"; then # Maybe just do a dry run. test -n "$run" && current_libdirs=" -n$current_libdirs" exec $SHELL $0 --finish$current_libdirs exit 1 fi exit 0 ;; # libtool finish mode finish) modename="$modename: finish" libdirs="$nonopt" admincmds= if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for dir do libdirs="$libdirs $dir" done for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. eval cmds=\"$finish_cmds\" IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" || admincmds="$admincmds $cmd" done IFS="$save_ifs" fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $run eval "$cmds" || admincmds="$admincmds $cmds" fi done fi # Exit here if they wanted silent mode. test "$show" = : && exit 0 echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do echo " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" echo " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then echo " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" echo "more information, such as the ld(1) and ld.so(8) manual pages." echo "----------------------------------------------------------------------" exit 0 ;; # libtool execute mode execute) modename="$modename: execute" # The first argument is the command name. cmd="$nonopt" if test -z "$cmd"; then $echo "$modename: you must specify a COMMAND" 1>&2 $echo "$help" exit 1 fi # Handle -dlopen flags immediately. for file in $execute_dlfiles; do if test ! -f "$file"; then $echo "$modename: \`$file' is not a file" 1>&2 $echo "$help" 1>&2 exit 1 fi dir= case "$file" in *.la) # Check to see that this really is a libtool archive. if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : else $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 $echo "$help" 1>&2 exit 1 fi # Read the libtool library. dlname= library_names= # If there is no directory component, then add one. case "$file" in */* | *\\*) . $file ;; *) . ./$file ;; esac # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" continue fi dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. if test -f "$dir/$objdir/$dlname"; then dir="$dir/$objdir" else $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 exit 1 fi ;; *.lo) # Just add the directory containing the .lo file. dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. ;; *) $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case "$file" in -*) ;; *) # Do a test to see if this is really a libtool program. if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then # If there is no directory component, then add one. case "$file" in */* | *\\*) . $file ;; *) . ./$file ;; esac # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` args="$args \"$file\"" done if test -z "$run"; then # Export the shlibpath_var. eval "export $shlibpath_var" # Restore saved enviroment variables if test "${save_LC_ALL+set}" = set; then LC_ALL="$save_LC_ALL"; export LC_ALL fi if test "${save_LANG+set}" = set; then LANG="$save_LANG"; export LANG fi # Now actually exec the command. eval "exec \$cmd$args" $echo "$modename: cannot exec \$cmd$args" exit 1 else # Display what would be done. eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" $echo "export $shlibpath_var" $echo "$cmd$args" exit 0 fi ;; # libtool uninstall mode uninstall) modename="$modename: uninstall" rm="$nonopt" files= for arg do case "$arg" in -*) rm="$rm $arg" ;; *) files="$files $arg" ;; esac done if test -z "$rm"; then $echo "$modename: you must specify an RM program" 1>&2 $echo "$help" 1>&2 exit 1 fi for file in $files; do dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` test "X$dir" = "X$file" && dir=. name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` rmfiles="$file" case "$name" in *.la) # Possibly a libtool archive, so verify it. if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then . $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do rmfiles="$rmfiles $dir/$n" test "X$n" = "X$dlname" && dlname= done test -n "$dlname" && rmfiles="$rmfiles $dir/$dlname" test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library" $show "$rm $rmfiles" $run $rm $rmfiles if test -n "$library_names"; then # Do each command in the postuninstall commands. eval cmds=\"$postuninstall_cmds\" IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" done IFS="$save_ifs" fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. eval cmds=\"$old_postuninstall_cmds\" IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" $show "$cmd" $run eval "$cmd" done IFS="$save_ifs" fi # FIXME: should reinstall the best remaining shared library. fi ;; *.lo) if test "$build_old_libs" = yes; then oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` rmfiles="$rmfiles $dir/$oldobj" fi $show "$rm $rmfiles" $run $rm $rmfiles ;; *) $show "$rm $rmfiles" $run $rm $rmfiles ;; esac done exit 0 ;; "") $echo "$modename: you must specify a MODE" 1>&2 $echo "$generic_help" 1>&2 exit 1 ;; esac $echo "$modename: invalid operation mode \`$mode'" 1>&2 $echo "$generic_help" 1>&2 exit 1 fi # test -z "$show_help" # We need to display help for each of the modes. case "$mode" in "") $echo \ "Usage: $modename [OPTION]... [MODE-ARG]... Provide generalized library-building support services. --config show all configuration variables --debug enable verbose shell tracing -n, --dry-run display commands without modifying any files --features display basic configuration information and exit --finish same as \`--mode=finish' --help display this help message and exit --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] --quiet same as \`--silent' --silent don't print informational messages --version print version information MODE must be one of the following: compile compile a source file into a libtool object execute automatically set library path, then run a program finish complete the installation of libtool libraries install install libraries or executables link create a library or an executable uninstall remove libraries from an installed directory MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for a more detailed description of MODE." exit 0 ;; compile) $echo \ "Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -static always build a \`.o' file suitable for static linking COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $echo \ "Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $echo \ "Usage: $modename [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $echo \ "Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $echo \ "Usage: $modename [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -static do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $echo \ "Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) $echo "$modename: invalid operation mode \`$mode'" 1>&2 $echo "$help" 1>&2 exit 1 ;; esac echo $echo "Try \`$modename --help' for more information about other modes." exit 0 # Local Variables: # mode:shell-script # sh-indentation:2 # End: ./shapelib-1.2.10/makefile.vc0100644000076500001440000000311307644273432015366 0ustar warmerdausers #CFLAGS = /DSHPAPI_CALL=__stdcall default: all all: shpcreate.exe shpadd.exe shpdump.exe shprewind.exe dbfcreate.exe \ dbfadd.exe dbfdump.exe shptest.exe shptreedump.exe shapelib.dll shpopen.obj: shpopen.c shapefil.h $(CC) $(CFLAGS) -c shpopen.c shptree.obj: shptree.c shapefil.h $(CC) $(CFLAGS) -c shptree.c dbfopen.obj: dbfopen.c shapefil.h $(CC) $(CFLAGS) -c dbfopen.c shpcreate.exe: shpcreate.c shpopen.obj $(CC) $(CFLAGS) shpcreate.c shpopen.obj $(LINKOPT) -o shpcreate shpadd.exe: shpadd.c shpopen.obj $(CC) $(CFLAGS) shpadd.c shpopen.obj $(LINKOPT) shpdump.exe: shpdump.c shpopen.obj $(CC) $(CFLAGS) shpdump.c shpopen.obj $(LINKOPT) shprewind.exe: shprewind.c shpopen.obj $(CC) $(CFLAGS) shprewind.c shpopen.obj $(LINKOPT) dbfcreate.exe: dbfcreate.c dbfopen.obj $(CC) $(CFLAGS) dbfcreate.c dbfopen.obj $(LINKOPT) dbfadd.exe: dbfadd.c dbfopen.obj $(CC) $(CFLAGS) dbfadd.c dbfopen.obj $(LINKOPT) dbfdump.exe: dbfdump.c dbfopen.obj $(CC) $(CFLAGS) dbfdump.c dbfopen.obj $(LINKOPT) shptest.exe: shptest.c shpopen.obj $(CC) $(CFLAGS) shptest.c shpopen.obj $(LINKOPT) shputils.exe: shputils.c shpopen.obj dbfopen.obj $(CC) $(CFLAGS) shputils.c shpopen.obj dbfopen.obj $(LINKOPT) shptreedump.exe: shptreedump.c shptree.obj shpopen.obj $(CC) $(CFLAGS) shptreedump.c shptree.obj shpopen.obj $(LINKOPT) clean: -del *.obj dbfdump dbfcreate dbfadd shpdump shpcreate shpadd shputils -del *.lib -del *.dll shapelib.dll: shpopen.obj dbfopen.obj shptree.obj shapelib.def link /dll /def:shapelib.def /out:shapelib.dll /implib:shapelib.lib \ shpopen.obj dbfopen.obj shptree.obj ./shapelib-1.2.10/makeshape.sh0100755000076500001440000000101107644273432015547 0ustar warmerdausers#!/bin/sh # # Use example programs to create a very simple dataset that # should display in ARCView II. # shpcreate test polygon dbfcreate test.dbf -s Description 30 -n TestInt 6 0 -n TestDouble 16 5 shpadd test 0 0 100 0 100 100 0 100 0 0 + 20 20 20 30 30 30 20 20 dbfadd test.dbf "Square with triangle missing" 1.5 2.5 shpadd test 150 150 160 150 180 170 150 150 dbfadd test.dbf "Smaller triangle" 100 1000.25 shpadd test 150 150 160 150 180 170 150 150 dbfadd test.dbf "" "" "" shpdump test.shp dbfdump test.dbf ./shapelib-1.2.10/mkinstalldirs0100644000076500001440000000122707644273432016066 0ustar warmerdausers#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here ./shapelib-1.2.10/shapefil.h0100644000076500001440000004003207644273432015224 0ustar warmerdausers#ifndef _SHAPEFILE_H_INCLUDED #define _SHAPEFILE_H_INCLUDED /****************************************************************************** * $Id: shapefil.h,v 1.26 2002/09/29 00:00:08 warmerda Exp $ * * Project: Shapelib * Purpose: Primary include file for Shapelib. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: shapefil.h,v $ * Revision 1.26 2002/09/29 00:00:08 warmerda * added FTLogical and logical attribute read/write calls * * Revision 1.25 2002/05/07 13:46:30 warmerda * added DBFWriteAttributeDirectly(). * * Revision 1.24 2002/04/10 16:59:54 warmerda * added SHPRewindObject * * Revision 1.23 2002/01/15 14:36:07 warmerda * updated email address * * Revision 1.22 2002/01/15 14:32:00 warmerda * try to improve SHPAPI_CALL docs * * Revision 1.21 2001/11/01 16:29:55 warmerda * move pabyRec into SHPInfo for thread safety * * Revision 1.20 2001/07/20 13:06:02 warmerda * fixed SHPAPI attribute for SHPTreeFindLikelyShapes * * Revision 1.19 2001/05/31 19:20:13 warmerda * added DBFGetFieldIndex() * * Revision 1.18 2001/05/31 18:15:40 warmerda * Added support for NULL fields in DBF files * * Revision 1.17 2001/05/23 13:36:52 warmerda * added use of SHPAPI_CALL * * Revision 1.16 2000/09/25 14:15:59 warmerda * added DBFGetNativeFieldType() * * Revision 1.15 2000/02/16 16:03:51 warmerda * added null shape support * * Revision 1.14 1999/11/05 14:12:05 warmerda * updated license terms * * Revision 1.13 1999/06/02 18:24:21 warmerda * added trimming code * * Revision 1.12 1999/06/02 17:56:12 warmerda * added quad'' subnode support for trees * * Revision 1.11 1999/05/18 19:11:11 warmerda * Added example searching capability * * Revision 1.10 1999/05/18 17:49:38 warmerda * added initial quadtree support * * Revision 1.9 1999/05/11 03:19:28 warmerda * added new Tuple api, and improved extension handling - add from candrsn * * Revision 1.8 1999/03/23 17:22:27 warmerda * Added extern "C" protection for C++ users of shapefil.h. * * Revision 1.7 1998/12/31 15:31:07 warmerda * Added the TRIM_DBF_WHITESPACE and DISABLE_MULTIPATCH_MEASURE options. * * Revision 1.6 1998/12/03 15:48:15 warmerda * Added SHPCalculateExtents(). * * Revision 1.5 1998/11/09 20:57:16 warmerda * Altered SHPGetInfo() call. * * Revision 1.4 1998/11/09 20:19:33 warmerda * Added 3D support, and use of SHPObject. * * Revision 1.3 1995/08/23 02:24:05 warmerda * Added support for reading bounds. * * Revision 1.2 1995/08/04 03:17:39 warmerda * Added header. * */ #include #ifdef USE_DBMALLOC #include #endif #ifdef __cplusplus extern "C" { #endif /************************************************************************/ /* Configuration options. */ /************************************************************************/ /* -------------------------------------------------------------------- */ /* Should the DBFReadStringAttribute() strip leading and */ /* trailing white space? */ /* -------------------------------------------------------------------- */ #define TRIM_DBF_WHITESPACE /* -------------------------------------------------------------------- */ /* Should we write measure values to the Multipatch object? */ /* Reportedly ArcView crashes if we do write it, so for now it */ /* is disabled. */ /* -------------------------------------------------------------------- */ #define DISABLE_MULTIPATCH_MEASURE /* -------------------------------------------------------------------- */ /* SHPAPI_CALL */ /* */ /* The following two macros are present to allow forcing */ /* various calling conventions on the Shapelib API. */ /* */ /* To force __stdcall conventions (needed to call Shapelib */ /* from Visual Basic and/or Dephi I believe) the makefile could */ /* be modified to define: */ /* */ /* /DSHPAPI_CALL=__stdcall */ /* */ /* If it is desired to force export of the Shapelib API without */ /* using the shapelib.def file, use the following definition. */ /* */ /* /DSHAPELIB_DLLEXPORT */ /* */ /* To get both at once it will be necessary to hack this */ /* include file to define: */ /* */ /* #define SHPAPI_CALL __declspec(dllexport) __stdcall */ /* #define SHPAPI_CALL1 __declspec(dllexport) * __stdcall */ /* */ /* The complexity of the situtation is partly caused by the */ /* peculiar requirement of Visual C++ that __stdcall appear */ /* after any "*"'s in the return value of a function while the */ /* __declspec(dllexport) must appear before them. */ /* -------------------------------------------------------------------- */ #ifdef SHAPELIB_DLLEXPORT # define SHPAPI_CALL __declspec(dllexport) # define SHPAPI_CALL1(x) __declspec(dllexport) x #endif #ifndef SHPAPI_CALL # define SHPAPI_CALL #endif #ifndef SHPAPI_CALL1 # define SHPAPI_CALL1(x) x SHPAPI_CALL #endif /************************************************************************/ /* SHP Support. */ /************************************************************************/ typedef struct { FILE *fpSHP; FILE *fpSHX; int nShapeType; /* SHPT_* */ int nFileSize; /* SHP file */ int nRecords; int nMaxRecords; int *panRecOffset; int *panRecSize; double adBoundsMin[4]; double adBoundsMax[4]; int bUpdated; unsigned char *pabyRec; int nBufSize; } SHPInfo; typedef SHPInfo * SHPHandle; /* -------------------------------------------------------------------- */ /* Shape types (nSHPType) */ /* -------------------------------------------------------------------- */ #define SHPT_NULL 0 #define SHPT_POINT 1 #define SHPT_ARC 3 #define SHPT_POLYGON 5 #define SHPT_MULTIPOINT 8 #define SHPT_POINTZ 11 #define SHPT_ARCZ 13 #define SHPT_POLYGONZ 15 #define SHPT_MULTIPOINTZ 18 #define SHPT_POINTM 21 #define SHPT_ARCM 23 #define SHPT_POLYGONM 25 #define SHPT_MULTIPOINTM 28 #define SHPT_MULTIPATCH 31 /* -------------------------------------------------------------------- */ /* Part types - everything but SHPT_MULTIPATCH just uses */ /* SHPP_RING. */ /* -------------------------------------------------------------------- */ #define SHPP_TRISTRIP 0 #define SHPP_TRIFAN 1 #define SHPP_OUTERRING 2 #define SHPP_INNERRING 3 #define SHPP_FIRSTRING 4 #define SHPP_RING 5 /* -------------------------------------------------------------------- */ /* SHPObject - represents on shape (without attributes) read */ /* from the .shp file. */ /* -------------------------------------------------------------------- */ typedef struct { int nSHPType; int nShapeId; /* -1 is unknown/unassigned */ int nParts; int *panPartStart; int *panPartType; int nVertices; double *padfX; double *padfY; double *padfZ; double *padfM; double dfXMin; double dfYMin; double dfZMin; double dfMMin; double dfXMax; double dfYMax; double dfZMax; double dfMMax; } SHPObject; /* -------------------------------------------------------------------- */ /* SHP API Prototypes */ /* -------------------------------------------------------------------- */ SHPHandle SHPAPI_CALL SHPOpen( const char * pszShapeFile, const char * pszAccess ); SHPHandle SHPAPI_CALL SHPCreate( const char * pszShapeFile, int nShapeType ); void SHPAPI_CALL SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType, double * padfMinBound, double * padfMaxBound ); SHPObject SHPAPI_CALL1(*) SHPReadObject( SHPHandle hSHP, int iShape ); int SHPAPI_CALL SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject ); void SHPAPI_CALL SHPDestroyObject( SHPObject * psObject ); void SHPAPI_CALL SHPComputeExtents( SHPObject * psObject ); SHPObject SHPAPI_CALL1(*) SHPCreateObject( int nSHPType, int nShapeId, int nParts, int * panPartStart, int * panPartType, int nVertices, double * padfX, double * padfY, double * padfZ, double * padfM ); SHPObject SHPAPI_CALL1(*) SHPCreateSimpleObject( int nSHPType, int nVertices, double * padfX, double * padfY, double * padfZ ); int SHPAPI_CALL SHPRewindObject( SHPHandle hSHP, SHPObject * psObject ); void SHPAPI_CALL SHPClose( SHPHandle hSHP ); const char SHPAPI_CALL1(*) SHPTypeName( int nSHPType ); const char SHPAPI_CALL1(*) SHPPartTypeName( int nPartType ); /* -------------------------------------------------------------------- */ /* Shape quadtree indexing API. */ /* -------------------------------------------------------------------- */ /* this can be two or four for binary or quad tree */ #define MAX_SUBNODE 4 typedef struct shape_tree_node { /* region covered by this node */ double adfBoundsMin[4]; double adfBoundsMax[4]; /* list of shapes stored at this node. The papsShapeObj pointers or the whole list can be NULL */ int nShapeCount; int *panShapeIds; SHPObject **papsShapeObj; int nSubNodes; struct shape_tree_node *apsSubNode[MAX_SUBNODE]; } SHPTreeNode; typedef struct { SHPHandle hSHP; int nMaxDepth; int nDimension; SHPTreeNode *psRoot; } SHPTree; SHPTree SHPAPI_CALL1(*) SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth, double *padfBoundsMin, double *padfBoundsMax ); void SHPAPI_CALL SHPDestroyTree( SHPTree * hTree ); int SHPAPI_CALL SHPWriteTree( SHPTree *hTree, const char * pszFilename ); SHPTree SHPAPI_CALL SHPReadTree( const char * pszFilename ); int SHPAPI_CALL SHPTreeAddObject( SHPTree * hTree, SHPObject * psObject ); int SHPAPI_CALL SHPTreeAddShapeId( SHPTree * hTree, SHPObject * psObject ); int SHPAPI_CALL SHPTreeRemoveShapeId( SHPTree * hTree, int nShapeId ); void SHPAPI_CALL SHPTreeTrimExtraNodes( SHPTree * hTree ); int SHPAPI_CALL1(*) SHPTreeFindLikelyShapes( SHPTree * hTree, double * padfBoundsMin, double * padfBoundsMax, int * ); int SHPAPI_CALL SHPCheckBoundsOverlap( double *, double *, double *, double *, int ); /************************************************************************/ /* DBF Support. */ /************************************************************************/ typedef struct { FILE *fp; int nRecords; int nRecordLength; int nHeaderLength; int nFields; int *panFieldOffset; int *panFieldSize; int *panFieldDecimals; char *pachFieldType; char *pszHeader; int nCurrentRecord; int bCurrentRecordModified; char *pszCurrentRecord; int bNoHeader; int bUpdated; } DBFInfo; typedef DBFInfo * DBFHandle; typedef enum { FTString, FTInteger, FTDouble, FTLogical, FTInvalid } DBFFieldType; #define XBASE_FLDHDR_SZ 32 DBFHandle SHPAPI_CALL DBFOpen( const char * pszDBFFile, const char * pszAccess ); DBFHandle SHPAPI_CALL DBFCreate( const char * pszDBFFile ); int SHPAPI_CALL DBFGetFieldCount( DBFHandle psDBF ); int SHPAPI_CALL DBFGetRecordCount( DBFHandle psDBF ); int SHPAPI_CALL DBFAddField( DBFHandle hDBF, const char * pszFieldName, DBFFieldType eType, int nWidth, int nDecimals ); DBFFieldType SHPAPI_CALL DBFGetFieldInfo( DBFHandle psDBF, int iField, char * pszFieldName, int * pnWidth, int * pnDecimals ); int SHPAPI_CALL DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName); int SHPAPI_CALL DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField ); double SHPAPI_CALL DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField ); const char SHPAPI_CALL1(*) DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField ); const char SHPAPI_CALL1(*) DBFReadLogicalAttribute( DBFHandle hDBF, int iShape, int iField ); int SHPAPI_CALL DBFIsAttributeNULL( DBFHandle hDBF, int iShape, int iField ); int SHPAPI_CALL DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField, int nFieldValue ); int SHPAPI_CALL DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField, double dFieldValue ); int SHPAPI_CALL DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField, const char * pszFieldValue ); int SHPAPI_CALL DBFWriteNULLAttribute( DBFHandle hDBF, int iShape, int iField ); int SHPAPI_CALL DBFWriteLogicalAttribute( DBFHandle hDBF, int iShape, int iField, const char lFieldValue); int SHPAPI_CALL DBFWriteAttributeDirectly(DBFHandle psDBF, int hEntity, int iField, void * pValue ); const char SHPAPI_CALL1(*) DBFReadTuple(DBFHandle psDBF, int hEntity ); int SHPAPI_CALL DBFWriteTuple(DBFHandle psDBF, int hEntity, void * pRawTuple ); DBFHandle SHPAPI_CALL DBFCloneEmpty(DBFHandle psDBF, const char * pszFilename ); void SHPAPI_CALL DBFClose( DBFHandle hDBF ); char SHPAPI_CALL DBFGetNativeFieldType( DBFHandle hDBF, int iField ); #ifdef __cplusplus } #endif #endif /* ndef _SHAPEFILE_H_INCLUDED */ ./shapelib-1.2.10/shapelib.def0100644000076500001440000000133107644273432015526 0ustar warmerdausersLIBRARY shapelib EXPORTS SHPOpen SHPCreate SHPGetInfo SHPReadObject SHPWriteObject SHPDestroyObject SHPComputeExtents SHPCreateObject SHPCreateSimpleObject SHPClose SHPTypeName SHPPartTypeName SHPCreateTree SHPDestroyTree SHPTreeAddShapeId SHPTreeTrimExtraNodes SHPTreeFindLikelyShapes SHPCheckBoundsOverlap DBFOpen DBFCreate DBFGetFieldCount DBFGetRecordCount DBFAddField DBFGetFieldInfo DBFReadIntegerAttribute DBFReadDoubleAttribute DBFReadStringAttribute DBFWriteIntegerAttribute DBFWriteDoubleAttribute DBFWriteStringAttribute DBFReadTuple DBFWriteTuple DBFCloneEmpty DBFClose DBFWriteNULLAttribute DBFGetFieldIndex DBFIsAttributeNULL DBFWriteLogicalAttribute DBFReadLogicalAttribute ./shapelib-1.2.10/shapelib.html0100644000076500001440000003222507644273432015742 0ustar warmerdausers Shapefile C Library V1.2

Shapefile C Library V1.2

Purpose

The Shapefile C Library provides the ability to write simple C programs for reading, writing and updating (to a limited extent) ESRI Shapefiles, and the associated attribute file (.dbf).

Manifest

  • shapelib.html: This file - general documentation on the Shapefile C Library.

  • shp_api.html: Documentation for the API for accessing the .shp/.shx files.

  • dbf_api.html: Documentation for the API for accessing the .dbf attribute files.

  • shpopen.c: C code for access to .shp/.shx vertex files.

  • dbfopen.c: C code for access to .dbf attribute file.

  • shapefil.h: Include file defining all the services of dbfopen.c and shpopen.c.

  • contrib/: A directory of "in progress" contributed programs from Carl Anderson.

  • dbfcreate.c: Simple example program for creating a new .dbf file.

  • dbfadd.c: Simple example program for adding a record to a .dbf file.

  • dbfdump.c: Simple example program for displaying the contents of a .dbf file.

  • shpcreate.c: Simple example program for creating a new .shp and .shx file.

  • shpadd.c: Simple example program for adding a shape to an existing shape file.

  • shpdump.c: Simple program for dumping all the vertices in a shapefile with an indicating of the parts.

  • shputils.c: Complex contributed program capable of clipping and appending shapefiles as well as a few other things. Type shputils after building to get a full usage message.

  • Makefile: A simple makefile to compile the library and example programs.

  • makeshape.sh: A simple script for running some of the example programs.

  • shptest.c: A simple test harnass to generate each of the supported types of shapefiles.

  • shptree.c: Implements a simple quadtree algorithm for fast spatial searches of shapefiles.

  • shptreedump.c: A simple mainly showing information on quad trees build using the quad tree api.

  • stream1.sh - A test script, which should produce stream1.out. Note this will only work if you have the example data downloaded.

  • stream1.out: Expected output of stream1.sh test script.

  • stream2.sh: A test script, which should produce stream2.out.

  • stream2.out: Expected output of stream2.sh test script.

  • pyshapelib-0.1: Prototype contributed Python bindings.

What is a Shapefile?

If you don't know, you probably don't need this library. The Shapefile format is a new working and interchange format promulagated by ESRI (http://www.esri.com/) for simple vector data with attributes. It is apparently the only file format that can be edited in ARCView 2/3, and can also be exported and imported in Arc/Info.

An excellent white paper on the shapefile format is available from ESRI, but it is .pdf format, so you will need Adobe Acrobat to browse it.

The file format actually consists of three files.

XXX.shp - holds the actual vertices.
XXX.shx - hold index data pointing to the structures in the .shp file.
XXX.dbf - holds the attributes in xBase (dBase) format.  

Release Notes

To get notification of new releases of Shapelib subscribe to the project at www.freshmeat.net. This is currently the only reliable way of finding out about new releases since there is no shapelib specific mailing list.

Release 1.2.10: Added SHPRewindObject() function, and shprewind utility program. Added FTLogical, DBFReadLogicalAttribute() and DBFWriteLogicalAttribute() (thanks to Olek Neyman).

Release 1.2.9: Good support for reading and writing NULL fields in .dbf files, good support for NULL shapes and addition of the DBFGetFieldIndex() functions (all contributed by Jim Matthews).

An upgraded shputils.c has been contributed by Bill Miller. Daniel Morissette contributed DBFGetNativeFieldType(). Better error checking for disk errors in dbfopen.c. Various other bug fixes and safety improvements.

Release 1.2.8: Added hacked libtool support (supplied by Jan) and "rpm ready" install logic.

Release 1.2.7: Fix record size (was 4 bytes too long). Modify SHPReadObject() to handle null shapes properly. Use atof() instead of sscanf(). Support .DBF as well as .dbf.

Release 1.2.6: Now available under old MIT style license, or at the users option, LGPL. Added the contrib directory of stuff from Carl Anderson and the shptree.c API for quadtree based spatial searches.

Release 1.2.5: SHPOpen() now forcably uses "rb" or "r+b" access string to avoid common mistakes on Windows. Also fixed a serious bug with .dbf files with a 'F' field type.

Release 1.2.4: DBFOpen() will now automatically translate a .shp extension to .dbf for convenience. SHPOpen() will try datasets with lower and uppercase extension. DBFAddField() now returns the field number, not TRUE/FALSE.

Release 1.2.3: Disable writing measures to multi-patches as ArcView seems to puke on them (as reported by Monika Sester). Add white space trimming, and string/numeric attribute interchangability in DBF API as suggested by Steve Lime. Dbfdump was updated to include several reporting options.

Release 1.2.2: Added proper support for multipatch (reading and writing) - this release just for testing purposes.

Release 1.2 is mostly a rewrite of the .shp/.shx access API to account for ArcView 3.x 3D shapes, and to encapsulate the shapes in a structure. Existing code using the shapefile library will require substantial changes to use release 1.2.

Release V1.1 has been built on a number of platforms, and used by a number of people successfully. V1.1 is the first release with the xBase API documentation.

Maintainer

This library is maintained by me (Frank Warmerdam) on my own time. Please send me bug patches and suggestions for the library. Email can be sent to warmerdam@pobox.com.

The current status of the Shapelib code can be found at http://pobox.com/~warmerdam/root/projects/shapelib/. To find out about new releases of Shapelib, select the "Subscribe to new releases" option from the link at Freshmeat.

The shputils.c module was contributed by Bill Miller (NC-DOT) who can be reached at bmiller@doh.dot.state.nc.us. I had to modify it substantially to work with the 1.2 API, and I am not sure that it works as well as it did when it was originally provided by Bill.

Credits

I didn't start this section anywhere near soon enough, so alot of earlier contributors to Shapelib are lost in pre-history.
  • Bill Miller (NY-DOT) for shputils.c
  • Carl Anderson for the contents of the contrib directory, and the "tuple" additions to dbfopen.c.
  • Andrea Giacomelli for patches for dbfopen.c.
  • Doug Matthews for portability improvements.
  • Jan-Oliver Wagner for convincing me to make it available under LGPL, shared library support, and various other patches.
  • Dennis Christopher (of Avenza) for testing and bug fixes.
  • Miko Syrj (of 3D-system Oy) for a record size bug fix.
  • Steven Lime and Curtis Hill for help with NULL shapes.
  • Jim Matthews for support of NULL attributes in dbf files.
  • PCI Geomatics who let me release a modified version of their shapefile code in the beginning and who hosted shapelib for years.

In Memorium

I would like to dedicate Shapelib to the memory of Sol Katz. While I never met him in person, his generous contributions to the GIS community took many forms, including free distribution of a variety of GIS translators with source. The fact that he used this Shapelib in some of his utilities, and thanked me was a great encouragement to me. I hope I can do his memory honour by trying to contribute in a similar fashion.

Portability

The Shapefile C Library should port easily to 32bit systems with ANSI C compilers. It should work on 64 bit architectures (such as the DEC AXP).

Care should also be taken to pass the binary access flag into SHPOpen() and DBFOpen() when operating on systems with special text file translation such as MSDOS.

The shputils.c module is contributed, and may not take the same approach to portability as the rest of the package.

On Linux, and most unix systems it should be possible to build and install shapefile support as a shared library using the "lib" and "lib_install" targets of the Makefile. Note that this Makefile doesn't use autoconf mechanisms and will generally require some hand tailoring for your environment.

Limitations

  • You can't modify the vertices of existing structures (though you can update the attributes of existing structures, and create new structures).

  • Not written in such a way as to be particularly fast. This is particularly true of the 1.2 API. For applications more concerned with speed it may be worth using the V1.1 API.

  • Doesn't set the last access time properly in the .dbf files.

  • There is no way to synchronize information to the file except to close it.

  • Poor error checking and reporting.

  • Not professionally supported (well it can be, if you want to pay).

  • Some aspects of xBase files not supported, though I believe they are not used by ESRI.

  • The application must keep the .dbf file in sync with the .shp/.shx files through appropriate use of the DBF and SHP APIs.

  • No support for the undocumented .sbn/.sbx spatial index files.

Copyright

The source for the Shapefile C Library is (c) 1998 Frank Warmerdam, and released under the following conditions. The intent is that anyone can do anything with the code, but that I do not assume any liability, nor express any warranty for this code.

As of Shapelib 1.2.6 the core portions of the library are made available under two possible licenses. The licensee can choose to use the code under either the Library GNU Public License (LGPL) described in LICENSE.LGPL or under the following MIT style license. Any files in the Shapelib distribution without explicit copyright license terms (such as this documentation, the Makefile and so forth) should be considered to have the following licensing terms. Some auxilary portions of Shapelib, notably some of the components in the contrib directory come under slightly different license restrictions. Check the source files that you are actually using for conditions.

Default License Terms

Copyright (c) 1999, Frank Warmerdam

This software is available under the following "MIT Style" license, or at the option of the licensee under the LGPL (see LICENSE.LGPL). This option is discussed in more detail in shapelib.html.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Shapelib Modifications

I am pleased to receive bug fixes, and improvements for Shapelib. Unless the submissions indicate otherwise I will assume that changes submitted to me remain under the the above "dual license" terms. If changes are made to the library with the intention that those changes should be protected by the LGPL then I should be informed upon submission. Note that I will not generally incorporate changes into the core of Shapelib that are protected under the LGPL as this would effectively limit the whole file and distribution to LGPL terms.

Opting for LGPL

For licensee's opting to use Shapelib under LGPL as opposed to the MIT Style license above, and wishing to redistribute the software based on Shapelib, I would ask that all "dual license" modules be updated to indicate that only the LGPL (and not the MIT Style license) applies. This action represents opting for the LGPL, and thereafter LGPL terms apply to any redistribution and modification of the affected modules.

./shapelib-1.2.10/shp_api.html0100644000076500001440000003151107644273432015573 0ustar warmerdausers .SHP File API

.SHP File API

The .SHP API uses a SHPHandle to represent an open .shp/.shx file pair. The contents of the SHPHandle are visible (see shapefile.h) but should be ignored by the application. It is intended that all information be accessed by the API functions.

Shape Types

Shapes have types associated with them. The following is a list of the different shapetypes supported by Shapefiles. At this time all shapes in a Shapefile must be of the same type (with the exception of NULL shapes).

  #define SHPT_NULL             0

  2D Shape Types (pre ArcView 3.x):

  #define SHPT_POINT		1	Points
  #define SHPT_ARC		3	Arcs (Polylines, possible in parts)
  #define SHPT_POLYGON		5	Polygons (possible in parts)
  #define SHPT_MULTIPOINT	8	MultiPoint (related points)

  3D Shape Types (may include "measure" values for vertices):

  #define SHPT_POINTZ		11	
  #define SHPT_ARCZ		13
  #define SHPT_POLYGONZ		15
  #define SHPT_MULTIPOINTZ 	18

  2D + Measure Types:

  #define SHPT_POINTM		21
  #define SHPT_ARCM		23
  #define SHPT_POLYGONM		25
  #define SHPT_MULTIPOINTM 	28

  Complex (TIN-like) with Z, and Measure:

  #define SHPT_MULTIPATCH 	31

SHPObject

An individual shape is represented by the SHPObject structure. SHPObject's created with SHPCreateObject(), SHPCreateSimpleObject(), or SHPReadObject() should be disposed of with SHPDestroyObject().

  typedef struct
  {
    int		nSHPType;	Shape Type (SHPT_* - see list above)

    int		nShapeId; 	Shape Number (-1 is unknown/unassigned)

    int		nParts;		# of Parts (0 implies single part with no info)
    int		*panPartStart;  Start Vertex of part
    int		*panPartType;	Part Type (SHPP_RING if not SHPT_MULTIPATCH)
    
    int		nVertices;	Vertex list 
    double	*padfX;		
    double	*padfY;
    double	*padfZ;		(all zero if not provided)
    double	*padfM;		(all zero if not provided)

    double	dfXMin;		Bounds in X, Y, Z and M dimensions
    double	dfYMin;
    double	dfZMin;
    double	dfMMin;

    double	dfXMax;
    double	dfYMax;
    double	dfZMax;
    double	dfMMax;
  } SHPObject;

SHPOpen()

SHPHandle SHPOpen( const char * pszShapeFile, const char * pszAccess );

  pszShapeFile:		The name of the layer to access.  This can be the
			name of either the .shp or the .shx file or can
			just be the path plus the basename of the pair.

  pszAccess:		The fopen() style access string.  At this time only
			"rb" (read-only binary) and "rb+" (read/write binary) 
		        should be used.
The SHPOpen() function should be used to establish access to the two files for accessing vertices (.shp and .shx). Note that both files have to be in the indicated directory, and must have the expected extensions in lower case. The returned SHPHandle is passed to other access functions, and SHPClose() should be invoked to recover resources, and flush changes to disk when complete.

SHPGetInfo()

void SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
                 double * padfMinBound, double * padfMaxBound );

  hSHP:			The handle previously returned by SHPOpen() 
			or SHPCreate().

  pnEntities:		A pointer to an integer into which the number of
			entities/structures should be placed.  May be NULL.

  pnShapetype:		A pointer to an integer into which the shapetype
			of this file should be placed.  Shapefiles may contain
			either SHPT_POINT, SHPT_ARC, SHPT_POLYGON or 
			SHPT_MULTIPOINT entities.  This may be NULL.

  padfMinBound:		The X, Y, Z and M minimum values will be placed into
                        this four entry array.  This may be NULL.
			
  padfMaxBound:		The X, Y, Z and M maximum values will be placed into
                        this four entry array.  This may be NULL.
The SHPGetInfo() function retrieves various information about shapefile as a whole. The bounds are read from the file header, and may be inaccurate if the file was improperly generated.

SHPReadObject()

SHPObject *SHPReadObject( SHPHandle hSHP, int iShape );

  hSHP:			The handle previously returned by SHPOpen() 
			or SHPCreate().

  iShape:		The entity number of the shape to read.  Entity 
			numbers are between 0 and nEntities-1 (as returned
			by SHPGetInfo()).
The SHPReadObject() call is used to read a single structure, or entity from the shapefile. See the definition of the SHPObject structure for detailed information on fields of a SHPObject. SHPObject's returned from SHPReadObject() should be deallocated with SHPDestroyShape(). SHPReadObject() will return NULL if an illegal iShape value is requested.

Note that the bounds placed into the SHPObject are those read from the file, and may not be correct. For points the bounds are generated from the single point since bounds aren't normally provided for point types.

Generally the shapes returned will be of the type of the file as a whole. However, any file may also contain type SHPT_NULL shapes which will have no geometry. Generally speaking applications should skip rather than preserve them, as they usually represented interactively deleted shapes.

SHPClose()

void	SHPClose( SHPHandle hSHP );

  hSHP:			The handle previously returned by SHPOpen() 
			or SHPCreate().
The SHPClose() function will close the .shp and .shx files, and flush all outstanding header information to the files. It will also recover resources associated with the handle. After this call the hSHP handle cannot be used again.

SHPCreate()

SHPHandle SHPCreate( const char * pszShapeFile, int nShapeType );

  pszShapeFile:		The name of the layer to access.  This can be the
			name of either the .shp or the .shx file or can
			just be the path plus the basename of the pair.

  nShapeType:		The type of shapes to be stored in the newly created
			file.  It may be either SHPT_POINT, SHPT_ARC, 
		        SHPT_POLYGON or SHPT_MULTIPOINT.
The SHPCreate() function will create a new .shp and .shx file of the desired type.

SHPCreateSimpleObject()

SHPObject * 
     SHPCreateSimpleObject( int nSHPType, int nVertices, 
			    double *padfX, double * padfY, double *padfZ, );

  nSHPType:		The SHPT_ type of the object to be created, such
                        as SHPT_POINT, or SHPT_POLYGON.
  
  nVertices:		The number of vertices being passed in padfX,    
                        padfY, and padfZ. 

  padfX:		An array of nVertices X coordinates of the vertices
                        for this object.

  padfY:		An array of nVertices Y coordinates of the vertices
                        for this object.

  padfZ:		An array of nVertices Z coordinates of the vertices
                        for this object.  This may be NULL in which case
		        they are all assumed to be zero.
The SHPCreateSimpleObject() allows for the convenient creation of simple objects. This is normally used so that the SHPObject can be passed to SHPWriteObject() to write it to the file. The simple object creation API assumes an M (measure) value of zero for each vertex. For complex objects (such as polygons) it is assumed that there is only one part, and that it is of the default type (SHPP_RING).

Use the SHPCreateObject() function for more sophisticated objects. The SHPDestroyObject() function should be used to free resources associated with an object allocated with SHPCreateSimpleObject().

This function computes a bounding box for the SHPObject from the given vertices.

SHPCreateObject()

SHPObject * 
     SHPCreateObject( int nSHPType, int iShape,
                      int nParts, int * panPartStart, int * panPartType,
                      int nVertices, double *padfX, double * padfY, 
                      double *padfZ, double *padfM );

  nSHPType:		The SHPT_ type of the object to be created, such
                        as SHPT_POINT, or SHPT_POLYGON.

  iShape:		The shapeid to be recorded with this shape.

  nParts:		The number of parts for this object.  If this is
                        zero for ARC, or POLYGON type objects, a single 
                        zero valued part will be created internally.
  
  panPartStart:		The list of zero based start vertices for the rings
                        (parts) in this object.  The first should always be
                        zero.  This may be NULL if nParts is 0.
  
  panPartType:		The type of each of the parts.  This is only meaningful
                        for MULTIPATCH files.  For all other cases this may
                        be NULL, and will be assumed to be SHPP_RING.
  
  nVertices:		The number of vertices being passed in padfX,    
                        padfY, and padfZ. 

  padfX:		An array of nVertices X coordinates of the vertices
                        for this object.

  padfY:		An array of nVertices Y coordinates of the vertices
                        for this object.

  padfZ:		An array of nVertices Z coordinates of the vertices
                        for this object.  This may be NULL in which case
		        they are all assumed to be zero.

  padfM:		An array of nVertices M (measure values) of the 
			vertices for this object.  This may be NULL in which 
			case they are all assumed to be zero.
The SHPCreateSimpleObject() allows for the creation of objects (shapes). This is normally used so that the SHPObject can be passed to SHPWriteObject() to write it to the file.

The SHPDestroyObject() function should be used to free resources associated with an object allocated with SHPCreateObject().

This function computes a bounding box for the SHPObject from the given vertices.

SHPComputeExtents()

void SHPComputeExtents( SHPObject * psObject );

  psObject:		An existing shape object to be updated in place.
This function will recompute the extents of this shape, replacing the existing values of the dfXMin, dfYMin, dfZMin, dfMMin, dfXMax, dfYMax, dfZMax, and dfMMax values based on the current set of vertices for the shape. This function is automatically called by SHPCreateObject() but if the vertices of an existing object are altered it should be called again to fix up the extents.

SHPWriteObject()

int SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject *psObject );

  hSHP:			The handle previously returned by SHPOpen("r+") 
			or SHPCreate().

  iShape:		The entity number of the shape to write.  A value of
		        -1 should be used for new shapes.  

  psObject:		The shape to write to the file. This should have
                        been created with SHPCreateObject(), or 
                        SHPCreateSimpleObject().
The SHPWriteObject() call is used to write a single structure, or entity to the shapefile. See the definition of the SHPObject structure for detailed information on fields of a SHPObject. The return value is the entity number of the written shape.

SHPDestroyObject()

void SHPDestroyObject( SHPObject *psObject );

  psObject:		The object to deallocate.
This function should be used to deallocate the resources associated with a SHPObject when it is no longer needed, including those created with SHPCreateSimpleObject(), SHPCreateObject() and returned from SHPReadObject().

SHPRewindObject()

int SHPRewindObject( SHPHandle hSHP, SHPObject *psObject );

  hSHP:                 The shapefile (not used at this time).
  psObject:		The object to deallocate.
This function will reverse any rings necessary in order to enforce the shapefile restrictions on the required order of inner and outer rings in the Shapefile specification. It returns TRUE if a change is made and FALSE if no change is made. Only polygon objects will be affected though any object may be passed.

./shapelib-1.2.10/shpadd.c0100644000076500001440000001266607644273432014703 0ustar warmerdausers/****************************************************************************** * $Id: shpadd.c,v 1.13 2002/01/15 14:36:07 warmerda Exp $ * * Project: Shapelib * Purpose: Sample application for adding a shape to a shapefile. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: shpadd.c,v $ * Revision 1.13 2002/01/15 14:36:07 warmerda * updated email address * * Revision 1.12 2001/05/31 19:35:29 warmerda * added support for writing null shapes * * Revision 1.11 2000/07/07 13:39:45 warmerda * removed unused variables, and added system include files * * Revision 1.10 2000/05/24 15:09:22 warmerda * Added logic to graw vertex lists of needed. * * Revision 1.9 1999/11/05 14:12:04 warmerda * updated license terms * * Revision 1.8 1998/12/03 16:36:26 warmerda * Use r+b rather than rb+ for binary access. * * Revision 1.7 1998/11/09 20:57:04 warmerda * Fixed SHPGetInfo() call. * * Revision 1.6 1998/11/09 20:19:16 warmerda * Changed to use SHPObject based API. * * Revision 1.5 1997/03/06 14:05:02 warmerda * fixed typo. * * Revision 1.4 1997/03/06 14:01:16 warmerda * added memory allocation checking, and free()s. * * Revision 1.3 1995/10/21 03:14:37 warmerda * Changed to use binary file access * * Revision 1.2 1995/08/04 03:18:01 warmerda * Added header. * */ static char rcsid[] = "$Id: shpadd.c,v 1.13 2002/01/15 14:36:07 warmerda Exp $"; #include #include #include "shapefil.h" int main( int argc, char ** argv ) { SHPHandle hSHP; int nShapeType, nVertices, nParts, *panParts, i, nVMax; double *padfX, *padfY; SHPObject *psObject; /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc < 2 ) { printf( "shpadd shp_file [[x y] [+]]*\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( argv[1], "r+b" ); if( hSHP == NULL ) { printf( "Unable to open:%s\n", argv[1] ); exit( 1 ); } SHPGetInfo( hSHP, NULL, &nShapeType, NULL, NULL ); if( argc == 2 ) nShapeType = SHPT_NULL; /* -------------------------------------------------------------------- */ /* Build a vertex/part list from the command line arguments. */ /* -------------------------------------------------------------------- */ nVMax = 1000; padfX = (double *) malloc(sizeof(double) * nVMax); padfY = (double *) malloc(sizeof(double) * nVMax); nVertices = 0; if( (panParts = (int *) malloc(sizeof(int) * 1000 )) == NULL ) { printf( "Out of memory\n" ); exit( 1 ); } nParts = 1; panParts[0] = 0; for( i = 2; i < argc; ) { if( argv[i][0] == '+' ) { panParts[nParts++] = nVertices; i++; } else if( i < argc-1 ) { if( nVertices == nVMax ) { nVMax = nVMax * 2; padfX = (double *) realloc(padfX,sizeof(double)*nVMax); padfY = (double *) realloc(padfY,sizeof(double)*nVMax); } sscanf( argv[i], "%lg", padfX+nVertices ); sscanf( argv[i+1], "%lg", padfY+nVertices ); nVertices += 1; i += 2; } } /* -------------------------------------------------------------------- */ /* Write the new entity to the shape file. */ /* -------------------------------------------------------------------- */ psObject = SHPCreateObject( nShapeType, -1, nParts, panParts, NULL, nVertices, padfX, padfY, NULL, NULL ); SHPWriteObject( hSHP, -1, psObject ); SHPDestroyObject( psObject ); SHPClose( hSHP ); free( panParts ); free( padfX ); free( padfY ); return 0; } ./shapelib-1.2.10/shpcreate.c0100644000076500001440000000723507644273432015412 0ustar warmerdausers/****************************************************************************** * $Id: shpcreate.c,v 1.5 2002/01/15 14:36:07 warmerda Exp $ * * Project: Shapelib * Purpose: Sample application for creating a new shapefile. * Author: Frank Warmerdam, warmerdm@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: shpcreate.c,v $ * Revision 1.5 2002/01/15 14:36:07 warmerda * updated email address * * Revision 1.4 2000/07/07 13:39:45 warmerda * removed unused variables, and added system include files * * Revision 1.3 1999/11/05 14:12:04 warmerda * updated license terms * * Revision 1.2 1995/08/04 03:16:43 warmerda * Added header. * */ static char rcsid[] = "$Id: shpcreate.c,v 1.5 2002/01/15 14:36:07 warmerda Exp $"; #include "shapefil.h" int main( int argc, char ** argv ) { SHPHandle hSHP; int nShapeType; /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc != 3 ) { printf( "shpcreate shp_file [point/arc/polygon/multipoint]\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Figure out the shape type. */ /* -------------------------------------------------------------------- */ if( strcmp(argv[2],"POINT") == 0 || strcmp(argv[2],"point") == 0 ) nShapeType = SHPT_POINT; else if( strcmp(argv[2],"ARC") == 0 || strcmp(argv[2],"arc") == 0 ) nShapeType = SHPT_ARC; else if( strcmp(argv[2],"POLYGON") == 0 || strcmp(argv[2],"polygon") == 0 ) nShapeType = SHPT_POLYGON; else if( strcmp(argv[2],"MULTIPOINT")==0 ||strcmp(argv[2],"multipoint")==0) nShapeType = SHPT_MULTIPOINT; else { printf( "Shape Type `%s' not recognised.\n", argv[2] ); exit( 2 ); } /* -------------------------------------------------------------------- */ /* Create the requested layer. */ /* -------------------------------------------------------------------- */ hSHP = SHPCreate( argv[1], nShapeType ); if( hSHP == NULL ) { printf( "Unable to create:%s\n", argv[1] ); exit( 3 ); } SHPClose( hSHP ); return 0; } ./shapelib-1.2.10/shpdump.c0100644000076500001440000001465007644273432015113 0ustar warmerdausers/****************************************************************************** * $Id: shpdump.c,v 1.10 2002/04/10 16:59:29 warmerda Exp $ * * Project: Shapelib * Purpose: Sample application for dumping contents of a shapefile to * the terminal in human readable form. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: shpdump.c,v $ * Revision 1.10 2002/04/10 16:59:29 warmerda * added -validate switch * * Revision 1.9 2002/01/15 14:36:07 warmerda * updated email address * * Revision 1.8 2000/07/07 13:39:45 warmerda * removed unused variables, and added system include files * * Revision 1.7 1999/11/05 14:12:04 warmerda * updated license terms * * Revision 1.6 1998/12/03 15:48:48 warmerda * Added report of shapefile type, and total number of shapes. * * Revision 1.5 1998/11/09 20:57:36 warmerda * use SHPObject. * * Revision 1.4 1995/10/21 03:14:49 warmerda * Changed to use binary file access. * * Revision 1.3 1995/08/23 02:25:25 warmerda * Added support for bounds. * * Revision 1.2 1995/08/04 03:18:11 warmerda * Added header. * */ static char rcsid[] = "$Id: shpdump.c,v 1.10 2002/04/10 16:59:29 warmerda Exp $"; #include "shapefil.h" int main( int argc, char ** argv ) { SHPHandle hSHP; int nShapeType, nEntities, i, iPart, bValidate = 0,nInvalidCount=0; const char *pszPlus; double adfMinBound[4], adfMaxBound[4]; if( argc > 1 && strcmp(argv[1],"-validate") == 0 ) { bValidate = 1; argv++; argc--; } /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc != 2 ) { printf( "shpdump [-validate] shp_file\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( argv[1], "rb" ); if( hSHP == NULL ) { printf( "Unable to open:%s\n", argv[1] ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Print out the file bounds. */ /* -------------------------------------------------------------------- */ SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound ); printf( "Shapefile Type: %s # of Shapes: %d\n\n", SHPTypeName( nShapeType ), nEntities ); printf( "File Bounds: (%12.3f,%12.3f,%g,%g)\n" " to (%12.3f,%12.3f,%g,%g)\n", adfMinBound[0], adfMinBound[1], adfMinBound[2], adfMinBound[3], adfMaxBound[0], adfMaxBound[1], adfMaxBound[2], adfMaxBound[3] ); /* -------------------------------------------------------------------- */ /* Skim over the list of shapes, printing all the vertices. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nEntities; i++ ) { int j; SHPObject *psShape; psShape = SHPReadObject( hSHP, i ); printf( "\nShape:%d (%s) nVertices=%d, nParts=%d\n" " Bounds:(%12.3f,%12.3f, %g, %g)\n" " to (%12.3f,%12.3f, %g, %g)\n", i, SHPTypeName(psShape->nSHPType), psShape->nVertices, psShape->nParts, psShape->dfXMin, psShape->dfYMin, psShape->dfZMin, psShape->dfMMin, psShape->dfXMax, psShape->dfYMax, psShape->dfZMax, psShape->dfMMax ); for( j = 0, iPart = 1; j < psShape->nVertices; j++ ) { const char *pszPartType = ""; if( j == 0 && psShape->nParts > 0 ) pszPartType = SHPPartTypeName( psShape->panPartType[0] ); if( iPart < psShape->nParts && psShape->panPartStart[iPart] == j ) { pszPartType = SHPPartTypeName( psShape->panPartType[iPart] ); iPart++; pszPlus = "+"; } else pszPlus = " "; printf(" %s (%12.3f,%12.3f, %g, %g) %s \n", pszPlus, psShape->padfX[j], psShape->padfY[j], psShape->padfZ[j], psShape->padfM[j], pszPartType ); } if( bValidate ) { int nAltered = SHPRewindObject( hSHP, psShape ); if( nAltered > 0 ) { printf( " %d rings wound in the wrong direction.\n", nAltered ); nInvalidCount++; } } SHPDestroyObject( psShape ); } SHPClose( hSHP ); if( bValidate ) { printf( "%d object has invalid ring orderings.\n", nInvalidCount ); } #ifdef USE_DBMALLOC malloc_dump(2); #endif exit( 0 ); } ./shapelib-1.2.10/shpopen.c0100644000076500001440000020666507644273432015120 0ustar warmerdausers/****************************************************************************** * $Id: shpopen.c,v 1.39 2002/08/26 06:46:56 warmerda Exp $ * * Project: Shapelib * Purpose: Implementation of core Shapefile read/write functions. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, 2001, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: shpopen.c,v $ * Revision 1.39 2002/08/26 06:46:56 warmerda * avoid c++ comments * * Revision 1.38 2002/05/07 16:43:39 warmerda * Removed debugging printf. * * Revision 1.37 2002/04/10 17:35:22 warmerda * fixed bug in ring reversal code * * Revision 1.36 2002/04/10 16:59:54 warmerda * added SHPRewindObject * * Revision 1.35 2001/12/07 15:10:44 warmerda * fix if .shx fails to open * * Revision 1.34 2001/11/01 16:29:55 warmerda * move pabyRec into SHPInfo for thread safety * * Revision 1.33 2001/07/03 12:18:15 warmerda * Improved cleanup if SHX not found, provied by Riccardo Cohen. * * Revision 1.32 2001/06/22 01:58:07 warmerda * be more careful about establishing initial bounds in face of NULL shapes * * Revision 1.31 2001/05/31 19:35:29 warmerda * added support for writing null shapes * * Revision 1.30 2001/05/28 12:46:29 warmerda * Add some checking on reasonableness of record count when opening. * * Revision 1.29 2001/05/23 13:36:52 warmerda * added use of SHPAPI_CALL * * Revision 1.28 2001/02/06 22:25:06 warmerda * fixed memory leaks when SHPOpen() fails * * Revision 1.27 2000/07/18 15:21:33 warmerda * added better enforcement of -1 for append in SHPWriteObject * * Revision 1.26 2000/02/16 16:03:51 warmerda * added null shape support * * Revision 1.25 1999/12/15 13:47:07 warmerda * Fixed record size settings in .shp file (was 4 words too long) * Added stdlib.h. * * Revision 1.24 1999/11/05 14:12:04 warmerda * updated license terms * * Revision 1.23 1999/07/27 00:53:46 warmerda * added support for rewriting shapes * * Revision 1.22 1999/06/11 19:19:11 warmerda * Cleanup pabyRec static buffer on SHPClose(). * * Revision 1.21 1999/06/02 14:57:56 kshih * Remove unused variables * * Revision 1.20 1999/04/19 21:04:17 warmerda * Fixed syntax error. * * Revision 1.19 1999/04/19 21:01:57 warmerda * Force access string to binary in SHPOpen(). * * Revision 1.18 1999/04/01 18:48:07 warmerda * Try upper case extensions if lower case doesn't work. * * Revision 1.17 1998/12/31 15:29:39 warmerda * Disable writing measure values to multipatch objects if * DISABLE_MULTIPATCH_MEASURE is defined. * * Revision 1.16 1998/12/16 05:14:33 warmerda * Added support to write MULTIPATCH. Fixed reading Z coordinate of * MULTIPATCH. Fixed record size written for all feature types. * * Revision 1.15 1998/12/03 16:35:29 warmerda * r+b is proper binary access string, not rb+. * * Revision 1.14 1998/12/03 15:47:56 warmerda * Fixed setting of nVertices in SHPCreateObject(). * * Revision 1.13 1998/12/03 15:33:54 warmerda * Made SHPCalculateExtents() separately callable. * * Revision 1.12 1998/11/11 20:01:50 warmerda * Fixed bug writing ArcM/Z, and PolygonM/Z for big endian machines. * * Revision 1.11 1998/11/09 20:56:44 warmerda * Fixed up handling of file wide bounds. * * Revision 1.10 1998/11/09 20:18:51 warmerda * Converted to support 3D shapefiles, and use of SHPObject. * * Revision 1.9 1998/02/24 15:09:05 warmerda * Fixed memory leak. * * Revision 1.8 1997/12/04 15:40:29 warmerda * Fixed byte swapping of record number, and record length fields in the * .shp file. * * Revision 1.7 1995/10/21 03:15:58 warmerda * Added support for binary file access, the magic cookie 9997 * and tried to improve the int32 selection logic for 16bit systems. * * Revision 1.6 1995/09/04 04:19:41 warmerda * Added fix for file bounds. * * Revision 1.5 1995/08/25 15:16:44 warmerda * Fixed a couple of problems with big endian systems ... one with bounds * and the other with multipart polygons. * * Revision 1.4 1995/08/24 18:10:17 warmerda * Switch to use SfRealloc() to avoid problems with pre-ANSI realloc() * functions (such as on the Sun). * * Revision 1.3 1995/08/23 02:23:15 warmerda * Added support for reading bounds, and fixed up problems in setting the * file wide bounds. * * Revision 1.2 1995/08/04 03:16:57 warmerda * Added header. * */ static char rcsid[] = "$Id: shpopen.c,v 1.39 2002/08/26 06:46:56 warmerda Exp $"; #include "shapefil.h" #include #include #include #include #include typedef unsigned char uchar; #if UINT_MAX == 65535 typedef long int32; #else typedef int int32; #endif #ifndef FALSE # define FALSE 0 # define TRUE 1 #endif #define ByteCopy( a, b, c ) memcpy( b, a, c ) #ifndef MAX # define MIN(a,b) ((ab) ? a : b) #endif static int bBigEndian; /************************************************************************/ /* SwapWord() */ /* */ /* Swap a 2, 4 or 8 byte word. */ /************************************************************************/ static void SwapWord( int length, void * wordP ) { int i; uchar temp; for( i=0; i < length/2; i++ ) { temp = ((uchar *) wordP)[i]; ((uchar *)wordP)[i] = ((uchar *) wordP)[length-i-1]; ((uchar *) wordP)[length-i-1] = temp; } } /************************************************************************/ /* SfRealloc() */ /* */ /* A realloc cover function that will access a NULL pointer as */ /* a valid input. */ /************************************************************************/ static void * SfRealloc( void * pMem, int nNewSize ) { if( pMem == NULL ) return( (void *) malloc(nNewSize) ); else return( (void *) realloc(pMem,nNewSize) ); } /************************************************************************/ /* SHPWriteHeader() */ /* */ /* Write out a header for the .shp and .shx files as well as the */ /* contents of the index (.shx) file. */ /************************************************************************/ static void SHPWriteHeader( SHPHandle psSHP ) { uchar abyHeader[100]; int i; int32 i32; double dValue; int32 *panSHX; /* -------------------------------------------------------------------- */ /* Prepare header block for .shp file. */ /* -------------------------------------------------------------------- */ for( i = 0; i < 100; i++ ) abyHeader[i] = 0; abyHeader[2] = 0x27; /* magic cookie */ abyHeader[3] = 0x0a; i32 = psSHP->nFileSize/2; /* file size */ ByteCopy( &i32, abyHeader+24, 4 ); if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); i32 = 1000; /* version */ ByteCopy( &i32, abyHeader+28, 4 ); if( bBigEndian ) SwapWord( 4, abyHeader+28 ); i32 = psSHP->nShapeType; /* shape type */ ByteCopy( &i32, abyHeader+32, 4 ); if( bBigEndian ) SwapWord( 4, abyHeader+32 ); dValue = psSHP->adBoundsMin[0]; /* set bounds */ ByteCopy( &dValue, abyHeader+36, 8 ); if( bBigEndian ) SwapWord( 8, abyHeader+36 ); dValue = psSHP->adBoundsMin[1]; ByteCopy( &dValue, abyHeader+44, 8 ); if( bBigEndian ) SwapWord( 8, abyHeader+44 ); dValue = psSHP->adBoundsMax[0]; ByteCopy( &dValue, abyHeader+52, 8 ); if( bBigEndian ) SwapWord( 8, abyHeader+52 ); dValue = psSHP->adBoundsMax[1]; ByteCopy( &dValue, abyHeader+60, 8 ); if( bBigEndian ) SwapWord( 8, abyHeader+60 ); dValue = psSHP->adBoundsMin[2]; /* z */ ByteCopy( &dValue, abyHeader+68, 8 ); if( bBigEndian ) SwapWord( 8, abyHeader+68 ); dValue = psSHP->adBoundsMax[2]; ByteCopy( &dValue, abyHeader+76, 8 ); if( bBigEndian ) SwapWord( 8, abyHeader+76 ); dValue = psSHP->adBoundsMin[3]; /* m */ ByteCopy( &dValue, abyHeader+84, 8 ); if( bBigEndian ) SwapWord( 8, abyHeader+84 ); dValue = psSHP->adBoundsMax[3]; ByteCopy( &dValue, abyHeader+92, 8 ); if( bBigEndian ) SwapWord( 8, abyHeader+92 ); /* -------------------------------------------------------------------- */ /* Write .shp file header. */ /* -------------------------------------------------------------------- */ fseek( psSHP->fpSHP, 0, 0 ); fwrite( abyHeader, 100, 1, psSHP->fpSHP ); /* -------------------------------------------------------------------- */ /* Prepare, and write .shx file header. */ /* -------------------------------------------------------------------- */ i32 = (psSHP->nRecords * 2 * sizeof(int32) + 100)/2; /* file size */ ByteCopy( &i32, abyHeader+24, 4 ); if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); fseek( psSHP->fpSHX, 0, 0 ); fwrite( abyHeader, 100, 1, psSHP->fpSHX ); /* -------------------------------------------------------------------- */ /* Write out the .shx contents. */ /* -------------------------------------------------------------------- */ panSHX = (int32 *) malloc(sizeof(int32) * 2 * psSHP->nRecords); for( i = 0; i < psSHP->nRecords; i++ ) { panSHX[i*2 ] = psSHP->panRecOffset[i]/2; panSHX[i*2+1] = psSHP->panRecSize[i]/2; if( !bBigEndian ) SwapWord( 4, panSHX+i*2 ); if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 ); } fwrite( panSHX, sizeof(int32) * 2, psSHP->nRecords, psSHP->fpSHX ); free( panSHX ); } /************************************************************************/ /* SHPOpen() */ /* */ /* Open the .shp and .shx files based on the basename of the */ /* files or either file name. */ /************************************************************************/ SHPHandle SHPAPI_CALL SHPOpen( const char * pszLayer, const char * pszAccess ) { char *pszFullname, *pszBasename; SHPHandle psSHP; uchar *pabyBuf; int i; double dValue; /* -------------------------------------------------------------------- */ /* Ensure the access string is one of the legal ones. We */ /* ensure the result string indicates binary to avoid common */ /* problems on Windows. */ /* -------------------------------------------------------------------- */ if( strcmp(pszAccess,"rb+") == 0 || strcmp(pszAccess,"r+b") == 0 || strcmp(pszAccess,"r+") == 0 ) pszAccess = "r+b"; else pszAccess = "rb"; /* -------------------------------------------------------------------- */ /* Establish the byte order on this machine. */ /* -------------------------------------------------------------------- */ i = 1; if( *((uchar *) &i) == 1 ) bBigEndian = FALSE; else bBigEndian = TRUE; /* -------------------------------------------------------------------- */ /* Initialize the info structure. */ /* -------------------------------------------------------------------- */ psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1); psSHP->bUpdated = FALSE; /* -------------------------------------------------------------------- */ /* Compute the base (layer) name. If there is any extension */ /* on the passed in filename we will strip it off. */ /* -------------------------------------------------------------------- */ pszBasename = (char *) malloc(strlen(pszLayer)+5); strcpy( pszBasename, pszLayer ); for( i = strlen(pszBasename)-1; i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' && pszBasename[i] != '\\'; i-- ) {} if( pszBasename[i] == '.' ) pszBasename[i] = '\0'; /* -------------------------------------------------------------------- */ /* Open the .shp and .shx files. Note that files pulled from */ /* a PC to Unix with upper case filenames won't work! */ /* -------------------------------------------------------------------- */ pszFullname = (char *) malloc(strlen(pszBasename) + 5); sprintf( pszFullname, "%s.shp", pszBasename ); psSHP->fpSHP = fopen(pszFullname, pszAccess ); if( psSHP->fpSHP == NULL ) { sprintf( pszFullname, "%s.SHP", pszBasename ); psSHP->fpSHP = fopen(pszFullname, pszAccess ); } if( psSHP->fpSHP == NULL ) { free( psSHP ); free( pszBasename ); free( pszFullname ); return( NULL ); } sprintf( pszFullname, "%s.shx", pszBasename ); psSHP->fpSHX = fopen(pszFullname, pszAccess ); if( psSHP->fpSHX == NULL ) { sprintf( pszFullname, "%s.SHX", pszBasename ); psSHP->fpSHX = fopen(pszFullname, pszAccess ); } if( psSHP->fpSHX == NULL ) { fclose( psSHP->fpSHP ); free( psSHP ); free( pszBasename ); free( pszFullname ); return( NULL ); } free( pszFullname ); free( pszBasename ); /* -------------------------------------------------------------------- */ /* Read the file size from the SHP file. */ /* -------------------------------------------------------------------- */ pabyBuf = (uchar *) malloc(100); fread( pabyBuf, 100, 1, psSHP->fpSHP ); psSHP->nFileSize = (pabyBuf[24] * 256 * 256 * 256 + pabyBuf[25] * 256 * 256 + pabyBuf[26] * 256 + pabyBuf[27]) * 2; /* -------------------------------------------------------------------- */ /* Read SHX file Header info */ /* -------------------------------------------------------------------- */ fread( pabyBuf, 100, 1, psSHP->fpSHX ); if( pabyBuf[0] != 0 || pabyBuf[1] != 0 || pabyBuf[2] != 0x27 || (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) ) { fclose( psSHP->fpSHP ); fclose( psSHP->fpSHX ); free( psSHP ); return( NULL ); } psSHP->nRecords = pabyBuf[27] + pabyBuf[26] * 256 + pabyBuf[25] * 256 * 256 + pabyBuf[24] * 256 * 256 * 256; psSHP->nRecords = (psSHP->nRecords*2 - 100) / 8; psSHP->nShapeType = pabyBuf[32]; if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 ) { /* this header appears to be corrupt. Give up. */ fclose( psSHP->fpSHP ); fclose( psSHP->fpSHX ); free( psSHP ); return( NULL ); } /* -------------------------------------------------------------------- */ /* Read the bounds. */ /* -------------------------------------------------------------------- */ if( bBigEndian ) SwapWord( 8, pabyBuf+36 ); memcpy( &dValue, pabyBuf+36, 8 ); psSHP->adBoundsMin[0] = dValue; if( bBigEndian ) SwapWord( 8, pabyBuf+44 ); memcpy( &dValue, pabyBuf+44, 8 ); psSHP->adBoundsMin[1] = dValue; if( bBigEndian ) SwapWord( 8, pabyBuf+52 ); memcpy( &dValue, pabyBuf+52, 8 ); psSHP->adBoundsMax[0] = dValue; if( bBigEndian ) SwapWord( 8, pabyBuf+60 ); memcpy( &dValue, pabyBuf+60, 8 ); psSHP->adBoundsMax[1] = dValue; if( bBigEndian ) SwapWord( 8, pabyBuf+68 ); /* z */ memcpy( &dValue, pabyBuf+68, 8 ); psSHP->adBoundsMin[2] = dValue; if( bBigEndian ) SwapWord( 8, pabyBuf+76 ); memcpy( &dValue, pabyBuf+76, 8 ); psSHP->adBoundsMax[2] = dValue; if( bBigEndian ) SwapWord( 8, pabyBuf+84 ); /* z */ memcpy( &dValue, pabyBuf+84, 8 ); psSHP->adBoundsMin[3] = dValue; if( bBigEndian ) SwapWord( 8, pabyBuf+92 ); memcpy( &dValue, pabyBuf+92, 8 ); psSHP->adBoundsMax[3] = dValue; free( pabyBuf ); /* -------------------------------------------------------------------- */ /* Read the .shx file to get the offsets to each record in */ /* the .shp file. */ /* -------------------------------------------------------------------- */ psSHP->nMaxRecords = psSHP->nRecords; psSHP->panRecOffset = (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) ); psSHP->panRecSize = (int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) ); pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) ); fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ); for( i = 0; i < psSHP->nRecords; i++ ) { int32 nOffset, nLength; memcpy( &nOffset, pabyBuf + i * 8, 4 ); if( !bBigEndian ) SwapWord( 4, &nOffset ); memcpy( &nLength, pabyBuf + i * 8 + 4, 4 ); if( !bBigEndian ) SwapWord( 4, &nLength ); psSHP->panRecOffset[i] = nOffset*2; psSHP->panRecSize[i] = nLength*2; } free( pabyBuf ); return( psSHP ); } /************************************************************************/ /* SHPClose() */ /* */ /* Close the .shp and .shx files. */ /************************************************************************/ void SHPAPI_CALL SHPClose(SHPHandle psSHP ) { /* -------------------------------------------------------------------- */ /* Update the header if we have modified anything. */ /* -------------------------------------------------------------------- */ if( psSHP->bUpdated ) { SHPWriteHeader( psSHP ); } /* -------------------------------------------------------------------- */ /* Free all resources, and close files. */ /* -------------------------------------------------------------------- */ free( psSHP->panRecOffset ); free( psSHP->panRecSize ); fclose( psSHP->fpSHX ); fclose( psSHP->fpSHP ); if( psSHP->pabyRec != NULL ) { free( psSHP->pabyRec ); } free( psSHP ); } /************************************************************************/ /* SHPGetInfo() */ /* */ /* Fetch general information about the shape file. */ /************************************************************************/ void SHPAPI_CALL SHPGetInfo(SHPHandle psSHP, int * pnEntities, int * pnShapeType, double * padfMinBound, double * padfMaxBound ) { int i; if( pnEntities != NULL ) *pnEntities = psSHP->nRecords; if( pnShapeType != NULL ) *pnShapeType = psSHP->nShapeType; for( i = 0; i < 4; i++ ) { if( padfMinBound != NULL ) padfMinBound[i] = psSHP->adBoundsMin[i]; if( padfMaxBound != NULL ) padfMaxBound[i] = psSHP->adBoundsMax[i]; } } /************************************************************************/ /* SHPCreate() */ /* */ /* Create a new shape file and return a handle to the open */ /* shape file with read/write access. */ /************************************************************************/ SHPHandle SHPAPI_CALL SHPCreate( const char * pszLayer, int nShapeType ) { char *pszBasename, *pszFullname; int i; FILE *fpSHP, *fpSHX; uchar abyHeader[100]; int32 i32; double dValue; /* -------------------------------------------------------------------- */ /* Establish the byte order on this system. */ /* -------------------------------------------------------------------- */ i = 1; if( *((uchar *) &i) == 1 ) bBigEndian = FALSE; else bBigEndian = TRUE; /* -------------------------------------------------------------------- */ /* Compute the base (layer) name. If there is any extension */ /* on the passed in filename we will strip it off. */ /* -------------------------------------------------------------------- */ pszBasename = (char *) malloc(strlen(pszLayer)+5); strcpy( pszBasename, pszLayer ); for( i = strlen(pszBasename)-1; i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/' && pszBasename[i] != '\\'; i-- ) {} if( pszBasename[i] == '.' ) pszBasename[i] = '\0'; /* -------------------------------------------------------------------- */ /* Open the two files so we can write their headers. */ /* -------------------------------------------------------------------- */ pszFullname = (char *) malloc(strlen(pszBasename) + 5); sprintf( pszFullname, "%s.shp", pszBasename ); fpSHP = fopen(pszFullname, "wb" ); if( fpSHP == NULL ) return( NULL ); sprintf( pszFullname, "%s.shx", pszBasename ); fpSHX = fopen(pszFullname, "wb" ); if( fpSHX == NULL ) return( NULL ); free( pszFullname ); free( pszBasename ); /* -------------------------------------------------------------------- */ /* Prepare header block for .shp file. */ /* -------------------------------------------------------------------- */ for( i = 0; i < 100; i++ ) abyHeader[i] = 0; abyHeader[2] = 0x27; /* magic cookie */ abyHeader[3] = 0x0a; i32 = 50; /* file size */ ByteCopy( &i32, abyHeader+24, 4 ); if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); i32 = 1000; /* version */ ByteCopy( &i32, abyHeader+28, 4 ); if( bBigEndian ) SwapWord( 4, abyHeader+28 ); i32 = nShapeType; /* shape type */ ByteCopy( &i32, abyHeader+32, 4 ); if( bBigEndian ) SwapWord( 4, abyHeader+32 ); dValue = 0.0; /* set bounds */ ByteCopy( &dValue, abyHeader+36, 8 ); ByteCopy( &dValue, abyHeader+44, 8 ); ByteCopy( &dValue, abyHeader+52, 8 ); ByteCopy( &dValue, abyHeader+60, 8 ); /* -------------------------------------------------------------------- */ /* Write .shp file header. */ /* -------------------------------------------------------------------- */ fwrite( abyHeader, 100, 1, fpSHP ); /* -------------------------------------------------------------------- */ /* Prepare, and write .shx file header. */ /* -------------------------------------------------------------------- */ i32 = 50; /* file size */ ByteCopy( &i32, abyHeader+24, 4 ); if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); fwrite( abyHeader, 100, 1, fpSHX ); /* -------------------------------------------------------------------- */ /* Close the files, and then open them as regular existing files. */ /* -------------------------------------------------------------------- */ fclose( fpSHP ); fclose( fpSHX ); return( SHPOpen( pszLayer, "r+b" ) ); } /************************************************************************/ /* _SHPSetBounds() */ /* */ /* Compute a bounds rectangle for a shape, and set it into the */ /* indicated location in the record. */ /************************************************************************/ static void _SHPSetBounds( uchar * pabyRec, SHPObject * psShape ) { ByteCopy( &(psShape->dfXMin), pabyRec + 0, 8 ); ByteCopy( &(psShape->dfYMin), pabyRec + 8, 8 ); ByteCopy( &(psShape->dfXMax), pabyRec + 16, 8 ); ByteCopy( &(psShape->dfYMax), pabyRec + 24, 8 ); if( bBigEndian ) { SwapWord( 8, pabyRec + 0 ); SwapWord( 8, pabyRec + 8 ); SwapWord( 8, pabyRec + 16 ); SwapWord( 8, pabyRec + 24 ); } } /************************************************************************/ /* SHPComputeExtents() */ /* */ /* Recompute the extents of a shape. Automatically done by */ /* SHPCreateObject(). */ /************************************************************************/ void SHPAPI_CALL SHPComputeExtents( SHPObject * psObject ) { int i; /* -------------------------------------------------------------------- */ /* Build extents for this object. */ /* -------------------------------------------------------------------- */ if( psObject->nVertices > 0 ) { psObject->dfXMin = psObject->dfXMax = psObject->padfX[0]; psObject->dfYMin = psObject->dfYMax = psObject->padfY[0]; psObject->dfZMin = psObject->dfZMax = psObject->padfZ[0]; psObject->dfMMin = psObject->dfMMax = psObject->padfM[0]; } for( i = 0; i < psObject->nVertices; i++ ) { psObject->dfXMin = MIN(psObject->dfXMin, psObject->padfX[i]); psObject->dfYMin = MIN(psObject->dfYMin, psObject->padfY[i]); psObject->dfZMin = MIN(psObject->dfZMin, psObject->padfZ[i]); psObject->dfMMin = MIN(psObject->dfMMin, psObject->padfM[i]); psObject->dfXMax = MAX(psObject->dfXMax, psObject->padfX[i]); psObject->dfYMax = MAX(psObject->dfYMax, psObject->padfY[i]); psObject->dfZMax = MAX(psObject->dfZMax, psObject->padfZ[i]); psObject->dfMMax = MAX(psObject->dfMMax, psObject->padfM[i]); } } /************************************************************************/ /* SHPCreateObject() */ /* */ /* Create a shape object. It should be freed with */ /* SHPDestroyObject(). */ /************************************************************************/ SHPObject SHPAPI_CALL1(*) SHPCreateObject( int nSHPType, int nShapeId, int nParts, int * panPartStart, int * panPartType, int nVertices, double * padfX, double * padfY, double * padfZ, double * padfM ) { SHPObject *psObject; int i, bHasM, bHasZ; psObject = (SHPObject *) calloc(1,sizeof(SHPObject)); psObject->nSHPType = nSHPType; psObject->nShapeId = nShapeId; /* -------------------------------------------------------------------- */ /* Establish whether this shape type has M, and Z values. */ /* -------------------------------------------------------------------- */ if( nSHPType == SHPT_ARCM || nSHPType == SHPT_POINTM || nSHPType == SHPT_POLYGONM || nSHPType == SHPT_MULTIPOINTM ) { bHasM = TRUE; bHasZ = FALSE; } else if( nSHPType == SHPT_ARCZ || nSHPType == SHPT_POINTZ || nSHPType == SHPT_POLYGONZ || nSHPType == SHPT_MULTIPOINTZ || nSHPType == SHPT_MULTIPATCH ) { bHasM = TRUE; bHasZ = TRUE; } else { bHasM = FALSE; bHasZ = FALSE; } /* -------------------------------------------------------------------- */ /* Capture parts. Note that part type is optional, and */ /* defaults to ring. */ /* -------------------------------------------------------------------- */ if( nSHPType == SHPT_ARC || nSHPType == SHPT_POLYGON || nSHPType == SHPT_ARCM || nSHPType == SHPT_POLYGONM || nSHPType == SHPT_ARCZ || nSHPType == SHPT_POLYGONZ || nSHPType == SHPT_MULTIPATCH ) { psObject->nParts = MAX(1,nParts); psObject->panPartStart = (int *) malloc(sizeof(int) * psObject->nParts); psObject->panPartType = (int *) malloc(sizeof(int) * psObject->nParts); psObject->panPartStart[0] = 0; psObject->panPartType[0] = SHPP_RING; for( i = 0; i < nParts; i++ ) { psObject->panPartStart[i] = panPartStart[i]; if( panPartType != NULL ) psObject->panPartType[i] = panPartType[i]; else psObject->panPartType[i] = SHPP_RING; } } /* -------------------------------------------------------------------- */ /* Capture vertices. Note that Z and M are optional, but X and */ /* Y are not. */ /* -------------------------------------------------------------------- */ if( nVertices > 0 ) { psObject->padfX = (double *) calloc(sizeof(double),nVertices); psObject->padfY = (double *) calloc(sizeof(double),nVertices); psObject->padfZ = (double *) calloc(sizeof(double),nVertices); psObject->padfM = (double *) calloc(sizeof(double),nVertices); assert( padfX != NULL ); assert( padfY != NULL ); for( i = 0; i < nVertices; i++ ) { psObject->padfX[i] = padfX[i]; psObject->padfY[i] = padfY[i]; if( padfZ != NULL && bHasZ ) psObject->padfZ[i] = padfZ[i]; if( padfM != NULL && bHasM ) psObject->padfM[i] = padfM[i]; } } /* -------------------------------------------------------------------- */ /* Compute the extents. */ /* -------------------------------------------------------------------- */ psObject->nVertices = nVertices; SHPComputeExtents( psObject ); return( psObject ); } /************************************************************************/ /* SHPCreateSimpleObject() */ /* */ /* Create a simple (common) shape object. Destroy with */ /* SHPDestroyObject(). */ /************************************************************************/ SHPObject SHPAPI_CALL1(*) SHPCreateSimpleObject( int nSHPType, int nVertices, double * padfX, double * padfY, double * padfZ ) { return( SHPCreateObject( nSHPType, -1, 0, NULL, NULL, nVertices, padfX, padfY, padfZ, NULL ) ); } /************************************************************************/ /* SHPWriteObject() */ /* */ /* Write out the vertices of a new structure. Note that it is */ /* only possible to write vertices at the end of the file. */ /************************************************************************/ int SHPAPI_CALL SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject ) { int nRecordOffset, i, nRecordSize; uchar *pabyRec; int32 i32; psSHP->bUpdated = TRUE; /* -------------------------------------------------------------------- */ /* Ensure that shape object matches the type of the file it is */ /* being written to. */ /* -------------------------------------------------------------------- */ assert( psObject->nSHPType == psSHP->nShapeType || psObject->nSHPType == SHPT_NULL ); /* -------------------------------------------------------------------- */ /* Ensure that -1 is used for appends. Either blow an */ /* assertion, or if they are disabled, set the shapeid to -1 */ /* for appends. */ /* -------------------------------------------------------------------- */ assert( nShapeId == -1 || (nShapeId >= 0 && nShapeId < psSHP->nRecords) ); if( nShapeId != -1 && nShapeId >= psSHP->nRecords ) nShapeId = -1; /* -------------------------------------------------------------------- */ /* Add the new entity to the in memory index. */ /* -------------------------------------------------------------------- */ if( nShapeId == -1 && psSHP->nRecords+1 > psSHP->nMaxRecords ) { psSHP->nMaxRecords =(int) ( psSHP->nMaxRecords * 1.3 + 100); psSHP->panRecOffset = (int *) SfRealloc(psSHP->panRecOffset,sizeof(int) * psSHP->nMaxRecords ); psSHP->panRecSize = (int *) SfRealloc(psSHP->panRecSize,sizeof(int) * psSHP->nMaxRecords ); } /* -------------------------------------------------------------------- */ /* Initialize record. */ /* -------------------------------------------------------------------- */ pabyRec = (uchar *) malloc(psObject->nVertices * 4 * sizeof(double) + psObject->nParts * 8 + 128); /* -------------------------------------------------------------------- */ /* Extract vertices for a Polygon or Arc. */ /* -------------------------------------------------------------------- */ if( psObject->nSHPType == SHPT_POLYGON || psObject->nSHPType == SHPT_POLYGONZ || psObject->nSHPType == SHPT_POLYGONM || psObject->nSHPType == SHPT_ARC || psObject->nSHPType == SHPT_ARCZ || psObject->nSHPType == SHPT_ARCM || psObject->nSHPType == SHPT_MULTIPATCH ) { int32 nPoints, nParts; int i; nPoints = psObject->nVertices; nParts = psObject->nParts; _SHPSetBounds( pabyRec + 12, psObject ); if( bBigEndian ) SwapWord( 4, &nPoints ); if( bBigEndian ) SwapWord( 4, &nParts ); ByteCopy( &nPoints, pabyRec + 40 + 8, 4 ); ByteCopy( &nParts, pabyRec + 36 + 8, 4 ); nRecordSize = 52; /* * Write part start positions. */ ByteCopy( psObject->panPartStart, pabyRec + 44 + 8, 4 * psObject->nParts ); for( i = 0; i < psObject->nParts; i++ ) { if( bBigEndian ) SwapWord( 4, pabyRec + 44 + 8 + 4*i ); nRecordSize += 4; } /* * Write multipatch part types if needed. */ if( psObject->nSHPType == SHPT_MULTIPATCH ) { memcpy( pabyRec + nRecordSize, psObject->panPartType, 4*psObject->nParts ); for( i = 0; i < psObject->nParts; i++ ) { if( bBigEndian ) SwapWord( 4, pabyRec + nRecordSize ); nRecordSize += 4; } } /* * Write the (x,y) vertex values. */ for( i = 0; i < psObject->nVertices; i++ ) { ByteCopy( psObject->padfX + i, pabyRec + nRecordSize, 8 ); ByteCopy( psObject->padfY + i, pabyRec + nRecordSize + 8, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize + 8 ); nRecordSize += 2 * 8; } /* * Write the Z coordinates (if any). */ if( psObject->nSHPType == SHPT_POLYGONZ || psObject->nSHPType == SHPT_ARCZ || psObject->nSHPType == SHPT_MULTIPATCH ) { ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; for( i = 0; i < psObject->nVertices; i++ ) { ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; } } /* * Write the M values, if any. */ if( psObject->nSHPType == SHPT_POLYGONM || psObject->nSHPType == SHPT_ARCM #ifndef DISABLE_MULTIPATCH_MEASURE || psObject->nSHPType == SHPT_MULTIPATCH #endif || psObject->nSHPType == SHPT_POLYGONZ || psObject->nSHPType == SHPT_ARCZ ) { ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; for( i = 0; i < psObject->nVertices; i++ ) { ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; } } } /* -------------------------------------------------------------------- */ /* Extract vertices for a MultiPoint. */ /* -------------------------------------------------------------------- */ else if( psObject->nSHPType == SHPT_MULTIPOINT || psObject->nSHPType == SHPT_MULTIPOINTZ || psObject->nSHPType == SHPT_MULTIPOINTM ) { int32 nPoints; int i; nPoints = psObject->nVertices; _SHPSetBounds( pabyRec + 12, psObject ); if( bBigEndian ) SwapWord( 4, &nPoints ); ByteCopy( &nPoints, pabyRec + 44, 4 ); for( i = 0; i < psObject->nVertices; i++ ) { ByteCopy( psObject->padfX + i, pabyRec + 48 + i*16, 8 ); ByteCopy( psObject->padfY + i, pabyRec + 48 + i*16 + 8, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 ); if( bBigEndian ) SwapWord( 8, pabyRec + 48 + i*16 + 8 ); } nRecordSize = 48 + 16 * psObject->nVertices; if( psObject->nSHPType == SHPT_MULTIPOINTZ ) { ByteCopy( &(psObject->dfZMin), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; ByteCopy( &(psObject->dfZMax), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; for( i = 0; i < psObject->nVertices; i++ ) { ByteCopy( psObject->padfZ + i, pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; } } if( psObject->nSHPType == SHPT_MULTIPOINTZ || psObject->nSHPType == SHPT_MULTIPOINTM ) { ByteCopy( &(psObject->dfMMin), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; ByteCopy( &(psObject->dfMMax), pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; for( i = 0; i < psObject->nVertices; i++ ) { ByteCopy( psObject->padfM + i, pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; } } } /* -------------------------------------------------------------------- */ /* Write point. */ /* -------------------------------------------------------------------- */ else if( psObject->nSHPType == SHPT_POINT || psObject->nSHPType == SHPT_POINTZ || psObject->nSHPType == SHPT_POINTM ) { ByteCopy( psObject->padfX, pabyRec + 12, 8 ); ByteCopy( psObject->padfY, pabyRec + 20, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + 12 ); if( bBigEndian ) SwapWord( 8, pabyRec + 20 ); nRecordSize = 28; if( psObject->nSHPType == SHPT_POINTZ ) { ByteCopy( psObject->padfZ, pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; } if( psObject->nSHPType == SHPT_POINTZ || psObject->nSHPType == SHPT_POINTM ) { ByteCopy( psObject->padfM, pabyRec + nRecordSize, 8 ); if( bBigEndian ) SwapWord( 8, pabyRec + nRecordSize ); nRecordSize += 8; } } /* -------------------------------------------------------------------- */ /* Not much to do for null geometries. */ /* -------------------------------------------------------------------- */ else if( psObject->nSHPType == SHPT_NULL ) { nRecordSize = 12; } else { /* unknown type */ assert( FALSE ); } /* -------------------------------------------------------------------- */ /* Establish where we are going to put this record. If we are */ /* rewriting and existing record, and it will fit, then put it */ /* back where the original came from. Otherwise write at the end. */ /* -------------------------------------------------------------------- */ if( nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize-8 ) { if( nShapeId == -1 ) nShapeId = psSHP->nRecords++; psSHP->panRecOffset[nShapeId] = nRecordOffset = psSHP->nFileSize; psSHP->panRecSize[nShapeId] = nRecordSize-8; psSHP->nFileSize += nRecordSize; } else { nRecordOffset = psSHP->panRecOffset[nShapeId]; } /* -------------------------------------------------------------------- */ /* Set the shape type, record number, and record size. */ /* -------------------------------------------------------------------- */ i32 = nShapeId+1; /* record # */ if( !bBigEndian ) SwapWord( 4, &i32 ); ByteCopy( &i32, pabyRec, 4 ); i32 = (nRecordSize-8)/2; /* record size */ if( !bBigEndian ) SwapWord( 4, &i32 ); ByteCopy( &i32, pabyRec + 4, 4 ); i32 = psObject->nSHPType; /* shape type */ if( bBigEndian ) SwapWord( 4, &i32 ); ByteCopy( &i32, pabyRec + 8, 4 ); /* -------------------------------------------------------------------- */ /* Write out record. */ /* -------------------------------------------------------------------- */ if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0 || fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 ) { printf( "Error in fseek() or fwrite().\n" ); free( pabyRec ); return -1; } free( pabyRec ); /* -------------------------------------------------------------------- */ /* Expand file wide bounds based on this shape. */ /* -------------------------------------------------------------------- */ if( psSHP->adBoundsMin[0] == 0.0 && psSHP->adBoundsMax[0] == 0.0 && psSHP->adBoundsMin[1] == 0.0 && psSHP->adBoundsMax[1] == 0.0 && psObject->nSHPType != SHPT_NULL ) { psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0]; psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0]; psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0]; psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0]; } for( i = 0; i < psObject->nVertices; i++ ) { psSHP->adBoundsMin[0] = MIN(psSHP->adBoundsMin[0],psObject->padfX[i]); psSHP->adBoundsMin[1] = MIN(psSHP->adBoundsMin[1],psObject->padfY[i]); psSHP->adBoundsMin[2] = MIN(psSHP->adBoundsMin[2],psObject->padfZ[i]); psSHP->adBoundsMin[3] = MIN(psSHP->adBoundsMin[3],psObject->padfM[i]); psSHP->adBoundsMax[0] = MAX(psSHP->adBoundsMax[0],psObject->padfX[i]); psSHP->adBoundsMax[1] = MAX(psSHP->adBoundsMax[1],psObject->padfY[i]); psSHP->adBoundsMax[2] = MAX(psSHP->adBoundsMax[2],psObject->padfZ[i]); psSHP->adBoundsMax[3] = MAX(psSHP->adBoundsMax[3],psObject->padfM[i]); } return( nShapeId ); } /************************************************************************/ /* SHPReadObject() */ /* */ /* Read the vertices, parts, and other non-attribute information */ /* for one shape. */ /************************************************************************/ SHPObject SHPAPI_CALL1(*) SHPReadObject( SHPHandle psSHP, int hEntity ) { SHPObject *psShape; /* -------------------------------------------------------------------- */ /* Validate the record/entity number. */ /* -------------------------------------------------------------------- */ if( hEntity < 0 || hEntity >= psSHP->nRecords ) return( NULL ); /* -------------------------------------------------------------------- */ /* Ensure our record buffer is large enough. */ /* -------------------------------------------------------------------- */ if( psSHP->panRecSize[hEntity]+8 > psSHP->nBufSize ) { psSHP->nBufSize = psSHP->panRecSize[hEntity]+8; psSHP->pabyRec = (uchar *) SfRealloc(psSHP->pabyRec,psSHP->nBufSize); } /* -------------------------------------------------------------------- */ /* Read the record. */ /* -------------------------------------------------------------------- */ fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ); fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP ); /* -------------------------------------------------------------------- */ /* Allocate and minimally initialize the object. */ /* -------------------------------------------------------------------- */ psShape = (SHPObject *) calloc(1,sizeof(SHPObject)); psShape->nShapeId = hEntity; memcpy( &psShape->nSHPType, psSHP->pabyRec + 8, 4 ); if( bBigEndian ) SwapWord( 4, &(psShape->nSHPType) ); /* ==================================================================== */ /* Extract vertices for a Polygon or Arc. */ /* ==================================================================== */ if( psShape->nSHPType == SHPT_POLYGON || psShape->nSHPType == SHPT_ARC || psShape->nSHPType == SHPT_POLYGONZ || psShape->nSHPType == SHPT_POLYGONM || psShape->nSHPType == SHPT_ARCZ || psShape->nSHPType == SHPT_ARCM || psShape->nSHPType == SHPT_MULTIPATCH ) { int32 nPoints, nParts; int i, nOffset; /* -------------------------------------------------------------------- */ /* Get the X/Y bounds. */ /* -------------------------------------------------------------------- */ memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 ); memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 ); memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 ); memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) ); /* -------------------------------------------------------------------- */ /* Extract part/point count, and build vertex and part arrays */ /* to proper size. */ /* -------------------------------------------------------------------- */ memcpy( &nPoints, psSHP->pabyRec + 40 + 8, 4 ); memcpy( &nParts, psSHP->pabyRec + 36 + 8, 4 ); if( bBigEndian ) SwapWord( 4, &nPoints ); if( bBigEndian ) SwapWord( 4, &nParts ); psShape->nVertices = nPoints; psShape->padfX = (double *) calloc(nPoints,sizeof(double)); psShape->padfY = (double *) calloc(nPoints,sizeof(double)); psShape->padfZ = (double *) calloc(nPoints,sizeof(double)); psShape->padfM = (double *) calloc(nPoints,sizeof(double)); psShape->nParts = nParts; psShape->panPartStart = (int *) calloc(nParts,sizeof(int)); psShape->panPartType = (int *) calloc(nParts,sizeof(int)); for( i = 0; i < nParts; i++ ) psShape->panPartType[i] = SHPP_RING; /* -------------------------------------------------------------------- */ /* Copy out the part array from the record. */ /* -------------------------------------------------------------------- */ memcpy( psShape->panPartStart, psSHP->pabyRec + 44 + 8, 4 * nParts ); for( i = 0; i < nParts; i++ ) { if( bBigEndian ) SwapWord( 4, psShape->panPartStart+i ); } nOffset = 44 + 8 + 4*nParts; /* -------------------------------------------------------------------- */ /* If this is a multipatch, we will also have parts types. */ /* -------------------------------------------------------------------- */ if( psShape->nSHPType == SHPT_MULTIPATCH ) { memcpy( psShape->panPartType, psSHP->pabyRec + nOffset, 4*nParts ); for( i = 0; i < nParts; i++ ) { if( bBigEndian ) SwapWord( 4, psShape->panPartType+i ); } nOffset += 4*nParts; } /* -------------------------------------------------------------------- */ /* Copy out the vertices from the record. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nPoints; i++ ) { memcpy(psShape->padfX + i, psSHP->pabyRec + nOffset + i * 16, 8 ); memcpy(psShape->padfY + i, psSHP->pabyRec + nOffset + i * 16 + 8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); if( bBigEndian ) SwapWord( 8, psShape->padfY + i ); } nOffset += 16*nPoints; /* -------------------------------------------------------------------- */ /* If we have a Z coordinate, collect that now. */ /* -------------------------------------------------------------------- */ if( psShape->nSHPType == SHPT_POLYGONZ || psShape->nSHPType == SHPT_ARCZ || psShape->nSHPType == SHPT_MULTIPATCH ) { memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); for( i = 0; i < nPoints; i++ ) { memcpy( psShape->padfZ + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); } nOffset += 16 + 8*nPoints; } /* -------------------------------------------------------------------- */ /* If we have a M measure value, then read it now. We assume */ /* that the measure can be present for any shape if the size is */ /* big enough, but really it will only occur for the Z shapes */ /* (options), and the M shapes. */ /* -------------------------------------------------------------------- */ if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) { memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); for( i = 0; i < nPoints; i++ ) { memcpy( psShape->padfM + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); } } } /* ==================================================================== */ /* Extract vertices for a MultiPoint. */ /* ==================================================================== */ else if( psShape->nSHPType == SHPT_MULTIPOINT || psShape->nSHPType == SHPT_MULTIPOINTM || psShape->nSHPType == SHPT_MULTIPOINTZ ) { int32 nPoints; int i, nOffset; memcpy( &nPoints, psSHP->pabyRec + 44, 4 ); if( bBigEndian ) SwapWord( 4, &nPoints ); psShape->nVertices = nPoints; psShape->padfX = (double *) calloc(nPoints,sizeof(double)); psShape->padfY = (double *) calloc(nPoints,sizeof(double)); psShape->padfZ = (double *) calloc(nPoints,sizeof(double)); psShape->padfM = (double *) calloc(nPoints,sizeof(double)); for( i = 0; i < nPoints; i++ ) { memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 ); memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfX + i ); if( bBigEndian ) SwapWord( 8, psShape->padfY + i ); } nOffset = 48 + 16*nPoints; /* -------------------------------------------------------------------- */ /* Get the X/Y bounds. */ /* -------------------------------------------------------------------- */ memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 + 4, 8 ); memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 ); memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 ); memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) ); /* -------------------------------------------------------------------- */ /* If we have a Z coordinate, collect that now. */ /* -------------------------------------------------------------------- */ if( psShape->nSHPType == SHPT_MULTIPOINTZ ) { memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) ); for( i = 0; i < nPoints; i++ ) { memcpy( psShape->padfZ + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfZ + i ); } nOffset += 16 + 8*nPoints; } /* -------------------------------------------------------------------- */ /* If we have a M measure value, then read it now. We assume */ /* that the measure can be present for any shape if the size is */ /* big enough, but really it will only occur for the Z shapes */ /* (options), and the M shapes. */ /* -------------------------------------------------------------------- */ if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints ) { memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 ); memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) ); if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) ); for( i = 0; i < nPoints; i++ ) { memcpy( psShape->padfM + i, psSHP->pabyRec + nOffset + 16 + i*8, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfM + i ); } } } /* ==================================================================== */ /* Extract vertices for a point. */ /* ==================================================================== */ else if( psShape->nSHPType == SHPT_POINT || psShape->nSHPType == SHPT_POINTM || psShape->nSHPType == SHPT_POINTZ ) { int nOffset; psShape->nVertices = 1; psShape->padfX = (double *) calloc(1,sizeof(double)); psShape->padfY = (double *) calloc(1,sizeof(double)); psShape->padfZ = (double *) calloc(1,sizeof(double)); psShape->padfM = (double *) calloc(1,sizeof(double)); memcpy( psShape->padfX, psSHP->pabyRec + 12, 8 ); memcpy( psShape->padfY, psSHP->pabyRec + 20, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfX ); if( bBigEndian ) SwapWord( 8, psShape->padfY ); nOffset = 20 + 8; /* -------------------------------------------------------------------- */ /* If we have a Z coordinate, collect that now. */ /* -------------------------------------------------------------------- */ if( psShape->nSHPType == SHPT_POINTZ ) { memcpy( psShape->padfZ, psSHP->pabyRec + nOffset, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfZ ); nOffset += 8; } /* -------------------------------------------------------------------- */ /* If we have a M measure value, then read it now. We assume */ /* that the measure can be present for any shape if the size is */ /* big enough, but really it will only occur for the Z shapes */ /* (options), and the M shapes. */ /* -------------------------------------------------------------------- */ if( psSHP->panRecSize[hEntity]+8 >= nOffset + 8 ) { memcpy( psShape->padfM, psSHP->pabyRec + nOffset, 8 ); if( bBigEndian ) SwapWord( 8, psShape->padfM ); } /* -------------------------------------------------------------------- */ /* Since no extents are supplied in the record, we will apply */ /* them from the single vertex. */ /* -------------------------------------------------------------------- */ psShape->dfXMin = psShape->dfXMax = psShape->padfX[0]; psShape->dfYMin = psShape->dfYMax = psShape->padfY[0]; psShape->dfZMin = psShape->dfZMax = psShape->padfZ[0]; psShape->dfMMin = psShape->dfMMax = psShape->padfM[0]; } return( psShape ); } /************************************************************************/ /* SHPTypeName() */ /************************************************************************/ const char SHPAPI_CALL1(*) SHPTypeName( int nSHPType ) { switch( nSHPType ) { case SHPT_NULL: return "NullShape"; case SHPT_POINT: return "Point"; case SHPT_ARC: return "Arc"; case SHPT_POLYGON: return "Polygon"; case SHPT_MULTIPOINT: return "MultiPoint"; case SHPT_POINTZ: return "PointZ"; case SHPT_ARCZ: return "ArcZ"; case SHPT_POLYGONZ: return "PolygonZ"; case SHPT_MULTIPOINTZ: return "MultiPointZ"; case SHPT_POINTM: return "PointM"; case SHPT_ARCM: return "ArcM"; case SHPT_POLYGONM: return "PolygonM"; case SHPT_MULTIPOINTM: return "MultiPointM"; case SHPT_MULTIPATCH: return "MultiPatch"; default: return "UnknownShapeType"; } } /************************************************************************/ /* SHPPartTypeName() */ /************************************************************************/ const char SHPAPI_CALL1(*) SHPPartTypeName( int nPartType ) { switch( nPartType ) { case SHPP_TRISTRIP: return "TriangleStrip"; case SHPP_TRIFAN: return "TriangleFan"; case SHPP_OUTERRING: return "OuterRing"; case SHPP_INNERRING: return "InnerRing"; case SHPP_FIRSTRING: return "FirstRing"; case SHPP_RING: return "Ring"; default: return "UnknownPartType"; } } /************************************************************************/ /* SHPDestroyObject() */ /************************************************************************/ void SHPAPI_CALL SHPDestroyObject( SHPObject * psShape ) { if( psShape == NULL ) return; if( psShape->padfX != NULL ) free( psShape->padfX ); if( psShape->padfY != NULL ) free( psShape->padfY ); if( psShape->padfZ != NULL ) free( psShape->padfZ ); if( psShape->padfM != NULL ) free( psShape->padfM ); if( psShape->panPartStart != NULL ) free( psShape->panPartStart ); if( psShape->panPartType != NULL ) free( psShape->panPartType ); free( psShape ); } /************************************************************************/ /* SHPRewindObject() */ /* */ /* Reset the winding of polygon objects to adhere to the */ /* specification. */ /************************************************************************/ int SHPAPI_CALL SHPRewindObject( SHPHandle hSHP, SHPObject * psObject ) { int iOpRing, bAltered = 0; /* -------------------------------------------------------------------- */ /* Do nothing if this is not a polygon object. */ /* -------------------------------------------------------------------- */ if( psObject->nSHPType != SHPT_POLYGON && psObject->nSHPType != SHPT_POLYGONZ && psObject->nSHPType != SHPT_POLYGONM ) return 0; /* -------------------------------------------------------------------- */ /* Process each of the rings. */ /* -------------------------------------------------------------------- */ for( iOpRing = 0; iOpRing < psObject->nParts; iOpRing++ ) { int bInner, iVert, nVertCount, nVertStart, iCheckRing; double dfSum, dfTestX, dfTestY; /* -------------------------------------------------------------------- */ /* Determine if this ring is an inner ring or an outer ring */ /* relative to all the other rings. For now we assume the */ /* first ring is outer and all others are inner, but eventually */ /* we need to fix this to handle multiple island polygons and */ /* unordered sets of rings. */ /* -------------------------------------------------------------------- */ dfTestX = psObject->padfX[psObject->panPartStart[iOpRing]]; dfTestY = psObject->padfY[psObject->panPartStart[iOpRing]]; bInner = FALSE; for( iCheckRing = 0; iCheckRing < psObject->nParts; iCheckRing++ ) { int iEdge; if( iCheckRing == iOpRing ) continue; nVertStart = psObject->panPartStart[iCheckRing]; if( iCheckRing == psObject->nParts-1 ) nVertCount = psObject->nVertices - psObject->panPartStart[iCheckRing]; else nVertCount = psObject->panPartStart[iCheckRing+1] - psObject->panPartStart[iCheckRing]; for( iEdge = 0; iEdge < nVertCount; iEdge++ ) { int iNext; if( iEdge < nVertCount-1 ) iNext = iEdge+1; else iNext = 0; if( (psObject->padfY[iEdge+nVertStart] < dfTestY && psObject->padfY[iNext+nVertStart] >= dfTestY) || (psObject->padfY[iNext+nVertStart] < dfTestY && psObject->padfY[iEdge+nVertStart] >= dfTestY) ) { if( psObject->padfX[iEdge+nVertStart] + (dfTestY - psObject->padfY[iEdge+nVertStart]) / (psObject->padfY[iNext+nVertStart] - psObject->padfY[iEdge+nVertStart]) * (psObject->padfX[iNext+nVertStart] - psObject->padfX[iEdge+nVertStart]) < dfTestX ) bInner = !bInner; } } } /* -------------------------------------------------------------------- */ /* Determine the current order of this ring so we will know if */ /* it has to be reversed. */ /* -------------------------------------------------------------------- */ nVertStart = psObject->panPartStart[iOpRing]; if( iOpRing == psObject->nParts-1 ) nVertCount = psObject->nVertices - psObject->panPartStart[iOpRing]; else nVertCount = psObject->panPartStart[iOpRing+1] - psObject->panPartStart[iOpRing]; dfSum = 0.0; for( iVert = nVertStart; iVert < nVertStart+nVertCount-1; iVert++ ) { dfSum += psObject->padfX[iVert] * psObject->padfY[iVert+1] - psObject->padfY[iVert] * psObject->padfX[iVert+1]; } dfSum += psObject->padfX[iVert] * psObject->padfY[nVertStart] - psObject->padfY[iVert] * psObject->padfX[nVertStart]; /* -------------------------------------------------------------------- */ /* Reverse if necessary. */ /* -------------------------------------------------------------------- */ if( (dfSum < 0.0 && bInner) || (dfSum > 0.0 && !bInner) ) { int i; bAltered++; for( i = 0; i < nVertCount/2; i++ ) { double dfSaved; /* Swap X */ dfSaved = psObject->padfX[nVertStart+i]; psObject->padfX[nVertStart+i] = psObject->padfX[nVertStart+nVertCount-i-1]; psObject->padfX[nVertStart+nVertCount-i-1] = dfSaved; /* Swap Y */ dfSaved = psObject->padfY[nVertStart+i]; psObject->padfY[nVertStart+i] = psObject->padfY[nVertStart+nVertCount-i-1]; psObject->padfY[nVertStart+nVertCount-i-1] = dfSaved; /* Swap Z */ if( psObject->padfZ ) { dfSaved = psObject->padfZ[nVertStart+i]; psObject->padfZ[nVertStart+i] = psObject->padfZ[nVertStart+nVertCount-i-1]; psObject->padfZ[nVertStart+nVertCount-i-1] = dfSaved; } /* Swap M */ if( psObject->padfM ) { dfSaved = psObject->padfM[nVertStart+i]; psObject->padfM[nVertStart+i] = psObject->padfM[nVertStart+nVertCount-i-1]; psObject->padfM[nVertStart+nVertCount-i-1] = dfSaved; } } } } return bAltered; } ./shapelib-1.2.10/shprewind.c0100644000076500001440000000757507644273432015446 0ustar warmerdausers/****************************************************************************** * $Id: shprewind.c,v 1.2 2002/04/10 17:23:11 warmerda Exp $ * * Project: Shapelib * Purpose: Utility to validate and reset the winding order of rings in * polygon geometries to match the ordering required by spec. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2002, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: shprewind.c,v $ * Revision 1.2 2002/04/10 17:23:11 warmerda * copy from source to destination now * * Revision 1.1 2002/04/10 16:56:36 warmerda * New * */ #include "shapefil.h" int main( int argc, char ** argv ) { SHPHandle hSHP, hSHPOut; int nShapeType, nEntities, i, nInvalidCount=0; double adfMinBound[4], adfMaxBound[4]; /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc != 3 ) { printf( "shprewind in_shp_file out_shp_file\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( argv[1], "rb" ); if( hSHP == NULL ) { printf( "Unable to open:%s\n", argv[1] ); exit( 1 ); } SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound ); /* -------------------------------------------------------------------- */ /* Create output shapefile. */ /* -------------------------------------------------------------------- */ hSHPOut = SHPCreate( argv[2], nShapeType ); if( hSHPOut == NULL ) { printf( "Unable to create:%s\n", argv[2] ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Skim over the list of shapes, printing all the vertices. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nEntities; i++ ) { int j; SHPObject *psShape; psShape = SHPReadObject( hSHP, i ); if( SHPRewindObject( hSHP, psShape ) ) nInvalidCount++; SHPWriteObject( hSHPOut, -1, psShape ); SHPDestroyObject( psShape ); } SHPClose( hSHP ); SHPClose( hSHPOut ); printf( "%d objects rewound.\n", nInvalidCount ); exit( 0 ); } ./shapelib-1.2.10/shptest.c0100644000076500001440000002276607644273432015134 0ustar warmerdausers/****************************************************************************** * $Id: shptest.c,v 1.6 2002/01/15 14:36:07 warmerda Exp $ * * Project: Shapelib * Purpose: Application for generating sample Shapefiles of various types. * Used by the stream2.sh test script. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: shptest.c,v $ * Revision 1.6 2002/01/15 14:36:07 warmerda * updated email address * * Revision 1.5 2001/06/22 02:18:20 warmerda * Added null shape support * * Revision 1.4 2000/07/07 13:39:45 warmerda * removed unused variables, and added system include files * * Revision 1.3 1999/11/05 14:12:05 warmerda * updated license terms * * Revision 1.2 1998/12/16 05:15:20 warmerda * Added support for writing multipatch. * * Revision 1.1 1998/11/09 20:18:42 warmerda * Initial revision * */ static char rcsid[] = "$Id: shptest.c,v 1.6 2002/01/15 14:36:07 warmerda Exp $"; #include #include #include "shapefil.h" /************************************************************************/ /* Test_WritePoints() */ /* */ /* Write a small point file. */ /************************************************************************/ static void Test_WritePoints( int nSHPType, const char *pszFilename ) { SHPHandle hSHPHandle; SHPObject *psShape; double x, y, z, m; hSHPHandle = SHPCreate( pszFilename, nSHPType ); x = 1.0; y = 2.0; z = 3.0; m = 4.0; psShape = SHPCreateObject( nSHPType, -1, 0, NULL, NULL, 1, &x, &y, &z, &m ); SHPWriteObject( hSHPHandle, -1, psShape ); SHPDestroyObject( psShape ); x = 10.0; y = 20.0; z = 30.0; m = 40.0; psShape = SHPCreateObject( nSHPType, -1, 0, NULL, NULL, 1, &x, &y, &z, &m ); SHPWriteObject( hSHPHandle, -1, psShape ); SHPDestroyObject( psShape ); SHPClose( hSHPHandle ); } /************************************************************************/ /* Test_WriteMultiPoints() */ /* */ /* Write a small multipoint file. */ /************************************************************************/ static void Test_WriteMultiPoints( int nSHPType, const char *pszFilename ) { SHPHandle hSHPHandle; SHPObject *psShape; double x[4], y[4], z[4], m[4]; int i, iShape; hSHPHandle = SHPCreate( pszFilename, nSHPType ); for( iShape = 0; iShape < 3; iShape++ ) { for( i = 0; i < 4; i++ ) { x[i] = iShape * 10 + i + 1.15; y[i] = iShape * 10 + i + 2.25; z[i] = iShape * 10 + i + 3.35; m[i] = iShape * 10 + i + 4.45; } psShape = SHPCreateObject( nSHPType, -1, 0, NULL, NULL, 4, x, y, z, m ); SHPWriteObject( hSHPHandle, -1, psShape ); SHPDestroyObject( psShape ); } SHPClose( hSHPHandle ); } /************************************************************************/ /* Test_WriteArcPoly() */ /* */ /* Write a small arc or polygon file. */ /************************************************************************/ static void Test_WriteArcPoly( int nSHPType, const char *pszFilename ) { SHPHandle hSHPHandle; SHPObject *psShape; double x[100], y[100], z[100], m[100]; int anPartStart[100]; int anPartType[100], *panPartType; int i, iShape; hSHPHandle = SHPCreate( pszFilename, nSHPType ); if( nSHPType == SHPT_MULTIPATCH ) panPartType = anPartType; else panPartType = NULL; for( iShape = 0; iShape < 3; iShape++ ) { x[0] = 1.0; y[0] = 1.0+iShape*3; x[1] = 2.0; y[1] = 1.0+iShape*3; x[2] = 2.0; y[2] = 2.0+iShape*3; x[3] = 1.0; y[3] = 2.0+iShape*3; x[4] = 1.0; y[4] = 1.0+iShape*3; for( i = 0; i < 5; i++ ) { z[i] = iShape * 10 + i + 3.35; m[i] = iShape * 10 + i + 4.45; } psShape = SHPCreateObject( nSHPType, -1, 0, NULL, NULL, 5, x, y, z, m ); SHPWriteObject( hSHPHandle, -1, psShape ); SHPDestroyObject( psShape ); } /* -------------------------------------------------------------------- */ /* Do a multi part polygon (shape). We close it, and have two */ /* inner rings. */ /* -------------------------------------------------------------------- */ x[0] = 0.0; y[0] = 0.0; x[1] = 0; y[1] = 100; x[2] = 100; y[2] = 100; x[3] = 100; y[3] = 0; x[4] = 0; y[4] = 0; x[5] = 10; y[5] = 20; x[6] = 30; y[6] = 20; x[7] = 30; y[7] = 40; x[8] = 10; y[8] = 40; x[9] = 10; y[9] = 20; x[10] = 60; y[10] = 20; x[11] = 90; y[11] = 20; x[12] = 90; y[12] = 40; x[13] = 60; y[13] = 40; x[14] = 60; y[14] = 20; for( i = 0; i < 15; i++ ) { z[i] = i; m[i] = i*2; } anPartStart[0] = 0; anPartStart[1] = 5; anPartStart[2] = 10; anPartType[0] = SHPP_RING; anPartType[1] = SHPP_INNERRING; anPartType[2] = SHPP_INNERRING; psShape = SHPCreateObject( nSHPType, -1, 3, anPartStart, panPartType, 15, x, y, z, m ); SHPWriteObject( hSHPHandle, -1, psShape ); SHPDestroyObject( psShape ); SHPClose( hSHPHandle ); } /************************************************************************/ /* main() */ /************************************************************************/ int main( int argc, char ** argv ) { /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc != 2 ) { printf( "shptest test_number\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Figure out which test to run. */ /* -------------------------------------------------------------------- */ if( atoi(argv[1]) == 0 ) Test_WritePoints( SHPT_NULL, "test0.shp" ); else if( atoi(argv[1]) == 1 ) Test_WritePoints( SHPT_POINT, "test1.shp" ); else if( atoi(argv[1]) == 2 ) Test_WritePoints( SHPT_POINTZ, "test2.shp" ); else if( atoi(argv[1]) == 3 ) Test_WritePoints( SHPT_POINTM, "test3.shp" ); else if( atoi(argv[1]) == 4 ) Test_WriteMultiPoints( SHPT_MULTIPOINT, "test4.shp" ); else if( atoi(argv[1]) == 5 ) Test_WriteMultiPoints( SHPT_MULTIPOINTZ, "test5.shp" ); else if( atoi(argv[1]) == 6 ) Test_WriteMultiPoints( SHPT_MULTIPOINTM, "test6.shp" ); else if( atoi(argv[1]) == 7 ) Test_WriteArcPoly( SHPT_ARC, "test7.shp" ); else if( atoi(argv[1]) == 8 ) Test_WriteArcPoly( SHPT_ARCZ, "test8.shp" ); else if( atoi(argv[1]) == 9 ) Test_WriteArcPoly( SHPT_ARCM, "test9.shp" ); else if( atoi(argv[1]) == 10 ) Test_WriteArcPoly( SHPT_POLYGON, "test10.shp" ); else if( atoi(argv[1]) == 11 ) Test_WriteArcPoly( SHPT_POLYGONZ, "test11.shp" ); else if( atoi(argv[1]) == 12 ) Test_WriteArcPoly( SHPT_POLYGONM, "test12.shp" ); else if( atoi(argv[1]) == 13 ) Test_WriteArcPoly( SHPT_MULTIPATCH, "test13.shp" ); else { printf( "Test `%s' not recognised.\n", argv[1] ); exit( 10 ); } #ifdef USE_DBMALLOC malloc_dump(2); #endif exit( 0 ); } ./shapelib-1.2.10/shptree.c0100644000076500001440000006540607644273432015112 0ustar warmerdausers/****************************************************************************** * $Id: shptree.c,v 1.9 2003/01/28 15:53:41 warmerda Exp $ * * Project: Shapelib * Purpose: Implementation of quadtree building and searching functions. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: shptree.c,v $ * Revision 1.9 2003/01/28 15:53:41 warmerda * Avoid build warnings. * * Revision 1.8 2002/05/07 13:07:45 warmerda * use qsort() - patch from Bernhard Herzog * * Revision 1.7 2002/01/15 14:36:07 warmerda * updated email address * * Revision 1.6 2001/05/23 13:36:52 warmerda * added use of SHPAPI_CALL * * Revision 1.5 1999/11/05 14:12:05 warmerda * updated license terms * * Revision 1.4 1999/06/02 18:24:21 warmerda * added trimming code * * Revision 1.3 1999/06/02 17:56:12 warmerda * added quad'' subnode support for trees * * Revision 1.2 1999/05/18 19:11:11 warmerda * Added example searching capability * * Revision 1.1 1999/05/18 17:49:20 warmerda * New * */ static char rcsid[] = "$Id: shptree.c,v 1.9 2003/01/28 15:53:41 warmerda Exp $"; #include "shapefil.h" #include #include #include #include #ifndef TRUE # define TRUE 1 # define FALSE 0 #endif /* -------------------------------------------------------------------- */ /* If the following is 0.5, nodes will be split in half. If it */ /* is 0.6 then each subnode will contain 60% of the parent */ /* node, with 20% representing overlap. This can be help to */ /* prevent small objects on a boundary from shifting too high */ /* up the tree. */ /* -------------------------------------------------------------------- */ #define SHP_SPLIT_RATIO 0.55 /************************************************************************/ /* SfRealloc() */ /* */ /* A realloc cover function that will access a NULL pointer as */ /* a valid input. */ /************************************************************************/ static void * SfRealloc( void * pMem, int nNewSize ) { if( pMem == NULL ) return( (void *) malloc(nNewSize) ); else return( (void *) realloc(pMem,nNewSize) ); } /************************************************************************/ /* SHPTreeNodeInit() */ /* */ /* Initialize a tree node. */ /************************************************************************/ static SHPTreeNode *SHPTreeNodeCreate( double * padfBoundsMin, double * padfBoundsMax ) { SHPTreeNode *psTreeNode; psTreeNode = (SHPTreeNode *) malloc(sizeof(SHPTreeNode)); psTreeNode->nShapeCount = 0; psTreeNode->panShapeIds = NULL; psTreeNode->papsShapeObj = NULL; psTreeNode->nSubNodes = 0; if( padfBoundsMin != NULL ) memcpy( psTreeNode->adfBoundsMin, padfBoundsMin, sizeof(double) * 4 ); if( padfBoundsMax != NULL ) memcpy( psTreeNode->adfBoundsMax, padfBoundsMax, sizeof(double) * 4 ); return psTreeNode; } /************************************************************************/ /* SHPCreateTree() */ /************************************************************************/ SHPTree SHPAPI_CALL1(*) SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth, double *padfBoundsMin, double *padfBoundsMax ) { SHPTree *psTree; if( padfBoundsMin == NULL && hSHP == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Allocate the tree object */ /* -------------------------------------------------------------------- */ psTree = (SHPTree *) malloc(sizeof(SHPTree)); psTree->hSHP = hSHP; psTree->nMaxDepth = nMaxDepth; psTree->nDimension = nDimension; /* -------------------------------------------------------------------- */ /* If no max depth was defined, try to select a reasonable one */ /* that implies approximately 8 shapes per node. */ /* -------------------------------------------------------------------- */ if( psTree->nMaxDepth == 0 && hSHP != NULL ) { int nMaxNodeCount = 1; int nShapeCount; SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL ); while( nMaxNodeCount*4 < nShapeCount ) { psTree->nMaxDepth += 1; nMaxNodeCount = nMaxNodeCount * 2; } } /* -------------------------------------------------------------------- */ /* Allocate the root node. */ /* -------------------------------------------------------------------- */ psTree->psRoot = SHPTreeNodeCreate( padfBoundsMin, padfBoundsMax ); /* -------------------------------------------------------------------- */ /* Assign the bounds to the root node. If none are passed in, */ /* use the bounds of the provided file otherwise the create */ /* function will have already set the bounds. */ /* -------------------------------------------------------------------- */ if( padfBoundsMin == NULL ) { SHPGetInfo( hSHP, NULL, NULL, psTree->psRoot->adfBoundsMin, psTree->psRoot->adfBoundsMax ); } /* -------------------------------------------------------------------- */ /* If we have a file, insert all it's shapes into the tree. */ /* -------------------------------------------------------------------- */ if( hSHP != NULL ) { int iShape, nShapeCount; SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL ); for( iShape = 0; iShape < nShapeCount; iShape++ ) { SHPObject *psShape; psShape = SHPReadObject( hSHP, iShape ); SHPTreeAddShapeId( psTree, psShape ); SHPDestroyObject( psShape ); } } return psTree; } /************************************************************************/ /* SHPDestroyTreeNode() */ /************************************************************************/ static void SHPDestroyTreeNode( SHPTreeNode * psTreeNode ) { int i; for( i = 0; i < psTreeNode->nSubNodes; i++ ) { if( psTreeNode->apsSubNode[i] != NULL ) SHPDestroyTreeNode( psTreeNode->apsSubNode[i] ); } if( psTreeNode->panShapeIds != NULL ) free( psTreeNode->panShapeIds ); if( psTreeNode->papsShapeObj != NULL ) { for( i = 0; i < psTreeNode->nShapeCount; i++ ) { if( psTreeNode->papsShapeObj[i] != NULL ) SHPDestroyObject( psTreeNode->papsShapeObj[i] ); } free( psTreeNode->papsShapeObj ); } free( psTreeNode ); } /************************************************************************/ /* SHPDestroyTree() */ /************************************************************************/ void SHPAPI_CALL SHPDestroyTree( SHPTree * psTree ) { SHPDestroyTreeNode( psTree->psRoot ); free( psTree ); } /************************************************************************/ /* SHPCheckBoundsOverlap() */ /* */ /* Do the given boxes overlap at all? */ /************************************************************************/ int SHPAPI_CALL SHPCheckBoundsOverlap( double * padfBox1Min, double * padfBox1Max, double * padfBox2Min, double * padfBox2Max, int nDimension ) { int iDim; for( iDim = 0; iDim < nDimension; iDim++ ) { if( padfBox2Max[iDim] < padfBox1Min[iDim] ) return FALSE; if( padfBox1Max[iDim] < padfBox2Min[iDim] ) return FALSE; } return TRUE; } /************************************************************************/ /* SHPCheckObjectContained() */ /* */ /* Does the given shape fit within the indicated extents? */ /************************************************************************/ static int SHPCheckObjectContained( SHPObject * psObject, int nDimension, double * padfBoundsMin, double * padfBoundsMax ) { if( psObject->dfXMin < padfBoundsMin[0] || psObject->dfXMax > padfBoundsMax[0] ) return FALSE; if( psObject->dfYMin < padfBoundsMin[1] || psObject->dfYMax > padfBoundsMax[1] ) return FALSE; if( nDimension == 2 ) return TRUE; if( psObject->dfZMin < padfBoundsMin[2] || psObject->dfZMax < padfBoundsMax[2] ) return FALSE; if( nDimension == 3 ) return TRUE; if( psObject->dfMMin < padfBoundsMin[3] || psObject->dfMMax < padfBoundsMax[3] ) return FALSE; return TRUE; } /************************************************************************/ /* SHPTreeSplitBounds() */ /* */ /* Split a region into two subregion evenly, cutting along the */ /* longest dimension. */ /************************************************************************/ void SHPAPI_CALL SHPTreeSplitBounds( double *padfBoundsMinIn, double *padfBoundsMaxIn, double *padfBoundsMin1, double * padfBoundsMax1, double *padfBoundsMin2, double * padfBoundsMax2 ) { /* -------------------------------------------------------------------- */ /* The output bounds will be very similar to the input bounds, */ /* so just copy over to start. */ /* -------------------------------------------------------------------- */ memcpy( padfBoundsMin1, padfBoundsMinIn, sizeof(double) * 4 ); memcpy( padfBoundsMax1, padfBoundsMaxIn, sizeof(double) * 4 ); memcpy( padfBoundsMin2, padfBoundsMinIn, sizeof(double) * 4 ); memcpy( padfBoundsMax2, padfBoundsMaxIn, sizeof(double) * 4 ); /* -------------------------------------------------------------------- */ /* Split in X direction. */ /* -------------------------------------------------------------------- */ if( (padfBoundsMaxIn[0] - padfBoundsMinIn[0]) > (padfBoundsMaxIn[1] - padfBoundsMinIn[1]) ) { double dfRange = padfBoundsMaxIn[0] - padfBoundsMinIn[0]; padfBoundsMax1[0] = padfBoundsMinIn[0] + dfRange * SHP_SPLIT_RATIO; padfBoundsMin2[0] = padfBoundsMaxIn[0] - dfRange * SHP_SPLIT_RATIO; } /* -------------------------------------------------------------------- */ /* Otherwise split in Y direction. */ /* -------------------------------------------------------------------- */ else { double dfRange = padfBoundsMaxIn[1] - padfBoundsMinIn[1]; padfBoundsMax1[1] = padfBoundsMinIn[1] + dfRange * SHP_SPLIT_RATIO; padfBoundsMin2[1] = padfBoundsMaxIn[1] - dfRange * SHP_SPLIT_RATIO; } } /************************************************************************/ /* SHPTreeNodeAddShapeId() */ /************************************************************************/ static int SHPTreeNodeAddShapeId( SHPTreeNode * psTreeNode, SHPObject * psObject, int nMaxDepth, int nDimension ) { int i; /* -------------------------------------------------------------------- */ /* If there are subnodes, then consider wiether this object */ /* will fit in them. */ /* -------------------------------------------------------------------- */ if( nMaxDepth > 1 && psTreeNode->nSubNodes > 0 ) { for( i = 0; i < psTreeNode->nSubNodes; i++ ) { if( SHPCheckObjectContained(psObject, nDimension, psTreeNode->apsSubNode[i]->adfBoundsMin, psTreeNode->apsSubNode[i]->adfBoundsMax)) { return SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[i], psObject, nMaxDepth-1, nDimension ); } } } /* -------------------------------------------------------------------- */ /* Otherwise, consider creating four subnodes if could fit into */ /* them, and adding to the appropriate subnode. */ /* -------------------------------------------------------------------- */ #if MAX_SUBNODE == 4 else if( nMaxDepth > 1 && psTreeNode->nSubNodes == 0 ) { double adfBoundsMinH1[4], adfBoundsMaxH1[4]; double adfBoundsMinH2[4], adfBoundsMaxH2[4]; double adfBoundsMin1[4], adfBoundsMax1[4]; double adfBoundsMin2[4], adfBoundsMax2[4]; double adfBoundsMin3[4], adfBoundsMax3[4]; double adfBoundsMin4[4], adfBoundsMax4[4]; SHPTreeSplitBounds( psTreeNode->adfBoundsMin, psTreeNode->adfBoundsMax, adfBoundsMinH1, adfBoundsMaxH1, adfBoundsMinH2, adfBoundsMaxH2 ); SHPTreeSplitBounds( adfBoundsMinH1, adfBoundsMaxH1, adfBoundsMin1, adfBoundsMax1, adfBoundsMin2, adfBoundsMax2 ); SHPTreeSplitBounds( adfBoundsMinH2, adfBoundsMaxH2, adfBoundsMin3, adfBoundsMax3, adfBoundsMin4, adfBoundsMax4 ); if( SHPCheckObjectContained(psObject, nDimension, adfBoundsMin1, adfBoundsMax1) || SHPCheckObjectContained(psObject, nDimension, adfBoundsMin2, adfBoundsMax2) || SHPCheckObjectContained(psObject, nDimension, adfBoundsMin3, adfBoundsMax3) || SHPCheckObjectContained(psObject, nDimension, adfBoundsMin4, adfBoundsMax4) ) { psTreeNode->nSubNodes = 4; psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1, adfBoundsMax1 ); psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2, adfBoundsMax2 ); psTreeNode->apsSubNode[2] = SHPTreeNodeCreate( adfBoundsMin3, adfBoundsMax3 ); psTreeNode->apsSubNode[3] = SHPTreeNodeCreate( adfBoundsMin4, adfBoundsMax4 ); /* recurse back on this node now that it has subnodes */ return( SHPTreeNodeAddShapeId( psTreeNode, psObject, nMaxDepth, nDimension ) ); } } #endif /* MAX_SUBNODE == 4 */ /* -------------------------------------------------------------------- */ /* Otherwise, consider creating two subnodes if could fit into */ /* them, and adding to the appropriate subnode. */ /* -------------------------------------------------------------------- */ #if MAX_SUBNODE == 2 else if( nMaxDepth > 1 && psTreeNode->nSubNodes == 0 ) { double adfBoundsMin1[4], adfBoundsMax1[4]; double adfBoundsMin2[4], adfBoundsMax2[4]; SHPTreeSplitBounds( psTreeNode->adfBoundsMin, psTreeNode->adfBoundsMax, adfBoundsMin1, adfBoundsMax1, adfBoundsMin2, adfBoundsMax2 ); if( SHPCheckObjectContained(psObject, nDimension, adfBoundsMin1, adfBoundsMax1)) { psTreeNode->nSubNodes = 2; psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1, adfBoundsMax1 ); psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2, adfBoundsMax2 ); return( SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[0], psObject, nMaxDepth - 1, nDimension ) ); } else if( SHPCheckObjectContained(psObject, nDimension, adfBoundsMin2, adfBoundsMax2) ) { psTreeNode->nSubNodes = 2; psTreeNode->apsSubNode[0] = SHPTreeNodeCreate( adfBoundsMin1, adfBoundsMax1 ); psTreeNode->apsSubNode[1] = SHPTreeNodeCreate( adfBoundsMin2, adfBoundsMax2 ); return( SHPTreeNodeAddShapeId( psTreeNode->apsSubNode[1], psObject, nMaxDepth - 1, nDimension ) ); } } #endif /* MAX_SUBNODE == 2 */ /* -------------------------------------------------------------------- */ /* If none of that worked, just add it to this nodes list. */ /* -------------------------------------------------------------------- */ psTreeNode->nShapeCount++; psTreeNode->panShapeIds = SfRealloc( psTreeNode->panShapeIds, sizeof(int) * psTreeNode->nShapeCount ); psTreeNode->panShapeIds[psTreeNode->nShapeCount-1] = psObject->nShapeId; if( psTreeNode->papsShapeObj != NULL ) { psTreeNode->papsShapeObj = SfRealloc( psTreeNode->papsShapeObj, sizeof(void *) * psTreeNode->nShapeCount ); psTreeNode->papsShapeObj[psTreeNode->nShapeCount-1] = NULL; } return TRUE; } /************************************************************************/ /* SHPTreeAddShapeId() */ /* */ /* Add a shape to the tree, but don't keep a pointer to the */ /* object data, just keep the shapeid. */ /************************************************************************/ int SHPAPI_CALL SHPTreeAddShapeId( SHPTree * psTree, SHPObject * psObject ) { return( SHPTreeNodeAddShapeId( psTree->psRoot, psObject, psTree->nMaxDepth, psTree->nDimension ) ); } /************************************************************************/ /* SHPTreeCollectShapesIds() */ /* */ /* Work function implementing SHPTreeFindLikelyShapes() on a */ /* tree node by tree node basis. */ /************************************************************************/ void SHPAPI_CALL SHPTreeCollectShapeIds( SHPTree *hTree, SHPTreeNode * psTreeNode, double * padfBoundsMin, double * padfBoundsMax, int * pnShapeCount, int * pnMaxShapes, int ** ppanShapeList ) { int i; /* -------------------------------------------------------------------- */ /* Does this node overlap the area of interest at all? If not, */ /* return without adding to the list at all. */ /* -------------------------------------------------------------------- */ if( !SHPCheckBoundsOverlap( psTreeNode->adfBoundsMin, psTreeNode->adfBoundsMax, padfBoundsMin, padfBoundsMax, hTree->nDimension ) ) return; /* -------------------------------------------------------------------- */ /* Grow the list to hold the shapes on this node. */ /* -------------------------------------------------------------------- */ if( *pnShapeCount + psTreeNode->nShapeCount > *pnMaxShapes ) { *pnMaxShapes = (*pnShapeCount + psTreeNode->nShapeCount) * 2 + 20; *ppanShapeList = (int *) SfRealloc(*ppanShapeList,sizeof(int) * *pnMaxShapes); } /* -------------------------------------------------------------------- */ /* Add the local nodes shapeids to the list. */ /* -------------------------------------------------------------------- */ for( i = 0; i < psTreeNode->nShapeCount; i++ ) { (*ppanShapeList)[(*pnShapeCount)++] = psTreeNode->panShapeIds[i]; } /* -------------------------------------------------------------------- */ /* Recurse to subnodes if they exist. */ /* -------------------------------------------------------------------- */ for( i = 0; i < psTreeNode->nSubNodes; i++ ) { if( psTreeNode->apsSubNode[i] != NULL ) SHPTreeCollectShapeIds( hTree, psTreeNode->apsSubNode[i], padfBoundsMin, padfBoundsMax, pnShapeCount, pnMaxShapes, ppanShapeList ); } } /************************************************************************/ /* SHPTreeFindLikelyShapes() */ /* */ /* Find all shapes within tree nodes for which the tree node */ /* bounding box overlaps the search box. The return value is */ /* an array of shapeids terminated by a -1. The shapeids will */ /* be in order, as hopefully this will result in faster (more */ /* sequential) reading from the file. */ /************************************************************************/ /* helper for qsort */ static int compare_ints( const void * a, const void * b) { return (*(int*)a) - (*(int*)b); } int SHPAPI_CALL1(*) SHPTreeFindLikelyShapes( SHPTree * hTree, double * padfBoundsMin, double * padfBoundsMax, int * pnShapeCount ) { int *panShapeList=NULL, nMaxShapes = 0; /* -------------------------------------------------------------------- */ /* Perform the search by recursive descent. */ /* -------------------------------------------------------------------- */ *pnShapeCount = 0; SHPTreeCollectShapeIds( hTree, hTree->psRoot, padfBoundsMin, padfBoundsMax, pnShapeCount, &nMaxShapes, &panShapeList ); /* -------------------------------------------------------------------- */ /* Sort the id array */ /* -------------------------------------------------------------------- */ qsort(panShapeList, *pnShapeCount, sizeof(int), compare_ints); return panShapeList; } /************************************************************************/ /* SHPTreeNodeTrim() */ /* */ /* This is the recurve version of SHPTreeTrimExtraNodes() that */ /* walks the tree cleaning it up. */ /************************************************************************/ static int SHPTreeNodeTrim( SHPTreeNode * psTreeNode ) { int i; /* -------------------------------------------------------------------- */ /* Trim subtrees, and free subnodes that come back empty. */ /* -------------------------------------------------------------------- */ for( i = 0; i < psTreeNode->nSubNodes; i++ ) { if( SHPTreeNodeTrim( psTreeNode->apsSubNode[i] ) ) { SHPDestroyTreeNode( psTreeNode->apsSubNode[i] ); psTreeNode->apsSubNode[i] = psTreeNode->apsSubNode[psTreeNode->nSubNodes-1]; psTreeNode->nSubNodes--; i--; /* process the new occupant of this subnode entry */ } } /* -------------------------------------------------------------------- */ /* We should be trimmed if we have no subnodes, and no shapes. */ /* -------------------------------------------------------------------- */ return( psTreeNode->nSubNodes == 0 && psTreeNode->nShapeCount == 0 ); } /************************************************************************/ /* SHPTreeTrimExtraNodes() */ /* */ /* Trim empty nodes from the tree. Note that we never trim an */ /* empty root node. */ /************************************************************************/ void SHPAPI_CALL SHPTreeTrimExtraNodes( SHPTree * hTree ) { SHPTreeNodeTrim( hTree->psRoot ); } ./shapelib-1.2.10/shptreedump.c0100644000076500001440000003317607644273432015777 0ustar warmerdausers/****************************************************************************** * $Id: shptreedump.c,v 1.7 2002/04/10 16:59:12 warmerda Exp $ * * Project: Shapelib * Purpose: Mainline for creating and dumping an ASCII representation of * a quadtree. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: shptreedump.c,v $ * Revision 1.7 2002/04/10 16:59:12 warmerda * fixed email * * Revision 1.6 1999/11/05 14:12:05 warmerda * updated license terms * * Revision 1.5 1999/06/02 18:24:21 warmerda * added trimming code * * Revision 1.4 1999/06/02 17:56:12 warmerda * added quad'' subnode support for trees * * Revision 1.3 1999/05/18 19:13:13 warmerda * Use fabs() instead of abs(). * * Revision 1.2 1999/05/18 19:11:11 warmerda * Added example searching capability * * Revision 1.1 1999/05/18 17:49:20 warmerda * New * */ static char rcsid[] = "$Id: shptreedump.c,v 1.7 2002/04/10 16:59:12 warmerda Exp $"; #include "shapefil.h" #include #include #include static void SHPTreeNodeDump( SHPTree *, SHPTreeNode *, const char *, int ); static void SHPTreeNodeSearchAndDump( SHPTree *, double *, double * ); /************************************************************************/ /* Usage() */ /************************************************************************/ static void Usage() { printf( "shptreedump [-maxdepth n] [-search xmin ymin xmax ymax]\n" " [-v] shp_file\n" ); exit( 1 ); } /************************************************************************/ /* main() */ /************************************************************************/ int main( int argc, char ** argv ) { SHPHandle hSHP; SHPTree *psTree; int nExpandShapes = 0; int nMaxDepth = 0; int nDoSearch = 0; double adfSearchMin[4], adfSearchMax[4]; /* -------------------------------------------------------------------- */ /* Consume flags. */ /* -------------------------------------------------------------------- */ while( argc > 1 ) { if( strcmp(argv[1],"-v") == 0 ) { nExpandShapes = 1; argv++; argc--; } else if( strcmp(argv[1],"-maxdepth") == 0 && argc > 2 ) { nMaxDepth = atoi(argv[2]); argv += 2; argc -= 2; } else if( strcmp(argv[1],"-search") == 0 && argc > 5 ) { nDoSearch = 1; adfSearchMin[0] = atof(argv[2]); adfSearchMin[1] = atof(argv[3]); adfSearchMax[0] = atof(argv[4]); adfSearchMax[1] = atof(argv[5]); adfSearchMin[2] = adfSearchMax[2] = 0.0; adfSearchMin[3] = adfSearchMax[3] = 0.0; if( adfSearchMin[0] > adfSearchMax[0] || adfSearchMin[1] > adfSearchMax[1] ) { printf( "Min greater than max in search criteria.\n" ); Usage(); } argv += 5; argc -= 5; } else break; } /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc < 2 ) { Usage(); } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( argv[1], "rb" ); if( hSHP == NULL ) { printf( "Unable to open:%s\n", argv[1] ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Build a quadtree structure for this file. */ /* -------------------------------------------------------------------- */ psTree = SHPCreateTree( hSHP, 2, nMaxDepth, NULL, NULL ); /* -------------------------------------------------------------------- */ /* Trim unused nodes from the tree. */ /* -------------------------------------------------------------------- */ SHPTreeTrimExtraNodes( psTree ); /* -------------------------------------------------------------------- */ /* Dump tree by recursive descent. */ /* -------------------------------------------------------------------- */ if( !nDoSearch ) SHPTreeNodeDump( psTree, psTree->psRoot, "", nExpandShapes ); /* -------------------------------------------------------------------- */ /* or do a search instead. */ /* -------------------------------------------------------------------- */ else SHPTreeNodeSearchAndDump( psTree, adfSearchMin, adfSearchMax ); /* -------------------------------------------------------------------- */ /* cleanup */ /* -------------------------------------------------------------------- */ SHPDestroyTree( psTree ); SHPClose( hSHP ); #ifdef USE_DBMALLOC malloc_dump(2); #endif exit( 0 ); } /************************************************************************/ /* EmitCoordinate() */ /************************************************************************/ static void EmitCoordinate( double * padfCoord, int nDimension ) { const char *pszFormat; if( fabs(padfCoord[0]) < 180 && fabs(padfCoord[1]) < 180 ) pszFormat = "%.9f"; else pszFormat = "%.2f"; printf( pszFormat, padfCoord[0] ); printf( "," ); printf( pszFormat, padfCoord[1] ); if( nDimension > 2 ) { printf( "," ); printf( pszFormat, padfCoord[2] ); } if( nDimension > 3 ) { printf( "," ); printf( pszFormat, padfCoord[3] ); } } /************************************************************************/ /* EmitShape() */ /************************************************************************/ static void EmitShape( SHPObject * psObject, const char * pszPrefix, int nDimension ) { int i; printf( "%s( Shape\n", pszPrefix ); printf( "%s ShapeId = %d\n", pszPrefix, psObject->nShapeId ); printf( "%s Min = (", pszPrefix ); EmitCoordinate( &(psObject->dfXMin), nDimension ); printf( ")\n" ); printf( "%s Max = (", pszPrefix ); EmitCoordinate( &(psObject->dfXMax), nDimension ); printf( ")\n" ); for( i = 0; i < psObject->nVertices; i++ ) { double adfVertex[4]; printf( "%s Vertex[%d] = (", pszPrefix, i ); adfVertex[0] = psObject->padfX[i]; adfVertex[1] = psObject->padfY[i]; adfVertex[2] = psObject->padfZ[i]; adfVertex[3] = psObject->padfM[i]; EmitCoordinate( adfVertex, nDimension ); printf( ")\n" ); } printf( "%s)\n", pszPrefix ); } /************************************************************************/ /* SHPTreeNodeDump() */ /* */ /* Dump a tree node in a readable form. */ /************************************************************************/ static void SHPTreeNodeDump( SHPTree * psTree, SHPTreeNode * psTreeNode, const char * pszPrefix, int nExpandShapes ) { char szNextPrefix[150]; int i; strcpy( szNextPrefix, pszPrefix ); if( strlen(pszPrefix) < sizeof(szNextPrefix) - 3 ) strcat( szNextPrefix, " " ); printf( "%s( SHPTreeNode\n", pszPrefix ); /* -------------------------------------------------------------------- */ /* Emit the bounds. */ /* -------------------------------------------------------------------- */ printf( "%s Min = (", pszPrefix ); EmitCoordinate( psTreeNode->adfBoundsMin, psTree->nDimension ); printf( ")\n" ); printf( "%s Max = (", pszPrefix ); EmitCoordinate( psTreeNode->adfBoundsMax, psTree->nDimension ); printf( ")\n" ); /* -------------------------------------------------------------------- */ /* Emit the list of shapes on this node. */ /* -------------------------------------------------------------------- */ if( nExpandShapes ) { printf( "%s Shapes(%d):\n", pszPrefix, psTreeNode->nShapeCount ); for( i = 0; i < psTreeNode->nShapeCount; i++ ) { SHPObject *psObject; psObject = SHPReadObject( psTree->hSHP, psTreeNode->panShapeIds[i] ); assert( psObject != NULL ); if( psObject != NULL ) { EmitShape( psObject, szNextPrefix, psTree->nDimension ); } SHPDestroyObject( psObject ); } } else { printf( "%s Shapes(%d): ", pszPrefix, psTreeNode->nShapeCount ); for( i = 0; i < psTreeNode->nShapeCount; i++ ) { printf( "%d ", psTreeNode->panShapeIds[i] ); } printf( "\n" ); } /* -------------------------------------------------------------------- */ /* Emit subnodes. */ /* -------------------------------------------------------------------- */ for( i = 0; i < psTreeNode->nSubNodes; i++ ) { if( psTreeNode->apsSubNode[i] != NULL ) SHPTreeNodeDump( psTree, psTreeNode->apsSubNode[i], szNextPrefix, nExpandShapes ); } printf( "%s)\n", pszPrefix ); return; } /************************************************************************/ /* SHPTreeNodeSearchAndDump() */ /************************************************************************/ static void SHPTreeNodeSearchAndDump( SHPTree * hTree, double *padfBoundsMin, double *padfBoundsMax ) { int *panHits, nShapeCount, i; /* -------------------------------------------------------------------- */ /* Perform the search for likely candidates. These are shapes */ /* that fall into a tree node whose bounding box intersects our */ /* area of interest. */ /* -------------------------------------------------------------------- */ panHits = SHPTreeFindLikelyShapes( hTree, padfBoundsMin, padfBoundsMax, &nShapeCount ); /* -------------------------------------------------------------------- */ /* Read all of these shapes, and establish whether the shape's */ /* bounding box actually intersects the area of interest. Note */ /* that the bounding box could intersect the area of interest, */ /* and the shape itself still not cross it but we don't try to */ /* address that here. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nShapeCount; i++ ) { SHPObject *psObject; psObject = SHPReadObject( hTree->hSHP, panHits[i] ); if( psObject == NULL ) continue; if( !SHPCheckBoundsOverlap( padfBoundsMin, padfBoundsMax, &(psObject->dfXMin), &(psObject->dfXMax), hTree->nDimension ) ) { printf( "Shape %d: not in area of interest, but fetched.\n", panHits[i] ); } else { printf( "Shape %d: appears to be in area of interest.\n", panHits[i] ); } SHPDestroyObject( psObject ); } if( nShapeCount == 0 ) printf( "No shapes found in search.\n" ); } ./shapelib-1.2.10/shputils.c0100644000076500001440000011677507644273432015321 0ustar warmerdausers/****************************************************************************** * $Id: shputils.c,v 1.7 2003/02/25 17:20:22 warmerda Exp $ * * Project: Shapelib * Purpose: * Altered "shpdump" and "dbfdump" to allow two files to be appended. * Other Functions: * Selecting from the DBF before the write occurs. * Change the UNITS between Feet and Meters and Shift X,Y. * Clip and Erase boundary. The program only passes thru the * data once. * * Bill Miller North Carolina - Department of Transporation * Feb. 1997 -- bmiller@dot.state.nc.us * There was not a lot of time to debug hidden problems; * And the code is not very well organized or documented. * The clip/erase function was not well tested. * Oct. 2000 -- bmiller@dot.state.nc.us * Fixed the problem when select is using numbers * larger than short integer. It now reads long integer. * NOTE: DBF files created using windows NT will read as a string with * a length of 381 characters. This is a bug in "dbfopen". * * * Author: Bill Miller (bmiller@dot.state.nc.us) * ****************************************************************************** * Copyright (c) 1999, Frank Warmerdam * * This software is available under the following "MIT Style" license, * or at the option of the licensee under the LGPL (see LICENSE.LGPL). This * option is discussed in more detail in shapelib.html. * * -- * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: shputils.c,v $ * Revision 1.7 2003/02/25 17:20:22 warmerda * Set psCShape to NULL after SHPDestroyObject() to avoid multi-frees of * the same memory ... as submitted by Fred Fox. * * Revision 1.6 2001/08/28 13:57:14 warmerda * fixed DBFAddField return value check * * Revision 1.5 2000/11/02 13:52:48 warmerda * major upgrade from Bill Miller * * Revision 1.4 1999/11/05 14:12:05 warmerda * updated license terms * * Revision 1.3 1998/12/03 15:47:39 warmerda * Did a bunch of rewriting to make it work with the V1.2 API. * * Revision 1.2 1998/06/18 01:19:49 warmerda * Made C++ compilable. * * Revision 1.1 1997/05/27 20:40:27 warmerda * Initial revision */ static char rcsid[] = "$Id: shputils.c,v 1.7 2003/02/25 17:20:22 warmerda Exp $"; #include "shapefil.h" #include "string.h" #ifndef FALSE # define FALSE 0 # define TRUE 1 #endif char infile[80], outfile[80], temp[400]; /* Variables for shape files */ SHPHandle hSHP; SHPHandle hSHPappend; int nShapeType, nEntities, iPart; int nShapeTypeAppend, nEntitiesAppend; SHPObject *psCShape; double adfBoundsMin[4], adfBoundsMax[4]; /* Variables for DBF files */ DBFHandle hDBF; DBFHandle hDBFappend; DBFFieldType iType; DBFFieldType jType; char iszTitle[12]; char jszTitle[12]; int *pt; char iszFormat[32], iszField[1024]; char jszFormat[32], jszField[1024]; int i, ti, iWidth, iDecimals, iRecord; int j, tj, jWidth, jDecimals, jRecord; int found, newdbf; void openfiles(void); void setext(char *pt, char *ext); int strncasecmp2(char *s1, char *s2, int n); void mergefields(void); void findselect(void); void showitems(void); int selectrec(); int check_theme_bnd(); int clip_boundary(); void error(); /* -------------------------------------------------------------------- */ /* Variables for the DESCRIBE function */ /* -------------------------------------------------------------------- */ int ilist = FALSE, iall = FALSE; /* -------------------------------------------------------------------- */ /* Variables for the SELECT function */ /* -------------------------------------------------------------------- */ int found = FALSE, newdbf = FALSE; char selectitem[40], *cpt; long int selectvalues[150], selcount=0; int iselect = FALSE, iselectitem = -1; int iunselect = FALSE; /* -------------------------------------------------------------------- */ /* Variables for the CLIP and ERASE functions */ /* -------------------------------------------------------------------- */ double cxmin, cymin, cxmax, cymax; int iclip = FALSE, ierase = FALSE; int itouch = FALSE, iinside = FALSE, icut = FALSE; int ibound = FALSE, ipoly = FALSE; char clipfile[80]; /* -------------------------------------------------------------------- */ /* Variables for the FACTOR function */ /* -------------------------------------------------------------------- */ double infactor,outfactor,factor = 0; /* NO FACTOR */ int iunit = FALSE; int ifactor = FALSE; /* -------------------------------------------------------------------- */ /* Variables for the SHIFT function */ /* -------------------------------------------------------------------- */ double xshift = 0, yshift = 0; /* NO SHIFT */ int main( int argc, char ** argv ) { /* -------------------------------------------------------------------- */ /* Check command line usage. */ /* -------------------------------------------------------------------- */ if( argc < 2 ) error(); strcpy(infile, argv[1]); if (argc > 2) { strcpy(outfile,argv[2]); if (strncasecmp2(outfile, "LIST",0) == 0) { ilist = TRUE; } if (strncasecmp2(outfile, "ALL",0) == 0) { iall = TRUE; } } if (ilist || iall || argc == 2 ) { setext(infile, "shp"); printf("DESCRIBE: %s\n",infile); strcpy(outfile,""); } /* -------------------------------------------------------------------- */ /* Look for other functions on the command line. (SELECT, UNIT) */ /* -------------------------------------------------------------------- */ for (i = 3; i < argc; i++) { if ((strncasecmp2(argv[i], "SEL",3) == 0) || (strncasecmp2(argv[i], "UNSEL",5) == 0)) { if (strncasecmp2(argv[i], "UNSEL",5) == 0) iunselect=TRUE; i++; if (i >= argc) error(); strcpy(selectitem,argv[i]); i++; if (i >= argc) error(); selcount=0; strcpy(temp,argv[i]); cpt=temp; tj = atoi(cpt); ti = 0; while (tj>0) { selectvalues[selcount] = tj; while( *cpt >= '0' && *cpt <= '9') cpt++; while( *cpt > '\0' && (*cpt < '0' || *cpt > '9') ) cpt++; tj=atoi(cpt); selcount++; } iselect=TRUE; } /*** End SEL & UNSEL ***/ else if ((strncasecmp2(argv[i], "CLIP",4) == 0) || (strncasecmp2(argv[i], "ERASE",5) == 0)) { if (strncasecmp2(argv[i], "ERASE",5) == 0) ierase=TRUE; i++; if (i >= argc) error(); strcpy(clipfile,argv[i]); sscanf(argv[i],"%lf",&cxmin); i++; if (i >= argc) error(); if (strncasecmp2(argv[i], "BOUND",5) == 0) { setext(clipfile, "shp"); hSHP = SHPOpen( clipfile, "rb" ); if( hSHP == NULL ) { printf( "ERROR: Unable to open the clip shape file:%s\n", clipfile ); exit( 1 ); } SHPGetInfo( hSHPappend, NULL, NULL, adfBoundsMin, adfBoundsMax ); cxmin = adfBoundsMin[0]; cymin = adfBoundsMin[1]; cxmax = adfBoundsMax[0]; cymax = adfBoundsMax[1]; printf("Theme Clip Boundary: (%lf,%lf) - (%lf,%lf)\n", cxmin, cymin, cxmax, cymax); ibound=TRUE; } else { /*** xmin,ymin,xmax,ymax ***/ sscanf(argv[i],"%lf",&cymin); i++; if (i >= argc) error(); sscanf(argv[i],"%lf",&cxmax); i++; if (i >= argc) error(); sscanf(argv[i],"%lf",&cymax); printf("Clip Box: (%lf,%lf) - (%lf,%lf)\n",cxmin, cymin, cxmax, cymax); } i++; if (i >= argc) error(); if (strncasecmp2(argv[i], "CUT",3) == 0) icut=TRUE; else if (strncasecmp2(argv[i], "TOUCH",5) == 0) itouch=TRUE; else if (strncasecmp2(argv[i], "INSIDE",6) == 0) iinside=TRUE; else error(); iclip=TRUE; } /*** End CLIP & ERASE ***/ else if (strncasecmp2(argv[i], "FACTOR",0) == 0) { i++; if (i >= argc) error(); infactor=findunit(argv[i]); if (infactor == 0) error(); iunit=TRUE; i++; if (i >= argc) error(); outfactor=findunit(argv[i]); if (outfactor == 0) { sscanf(argv[i],"%lf",&factor); if (factor == 0) error(); } if (factor == 0) { if (infactor ==0) { puts("ERROR: Input unit must be defined before output unit"); exit(); } factor=infactor/outfactor; } printf("Output file coordinate values will be factored by %lg\n",factor); ifactor=(factor != 1); /* True if a valid factor */ } /*** End FACTOR ***/ else if (strncasecmp2(argv[i],"SHIFT",5) == 0) { i++; if (i >= argc) error(); sscanf(argv[i],"%lf",&xshift); i++; if (i >= argc) error(); sscanf(argv[i],"%lf",&yshift); iunit=TRUE; printf("X Shift: %lg Y Shift: %lg\n",xshift,yshift); } /*** End SHIFT ***/ else { printf("ERROR: Unknown function %s\n",argv[i]); error(); } } /* -------------------------------------------------------------------- */ /* If there is no data in this file let the user know. */ /* -------------------------------------------------------------------- */ openfiles(); /* Open the infile and the outfile for shape and dbf. */ if( DBFGetFieldCount(hDBF) == 0 ) { puts( "There are no fields in this table!" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Print out the file bounds. */ /* -------------------------------------------------------------------- */ iRecord = DBFGetRecordCount( hDBF ); SHPGetInfo( hSHP, NULL, NULL, adfBoundsMin, adfBoundsMax ); printf( "Input Bounds: (%lg,%lg) - (%lg,%lg) Entities: %d DBF: %d\n", adfBoundsMin[0], adfBoundsMin[1], adfBoundsMax[0], adfBoundsMax[1], nEntities, iRecord ); if (strcmp(outfile,"") == 0) /* Describe the shapefile; No other functions */ { ti = DBFGetFieldCount( hDBF ); showitems(); exit(0); } if (iclip) check_theme_bnd(); jRecord = DBFGetRecordCount( hDBFappend ); SHPGetInfo( hSHPappend, NULL, NULL, adfBoundsMin, adfBoundsMax ); if (nEntitiesAppend == 0) puts("New Output File\n"); else printf( "Append Bounds: (%lg,%lg)-(%lg,%lg) Entities: %d DBF: %d\n", adfBoundsMin[0], adfBoundsMin[1], adfBoundsMax[0], adfBoundsMax[1], nEntitiesAppend, jRecord ); /* -------------------------------------------------------------------- */ /* Find matching fields in the append file or add new items. */ /* -------------------------------------------------------------------- */ mergefields(); /* -------------------------------------------------------------------- */ /* Find selection field if needed. */ /* -------------------------------------------------------------------- */ if (iselect) findselect(); /* -------------------------------------------------------------------- */ /* Read all the records */ /* -------------------------------------------------------------------- */ jRecord = DBFGetRecordCount( hDBFappend ); for( iRecord = 0; iRecord < nEntities; iRecord++) /** DBFGetRecordCount(hDBF) **/ { /* -------------------------------------------------------------------- */ /* SELECT for values if needed. (Can the record be skipped.) */ /* -------------------------------------------------------------------- */ if (iselect) if (selectrec() == 0) goto SKIP_RECORD; /** SKIP RECORD **/ /* -------------------------------------------------------------------- */ /* Read a Shape record */ /* -------------------------------------------------------------------- */ psCShape = SHPReadObject( hSHP, iRecord ); /* -------------------------------------------------------------------- */ /* Clip coordinates of shapes if needed. */ /* -------------------------------------------------------------------- */ if (iclip) if (clip_boundary() == 0) goto SKIP_RECORD; /** SKIP RECORD **/ /* -------------------------------------------------------------------- */ /* Read a DBF record and copy each field. */ /* -------------------------------------------------------------------- */ for( i = 0; i < DBFGetFieldCount(hDBF); i++ ) { /* -------------------------------------------------------------------- */ /* Store the record according to the type and formatting */ /* information implicit in the DBF field description. */ /* -------------------------------------------------------------------- */ if (pt[i] > -1) /* if the current field exists in output file */ { switch( DBFGetFieldInfo( hDBF, i, NULL, &iWidth, &iDecimals ) ) { case FTString: DBFWriteStringAttribute(hDBFappend, jRecord, pt[i], (DBFReadStringAttribute( hDBF, iRecord, i )) ); break; case FTInteger: DBFWriteIntegerAttribute(hDBFappend, jRecord, pt[i], (DBFReadIntegerAttribute( hDBF, iRecord, i )) ); break; case FTDouble: DBFWriteDoubleAttribute(hDBFappend, jRecord, pt[i], (DBFReadDoubleAttribute( hDBF, iRecord, i )) ); break; } } } jRecord++; /* -------------------------------------------------------------------- */ /* Change FACTOR and SHIFT coordinates of shapes if needed. */ /* -------------------------------------------------------------------- */ if (iunit) { for( j = 0; j < psCShape->nVertices; j++ ) { psCShape->padfX[j] = psCShape->padfX[j] * factor + xshift; psCShape->padfY[j] = psCShape->padfY[j] * factor + yshift; } } /* -------------------------------------------------------------------- */ /* Write the Shape record after recomputing current extents. */ /* -------------------------------------------------------------------- */ SHPComputeExtents( psCShape ); SHPWriteObject( hSHPappend, -1, psCShape ); SKIP_RECORD: SHPDestroyObject( psCShape ); psCShape = NULL; j=0; } /* -------------------------------------------------------------------- */ /* Print out the # of Entities and the file bounds. */ /* -------------------------------------------------------------------- */ jRecord = DBFGetRecordCount( hDBFappend ); SHPGetInfo( hSHPappend, &nEntitiesAppend, &nShapeTypeAppend, adfBoundsMin, adfBoundsMax ); printf( "Output Bounds: (%lg,%lg) - (%lg,%lg) Entities: %d DBF: %d\n\n", adfBoundsMin[0], adfBoundsMin[1], adfBoundsMax[0], adfBoundsMax[1], nEntitiesAppend, jRecord ); /* -------------------------------------------------------------------- */ /* Close the both shapefiles. */ /* -------------------------------------------------------------------- */ SHPClose( hSHP ); SHPClose( hSHPappend ); DBFClose( hDBF ); DBFClose( hDBFappend ); if (nEntitiesAppend == 0) { puts("Remove the output files."); setext(outfile, "dbf"); remove(outfile); setext(outfile, "shp"); remove(outfile); setext(outfile, "shx"); remove(outfile); } return( 0 ); } /************************************************************************/ /* openfiles() */ /************************************************************************/ void openfiles() { /* -------------------------------------------------------------------- */ /* Open the DBF file. */ /* -------------------------------------------------------------------- */ setext(infile, "dbf"); hDBF = DBFOpen( infile, "rb" ); if( hDBF == NULL ) { printf( "ERROR: Unable to open the input DBF:%s\n", infile ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open the append DBF file. */ /* -------------------------------------------------------------------- */ if (strcmp(outfile,"")) { setext(outfile, "dbf"); hDBFappend = DBFOpen( outfile, "rb+" ); newdbf=0; if( hDBFappend == NULL ) { newdbf=1; hDBFappend = DBFCreate( outfile ); if( hDBFappend == NULL ) { printf( "ERROR: Unable to open the append DBF:%s\n", outfile ); exit( 1 ); } } } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ setext(infile, "shp"); hSHP = SHPOpen( infile, "rb" ); if( hSHP == NULL ) { printf( "ERROR: Unable to open the input shape file:%s\n", infile ); exit( 1 ); } SHPGetInfo( hSHP, &nEntities, &nShapeType, NULL, NULL ); /* -------------------------------------------------------------------- */ /* Open the passed append shapefile. */ /* -------------------------------------------------------------------- */ if (strcmp(outfile,"")) { setext(outfile, "shp"); hSHPappend = SHPOpen( outfile, "rb+" ); if( hSHPappend == NULL ) { hSHPappend = SHPCreate( outfile, nShapeType ); if( hSHPappend == NULL ) { printf( "ERROR: Unable to open the append shape file:%s\n", outfile ); exit( 1 ); } } SHPGetInfo( hSHPappend, &nEntitiesAppend, &nShapeTypeAppend, NULL, NULL ); if (nShapeType != nShapeTypeAppend) { puts( "ERROR: Input and Append shape files are of different types."); exit( 1 ); } } } /* -------------------------------------------------------------------- */ /* Change the extension. If there is any extension on the */ /* filename, strip it off and add the new extension */ /* -------------------------------------------------------------------- */ void setext(char *pt, char *ext) { int i; for( i = strlen(pt)-1; i > 0 && pt[i] != '.' && pt[i] != '/' && pt[i] != '\\'; i-- ) {} if( pt[i] == '.' ) pt[i] = '\0'; strcat(pt,"."); strcat(pt,ext); } /* -------------------------------------------------------------------- */ /* Find matching fields in the append file. */ /* Output file must have zero records to add any new fields. */ /* -------------------------------------------------------------------- */ void mergefields() { int i,j; ti = DBFGetFieldCount( hDBF ); tj = DBFGetFieldCount( hDBFappend ); /* Create a pointer array for the max # of fields in the output file */ pt = (int *) malloc( (ti+tj+1) * sizeof(int) ); for( i = 0; i < ti; i++ ) { pt[i]= -1; /* Initial pt values to -1 */ } /* DBF must be empty before adding items */ jRecord = DBFGetRecordCount( hDBFappend ); for( i = 0; i < ti; i++ ) { iType = DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals ); found=FALSE; { for( j = 0; j < tj; j++ ) /* Search all field names for a match */ { jType = DBFGetFieldInfo( hDBFappend, j, jszTitle, &jWidth, &jDecimals ); if (iType == jType && (strcmp(iszTitle, jszTitle) == 0) ) { if (found || newdbf) { if (i == j) pt[i]=j; printf("Warning: Duplicate field name found (%s)\n",iszTitle); /* Duplicate field name (Try to guess the correct field by position) */ } else { pt[i]=j; found=TRUE; } } } } if (pt[i] == -1 && (! found) ) /* Try to force into an existing field */ { /* Ignore the field name, width, and decimal places */ jType = DBFGetFieldInfo( hDBFappend, j, jszTitle, &jWidth, &jDecimals ); if (iType == jType) { pt[i]=i; found=1; } } if ( (! found) && jRecord == 0) /* Add missing field to the append table */ { /* The output DBF must be is empty */ pt[i]=tj; tj++; if( DBFAddField( hDBFappend, iszTitle, iType, iWidth, iDecimals ) == -1 ) { printf( "Warning: DBFAddField(%s, TYPE:%d, WIDTH:%d DEC:%d, ITEM#:%d of %d) failed.\n", iszTitle, iType, iWidth, iDecimals, (i+1), (ti+1) ); pt[i]=-1; } } } } void findselect() { /* Find the select field name */ iselectitem = -1; for( i = 0; i < ti && iselectitem < 0; i++ ) { iType = DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals ); if (strncasecmp2(iszTitle, selectitem, 0) == 0) iselectitem = i; } if (iselectitem == -1) { printf("Warning: Item not found for selection (%s)\n",selectitem); iselect = FALSE; iall = FALSE; showitems(); printf("Continued... (Selecting entire file)\n"); } /* Extract all of the select values (by field type) */ } void showitems() { char stmp[40],slow[40],shigh[40]; double dtmp,dlow,dhigh,dsum,mean; long int itmp,ilow,ihigh,isum; long int maxrec; char *pt; printf("Available Items: (%d)",ti); maxrec = DBFGetRecordCount(hDBF); if (maxrec > 5000 && ! iall) { maxrec=5000; printf(" ** ESTIMATED RANGES (MEAN) For more records use \"All\""); } else { printf(" RANGES (MEAN)"); } for( i = 0; i < ti; i++ ) { switch( DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals ) ) { case FTString: strcpy(slow, "~"); strcpy(shigh,"\0"); printf("\n String %3d %-16s",iWidth,iszTitle); for( iRecord = 0; iRecord < maxrec; iRecord++ ) { strncpy(stmp,DBFReadStringAttribute( hDBF, iRecord, i ),39); if (strcmp(stmp,"!!") > 0) { if (strncasecmp2(stmp,slow,0) < 0) strncpy(slow, stmp,39); if (strncasecmp2(stmp,shigh,0) > 0) strncpy(shigh,stmp,39); } } pt=slow+strlen(slow)-1; while(*pt == ' ') { *pt='\0'; pt--; } pt=shigh+strlen(shigh)-1; while(*pt == ' ') { *pt='\0'; pt--; } if (strncasecmp2(slow,shigh,0) < 0) printf("%s to %s",slow,shigh); else if (strncasecmp2(slow,shigh,0) == 0) printf("= %s",slow); else printf("No Values"); break; case FTInteger: printf("\n Integer %3d %-16s",iWidth,iszTitle); ilow = 1999999999; ihigh= -1999999999; isum = 0; for( iRecord = 0; iRecord < maxrec; iRecord++ ) { itmp = DBFReadIntegerAttribute( hDBF, iRecord, i ); if (ilow > itmp) ilow = itmp; if (ihigh < itmp) ihigh = itmp; isum = isum + itmp; } mean=isum/maxrec; if (ilow < ihigh) printf("%d to %d \t(%.1f)",ilow,ihigh,mean); else if (ilow == ihigh) printf("= %d",ilow); else printf("No Values"); break; case FTDouble: printf("\n Real %3d,%d %-16s",iWidth,iDecimals,iszTitle); dlow = 999999999999999.0; dhigh= -999999999999999.0; dsum = 0; for( iRecord = 0; iRecord < maxrec; iRecord++ ) { dtmp = DBFReadDoubleAttribute( hDBF, iRecord, i ); if (dlow > dtmp) dlow = dtmp; if (dhigh < dtmp) dhigh = dtmp; dsum = dsum + dtmp; } mean=dsum/maxrec; sprintf(stmp,"%%.%df to %%.%df \t(%%.%df)",iDecimals,iDecimals,iDecimals); if (dlow < dhigh) printf(stmp,dlow,dhigh,mean); else if (dlow == dhigh) { sprintf(stmp,"= %%.%df",iDecimals); printf(stmp,dlow); } else printf("No Values"); break; } } printf("\n"); } int selectrec() { long int value, ty; ty = DBFGetFieldInfo( hDBF, iselectitem, NULL, &iWidth, &iDecimals); switch(ty) { case FTString: puts("Invalid Item"); iselect=FALSE; break; case FTInteger: value = DBFReadIntegerAttribute( hDBF, iRecord, iselectitem ); for (j = 0; j= cxmin) && (adfBoundsMax[0] <= cxmax) && (adfBoundsMin[1] >= cymin) && (adfBoundsMax[1] <= cymax) ) { /** Theme is totally inside clip area **/ if (ierase) nEntities=0; /** SKIP THEME **/ else iclip=FALSE; /** WRITE THEME (Clip not needed) **/ } if ( ( (adfBoundsMin[0] < cxmin) && (adfBoundsMax[0] < cxmin) ) || ( (adfBoundsMin[1] < cymin) && (adfBoundsMax[1] < cymin) ) || ( (adfBoundsMin[0] > cxmax) && (adfBoundsMax[0] > cxmax) ) || ( (adfBoundsMin[1] > cymax) && (adfBoundsMax[1] > cymax) ) ) { /** Theme is totally outside clip area **/ if (ierase) iclip=FALSE; /** WRITE THEME (Clip not needed) **/ else nEntities=0; /** SKIP THEME **/ } if (nEntities == 0) puts("WARNING: Theme is outside the clip area."); /** SKIP THEME **/ } clip_boundary() { int inside; int prev_outside; int i2; int j2; /*** FIRST check the boundary of the feature ***/ if ( ( (psCShape->dfXMin < cxmin) && (psCShape->dfXMax < cxmin) ) || ( (psCShape->dfYMin < cymin) && (psCShape->dfYMax < cymin) ) || ( (psCShape->dfXMin > cxmax) && (psCShape->dfXMax > cxmax) ) || ( (psCShape->dfYMin > cymax) && (psCShape->dfYMax > cymax) ) ) { /** Feature is totally outside clip area **/ if (ierase) return(1); /** WRITE RECORD **/ else return(0); /** SKIP RECORD **/ } if ( (psCShape->dfXMin >= cxmin) && (psCShape->dfXMax <= cxmax) && (psCShape->dfYMin >= cymin) && (psCShape->dfYMax <= cymax) ) { /** Feature is totally inside clip area **/ if (ierase) return(0); /** SKIP RECORD **/ else return(1); /** WRITE RECORD **/ } if (iinside) { /** INSIDE * Feature might touch the boundary or could be outside **/ if (ierase) return(1); /** WRITE RECORD **/ else return(0); /** SKIP RECORD **/ } if (itouch) { /** TOUCH **/ if ( ( (psCShape->dfXMin <= cxmin) || (psCShape->dfXMax >= cxmax) ) && (psCShape->dfYMin >= cymin) && (psCShape->dfYMax <= cymax) ) { /** Feature intersects the clip boundary only on the X axis **/ if (ierase) return(0); /** SKIP RECORD **/ else return(1); /** WRITE RECORD **/ } if ( (psCShape->dfXMin >= cxmin) && (psCShape->dfXMax <= cxmax) && ( (psCShape->dfYMin <= cymin) || (psCShape->dfYMax >= cymax) ) ) { /** Feature intersects the clip boundary only on the Y axis **/ if (ierase) return(0); /** SKIP RECORD **/ else return(1); /** WRITE RECORD **/ } for( j2 = 0; j2 < psCShape->nVertices; j2++ ) { /** At least one vertex must be inside the clip boundary **/ if ( (psCShape->padfX[j2] >= cxmin && psCShape->padfX[j2] <= cxmax) || (psCShape->padfY[j2] >= cymin && psCShape->padfY[j2] <= cymax) ) if (ierase) return(0); /** SKIP RECORD **/ else return(1); /** WRITE RECORD **/ } /** All vertices are outside the clip boundary **/ if (ierase) return(1); /** WRITE RECORD **/ else return(0); /** SKIP RECORD **/ } /** End TOUCH **/ if (icut) { /** CUT **/ /*** Check each vertex in the feature with the Boundary and "CUT" ***/ /*** THIS CODE WAS NOT COMPLETED! READ NOTE AT THE BOTTOM ***/ i2=0; prev_outside=FALSE; for( j2 = 0; j2 < psCShape->nVertices; j2++ ) { inside = psCShape->padfX[j2] >= cxmin && psCShape->padfX[j2] <= cxmax && psCShape->padfY[j2] >= cymin && psCShape->padfY[j2] <= cymax ; if (ierase) inside=(! inside); if (inside) { if (i2 != j2) { if (prev_outside) { /*** AddIntersection(i2); /*** Add intersection ***/ prev_outside=FALSE; } psCShape->padfX[i2]=psCShape->padfX[j2]; /** move vertex **/ psCShape->padfY[i2]=psCShape->padfY[j2]; } i2++; } else { if ( (! prev_outside) && (j2 > 0) ) { /*** AddIntersection(i2); /*** Add intersection (Watch out for j2==i2-1) ***/ /*** Also a polygon may overlap twice and will split into a several parts ***/ prev_outside=TRUE; } } } printf("Vertices:%d OUT:%d Number of Parts:%d\n", psCShape->nVertices,i2, psCShape->nParts ); psCShape->nVertices = i2; if (i2 < 2) return(0); /** SKIP RECORD **/ /*** (WE ARE NOT CREATING INTERESECTIONS and some lines could be reduced to one point) **/ if (i2 == 0) return(0); /** SKIP RECORD **/ else return(1); /** WRITE RECORD **/ } /** End CUT **/ } /************************************************************************/ /* strncasecmp2() */ /* */ /* Compare two strings up to n characters */ /* If n=0 then s1 and s2 must be an exact match */ /************************************************************************/ int strncasecmp2(char *s1, char *s2, int n) { int j,i; if (n<1) n=strlen(s1)+1; for (i=0; i= 'a' && *s1 <= 'z') { j=*s1-32; if (j != *s2) return(*s1-*s2); } else { if (*s1 >= 'A' && *s1 <= 'Z') { j=*s1+32; } else { j=*s1; } if (j != *s2) return(*s1-*s2); } } s1++; s2++; } return(0); } #define NKEYS (sizeof(unitkeytab) / sizeof(struct unitkey)) findunit(unit) char *unit; { struct unitkey { char *name; double value; } unitkeytab[] = { "CM", 39.37, "CENTIMETER", 39.37, "CENTIMETERS", 39.37, /** # of inches * 100 in unit **/ "METER", 3937, "METERS", 3937, "KM", 3937000, "KILOMETER", 3937000, "KILOMETERS", 3937000, "INCH", 100, "INCHES", 100, "FEET", 1200, "FOOT", 1200, "YARD", 3600, "YARDS", 3600, "MILE", 6336000, "MILES", 6336000 }; double unitfactor=0; for (j = 0; j < NKEYS; j++) { if (strncasecmp2(unit, unitkeytab[j].name, 0) == 0) unitfactor=unitkeytab[j].value; } return(unitfactor); } /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ void error() { puts( "The program will append to an existing shape file or it will" ); puts( "create a new file if needed." ); puts( "Only the items in the first output file will be preserved." ); puts( "When an item does not match with the append theme then the item"); puts( "might be placed to an existing item at the same position and type." ); puts( " OTHER FUNCTIONS:" ); puts( " - Describe all items in the dbase file (Use ALL for more than 5000 recs.)"); puts( " - Select a group of shapes from a comma separated selection list."); puts( " - UnSelect a group of shapes from a comma separated selection list."); puts( " - Clip boundary extent or by theme boundary." ); puts( " Touch writes all the shapes that touch the boundary."); puts( " Inside writes all the shapes that are completely within the boundary."); puts( " Boundary clips are only the min and max of a theme boundary." ); puts( " - Erase boundary extent or by theme boundary." ); puts( " Erase is the direct opposite of the Clip function." ); puts( " - Change coordinate value units between meters and feet."); puts( " There is no way to determine the input unit of a shape file."); puts( " Skip this function if the shape file is already in the correct unit."); puts( " Clip and Erase will be done before the unit is changed."); puts( " A shift will be done after the unit is changed."); puts( " - Shift X and Y coordinates.\n" ); puts( "Finally, There can only be one select or unselect in the command line."); puts( " There can only be one clip or erase in the command line."); puts( " There can only be one unit and only one shift in the command line.\n"); puts( "Ex: shputils in.shp out.shp SELECT countycode 3,5,9,13,17,27"); puts( " shputils in.shp out.shp CLIP 10 10 90 90 Touch FACTOR Meter Feet"); puts( " shputils in.shp out.shp FACTOR Meter 3.0"); puts( " shputils in.shp out.shp CLIP clip.shp Boundary Touch SHIFT 40 40"); puts( " shputils in.shp out.shp SELECT co 112 CLIP clip.shp Boundary Touch\n"); puts( "USAGE: shputils {ALL}"); puts( "USAGE: shputils " ); puts( " { }" ); puts( " { }" ); puts( " { }" ); puts( " { }" ); puts( " { }" ); puts( " Note: CUT is not complete and does not create intersections."); puts( " For more information read programmer comment."); /**** Clip functions for Polygon and Cut is not supported There are several web pages that describe methods of doing this function. It seem easy to impliment until you start writting code. I don't have the time to add these functions but a did leave a simple cut routine in the program that can be called by using CUT instead of TOUCH in the CLIP or ERASE functions. It does not add the intersection of the line and the clip box, so polygons could look incomplete and lines will come up short. Information about clipping lines with a box: http://www.csclub.uwaterloo.ca/u/mpslager/articles/sutherland/wr.html Information about finding the intersection of two lines: http://www.whisqu.se/per/docs/math28.htm THE CODE LOOKS LIKE THIS: ******************************************************** void Intersect_Lines(float x0,float y0,float x1,float y1, float x2,float y2,float x3,float y3, float *xi,float *yi) { // this function computes the intersection of the sent lines // and returns the intersection point, note that the function assumes // the lines intersect. the function can handle vertical as well // as horizontal lines. note the function isn't very clever, it simply // applies the math, but we don't need speed since this is a // pre-processing step // The Intersect_lines program came from (http://www.whisqu.se/per/docs/math28.htm) float a1,b1,c1, // constants of linear equations a2,b2,c2, det_inv, // the inverse of the determinant of the coefficientmatrix m1,m2; // the slopes of each line // compute slopes, note the cludge for infinity, however, this will // be close enough if ((x1-x0)!=0) m1 = (y1-y0)/(x1-x0); else m1 = (float)1e+10; // close enough to infinity if ((x3-x2)!=0) m2 = (y3-y2)/(x3-x2); else m2 = (float)1e+10; // close enough to infinity // compute constants a1 = m1; a2 = m2; b1 = -1; b2 = -1; c1 = (y0-m1*x0); c2 = (y2-m2*x2); // compute the inverse of the determinate det_inv = 1/(a1*b2 - a2*b1); // use Kramers rule to compute xi and yi *xi=((b1*c2 - b2*c1)*det_inv); *yi=((a2*c1 - a1*c2)*det_inv); } // end Intersect_Lines **********************************************************/ exit( 1 ); } ./shapelib-1.2.10/stream1.out0100644000076500001440000016514407644273432015401 0ustar warmerdausers------------------------------------------------------------------------- Test 1: dump anno.shp ------------------------------------------------------------------------- Shapefile Type: Polygon # of Shapes: 201 File Bounds: ( 471276.281, 4751595.500,0,0) to ( 492683.536, 4765390.413,0,0) Shape:0 (Polygon) nVertices=5, nParts=1 Bounds:( 486019.130, 4764549.500, 0, 0) to ( 486356.183, 4765212.744, 0, 0) ( 486089.531, 4764549.500, 0, 0) Ring ( 486019.130, 4764579.128, 0, 0) ( 486285.782, 4765212.744, 0, 0) ( 486356.183, 4765183.116, 0, 0) ( 486089.531, 4764549.500, 0, 0) Shape:1 (Polygon) nVertices=5, nParts=1 Bounds:( 484948.275, 4763866.500, 0, 0) to ( 485333.012, 4764070.376, 0, 0) ( 484974.719, 4763866.500, 0, 0) Ring ( 484948.275, 4763938.159, 0, 0) ( 485306.569, 4764070.376, 0, 0) ( 485333.012, 4763998.717, 0, 0) ( 484974.719, 4763866.500, 0, 0) Shape:2 (Polygon) nVertices=5, nParts=1 Bounds:( 485577.021, 4764106.500, 0, 0) to ( 485818.355, 4764259.305, 0, 0) ( 485604.156, 4764106.500, 0, 0) Ring ( 485577.021, 4764177.900, 0, 0) ( 485791.220, 4764259.305, 0, 0) ( 485818.355, 4764187.906, 0, 0) ( 485604.156, 4764106.500, 0, 0) Shape:3 (Polygon) nVertices=5, nParts=1 Bounds:( 484861.500, 4762570.513, 0, 0) to ( 485092.062, 4763026.856, 0, 0) ( 485092.062, 4762597.000, 0, 0) Ring ( 485020.420, 4762570.513, 0, 0) ( 484861.500, 4763000.370, 0, 0) ( 484933.143, 4763026.856, 0, 0) ( 485092.062, 4762597.000, 0, 0) Shape:4 (Polygon) nVertices=5, nParts=1 Bounds:( 484452.624, 4763792.614, 0, 0) to ( 484628.031, 4764105.947, 0, 0) ( 484628.031, 4763818.500, 0, 0) Ring ( 484556.169, 4763792.614, 0, 0) ( 484452.624, 4764080.061, 0, 0) ( 484524.486, 4764105.947, 0, 0) ( 484628.031, 4763818.500, 0, 0) Shape:5 (Polygon) nVertices=5, nParts=1 Bounds:( 484355.352, 4764139.435, 0, 0) to ( 484505.344, 4764380.892, 0, 0) ( 484505.344, 4764165.500, 0, 0) Ring ( 484433.546, 4764139.435, 0, 0) ( 484355.352, 4764354.827, 0, 0) ( 484427.150, 4764380.892, 0, 0) ( 484505.344, 4764165.500, 0, 0) Shape:6 (Polygon) nVertices=9, nParts=1 Bounds:( 484548.866, 4763118.531, 0, 0) to ( 484772.062, 4763742.258, 0, 0) ( 484772.062, 4763152.000, 0, 0) Ring ( 484703.404, 4763118.531, 0, 0) ( 484605.763, 4763318.832, 0, 0) ( 484548.866, 4763471.149, 0, 0) ( 484603.088, 4763742.258, 0, 0) ( 484677.987, 4763727.278, 0, 0) ( 484628.031, 4763477.500, 0, 0) ( 484676.031, 4763349.000, 0, 0) ( 484772.062, 4763152.000, 0, 0) Shape:7 (Polygon) nVertices=5, nParts=1 Bounds:( 484671.739, 4763562.500, 0, 0) to ( 484911.415, 4763682.338, 0, 0) ( 484686.719, 4763562.500, 0, 0) Ring ( 484671.739, 4763637.399, 0, 0) ( 484896.435, 4763682.338, 0, 0) ( 484911.415, 4763607.439, 0, 0) ( 484686.719, 4763562.500, 0, 0) Shape:8 (Polygon) nVertices=5, nParts=1 Bounds:( 484930.172, 4763125.500, 0, 0) to ( 485596.342, 4763453.269, 0, 0) ( 484958.719, 4763125.500, 0, 0) Ring ( 484930.172, 4763196.347, 0, 0) ( 485567.795, 4763453.269, 0, 0) ( 485596.342, 4763382.423, 0, 0) ( 484958.719, 4763125.500, 0, 0) Shape:9 (Polygon) nVertices=5, nParts=1 Bounds:( 485102.757, 4763082.500, 0, 0) to ( 485344.154, 4763234.029, 0, 0) ( 485129.406, 4763082.500, 0, 0) Ring ( 485102.757, 4763154.083, 0, 0) ( 485317.505, 4763234.029, 0, 0) ( 485344.154, 4763162.446, 0, 0) ( 485129.406, 4763082.500, 0, 0) Shape:10 (Polygon) nVertices=5, nParts=1 Bounds:( 485368.786, 4762538.500, 0, 0) to ( 485824.016, 4762774.029, 0, 0) ( 485396.156, 4762538.500, 0, 0) Ring ( 485368.786, 4762609.810, 0, 0) ( 485796.646, 4762774.029, 0, 0) ( 485824.016, 4762702.719, 0, 0) ( 485396.156, 4762538.500, 0, 0) Shape:11 (Polygon) nVertices=5, nParts=1 Bounds:( 487002.484, 4763184.000, 0, 0) to ( 487243.960, 4763333.368, 0, 0) ( 487028.312, 4763184.000, 0, 0) Ring ( 487002.484, 4763255.883, 0, 0) ( 487218.132, 4763333.368, 0, 0) ( 487243.960, 4763261.486, 0, 0) ( 487028.312, 4763184.000, 0, 0) Shape:12 (Polygon) nVertices=5, nParts=1 Bounds:( 486733.537, 4762455.413, 0, 0) to ( 487076.312, 4763275.483, 0, 0) ( 487076.312, 4762480.000, 0, 0) Ring ( 487003.996, 4762455.413, 0, 0) ( 486733.537, 4763250.896, 0, 0) ( 486805.854, 4763275.483, 0, 0) ( 487076.312, 4762480.000, 0, 0) Shape:13 (Polygon) nVertices=5, nParts=1 Bounds:( 486440.735, 4762331.029, 0, 0) to ( 486772.281, 4763075.311, 0, 0) ( 486772.281, 4762357.000, 0, 0) Ring ( 486700.450, 4762331.029, 0, 0) ( 486440.735, 4763049.339, 0, 0) ( 486512.566, 4763075.311, 0, 0) ( 486772.281, 4762357.000, 0, 0) Shape:14 (Polygon) nVertices=5, nParts=1 Bounds:( 486383.882, 4762986.530, 0, 0) to ( 486521.594, 4763227.908, 0, 0) ( 486521.594, 4763008.000, 0, 0) Ring ( 486448.291, 4762986.530, 0, 0) ( 486383.882, 4763206.438, 0, 0) ( 486457.184, 4763227.908, 0, 0) ( 486521.594, 4763008.000, 0, 0) Shape:15 (Polygon) nVertices=9, nParts=1 Bounds:( 486360.416, 4762774.310, 0, 0) to ( 486800.882, 4763656.208, 0, 0) ( 486489.594, 4763600.000, 0, 0) Ring ( 486541.313, 4763656.208, 0, 0) ( 486762.057, 4763453.094, 0, 0) ( 486800.882, 4763266.659, 0, 0) ( 486420.883, 4762774.310, 0, 0) ( 486360.416, 4762820.979, 0, 0) ( 486718.938, 4763285.500, 0, 0) ( 486692.281, 4763413.500, 0, 0) ( 486489.594, 4763600.000, 0, 0) Shape:16 (Polygon) nVertices=5, nParts=1 Bounds:( 486682.872, 4762181.000, 0, 0) to ( 487292.496, 4762415.463, 0, 0) ( 486702.969, 4762181.000, 0, 0) Ring ( 486682.872, 4762254.691, 0, 0) ( 487272.400, 4762415.463, 0, 0) ( 487292.496, 4762341.772, 0, 0) ( 486702.969, 4762181.000, 0, 0) Shape:17 (Polygon) nVertices=5, nParts=1 Bounds:( 487480.713, 4762283.320, 0, 0) to ( 487732.406, 4762812.552, 0, 0) ( 487732.406, 4762309.000, 0, 0) Ring ( 487660.470, 4762283.320, 0, 0) ( 487480.713, 4762786.872, 0, 0) ( 487552.649, 4762812.552, 0, 0) ( 487732.406, 4762309.000, 0, 0) Shape:18 (Polygon) nVertices=5, nParts=1 Bounds:( 487069.757, 4763685.709, 0, 0) to ( 487220.344, 4763927.145, 0, 0) ( 487220.344, 4763712.000, 0, 0) Ring ( 487148.629, 4763685.709, 0, 0) ( 487069.757, 4763900.854, 0, 0) ( 487141.471, 4763927.145, 0, 0) ( 487220.344, 4763712.000, 0, 0) Shape:19 (Polygon) nVertices=9, nParts=1 Bounds:( 487854.719, 4758279.000, 0, 0) to ( 488518.085, 4758475.003, 0, 0) ( 487854.719, 4758404.000, 0, 0) Ring ( 487882.875, 4758475.003, 0, 0) ( 488183.362, 4758355.845, 0, 0) ( 488341.273, 4758360.840, 0, 0) ( 488515.420, 4758366.919, 0, 0) ( 488518.085, 4758290.583, 0, 0) ( 488343.812, 4758284.500, 0, 0) ( 488169.938, 4758279.000, 0, 0) ( 487854.719, 4758404.000, 0, 0) Shape:20 (Polygon) nVertices=5, nParts=1 Bounds:( 486300.557, 4758366.000, 0, 0) to ( 486613.245, 4758546.262, 0, 0) ( 486327.781, 4758366.000, 0, 0) Ring ( 486300.557, 4758437.366, 0, 0) ( 486586.021, 4758546.262, 0, 0) ( 486613.245, 4758474.896, 0, 0) ( 486327.781, 4758366.000, 0, 0) Shape:21 (Polygon) nVertices=5, nParts=1 Bounds:( 486709.618, 4758518.000, 0, 0) to ( 486949.999, 4758681.145, 0, 0) ( 486740.750, 4758518.000, 0, 0) Ring ( 486709.618, 4758587.750, 0, 0) ( 486918.867, 4758681.145, 0, 0) ( 486949.999, 4758611.396, 0, 0) ( 486740.750, 4758518.000, 0, 0) Shape:22 (Polygon) nVertices=5, nParts=1 Bounds:( 487325.398, 4757807.034, 0, 0) to ( 487555.844, 4758263.402, 0, 0) ( 487555.844, 4757833.500, 0, 0) Ring ( 487484.193, 4757807.034, 0, 0) ( 487325.398, 4758236.937, 0, 0) ( 487397.049, 4758263.402, 0, 0) ( 487555.844, 4757833.500, 0, 0) Shape:23 (Polygon) nVertices=5, nParts=1 Bounds:( 487255.256, 4758215.573, 0, 0) to ( 487387.406, 4758456.611, 0, 0) ( 487387.406, 4758235.000, 0, 0) Ring ( 487313.536, 4758215.573, 0, 0) ( 487255.256, 4758437.184, 0, 0) ( 487329.126, 4758456.611, 0, 0) ( 487387.406, 4758235.000, 0, 0) Shape:24 (Polygon) nVertices=5, nParts=1 Bounds:( 487248.714, 4758360.500, 0, 0) to ( 487559.687, 4758550.761, 0, 0) ( 487278.719, 4758360.500, 0, 0) Ring ( 487248.714, 4758430.742, 0, 0) ( 487529.682, 4758550.761, 0, 0) ( 487559.687, 4758480.519, 0, 0) ( 487278.719, 4758360.500, 0, 0) Shape:25 (Polygon) nVertices=5, nParts=1 Bounds:( 487573.994, 4758496.500, 0, 0) to ( 487815.502, 4758644.603, 0, 0) ( 487599.344, 4758496.500, 0, 0) Ring ( 487573.994, 4758568.553, 0, 0) ( 487790.152, 4758644.603, 0, 0) ( 487815.502, 4758572.550, 0, 0) ( 487599.344, 4758496.500, 0, 0) ------------------------------------------------------------------------- Test 2: dump brklinz.shp ------------------------------------------------------------------------- Shapefile Type: ArcZ # of Shapes: 122 File Bounds: ( 6294338.260, 1978444.010,0,0) to ( 6296321.860, 1979694.450,0,0) Shape:0 (ArcZ) nVertices=92, nParts=1 Bounds:( 6294700.210, 1978579.390, 818.64, 0) to ( 6295395.930, 1979050.330, 917.86, 0) ( 6295372.750, 1978755.830, 823.06, 0) Ring ( 6295366.170, 1978739.190, 826.58, 0) ( 6295360.400, 1978718.540, 829.2, 0) ( 6295352.620, 1978697.000, 832.22, 0) ( 6295345.960, 1978677.040, 834.64, 0) ( 6295339.690, 1978656.810, 838.51, 0) ( 6295335.040, 1978637.600, 840.94, 0) ( 6295331.080, 1978621.450, 844.48, 0) ( 6295324.350, 1978607.940, 847.04, 0) ( 6295313.370, 1978598.450, 850.38, 0) ( 6295296.780, 1978594.950, 853.27, 0) ( 6295273.800, 1978594.990, 858.06, 0) ( 6295251.750, 1978595.380, 861.53, 0) ( 6295232.340, 1978598.400, 864.22, 0) ( 6295206.740, 1978606.390, 866.38, 0) ( 6295180.610, 1978616.970, 868.15, 0) ( 6295156.350, 1978630.540, 870.65, 0) ( 6295132.270, 1978645.210, 872.02, 0) ( 6295111.070, 1978659.740, 875.17, 0) ( 6295090.030, 1978674.920, 878.84, 0) ( 6295071.060, 1978689.340, 882.06, 0) ( 6295051.900, 1978705.080, 886.98, 0) ( 6295036.460, 1978719.260, 889.66, 0) ( 6295023.620, 1978732.910, 893.53, 0) ( 6295010.450, 1978750.380, 895.24, 0) ( 6294999.910, 1978767.850, 897.47, 0) ( 6294989.810, 1978783.860, 900.29, 0) ( 6294975.040, 1978795.570, 902.45, 0) ( 6294956.300, 1978806.830, 906.32, 0) ( 6294937.260, 1978814.620, 909.21, 0) ( 6294919.240, 1978821.960, 912.88, 0) ( 6294897.040, 1978832.210, 915.04, 0) ( 6294878.070, 1978844.070, 916.49, 0) ( 6294865.010, 1978855.820, 917.34, 0) ( 6294859.560, 1978870.150, 916.81, 0) ( 6294861.520, 1978882.920, 916.62, 0) ( 6294874.640, 1978906.220, 917.86, 0) ( 6294886.980, 1978926.880, 917.6, 0) ( 6294889.630, 1978953.270, 917.54, 0) ( 6294888.520, 1978978.280, 916.88, 0) ( 6294880.350, 1978998.390, 915.96, 0) ( 6294866.540, 1979018.920, 915.57, 0) ( 6294843.270, 1979039.140, 915.57, 0) ( 6294812.250, 1979049.040, 915.96, 0) ( 6294777.640, 1979050.330, 916.75, 0) ( 6294752.060, 1979040.520, 916.68, 0) ( 6294730.990, 1979028.850, 916.62, 0) ( 6294716.690, 1979008.420, 916.62, 0) ( 6294706.050, 1978987.490, 916.95, 0) ( 6294700.210, 1978965.390, 916.95, 0) ( 6294700.520, 1978937.670, 917.01, 0) ( 6294712.060, 1978911.340, 916.95, 0) ( 6294724.820, 1978893.560, 916.62, 0) ( 6294741.630, 1978878.010, 916.36, 0) ( 6294759.360, 1978865.090, 916.36, 0) ( 6294777.650, 1978855.370, 916.22, 0) ( 6294807.570, 1978846.970, 916.36, 0) ( 6294837.640, 1978836.590, 916.55, 0) ( 6294858.650, 1978831.390, 916.29, 0) ( 6294878.860, 1978825.840, 915.37, 0) ( 6294897.630, 1978817.860, 913.67, 0) ( 6294914.550, 1978809.520, 910.78, 0) ( 6294932.380, 1978798.580, 907.17, 0) ( 6294947.360, 1978788.370, 904.42, 0) ( 6294960.500, 1978778.120, 901.86, 0) ( 6294974.780, 1978761.900, 898.78, 0) ( 6294988.510, 1978747.610, 895.7, 0) ( 6295005.230, 1978730.220, 892.81, 0) ( 6295023.560, 1978713.470, 889.34, 0) ( 6295043.310, 1978696.320, 885.07, 0) ( 6295061.830, 1978680.810, 881.47, 0) ( 6295080.970, 1978664.550, 877.79, 0) ( 6295104.570, 1978648.190, 874.58, 0) ( 6295126.310, 1978633.890, 872.09, 0) ( 6295149.840, 1978618.720, 869.6, 0) ( 6295173.840, 1978605.030, 867.37, 0) ( 6295198.110, 1978594.150, 866.12, 0) ( 6295222.830, 1978586.990, 865.2, 0) ( 6295243.030, 1978583.810, 863.5, 0) ( 6295268.110, 1978581.290, 860.35, 0) ( 6295291.530, 1978579.390, 856.48, 0) ( 6295313.200, 1978582.040, 852.42, 0) ( 6295329.170, 1978591.410, 848.81, 0) ( 6295339.780, 1978603.880, 845.07, 0) ( 6295345.640, 1978621.110, 842.12, 0) ( 6295351.070, 1978642.970, 838.32, 0) ( 6295357.250, 1978666.560, 834.77, 0) ( 6295367.290, 1978691.000, 831.89, 0) ( 6295376.030, 1978718.470, 828.09, 0) ( 6295383.930, 1978744.860, 824.35, 0) ( 6295389.990, 1978768.720, 821.33, 0) ( 6295395.930, 1978790.090, 818.64, 0) Shape:1 (ArcZ) nVertices=9, nParts=1 Bounds:( 6295218.470, 1978444.010, 864.55, 0) to ( 6295330.760, 1978581.880, 882.45, 0) ( 6295330.760, 1978444.010, 882.45, 0) Ring ( 6295306.050, 1978461.190, 880.94, 0) ( 6295280.210, 1978482.710, 878.52, 0) ( 6295258.180, 1978504.050, 875.89, 0) ( 6295239.910, 1978524.670, 871.89, 0) ( 6295225.650, 1978546.540, 869.53, 0) ( 6295218.470, 1978565.550, 866.97, 0) ( 6295223.960, 1978575.510, 865.27, 0) ( 6295230.580, 1978581.880, 864.55, 0) Shape:2 (ArcZ) nVertices=10, nParts=1 Bounds:( 6295199.220, 1978444.010, 866.32, 0) to ( 6295309.040, 1978588.800, 882.08, 0) ( 6295200.070, 1978588.800, 866.32, 0) Ring ( 6295199.220, 1978571.840, 867.24, 0) ( 6295200.770, 1978555.740, 868.88, 0) ( 6295207.890, 1978538.040, 869.86, 0) ( 6295223.020, 1978520.530, 870.84, 0) ( 6295239.450, 1978502.440, 874.06, 0) ( 6295258.050, 1978483.440, 876.48, 0) ( 6295268.990, 1978473.760, 879.17, 0) ( 6295285.710, 1978461.560, 880.55, 0) ( 6295309.040, 1978444.010, 882.08, 0) Shape:3 (ArcZ) nVertices=5, nParts=1 Bounds:( 6294340.890, 1979449.280, 1031.78, 0) to ( 6294394.080, 1979522.030, 1039.78, 0) ( 6294394.080, 1979449.280, 1039.78, 0) Ring ( 6294378.800, 1979469.230, 1038.73, 0) ( 6294364.980, 1979486.740, 1037.28, 0) ( 6294350.800, 1979504.980, 1035.12, 0) ( 6294340.890, 1979522.030, 1031.78, 0) Shape:4 (ArcZ) nVertices=6, nParts=1 Bounds:( 6294344.380, 1979583.450, 1008.04, 0) to ( 6294354.670, 1979678.070, 1023.45, 0) ( 6294344.380, 1979583.450, 1023.45, 0) Ring ( 6294348.050, 1979601.580, 1019.18, 0) ( 6294349.570, 1979621.200, 1016.5, 0) ( 6294351.990, 1979637.890, 1012.95, 0) ( 6294353.090, 1979657.140, 1011.51, 0) ( 6294354.670, 1979678.070, 1008.04, 0) Shape:5 (ArcZ) nVertices=3, nParts=1 Bounds:( 6294338.260, 1979628.600, 1008.63, 0) to ( 6294341.080, 1979674.100, 1015.71, 0) ( 6294341.080, 1979674.100, 1008.63, 0) Ring ( 6294339.460, 1979649.880, 1011.71, 0) ( 6294338.260, 1979628.600, 1015.71, 0) Shape:6 (ArcZ) nVertices=3, nParts=1 Bounds:( 6294350.160, 1979437.980, 1038.6, 0) to ( 6294379.980, 1979476.720, 1040.1, 0) ( 6294350.160, 1979476.720, 1038.6, 0) Ring ( 6294368.100, 1979454.860, 1040.1, 0) ( 6294379.980, 1979437.980, 1039.32, 0) Shape:7 (ArcZ) nVertices=39, nParts=1 Bounds:( 6295371.530, 1978758.160, 754.11, 0) to ( 6295534.560, 1979677.750, 823.3, 0) ( 6295534.560, 1979677.750, 779.95, 0) Ring ( 6295534.380, 1979648.150, 778.57, 0) ( 6295534.480, 1979605.990, 775.16, 0) ( 6295533.970, 1979577.580, 772.21, 0) ( 6295532.310, 1979547.260, 768.41, 0) ( 6295532.970, 1979521.290, 763.82, 0) ( 6295532.390, 1979496.890, 759.1, 0) ( 6295532.940, 1979474.010, 755.49, 0) ( 6295533.680, 1979452.180, 754.11, 0) ( 6295533.850, 1979434.640, 754.11, 0) ( 6295532.170, 1979409.180, 755.75, 0) ( 6295531.580, 1979384.450, 758.7, 0) ( 6295531.590, 1979356.090, 760.28, 0) ( 6295530.190, 1979325.690, 761.13, 0) ( 6295530.020, 1979291.090, 761.66, 0) ( 6295529.210, 1979259.420, 762.7, 0) ( 6295526.250, 1979221.610, 762.77, 0) ( 6295524.260, 1979187.500, 763.75, 0) ( 6295522.640, 1979155.350, 764.61, 0) ( 6295521.540, 1979123.230, 765.33, 0) ( 6295518.460, 1979096.000, 765.92, 0) ( 6295511.670, 1979081.110, 767.16, 0) ( 6295500.700, 1979064.060, 768.41, 0) ( 6295489.330, 1979049.600, 770.11, 0) ( 6295475.500, 1979033.100, 773.07, 0) ( 6295462.530, 1979018.190, 775.16, 0) ( 6295447.760, 1979001.400, 779.49, 0) ( 6295433.380, 1978984.530, 782.9, 0) ( 6295419.040, 1978965.820, 785.92, 0) ( 6295409.020, 1978946.820, 790.58, 0) ( 6295399.860, 1978923.910, 795.1, 0) ( 6295391.010, 1978894.410, 800.94, 0) ( 6295387.440, 1978875.550, 805.53, 0) ( 6295382.030, 1978849.030, 809.79, 0) ( 6295382.190, 1978828.930, 813.33, 0) ( 6295383.570, 1978809.290, 817.4, 0) ( 6295380.880, 1978789.860, 819.69, 0) ( 6295375.630, 1978771.810, 822.58, 0) ( 6295371.530, 1978758.160, 823.3, 0) Shape:8 (ArcZ) nVertices=35, nParts=1 Bounds:( 6295396.480, 1978794.780, 753.98, 0) to ( 6295549.010, 1979670.060, 818.58, 0) ( 6295396.620, 1978794.780, 818.58, 0) Ring ( 6295397.330, 1978816.670, 815.76, 0) ( 6295396.480, 1978836.150, 812.22, 0) ( 6295397.670, 1978857.110, 807.95, 0) ( 6295401.180, 1978874.720, 804.61, 0) ( 6295406.260, 1978897.320, 799.95, 0) ( 6295413.580, 1978919.930, 794.77, 0) ( 6295421.330, 1978938.190, 790.31, 0) ( 6295431.450, 1978956.590, 786.51, 0) ( 6295444.950, 1978974.360, 782.38, 0) ( 6295461.420, 1978993.620, 777.66, 0) ( 6295479.760, 1979013.510, 773.26, 0) ( 6295494.630, 1979032.330, 771.1, 0) ( 6295510.990, 1979052.120, 767.69, 0) ( 6295524.170, 1979071.090, 766.84, 0) ( 6295532.180, 1979091.890, 765.33, 0) ( 6295536.530, 1979120.830, 764.8, 0) ( 6295537.480, 1979150.200, 764.08, 0) ( 6295539.470, 1979189.490, 763.43, 0) ( 6295541.670, 1979230.490, 762.64, 0) ( 6295541.760, 1979271.330, 761.79, 0) ( 6295543.650, 1979306.300, 761.46, 0) ( 6295544.470, 1979335.540, 760.47, 0) ( 6295544.960, 1979363.490, 759.23, 0) ( 6295545.620, 1979392.020, 757.13, 0) ( 6295546.340, 1979419.430, 754.9, 0) ( 6295547.120, 1979439.940, 753.98, 0) ( 6295546.510, 1979459.150, 754.38, 0) ( 6295545.460, 1979482.710, 757.66, 0) ( 6295545.530, 1979507.330, 761.13, 0) ( 6295545.610, 1979532.470, 765.59, 0) ( 6295546.490, 1979565.520, 770.44, 0) ( 6295547.960, 1979597.100, 775.03, 0) ( 6295548.990, 1979628.040, 777.26, 0) ( 6295549.010, 1979670.060, 780.15, 0) Shape:9 (ArcZ) nVertices=45, nParts=1 Bounds:( 6295694.040, 1978444.010, 696.95, 0) to ( 6296208.790, 1979687.080, 787.43, 0) ( 6295698.400, 1979687.080, 787.43, 0) Ring ( 6295694.040, 1979670.950, 786.31, 0) ( 6295696.410, 1979650.280, 785.13, 0) ( 6295700.080, 1979634.530, 784.8, 0) ( 6295704.080, 1979620.010, 784.15, 0) ( 6295708.420, 1979601.930, 782.44, 0) ( 6295711.230, 1979584.790, 781.99, 0) ( 6295712.060, 1979564.780, 780.8, 0) ( 6295710.550, 1979537.480, 779.69, 0) ( 6295711.290, 1979508.020, 777.59, 0) ( 6295710.010, 1979477.420, 776.08, 0) ( 6295709.300, 1979442.530, 773.59, 0) ( 6295709.160, 1979413.640, 772.21, 0) ( 6295707.090, 1979372.570, 769.46, 0) ( 6295708.140, 1979336.210, 767.49, 0) ( 6295709.710, 1979297.130, 764.67, 0) ( 6295710.960, 1979272.310, 763.29, 0) ( 6295714.640, 1979241.200, 761.2, 0) ( 6295719.050, 1979211.560, 759.82, 0) ( 6295724.280, 1979179.840, 758.31, 0) ( 6295729.460, 1979152.460, 756.74, 0) ( 6295735.770, 1979126.530, 754.44, 0) ( 6295744.970, 1979095.400, 752.87, 0) ( 6295755.820, 1979063.140, 750.31, 0) ( 6295767.590, 1979028.330, 747.62, 0) ( 6295782.240, 1978993.450, 744.21, 0) ( 6295801.580, 1978952.420, 741.26, 0) ( 6295825.730, 1978905.370, 736.87, 0) ( 6295842.330, 1978877.810, 734.7, 0) ( 6295859.110, 1978851.150, 731.55, 0) ( 6295875.620, 1978827.010, 729.52, 0) ( 6295899.080, 1978794.830, 727.42, 0) ( 6295923.640, 1978763.720, 724.34, 0) ( 6295949.340, 1978734.180, 721.39, 0) ( 6295975.020, 1978704.320, 718.57, 0) ( 6296000.320, 1978677.440, 716.01, 0) ( 6296026.940, 1978648.120, 713.45, 0) ( 6296053.500, 1978617.500, 709.78, 0) ( 6296078.620, 1978589.630, 706.9, 0) ( 6296098.880, 1978566.880, 704.47, 0) ( 6296126.050, 1978537.930, 702.37, 0) ( 6296150.670, 1978507.990, 700.14, 0) ( 6296179.280, 1978476.280, 698.7, 0) ( 6296208.030, 1978444.880, 696.99, 0) ( 6296208.790, 1978444.010, 696.95, 0) Shape:10 (ArcZ) nVertices=10, nParts=1 Bounds:( 6296270.060, 1979014.970, 712.54, 0) to ( 6296315.990, 1979152.310, 725.13, 0) ( 6296306.110, 1979152.310, 725.13, 0) Ring ( 6296288.270, 1979139.690, 723.42, 0) ( 6296276.630, 1979122.410, 721.98, 0) ( 6296270.060, 1979101.470, 719.95, 0) ( 6296270.390, 1979084.580, 719.36, 0) ( 6296275.110, 1979068.970, 717.26, 0) ( 6296284.280, 1979052.820, 716.41, 0) ( 6296294.680, 1979040.410, 715.49, 0) ( 6296305.720, 1979027.370, 713.59, 0) ( 6296315.990, 1979014.970, 712.54, 0) Shape:11 (ArcZ) nVertices=18, nParts=1 Bounds:( 6296044.930, 1978451.120, 690.11, 0) to ( 6296312.920, 1978679.190, 713.72, 0) ( 6296312.920, 1978493.560, 690.11, 0) Ring ( 6296301.160, 1978479.050, 690.9, 0) ( 6296287.840, 1978464.950, 692.4, 0) ( 6296276.430, 1978454.890, 693.58, 0) ( 6296262.580, 1978451.120, 694.44, 0) ( 6296249.650, 1978452.500, 694.9, 0) ( 6296237.110, 1978461.670, 696.08, 0) ( 6296223.600, 1978477.650, 697.78, 0) ( 6296209.320, 1978493.930, 698.7, 0) ( 6296193.640, 1978511.140, 699.16, 0) ( 6296176.980, 1978529.710, 700.6, 0) ( 6296157.700, 1978550.970, 701.98, 0) ( 6296136.720, 1978574.950, 703.49, 0) ( 6296121.400, 1978591.550, 705.39, 0) ( 6296102.290, 1978613.590, 707.36, 0) ( 6296084.440, 1978634.580, 709.13, 0) ( 6296065.890, 1978654.760, 711.29, 0) ( 6296044.930, 1978679.190, 713.72, 0) Shape:12 (ArcZ) nVertices=71, nParts=1 Bounds:( 6295741.070, 1978679.190, 713.72, 0) to ( 6296321.860, 1979680.370, 813.79, 0) ( 6296044.930, 1978679.190, 713.72, 0) Ring ( 6296025.660, 1978700.780, 716.6, 0) ( 6296006.480, 1978721.510, 718.37, 0) ( 6295987.070, 1978742.720, 721, 0) ( 6295970.410, 1978761.420, 722.44, 0) ( 6295953.490, 1978780.070, 724.28, 0) ( 6295932.470, 1978805.820, 726.44, 0) ( 6295913.490, 1978830.550, 728.67, 0) ( 6295896.490, 1978855.310, 731.16, 0) ( 6295881.220, 1978878.070, 733.39, 0) ( 6295867.710, 1978899.180, 734.7, 0) ( 6295853.950, 1978923.310, 737, 0) ( 6295839.810, 1978950.030, 739.56, 0) ( 6295825.270, 1978979.390, 742.11, 0) ( 6295809.100, 1979015.600, 745.46, 0) ( 6295796.940, 1979045.170, 748.02, 0) ( 6295785.770, 1979078.900, 750.97, 0) ( 6295777.080, 1979104.550, 752.54, 0) ( 6295768.950, 1979133.460, 754.84, 0) ( 6295762.170, 1979163.090, 756.87, 0) ( 6295755.640, 1979194.930, 758.9, 0) ( 6295750.610, 1979225.390, 760.48, 0) ( 6295746.300, 1979259.750, 762.64, 0) ( 6295743.320, 1979291.750, 764.54, 0) ( 6295741.650, 1979321.060, 766.64, 0) ( 6295741.070, 1979353.790, 768.54, 0) ( 6295741.170, 1979384.450, 770.71, 0) ( 6295742.010, 1979419.210, 772.48, 0) ( 6295743.010, 1979454.740, 774.44, 0) ( 6295743.910, 1979493.310, 776.94, 0) ( 6295744.990, 1979530.290, 778.97, 0) ( 6295745.900, 1979569.120, 781.46, 0) ( 6295745.940, 1979603.910, 783.3, 0) ( 6295747.600, 1979636.660, 785.85, 0) ( 6295751.850, 1979653.260, 787.49, 0) ( 6295760.490, 1979665.820, 788.87, 0) ( 6295773.510, 1979673.830, 790.18, 0) ( 6295788.460, 1979676.100, 791.95, 0) ( 6295823.990, 1979674.960, 793.46, 0) ( 6295871.620, 1979674.070, 796.94, 0) ( 6295918.980, 1979673.120, 798.97, 0) ( 6295971.200, 1979672.130, 802.25, 0) ( 6296019.370, 1979671.600, 803.95, 0) ( 6296054.350, 1979670.030, 805.92, 0) ( 6296074.580, 1979662.250, 806.58, 0) ( 6296085.660, 1979647.700, 806.97, 0) ( 6296089.370, 1979635.300, 807.69, 0) ( 6296086.380, 1979620.160, 808.61, 0) ( 6296080.060, 1979601.690, 810.32, 0) ( 6296074.440, 1979583.990, 811.17, 0) ( 6296070.250, 1979568.770, 812.22, 0) ( 6296072.470, 1979552.830, 812.94, 0) ( 6296083.220, 1979536.790, 813.46, 0) ( 6296102.650, 1979531.410, 813.79, 0) ( 6296121.290, 1979536.450, 813.73, 0) ( 6296133.190, 1979548.520, 813.2, 0) ( 6296138.010, 1979563.380, 812.61, 0) ( 6296135.460, 1979580.580, 811.37, 0) ( 6296129.950, 1979598.850, 810.18, 0) ( 6296124.490, 1979618.170, 809.46, 0) ( 6296122.100, 1979635.880, 808.35, 0) ( 6296126.820, 1979651.410, 807.36, 0) ( 6296136.390, 1979661.360, 806.51, 0) ( 6296149.630, 1979666.080, 806.05, 0) ( 6296163.380, 1979667.880, 805.73, 0) ( 6296186.080, 1979667.460, 805.14, 0) ( 6296215.190, 1979666.580, 805, 0) ( 6296247.690, 1979667.830, 803.5, 0) ( 6296273.580, 1979670.850, 802.32, 0) ( 6296295.410, 1979674.090, 800.68, 0) ( 6296321.860, 1979680.370, 799.23, 0) Shape:13 (ArcZ) nVertices=6, nParts=1 Bounds:( 6295372.650, 1979608.700, 773.19, 0) to ( 6295470.330, 1979679.550, 780.15, 0) ( 6295372.650, 1979679.550, 780.15, 0) Ring ( 6295387.140, 1979664.770, 777.85, 0) ( 6295406.650, 1979645.400, 776.21, 0) ( 6295422.760, 1979631.580, 775.29, 0) ( 6295442.800, 1979612.190, 773.65, 0) ( 6295470.330, 1979608.700, 773.19, 0) Shape:14 (ArcZ) nVertices=7, nParts=1 Bounds:( 6295415.710, 1979491.540, 772.08, 0) to ( 6295453.550, 1979590.190, 773.85, 0) ( 6295453.550, 1979590.110, 772.09, 0) Ring ( 6295453.110, 1979590.190, 772.08, 0) ( 6295439.430, 1979579.260, 772.74, 0) ( 6295430.870, 1979552.770, 772.93, 0) ( 6295420.940, 1979527.860, 773.19, 0) ( 6295415.710, 1979510.070, 773.79, 0) ( 6295421.080, 1979491.540, 773.85, 0) Shape:15 (ArcZ) nVertices=9, nParts=1 Bounds:( 6295351.240, 1979521.410, 773, 0) to ( 6295430.330, 1979692.520, 782.11, 0) ( 6295395.270, 1979521.410, 774.51, 0) Ring ( 6295415.880, 1979549.790, 773.85, 0) ( 6295426.030, 1979579.220, 773, 0) ( 6295430.330, 1979604.610, 773.06, 0) ( 6295418.610, 1979622.140, 774.31, 0) ( 6295398.970, 1979639.020, 776.34, 0) ( 6295382.220, 1979655.690, 778.31, 0) ( 6295365.040, 1979674.420, 780.15, 0) ( 6295351.240, 1979692.520, 782.11, 0) Shape:16 (ArcZ) nVertices=28, nParts=1 Bounds:( 6294520.270, 1979256.990, 932.36, 0) to ( 6294743.290, 1979675.030, 1016.69, 0) ( 6294531.940, 1979675.030, 932.36, 0) Ring ( 6294523.870, 1979650.550, 933.54, 0) ( 6294520.270, 1979620.920, 936.75, 0) ( 6294525.030, 1979592.840, 940.29, 0) ( 6294533.880, 1979567.770, 942.98, 0) ( 6294546.040, 1979543.320, 949.28, 0) ( 6294564.140, 1979524.750, 951.64, 0) ( 6294585.590, 1979515.130, 956.36, 0) ( 6294611.810, 1979503.890, 959.38, 0) ( 6294635.130, 1979494.900, 966.2, 0) ( 6294662.590, 1979487.470, 969.41, 0) ( 6294687.540, 1979482.070, 971.77, 0) ( 6294710.180, 1979470.160, 976.75, 0) ( 6294732.150, 1979450.140, 978.53, 0) ( 6294743.290, 1979431.460, 981.94, 0) ( 6294738.700, 1979402.930, 984.69, 0) ( 6294731.290, 1979380.980, 986.79, 0) ( 6294717.670, 1979358.290, 988.3, 0) ( 6294706.340, 1979342.050, 991.38, 0) ( 6294697.140, 1979315.920, 996.76, 0) ( 6294696.360, 1979292.580, 1000.17, 0) ( 6294691.930, 1979275.010, 1002.4, 0) ( 6294681.970, 1979259.950, 1004.76, 0) ( 6294665.150, 1979256.990, 1006.53, 0) ( 6294638.580, 1979258.930, 1010.33, 0) ( 6294617.350, 1979259.730, 1012.76, 0) ( 6294592.000, 1979262.260, 1015.32, 0) ( 6294572.550, 1979262.000, 1016.69, 0) Shape:17 (ArcZ) nVertices=43, nParts=1 Bounds:( 6294466.100, 1979253.610, 930.98, 0) to ( 6294720.520, 1979678.410, 1018.46, 0) ( 6294572.550, 1979262.000, 1016.69, 0) Ring ( 6294549.640, 1979260.720, 1017.48, 0) ( 6294522.440, 1979260.520, 1017.48, 0) ( 6294472.060, 1979253.610, 1016.63, 0) ( 6294469.530, 1979302.330, 1017.15, 0) ( 6294466.100, 1979341.240, 1016.63, 0) ( 6294469.480, 1979374.290, 1016.5, 0) ( 6294506.640, 1979382.010, 1016.96, 0) ( 6294538.320, 1979377.390, 1016.89, 0) ( 6294581.400, 1979377.510, 1017.74, 0) ( 6294603.050, 1979366.770, 1017.74, 0) ( 6294597.820, 1979338.470, 1018, 0) ( 6294587.060, 1979307.490, 1018.46, 0) ( 6294579.280, 1979283.460, 1017.87, 0) ( 6294593.320, 1979278.020, 1016.36, 0) ( 6294613.160, 1979275.640, 1013.15, 0) ( 6294634.390, 1979274.630, 1009.54, 0) ( 6294650.590, 1979272.960, 1006.4, 0) ( 6294666.970, 1979274.830, 1003.77, 0) ( 6294675.710, 1979289.290, 1001.81, 0) ( 6294681.310, 1979309.230, 998.13, 0) ( 6294686.190, 1979327.900, 995.64, 0) ( 6294692.280, 1979346.960, 991.64, 0) ( 6294699.730, 1979367.200, 989.08, 0) ( 6294709.530, 1979384.310, 985.74, 0) ( 6294716.160, 1979401.370, 983.25, 0) ( 6294720.520, 1979414.810, 980.1, 0) ( 6294718.980, 1979441.480, 978, 0) ------------------------------------------------------------------------- Test 3: dump polygon.shp ------------------------------------------------------------------------- Shapefile Type: Polygon # of Shapes: 474 File Bounds: ( 471127.188, 4751545.000,0,0) to ( 489292.312, 4765610.500,0,0) Shape:0 (Polygon) nVertices=20, nParts=1 Bounds:( 479647.000, 4764856.500, 0, 0) to ( 480389.688, 4765610.500, 0, 0) ( 479819.844, 4765180.500, 0, 0) Ring ( 479690.188, 4765259.500, 0, 0) ( 479647.000, 4765369.500, 0, 0) ( 479730.375, 4765400.500, 0, 0) ( 480039.031, 4765539.500, 0, 0) ( 480035.344, 4765558.500, 0, 0) ( 480159.781, 4765610.500, 0, 0) ( 480202.281, 4765482.000, 0, 0) ( 480365.000, 4765015.500, 0, 0) ( 480389.688, 4764950.000, 0, 0) ( 480133.969, 4764856.500, 0, 0) ( 480080.281, 4764979.500, 0, 0) ( 480082.969, 4765049.500, 0, 0) ( 480088.812, 4765139.500, 0, 0) ( 480059.906, 4765239.500, 0, 0) ( 480019.719, 4765319.500, 0, 0) ( 479980.219, 4765409.500, 0, 0) ( 479909.875, 4765370.000, 0, 0) ( 479859.875, 4765270.000, 0, 0) ( 479819.844, 4765180.500, 0, 0) Shape:1 (Polygon) nVertices=20, nParts=1 Bounds:( 479014.938, 4764879.000, 0, 0) to ( 480039.031, 4765558.500, 0, 0) ( 480035.344, 4765558.500, 0, 0) Ring ( 480039.031, 4765539.500, 0, 0) ( 479730.375, 4765400.500, 0, 0) ( 479647.000, 4765369.500, 0, 0) ( 479690.188, 4765259.500, 0, 0) ( 479819.844, 4765180.500, 0, 0) ( 479779.844, 4765109.500, 0, 0) ( 479681.781, 4764940.000, 0, 0) ( 479468.000, 4764942.500, 0, 0) ( 479411.438, 4764940.500, 0, 0) ( 479353.000, 4764939.500, 0, 0) ( 479208.656, 4764882.500, 0, 0) ( 479196.812, 4764879.000, 0, 0) ( 479123.281, 4765015.000, 0, 0) ( 479046.531, 4765117.000, 0, 0) ( 479029.719, 4765110.500, 0, 0) ( 479014.938, 4765147.500, 0, 0) ( 479149.938, 4765200.500, 0, 0) ( 479639.625, 4765399.500, 0, 0) ( 480035.344, 4765558.500, 0, 0) Shape:2 (Polygon) nVertices=54, nParts=1 Bounds:( 480882.688, 4763472.500, 0, 0) to ( 484519.969, 4765410.000, 0, 0) ( 481575.000, 4764999.500, 0, 0) Ring ( 481542.312, 4765097.500, 0, 0) ( 481443.688, 4765387.500, 0, 0) ( 481499.656, 4765410.000, 0, 0) ( 481631.000, 4765031.000, 0, 0) ( 481693.312, 4764853.000, 0, 0) ( 481759.281, 4764889.500, 0, 0) ( 481860.031, 4764920.000, 0, 0) ( 482002.969, 4764910.000, 0, 0) ( 482180.094, 4764909.500, 0, 0) ( 482359.812, 4764960.000, 0, 0) ( 482510.500, 4765065.000, 0, 0) ( 482619.906, 4765080.500, 0, 0) ( 482809.500, 4765090.000, 0, 0) ( 483189.812, 4765084.500, 0, 0) ( 483330.312, 4765105.500, 0, 0) ( 483591.094, 4765260.000, 0, 0) ( 483700.500, 4765280.000, 0, 0) ( 483799.938, 4765270.000, 0, 0) ( 484039.844, 4765280.500, 0, 0) ( 484115.688, 4765300.000, 0, 0) ( 484120.625, 4765280.000, 0, 0) ( 484131.125, 4765260.000, 0, 0) ( 484167.844, 4765271.000, 0, 0) ( 484277.875, 4765015.500, 0, 0) ( 484455.062, 4764500.000, 0, 0) ( 484519.969, 4764345.000, 0, 0) ( 484482.031, 4764332.000, 0, 0) ( 483904.719, 4764113.500, 0, 0) ( 483334.844, 4763905.000, 0, 0) ( 482941.031, 4763760.500, 0, 0) ( 482590.719, 4763624.500, 0, 0) ( 482185.656, 4763472.500, 0, 0) ( 482009.844, 4763980.500, 0, 0) ( 481960.438, 4764099.500, 0, 0) ( 481767.500, 4764014.500, 0, 0) ( 480955.500, 4763700.000, 0, 0) ( 480882.688, 4763670.000, 0, 0) ( 481039.938, 4763889.500, 0, 0) ( 481130.312, 4763979.500, 0, 0) ( 481143.438, 4764010.500, 0, 0) ( 481199.844, 4764180.000, 0, 0) ( 481141.625, 4764480.500, 0, 0) ( 481140.469, 4764510.500, 0, 0) ( 481159.938, 4764580.000, 0, 0) ( 481185.500, 4764607.000, 0, 0) ( 481199.219, 4764623.500, 0, 0) ( 481209.812, 4764633.500, 0, 0) ( 481235.312, 4764650.000, 0, 0) ( 481635.969, 4764795.500, 0, 0) ( 481645.312, 4764797.500, 0, 0) ( 481629.844, 4764829.500, 0, 0) ( 481602.125, 4764915.500, 0, 0) ( 481575.000, 4764999.500, 0, 0) Shape:3 (Polygon) nVertices=29, nParts=1 Bounds:( 479117.812, 4764505.000, 0, 0) to ( 480088.812, 4765409.500, 0, 0) ( 479819.844, 4765180.500, 0, 0) Ring ( 479859.875, 4765270.000, 0, 0) ( 479909.875, 4765370.000, 0, 0) ( 479980.219, 4765409.500, 0, 0) ( 480019.719, 4765319.500, 0, 0) ( 480059.906, 4765239.500, 0, 0) ( 480088.812, 4765139.500, 0, 0) ( 480082.969, 4765049.500, 0, 0) ( 480000.281, 4765043.000, 0, 0) ( 479934.969, 4765020.000, 0, 0) ( 479895.125, 4765000.000, 0, 0) ( 479734.375, 4764865.000, 0, 0) ( 479680.281, 4764852.000, 0, 0) ( 479644.781, 4764827.500, 0, 0) ( 479637.875, 4764803.000, 0, 0) ( 479617.219, 4764760.000, 0, 0) ( 479587.281, 4764718.000, 0, 0) ( 479548.031, 4764693.500, 0, 0) ( 479504.906, 4764609.500, 0, 0) ( 479239.812, 4764505.000, 0, 0) ( 479117.812, 4764847.000, 0, 0) ( 479196.812, 4764879.000, 0, 0) ( 479208.656, 4764882.500, 0, 0) ( 479353.000, 4764939.500, 0, 0) ( 479411.438, 4764940.500, 0, 0) ( 479468.000, 4764942.500, 0, 0) ( 479681.781, 4764940.000, 0, 0) ( 479779.844, 4765109.500, 0, 0) ( 479819.844, 4765180.500, 0, 0) Shape:4 (Polygon) nVertices=22, nParts=1 Bounds:( 480537.156, 4764738.000, 0, 0) to ( 481575.000, 4765387.500, 0, 0) ( 480537.156, 4765014.000, 0, 0) Ring ( 481090.281, 4765242.000, 0, 0) ( 481443.688, 4765387.500, 0, 0) ( 481542.312, 4765097.500, 0, 0) ( 481575.000, 4764999.500, 0, 0) ( 481538.906, 4764982.500, 0, 0) ( 481509.656, 4764967.000, 0, 0) ( 481457.375, 4764937.000, 0, 0) ( 481465.906, 4764872.500, 0, 0) ( 481291.094, 4764810.000, 0, 0) ( 481281.312, 4764876.500, 0, 0) ( 481136.844, 4764994.500, 0, 0) ( 481088.188, 4764936.000, 0, 0) ( 480984.250, 4764875.000, 0, 0) ( 480930.719, 4764852.000, 0, 0) ( 480922.031, 4764850.500, 0, 0) ( 480824.969, 4764820.000, 0, 0) ( 480761.469, 4764778.000, 0, 0) ( 480701.062, 4764738.000, 0, 0) ( 480605.000, 4764835.000, 0, 0) ( 480567.969, 4764918.000, 0, 0) ( 480537.156, 4765014.000, 0, 0) Shape:5 (Polygon) nVertices=60, nParts=1 Bounds:( 484482.031, 4760649.500, 0, 0) to ( 488408.281, 4765179.000, 0, 0) ( 484482.031, 4764332.000, 0, 0) Ring ( 484519.969, 4764345.000, 0, 0) ( 484817.938, 4764465.500, 0, 0) ( 485615.406, 4764770.000, 0, 0) ( 486269.688, 4765010.000, 0, 0) ( 486320.062, 4765024.000, 0, 0) ( 486340.594, 4765040.000, 0, 0) ( 486369.844, 4765050.000, 0, 0) ( 486719.969, 4765170.000, 0, 0) ( 486738.625, 4765179.000, 0, 0) ( 486987.781, 4764497.500, 0, 0) ( 487019.875, 4764384.500, 0, 0) ( 487077.375, 4764226.500, 0, 0) ( 487120.031, 4764100.000, 0, 0) ( 487160.250, 4763998.000, 0, 0) ( 487186.812, 4763922.500, 0, 0) ( 487408.250, 4763315.500, 0, 0) ( 487608.062, 4762780.000, 0, 0) ( 487659.406, 4762650.000, 0, 0) ( 487719.406, 4762480.000, 0, 0) ( 487741.062, 4762419.500, 0, 0) ( 487747.875, 4762395.500, 0, 0) ( 487880.875, 4762032.000, 0, 0) ( 487899.438, 4761975.500, 0, 0) ( 488082.000, 4761480.000, 0, 0) ( 488408.281, 4760649.500, 0, 0) ( 488050.375, 4760824.500, 0, 0) ( 487690.906, 4760802.000, 0, 0) ( 487640.062, 4760879.500, 0, 0) ( 487594.938, 4761023.000, 0, 0) ( 487341.375, 4761776.500, 0, 0) ( 487037.125, 4761672.500, 0, 0) ( 487005.375, 4761662.500, 0, 0) ( 486788.219, 4761579.500, 0, 0) ( 486822.250, 4761492.000, 0, 0) ( 486838.312, 4761437.500, 0, 0) ( 486841.312, 4761381.000, 0, 0) ( 486850.562, 4761340.000, 0, 0) ( 486810.750, 4761335.500, 0, 0) ( 486775.438, 4761400.000, 0, 0) ( 486710.094, 4761368.000, 0, 0) ( 486606.188, 4761330.000, 0, 0) ( 486548.656, 4761488.000, 0, 0) ( 486380.656, 4761428.500, 0, 0) ( 486152.906, 4761348.000, 0, 0) ( 485900.250, 4761250.500, 0, 0) ( 485666.875, 4761156.500, 0, 0) ( 485585.875, 4761374.500, 0, 0) ( 485564.875, 4761444.500, 0, 0) ( 485496.219, 4761614.500, 0, 0) ( 485438.688, 4761760.500, 0, 0) ( 485264.969, 4762222.500, 0, 0) ( 485192.688, 4762439.000, 0, 0) ( 485175.406, 4762493.500, 0, 0) ( 484947.344, 4763100.500, 0, 0) ( 484888.000, 4763260.500, 0, 0) ( 484785.469, 4763560.500, 0, 0) ( 484760.219, 4763659.500, 0, 0) ( 484696.969, 4763734.000, 0, 0) ( 484482.031, 4764332.000, 0, 0) Shape:6 (Polygon) nVertices=26, nParts=1 Bounds:( 478315.531, 4764174.000, 0, 0) to ( 479305.875, 4765147.500, 0, 0) ( 479014.938, 4765147.500, 0, 0) Ring ( 479029.719, 4765110.500, 0, 0) ( 479117.812, 4764847.000, 0, 0) ( 479239.812, 4764505.000, 0, 0) ( 479305.875, 4764361.000, 0, 0) ( 479256.031, 4764314.500, 0, 0) ( 479220.906, 4764212.500, 0, 0) ( 479114.500, 4764174.000, 0, 0) ( 479018.281, 4764418.500, 0, 0) ( 478896.938, 4764371.000, 0, 0) ( 478748.812, 4764308.500, 0, 0) ( 478503.031, 4764218.000, 0, 0) ( 478461.750, 4764337.500, 0, 0) ( 478443.938, 4764400.500, 0, 0) ( 478447.812, 4764454.000, 0, 0) ( 478448.688, 4764531.500, 0, 0) ( 478502.188, 4764541.500, 0, 0) ( 478683.000, 4764730.500, 0, 0) ( 478621.031, 4764788.500, 0, 0) ( 478597.344, 4764766.500, 0, 0) ( 478532.500, 4764695.500, 0, 0) ( 478460.125, 4764615.000, 0, 0) ( 478408.062, 4764654.000, 0, 0) ( 478315.531, 4764876.000, 0, 0) ( 478889.250, 4765100.000, 0, 0) ( 479014.938, 4765147.500, 0, 0) Shape:7 (Polygon) nVertices=6, nParts=1 Bounds:( 479029.719, 4764847.000, 0, 0) to ( 479196.812, 4765117.000, 0, 0) ( 479029.719, 4765110.500, 0, 0) Ring ( 479046.531, 4765117.000, 0, 0) ( 479123.281, 4765015.000, 0, 0) ( 479196.812, 4764879.000, 0, 0) ( 479117.812, 4764847.000, 0, 0) ( 479029.719, 4765110.500, 0, 0) Shape:8 (Polygon) nVertices=20, nParts=1 Bounds:( 479504.906, 4764609.500, 0, 0) to ( 480133.969, 4765049.500, 0, 0) ( 480082.969, 4765049.500, 0, 0) Ring ( 480080.281, 4764979.500, 0, 0) ( 480133.969, 4764856.500, 0, 0) ( 479968.469, 4764788.000, 0, 0) ( 479750.688, 4764702.000, 0, 0) ( 479735.906, 4764752.000, 0, 0) ( 479640.094, 4764721.000, 0, 0) ( 479658.594, 4764670.000, 0, 0) ( 479504.906, 4764609.500, 0, 0) ( 479548.031, 4764693.500, 0, 0) ( 479587.281, 4764718.000, 0, 0) ( 479617.219, 4764760.000, 0, 0) ( 479637.875, 4764803.000, 0, 0) ( 479644.781, 4764827.500, 0, 0) ( 479680.281, 4764852.000, 0, 0) ( 479734.375, 4764865.000, 0, 0) ( 479895.125, 4765000.000, 0, 0) ( 479934.969, 4765020.000, 0, 0) ( 480000.281, 4765043.000, 0, 0) ( 480082.969, 4765049.500, 0, 0) Shape:9 (Polygon) nVertices=31, nParts=1 Bounds:( 479968.469, 4764183.000, 0, 0) to ( 480731.656, 4765014.000, 0, 0) ( 480389.688, 4764950.000, 0, 0) Ring ( 480537.156, 4765014.000, 0, 0) ( 480567.969, 4764918.000, 0, 0) ( 480605.000, 4764835.000, 0, 0) ( 480701.062, 4764738.000, 0, 0) ( 480710.250, 4764690.500, 0, 0) ( 480588.594, 4764740.500, 0, 0) ( 480540.719, 4764741.000, 0, 0) ( 480515.125, 4764695.000, 0, 0) ( 480731.656, 4764561.500, 0, 0) ( 480692.188, 4764453.500, 0, 0) ( 480677.844, 4764439.000, 0, 0) ( 480655.344, 4764397.500, 0, 0) ( 480584.375, 4764353.000, 0, 0) ( 480500.406, 4764326.500, 0, 0) ( 480358.531, 4764277.000, 0, 0) ( 480192.312, 4764183.000, 0, 0) ( 480157.125, 4764266.500, 0, 0) ( 480234.312, 4764304.000, 0, 0) ( 480289.125, 4764348.500, 0, 0) ( 480316.000, 4764395.000, 0, 0) ( 480343.562, 4764477.000, 0, 0) ( 480343.719, 4764532.500, 0, 0) ( 480258.031, 4764767.000, 0, 0) ( 480177.156, 4764742.000, 0, 0) ( 480093.750, 4764703.000, 0, 0) ( 480011.000, 4764674.500, 0, 0) ( 479985.062, 4764732.000, 0, 0) ( 479968.469, 4764788.000, 0, 0) ( 480133.969, 4764856.500, 0, 0) ( 480389.688, 4764950.000, 0, 0) Shape:10 (Polygon) nVertices=61, nParts=1 Bounds:( 479492.688, 4762880.500, 0, 0) to ( 481645.312, 4764999.500, 0, 0) ( 480701.062, 4764738.000, 0, 0) Ring ( 480761.469, 4764778.000, 0, 0) ( 480824.969, 4764820.000, 0, 0) ( 480922.031, 4764850.500, 0, 0) ( 480930.719, 4764852.000, 0, 0) ( 480984.250, 4764875.000, 0, 0) ( 481088.188, 4764936.000, 0, 0) ( 481136.844, 4764994.500, 0, 0) ( 481281.312, 4764876.500, 0, 0) ( 481291.094, 4764810.000, 0, 0) ( 481465.906, 4764872.500, 0, 0) ( 481457.375, 4764937.000, 0, 0) ( 481509.656, 4764967.000, 0, 0) ( 481538.906, 4764982.500, 0, 0) ( 481575.000, 4764999.500, 0, 0) ( 481602.125, 4764915.500, 0, 0) ( 481629.844, 4764829.500, 0, 0) ( 481645.312, 4764797.500, 0, 0) ( 481635.969, 4764795.500, 0, 0) ( 481235.312, 4764650.000, 0, 0) ( 481209.812, 4764633.500, 0, 0) ( 481199.219, 4764623.500, 0, 0) ( 481185.500, 4764607.000, 0, 0) ( 481159.938, 4764580.000, 0, 0) ( 481140.469, 4764510.500, 0, 0) ( 481141.625, 4764480.500, 0, 0) ( 481199.844, 4764180.000, 0, 0) ( 481143.438, 4764010.500, 0, 0) ( 481130.312, 4763979.500, 0, 0) ( 481039.938, 4763889.500, 0, 0) ( 480882.688, 4763670.000, 0, 0) ( 480826.062, 4763650.500, 0, 0) ( 480745.188, 4763628.500, 0, 0) ( 480654.438, 4763627.500, 0, 0) ( 480599.812, 4763660.000, 0, 0) ( 480281.938, 4763576.500, 0, 0) ( 480221.500, 4763533.500, 0, 0) ( 480199.688, 4763509.000, 0, 0) ( 480195.094, 4763430.000, 0, 0) ( 480273.688, 4763305.500, 0, 0) ( 480309.688, 4763063.500, 0, 0) ( 480201.844, 4762962.500, 0, 0) ( 479855.312, 4762880.500, 0, 0) ( 479848.531, 4762897.000, 0, 0) ( 479728.875, 4763217.500, 0, 0) ( 479492.688, 4763850.000, 0, 0) ( 479550.062, 4763919.500, 0, 0) ( 480120.219, 4764188.500, 0, 0) ( 480192.312, 4764183.000, 0, 0) ( 480358.531, 4764277.000, 0, 0) ( 480500.406, 4764326.500, 0, 0) ( 480584.375, 4764353.000, 0, 0) ( 480655.344, 4764397.500, 0, 0) ( 480677.844, 4764439.000, 0, 0) ( 480692.188, 4764453.500, 0, 0) ( 480731.656, 4764561.500, 0, 0) ( 480515.125, 4764695.000, 0, 0) ( 480540.719, 4764741.000, 0, 0) ( 480588.594, 4764740.500, 0, 0) ( 480710.250, 4764690.500, 0, 0) ( 480701.062, 4764738.000, 0, 0) Shape:11 (Polygon) nVertices=21, nParts=1 Bounds:( 476732.906, 4763624.500, 0, 0) to ( 478408.062, 4764876.000, 0, 0) ( 478315.531, 4764876.000, 0, 0) Ring ( 478408.062, 4764654.000, 0, 0) ( 478325.250, 4764606.500, 0, 0) ( 478220.094, 4764574.500, 0, 0) ( 478140.344, 4764511.000, 0, 0) ( 478065.062, 4764487.500, 0, 0) ( 478080.938, 4764401.500, 0, 0) ( 478110.500, 4764308.500, 0, 0) ( 478149.969, 4764212.500, 0, 0) ( 478180.219, 4764150.000, 0, 0) ( 478192.500, 4764099.500, 0, 0) ( 477893.125, 4763984.500, 0, 0) ( 477417.031, 4763800.500, 0, 0) ( 477005.594, 4763640.000, 0, 0) ( 476958.312, 4763624.500, 0, 0) ( 476947.250, 4763664.500, 0, 0) ( 476732.906, 4764243.000, 0, 0) ( 477322.375, 4764502.000, 0, 0) ( 477599.906, 4764600.000, 0, 0) ( 477949.656, 4764745.000, 0, 0) ( 478315.531, 4764876.000, 0, 0) Shape:12 (Polygon) nVertices=22, nParts=1 Bounds:( 478065.062, 4764099.500, 0, 0) to ( 478683.000, 4764788.500, 0, 0) ( 478408.062, 4764654.000, 0, 0) Ring ( 478460.125, 4764615.000, 0, 0) ( 478532.500, 4764695.500, 0, 0) ( 478597.344, 4764766.500, 0, 0) ( 478621.031, 4764788.500, 0, 0) ( 478683.000, 4764730.500, 0, 0) ( 478502.188, 4764541.500, 0, 0) ( 478448.688, 4764531.500, 0, 0) ( 478447.812, 4764454.000, 0, 0) ( 478443.938, 4764400.500, 0, 0) ( 478461.750, 4764337.500, 0, 0) ( 478503.031, 4764218.000, 0, 0) ( 478192.500, 4764099.500, 0, 0) ( 478180.219, 4764150.000, 0, 0) ( 478149.969, 4764212.500, 0, 0) ( 478110.500, 4764308.500, 0, 0) ( 478080.938, 4764401.500, 0, 0) ( 478065.062, 4764487.500, 0, 0) ( 478140.344, 4764511.000, 0, 0) ( 478220.094, 4764574.500, 0, 0) ( 478325.250, 4764606.500, 0, 0) ( 478408.062, 4764654.000, 0, 0) Shape:13 (Polygon) nVertices=27, nParts=1 Bounds:( 479239.812, 4763850.000, 0, 0) to ( 480343.719, 4764788.000, 0, 0) ( 479750.688, 4764702.000, 0, 0) Ring ( 479968.469, 4764788.000, 0, 0) ( 479985.062, 4764732.000, 0, 0) ( 480011.000, 4764674.500, 0, 0) ( 480093.750, 4764703.000, 0, 0) ( 480177.156, 4764742.000, 0, 0) ( 480258.031, 4764767.000, 0, 0) ( 480343.719, 4764532.500, 0, 0) ( 480343.562, 4764477.000, 0, 0) ( 480316.000, 4764395.000, 0, 0) ( 480289.125, 4764348.500, 0, 0) ( 480234.312, 4764304.000, 0, 0) ( 480157.125, 4764266.500, 0, 0) ( 480192.312, 4764183.000, 0, 0) ( 480120.219, 4764188.500, 0, 0) ( 479550.062, 4763919.500, 0, 0) ( 479492.688, 4763850.000, 0, 0) ( 479487.750, 4763864.500, 0, 0) ( 479442.750, 4763990.000, 0, 0) ( 479436.000, 4764023.000, 0, 0) ( 479398.938, 4764100.000, 0, 0) ( 479349.625, 4764230.000, 0, 0) ( 479305.875, 4764361.000, 0, 0) ( 479239.812, 4764505.000, 0, 0) ( 479504.906, 4764609.500, 0, 0) ( 479658.594, 4764670.000, 0, 0) ( 479750.688, 4764702.000, 0, 0) Shape:14 (Polygon) nVertices=5, nParts=1 Bounds:( 479640.094, 4764670.000, 0, 0) to ( 479750.688, 4764752.000, 0, 0) ( 479750.688, 4764702.000, 0, 0) Ring ( 479658.594, 4764670.000, 0, 0) ( 479640.094, 4764721.000, 0, 0) ( 479735.906, 4764752.000, 0, 0) ( 479750.688, 4764702.000, 0, 0) Shape:15 (Polygon) nVertices=28, nParts=1 Bounds:( 478503.031, 4763357.500, 0, 0) to ( 479349.625, 4764418.500, 0, 0) ( 479305.875, 4764361.000, 0, 0) Ring ( 479349.625, 4764230.000, 0, 0) ( 479218.156, 4764126.000, 0, 0) ( 479128.344, 4764030.500, 0, 0) ( 479103.406, 4764000.000, 0, 0) ( 479099.594, 4763977.500, 0, 0) ( 479080.812, 4763930.000, 0, 0) ( 478999.812, 4763864.500, 0, 0) ------------------------------------------------------------------------- Test 4: dump pline.dbf - uses new F field type ------------------------------------------------------------------------- Field 0: Type=Integer, Title=`FNODE_', Width=11, Decimals=0 Field 1: Type=Integer, Title=`TNODE_', Width=11, Decimals=0 Field 2: Type=Integer, Title=`LPOLY_', Width=11, Decimals=0 Field 3: Type=Integer, Title=`RPOLY_', Width=11, Decimals=0 Field 4: Type=Double, Title=`LENGTH', Width=13, Decimals=3 Field 5: Type=Integer, Title=`PLINE_', Width=11, Decimals=0 Field 6: Type=Integer, Title=`PLINE_ID', Width=11, Decimals=0 Field 7: Type=Integer, Title=`UID', Width=11, Decimals=0 Field 8: Type=Integer, Title=`GISO_TYPE_', Width=11, Decimals=0 Field 9: Type=Integer, Title=`SYMBOL', Width=6, Decimals=0 Field 10: Type=Integer, Title=`LOCK__ID', Width=11, Decimals=0 Field 11: Type=Integer, Title=`PHASE__ID', Width=6, Decimals=0 Field 12: Type=Integer, Title=`OBJECT__ID', Width=11, Decimals=0 Field 13: Type=String, Title=`TYPE', Width=50, Decimals=0 Field 14: Type=Integer, Title=`SYM_NBR', Width=6, Decimals=0 Field 15: Type=String, Title=`PHASE', Width=4, Decimals=0 Field 16: Type=String, Title=`CKT_NM', Width=30, Decimals=0 Field 17: Type=String, Title=`VOLTAGE', Width=30, Decimals=0 Field 18: Type=String, Title=`CMPN', Width=30, Decimals=0 Record: 0 FNODE_: 351 TNODE_: 352 LPOLY_: 0 RPOLY_: 0 LENGTH: 139.451 PLINE_: 1 PLINE_ID: 8588 UID: 544484 GISO_TYPE_: 13 SYMBOL: 101 LOCK__ID: 0 PHASE__ID: 0 OBJECT__ID: 131978 TYPE: Overhead Primary SYM_NBR: 101 PHASE: ABC CKT_NM: MED36 VOLTAGE: (NULL) CMPN: (NULL) Record: 1 FNODE_: 352 TNODE_: 362 LPOLY_: 0 RPOLY_: 0 LENGTH: 158.033 PLINE_: 2 PLINE_ID: 8695 UID: 544591 ------------------------------------------------------------------------- Test 5: NULL Shapes. ------------------------------------------------------------------------- Shapefile Type: Arc # of Shapes: 124 File Bounds: ( 257104.880, 5176098.606,0,0) to ( 335497.500, 5226768.100,0,0) Shape:0 (Arc) nVertices=21, nParts=1 Bounds:( 317138.450, 5176398.916, 0, 0) to ( 317325.590, 5186063.780, 0, 0) ( 317255.906, 5176398.916, 0, 0) Ring ( 317188.010, 5176506.460, 0, 0) ( 317176.920, 5176524.510, 0, 0) ( 317165.340, 5176546.850, 0, 0) ( 317157.950, 5176566.020, 0, 0) ( 317150.020, 5176587.650, 0, 0) ( 317140.130, 5176623.380, 0, 0) ( 317138.700, 5176637.220, 0, 0) ( 317138.450, 5176652.790, 0, 0) ( 317194.710, 5177654.350, 0, 0) ( 317208.900, 5178001.150, 0, 0) ( 317257.240, 5178791.400, 0, 0) ( 317233.330, 5179171.730, 0, 0) ( 317178.860, 5179593.910, 0, 0) ( 317177.430, 5180161.330, 0, 0) ( 317179.910, 5181231.060, 0, 0) ( 317191.120, 5182009.000, 0, 0) ( 317217.150, 5182812.160, 0, 0) ( 317251.760, 5184426.350, 0, 0) ( 317285.550, 5185242.720, 0, 0) ( 317325.590, 5186063.780, 0, 0) Shape:1 (Arc) nVertices=14, nParts=1 Bounds:( 327417.340, 5176119.960, 0, 0) to ( 327575.150, 5179522.550, 0, 0) ( 327417.340, 5176119.960, 0, 0) Ring ( 327472.250, 5177756.610, 0, 0) ( 327475.670, 5178507.280, 0, 0) ( 327487.420, 5179001.910, 0, 0) ( 327488.760, 5179080.090, 0, 0) ( 327485.310, 5179309.310, 0, 0) ( 327487.010, 5179328.210, 0, 0) ( 327491.800, 5179348.860, 0, 0) ( 327499.800, 5179374.940, 0, 0) ( 327512.980, 5179413.100, 0, 0) ( 327527.290, 5179446.960, 0, 0) ( 327538.870, 5179469.890, 0, 0) ( 327552.260, 5179491.550, 0, 0) ( 327575.150, 5179522.550, 0, 0) Shape:2 (Arc) nVertices=40, nParts=1 Bounds:( 326935.880, 5180924.980, 0, 0) to ( 327723.190, 5198803.660, 0, 0) ( 327370.950, 5180924.980, 0, 0) Ring ( 327410.070, 5181060.540, 0, 0) ( 327512.850, 5181435.450, 0, 0) ( 327518.640, 5181464.010, 0, 0) ( 327523.700, 5181488.920, 0, 0) ( 327524.500, 5181514.570, 0, 0) ( 327468.010, 5182633.640, 0, 0) ( 327500.040, 5183199.840, 0, 0) ( 327499.600, 5183224.920, 0, 0) ( 327484.700, 5183355.010, 0, 0) ( 327483.690, 5183400.900, 0, 0) ( 327483.840, 5183464.480, 0, 0) ( 327486.010, 5183494.980, 0, 0) ( 327571.280, 5184207.820, 0, 0) ( 327617.210, 5184599.430, 0, 0) ( 327620.420, 5184623.780, 0, 0) ( 327625.530, 5184650.530, 0, 0) ( 327698.430, 5184927.070, 0, 0) ( 327702.100, 5184946.520, 0, 0) ( 327717.940, 5185394.820, 0, 0) ( 327723.190, 5185719.320, 0, 0) ( 327719.460, 5185737.170, 0, 0) ( 327712.090, 5185755.740, 0, 0) ( 327699.840, 5185775.080, 0, 0) ( 327683.830, 5185791.480, 0, 0) ( 327665.380, 5185807.950, 0, 0) ( 327641.970, 5185822.740, 0, 0) ( 327622.280, 5185829.070, 0, 0) ( 327604.950, 5185832.940, 0, 0) ( 326937.500, 5185829.310, 0, 0) ( 326935.880, 5187515.510, 0, 0) ( 326983.050, 5189115.230, 0, 0) ( 326998.860, 5189920.820, 0, 0) ( 327060.240, 5190715.870, 0, 0) ( 327123.230, 5192332.220, 0, 0) ( 327179.920, 5193766.290, 0, 0) ( 327185.490, 5193921.940, 0, 0) ( 327204.120, 5195553.580, 0, 0) ( 327218.270, 5197179.250, 0, 0) ( 327251.330, 5198803.660, 0, 0) Shape:3 (NullShape) nVertices=0, nParts=0 Bounds:( 0.000, 0.000, 0, 0) to ( 0.000, 0.000, 0, 0) Shape:4 (NullShape) nVertices=0, nParts=0 Bounds:( 0.000, 0.000, 0, 0) to ( 0.000, 0.000, 0, 0) Shape:5 (NullShape) nVertices=0, nParts=0 Bounds:( 0.000, 0.000, 0, 0) to ( 0.000, 0.000, 0, 0) Shape:6 (Arc) nVertices=2, nParts=1 Bounds:( 327123.230, 5192296.600, 0, 0) to ( 328480.850, 5192332.220, 0, 0) ( 327123.230, 5192332.220, 0, 0) Ring ( 328480.850, 5192296.600, 0, 0) Shape:7 (Arc) nVertices=5, nParts=1 Bounds:( 329222.060, 5217943.490, 0, 0) to ( 335290.680, 5218084.780, 0, 0) ( 329222.060, 5218084.780, 0, 0) Ring ( 330442.520, 5218057.650, 0, 0) ( 332059.960, 5218033.810, 0, 0) ( 333685.820, 5218004.860, 0, 0) ( 335290.680, 5217943.490, 0, 0) Shape:8 (Arc) nVertices=65, nParts=1 Bounds:( 280048.100, 5177687.643, 0, 0) to ( 280439.410, 5182567.120, 0, 0) ( 280316.840, 5177687.643, 0, 0) Ring ( 280325.310, 5177968.830, 0, 0) ( 280324.630, 5178037.940, 0, 0) ( 280324.150, 5178059.350, 0, 0) ( 280320.130, 5178084.560, 0, 0) ( 280299.860, 5178170.250, 0, 0) ( 280288.710, 5178218.940, 0, 0) ( 280274.280, 5178283.640, 0, 0) ( 280268.000, 5178330.870, 0, 0) ( 280267.910, 5178346.760, 0, 0) ( 280270.510, 5178364.580, 0, 0) ( 280274.820, 5178382.360, 0, 0) ( 280278.440, 5178397.210, 0, 0) ( 280351.400, 5178743.800, 0, 0) ( 280369.860, 5178800.630, 0, 0) ( 280378.670, 5178826.010, 0, 0) ( 280400.350, 5178869.890, 0, 0) ( 280414.870, 5178901.180, 0, 0) ( 280427.030, 5178934.990, 0, 0) ( 280436.250, 5178971.970, 0, 0) ( 280439.410, 5178992.650, 0, 0) ( 280439.170, 5179001.630, 0, 0) ( 280437.010, 5179011.690, 0, 0) ( 280434.930, 5179016.970, 0, 0) ( 280431.870, 5179022.260, 0, 0) ( 280413.610, 5179041.850, 0, 0) ( 280410.040, 5179046.780, 0, 0) ( 280406.640, 5179052.480, 0, 0) ./shapelib-1.2.10/stream1.sh0100755000076500001440000000231107644273432015171 0ustar warmerdausers#!/bin/sh EG_DATA=/u/www/projects/shapelib/eg_data echo ------------------------------------------------------------------------- echo Test 1: dump anno.shp echo ------------------------------------------------------------------------- ./shpdump $EG_DATA/anno.shp | head -250 echo ------------------------------------------------------------------------- echo Test 2: dump brklinz.shp echo ------------------------------------------------------------------------- ./shpdump $EG_DATA/brklinz.shp | head -500 echo ------------------------------------------------------------------------- echo Test 3: dump polygon.shp echo ------------------------------------------------------------------------- ./shpdump $EG_DATA/polygon.shp | head -500 echo ------------------------------------------------------------------------- echo Test 4: dump pline.dbf - uses new F field type echo ------------------------------------------------------------------------- ./dbfdump -m -h $EG_DATA/pline.dbf | head -50 echo ------------------------------------------------------------------------- echo Test 5: NULL Shapes. echo ------------------------------------------------------------------------- ./shpdump $EG_DATA/csah.dbf | head -150 ./shapelib-1.2.10/stream2.out0100644000076500001440000005123407644273432015374 0ustar warmerdausers----------------------------------------------------------------------- Test 2/0 ----------------------------------------------------------------------- Shapefile Type: NullShape # of Shapes: 2 File Bounds: ( 0.000, 0.000,0,0) to ( 10.000, 20.000,0,0) Shape:0 (NullShape) nVertices=0, nParts=0 Bounds:( 0.000, 0.000, 0, 0) to ( 0.000, 0.000, 0, 0) Shape:1 (NullShape) nVertices=0, nParts=0 Bounds:( 0.000, 0.000, 0, 0) to ( 0.000, 0.000, 0, 0) ----------------------------------------------------------------------- Test 2/1 ----------------------------------------------------------------------- Shapefile Type: Point # of Shapes: 2 File Bounds: ( 1.000, 2.000,0,0) to ( 10.000, 20.000,0,0) Shape:0 (Point) nVertices=1, nParts=0 Bounds:( 1.000, 2.000, 0, 0) to ( 1.000, 2.000, 0, 0) ( 1.000, 2.000, 0, 0) Shape:1 (Point) nVertices=1, nParts=0 Bounds:( 10.000, 20.000, 0, 0) to ( 10.000, 20.000, 0, 0) ( 10.000, 20.000, 0, 0) ----------------------------------------------------------------------- Test 2/2 ----------------------------------------------------------------------- Shapefile Type: PointZ # of Shapes: 2 File Bounds: ( 1.000, 2.000,3,4) to ( 10.000, 20.000,30,40) Shape:0 (PointZ) nVertices=1, nParts=0 Bounds:( 1.000, 2.000, 3, 4) to ( 1.000, 2.000, 3, 4) ( 1.000, 2.000, 3, 4) Shape:1 (PointZ) nVertices=1, nParts=0 Bounds:( 10.000, 20.000, 30, 40) to ( 10.000, 20.000, 30, 40) ( 10.000, 20.000, 30, 40) ----------------------------------------------------------------------- Test 2/3 ----------------------------------------------------------------------- Shapefile Type: PointM # of Shapes: 2 File Bounds: ( 1.000, 2.000,0,4) to ( 10.000, 20.000,0,40) Shape:0 (PointM) nVertices=1, nParts=0 Bounds:( 1.000, 2.000, 0, 4) to ( 1.000, 2.000, 0, 4) ( 1.000, 2.000, 0, 4) Shape:1 (PointM) nVertices=1, nParts=0 Bounds:( 10.000, 20.000, 0, 40) to ( 10.000, 20.000, 0, 40) ( 10.000, 20.000, 0, 40) ----------------------------------------------------------------------- Test 2/4 ----------------------------------------------------------------------- Shapefile Type: MultiPoint # of Shapes: 3 File Bounds: ( 1.150, 2.250,0,0) to ( 24.150, 25.250,0,0) Shape:0 (MultiPoint) nVertices=4, nParts=0 Bounds:( 1.150, 2.250, 0, 0) to ( 4.150, 5.250, 0, 0) ( 1.150, 2.250, 0, 0) ( 2.150, 3.250, 0, 0) ( 3.150, 4.250, 0, 0) ( 4.150, 5.250, 0, 0) Shape:1 (MultiPoint) nVertices=4, nParts=0 Bounds:( 11.150, 12.250, 0, 0) to ( 14.150, 15.250, 0, 0) ( 11.150, 12.250, 0, 0) ( 12.150, 13.250, 0, 0) ( 13.150, 14.250, 0, 0) ( 14.150, 15.250, 0, 0) Shape:2 (MultiPoint) nVertices=4, nParts=0 Bounds:( 21.150, 22.250, 0, 0) to ( 24.150, 25.250, 0, 0) ( 21.150, 22.250, 0, 0) ( 22.150, 23.250, 0, 0) ( 23.150, 24.250, 0, 0) ( 24.150, 25.250, 0, 0) ----------------------------------------------------------------------- Test 2/5 ----------------------------------------------------------------------- Shapefile Type: MultiPointZ # of Shapes: 3 File Bounds: ( 1.150, 2.250,3.35,4.45) to ( 24.150, 25.250,26.35,27.45) Shape:0 (MultiPointZ) nVertices=4, nParts=0 Bounds:( 1.150, 2.250, 3.35, 4.45) to ( 4.150, 5.250, 6.35, 7.45) ( 1.150, 2.250, 3.35, 4.45) ( 2.150, 3.250, 4.35, 5.45) ( 3.150, 4.250, 5.35, 6.45) ( 4.150, 5.250, 6.35, 7.45) Shape:1 (MultiPointZ) nVertices=4, nParts=0 Bounds:( 11.150, 12.250, 13.35, 14.45) to ( 14.150, 15.250, 16.35, 17.45) ( 11.150, 12.250, 13.35, 14.45) ( 12.150, 13.250, 14.35, 15.45) ( 13.150, 14.250, 15.35, 16.45) ( 14.150, 15.250, 16.35, 17.45) Shape:2 (MultiPointZ) nVertices=4, nParts=0 Bounds:( 21.150, 22.250, 23.35, 24.45) to ( 24.150, 25.250, 26.35, 27.45) ( 21.150, 22.250, 23.35, 24.45) ( 22.150, 23.250, 24.35, 25.45) ( 23.150, 24.250, 25.35, 26.45) ( 24.150, 25.250, 26.35, 27.45) ----------------------------------------------------------------------- Test 2/6 ----------------------------------------------------------------------- Shapefile Type: MultiPointM # of Shapes: 3 File Bounds: ( 1.150, 2.250,0,4.45) to ( 24.150, 25.250,0,27.45) Shape:0 (MultiPointM) nVertices=4, nParts=0 Bounds:( 1.150, 2.250, 0, 4.45) to ( 4.150, 5.250, 0, 7.45) ( 1.150, 2.250, 0, 4.45) ( 2.150, 3.250, 0, 5.45) ( 3.150, 4.250, 0, 6.45) ( 4.150, 5.250, 0, 7.45) Shape:1 (MultiPointM) nVertices=4, nParts=0 Bounds:( 11.150, 12.250, 0, 14.45) to ( 14.150, 15.250, 0, 17.45) ( 11.150, 12.250, 0, 14.45) ( 12.150, 13.250, 0, 15.45) ( 13.150, 14.250, 0, 16.45) ( 14.150, 15.250, 0, 17.45) Shape:2 (MultiPointM) nVertices=4, nParts=0 Bounds:( 21.150, 22.250, 0, 24.45) to ( 24.150, 25.250, 0, 27.45) ( 21.150, 22.250, 0, 24.45) ( 22.150, 23.250, 0, 25.45) ( 23.150, 24.250, 0, 26.45) ( 24.150, 25.250, 0, 27.45) ----------------------------------------------------------------------- Test 2/7 ----------------------------------------------------------------------- Shapefile Type: Arc # of Shapes: 4 File Bounds: ( 0.000, 0.000,0,0) to ( 100.000, 100.000,0,0) Shape:0 (Arc) nVertices=5, nParts=1 Bounds:( 1.000, 1.000, 0, 0) to ( 2.000, 2.000, 0, 0) ( 1.000, 1.000, 0, 0) Ring ( 2.000, 1.000, 0, 0) ( 2.000, 2.000, 0, 0) ( 1.000, 2.000, 0, 0) ( 1.000, 1.000, 0, 0) Shape:1 (Arc) nVertices=5, nParts=1 Bounds:( 1.000, 4.000, 0, 0) to ( 2.000, 5.000, 0, 0) ( 1.000, 4.000, 0, 0) Ring ( 2.000, 4.000, 0, 0) ( 2.000, 5.000, 0, 0) ( 1.000, 5.000, 0, 0) ( 1.000, 4.000, 0, 0) Shape:2 (Arc) nVertices=5, nParts=1 Bounds:( 1.000, 7.000, 0, 0) to ( 2.000, 8.000, 0, 0) ( 1.000, 7.000, 0, 0) Ring ( 2.000, 7.000, 0, 0) ( 2.000, 8.000, 0, 0) ( 1.000, 8.000, 0, 0) ( 1.000, 7.000, 0, 0) Shape:3 (Arc) nVertices=15, nParts=3 Bounds:( 0.000, 0.000, 0, 0) to ( 100.000, 100.000, 0, 0) ( 0.000, 0.000, 0, 0) Ring ( 0.000, 100.000, 0, 0) ( 100.000, 100.000, 0, 0) ( 100.000, 0.000, 0, 0) ( 0.000, 0.000, 0, 0) + ( 10.000, 20.000, 0, 0) Ring ( 30.000, 20.000, 0, 0) ( 30.000, 40.000, 0, 0) ( 10.000, 40.000, 0, 0) ( 10.000, 20.000, 0, 0) + ( 60.000, 20.000, 0, 0) Ring ( 90.000, 20.000, 0, 0) ( 90.000, 40.000, 0, 0) ( 60.000, 40.000, 0, 0) ( 60.000, 20.000, 0, 0) ----------------------------------------------------------------------- Test 2/8 ----------------------------------------------------------------------- Shapefile Type: ArcZ # of Shapes: 4 File Bounds: ( 0.000, 0.000,0,0) to ( 100.000, 100.000,27.35,28.45) Shape:0 (ArcZ) nVertices=5, nParts=1 Bounds:( 1.000, 1.000, 3.35, 4.45) to ( 2.000, 2.000, 7.35, 8.45) ( 1.000, 1.000, 3.35, 4.45) Ring ( 2.000, 1.000, 4.35, 5.45) ( 2.000, 2.000, 5.35, 6.45) ( 1.000, 2.000, 6.35, 7.45) ( 1.000, 1.000, 7.35, 8.45) Shape:1 (ArcZ) nVertices=5, nParts=1 Bounds:( 1.000, 4.000, 13.35, 14.45) to ( 2.000, 5.000, 17.35, 18.45) ( 1.000, 4.000, 13.35, 14.45) Ring ( 2.000, 4.000, 14.35, 15.45) ( 2.000, 5.000, 15.35, 16.45) ( 1.000, 5.000, 16.35, 17.45) ( 1.000, 4.000, 17.35, 18.45) Shape:2 (ArcZ) nVertices=5, nParts=1 Bounds:( 1.000, 7.000, 23.35, 24.45) to ( 2.000, 8.000, 27.35, 28.45) ( 1.000, 7.000, 23.35, 24.45) Ring ( 2.000, 7.000, 24.35, 25.45) ( 2.000, 8.000, 25.35, 26.45) ( 1.000, 8.000, 26.35, 27.45) ( 1.000, 7.000, 27.35, 28.45) Shape:3 (ArcZ) nVertices=15, nParts=3 Bounds:( 0.000, 0.000, 0, 0) to ( 100.000, 100.000, 14, 28) ( 0.000, 0.000, 0, 0) Ring ( 0.000, 100.000, 1, 2) ( 100.000, 100.000, 2, 4) ( 100.000, 0.000, 3, 6) ( 0.000, 0.000, 4, 8) + ( 10.000, 20.000, 5, 10) Ring ( 30.000, 20.000, 6, 12) ( 30.000, 40.000, 7, 14) ( 10.000, 40.000, 8, 16) ( 10.000, 20.000, 9, 18) + ( 60.000, 20.000, 10, 20) Ring ( 90.000, 20.000, 11, 22) ( 90.000, 40.000, 12, 24) ( 60.000, 40.000, 13, 26) ( 60.000, 20.000, 14, 28) ----------------------------------------------------------------------- Test 2/9 ----------------------------------------------------------------------- Shapefile Type: ArcM # of Shapes: 4 File Bounds: ( 0.000, 0.000,0,0) to ( 100.000, 100.000,0,28.45) Shape:0 (ArcM) nVertices=5, nParts=1 Bounds:( 1.000, 1.000, 0, 4.45) to ( 2.000, 2.000, 0, 8.45) ( 1.000, 1.000, 0, 4.45) Ring ( 2.000, 1.000, 0, 5.45) ( 2.000, 2.000, 0, 6.45) ( 1.000, 2.000, 0, 7.45) ( 1.000, 1.000, 0, 8.45) Shape:1 (ArcM) nVertices=5, nParts=1 Bounds:( 1.000, 4.000, 0, 14.45) to ( 2.000, 5.000, 0, 18.45) ( 1.000, 4.000, 0, 14.45) Ring ( 2.000, 4.000, 0, 15.45) ( 2.000, 5.000, 0, 16.45) ( 1.000, 5.000, 0, 17.45) ( 1.000, 4.000, 0, 18.45) Shape:2 (ArcM) nVertices=5, nParts=1 Bounds:( 1.000, 7.000, 0, 24.45) to ( 2.000, 8.000, 0, 28.45) ( 1.000, 7.000, 0, 24.45) Ring ( 2.000, 7.000, 0, 25.45) ( 2.000, 8.000, 0, 26.45) ( 1.000, 8.000, 0, 27.45) ( 1.000, 7.000, 0, 28.45) Shape:3 (ArcM) nVertices=15, nParts=3 Bounds:( 0.000, 0.000, 0, 0) to ( 100.000, 100.000, 0, 28) ( 0.000, 0.000, 0, 0) Ring ( 0.000, 100.000, 0, 2) ( 100.000, 100.000, 0, 4) ( 100.000, 0.000, 0, 6) ( 0.000, 0.000, 0, 8) + ( 10.000, 20.000, 0, 10) Ring ( 30.000, 20.000, 0, 12) ( 30.000, 40.000, 0, 14) ( 10.000, 40.000, 0, 16) ( 10.000, 20.000, 0, 18) + ( 60.000, 20.000, 0, 20) Ring ( 90.000, 20.000, 0, 22) ( 90.000, 40.000, 0, 24) ( 60.000, 40.000, 0, 26) ( 60.000, 20.000, 0, 28) ----------------------------------------------------------------------- Test 2/10 ----------------------------------------------------------------------- Shapefile Type: Polygon # of Shapes: 4 File Bounds: ( 0.000, 0.000,0,0) to ( 100.000, 100.000,0,0) Shape:0 (Polygon) nVertices=5, nParts=1 Bounds:( 1.000, 1.000, 0, 0) to ( 2.000, 2.000, 0, 0) ( 1.000, 1.000, 0, 0) Ring ( 2.000, 1.000, 0, 0) ( 2.000, 2.000, 0, 0) ( 1.000, 2.000, 0, 0) ( 1.000, 1.000, 0, 0) Shape:1 (Polygon) nVertices=5, nParts=1 Bounds:( 1.000, 4.000, 0, 0) to ( 2.000, 5.000, 0, 0) ( 1.000, 4.000, 0, 0) Ring ( 2.000, 4.000, 0, 0) ( 2.000, 5.000, 0, 0) ( 1.000, 5.000, 0, 0) ( 1.000, 4.000, 0, 0) Shape:2 (Polygon) nVertices=5, nParts=1 Bounds:( 1.000, 7.000, 0, 0) to ( 2.000, 8.000, 0, 0) ( 1.000, 7.000, 0, 0) Ring ( 2.000, 7.000, 0, 0) ( 2.000, 8.000, 0, 0) ( 1.000, 8.000, 0, 0) ( 1.000, 7.000, 0, 0) Shape:3 (Polygon) nVertices=15, nParts=3 Bounds:( 0.000, 0.000, 0, 0) to ( 100.000, 100.000, 0, 0) ( 0.000, 0.000, 0, 0) Ring ( 0.000, 100.000, 0, 0) ( 100.000, 100.000, 0, 0) ( 100.000, 0.000, 0, 0) ( 0.000, 0.000, 0, 0) + ( 10.000, 20.000, 0, 0) Ring ( 30.000, 20.000, 0, 0) ( 30.000, 40.000, 0, 0) ( 10.000, 40.000, 0, 0) ( 10.000, 20.000, 0, 0) + ( 60.000, 20.000, 0, 0) Ring ( 90.000, 20.000, 0, 0) ( 90.000, 40.000, 0, 0) ( 60.000, 40.000, 0, 0) ( 60.000, 20.000, 0, 0) ----------------------------------------------------------------------- Test 2/11 ----------------------------------------------------------------------- Shapefile Type: PolygonZ # of Shapes: 4 File Bounds: ( 0.000, 0.000,0,0) to ( 100.000, 100.000,27.35,28.45) Shape:0 (PolygonZ) nVertices=5, nParts=1 Bounds:( 1.000, 1.000, 3.35, 4.45) to ( 2.000, 2.000, 7.35, 8.45) ( 1.000, 1.000, 3.35, 4.45) Ring ( 2.000, 1.000, 4.35, 5.45) ( 2.000, 2.000, 5.35, 6.45) ( 1.000, 2.000, 6.35, 7.45) ( 1.000, 1.000, 7.35, 8.45) Shape:1 (PolygonZ) nVertices=5, nParts=1 Bounds:( 1.000, 4.000, 13.35, 14.45) to ( 2.000, 5.000, 17.35, 18.45) ( 1.000, 4.000, 13.35, 14.45) Ring ( 2.000, 4.000, 14.35, 15.45) ( 2.000, 5.000, 15.35, 16.45) ( 1.000, 5.000, 16.35, 17.45) ( 1.000, 4.000, 17.35, 18.45) Shape:2 (PolygonZ) nVertices=5, nParts=1 Bounds:( 1.000, 7.000, 23.35, 24.45) to ( 2.000, 8.000, 27.35, 28.45) ( 1.000, 7.000, 23.35, 24.45) Ring ( 2.000, 7.000, 24.35, 25.45) ( 2.000, 8.000, 25.35, 26.45) ( 1.000, 8.000, 26.35, 27.45) ( 1.000, 7.000, 27.35, 28.45) Shape:3 (PolygonZ) nVertices=15, nParts=3 Bounds:( 0.000, 0.000, 0, 0) to ( 100.000, 100.000, 14, 28) ( 0.000, 0.000, 0, 0) Ring ( 0.000, 100.000, 1, 2) ( 100.000, 100.000, 2, 4) ( 100.000, 0.000, 3, 6) ( 0.000, 0.000, 4, 8) + ( 10.000, 20.000, 5, 10) Ring ( 30.000, 20.000, 6, 12) ( 30.000, 40.000, 7, 14) ( 10.000, 40.000, 8, 16) ( 10.000, 20.000, 9, 18) + ( 60.000, 20.000, 10, 20) Ring ( 90.000, 20.000, 11, 22) ( 90.000, 40.000, 12, 24) ( 60.000, 40.000, 13, 26) ( 60.000, 20.000, 14, 28) ----------------------------------------------------------------------- Test 2/12 ----------------------------------------------------------------------- Shapefile Type: PolygonM # of Shapes: 4 File Bounds: ( 0.000, 0.000,0,0) to ( 100.000, 100.000,0,28.45) Shape:0 (PolygonM) nVertices=5, nParts=1 Bounds:( 1.000, 1.000, 0, 4.45) to ( 2.000, 2.000, 0, 8.45) ( 1.000, 1.000, 0, 4.45) Ring ( 2.000, 1.000, 0, 5.45) ( 2.000, 2.000, 0, 6.45) ( 1.000, 2.000, 0, 7.45) ( 1.000, 1.000, 0, 8.45) Shape:1 (PolygonM) nVertices=5, nParts=1 Bounds:( 1.000, 4.000, 0, 14.45) to ( 2.000, 5.000, 0, 18.45) ( 1.000, 4.000, 0, 14.45) Ring ( 2.000, 4.000, 0, 15.45) ( 2.000, 5.000, 0, 16.45) ( 1.000, 5.000, 0, 17.45) ( 1.000, 4.000, 0, 18.45) Shape:2 (PolygonM) nVertices=5, nParts=1 Bounds:( 1.000, 7.000, 0, 24.45) to ( 2.000, 8.000, 0, 28.45) ( 1.000, 7.000, 0, 24.45) Ring ( 2.000, 7.000, 0, 25.45) ( 2.000, 8.000, 0, 26.45) ( 1.000, 8.000, 0, 27.45) ( 1.000, 7.000, 0, 28.45) Shape:3 (PolygonM) nVertices=15, nParts=3 Bounds:( 0.000, 0.000, 0, 0) to ( 100.000, 100.000, 0, 28) ( 0.000, 0.000, 0, 0) Ring ( 0.000, 100.000, 0, 2) ( 100.000, 100.000, 0, 4) ( 100.000, 0.000, 0, 6) ( 0.000, 0.000, 0, 8) + ( 10.000, 20.000, 0, 10) Ring ( 30.000, 20.000, 0, 12) ( 30.000, 40.000, 0, 14) ( 10.000, 40.000, 0, 16) ( 10.000, 20.000, 0, 18) + ( 60.000, 20.000, 0, 20) Ring ( 90.000, 20.000, 0, 22) ( 90.000, 40.000, 0, 24) ( 60.000, 40.000, 0, 26) ( 60.000, 20.000, 0, 28) ----------------------------------------------------------------------- Test 2/13 ----------------------------------------------------------------------- Shapefile Type: MultiPatch # of Shapes: 4 File Bounds: ( 0.000, 0.000,0,0) to ( 100.000, 100.000,27.35,28.45) Shape:0 (MultiPatch) nVertices=5, nParts=1 Bounds:( 1.000, 1.000, 3.35, 0) to ( 2.000, 2.000, 7.35, 0) ( 1.000, 1.000, 3.35, 0) Ring ( 2.000, 1.000, 4.35, 0) ( 2.000, 2.000, 5.35, 0) ( 1.000, 2.000, 6.35, 0) ( 1.000, 1.000, 7.35, 0) Shape:1 (MultiPatch) nVertices=5, nParts=1 Bounds:( 1.000, 4.000, 13.35, 0) to ( 2.000, 5.000, 17.35, 0) ( 1.000, 4.000, 13.35, 0) Ring ( 2.000, 4.000, 14.35, 0) ( 2.000, 5.000, 15.35, 0) ( 1.000, 5.000, 16.35, 0) ( 1.000, 4.000, 17.35, 0) Shape:2 (MultiPatch) nVertices=5, nParts=1 Bounds:( 1.000, 7.000, 23.35, 0) to ( 2.000, 8.000, 27.35, 0) ( 1.000, 7.000, 23.35, 0) Ring ( 2.000, 7.000, 24.35, 0) ( 2.000, 8.000, 25.35, 0) ( 1.000, 8.000, 26.35, 0) ( 1.000, 7.000, 27.35, 0) Shape:3 (MultiPatch) nVertices=15, nParts=3 Bounds:( 0.000, 0.000, 0, 0) to ( 100.000, 100.000, 14, 0) ( 0.000, 0.000, 0, 0) Ring ( 0.000, 100.000, 1, 0) ( 100.000, 100.000, 2, 0) ( 100.000, 0.000, 3, 0) ( 0.000, 0.000, 4, 0) + ( 10.000, 20.000, 5, 0) InnerRing ( 30.000, 20.000, 6, 0) ( 30.000, 40.000, 7, 0) ( 10.000, 40.000, 8, 0) ( 10.000, 20.000, 9, 0) + ( 60.000, 20.000, 10, 0) InnerRing ( 90.000, 20.000, 11, 0) ( 90.000, 40.000, 12, 0) ( 60.000, 40.000, 13, 0) ( 60.000, 20.000, 14, 0) ./shapelib-1.2.10/stream2.sh0100755000076500001440000000042607644273432015177 0ustar warmerdausers#!/bin/sh for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13; do echo ----------------------------------------------------------------------- echo Test 2/$i echo ----------------------------------------------------------------------- ./shptest $i ./shpdump test${i}.shp done ./shapelib-1.2.10/stream3.out0100644000076500001440000000266107644273432015375 0ustar warmerdausersShapefile Type: Polygon # of Shapes: 3 File Bounds: ( 0.000, 0.000,0,0) to ( 180.000, 170.000,0,0) Shape:0 (Polygon) nVertices=9, nParts=2 Bounds:( 0.000, 0.000, 0, 0) to ( 100.000, 100.000, 0, 0) ( 0.000, 0.000, 0, 0) Ring ( 100.000, 0.000, 0, 0) ( 100.000, 100.000, 0, 0) ( 0.000, 100.000, 0, 0) ( 0.000, 0.000, 0, 0) + ( 20.000, 20.000, 0, 0) Ring ( 20.000, 30.000, 0, 0) ( 30.000, 30.000, 0, 0) ( 20.000, 20.000, 0, 0) Shape:1 (Polygon) nVertices=4, nParts=1 Bounds:( 150.000, 150.000, 0, 0) to ( 180.000, 170.000, 0, 0) ( 150.000, 150.000, 0, 0) Ring ( 160.000, 150.000, 0, 0) ( 180.000, 170.000, 0, 0) ( 150.000, 150.000, 0, 0) Shape:2 (Polygon) nVertices=4, nParts=1 Bounds:( 150.000, 150.000, 0, 0) to ( 180.000, 170.000, 0, 0) ( 150.000, 150.000, 0, 0) Ring ( 160.000, 150.000, 0, 0) ( 180.000, 170.000, 0, 0) ( 150.000, 150.000, 0, 0) Descriptio TestInt TestDouble Square with triangle missing 1 2.50000 Smaller triangle 100 1000.25000 (NULL) (NULL) (NULL) ./shapelib-1.2.10/shprewind0100755000076500001440000014264707644273432015230 0ustar warmerdausersELF44 ("444KKK@L@@ /lib/ld-linux.so.2GNU   I%;5$'4DT-dQQt9'Xf ąkԅqdP4_q 0libc.so.6strcpymemcpymalloccallocfseekreallocfread__assert_failstrcmpsprintffclosefwriteexitfopen_IO_stdin_used__libc_start_mainstrlenfree__gmon_start__GLIBC_2.1GLIBC_2.0ii ii p(,048<@DH L P T X \`dhlUa*C5 %$%(h%,h%0h%4h%8h %<h(%@h0%Dh8p%Hh@`%LhHP%PhP@%ThX0%Xh` %\hh%`hp%dhx%hh%lh1^PTRh0h̄QVhĆUSP[VTtЋ]ÐU=tu)tҡutÉUtt hCyÐUx)E}t h jhE 0E}u"E 0hC jf EPEPEPEPuC uE 0E}u"E 0h jEE;E|VuuT*Euu9tEuju u8E렃 u u uhD jgUEU9E|=EE EEM UE)E HUE)E PEEÐU}u u YEu uEEUVSE}c~EEEE'E EP EjEPEPK=xuEPjEjEPEP=xtEPjE@EjEPE P=xtE PjpEP$@ x|jxPE$P=xtE$Pj#EP,@(x|jxPE,P7=xtE,PjEPD@@x|jxPE4P=xtE4PjEPL@Hx|jxPE Ep- uOEMEEEEAEEȋE@dEă}yEEUȉBUE BExxEx@B; E0q Ep` uE=xtE$PjjE$PEPME؋U܉A Q$=xtE,PjjE,PEPME؋U܉A(Q,=xtE4PjMjE4PEPyME؋U܉A@QD=xtE} t} t}t}t}tEEEE}t)}t#}t}t} t}t }tEEUU}}EUEP] E@PC ] E@PCE@ E@EE;E|lUEJ EE}t%UEJEEMEAE늃}|]ujC]ujC]ujC ]ujC$} uh-hbh=hG}$uh-hch=h\EE;E|UEJEE RTUEJEE$RT}(t2}t,UEJ EE(RT},t2}t,UEJ$EE,RTE!UEB uVE]ÐUjuuuu jjjju0USE@`EU;Bt!E8thqhh=h6} t,} x UE ;B}hqhh=h} tUE ;B|E } EPBE;P~qUE@`h}fEδ fEmZm΋]E@PEp)C]E@PEpC E@EHPMEE8t5E8t-E8t%E8tE8 tE8t E8tE@EE@E܃uE P=xtEPj=xtEPjjEPE0P jEPE,PE4E@PEp E4PEUE;B|0=xtEE4PjNEEËE8u`E@PEpEEP[EUE;B|*=xtEEPjEEEUE;B|jUEBPEEPjUEBPEEP=xtEEPj`=xtEEPj@EE^E8tE8 t E8tjE8PEEP<=xtEEPjEjEXPEEP=xtEEPjEEUE;B|KjUEB PEEP=xtEEPjEEE먋E8tE8tE8t E8 t;jE@PEEP<=xtEEPjEjE`PEEP=xtEEPjEEUE;B|jUEB$PEEP=xtEEPjBEE륋E8tE8t E8tE@EԃuE P=xtEPjjEPE,P EUE;B|jUEBPEE0PjUEBPEE8P=xtEE0Pj@=xtEE8PjERE@0EE8jE8PEEP!=xtEEPjEjEXPEEP=xtEEPjEEUE;B|KjUEB PEEP=xtEEPj*EE먋E8t E8t0jE@PEEP1=xtEEPjEjE`PEEP=xtEEPjEEUE;B|jUEB$PEEP=xtEEPj7EE륋E8tE8 t E8t jEpE P7jEpEP=xtE Pj=xtEPjEE8 u=jEp EEP=xtEEPjYEE8 t E8tijEp$EEPk=xtEEPj E*E8u E hqhh=h } tUE RE9 |X} u EPU @UE RE@ E UE RE MUEB A ME AEE @E=xuEPj&jEPuVUE=xuEPjjEPEPEE=xtEPjjEPEPjuE0ouE0juuu* h@ uE uE@ E@tE@@E@tE@(E@tE@HE@t|E8tt]ME@PA@QDC S$]ME@PAHQLC(S,]ME@ PAPQTC0S4]ME@$PAXQ\C8SjUEBd8PUEBP=xtUEBPj=xtUEBPjEOE0EjE@d PE(PjE@dPE0P|jE@dPEHP^jE@d$PEPP@=xtE(Pj=xtE0Pj=xtEHPj=xtEPPjE8jUEBdPE8PjUEBdPEXP=xtE8Pj =xtEXPjEE;E|\jUERd‹EPUEB P=xtUEB PjE뚋EEEME AEE9jUEBdPE@PjUEBdPE`Pb=xtE@Pj=xtE`PjEE;E|djUERd‹EPUEB$P=xtUEB$Pj{E뗋E8tE8t E8 tE@]jjC]jjC]jjC ]jjpC$jE@d PEp jE@dPEp=xtEpj=xtEpjEE8 u?jUEBdPEp =xtEp j?EME AE9|9jUEBdPEp$@=xtEp$j]ME@PAHQLC(S,]ME@PAPQTC0S4]ME@ PAXQ\C8S<]ME@$PA`QdC@SDEE܋E܋]ÐU}EEp|EzsEjEaEXEOEFE=E4E+E"EEEEEU}wDEEx4E+E"EEEEEU}uExt EpExt EpEx t Ep ~Ex$t Ep$dEx t Ep JExt Ep0 u"ÐUWVSTEE 8tE 8tE 8t E%EU E;B|] M EA CREUċ] M EA CREUEEU E;B|E;EuM EԍA E؋E @H9Eu ] M EԍA C)ЉE)U EB XM EԍA )ЉEEE;E|gEH9E} E@EEM EEAEEt$M EEAEtPM EEAEEtM EEAEtU EE<RUM EEAE$U EErM EEA$U EErM EEA$ɋE8EEt }EEEM EA E؋E @H9Eu ] M EA C)ЉE)U EB XM EA )ЉEEEE؉EEEH9E|YU E ZU EB U E ZU EB E]ȍE뙋U E4ZM E؍A3 U E4ZM E؍A3 E]EEt}uEEt }EEU܉9E|M EE؍AREUU EE؍JU EE+EBPTU EE+EBHEUQM EE؍AREUU EE؍JU EE+EBPTU EE+EBHEUQE x tuM EE؍A REUU EE؍J U EE+EB PTU EE+EB HEUQE x$tuM EE؍A$REUU EE؍J$U EE+EB$PTU EE+EB$HEUQEEEEET[^_USRt ЋuX[USR[]shprewind in_shp_file out_shp_file rbUnable to open:%s Unable to create:%s %d objects rewound. rb+r+br+rb%s.shp%s.SHP%s.shx%s.SHXwbSHPCreateObjectshpopen.cpadfX != ((void *)0)padfY != ((void *)0)SHPWriteObjectpsObject->nSHPType == psSHP->nShapeType || psObject->nSHPType == 0nShapeId == -1 || (nShapeId >= 0 && nShapeId < psSHP->nRecords)0Error in fseek() or fwrite(). ?Y@NullShapePointArcPolygonMultiPointPointZArcZPolygonZMultiPointZPointMArcMPolygonMMultiPointMMultiPatchUnknownShapeType (1:CLU^gpyTriangleStripTriangleFanOuterRingInnerRingFirstRingRingUnknownPartType$Id: shpopen.c,v 1.39 2002/08/26 06:46:56 warmerda Exp $ ̄ 0(ȁ <4oooڃ@ *:JZjzʅڅ GCC: (GNU) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)GCC: (GNU) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)GCC: (GNU) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)GCC: (GNU) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)GCC: (GNU) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)GCC: (GNU) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)GCC: (GNU) 3.2 20020903 (Red Hat Linux 8.0 3.2-7), 0̄ 8#. Ćy@?$|>G! _IO_stdin_used.  main|SHPOpenSHPCloseSHPGetInfojSHPCreateTSHPComputeExtentsSHPCreateObjectvSHPCreateSimpleObjectSHPWriteObjectSHPReadObjectSHPTypeNameSHPPartTypeName SHPDestroyObject4SHPRewindObject 88o# <NM<#LSLintuEFS#w#RS#0$*+S#,S#-Z#.S# /S#&00#N1S#27#30# _ ^ <:u#M;d# T ^CBS#SNS#OS#@Pd#QS#  Ru#Zt YS#Vb d}eu#fS#gd# P hd#id#jS#kS#{t?rS#sS#l}u#l~S#S# d#S# N 8L %MM  L5OIS#N#Z <Z#*#H#<!#*"#X&J))zy 8a:B#g#h#i-#j7# Zk3#mSmD7 sD8?>r?#sE#uS#wP# JxP#z#{#T|#S# #S#$S#(=S#,WS#07#4 J$@##S#S# S#f#*#3#     0 :S7 -7 !   9 K   SmDSS VSm m  0#m##JL(,42#3J# G,5 / 4_R !o!"R# j%&v12 3,4o(5Sb6R8^92;( =>v ?v@ AvBvHC DESPFS/G^HvIv N%QS RP STRdUVX[SM^SeSuhoZlqruvvyzr}X{i2YSR# ^4<95CjFRiSZ^Sc l+tVyO Sm{7|&MAROb5#aH V2K BL U :@Z ^  . SE.  4 EaE K ` S` E 7bq ! C5(78S 9o:R] dSS 3/usr/src/build/148620-i386/BUILD/glibc-2.2.93/csuGNU AS 2.13.90.0.2=Ć # <NM<#LSLintuEFS#w#RS#0$*+S#,S#-Z#.S# /S#&00#N1S#27#30# _ ^ <:u#M;d# T ^CBS#SNS#OS#@Pd#QS#  Ru#Zt YS# N 8L %M MLIOIS#N#n <n#*$#H#<!#*"$#X&J))zy 8aNB#g#h/#iA#j7# ZkG#SX7 X8?>rS#sY#uS#wd# Jxd#z#{#T|#S# #S#$S#(=S#,WS#07#4 ^$@##S#S# S#f#*$#G#     0 N/S7  A7 5   M _ SXSS jS   $0###^L<,42#3^# [,5 / 4s [# +#=S# [+ .S#>  d#d# d# d d# d# d# d#~ d# S d#$ d#( d#,3#0i +#4 S#8K "S#< $n#@ (V#D)]#F *d#Gp.t#H7#Lp =7#Tw >7#Xa @S#\u Bv#` V    7 tL L3E l $ E # E # S# S# ' S#9 S# K #. K #J Q #  Q #@~ S#`< #d S#h  Sa a LD} h  S#$ S#R S#\ K #  K # S# } # } #V } #  } #$7 a #( a #0U a #8 a #@ a #H0 a #P a #X a #` a  s` D FQ #E GQ #  KS#@ LK #D M #HK OS#L P #P  h   L  b  \ Vb # XS# YS# [h #   X < fp E #' S# S# S#  S#~ K #P K # K #2 d#  d#$ S#(\ S#,k d#0 S#4~ S#8    *@  N  2SĆ=U 0S 0N   3b t 3b p4Sl4Shi4Sd$ 4S`5Q s5Q j]SH ^  d _ _    !V !"_ #   j%  &  v1] 2 3  ,4V (5S b6_ 8 ^9 2;'  = >| ?| @ A| B| HC  D ES PFS /G ^H vI| N% QS  Rd S T_ dU V X [S M^S eS uhV Zl q r u v vy z r} Xz i 2 YS _ # ^ 4 <9 5Cj F_ iS Z ^S  . >!| &!M A_ O$ bI #u H j 2K  BL  U N @Z   ^ SY   Y a $9S9Y 7 bJ 5 [  C5< 7 8S  9V :_ +  # "Y ! G g ! ^7dT ! g7YT !| o :S7:S !] rL\S7 e Xq ҆ } g!- h ! R ! \ ! n !  ! X x` @@ # <NM<#LSLintuEFS#w#RS#0$*+S#,S#-Z#.S# /S#&00#N1S#27#30# _ ^ <:u#M;d# T ^CBS#SNS#OS#@Pd#QS#  Ru#Zt YS# N 8L %M MLIOIS#N#n <n#*$#H#<!#*"$#X&J))zy 8aNB#g#h/#iA#j7# ZkG#SX7 X8?>rS#sY#uS#wd# Jxd#z#{#T|#S# #S#$S#(=S#,WS#07#4 ^$@##S#S# S#f#*$#G#     0 N/S7  A7 5   M _ SXSS jS   $0###^L<,42#3^# [,5 / 4s [# +#=S# [+ .S#>  d#d# d# d d# d# d# d#~ d# S d#$ d#( d#,3#0i +#4 S#8K "S#< $n#@ (V#D)]#F *d#Gp.t#H7#Lp =7#Tw >7#Xa @S#\u Bv#` V    7 tL L3E l $ E # E # S# S# ' S#9 S# K #. K #J Q #  Q #@~ S#`< #d S#h  Sa a LD} h  S#$ S#R S#\ K #  K # S# } # } #V } #  } #$7 a #( a #0U a #8 a #@ a #H0 a #P a #X a #` a  s` D FQ #E GQ #  KS#@ LK #D M #HK OS#L P #P  h   L  b  \ Vb # XS# YS# [h #   X < fp E #' S# S# S#  S#~ K #P K # K #2 d#  d#$ S#(\ S#,k d#0 S#4~ S#8    *@    V'  [ S# d# a #l a # a #%  c aS#rem bS#J  k i#rem j#a  a #q q L  uv #w#  DE #F #d N6K # L}J ' }# }# }#V S#  S# S#d }#  __x # #__c V#  V#__a #VLG@US7 iS| ;G{!7܈U7S 8܈Ub  iSi32 a ~  ~GLc/ "Wb U#MUY#|UY $Xdt$,Xdp$Yb l$A[h%i\Sd$]a X&N$T$P G'G+U#)b 'jO3U#Lb #LK  #LK #M} #rM} %iPSx"kb 4U#MiY#iS $,ldt$ldp%imSl$$nE h$ nE d$o~%i32p~$qa ~(TU#<#H   'I U# %iSt"v _U# S#$ S #R S#\ K # K # S# }  # } $#V } (# } ,$ x%iSt$!Sp$5Sl" `U# S# S # } # } #V } "`SU#b #$ S # $St%iSp$ Sl$<h%i32d) $`$R \%iSX&+$?T%i@SP" U#b #S $H  x)aiX$)t$R )p%i*Sl$*Sh)uϽ$h%iSd$S`&׿$ S`"FYU# DS" &YU# }S'4U#H  "zqS U# b #  $Sl$[Sh&$4Sd$S`$S\$SX$ST$a H$a @$a )Fm`$oS&V$S&%i!S&$&a L8 z*_ɦ* *!V*!"*#q *j%*&*v1]*2* 3*,4V*(5S*b6*8*^9*2;` *=*>* ?*@* A*B*HC* D*ES*PFS*/G*^H*vI* N%*QS* Rd* S*T*dU*V*X*[S*M^S*eS*uhV*Zl*q*r*u*v*vy*z*r}*X*i*2q *YS**# ^*4*<9*5Cj*F*iS*Z*^S*q * .* >+|&+MA*O$*bI*#u*H j*2K *BL *U N*@Z  *^  &@SY@ F Y*aW ]rSrY 7*b 5* *C5<*7*8S* 9V*:* +  # ,Y + G g + ^ '7d+ g3M7Y+| oYsS7sS +] rS7*e X* ҆* Զ +- h + R + \ + n +  + X +;  *v c *u k% *"*#*#$*%*n&*l'*(* -*1*=f* B|* G*L*Qq* W*{c*%h*Rm* s* t *zc* L* \M*OhX*q *V**]* *S*a**V*Ʀ*]*gS* S* J *&*f1,*7*N *U***x+& 2 8MSMM S-**/S SxS  /usr/src/build/148620-i386/BUILD/glibc-2.2.93/csuGNU AS 2.13.90.0.2%  : ;  : ; I8 I!I/ $ > $ >  : ;  <  I  : ; : ; I : ; ( ' II&I' !I: ; I5I: ;I4: ; I?  %%  : ;  : ; I8 I!I/ $ > $ >  : ;  <  I  : ; : ; I : ; ( ' II&I' !I : ;I8  : ;  : ; : ; : ;I8  : ;.? : ; ' I@ : ; I 4: ; I 4: ; I   : ; I!: ;I": ; %  : ;  : ; I8 I!I/ $ > $ >  : ;  <  I  : ; : ; I : ; ( ' II&I' !I : ;I8  : ;  : ; : ; : ;I8  : ;(  : ; I8 .: ; ' @ : ; I 4: ; I 4: ; I !.: ; ' I@ ".? : ;' I@ #: ;I $4: ;I %4: ;I & '.? : ;' @ (.: ;' @ ) *: ; I+: ;I,: ; -&%/) init.c../sysdeps/unix/sysv/linux/bits/types.h../sysdeps/unix/sysv/linux/bits/sched.h../linuxthreads/sysdeps/pthread/bits/pthreadtypes.h../wcsmbs/wchar.h../sysdeps/gnu/_G_config.h../iconv/gconv.h/usr/lib/gcc-lib/i386-redhat-linux/3.2/include/stddef.hm# /tmp/ccnhFcil.s0,W̄3,:8,Wdd,,-:} shprewind.c/usr/include/bits/types.h/usr/include/bits/sched.h/usr/include/bits/pthreadtypes.h/usr/include/wchar.h/usr/include/_G_config.h/usr/include/gconv.h/usr/include/libio.h/usr/include/stdio.hshapefil.h/usr/lib/gcc-lib/i386-redhat-linux/3.2/include/stddef.h/usr/lib/gcc-lib/i386-redhat-linux/3.2/include/stdarg.hĆ1weerer:HV,w q- m5 shpopen.c/usr/include/bits/types.h/usr/include/bits/sched.h/usr/include/bits/pthreadtypes.h/usr/include/wchar.h/usr/include/_G_config.h/usr/include/gconv.h/usr/include/libio.h/usr/include/stdio.hshapefil.h/usr/include/math.h/usr/include/stdlib.h/usr/include/bits/sigset.h/usr/include/time.h/usr/include/bits/time.h/usr/include/sys/select.h/usr/lib/gcc-lib/i386-redhat-linux/3.2/include/stddef.h/usr/lib/gcc-lib/i386-redhat-linux/3.2/include/stdarg.h/usr/include/sys/types.h@gǪr'w 9dd-: U tHIVrrrrHHHHHHHH:LrHZe31#&  q qEvrdBVVVXԺVdVfԺ;DI4պB*fսrrrrrrrrٹ44+gruq d g +tddd#d# x q rdBVVdVVdtrs:ZZ dd::; 9eTTTTVVVv_ urrrx/#d%zcqVVVW;,,,y,:cd$ +.2v/+ =Irsw;#` q;` qe$;eucee;_ q%eee_ qIse''#z# ee;_yJeee_ qsf #d[r;Vsv2ԺqeTTTT_eewe d w,%, =VVVWVWbw# v# v;/2#u#2# x *;2#  qVVVW;**#z# 2# x *;2#  qHHHIv cd dts UdP> ğd 0(Px+!> (ȁڃ4< ̄   0 `<@t !8 #.<J<]jntz\  # <  9@c 8 ܈ $x/ =Jd Z@c t%`b `, \ ̄  $4! (D: S JtVĆy [TxdQ t90 '4     t4ąD|I Xԅidx4 q !  0init.cinitfini.ccall_gmon_startcrtstuff.c__CTOR_LIST____DTOR_LIST____EH_FRAME_BEGIN____JCR_LIST__p.0completed.1__do_global_dtors_auxframe_dummy__CTOR_END____DTOR_END____FRAME_END____JCR_END____do_global_ctors_auxshprewind.cshpopen.crcsidSwapWordSfReallocSHPWriteHeaderbBigEndian_SHPSetBounds__dso_handleSHPRewindObject_DYNAMICSHPDestroyObjectstrcmp@@GLIBC_2.0_fp_hw__assert_fail@@GLIBC_2.0SHPComputeExtentsSHPCreateSimpleObjectSHPPartTypeName_initSHPClosemalloc@@GLIBC_2.0fread@@GLIBC_2.0fseek@@GLIBC_2.0_startstrlen@@GLIBC_2.0SHPCreateObject__bss_startmain__libc_start_main@@GLIBC_2.0realloc@@GLIBC_2.0data_startprintf@@GLIBC_2.0_finimemcpy@@GLIBC_2.0fclose@@GLIBC_2.1SHPCreateSHPGetInfoexit@@GLIBC_2.0calloc@@GLIBC_2.0SHPReadObject_edata_GLOBAL_OFFSET_TABLE_free@@GLIBC_2.0_endSHPWriteObjectfopen@@GLIBC_2.1_IO_stdin_usedsprintf@@GLIBC_2.0SHPTypeNamefwrite@@GLIBC_2.0__data_start_Jv_RegisterClassesSHPOpen__gmon_start__strcpy@@GLIBC_2.0