Upgrade shapelib to 1.2.10
This commit is contained in:
parent
ba5a9b363e
commit
d5da7c56f6
23 changed files with 3996 additions and 895 deletions
BIN
src/Lib/shapelib-1.2.10.tar.gz
Normal file
BIN
src/Lib/shapelib-1.2.10.tar.gz
Normal file
Binary file not shown.
Binary file not shown.
|
@ -1,3 +1,201 @@
|
|||
2003-04-07 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* Issue 1.2.10 Release.
|
||||
|
||||
2003-03-10 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* dbfopen.c: modified DBFWriteAttribute call so that it returns FALSE
|
||||
if it has to truncate the input value.
|
||||
|
||||
2003-01-28 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* shptree.c: avoid build warnings.
|
||||
|
||||
2002-05-07 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* 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 <warmerdam@pobox.com>
|
||||
|
||||
* shpopen.c: Added SHPRewindObject() to correct ring winding.
|
||||
|
||||
* shprewind.c: New utility program.
|
||||
|
||||
2002-03-12 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* shapelib.def: added DBFWriteNULLAttribute.
|
||||
|
||||
2002-01-17 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* contrib/ShapeFileII.pas: Contributed Delphi Pascal interface
|
||||
to Shapelib.
|
||||
|
||||
2002-01-15 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* 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 <warmerdam@pobox.com>
|
||||
|
||||
* 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 <warmerdam@pobox.com>
|
||||
|
||||
* dbfopen.c: two fixes for compiler warnings as suggested by
|
||||
Richard Hash.
|
||||
|
||||
2001-11-01 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* 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 <warmerdam@pobox.com>
|
||||
|
||||
* Issue Shapelib 1.2.9
|
||||
|
||||
* shputils.c: DBFAddField() call should check for -1 return value
|
||||
for failure.
|
||||
|
||||
2001-07-03 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* shpopen.c: cleanup better if SHX missing, provided by
|
||||
Riccardo Cohen.
|
||||
|
||||
2001-06-21 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* 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 <warmerdam@pobox.com>
|
||||
|
||||
* dbfopen.c: ensure binary mode open.
|
||||
|
||||
2001-05-31 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* 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 <warmerdam@pobox.com>
|
||||
|
||||
* shpopen.c: add some checking on the record count to ensure it
|
||||
is reasonable.
|
||||
|
||||
2001-05-23 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* shapefile.h, shpopen.c, dbfopen.c, shptree.c: added the SHPAPI_CALL
|
||||
macro to allow compilation with _stdcall conventions.
|
||||
|
||||
2001-02-06 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* Fixed a few memory leaks when SHPOpen() fails.
|
||||
|
||||
2000-12-05 Frank Warmerdam <warmerdam@pobox.com>
|
||||
|
||||
* Fix from Craig Bruce (Cubewerx) for DBFReadAttribute() for
|
||||
the white space trimming code to avoid reading outside allocated
|
||||
memory.
|
||||
|
||||
2000-11-02 Frank Warmerdam <warmerda@cs46980-c>
|
||||
|
||||
* Checked in upgraded shputils.c from Bill Miller.
|
||||
|
||||
2000-10-05 Frank Warmerdam <warmerda@cs46980-c>
|
||||
|
||||
* 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 <kirk@rsinc.com>.
|
||||
|
||||
2000-09-25 Frank Warmerdam <warmerda@cs46980-c>
|
||||
|
||||
* Added DBFGetNativeFieldType() (contributed by Daniel) to dbfopen.c.
|
||||
|
||||
2000-07-18 Frank Warmerdam <warmerda@cs46980-c>
|
||||
|
||||
* added better enforcement of -1 for append in SHPWriteObject().
|
||||
|
||||
2000-07-07 Frank Warmerdam <warmerda@cs46980-c>
|
||||
|
||||
* 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 <warmerda@cs46980-c>
|
||||
|
||||
* Added logic to shpadd to grow vertex lists at the suggestion of
|
||||
Santiago Nullo <sn@softhome.net>.
|
||||
|
||||
2000-05-23 Frank Warmerdam <warmerda@cs46980-c>
|
||||
|
||||
* 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 <warmerda@cs46980-c>
|
||||
|
||||
* Release as 1.2.8.
|
||||
|
||||
* Incorporated a -version-info fix and added mkinstalldirs from Jan.
|
||||
|
||||
2000-03-17 Frank Warmerdam <warmerda@cs46980-c>
|
||||
|
||||
* Added shared library hack to Makefile.
|
||||
|
||||
* Fixed up test scripts to look in ./ for executables.
|
||||
|
||||
Wed Feb 16 11:20:29 2000 Frank Warmerdam <warmerda@gdal.velocet.ca>
|
||||
|
||||
* 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 <warmerda@gdal.velocet.ca>
|
||||
|
||||
* 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 <warmerda@gdal.velocet.ca>
|
||||
|
||||
* Added support for uppercase .DBF extention c/o
|
||||
Dennis Christopher <dennis@avenza.com>
|
||||
|
||||
Fri Nov 5 09:12:31 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
|
||||
|
||||
* Updated license headers to include the option of use of the code
|
||||
under the LGPL.
|
||||
|
||||
1999-09-15 <warmerda@CS46980-B>
|
||||
|
||||
* Added shapelib.dll target to makefile.vc.
|
||||
|
||||
Mon May 10 23:19:42 1999 Frank Warmerdam <warmerda@gdal.velocet.ca>
|
||||
|
||||
* 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 <warmerda@gdal.velocet.ca>
|
||||
|
||||
* Prepare 1.2.5 release.
|
||||
|
|
|
@ -80,6 +80,22 @@ int DBFGetRecordCount( DBFHandle hDBF );
|
|||
|
||||
<!-------------------------------------------------------------------------->
|
||||
|
||||
<h2>DBFGetFieldIndex()</h2>
|
||||
|
||||
<pre>
|
||||
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.
|
||||
</pre>
|
||||
|
||||
Returns the index of the field matching this name, or -1 on failure. The
|
||||
comparison is case insensitive. However, lengths must match exactly.<p>
|
||||
|
||||
<!-------------------------------------------------------------------------->
|
||||
|
||||
<h2>DBFGetFieldInfo()</h2>
|
||||
|
||||
<pre>
|
||||
|
@ -119,6 +135,7 @@ DBFFieldType DBFGetFieldInfo( DBFHandle hDBF, int iField, char * pszFieldName,
|
|||
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;
|
||||
</pre>
|
||||
|
@ -145,7 +162,8 @@ int DBFAddField( DBFHandle hDBF, const char * pszFieldName,
|
|||
|
||||
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 largest number that can
|
||||
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.
|
||||
|
@ -232,6 +250,28 @@ const char *DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
|
|||
|
||||
<!-------------------------------------------------------------------------->
|
||||
|
||||
<h2>DBFIsAttributeNULL()</h2>
|
||||
|
||||
<pre>
|
||||
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.
|
||||
</pre>
|
||||
|
||||
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.<p>
|
||||
|
||||
<!-------------------------------------------------------------------------->
|
||||
|
||||
<h2>DBFWriteIntegerAttribute</h2>
|
||||
|
||||
<pre>
|
||||
|
@ -251,8 +291,8 @@ int DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField,
|
|||
|
||||
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. The value may be truncated
|
||||
without warning if written to a field to narrow to represent the value.<p>
|
||||
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.<p>
|
||||
|
||||
<!-------------------------------------------------------------------------->
|
||||
|
||||
|
@ -275,8 +315,8 @@ int DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField,
|
|||
|
||||
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. The value may be truncated
|
||||
without warning if written to a field to narrow to represent the value.<p>
|
||||
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.<p>
|
||||
|
||||
<!-------------------------------------------------------------------------->
|
||||
|
||||
|
@ -299,8 +339,29 @@ int DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField,
|
|||
|
||||
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. The value may be truncated
|
||||
without warning if written to a field to narrow to hold the string.<p>
|
||||
otherwise FALSE will be returned. If the value is too large to
|
||||
fit in the field, it will be truncated and FALSE returned.<p>
|
||||
|
||||
<!-------------------------------------------------------------------------->
|
||||
|
||||
<h2>DBFWriteNULLAttribute()</h2>
|
||||
|
||||
<pre>
|
||||
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.
|
||||
</pre>
|
||||
|
||||
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.<p>
|
||||
|
||||
<!-------------------------------------------------------------------------->
|
||||
|
||||
|
@ -318,5 +379,30 @@ void DBFClose( DBFHandle hDBF );
|
|||
The file handle (hDBF) should not be used again with the DBF API after
|
||||
calling DBFClose().<p>
|
||||
|
||||
<!-------------------------------------------------------------------------->
|
||||
|
||||
<h2>DBFGetNativeFieldType()</h2>
|
||||
|
||||
<pre>
|
||||
char DBFGetNativeFieldType( DBFHandle hDBF, int iField );
|
||||
|
||||
hDBF: The access handle for the file.
|
||||
iField: The field index to query.
|
||||
|
||||
</pre>
|
||||
|
||||
This function returns the DBF type code of the indicated field. It will
|
||||
be one of:<p>
|
||||
|
||||
<ul>
|
||||
<li> 'C' (String)
|
||||
<li> 'D' (Date)
|
||||
<li> 'F' (Float)
|
||||
<li> 'N' (Numeric, with or without decimal)
|
||||
<li> 'L' (Logical)
|
||||
<li> 'M' (Memo: 10 digits .DBT block ptr)
|
||||
<li> ' ' (field out of range)
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,14 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 1995 Frank Warmerdam
|
||||
/******************************************************************************
|
||||
* $Id: dbfadd.c,v 1.7 2002/01/15 14:36:07 warmerda Exp $
|
||||
*
|
||||
* This code is in the public domain.
|
||||
* 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.1 2000-02-09 19:51:46 curt
|
||||
* Initial revision
|
||||
* Revision 1.7 2002/01/15 14:36:07 warmerda
|
||||
* updated email address
|
||||
*
|
||||
* Revision 1.1 1999/08/24 21:13:00 curt
|
||||
* Initial revision.
|
||||
* 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.
|
||||
|
@ -22,7 +55,7 @@
|
|||
*/
|
||||
|
||||
static char rcsid[] =
|
||||
"$Id: dbfadd.c,v 1.1 2000-02-09 19:51:46 curt Exp $";
|
||||
"$Id: dbfadd.c,v 1.7 2002/01/15 14:36:07 warmerda Exp $";
|
||||
|
||||
#include "shapefil.h"
|
||||
#include <math.h>
|
||||
|
@ -71,7 +104,9 @@ int main( int argc, char ** argv )
|
|||
/* -------------------------------------------------------------------- */
|
||||
for( i = 0; i < DBFGetFieldCount(hDBF); i++ )
|
||||
{
|
||||
if( DBFGetFieldInfo( hDBF, i, NULL, NULL, NULL ) == FTString )
|
||||
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]) );
|
||||
|
|
|
@ -1,14 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 1995 Frank Warmerdam
|
||||
/******************************************************************************
|
||||
* $Id: dbfcreate.c,v 1.6 2002/01/15 14:36:07 warmerda Exp $
|
||||
*
|
||||
* This code is in the public domain.
|
||||
* 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.1 2000-02-09 19:51:46 curt
|
||||
* Initial revision
|
||||
* Revision 1.6 2002/01/15 14:36:07 warmerda
|
||||
* updated email address
|
||||
*
|
||||
* Revision 1.1 1999/08/24 21:13:00 curt
|
||||
* Initial revision.
|
||||
* 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.
|
||||
|
@ -19,17 +52,17 @@
|
|||
*/
|
||||
|
||||
static char rcsid[] =
|
||||
"$Id: dbfcreate.c,v 1.1 2000-02-09 19:51:46 curt Exp $";
|
||||
"$Id: dbfcreate.c,v 1.6 2002/01/15 14:36:07 warmerda Exp $";
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "shapefil.h"
|
||||
|
||||
int main( int argc, char ** argv )
|
||||
|
||||
{
|
||||
DBFHandle hDBF;
|
||||
int *panWidth, i, iRecord;
|
||||
char szFormat[32], szField[1024];
|
||||
int nWidth, nDecimals;
|
||||
int i;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Display a usage message. */
|
||||
|
|
|
@ -1,14 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 1995 Frank Warmerdam
|
||||
/******************************************************************************
|
||||
* $Id: dbfdump.c,v 1.9 2002/01/15 14:36:07 warmerda Exp $
|
||||
*
|
||||
* This code is in the public domain.
|
||||
* 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.1 2000-02-09 19:51:46 curt
|
||||
* Initial revision
|
||||
* Revision 1.9 2002/01/15 14:36:07 warmerda
|
||||
* updated email address
|
||||
*
|
||||
* Revision 1.1 1999/08/24 21:13:00 curt
|
||||
* Initial revision.
|
||||
* 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.
|
||||
|
@ -22,8 +61,10 @@
|
|||
*/
|
||||
|
||||
static char rcsid[] =
|
||||
"$Id: dbfdump.c,v 1.1 2000-02-09 19:51:46 curt Exp $";
|
||||
"$Id: dbfdump.c,v 1.9 2002/01/15 14:36:07 warmerda Exp $";
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "shapefil.h"
|
||||
|
||||
int main( int argc, char ** argv )
|
||||
|
@ -31,7 +72,7 @@ int main( int argc, char ** argv )
|
|||
{
|
||||
DBFHandle hDBF;
|
||||
int *panWidth, i, iRecord;
|
||||
char szFormat[32], szField[1024], *pszFilename = NULL;
|
||||
char szFormat[32], *pszFilename = NULL;
|
||||
int nWidth, nDecimals;
|
||||
int bHeader = 0;
|
||||
int bRaw = 0;
|
||||
|
@ -159,25 +200,40 @@ int main( int argc, char ** argv )
|
|||
/* -------------------------------------------------------------------- */
|
||||
if( !bRaw )
|
||||
{
|
||||
switch( eType )
|
||||
if( DBFIsAttributeNULL( hDBF, iRecord, i ) )
|
||||
{
|
||||
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;
|
||||
if( eType == FTString )
|
||||
sprintf( szFormat, "%%-%ds", nWidth );
|
||||
else
|
||||
sprintf( szFormat, "%%%ds", nWidth );
|
||||
|
||||
case FTDouble:
|
||||
sprintf( szFormat, "%%%d.%dlf", nWidth, nDecimals );
|
||||
printf( szFormat,
|
||||
DBFReadDoubleAttribute( hDBF, iRecord, i ) );
|
||||
break;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,5 +14,8 @@ 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
|
||||
|
|
|
@ -1,17 +1,95 @@
|
|||
#ifndef _SHAPEFILE_H_INCLUDED
|
||||
#define _SHAPEFILE_H_INCLUDED
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 Frank Warmerdam
|
||||
/******************************************************************************
|
||||
* $Id: shapefil.h,v 1.26 2002/09/29 00:00:08 warmerda Exp $
|
||||
*
|
||||
* This code is in the public domain.
|
||||
* 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.1 2000-02-09 19:51:46 curt
|
||||
* Initial revision
|
||||
* Revision 1.26 2002/09/29 00:00:08 warmerda
|
||||
* added FTLogical and logical attribute read/write calls
|
||||
*
|
||||
* Revision 1.1 1999/08/24 21:13:01 curt
|
||||
* Initial revision.
|
||||
* 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.
|
||||
|
@ -45,7 +123,7 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Configuration options. */
|
||||
/************************************************************************/
|
||||
|
@ -63,6 +141,48 @@ extern "C" {
|
|||
/* -------------------------------------------------------------------- */
|
||||
#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. */
|
||||
/************************************************************************/
|
||||
|
@ -84,6 +204,9 @@ typedef struct
|
|||
double adBoundsMax[4];
|
||||
|
||||
int bUpdated;
|
||||
|
||||
unsigned char *pabyRec;
|
||||
int nBufSize;
|
||||
} SHPInfo;
|
||||
|
||||
typedef SHPInfo * SHPHandle;
|
||||
|
@ -91,6 +214,7 @@ typedef SHPInfo * SHPHandle;
|
|||
/* -------------------------------------------------------------------- */
|
||||
/* Shape types (nSHPType) */
|
||||
/* -------------------------------------------------------------------- */
|
||||
#define SHPT_NULL 0
|
||||
#define SHPT_POINT 1
|
||||
#define SHPT_ARC 3
|
||||
#define SHPT_POLYGON 5
|
||||
|
@ -152,27 +276,105 @@ typedef struct
|
|||
/* -------------------------------------------------------------------- */
|
||||
/* SHP API Prototypes */
|
||||
/* -------------------------------------------------------------------- */
|
||||
SHPHandle SHPOpen( const char * pszShapeFile, const char * pszAccess );
|
||||
SHPHandle SHPCreate( const char * pszShapeFile, int nShapeType );
|
||||
void SHPGetInfo( SHPHandle hSHP, int * pnEntities, int * pnShapeType,
|
||||
double * padfMinBound, double * padfMaxBound );
|
||||
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 *SHPReadObject( SHPHandle hSHP, int iShape );
|
||||
int SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject );
|
||||
SHPObject SHPAPI_CALL1(*)
|
||||
SHPReadObject( SHPHandle hSHP, int iShape );
|
||||
int SHPAPI_CALL
|
||||
SHPWriteObject( SHPHandle hSHP, int iShape, SHPObject * psObject );
|
||||
|
||||
void SHPDestroyObject( SHPObject * psObject );
|
||||
void SHPComputeExtents( SHPObject * psObject );
|
||||
SHPObject *SHPCreateObject( int nSHPType, int nShapeId,
|
||||
int nParts, int * panPartStart, int * panPartType,
|
||||
int nVertices, double * padfX, double * padfY,
|
||||
double * padfZ, double * padfM );
|
||||
SHPObject *SHPCreateSimpleObject( int nSHPType, int nVertices,
|
||||
double * padfX, double * padfY, double * padfZ );
|
||||
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 );
|
||||
|
||||
void SHPClose( SHPHandle hSHP );
|
||||
int SHPAPI_CALL
|
||||
SHPRewindObject( SHPHandle hSHP, SHPObject * psObject );
|
||||
|
||||
const char *SHPTypeName( int nSHPType );
|
||||
const char *SHPPartTypeName( int nPartType );
|
||||
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. */
|
||||
|
@ -207,33 +409,73 @@ typedef enum {
|
|||
FTString,
|
||||
FTInteger,
|
||||
FTDouble,
|
||||
FTLogical,
|
||||
FTInvalid
|
||||
} DBFFieldType;
|
||||
|
||||
DBFHandle DBFOpen( const char * pszDBFFile, const char * pszAccess );
|
||||
DBFHandle DBFCreate( const char * pszDBFFile );
|
||||
#define XBASE_FLDHDR_SZ 32
|
||||
|
||||
int DBFGetFieldCount( DBFHandle psDBF );
|
||||
int DBFGetRecordCount( DBFHandle psDBF );
|
||||
int DBFAddField( DBFHandle hDBF, const char * pszFieldName,
|
||||
DBFFieldType eType, int nWidth, int nDecimals );
|
||||
DBFHandle SHPAPI_CALL
|
||||
DBFOpen( const char * pszDBFFile, const char * pszAccess );
|
||||
DBFHandle SHPAPI_CALL
|
||||
DBFCreate( const char * pszDBFFile );
|
||||
|
||||
DBFFieldType DBFGetFieldInfo( DBFHandle psDBF, int iField,
|
||||
char * pszFieldName,
|
||||
int * pnWidth, int * pnDecimals );
|
||||
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 );
|
||||
|
||||
int DBFReadIntegerAttribute( DBFHandle hDBF, int iShape, int iField );
|
||||
double DBFReadDoubleAttribute( DBFHandle hDBF, int iShape, int iField );
|
||||
const char *DBFReadStringAttribute( DBFHandle hDBF, int iShape, int iField );
|
||||
DBFFieldType SHPAPI_CALL
|
||||
DBFGetFieldInfo( DBFHandle psDBF, int iField,
|
||||
char * pszFieldName, int * pnWidth, int * pnDecimals );
|
||||
|
||||
int DBFWriteIntegerAttribute( DBFHandle hDBF, int iShape, int iField,
|
||||
int nFieldValue );
|
||||
int DBFWriteDoubleAttribute( DBFHandle hDBF, int iShape, int iField,
|
||||
double dFieldValue );
|
||||
int DBFWriteStringAttribute( DBFHandle hDBF, int iShape, int iField,
|
||||
const char * pszFieldValue );
|
||||
int SHPAPI_CALL
|
||||
DBFGetFieldIndex(DBFHandle psDBF, const char *pszFieldName);
|
||||
|
||||
void DBFClose( DBFHandle hDBF );
|
||||
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
|
||||
}
|
||||
|
|
|
@ -12,34 +12,6 @@ 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).<p>
|
||||
|
||||
|
||||
<h2>Copyright</h2>
|
||||
|
||||
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. <p>
|
||||
|
||||
<quote>
|
||||
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:<p>
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.<p>
|
||||
|
||||
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.<p>
|
||||
</quote>
|
||||
|
||||
<h2>Manifest</h2>
|
||||
|
||||
<ul>
|
||||
|
@ -59,6 +31,9 @@ for the API for accessing the .dbf attribute files. <p>
|
|||
<li> <b>shapefil.h</b>: Include file defining all the services of dbfopen.c
|
||||
and shpopen.c.<p>
|
||||
|
||||
<li> <b>contrib/</b>: A directory of "in progress" contributed programs
|
||||
from Carl Anderson.<p>
|
||||
|
||||
<li> <b>dbfcreate.c</b>: Simple example program for creating a new .dbf file.
|
||||
<p>
|
||||
|
||||
|
@ -91,6 +66,13 @@ programs.<p>
|
|||
<li> <b>shptest.c</b>: A simple test harnass to generate each of the supported
|
||||
types of shapefiles. <p>
|
||||
|
||||
|
||||
<li> <b>shptree.c</b>: Implements a simple quadtree algorithm for fast
|
||||
spatial searches of shapefiles.<p>
|
||||
|
||||
<li> <b>shptreedump.c</b>: A simple mainly showing information on quad
|
||||
trees build using the quad tree api.<p>
|
||||
|
||||
<li> <b>stream1.sh</b> - A test script, which should produce stream1.out.
|
||||
Note this will only work if you have the example data downloaded.<p>
|
||||
|
||||
|
@ -99,6 +81,9 @@ Note this will only work if you have the example data downloaded.<p>
|
|||
<li> <b>stream2.sh</b>: A test script, which should produce stream2.out.<p>
|
||||
|
||||
<li> <b>stream2.out</b>: Expected output of stream2.sh test script.<p>
|
||||
|
||||
<li> <b>pyshapelib-0.1</b>: Prototype contributed Python bindings.<p>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>What is a Shapefile?</h2>
|
||||
|
@ -122,8 +107,38 @@ XXX.dbf - holds the attributes in xBase (dBase) format.
|
|||
|
||||
<h2>Release Notes</h2>
|
||||
|
||||
To get notification of new releases of Shapelib <i>subscribe</i> 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.<p>
|
||||
|
||||
<b>Release 1.2.10</b>: Added SHPRewindObject() function, and shprewind utility
|
||||
program. Added FTLogical, DBFReadLogicalAttribute() and
|
||||
DBFWriteLogicalAttribute() (thanks to Olek Neyman). <p>
|
||||
|
||||
<b>Release 1.2.9</b>: 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).<p>
|
||||
|
||||
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.
|
||||
<p>
|
||||
|
||||
<b>Release 1.2.8</b>: Added hacked libtool support (supplied by Jan)
|
||||
and "rpm ready" install logic.<p>
|
||||
|
||||
<b>Release 1.2.7</b>: 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.<p>
|
||||
|
||||
<b>Release 1.2.6</b>: 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.<p>
|
||||
|
||||
<b>Release 1.2.5</b>: SHPOpen() now forcably uses "rb" or "r+b" access string
|
||||
to avoid common mistakes on Windows.<p>
|
||||
to avoid common mistakes on Windows. Also fixed a serious bug with .dbf
|
||||
files with a 'F' field type.<p>
|
||||
|
||||
<b>Release 1.2.4</b>: DBFOpen() will now automatically translate a .shp
|
||||
extension to .dbf for convenience. SHPOpen() will try datasets with lower
|
||||
|
@ -153,16 +168,51 @@ documentation.<p>
|
|||
|
||||
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
|
||||
warmerda@home.com.<p>
|
||||
warmerdam@pobox.com.<p>
|
||||
|
||||
The current status of the Shapelib code can be found somewhere off my
|
||||
home page at http://members.home.com/warmerda.<p>
|
||||
The current status of the Shapelib code can be found at
|
||||
<a href="http://pobox.com/~warmerdam/root/projects/shapelib/">
|
||||
http://pobox.com/~warmerdam/root/projects/shapelib/</a>. To find out about
|
||||
new releases of Shapelib, select the "Subscribe to new releases" option
|
||||
from the link at
|
||||
<a href="http://freshmeat.net/projects/shapelib/">Freshmeat</a>.<p>
|
||||
|
||||
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.<p>
|
||||
|
||||
<h2>Credits</h2>
|
||||
|
||||
I didn't start this section anywhere near soon enough, so alot of earlier
|
||||
contributors to Shapelib are lost in pre-history.
|
||||
|
||||
<ul>
|
||||
<li> Bill Miller (NY-DOT) for shputils.c
|
||||
<li> Carl Anderson for the contents of the contrib directory, and
|
||||
the "tuple" additions to dbfopen.c.
|
||||
<li> Andrea Giacomelli for patches for dbfopen.c.
|
||||
<li> Doug Matthews for portability improvements.
|
||||
<li> Jan-Oliver Wagner for convincing me to make it available under LGPL,
|
||||
shared library support, and various other patches.
|
||||
<li> Dennis Christopher (of Avenza) for testing and bug fixes.
|
||||
<li> Miko Syrjä (of 3D-system Oy) for a record size bug fix.
|
||||
<li> Steven Lime and Curtis Hill for help with NULL shapes.
|
||||
<li> Jim Matthews for support of NULL attributes in dbf files.
|
||||
<li> <a href="http://www.pcigeomatics.com/">PCI Geomatics</a> who let me
|
||||
release a modified version of their shapefile code in the beginning and
|
||||
who hosted shapelib for years.
|
||||
</ul>
|
||||
|
||||
<h2>In Memorium</h2>
|
||||
|
||||
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.<p>
|
||||
|
||||
<h2>Portability</h2>
|
||||
|
||||
The Shapefile C Library should port easily to 32bit systems with ANSI C
|
||||
|
@ -175,6 +225,10 @@ such as MSDOS.<p>
|
|||
The shputils.c module is contributed, and may not take the same approach
|
||||
to portability as the rest of the package.<p>
|
||||
|
||||
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.
|
||||
|
||||
<h2>Limitations</h2>
|
||||
|
||||
|
@ -203,8 +257,76 @@ not used by ESRI.<p>
|
|||
<li> The application must keep the .dbf file in sync with the .shp/.shx
|
||||
files through appropriate use of the DBF and SHP APIs.<p>
|
||||
|
||||
<li> No support for the undocumented .sbn/.sbx spatial index files.<p>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Copyright</h2>
|
||||
|
||||
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. <p>
|
||||
|
||||
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.<p>
|
||||
|
||||
<h3>Default License Terms</h3>
|
||||
|
||||
<quote>
|
||||
Copyright (c) 1999, Frank Warmerdam<p>
|
||||
|
||||
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.<p>
|
||||
|
||||
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:<p>
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.<p>
|
||||
|
||||
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.<p>
|
||||
</quote>
|
||||
|
||||
<h3>Shapelib Modifications</h3>
|
||||
|
||||
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.<p>
|
||||
|
||||
<h3>Opting for LGPL</h3>
|
||||
|
||||
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.<p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
|
@ -17,9 +17,11 @@ accessed by the API functions. <p>
|
|||
|
||||
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. <p>
|
||||
a Shapefile must be of the same type (with the exception of NULL shapes). <p>
|
||||
|
||||
<pre>
|
||||
#define SHPT_NULL 0
|
||||
|
||||
2D Shape Types (pre ArcView 3.x):
|
||||
|
||||
#define SHPT_POINT 1 Points
|
||||
|
@ -161,6 +163,11 @@ SHPObject *SHPReadObject( SHPHandle hSHP, int iShape );
|
|||
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.<p>
|
||||
|
||||
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.<p>
|
||||
|
||||
<!-------------------------------------------------------------------------->
|
||||
|
||||
<h2>SHPClose()</h2>
|
||||
|
@ -347,5 +354,23 @@ void SHPDestroyObject( SHPObject *psObject );
|
|||
SHPCreateSimpleObject(), SHPCreateObject() and returned from SHPReadObject().
|
||||
<p>
|
||||
|
||||
<!-------------------------------------------------------------------------->
|
||||
|
||||
<h2>SHPRewindObject()</h2>
|
||||
|
||||
<pre>
|
||||
int SHPRewindObject( SHPHandle hSHP, SHPObject *psObject );
|
||||
|
||||
hSHP: The shapefile (not used at this time).
|
||||
psObject: The object to deallocate.
|
||||
</pre>
|
||||
|
||||
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.
|
||||
<p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,14 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 1995 Frank Warmerdam
|
||||
/******************************************************************************
|
||||
* $Id: shpadd.c,v 1.13 2002/01/15 14:36:07 warmerda Exp $
|
||||
*
|
||||
* This code is in the public domain.
|
||||
* 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.1 2000-02-09 19:51:46 curt
|
||||
* Initial revision
|
||||
* Revision 1.13 2002/01/15 14:36:07 warmerda
|
||||
* updated email address
|
||||
*
|
||||
* Revision 1.1 1999/08/24 21:13:01 curt
|
||||
* Initial revision.
|
||||
* 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.
|
||||
|
@ -34,22 +73,24 @@
|
|||
*/
|
||||
|
||||
static char rcsid[] =
|
||||
"$Id: shpadd.c,v 1.1 2000-02-09 19:51:46 curt Exp $";
|
||||
"$Id: shpadd.c,v 1.13 2002/01/15 14:36:07 warmerda Exp $";
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "shapefil.h"
|
||||
|
||||
int main( int argc, char ** argv )
|
||||
|
||||
{
|
||||
SHPHandle hSHP;
|
||||
int nShapeType, nVertices, nParts, *panParts, i;
|
||||
int nShapeType, nVertices, nParts, *panParts, i, nVMax;
|
||||
double *padfX, *padfY;
|
||||
SHPObject *psObject;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Display a usage message. */
|
||||
/* -------------------------------------------------------------------- */
|
||||
if( argc < 4 )
|
||||
if( argc < 2 )
|
||||
{
|
||||
printf( "shpadd shp_file [[x y] [+]]*\n" );
|
||||
exit( 1 );
|
||||
|
@ -68,11 +109,15 @@ int main( int argc, char ** argv )
|
|||
|
||||
SHPGetInfo( hSHP, NULL, &nShapeType, NULL, NULL );
|
||||
|
||||
if( argc == 2 )
|
||||
nShapeType = SHPT_NULL;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Build a vertex/part list from the command line arguments. */
|
||||
/* -------------------------------------------------------------------- */
|
||||
padfX = (double *) malloc(sizeof(double) * 1000);
|
||||
padfY = (double *) malloc(sizeof(double) * 1000);
|
||||
nVMax = 1000;
|
||||
padfX = (double *) malloc(sizeof(double) * nVMax);
|
||||
padfY = (double *) malloc(sizeof(double) * nVMax);
|
||||
|
||||
nVertices = 0;
|
||||
|
||||
|
@ -94,6 +139,13 @@ int main( int argc, char ** argv )
|
|||
}
|
||||
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;
|
||||
|
@ -114,4 +166,6 @@ int main( int argc, char ** argv )
|
|||
free( panParts );
|
||||
free( padfX );
|
||||
free( padfY );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,22 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 1995 Frank Warmerdam
|
||||
/******************************************************************************
|
||||
* $Id: shpcreate.c,v 1.5 2002/01/15 14:36:07 warmerda Exp $
|
||||
*
|
||||
* This code is in the public domain.
|
||||
* 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.1 2000-02-09 19:51:46 curt
|
||||
* Initial revision
|
||||
* Revision 1.5 2002/01/15 14:36:07 warmerda
|
||||
* updated email address
|
||||
*
|
||||
* Revision 1.1 1999/08/24 21:13:01 curt
|
||||
* Initial revision.
|
||||
* Revision 1.4 2000/07/07 13:39:45 warmerda
|
||||
* removed unused variables, and added system include files
|
||||
*
|
||||
* Revision 1.2 1995/08/04 03:16:43 warmerda
|
||||
* 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.1 2000-02-09 19:51:46 curt Exp $";
|
||||
"$Id: shpcreate.c,v 1.5 2002/01/15 14:36:07 warmerda Exp $";
|
||||
|
||||
#include "shapefil.h"
|
||||
|
||||
|
@ -25,7 +58,6 @@ int main( int argc, char ** argv )
|
|||
{
|
||||
SHPHandle hSHP;
|
||||
int nShapeType;
|
||||
double *padVertices;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Display a usage message. */
|
||||
|
@ -65,4 +97,6 @@ int main( int argc, char ** argv )
|
|||
}
|
||||
|
||||
SHPClose( hSHP );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 1995 Frank Warmerdam
|
||||
/******************************************************************************
|
||||
* $Id: shpdump.c,v 1.10 2002/04/10 16:59:29 warmerda Exp $
|
||||
*
|
||||
* This code is in the public domain.
|
||||
* 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.1 2000-02-09 19:51:46 curt
|
||||
* Initial revision
|
||||
* Revision 1.10 2002/04/10 16:59:29 warmerda
|
||||
* added -validate switch
|
||||
*
|
||||
* Revision 1.1 1999/08/24 21:13:01 curt
|
||||
* Initial revision.
|
||||
* 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.
|
||||
|
@ -28,7 +65,7 @@
|
|||
*/
|
||||
|
||||
static char rcsid[] =
|
||||
"$Id: shpdump.c,v 1.1 2000-02-09 19:51:46 curt Exp $";
|
||||
"$Id: shpdump.c,v 1.10 2002/04/10 16:59:29 warmerda Exp $";
|
||||
|
||||
#include "shapefil.h"
|
||||
|
||||
|
@ -36,16 +73,23 @@ int main( int argc, char ** argv )
|
|||
|
||||
{
|
||||
SHPHandle hSHP;
|
||||
int nShapeType, nEntities, i, iPart;
|
||||
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 shp_file\n" );
|
||||
printf( "shpdump [-validate] shp_file\n" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
|
@ -68,8 +112,8 @@ int main( int argc, char ** argv )
|
|||
printf( "Shapefile Type: %s # of Shapes: %d\n\n",
|
||||
SHPTypeName( nShapeType ), nEntities );
|
||||
|
||||
printf( "File Bounds: (%12.3f,%12.3f,%lg,%lg)\n"
|
||||
" to (%12.3f,%12.3f,%lg,%lg)\n",
|
||||
printf( "File Bounds: (%12.3f,%12.3f,%g,%g)\n"
|
||||
" to (%12.3f,%12.3f,%g,%g)\n",
|
||||
adfMinBound[0],
|
||||
adfMinBound[1],
|
||||
adfMinBound[2],
|
||||
|
@ -90,8 +134,8 @@ int main( int argc, char ** argv )
|
|||
psShape = SHPReadObject( hSHP, i );
|
||||
|
||||
printf( "\nShape:%d (%s) nVertices=%d, nParts=%d\n"
|
||||
" Bounds:(%12.3f,%12.3f, %lg, %lg)\n"
|
||||
" to (%12.3f,%12.3f, %lg, %lg)\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,
|
||||
|
@ -116,7 +160,7 @@ int main( int argc, char ** argv )
|
|||
else
|
||||
pszPlus = " ";
|
||||
|
||||
printf(" %s (%12.3f,%12.3f, %lg, %lg) %s \n",
|
||||
printf(" %s (%12.3f,%12.3f, %g, %g) %s \n",
|
||||
pszPlus,
|
||||
psShape->padfX[j],
|
||||
psShape->padfY[j],
|
||||
|
@ -124,12 +168,29 @@ int main( int argc, char ** argv )
|
|||
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
|
||||
|
|
File diff suppressed because it is too large
Load diff
109
src/Lib/shapelib/shprewind.c
Normal file
109
src/Lib/shapelib/shprewind.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
/******************************************************************************
|
||||
* $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 );
|
||||
}
|
|
@ -1,14 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 1998 Frank Warmerdam
|
||||
/******************************************************************************
|
||||
* $Id: shptest.c,v 1.6 2002/01/15 14:36:07 warmerda Exp $
|
||||
*
|
||||
* This code is in the public domain.
|
||||
* 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.1 2000-02-09 19:51:46 curt
|
||||
* Initial revision
|
||||
* Revision 1.6 2002/01/15 14:36:07 warmerda
|
||||
* updated email address
|
||||
*
|
||||
* Revision 1.1 1999/08/24 21:13:01 curt
|
||||
* Initial revision.
|
||||
* 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.
|
||||
|
@ -19,8 +56,10 @@
|
|||
*/
|
||||
|
||||
static char rcsid[] =
|
||||
"$Id: shptest.c,v 1.1 2000-02-09 19:51:46 curt Exp $";
|
||||
"$Id: shptest.c,v 1.6 2002/01/15 14:36:07 warmerda Exp $";
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "shapefil.h"
|
||||
|
||||
/************************************************************************/
|
||||
|
@ -208,10 +247,6 @@ static void Test_WriteArcPoly( int nSHPType, const char *pszFilename )
|
|||
int main( int argc, char ** argv )
|
||||
|
||||
{
|
||||
SHPHandle hSHP;
|
||||
int nShapeType, nEntities, i, iPart;
|
||||
const char *pszPlus;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Display a usage message. */
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -225,7 +260,10 @@ int main( int argc, char ** argv )
|
|||
/* Figure out which test to run. */
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
if( atoi(argv[1]) == 1 )
|
||||
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" );
|
||||
|
|
679
src/Lib/shapelib/shptree.c
Normal file
679
src/Lib/shapelib/shptree.c
Normal file
|
@ -0,0 +1,679 @@
|
|||
/******************************************************************************
|
||||
* $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 <math.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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 );
|
||||
}
|
||||
|
398
src/Lib/shapelib/shptreedump.c
Normal file
398
src/Lib/shapelib/shptreedump.c
Normal file
|
@ -0,0 +1,398 @@
|
|||
/******************************************************************************
|
||||
* $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 <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
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" );
|
||||
}
|
|
@ -1,15 +1,70 @@
|
|||
/*
|
||||
* ORGINAL CODE WAS FROM "dbfdump.c", "shpdump.c", and "shpopen.c".
|
||||
* Frank Warmerdam 1995
|
||||
/******************************************************************************
|
||||
* $Id: shputils.c,v 1.7 2003/02/25 17:20:22 warmerda Exp $
|
||||
*
|
||||
* This code is in the public domain.
|
||||
* 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.1 2000-02-09 19:51:46 curt
|
||||
* Initial revision
|
||||
* 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.1 1999/08/24 21:13:01 curt
|
||||
* Initial revision.
|
||||
* 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.
|
||||
|
@ -19,27 +74,10 @@
|
|||
*
|
||||
* Revision 1.1 1997/05/27 20:40:27 warmerda
|
||||
* Initial revision
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Bill Miller NC-DOT -- Feb. 1997 -- bmiller@doh.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.
|
||||
*
|
||||
* PURPOSE: I needed a program to Append, Select, Change Unit, and
|
||||
* Clip boundaries. The program only passes thru the
|
||||
* data once.
|
||||
*
|
||||
*/
|
||||
|
||||
static char rcsid[] =
|
||||
"$Id: shputils.c,v 1.1 2000-02-09 19:51:46 curt Exp $";
|
||||
"$Id: shputils.c,v 1.7 2003/02/25 17:20:22 warmerda Exp $";
|
||||
|
||||
#include "shapefil.h"
|
||||
#include "string.h"
|
||||
|
@ -76,6 +114,7 @@ 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);
|
||||
|
@ -84,33 +123,39 @@ void findselect(void);
|
|||
void showitems(void);
|
||||
int selectrec();
|
||||
int check_theme_bnd();
|
||||
int clip();
|
||||
int clip_boundary();
|
||||
void error();
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Variables for the DESCRIBE function */
|
||||
/* -------------------------------------------------------------------- */
|
||||
int ilist = FALSE, iall = FALSE;
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Variables for the SELECT function */
|
||||
/* -------------------------------------------------------------------- */
|
||||
char selectitem[40], *cpt;
|
||||
int selectvalues[150];
|
||||
int iselect = FALSE, iselectitem = -1, selcount=0;
|
||||
int iunselect = FALSE;
|
||||
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 iclip = FALSE, ierase = FALSE;
|
||||
int itouch = FALSE, iinside = FALSE, icut = FALSE;
|
||||
int ibound = FALSE, ipoly = FALSE;
|
||||
char clipfile[80];
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Variables for the UNIT function */
|
||||
/* Variables for the FACTOR function */
|
||||
/* -------------------------------------------------------------------- */
|
||||
double factor = 1; /* NO FACTOR */
|
||||
double infactor,outfactor,factor = 0; /* NO FACTOR */
|
||||
int iunit = FALSE;
|
||||
|
||||
int ifactor = FALSE;
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Variables for the SHIFT function */
|
||||
|
@ -125,12 +170,15 @@ int main( int argc, char ** argv )
|
|||
/* -------------------------------------------------------------------- */
|
||||
if( argc < 2 ) error();
|
||||
strcpy(infile, argv[1]);
|
||||
if (argc == 2 ) {
|
||||
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,"");
|
||||
} else {
|
||||
strcpy(outfile,argv[2]);
|
||||
}
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Look for other functions on the command line. (SELECT, UNIT) */
|
||||
|
@ -161,7 +209,7 @@ int main( int argc, char ** argv )
|
|||
selcount++;
|
||||
}
|
||||
iselect=TRUE;
|
||||
}
|
||||
} /*** End SEL & UNSEL ***/
|
||||
else
|
||||
if ((strncasecmp2(argv[i], "CLIP",4) == 0) ||
|
||||
(strncasecmp2(argv[i], "ERASE",5) == 0))
|
||||
|
@ -190,12 +238,7 @@ int main( int argc, char ** argv )
|
|||
printf("Theme Clip Boundary: (%lf,%lf) - (%lf,%lf)\n",
|
||||
cxmin, cymin, cxmax, cymax);
|
||||
ibound=TRUE;
|
||||
}
|
||||
else if (strncasecmp2(argv[i], "POLY",4) == 0)
|
||||
{
|
||||
ipoly=TRUE;
|
||||
}
|
||||
else { /*** xmin,ymin,xmax,ymax ***/
|
||||
} else { /*** xmin,ymin,xmax,ymax ***/
|
||||
sscanf(argv[i],"%lf",&cymin);
|
||||
i++;
|
||||
if (i >= argc) error();
|
||||
|
@ -207,46 +250,50 @@ int main( int argc, char ** argv )
|
|||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
else
|
||||
if (strncasecmp2(argv[i], "UNIT",4) == 0)
|
||||
} /*** End CLIP & ERASE ***/
|
||||
else if (strncasecmp2(argv[i], "FACTOR",0) == 0)
|
||||
{
|
||||
i++;
|
||||
if (i >= argc) error();
|
||||
if (strncasecmp2(argv[i], "METER",5) == 0)
|
||||
factor=0.304800609601;
|
||||
else
|
||||
{
|
||||
if (strncasecmp2(argv[i], "FEET",4) == 0)
|
||||
factor=3.280833;
|
||||
else
|
||||
sscanf(argv[i],"%lf",&factor);
|
||||
}
|
||||
if (factor == 0) error();
|
||||
iunit=TRUE;
|
||||
printf("Output file coordinate values will be factored by %lg\n",factor);
|
||||
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();
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("ERROR: Unknown function %s\n",argv[i]); error();
|
||||
}
|
||||
}
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* If there is no data in this file let the user know. */
|
||||
|
@ -268,7 +315,7 @@ int main( int argc, char ** argv )
|
|||
adfBoundsMax[0], adfBoundsMax[1],
|
||||
nEntities, iRecord );
|
||||
|
||||
if (strcmp(outfile,"") == 0)
|
||||
if (strcmp(outfile,"") == 0) /* Describe the shapefile; No other functions */
|
||||
{
|
||||
ti = DBFGetFieldCount( hDBF );
|
||||
showitems();
|
||||
|
@ -317,7 +364,7 @@ int main( int argc, char ** argv )
|
|||
/* Clip coordinates of shapes if needed. */
|
||||
/* -------------------------------------------------------------------- */
|
||||
if (iclip)
|
||||
if (clip() == 0) goto SKIP_RECORD; /** SKIP RECORD **/
|
||||
if (clip_boundary() == 0) goto SKIP_RECORD; /** SKIP RECORD **/
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Read a DBF record and copy each field. */
|
||||
|
@ -351,9 +398,9 @@ int main( int argc, char ** argv )
|
|||
}
|
||||
jRecord++;
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Change UNIT and SHIFT coordinates of shapes if needed. */
|
||||
/* Change FACTOR and SHIFT coordinates of shapes if needed. */
|
||||
/* -------------------------------------------------------------------- */
|
||||
if (iunit)
|
||||
if (iunit)
|
||||
{
|
||||
for( j = 0; j < psCShape->nVertices; j++ )
|
||||
{
|
||||
|
@ -370,6 +417,7 @@ int main( int argc, char ** argv )
|
|||
|
||||
SKIP_RECORD:
|
||||
SHPDestroyObject( psCShape );
|
||||
psCShape = NULL;
|
||||
j=0;
|
||||
}
|
||||
|
||||
|
@ -392,6 +440,15 @@ int main( int argc, char ** argv )
|
|||
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 );
|
||||
}
|
||||
|
||||
|
@ -512,14 +569,14 @@ void mergefields()
|
|||
for( i = 0; i < ti; i++ )
|
||||
{
|
||||
iType = DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals );
|
||||
found=0;
|
||||
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 == 1 || newdbf == 1)
|
||||
if (found || newdbf)
|
||||
{
|
||||
if (i == j) pt[i]=j;
|
||||
printf("Warning: Duplicate field name found (%s)\n",iszTitle);
|
||||
|
@ -528,13 +585,13 @@ void mergefields()
|
|||
}
|
||||
else
|
||||
{
|
||||
pt[i]=j; found=1;
|
||||
pt[i]=j; found=TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pt[i] == -1 && found == 0) /* Try to force into an existing field */
|
||||
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)
|
||||
|
@ -542,11 +599,12 @@ void mergefields()
|
|||
pt[i]=i; found=1;
|
||||
}
|
||||
}
|
||||
if (found == 0 && jRecord == 0) /* Add missing field to the append table */
|
||||
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 ))
|
||||
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) );
|
||||
|
@ -569,7 +627,8 @@ void findselect()
|
|||
if (iselectitem == -1)
|
||||
{
|
||||
printf("Warning: Item not found for selection (%s)\n",selectitem);
|
||||
iselect = 0;
|
||||
iselect = FALSE;
|
||||
iall = FALSE;
|
||||
showitems();
|
||||
printf("Continued... (Selecting entire file)\n");
|
||||
}
|
||||
|
@ -579,23 +638,95 @@ void findselect()
|
|||
|
||||
void showitems()
|
||||
{
|
||||
printf("Available Items: ");
|
||||
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++ )
|
||||
{
|
||||
iType = DBFGetFieldInfo( hDBF, i, iszTitle, &iWidth, &iDecimals );
|
||||
printf("%s, ",iszTitle);
|
||||
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("(total=%d)\n",ti);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int selectrec()
|
||||
{
|
||||
int value, ty;
|
||||
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 );
|
||||
|
@ -607,6 +738,8 @@ int value, ty;
|
|||
}
|
||||
break;
|
||||
case FTDouble:
|
||||
puts("Invalid Item");
|
||||
iselect=FALSE;
|
||||
break;
|
||||
}
|
||||
if (iunselect) return(1); /* Skip this record */
|
||||
|
@ -629,164 +762,120 @@ int check_theme_bnd()
|
|||
( (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 **/
|
||||
else nEntities=0; /** SKIP THEME **/
|
||||
}
|
||||
|
||||
if (nEntities == 0)
|
||||
puts("WARNING: Theme is outside the clip area."); /** SKIP THEME **/
|
||||
}
|
||||
|
||||
int clip()
|
||||
clip_boundary()
|
||||
{
|
||||
int outside=FALSE;
|
||||
int j2=0, i2=0;
|
||||
|
||||
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 ( ( psCShape->dfXMax < cxmin ) ||
|
||||
( psCShape->dfYMax < cymin ) ||
|
||||
( psCShape->dfXMin > cxmax ) ||
|
||||
( psCShape->dfYMin > cymax ) )
|
||||
{ /** Feature is totally outside clip area **/
|
||||
if (ierase) return(1); /** WRITE RECORD **/
|
||||
else return(0); /** SKIP RECORD **/
|
||||
}
|
||||
|
||||
if (itouch)
|
||||
{
|
||||
if (ierase) return(0); /** SKIP RECORD **/
|
||||
else return(1); /** WRITE RECORD **/
|
||||
}
|
||||
|
||||
if (iinside)
|
||||
{
|
||||
if (ierase) return(1); /** WRITE RECORD **/
|
||||
else return(0); /** SKIP RECORD **/
|
||||
}
|
||||
|
||||
/*** SECOND check each vertex in the feature ***/
|
||||
for( j2 = 0; j2 < psCShape->nVertices; j2++ )
|
||||
{
|
||||
if (psCShape->padfX[j2] < cxmin || psCShape->padfX[j2] > cxmax)
|
||||
{
|
||||
outside=TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (psCShape->padfY[j2] < cymin || psCShape->padfY[j2] > cymax)
|
||||
outside=TRUE;
|
||||
else
|
||||
outside=FALSE;
|
||||
}
|
||||
|
||||
|
||||
if (icut)
|
||||
{
|
||||
if (outside)
|
||||
{
|
||||
} else {
|
||||
if (i2 != j2)
|
||||
{
|
||||
/* write vertex */
|
||||
psCShape->padfX[i2] = psCShape->padfX[j2];
|
||||
psCShape->padfY[i2] = psCShape->padfY[j2];
|
||||
}
|
||||
i2++;
|
||||
}
|
||||
}
|
||||
else
|
||||
if (outside) /* vertex is outside boundary */
|
||||
{
|
||||
if (iinside)
|
||||
{
|
||||
if (ierase) return(1); /** WRITE RECORD **/
|
||||
else return(0); /** SKIP RECORD **/
|
||||
}
|
||||
}
|
||||
else /* vertex is inside boundary */
|
||||
{
|
||||
if (itouch)
|
||||
{
|
||||
if (ierase) return(0); /** SKIP RECORD **/
|
||||
else return(1); /** WRITE RECORD **/
|
||||
}
|
||||
}
|
||||
}
|
||||
int inside;
|
||||
int prev_outside;
|
||||
int i2;
|
||||
int j2;
|
||||
|
||||
if (icut)
|
||||
{
|
||||
j2 = psCShape->nVertices;
|
||||
if (i2 < 2) return(0); /** SKIP RECORD **/
|
||||
|
||||
psCShape->nVertices = i2;
|
||||
/*** 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",
|
||||
j2, psCShape->nVertices, psCShape->nParts );
|
||||
}
|
||||
if (itouch)
|
||||
{
|
||||
if (ierase) return(1); /** WRITE RECORD **/
|
||||
else return(0); /** SKIP RECORD **/
|
||||
}
|
||||
if (iinside)
|
||||
{
|
||||
if (ierase) return(0); /** SKIP RECORD **/
|
||||
else return(1); /** WRITE RECORD **/
|
||||
}
|
||||
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 **/
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Display a usage message. */
|
||||
/* -------------------------------------------------------------------- */
|
||||
void error()
|
||||
{
|
||||
puts( "USAGE: shputils <DescribeShape>");
|
||||
puts( "USAGE: shputils <InputShape> <AppendShape>" );
|
||||
puts( " { <SELECT> <Item> <valuelist> }" );
|
||||
puts( " { <UNSELECT> <Item> <valuelist> }" );
|
||||
puts( " { <CLIP> <xmin> <ymin> <xmax> <ymax> <TOUCH|INSIDE|CUT> }" );
|
||||
puts( " { <CLIP> <Theme> <BOUNDARY|POLYGON> <TOUCH|INSIDE|CUT> }" );
|
||||
puts( " Clip functions for Cut and Polygon are not supported yet..." );
|
||||
puts( " { <ERASE> <xmin> <ymin> <xmax> <ymax> <TOUCH|INSIDE|CUT> }" );
|
||||
puts( " { <ERASE> <Theme> <BOUNDARY|POLYGON> <TOUCH|INSIDE|CUT> }" );
|
||||
puts( " { <UNIT> <FEET|METERS|factor> }" );
|
||||
puts( " { <SHIFT> <xshift> <yshift> }\n" );
|
||||
|
||||
|
||||
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( " - 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( " *(N/A) Cut will cookie-cut shapes that are touching the boundary.");
|
||||
puts( " Boundary clips are only the min and max of a theme boundary." );
|
||||
puts( " *(N/A) Polygon clips use the polygons within a theme.");
|
||||
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.");
|
||||
puts( "EX: shputils in.shp out.shp CLIP 10 10 90 90 Touch UNIT Feet SHIFT 40 40");
|
||||
puts( " shputils in.shp out.shp SELECT countycode 3,5,9,13,17,27");
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* strncasecmp2() */
|
||||
|
@ -806,12 +895,11 @@ int j,i;
|
|||
{
|
||||
if (*s1 >= 'a' && *s1 <= 'z') {
|
||||
j=*s1-32;
|
||||
if (j != *s2) return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
j=*s1+32;
|
||||
if (j != *s2) return(1);
|
||||
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++;
|
||||
|
@ -819,3 +907,144 @@ int j,i;
|
|||
}
|
||||
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 <DescribeShape> {ALL}");
|
||||
puts( "USAGE: shputils <InputShape> <OutShape|AppendShape>" );
|
||||
puts( " { <FACTOR> <FEET|MILES|METERS|KM> <FEET|MILES|METERS|KM|factor> }" );
|
||||
puts( " { <SHIFT> <xshift> <yshift> }" );
|
||||
puts( " { <SELECT|UNSEL> <Item> <valuelist> }" );
|
||||
puts( " { <CLIP|ERASE> <xmin> <ymin> <xmax> <ymax> <TOUCH|INSIDE|CUT> }" );
|
||||
puts( " { <CLIP|ERASE> <theme> <BOUNDARY> <TOUCH|INSIDE|CUT> }" );
|
||||
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 );
|
||||
}
|
||||
|
|
|
@ -1,26 +1,28 @@
|
|||
#!/bin/sh
|
||||
|
||||
EG_DATA=/home/warmerda/www/projects/shapelib/eg_data
|
||||
EG_DATA=/u/www/projects/shapelib/eg_data
|
||||
|
||||
echo -------------------------------------------------------------------------
|
||||
echo Test 1: dump anno.shp
|
||||
echo -------------------------------------------------------------------------
|
||||
shpdump $EG_DATA/anno.shp | head -250
|
||||
./shpdump $EG_DATA/anno.shp | head -250
|
||||
|
||||
echo -------------------------------------------------------------------------
|
||||
echo Test 2: dump brklinz.shp
|
||||
echo -------------------------------------------------------------------------
|
||||
shpdump $EG_DATA/brklinz.shp | head -500
|
||||
./shpdump $EG_DATA/brklinz.shp | head -500
|
||||
|
||||
echo -------------------------------------------------------------------------
|
||||
echo Test 3: dump polygon.shp
|
||||
echo -------------------------------------------------------------------------
|
||||
shpdump $EG_DATA/polygon.shp | head -500
|
||||
./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
|
||||
|
||||
|
||||
./dbfdump -m -h $EG_DATA/pline.dbf | head -50
|
||||
|
||||
echo -------------------------------------------------------------------------
|
||||
echo Test 5: NULL Shapes.
|
||||
echo -------------------------------------------------------------------------
|
||||
./shpdump $EG_DATA/csah.dbf | head -150
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#!/bin/sh
|
||||
|
||||
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13; do
|
||||
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
|
||||
./shpdump test${i}.shp
|
||||
done
|
||||
|
||||
|
|
Loading…
Reference in a new issue