34 |
****************************************************************************** |
****************************************************************************** |
35 |
* |
* |
36 |
* $Log$ |
* $Log$ |
37 |
* Revision 1.2 2003/10/02 15:15:16 bh |
* Revision 1.3 2004/05/17 15:47:57 bh |
38 |
* Update to shapelib 1.2.10 |
* Update to newest shapelib and get rid of Thuban specific extensions, |
39 |
|
* i.e. use the new DBFUpdateHeader instead of our DBFCommit kludge |
40 |
|
* |
41 |
|
* * libraries/shapelib/shpopen.c: Update to version from current |
42 |
|
* shapelib CVS. |
43 |
|
* |
44 |
|
* * libraries/shapelib/shapefil.h: Update to version from current |
45 |
|
* shapelib CVS. |
46 |
|
* |
47 |
|
* * libraries/shapelib/dbfopen.c: Update to version from current |
48 |
|
* shapelib CVS. |
49 |
|
* (DBFCommit): Effectively removed since shapelib itself has |
50 |
|
* DBFUpdateHeader now which is better for what DBFCommit wanted to |
51 |
|
* achieve. |
52 |
|
* We're now using an unmodified version of dbfopen. |
53 |
|
* |
54 |
|
* * libraries/pyshapelib/dbflib_wrap.c, libraries/pyshapelib/dbflib.py: |
55 |
|
* Update from dbflib.i |
56 |
|
* |
57 |
|
* * libraries/pyshapelib/dbflib.i (DBFInfo_commit): New. Implementation of |
58 |
|
* the commit method. This new indirection is necessary because we use the |
59 |
|
* DBFUpdateHeader function now which is not available in shapelib <= |
60 |
|
* 1.2.10 |
61 |
|
* (DBFFile::commit): Use DBFInfo_commit as implementation |
62 |
|
* (pragma __class__): New. Kludge to remove the commit method when |
63 |
|
* the DBFUpdateHeader function isn't available |
64 |
|
* (_have_commit): New. Helper for the pragma kludge. |
65 |
|
* |
66 |
|
* * libraries/pyshapelib/setup.py (dbf_macros): New. Return the |
67 |
|
* preprocessor macros needed to compile the dbflib wrapper. Determine |
68 |
|
* whether DBFUpdateHeader is available and define the right value of |
69 |
|
* HAVE_UPDATE_HEADER |
70 |
|
* (extensions): Use dbf_macros for the dbflibc extension |
71 |
|
* |
72 |
|
* * setup.py (extensions): Add the HAVE_UPDATE_HEADER macro with |
73 |
|
* value '1' to the Lib.dbflibc extension. This simply reflects the |
74 |
|
* shapelib and pyshapelib updates |
75 |
|
* |
76 |
|
* Revision 1.44 2003/12/29 00:18:39 fwarmerdam |
77 |
|
* added error checking for failed IO and optional CPL error reporting |
78 |
|
* |
79 |
|
* Revision 1.43 2003/12/01 16:20:08 warmerda |
80 |
|
* be careful of zero vertex shapes |
81 |
|
* |
82 |
|
* Revision 1.42 2003/12/01 14:58:27 warmerda |
83 |
|
* added degenerate object check in SHPRewindObject() |
84 |
|
* |
85 |
|
* Revision 1.41 2003/07/08 15:22:43 warmerda |
86 |
|
* avoid warning |
87 |
|
* |
88 |
|
* Revision 1.40 2003/04/21 18:30:37 warmerda |
89 |
|
* added header write/update public methods |
90 |
* |
* |
91 |
* Revision 1.39 2002/08/26 06:46:56 warmerda |
* Revision 1.39 2002/08/26 06:46:56 warmerda |
92 |
* avoid c++ comments |
* avoid c++ comments |
288 |
/* contents of the index (.shx) file. */ |
/* contents of the index (.shx) file. */ |
289 |
/************************************************************************/ |
/************************************************************************/ |
290 |
|
|
291 |
static void SHPWriteHeader( SHPHandle psSHP ) |
void SHPWriteHeader( SHPHandle psSHP ) |
292 |
|
|
293 |
{ |
{ |
294 |
uchar abyHeader[100]; |
uchar abyHeader[100]; |
353 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
354 |
/* Write .shp file header. */ |
/* Write .shp file header. */ |
355 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
356 |
fseek( psSHP->fpSHP, 0, 0 ); |
if( fseek( psSHP->fpSHP, 0, 0 ) != 0 |
357 |
fwrite( abyHeader, 100, 1, psSHP->fpSHP ); |
|| fwrite( abyHeader, 100, 1, psSHP->fpSHP ) != 1 ) |
358 |
|
{ |
359 |
|
#ifdef USE_CPL |
360 |
|
CPLError( CE_Failure, CPLE_OpenFailed, |
361 |
|
"Failure writing .shp header." ); |
362 |
|
#endif |
363 |
|
return; |
364 |
|
} |
365 |
|
|
366 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
367 |
/* Prepare, and write .shx file header. */ |
/* Prepare, and write .shx file header. */ |
370 |
ByteCopy( &i32, abyHeader+24, 4 ); |
ByteCopy( &i32, abyHeader+24, 4 ); |
371 |
if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); |
if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); |
372 |
|
|
373 |
fseek( psSHP->fpSHX, 0, 0 ); |
if( fseek( psSHP->fpSHX, 0, 0 ) != 0 |
374 |
fwrite( abyHeader, 100, 1, psSHP->fpSHX ); |
|| fwrite( abyHeader, 100, 1, psSHP->fpSHX ) != 1 ) |
375 |
|
{ |
376 |
|
#ifdef USE_CPL |
377 |
|
CPLError( CE_Failure, CPLE_OpenFailed, |
378 |
|
"Failure writing .shx header." ); |
379 |
|
#endif |
380 |
|
return; |
381 |
|
} |
382 |
|
|
383 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
384 |
/* Write out the .shx contents. */ |
/* Write out the .shx contents. */ |
393 |
if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 ); |
if( !bBigEndian ) SwapWord( 4, panSHX+i*2+1 ); |
394 |
} |
} |
395 |
|
|
396 |
fwrite( panSHX, sizeof(int32) * 2, psSHP->nRecords, psSHP->fpSHX ); |
if( fwrite( panSHX, sizeof(int32) * 2, psSHP->nRecords, psSHP->fpSHX ) |
397 |
|
!= psSHP->nRecords ) |
398 |
|
{ |
399 |
|
#ifdef USE_CPL |
400 |
|
CPLError( CE_Failure, CPLE_OpenFailed, |
401 |
|
"Failure writing .shx contents." ); |
402 |
|
#endif |
403 |
|
} |
404 |
|
|
405 |
free( panSHX ); |
free( panSHX ); |
406 |
|
|
407 |
|
/* -------------------------------------------------------------------- */ |
408 |
|
/* Flush to disk. */ |
409 |
|
/* -------------------------------------------------------------------- */ |
410 |
|
fflush( psSHP->fpSHP ); |
411 |
|
fflush( psSHP->fpSHX ); |
412 |
} |
} |
413 |
|
|
414 |
/************************************************************************/ |
/************************************************************************/ |
415 |
/* SHPOpen() */ |
/* shpopen() */ |
416 |
/* */ |
/* */ |
417 |
/* Open the .shp and .shx files based on the basename of the */ |
/* Open the .shp and .shx files based on the basename of the */ |
418 |
/* files or either file name. */ |
/* files or either file name. */ |
423 |
|
|
424 |
{ |
{ |
425 |
char *pszFullname, *pszBasename; |
char *pszFullname, *pszBasename; |
426 |
SHPHandle psSHP; |
FILE *fpSHP, *fpSHX; |
|
|
|
|
uchar *pabyBuf; |
|
427 |
int i; |
int i; |
|
double dValue; |
|
428 |
|
|
429 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
430 |
/* Ensure the access string is one of the legal ones. We */ |
/* Ensure the access string is one of the legal ones. We */ |
447 |
bBigEndian = TRUE; |
bBigEndian = TRUE; |
448 |
|
|
449 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
|
/* Initialize the info structure. */ |
|
|
/* -------------------------------------------------------------------- */ |
|
|
psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1); |
|
|
|
|
|
psSHP->bUpdated = FALSE; |
|
|
|
|
|
/* -------------------------------------------------------------------- */ |
|
450 |
/* Compute the base (layer) name. If there is any extension */ |
/* Compute the base (layer) name. If there is any extension */ |
451 |
/* on the passed in filename we will strip it off. */ |
/* on the passed in filename we will strip it off. */ |
452 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
466 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
467 |
pszFullname = (char *) malloc(strlen(pszBasename) + 5); |
pszFullname = (char *) malloc(strlen(pszBasename) + 5); |
468 |
sprintf( pszFullname, "%s.shp", pszBasename ); |
sprintf( pszFullname, "%s.shp", pszBasename ); |
469 |
psSHP->fpSHP = fopen(pszFullname, pszAccess ); |
fpSHP = fopen(pszFullname, pszAccess ); |
470 |
if( psSHP->fpSHP == NULL ) |
if( fpSHP == NULL ) |
471 |
{ |
{ |
472 |
sprintf( pszFullname, "%s.SHP", pszBasename ); |
sprintf( pszFullname, "%s.SHP", pszBasename ); |
473 |
psSHP->fpSHP = fopen(pszFullname, pszAccess ); |
fpSHP = fopen(pszFullname, pszAccess ); |
474 |
} |
} |
475 |
|
|
476 |
if( psSHP->fpSHP == NULL ) |
if( fpSHP == NULL ) |
477 |
{ |
{ |
478 |
free( psSHP ); |
#ifdef USE_CPL |
479 |
|
CPLError( CE_Failure, CPLE_OpenFailed, |
480 |
|
"Unable to open %s.shp or %s.SHP.", |
481 |
|
pszBasename, pszBasename ); |
482 |
|
#endif |
483 |
free( pszBasename ); |
free( pszBasename ); |
484 |
free( pszFullname ); |
free( pszFullname ); |
485 |
return( NULL ); |
return( NULL ); |
486 |
} |
} |
487 |
|
|
488 |
sprintf( pszFullname, "%s.shx", pszBasename ); |
sprintf( pszFullname, "%s.shx", pszBasename ); |
489 |
psSHP->fpSHX = fopen(pszFullname, pszAccess ); |
fpSHX = fopen(pszFullname, pszAccess ); |
490 |
if( psSHP->fpSHX == NULL ) |
if( fpSHX == NULL ) |
491 |
{ |
{ |
492 |
sprintf( pszFullname, "%s.SHX", pszBasename ); |
sprintf( pszFullname, "%s.SHX", pszBasename ); |
493 |
psSHP->fpSHX = fopen(pszFullname, pszAccess ); |
fpSHX = fopen(pszFullname, pszAccess ); |
494 |
} |
} |
495 |
|
|
496 |
if( psSHP->fpSHX == NULL ) |
if( fpSHX == NULL ) |
497 |
{ |
{ |
498 |
fclose( psSHP->fpSHP ); |
#ifdef USE_CPL |
499 |
free( psSHP ); |
CPLError( CE_Failure, CPLE_OpenFailed, |
500 |
|
"Unable to open %s.shx or %s.SHX.", |
501 |
|
pszBasename, pszBasename ); |
502 |
|
#endif |
503 |
|
fclose( fpSHP ); |
504 |
free( pszBasename ); |
free( pszBasename ); |
505 |
free( pszFullname ); |
free( pszFullname ); |
506 |
return( NULL ); |
return( NULL ); |
509 |
free( pszFullname ); |
free( pszFullname ); |
510 |
free( pszBasename ); |
free( pszBasename ); |
511 |
|
|
512 |
|
return SHPOpenEx( fpSHP, fpSHX ); |
513 |
|
} |
514 |
|
|
515 |
|
|
516 |
|
/************************************************************************/ |
517 |
|
/* SHPOpenW() */ |
518 |
|
/* */ |
519 |
|
/* Open the .shp and .shx files based on the basename of the */ |
520 |
|
/* files or either file name, for wide character filenames */ |
521 |
|
/************************************************************************/ |
522 |
|
|
523 |
|
#ifdef SHPAPI_HAS_WIDE |
524 |
|
|
525 |
|
SHPHandle SHPAPI_CALL |
526 |
|
SHPOpenW( const wchar_t * pszLayer, const wchar_t * pszAccess ) |
527 |
|
|
528 |
|
{ |
529 |
|
wchar_t *pszFullname, *pszBasename; |
530 |
|
FILE *fpSHP, *fpSHX; |
531 |
|
int i; |
532 |
|
|
533 |
|
/* -------------------------------------------------------------------- */ |
534 |
|
/* Ensure the access string is one of the legal ones. We */ |
535 |
|
/* ensure the result string indicates binary to avoid common */ |
536 |
|
/* problems on Windows. */ |
537 |
|
/* -------------------------------------------------------------------- */ |
538 |
|
if( wcscmp(pszAccess,L"rb+") == 0 || wcscmp(pszAccess,L"r+b") == 0 |
539 |
|
|| wcscmp(pszAccess,L"r+") == 0 ) |
540 |
|
pszAccess = L"r+b"; |
541 |
|
else |
542 |
|
pszAccess = L"rb"; |
543 |
|
|
544 |
|
/* -------------------------------------------------------------------- */ |
545 |
|
/* Compute the base (layer) name. If there is any extension */ |
546 |
|
/* on the passed in filename we will strip it off. */ |
547 |
|
/* -------------------------------------------------------------------- */ |
548 |
|
pszBasename = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszLayer)+5)); |
549 |
|
wcscpy( pszBasename, pszLayer ); |
550 |
|
for( i = wcslen(pszBasename)-1; |
551 |
|
i > 0 && pszBasename[i] != L'.' && pszBasename[i] != L'/' |
552 |
|
&& pszBasename[i] != L'\\'; |
553 |
|
i-- ) {} |
554 |
|
|
555 |
|
if( pszBasename[i] == L'.' ) |
556 |
|
pszBasename[i] = L'\0'; |
557 |
|
|
558 |
|
/* -------------------------------------------------------------------- */ |
559 |
|
/* Open the .shp and .shx files. Note that files pulled from */ |
560 |
|
/* a PC to Unix with upper case filenames won't work! */ |
561 |
|
/* -------------------------------------------------------------------- */ |
562 |
|
pszFullname = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszBasename) + 5)); |
563 |
|
swprintf( pszFullname, L"%s.shp", pszBasename ); |
564 |
|
fpSHP = _wfopen(pszFullname, pszAccess ); |
565 |
|
if( fpSHP == NULL ) |
566 |
|
{ |
567 |
|
swprintf( pszFullname, L"%s.SHP", pszBasename ); |
568 |
|
fpSHP = _wfopen(pszFullname, pszAccess ); |
569 |
|
} |
570 |
|
|
571 |
|
if( fpSHP == NULL ) |
572 |
|
{ |
573 |
|
#ifdef USE_CPL |
574 |
|
CPLError( CE_Failure, CPLE_OpenFailed, |
575 |
|
"Unable to open .shp file." ); |
576 |
|
#endif |
577 |
|
free( pszBasename ); |
578 |
|
free( pszFullname ); |
579 |
|
return( NULL ); |
580 |
|
} |
581 |
|
|
582 |
|
swprintf( pszFullname, L"%s.shx", pszBasename ); |
583 |
|
fpSHX = _wfopen(pszFullname, pszAccess ); |
584 |
|
if( fpSHX == NULL ) |
585 |
|
{ |
586 |
|
swprintf( pszFullname, L"%s.SHX", pszBasename ); |
587 |
|
fpSHX = _wfopen(pszFullname, pszAccess ); |
588 |
|
} |
589 |
|
|
590 |
|
if( fpSHX == NULL ) |
591 |
|
{ |
592 |
|
#ifdef USE_CPL |
593 |
|
CPLError( CE_Failure, CPLE_OpenFailed, |
594 |
|
"Unable to open .shx file." ); |
595 |
|
#endif |
596 |
|
fclose( fpSHP ); |
597 |
|
free( pszBasename ); |
598 |
|
free( pszFullname ); |
599 |
|
return( NULL ); |
600 |
|
} |
601 |
|
|
602 |
|
free( pszFullname ); |
603 |
|
free( pszBasename ); |
604 |
|
|
605 |
|
return SHPOpenEx( fpSHP, fpSHX ); |
606 |
|
} |
607 |
|
|
608 |
|
#endif |
609 |
|
|
610 |
|
/************************************************************************/ |
611 |
|
/* shpopen() */ |
612 |
|
/* */ |
613 |
|
/* Open the .shp and .shx files based on the basename of the */ |
614 |
|
/* files or either file name. */ |
615 |
|
/************************************************************************/ |
616 |
|
|
617 |
|
SHPHandle SHPAPI_CALL |
618 |
|
SHPOpenEx( FILE * fpSHP, FILE * fpSHX ) |
619 |
|
{ |
620 |
|
SHPHandle psSHP; |
621 |
|
uchar *pabyBuf; |
622 |
|
int i; |
623 |
|
double dValue; |
624 |
|
|
625 |
|
/* -------------------------------------------------------------------- */ |
626 |
|
/* Establish the byte order on this machine. */ |
627 |
|
/* -------------------------------------------------------------------- */ |
628 |
|
i = 1; |
629 |
|
if( *((uchar *) &i) == 1 ) |
630 |
|
bBigEndian = FALSE; |
631 |
|
else |
632 |
|
bBigEndian = TRUE; |
633 |
|
|
634 |
|
/* -------------------------------------------------------------------- */ |
635 |
|
/* Initialize the info structure. */ |
636 |
|
/* -------------------------------------------------------------------- */ |
637 |
|
psSHP = (SHPHandle) calloc(sizeof(SHPInfo),1); |
638 |
|
|
639 |
|
psSHP->fpSHP = fpSHP; |
640 |
|
psSHP->fpSHX = fpSHX; |
641 |
|
psSHP->bUpdated = FALSE; |
642 |
|
|
643 |
|
|
644 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
645 |
/* Read the file size from the SHP file. */ |
/* Read the file size from the SHP file. */ |
646 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
655 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
656 |
/* Read SHX file Header info */ |
/* Read SHX file Header info */ |
657 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
658 |
fread( pabyBuf, 100, 1, psSHP->fpSHX ); |
if( fread( pabyBuf, 100, 1, psSHP->fpSHX ) != 1 |
659 |
|
|| pabyBuf[0] != 0 |
|
if( pabyBuf[0] != 0 |
|
660 |
|| pabyBuf[1] != 0 |
|| pabyBuf[1] != 0 |
661 |
|| pabyBuf[2] != 0x27 |
|| pabyBuf[2] != 0x27 |
662 |
|| (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) ) |
|| (pabyBuf[3] != 0x0a && pabyBuf[3] != 0x0d) ) |
663 |
{ |
{ |
664 |
|
#ifdef USE_CPL |
665 |
|
CPLError( CE_Failure, CPLE_AppDefined, |
666 |
|
".shx file is unreadable, or corrupt." ); |
667 |
|
#endif |
668 |
fclose( psSHP->fpSHP ); |
fclose( psSHP->fpSHP ); |
669 |
fclose( psSHP->fpSHX ); |
fclose( psSHP->fpSHX ); |
670 |
free( psSHP ); |
free( psSHP ); |
680 |
|
|
681 |
if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 ) |
if( psSHP->nRecords < 0 || psSHP->nRecords > 256000000 ) |
682 |
{ |
{ |
683 |
/* this header appears to be corrupt. Give up. */ |
#ifdef USE_CPL |
684 |
|
CPLError( CE_Failure, CPLE_AppDefined, |
685 |
|
"Record count in .shp header is %d, which seems\n" |
686 |
|
"unreasonable. Assuming header is corrupt.", |
687 |
|
psSHP->nRecords ); |
688 |
|
#endif |
689 |
fclose( psSHP->fpSHP ); |
fclose( psSHP->fpSHP ); |
690 |
fclose( psSHP->fpSHX ); |
fclose( psSHP->fpSHX ); |
691 |
free( psSHP ); |
free( psSHP ); |
742 |
(int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) ); |
(int *) malloc(sizeof(int) * MAX(1,psSHP->nMaxRecords) ); |
743 |
|
|
744 |
pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) ); |
pabyBuf = (uchar *) malloc(8 * MAX(1,psSHP->nRecords) ); |
745 |
fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ); |
if( fread( pabyBuf, 8, psSHP->nRecords, psSHP->fpSHX ) != psSHP->nRecords ) |
746 |
|
{ |
747 |
|
#ifdef USE_CPL |
748 |
|
CPLError( CE_Failure, CPLE_AppDefined, |
749 |
|
"Failed to read all values for %d records in .shx file.", |
750 |
|
psSHP->nRecords ); |
751 |
|
#endif |
752 |
|
/* SHX is short or unreadable for some reason. */ |
753 |
|
fclose( psSHP->fpSHP ); |
754 |
|
fclose( psSHP->fpSHX ); |
755 |
|
free( psSHP->panRecOffset ); |
756 |
|
free( psSHP->panRecSize ); |
757 |
|
free( psSHP ); |
758 |
|
|
759 |
|
return( NULL ); |
760 |
|
} |
761 |
|
|
762 |
for( i = 0; i < psSHP->nRecords; i++ ) |
for( i = 0; i < psSHP->nRecords; i++ ) |
763 |
{ |
{ |
787 |
SHPClose(SHPHandle psSHP ) |
SHPClose(SHPHandle psSHP ) |
788 |
|
|
789 |
{ |
{ |
790 |
|
if( psSHP == NULL ) |
791 |
|
return; |
792 |
|
|
793 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
794 |
/* Update the header if we have modified anything. */ |
/* Update the header if we have modified anything. */ |
795 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
796 |
if( psSHP->bUpdated ) |
if( psSHP->bUpdated ) |
|
{ |
|
797 |
SHPWriteHeader( psSHP ); |
SHPWriteHeader( psSHP ); |
|
} |
|
798 |
|
|
799 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
800 |
/* Free all resources, and close files. */ |
/* Free all resources, and close files. */ |
825 |
|
|
826 |
{ |
{ |
827 |
int i; |
int i; |
828 |
|
|
829 |
|
if( psSHP == NULL ) |
830 |
|
return; |
831 |
|
|
832 |
if( pnEntities != NULL ) |
if( pnEntities != NULL ) |
833 |
*pnEntities = psSHP->nRecords; |
*pnEntities = psSHP->nRecords; |
858 |
char *pszBasename, *pszFullname; |
char *pszBasename, *pszFullname; |
859 |
int i; |
int i; |
860 |
FILE *fpSHP, *fpSHX; |
FILE *fpSHP, *fpSHX; |
|
uchar abyHeader[100]; |
|
|
int32 i32; |
|
|
double dValue; |
|
|
|
|
|
/* -------------------------------------------------------------------- */ |
|
|
/* Establish the byte order on this system. */ |
|
|
/* -------------------------------------------------------------------- */ |
|
|
i = 1; |
|
|
if( *((uchar *) &i) == 1 ) |
|
|
bBigEndian = FALSE; |
|
|
else |
|
|
bBigEndian = TRUE; |
|
861 |
|
|
862 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
863 |
/* Compute the base (layer) name. If there is any extension */ |
/* Compute the base (layer) name. If there is any extension */ |
880 |
sprintf( pszFullname, "%s.shp", pszBasename ); |
sprintf( pszFullname, "%s.shp", pszBasename ); |
881 |
fpSHP = fopen(pszFullname, "wb" ); |
fpSHP = fopen(pszFullname, "wb" ); |
882 |
if( fpSHP == NULL ) |
if( fpSHP == NULL ) |
883 |
|
{ |
884 |
|
#ifdef USE_CPL |
885 |
|
CPLError( CE_Failure, CPLE_AppDefined, |
886 |
|
"Failed to create file %s.", |
887 |
|
pszFullname ); |
888 |
|
#endif |
889 |
return( NULL ); |
return( NULL ); |
890 |
|
} |
891 |
|
|
892 |
sprintf( pszFullname, "%s.shx", pszBasename ); |
sprintf( pszFullname, "%s.shx", pszBasename ); |
893 |
fpSHX = fopen(pszFullname, "wb" ); |
fpSHX = fopen(pszFullname, "wb" ); |
894 |
if( fpSHX == NULL ) |
if( fpSHX == NULL ) |
895 |
|
{ |
896 |
|
#ifdef USE_CPL |
897 |
|
CPLError( CE_Failure, CPLE_AppDefined, |
898 |
|
"Failed to create file %s.", |
899 |
|
pszFullname ); |
900 |
|
#endif |
901 |
|
return( NULL ); |
902 |
|
} |
903 |
|
|
904 |
|
free( pszFullname ); |
905 |
|
free( pszBasename ); |
906 |
|
|
907 |
|
SHPCreateEx( fpSHP, fpSHX, nShapeType ); |
908 |
|
|
909 |
|
/* -------------------------------------------------------------------- */ |
910 |
|
/* Close the files, and then open them as regular existing files. */ |
911 |
|
/* -------------------------------------------------------------------- */ |
912 |
|
fclose( fpSHP ); |
913 |
|
fclose( fpSHX ); |
914 |
|
|
915 |
|
return( SHPOpen( pszLayer, "r+b" ) ); |
916 |
|
} |
917 |
|
|
918 |
|
#ifdef SHPAPI_HAS_WIDE |
919 |
|
|
920 |
|
/************************************************************************/ |
921 |
|
/* SHPCreate() */ |
922 |
|
/* */ |
923 |
|
/* Create a new shape file and return a handle to the open */ |
924 |
|
/* shape file with read/write access. */ |
925 |
|
/************************************************************************/ |
926 |
|
|
927 |
|
SHPHandle SHPAPI_CALL |
928 |
|
SHPCreateW( const wchar_t * pszLayer, int nShapeType ) |
929 |
|
|
930 |
|
{ |
931 |
|
wchar_t *pszBasename, *pszFullname; |
932 |
|
int i; |
933 |
|
FILE *fpSHP, *fpSHX; |
934 |
|
|
935 |
|
/* -------------------------------------------------------------------- */ |
936 |
|
/* Compute the base (layer) name. If there is any extension */ |
937 |
|
/* on the passed in filename we will strip it off. */ |
938 |
|
/* -------------------------------------------------------------------- */ |
939 |
|
pszBasename = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszLayer)+5)); |
940 |
|
wcscpy( pszBasename, pszLayer ); |
941 |
|
for( i = wcslen(pszBasename)-1; |
942 |
|
i > 0 && pszBasename[i] != L'.' && pszBasename[i] != L'/' |
943 |
|
&& pszBasename[i] != L'\\'; |
944 |
|
i-- ) {} |
945 |
|
|
946 |
|
if( pszBasename[i] == L'.' ) |
947 |
|
pszBasename[i] = L'\0'; |
948 |
|
|
949 |
|
/* -------------------------------------------------------------------- */ |
950 |
|
/* Open the two files so we can write their headers. */ |
951 |
|
/* -------------------------------------------------------------------- */ |
952 |
|
pszFullname = (wchar_t *) malloc(sizeof(wchar_t)*(wcslen(pszBasename) + 5)); |
953 |
|
swprintf( pszFullname, L"%s.shp", pszBasename ); |
954 |
|
fpSHP = _wfopen(pszFullname, L"wb" ); |
955 |
|
if( fpSHP == NULL ) |
956 |
|
{ |
957 |
|
#ifdef USE_CPL |
958 |
|
CPLError( CE_Failure, CPLE_AppDefined, |
959 |
|
"Failed to create file." ); |
960 |
|
#endif |
961 |
|
return( NULL ); |
962 |
|
} |
963 |
|
|
964 |
|
swprintf( pszFullname, L"%s.shx", pszBasename ); |
965 |
|
fpSHX = _wfopen(pszFullname, L"wb" ); |
966 |
|
if( fpSHX == NULL ) |
967 |
|
{ |
968 |
|
#ifdef USE_CPL |
969 |
|
CPLError( CE_Failure, CPLE_AppDefined, |
970 |
|
"Failed to create file." ); |
971 |
|
#endif |
972 |
return( NULL ); |
return( NULL ); |
973 |
|
} |
974 |
|
|
975 |
free( pszFullname ); |
free( pszFullname ); |
976 |
free( pszBasename ); |
free( pszBasename ); |
977 |
|
|
978 |
|
SHPCreateEx( fpSHP, fpSHX, nShapeType ); |
979 |
|
|
980 |
|
/* -------------------------------------------------------------------- */ |
981 |
|
/* Close the files, and then open them as regular existing files. */ |
982 |
|
/* -------------------------------------------------------------------- */ |
983 |
|
fclose( fpSHP ); |
984 |
|
fclose( fpSHX ); |
985 |
|
|
986 |
|
return( SHPOpenW( pszLayer, L"r+b" ) ); |
987 |
|
} |
988 |
|
|
989 |
|
#endif |
990 |
|
|
991 |
|
/************************************************************************/ |
992 |
|
/* SHPCreateEx() */ |
993 |
|
/* */ |
994 |
|
/* Create a new shape file and return a handle to the open */ |
995 |
|
/* shape file with read/write access. */ |
996 |
|
/************************************************************************/ |
997 |
|
|
998 |
|
void SHPAPI_CALL |
999 |
|
SHPCreateEx( FILE * fpSHP, FILE * fpSHX, int nShapeType ) |
1000 |
|
|
1001 |
|
{ |
1002 |
|
int i; |
1003 |
|
uchar abyHeader[100]; |
1004 |
|
int32 i32; |
1005 |
|
double dValue; |
1006 |
|
|
1007 |
|
/* -------------------------------------------------------------------- */ |
1008 |
|
/* Establish the byte order on this system. */ |
1009 |
|
/* -------------------------------------------------------------------- */ |
1010 |
|
i = 1; |
1011 |
|
if( *((uchar *) &i) == 1 ) |
1012 |
|
bBigEndian = FALSE; |
1013 |
|
else |
1014 |
|
bBigEndian = TRUE; |
1015 |
|
|
1016 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1017 |
/* Prepare header block for .shp file. */ |
/* Prepare header block for .shp file. */ |
1018 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1043 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1044 |
/* Write .shp file header. */ |
/* Write .shp file header. */ |
1045 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1046 |
fwrite( abyHeader, 100, 1, fpSHP ); |
if( fwrite( abyHeader, 100, 1, fpSHP ) != 1 ) |
1047 |
|
{ |
1048 |
|
#ifdef USE_CPL |
1049 |
|
CPLError( CE_Failure, CPLE_AppDefined, |
1050 |
|
"Failed to write .shp header." ); |
1051 |
|
#endif |
1052 |
|
return; |
1053 |
|
} |
1054 |
|
|
1055 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1056 |
/* Prepare, and write .shx file header. */ |
/* Prepare, and write .shx file header. */ |
1059 |
ByteCopy( &i32, abyHeader+24, 4 ); |
ByteCopy( &i32, abyHeader+24, 4 ); |
1060 |
if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); |
if( !bBigEndian ) SwapWord( 4, abyHeader+24 ); |
1061 |
|
|
1062 |
fwrite( abyHeader, 100, 1, fpSHX ); |
if( fwrite( abyHeader, 100, 1, fpSHX ) != 1 ) |
1063 |
|
{ |
1064 |
/* -------------------------------------------------------------------- */ |
#ifdef USE_CPL |
1065 |
/* Close the files, and then open them as regular existing files. */ |
CPLError( CE_Failure, CPLE_AppDefined, |
1066 |
/* -------------------------------------------------------------------- */ |
"Failed to write .shx header." ); |
1067 |
fclose( fpSHP ); |
#endif |
1068 |
fclose( fpSHX ); |
return; |
1069 |
|
} |
|
return( SHPOpen( pszLayer, "r+b" ) ); |
|
1070 |
} |
} |
1071 |
|
|
1072 |
|
|
1073 |
/************************************************************************/ |
/************************************************************************/ |
1074 |
/* _SHPSetBounds() */ |
/* _SHPSetBounds() */ |
1075 |
/* */ |
/* */ |
1270 |
SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject ) |
SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject ) |
1271 |
|
|
1272 |
{ |
{ |
1273 |
int nRecordOffset, i, nRecordSize; |
int nRecordOffset, i, nRecordSize=0; |
1274 |
uchar *pabyRec; |
uchar *pabyRec; |
1275 |
int32 i32; |
int32 i32; |
1276 |
|
|
1584 |
if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0 |
if( fseek( psSHP->fpSHP, nRecordOffset, 0 ) != 0 |
1585 |
|| fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 ) |
|| fwrite( pabyRec, nRecordSize, 1, psSHP->fpSHP ) < 1 ) |
1586 |
{ |
{ |
1587 |
printf( "Error in fseek() or fwrite().\n" ); |
#ifdef USE_CPL |
1588 |
|
CPLError( CE_Failure, CPLE_FileIO, |
1589 |
|
"Error in fseek() or fwrite() writing object to .shp file." ); |
1590 |
|
#endif |
1591 |
free( pabyRec ); |
free( pabyRec ); |
1592 |
return -1; |
return -1; |
1593 |
} |
} |
1600 |
if( psSHP->adBoundsMin[0] == 0.0 |
if( psSHP->adBoundsMin[0] == 0.0 |
1601 |
&& psSHP->adBoundsMax[0] == 0.0 |
&& psSHP->adBoundsMax[0] == 0.0 |
1602 |
&& psSHP->adBoundsMin[1] == 0.0 |
&& psSHP->adBoundsMin[1] == 0.0 |
1603 |
&& psSHP->adBoundsMax[1] == 0.0 |
&& psSHP->adBoundsMax[1] == 0.0 ) |
|
&& psObject->nSHPType != SHPT_NULL ) |
|
1604 |
{ |
{ |
1605 |
psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0]; |
if( psObject->nSHPType == SHPT_NULL || psObject->nVertices == 0 ) |
1606 |
psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0]; |
{ |
1607 |
psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0]; |
psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = 0.0; |
1608 |
psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0]; |
psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = 0.0; |
1609 |
|
psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = 0.0; |
1610 |
|
psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = 0.0; |
1611 |
|
} |
1612 |
|
else |
1613 |
|
{ |
1614 |
|
psSHP->adBoundsMin[0] = psSHP->adBoundsMax[0] = psObject->padfX[0]; |
1615 |
|
psSHP->adBoundsMin[1] = psSHP->adBoundsMax[1] = psObject->padfY[0]; |
1616 |
|
psSHP->adBoundsMin[2] = psSHP->adBoundsMax[2] = psObject->padfZ[0]; |
1617 |
|
psSHP->adBoundsMin[3] = psSHP->adBoundsMax[3] = psObject->padfM[0]; |
1618 |
|
} |
1619 |
} |
} |
1620 |
|
|
1621 |
for( i = 0; i < psObject->nVertices; i++ ) |
for( i = 0; i < psObject->nVertices; i++ ) |
1664 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1665 |
/* Read the record. */ |
/* Read the record. */ |
1666 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1667 |
fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ); |
if( fseek( psSHP->fpSHP, psSHP->panRecOffset[hEntity], 0 ) != 0 |
1668 |
fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, psSHP->fpSHP ); |
|| fread( psSHP->pabyRec, psSHP->panRecSize[hEntity]+8, 1, |
1669 |
|
psSHP->fpSHP ) != 1 ) |
1670 |
|
{ |
1671 |
|
#ifdef USE_CPL |
1672 |
|
CPLError( CE_Failure, CPLE_FileIO, |
1673 |
|
"Error in fseek() or fread() reading object from .shp file." ); |
1674 |
|
#endif |
1675 |
|
return NULL; |
1676 |
|
} |
1677 |
|
|
1678 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
1679 |
/* Allocate and minimally initialize the object. */ |
/* Allocate and minimally initialize the object. */ |
2111 |
&& psObject->nSHPType != SHPT_POLYGONM ) |
&& psObject->nSHPType != SHPT_POLYGONM ) |
2112 |
return 0; |
return 0; |
2113 |
|
|
2114 |
|
if( psObject->nVertices == 0 || psObject->nParts == 0 ) |
2115 |
|
return 0; |
2116 |
|
|
2117 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |
2118 |
/* Process each of the rings. */ |
/* Process each of the rings. */ |
2119 |
/* -------------------------------------------------------------------- */ |
/* -------------------------------------------------------------------- */ |