inline void visitShape(const SHPObject& shape, Tags& tags, Visitor& visitor) const { switch (shape.nSHPType) { case SHPT_POINT: case SHPT_POINTM: case SHPT_POINTZ: visitPoint(shape, tags, visitor); break; case SHPT_ARC: case SHPT_ARCZ: case SHPT_ARCM: visitArc(shape, tags, visitor); break; case SHPT_POLYGON: case SHPT_POLYGONZ: case SHPT_POLYGONM: visitPolygon(shape, tags, visitor); break; case SHPT_MULTIPOINT: case SHPT_MULTIPOINTZ: case SHPT_MULTIPOINTM: case SHPT_MULTIPATCH: std::cerr << "Unsupported shape type:" << SHPTypeName(shape.nSHPType); break; default: std::cerr << "Unknown shape type:" << SHPTypeName(shape.nSHPType); break; } }
/* -------------------------------------------------------------------- */ void printSHP(SHPHandle iSHP, int iRecord) { const char *pszPlus; SHPObject *psShape; int j, iPart; psShape = SHPReadObject( iSHP, iRecord ); printf( "%s", SHPTypeName(psShape->nSHPType)); for( j = 0, iPart = 1; j < psShape->nVertices; j++ ) { const char *pszPartType = ""; if( j == 0 && psShape->nParts > 0 ) pszPartType = SHPPartTypeName( psShape->panPartType[0] ); if( iPart < psShape->nParts && psShape->panPartStart[iPart] == j ) { pszPartType = SHPPartTypeName( psShape->panPartType[iPart] ); iPart++; pszPlus = "+"; } else pszPlus = " "; printf("%s%.3f-%.3f", pszPlus, psShape->padfX[j], psShape->padfY[j] ); if( psShape->padfZ[j] || psShape->padfM[j] ) { printf("(%g, %g) %s \n", psShape->padfZ[j], psShape->padfM[j], pszPartType ); } } SHPDestroyObject( psShape ); }
/* -------------------------------------------------------------------- */ void printHeader(DBFHandle xDBF, SHPHandle xSHP) { double adfMinBound[4], adfMaxBound[4]; int xEntities; int xShapeType; int nWidth, nDecimals; int i; char szTitle[12]; SHPGetInfo( xSHP, &xEntities, &xShapeType, adfMinBound, adfMaxBound ); printf( "Shapefile Type: %s, %d shapes ", SHPTypeName( xShapeType ), xEntities ); printf( "%d database records\n", DBFGetRecordCount(xDBF) ); if( bVerbose ) { for( i = 0; i < DBFGetFieldCount(xDBF); i++ ) { DBFFieldType eType; const char *pszTypeName; eType = DBFGetFieldInfo( xDBF, i, szTitle, &nWidth, &nDecimals ); if( eType == FTString ) pszTypeName = "String"; else if( eType == FTInteger ) pszTypeName = "Integer"; else if( eType == FTDouble ) pszTypeName = "Double"; else if( eType == FTInvalid ) pszTypeName = "Invalid"; printf( "Field %d: Type=%s, Title=`%s', Width=%d, Decimals=%d\n", i, pszTypeName, szTitle, nWidth, nDecimals ); } } }
int main (int argc, char **argv) { SHPLOADERCONFIG *config; SHPLOADERSTATE *state; char *header, *footer, *record; int c; int ret, i; #ifdef ENABLE_NLS setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, PGSQL_LOCALEDIR); textdomain (PACKAGE); #endif /* If no options are specified, display usage */ if (argc == 1) { usage(); exit(0); } /* Parse command line options and set configuration */ config = malloc(sizeof(SHPLOADERCONFIG)); set_loader_config_defaults(config); /* Keep the flag list alphabetic so it's easy to see what's left. */ while ((c = pgis_getopt(argc, argv, "acdeg:iknps:t:wDGIN:ST:W:X:")) != EOF) { switch (c) { case 'c': case 'd': case 'a': case 'p': config->opt = c; break; case 'D': config->dump_format = 1; break; case 'G': config->geography = 1; break; case 'S': config->simple_geometries = 1; break; case 's': if (pgis_optarg) { char *ptr = strchr(pgis_optarg, ':'); if (ptr) { *ptr++ = '\0'; sscanf(pgis_optarg, "%d", &config->shp_sr_id); sscanf(ptr, "%d", &config->sr_id); } else { /* Only TO_SRID specified */ sscanf(pgis_optarg, "%d", &config->sr_id); } } else { /* With -s, user must specify TO_SRID or FROM_SRID:TO_SRID */ fprintf(stderr, "The -s parameter must be specified in the form [FROM_SRID:]TO_SRID\n"); exit(1); } break; case 'g': config->geo_col = pgis_optarg; break; case 'k': config->quoteidentifiers = 1; break; case 'i': config->forceint4 = 1; break; case 'I': config->createindex = 1; break; case 'w': config->use_wkt = 1; break; case 'n': config->readshape = 0; break; case 'W': config->encoding = pgis_optarg; break; case 'N': switch (pgis_optarg[0]) { case 'a': config->null_policy = POLICY_NULL_ABORT; break; case 'i': config->null_policy = POLICY_NULL_INSERT; break; case 's': config->null_policy = POLICY_NULL_SKIP; break; default: fprintf(stderr, "Unsupported NULL geometry handling policy.\nValid policies: insert, skip, abort\n"); exit(1); } break; case 't': if (strcasecmp(pgis_optarg, "2D") == 0) { config->force_output = FORCE_OUTPUT_2D; } else if (strcasecmp(pgis_optarg, "3DZ") == 0 ) { config->force_output = FORCE_OUTPUT_3DZ; } else if (strcasecmp(pgis_optarg, "3DM") == 0 ) { config->force_output = FORCE_OUTPUT_3DM; } else if (strcasecmp(pgis_optarg, "4D") == 0 ) { config->force_output = FORCE_OUTPUT_4D; } else { fprintf(stderr, "Unsupported output type: %s\nValid output types are 2D, 3DZ, 3DM and 4D\n", pgis_optarg); exit(1); } break; case 'T': config->tablespace = pgis_optarg; break; case 'X': config->idxtablespace = pgis_optarg; break; case 'e': config->usetransaction = 0; break; case '?': usage(); exit(0); default: usage(); exit(0); } } /* Once we have parsed the arguments, make sure certain combinations are valid */ if (config->dump_format && !config->usetransaction) { fprintf(stderr, "Invalid argument combination - cannot use both -D and -e\n"); exit(1); } if (config->dump_format && config->shp_sr_id != SRID_UNKNOWN) { fprintf(stderr, "Invalid argument combination - cannot use -D with -s FROM_SRID:TO_SRID\n"); exit(1); } /* Determine the shapefile name from the next argument, if no shape file, exit. */ if (pgis_optind < argc) { config->shp_file = argv[pgis_optind]; pgis_optind++; } else { usage(); exit(0); } /* Determine the table and schema names from the next argument */ if (pgis_optind < argc) { char *strptr = argv[pgis_optind]; char *chrptr = strchr(strptr, '.'); /* OK, this is a schema-qualified table name... */ if (chrptr) { if ( chrptr == strptr ) { /* ".something" ??? */ usage(); exit(0); } /* Null terminate at the '.' */ *chrptr = '\0'; /* Copy in the parts */ config->schema = strdup(strptr); config->table = strdup(chrptr+1); } else { config->table = strdup(strptr); } } /* If the table parameter is not provided, use the shape file name as a proxy value. Strip out the .shp and the leading path information first. */ if ( config->shp_file && config->table == NULL) { char *shp_file = strdup(config->shp_file); char *ptr; for ( ptr = shp_file + strlen(shp_file); ptr > shp_file; ptr-- ) { if ( *ptr == '.' ) { *ptr = '\0'; } if ( *ptr == '/' || *ptr == '\\' ) { ptr++; break; } } config->table = strdup(ptr); free(shp_file); } /* Transform table name to lower case if no quoting specified */ if (!config->quoteidentifiers) { if ( config->table ) strtolower(config->table); if ( config->schema ) strtolower(config->schema); } /* Create the shapefile state object */ state = ShpLoaderCreate(config); /* Open the shapefile */ ret = ShpLoaderOpenShape(state); if (ret != SHPLOADEROK) { fprintf(stderr, "%s\n", state->message); if (ret == SHPLOADERERR) exit(1); } /* If reading the whole shapefile, display its type */ if (state->config->readshape) { fprintf(stderr, "Shapefile type: %s\n", SHPTypeName(state->shpfiletype)); fprintf(stderr, "Postgis type: %s[%d]\n", state->pgtype, state->pgdims); } /* Print the header to stdout */ ret = ShpLoaderGetSQLHeader(state, &header); if (ret != SHPLOADEROK) { fprintf(stderr, "%s\n", state->message); if (ret == SHPLOADERERR) exit(1); } printf("%s", header); free(header); /* If we are not in "prepare" mode, go ahead and write out the data. */ if ( state->config->opt != 'p' ) { /* If in COPY mode, output the COPY statement */ if (state->config->dump_format) { ret = ShpLoaderGetSQLCopyStatement(state, &header); if (ret != SHPLOADEROK) { fprintf(stderr, "%s\n", state->message); if (ret == SHPLOADERERR) exit(1); } printf("%s", header); free(header); } /* Main loop: iterate through all of the records and send them to stdout */ for (i = 0; i < ShpLoaderGetRecordCount(state); i++) { ret = ShpLoaderGenerateSQLRowStatement(state, i, &record); switch (ret) { case SHPLOADEROK: /* Simply display the geometry */ printf("%s\n", record); free(record); break; case SHPLOADERERR: /* Display the error message then stop */ fprintf(stderr, "%s\n", state->message); exit(1); break; case SHPLOADERWARN: /* Display the warning, but continue */ fprintf(stderr, "%s\n", state->message); printf("%s\n", record); free(record); break; case SHPLOADERRECDELETED: /* Record is marked as deleted - ignore */ break; case SHPLOADERRECISNULL: /* Record is NULL and should be ignored according to NULL policy */ break; } } /* If in COPY mode, terminate the COPY statement */ if (state->config->dump_format) printf("\\.\n"); } /* Print the footer to stdout */ ret = ShpLoaderGetSQLFooter(state, &footer); if (ret != SHPLOADEROK) { fprintf(stderr, "%s\n", state->message); if (ret == SHPLOADERERR) exit(1); } printf("%s", footer); free(footer); /* Free the state object */ ShpLoaderDestroy(state); /* Free configuration variables */ if (config->schema) free(config->schema); if (config->table) free(config->table); free(config); return 0; }
int main( int argc, char ** argv ) { SHPHandle hSHP; int nShapeType, nEntities, i, iPart, bValidate = 0,nInvalidCount=0; int bHeaderOnly = 0; const char *pszPlus; double adfMinBound[4], adfMaxBound[4]; if( argc > 1 && strcmp(argv[1],"-validate") == 0 ) { bValidate = 1; argv++; argc--; } if( argc > 1 && strcmp(argv[1],"-ho") == 0 ) { bHeaderOnly = 1; argv++; argc--; } /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc != 2 ) { printf( "shpdump [-validate] [-ho] shp_file\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( argv[1], "rb" ); if( hSHP == NULL ) { printf( "Unable to open:%s\n", argv[1] ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Print out the file bounds. */ /* -------------------------------------------------------------------- */ SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound ); printf( "Shapefile Type: %s # of Shapes: %d\n\n", SHPTypeName( nShapeType ), nEntities ); printf( "File Bounds: (%.15g,%.15g,%.15g,%.15g)\n" " to (%.15g,%.15g,%.15g,%.15g)\n", adfMinBound[0], adfMinBound[1], adfMinBound[2], adfMinBound[3], adfMaxBound[0], adfMaxBound[1], adfMaxBound[2], adfMaxBound[3] ); /* -------------------------------------------------------------------- */ /* Skim over the list of shapes, printing all the vertices. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nEntities && !bHeaderOnly; i++ ) { int j; SHPObject *psShape; psShape = SHPReadObject( hSHP, i ); if( psShape == NULL ) { fprintf( stderr, "Unable to read shape %d, terminating object reading.\n", i ); break; } if( psShape->bMeasureIsUsed ) printf( "\nShape:%d (%s) nVertices=%d, nParts=%d\n" " Bounds:(%.15g,%.15g, %.15g, %.15g)\n" " to (%.15g,%.15g, %.15g, %.15g)\n", i, SHPTypeName(psShape->nSHPType), psShape->nVertices, psShape->nParts, psShape->dfXMin, psShape->dfYMin, psShape->dfZMin, psShape->dfMMin, psShape->dfXMax, psShape->dfYMax, psShape->dfZMax, psShape->dfMMax ); else printf( "\nShape:%d (%s) nVertices=%d, nParts=%d\n" " Bounds:(%.15g,%.15g, %.15g)\n" " to (%.15g,%.15g, %.15g)\n", i, SHPTypeName(psShape->nSHPType), psShape->nVertices, psShape->nParts, psShape->dfXMin, psShape->dfYMin, psShape->dfZMin, psShape->dfXMax, psShape->dfYMax, psShape->dfZMax ); if( psShape->nParts > 0 && psShape->panPartStart[0] != 0 ) { fprintf( stderr, "panPartStart[0] = %d, not zero as expected.\n", psShape->panPartStart[0] ); } for( j = 0, iPart = 1; j < psShape->nVertices; j++ ) { const char *pszPartType = ""; if( j == 0 && psShape->nParts > 0 ) pszPartType = SHPPartTypeName( psShape->panPartType[0] ); if( iPart < psShape->nParts && psShape->panPartStart[iPart] == j ) { pszPartType = SHPPartTypeName( psShape->panPartType[iPart] ); iPart++; pszPlus = "+"; } else pszPlus = " "; if( psShape->bMeasureIsUsed ) printf(" %s (%.15g,%.15g, %.15g, %.15g) %s \n", pszPlus, psShape->padfX[j], psShape->padfY[j], psShape->padfZ[j], psShape->padfM[j], pszPartType ); else printf(" %s (%.15g,%.15g, %.15g) %s \n", pszPlus, psShape->padfX[j], psShape->padfY[j], psShape->padfZ[j], pszPartType ); } if( bValidate ) { int nAltered = SHPRewindObject( hSHP, psShape ); if( nAltered > 0 ) { printf( " %d rings wound in the wrong direction.\n", nAltered ); nInvalidCount++; } } SHPDestroyObject( psShape ); } SHPClose( hSHP ); if( bValidate ) { printf( "%d object has invalid ring orderings.\n", nInvalidCount ); } #ifdef USE_DBMALLOC malloc_dump(2); #endif exit( 0 ); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) { /* Pointer to temporary matlab array */ const mxArray *mx; mxArray *m_shape_type; int nShapeType, nEntities, i, j, k, iPart, nFields, nStructElem, isPoint, firstInPoints = 1; int num_dbf_fields, num_dbf_records; /* number of DBF attributes, records */ int buflen; /* length of input shapefile name */ int status; /* success or failure */ char *shapefile; /* holder for input shapefile name */ const char *pszPartType = ""; /* Not used. */ double adfMinBound[4], adfMaxBound[4]; /* pointer to the shapefile */ SHPHandle hSHP; SHPObject *psShape; DBFHandle dbh; /* handle for DBF file */ /* This structure will hold a description of each field in the DBF file. */ typedef struct DBF_Field_Descriptor { char pszFieldName[12]; DBFFieldType field_type; } DBF_Field_Descriptor; DBF_Field_Descriptor *dbf_field; /* stores individual values from the DBF. */ int dbf_integer_val, dims[2], *p_parts_ptr, nNaNs, c, i_start, i_stop; char *dbf_char_val, error_buffer[500]; char *fnames[100]; /* holds name of fields */ mxArray *out_struct, *x_out, *y_out, *z_out, *bbox, *p_parts; double *x_out_ptr, *y_out_ptr, *z_out_ptr, *bb_ptr, nan, dbf_double_val; size_t sizebuf; /* Initialize the dbf record. */ dbf_field = NULL; /* Check for proper number of arguments */ if (nrhs != 1) mexErrMsgTxt("One input arguments are required."); if (nlhs != 2) mexErrMsgTxt("Two output arguments required."); /* Make sure the input is a proper string. */ if ( mxIsChar(prhs[0]) != 1 ) mexErrMsgTxt("Shapefile parameter must be a string\n" ); if ( mxGetM(prhs[0]) != 1 ) mexErrMsgTxt("Shapefile parameter must be a row vector, not a column string\n" ); buflen = mxGetN(prhs[0]) + 1; shapefile = mxCalloc( buflen, sizeof(char) ); /* copy the string data from prhs[0] into a C string. */ status = mxGetString( prhs[0], shapefile, buflen ); if ( status != 0 ) mxErrMsgTxt( "Not enough space for shapefile argument.\n" ); /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( shapefile, "rb" ); if( hSHP == NULL ) mxErrMsgTxt( "Unable to open:%s\n", shapefile ); /* -------------------------------------------------------------------- */ /* Get the needed information about the shapefile. */ /* -------------------------------------------------------------------- */ SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound ); /* Make sure that we can handle the type. */ switch ( nShapeType ) { case SHPT_POINT: break; case SHPT_POINTZ: break; case SHPT_ARC: break; case SHPT_ARCZ: break; case SHPT_POLYGON: break; case SHPT_POLYGONZ: break; case SHPT_MULTIPOINT: /* JL */ break; default: sprintf ( error_buffer, "Unhandled shape code %d (%s)", nShapeType, SHPTypeName ( nShapeType ) ); mexErrMsgTxt( error_buffer ); } /* Create the output shape type parameter. */ plhs[1] = mxCreateString ( SHPTypeName ( nShapeType ) ); /* Open the DBF, and retrieve the number of fields and records */ dbh = DBFOpen (shapefile, "rb"); num_dbf_fields = DBFGetFieldCount ( dbh ); num_dbf_records = DBFGetRecordCount ( dbh ); /* Allocate space for a description of each record, and populate it. * I allocate space for two extra "dummy" records that go in positions * 0 and 1. These I reserve for the xy data. */ nFields = 3; if ( (nShapeType == SHPT_POLYGONZ) || (nShapeType == SHPT_ARCZ) || (nShapeType == SHPT_POINTZ) ) nFields++; dbf_field = (DBF_Field_Descriptor *) mxMalloc ( (num_dbf_fields+nFields) * sizeof ( DBF_Field_Descriptor ) ); if ( dbf_field == NULL ) mexErrMsgTxt("Memory allocation for DBF_Field_Descriptor failed."); for ( j = 0; j < num_dbf_fields; ++j ) dbf_field[j+nFields].field_type = DBFGetFieldInfo ( dbh, j, dbf_field[j+nFields].pszFieldName, NULL, NULL ); fnames[0] = strdup ( "X" ); fnames[1] = strdup ( "Y" ); if ( (nShapeType == SHPT_POLYGONZ) || (nShapeType == SHPT_ARCZ) || (nShapeType == SHPT_POINTZ) ) { fnames[2] = strdup ( "Z" ); fnames[3] = strdup ( "BoundingBox" ); } else fnames[2] = strdup ( "BoundingBox" ); for ( j = 0; j < num_dbf_fields; ++j ) fnames[j+nFields] = strdup ( dbf_field[j+nFields].pszFieldName ); /* To hold information on eventual polygons with rings */ /*fnames[num_dbf_fields+3] = strdup ( "nParts" );*/ /*fnames[num_dbf_fields+4] = strdup ( "PartsIndex" );*/ /* Allocate space for the output structure. */ isPoint = ( nShapeType == SHPT_POINT || nShapeType == SHPT_POINTZ ) ? 1: 0; nStructElem = ( nShapeType == SHPT_POINT || nShapeType == SHPT_POINTZ ) ? 1: nEntities; out_struct = mxCreateStructMatrix ( nStructElem, 1, nFields + num_dbf_fields, (const char **)fnames ); /* create the BoundingBox */ dims[0] = 4; dims[1] = 2; bbox = mxCreateNumericArray ( 2, dims, mxDOUBLE_CLASS, mxREAL ); bb_ptr = mxGetData ( bbox ); for (i = 0; i < 4; i++) bb_ptr[i] = adfMinBound[i]; for (i = 0; i < 4; i++) bb_ptr[i+4] = adfMaxBound[i]; mxSetField ( out_struct, 0, "BoundingBox", bbox ); nan = mxGetNaN(); /* -------------------------------------------------------------------- */ /* Skim over the list of shapes, printing all the vertices. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nEntities; i++ ) { psShape = SHPReadObject( hSHP, i ); /* Create the fields in this struct element. */ if ( !isPoint ) { nNaNs = psShape->nParts > 1 ? psShape->nParts : 0; dims[0] = psShape->nVertices + nNaNs; dims[1] = 1; x_out = mxCreateNumericArray ( 2, dims, mxDOUBLE_CLASS, mxREAL ); x_out_ptr = mxGetData ( x_out ); y_out = mxCreateNumericArray ( 2, dims, mxDOUBLE_CLASS, mxREAL ); y_out_ptr = mxGetData ( y_out ); if ( (nShapeType == SHPT_POLYGONZ) || (nShapeType == SHPT_POINTZ) || (nShapeType == SHPT_ARCZ)) { z_out = mxCreateNumericArray ( 2, dims, mxDOUBLE_CLASS, mxREAL ); z_out_ptr = mxGetData ( z_out ); } } else if (firstInPoints) { /* Allocate all memory we'll need */ x_out = mxCreateDoubleMatrix (nEntities, 1, mxREAL); x_out_ptr = mxGetPr ( x_out ); y_out = mxCreateDoubleMatrix (nEntities, 1, mxREAL); y_out_ptr = mxGetPr ( y_out ); if (nShapeType == SHPT_POINTZ) { z_out = mxCreateDoubleMatrix (nEntities, 1, mxREAL); z_out_ptr = mxGetPr ( z_out ); } firstInPoints = 0; } if (!isPoint && psShape->nParts > 1) { for (k = c = 0; k < psShape->nParts; k++) { i_start = psShape->panPartStart[k]; if (k < psShape->nParts - 1) i_stop = psShape->panPartStart[k+1]; else i_stop = psShape->nVertices; if ( nShapeType == SHPT_POLYGONZ ) { for (j = i_start; j < i_stop; c++, j++) { x_out_ptr[c] = psShape->padfX[j]; y_out_ptr[c] = psShape->padfY[j]; z_out_ptr[c] = psShape->padfZ[j]; } x_out_ptr[c] = nan; y_out_ptr[c] = nan; z_out_ptr[c] = nan; } else { for (j = i_start; j < i_stop; c++, j++) { x_out_ptr[c] = psShape->padfX[j]; y_out_ptr[c] = psShape->padfY[j]; } x_out_ptr[c] = nan; y_out_ptr[c] = nan; } c++; } } else if ( isPoint ) { x_out_ptr[i] = *psShape->padfX; y_out_ptr[i] = *psShape->padfY; if (nShapeType == SHPT_POINTZ) z_out_ptr[i] = *psShape->padfZ; if (i > 0) { SHPDestroyObject( psShape ); continue; } } else { /* Just copy the vertices over. */ sizebuf = mxGetElementSize ( x_out ) * psShape->nVertices; memcpy ( (void *) x_out_ptr, (void *) psShape->padfX, sizebuf ); memcpy ( (void *) y_out_ptr, (void *) psShape->padfY, sizebuf ); if ( (nShapeType == SHPT_POLYGONZ) || (nShapeType == SHPT_ARCZ)) memcpy ( (void *) z_out_ptr, (void *) psShape->padfZ, sizebuf ); } mxSetField ( out_struct, i, "X", x_out ); mxSetField ( out_struct, i, "Y", y_out ); if ( (nShapeType == SHPT_POLYGONZ) || (nShapeType == SHPT_ARCZ) ) mxSetField ( out_struct, i, "Z", z_out ); bbox = mxCreateNumericMatrix ( 4, 2, mxDOUBLE_CLASS, mxREAL ); bb_ptr = (double *)mxGetData ( bbox ); bb_ptr[0] = psShape->dfXMin; bb_ptr[1] = psShape->dfYMin; bb_ptr[2] = psShape->dfZMin; bb_ptr[3] = psShape->dfMMin; bb_ptr[4] = psShape->dfXMax; bb_ptr[5] = psShape->dfYMax; bb_ptr[6] = psShape->dfZMax; bb_ptr[7] = psShape->dfMMax; if (i > 0) /* First BB contains the ensemble extent */ mxSetField ( out_struct, i, "BoundingBox", bbox ); for ( j = 0; j < num_dbf_fields; ++j ) { switch ( dbf_field[j+nFields].field_type ) { case FTString: dbf_char_val = (char *) DBFReadStringAttribute ( dbh, i, j ); mxSetField ( out_struct, i, dbf_field[j+nFields].pszFieldName, mxCreateString ( dbf_char_val ) ); break; case FTDouble: dbf_double_val = DBFReadDoubleAttribute ( dbh, i, j ); mxSetField ( out_struct, i, dbf_field[j+nFields].pszFieldName, mxCreateDoubleScalar ( dbf_double_val ) ); break; case FTInteger: case FTLogical: dbf_integer_val = DBFReadIntegerAttribute ( dbh, i, j ); dbf_double_val = dbf_integer_val; mxSetField ( out_struct, i, dbf_field[j+nFields].pszFieldName, mxCreateDoubleScalar ( dbf_double_val ) ); break; default: sprintf ( error_buffer, "Unhandled code %d, shape %d, record %d\n", dbf_field[j+nFields].field_type, i, j ); mexErrMsgTxt("Unhandled code"); } } SHPDestroyObject( psShape ); } if ( isPoint ) { /* In this case we still need to "send the true data out" */ mxSetField ( out_struct, 0, "X", x_out ); mxSetField ( out_struct, 0, "Y", y_out ); if (nShapeType == SHPT_POINTZ) mxSetField ( out_struct, 0, "Z", z_out ); } /* Clean up, close up shop. */ SHPClose( hSHP ); DBFClose ( dbh ); if ( dbf_field != NULL ) mxFree ( (void *)dbf_field ); plhs[0] = out_struct; }
int main(int argc, char *argv[]) { int opt; size_t i; const char *argv0 = argv[0]; struct rt_wdb *fd_out; struct bu_vls vls_in = BU_VLS_INIT_ZERO; struct bu_vls vls_out = BU_VLS_INIT_ZERO; int opt_debug = 0; int opt_verbose = 0; /* shapelib vars */ SHPHandle shapefile; size_t shp_num_invalid = 0; int shp_num_entities = 0; int shp_type = 0; /* intentionally double for scan */ double shp_min[4] = HINIT_ZERO; double shp_max[4] = HINIT_ZERO; /* geometry */ point2d_t *verts = NULL; size_t num_verts = 0; if (argc < 2) { usage(argv0); bu_exit(1, NULL); } while ((opt = bu_getopt(argc, argv, "dxv")) != -1) { switch (opt) { case 'd': opt_debug = 1; break; case 'x': sscanf(bu_optarg, "%x", (unsigned int *) &RTG.debug); bu_printb("librt RT_G_DEBUG", RT_G_DEBUG, DEBUG_FORMAT); bu_log("\n"); break; case 'v': opt_verbose++; break; default: usage(argv0); bu_exit(1, NULL); break; } } argv += bu_optind; argc -= bu_optind; if (opt_verbose) bu_log("Verbose output enabled.\n"); if (opt_debug) bu_log("Debugging output enabled.\n"); /* validate input/output file specifiers */ if (argc < 1) { usage(argv0); bu_exit(1, "ERROR: Missing input and output file names\n"); } bu_vls_strcat(&vls_in, argv[0]); if (argc < 2) { bu_vls_printf(&vls_out, "%s.g", argv[0]); } else { bu_vls_strcat(&vls_out, argv[1]); } if (opt_verbose) { bu_log("Reading from [%s]\n", bu_vls_addr(&vls_in)); bu_log("Writing to [%s]\n\n", bu_vls_addr(&vls_out)); } /* initialize single threaded resource */ rt_init_resource(&rt_uniresource, 0, NULL); /* open the input */ shapefile = SHPOpen(bu_vls_addr(&vls_in), "rb"); if (!shapefile) { bu_log("ERROR: Unable to open shapefile [%s]\n", bu_vls_addr(&vls_in)); bu_vls_free(&vls_in); bu_vls_free(&vls_out); bu_exit(4, NULL); } /* print shapefile details */ if (opt_verbose) { SHPGetInfo(shapefile, &shp_num_entities, &shp_type, shp_min, shp_max); bu_log("Shapefile Type: %s\n", SHPTypeName(shp_type)); bu_log("# of Shapes: %d\n\n", shp_num_entities); bu_log("File Bounds: (%12.3f,%12.3f, %.3g, %.3g)\n" " to (%12.3f,%12.3f, %.3g, %.3g)\n", shp_min[0], shp_min[1], shp_min[2], shp_min[3], shp_max[0], shp_max[1], shp_max[2], shp_max[3]); } /* open the .g for writing */ if ((fd_out = wdb_fopen(bu_vls_addr(&vls_out))) == NULL) { bu_log("ERROR: Unable to open shapefile [%s]\n", bu_vls_addr(&vls_out)); bu_vls_free(&vls_in); bu_vls_free(&vls_out); perror(argv0); bu_exit(5, NULL); } /* iterate over all entities */ for (i=0; i < (size_t)shp_num_entities; i++) { SHPObject *object; int shp_part; size_t j; object = SHPReadObject(shapefile, i); if (!object) { if (opt_debug) bu_log("Shape %zu of %zu is missing, skipping.\n", i+1, (size_t)shp_num_entities); continue; } /* validate the object */ if (opt_debug) { int shp_altered = SHPRewindObject(shapefile, object); if (shp_altered > 0) { bu_log("WARNING: Shape %zu of %zu has [%d] bad loop orientations.\n", i+1, (size_t)shp_num_entities, shp_altered); shp_num_invalid++; } } /* print detail header */ if (opt_verbose) { if (object->bMeasureIsUsed) { bu_log("\nShape:%zu (%s) nVertices=%d, nParts=%d\n" " Bounds:(%12.3f,%12.3f, %g, %g)\n" " to (%12.3f,%12.3f, %g, %g)\n", i+1, SHPTypeName(object->nSHPType), object->nVertices, object->nParts, object->dfXMin, object->dfYMin, object->dfZMin, object->dfMMin, object->dfXMax, object->dfYMax, object->dfZMax, object->dfMMax); } else { bu_log("\nShape:%zu (%s) nVertices=%d, nParts=%d\n" " Bounds:(%12.3f,%12.3f, %g)\n" " to (%12.3f,%12.3f, %g)\n", i+1, SHPTypeName(object->nSHPType), object->nVertices, object->nParts, object->dfXMin, object->dfYMin, object->dfZMin, object->dfXMax, object->dfYMax, object->dfZMax); } if (object->nParts > 0 && object->panPartStart[0] != 0) { if (opt_debug) bu_log("Shape %zu of %zu: panPartStart[0] = %d, not zero as expected.\n", i+1, (size_t)shp_num_entities, object->panPartStart[0]); continue; } } num_verts = 0; verts = (point2d_t *)bu_calloc((size_t)object->nVertices, sizeof(point2d_t), "alloc point array"); for (j = 0, shp_part = 1; j < (size_t)object->nVertices; j++) { if (shp_part < object->nParts && j == (size_t)object->panPartStart[shp_part]) { shp_part++; bu_log("Shape %zu of %zu: End of Loop\n", i+1, (size_t)shp_num_entities); make_shape(fd_out, opt_verbose, opt_debug, i, num_verts, verts); /* reset for next loop */ memset(verts, 0, sizeof(point2d_t) * object->nVertices); num_verts = 0; } bu_log("%zu/%zu:%zu/%zu\t\t", i+1, (size_t)shp_num_entities, j+1, (size_t)object->nVertices); bu_log("(%12.4f, %12.4f, %12.4f, %g)\n", object->padfX[j], object->padfY[j], object->padfZ[j], object->padfM[j]); V2SET(verts[num_verts], object->padfX[j], object->padfY[j]); num_verts++; } bu_log("Shape %zu of %zu: End of Loop\n", i+1, (size_t)shp_num_entities); make_shape(fd_out, opt_verbose, opt_debug, i, num_verts, verts); bu_free(verts, "free point array"); verts = NULL; num_verts = 0; SHPDestroyObject(object); object = NULL; } if (opt_verbose) { if (shp_num_invalid > 0) { bu_log("WARNING: %zu of %zu shape(s) had bad loop orientations.\n", shp_num_invalid, (size_t)shp_num_entities); } bu_log("\nDone.\n"); } /* close up our files */ SHPClose(shapefile); wdb_close(fd_out); /* free up allocated resources */ bu_vls_free(&vls_in); bu_vls_free(&vls_out); return 0; }
SEXP Rshapeget(SEXP shpnm, SEXP repair) { SHPHandle hSHP; int nShapeType, nEntities, qRep, i, pc=0; double adfMinBound[4], adfMaxBound[4]; int j, pz=0, k; SHPObject *psShape; SEXP Rshplst, shplistnms; SEXP temp0, temp1, temp2, temp3; /*#ifdef DEBUG PT Cent; double Area; #endif*/ /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen(CHAR(STRING_ELT(shpnm,0)), "rb" ); if( hSHP == NULL ) error("unable to open SHP or SHX file"); qRep = LOGICAL_POINTER(repair)[0]; /* file length implied by *.shx */ k = SHPCheck_SHX(hSHP); if (k == 1 && qRep == 0) { error("File size and implied file size differ, consider trying repair=TRUE"); /* implied file length greater than file size */ } if (qRep == 1 && k == 1) { j = SHPCheck_SHX_Geolytics(hSHP); if (j > 0) error("Cannot repair file size error"); if (j == 0) {/* Geolytics size + 8 bug */ for (i=1; i < hSHP->nRecords; i++) hSHP->panRecSize[i] = hSHP->panRecSize[i] - 8; warning("SHX object size off by 8 bug repaired"); } } /* -------------------------------------------------------------------- */ /* Print out the file bounds. */ /* -------------------------------------------------------------------- */ SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound ); /* Rprintf("Shapefile Type: %s # of Shapes: %d\n\n", SHPTypeName( nShapeType ), nEntities );*/ PROTECT(Rshplst=allocVector(VECSXP, nEntities)); pc++; PROTECT(temp0=allocVector(STRSXP, 1)); pc++; if(nShapeType==1){ /* POINT */ SET_STRING_ELT(temp0, 0, mkChar("point")); setAttrib(Rshplst, install("shp.type"), temp0); } else if(nShapeType==11){ /* POINTZ */ SET_STRING_ELT(temp0, 0, mkChar("point")); setAttrib(Rshplst, install("shp.type"), temp0); pz=1; } else if(nShapeType==3){ /* ARC */ SET_STRING_ELT(temp0, 0, mkChar("arc")); setAttrib(Rshplst, install("shp.type"), temp0); } else if(nShapeType==13){ /* ARCZ */ SET_STRING_ELT(temp0, 0, mkChar("arc")); setAttrib(Rshplst, install("shp.type"), temp0); } else if(nShapeType==5){/* POLYGON */ SET_STRING_ELT(temp0, 0, mkChar("poly")); setAttrib(Rshplst, install("shp.type"), temp0); } else if(nShapeType==15){/* POLYGONZ */ SET_STRING_ELT(temp0, 0, mkChar("poly")); setAttrib(Rshplst, install("shp.type"), temp0); } else if(nShapeType==8){ /* MULTIPOINT */ SET_STRING_ELT(temp0, 0, mkChar("point")); setAttrib(Rshplst, install("shp.type"), temp0); } else { Rprintf("Shapefile type: %s (%d), # of Shapes: %d\n\n", SHPTypeName( nShapeType ), nShapeType, nEntities ); error("Shapefile type not (yet) handled by this function"); } PROTECT(temp1=allocVector(INTSXP,1)); pc++; INTEGER(temp1)[0] = nEntities; setAttrib(Rshplst,install("nshps"),temp1); PROTECT(temp2=allocVector(REALSXP,4)); pc++; REAL(temp2)[0] = adfMinBound[0]; REAL(temp2)[1] = adfMinBound[1]; REAL(temp2)[2] = adfMinBound[2]; REAL(temp2)[3] = adfMinBound[3]; setAttrib(Rshplst,install("minbb"),temp2); PROTECT(temp3=allocVector(REALSXP,4)); pc++; REAL(temp3)[0] = adfMaxBound[0]; REAL(temp3)[1] = adfMaxBound[1]; REAL(temp3)[2] = adfMaxBound[2]; REAL(temp3)[3] = adfMaxBound[3]; setAttrib(Rshplst,install("maxbb"),temp3); /*-------------------------------------------------------------------- Skim over the list of shapes, printing all the vertices. --------------------------------------------------------------------*/ PROTECT(shplistnms = allocVector(STRSXP,7)); pc++; SET_STRING_ELT(shplistnms,0,mkChar("Pstart")); SET_STRING_ELT(shplistnms,1,mkChar("verts")); SET_STRING_ELT(shplistnms,2,mkChar("shp.type")); SET_STRING_ELT(shplistnms,3,mkChar("nVerts")); SET_STRING_ELT(shplistnms,4,mkChar("nParts")); SET_STRING_ELT(shplistnms,5,mkChar("bbox")); SET_STRING_ELT(shplistnms,6,mkChar("shpID")); for( i = 0; i < nEntities; i++ ) { psShape = SHPReadObject( hSHP, i); if (psShape == NULL) {/* Jon Wakefield 060428 */ Rprintf("Bailing out at geometry object %d of %d\n", i+1, nEntities); SHPClose(hSHP); error("Error in fseek() or fread() reading object from .shp file."); } if(nShapeType==8 && psShape->nVertices > 1){ Rprintf("Shapefile type: %s (%d), # of Shapes: %d\n", SHPTypeName( nShapeType ), nShapeType, nEntities ); Rprintf("Shape: %d has %d vertices\n", i, psShape->nVertices); error("Multipoint shapefile error"); } SET_VECTOR_ELT(Rshplst, i, allocVector(VECSXP, 7)); SET_VECTOR_ELT(VECTOR_ELT(Rshplst,i),0, allocVector(INTSXP,psShape->nParts)); if (pz == 0) SET_VECTOR_ELT(VECTOR_ELT(Rshplst,i),1, allocMatrix(REALSXP,psShape->nVertices,2)); else SET_VECTOR_ELT(VECTOR_ELT(Rshplst,i),1, allocMatrix(REALSXP,psShape->nVertices,3)); SET_VECTOR_ELT(VECTOR_ELT(Rshplst,i),2, allocVector(INTSXP,1)); SET_VECTOR_ELT(VECTOR_ELT(Rshplst,i),3, allocVector(INTSXP,1)); SET_VECTOR_ELT(VECTOR_ELT(Rshplst,i),4, allocVector(INTSXP,1)); SET_VECTOR_ELT(VECTOR_ELT(Rshplst,i),5, allocVector(REALSXP,4)); SET_VECTOR_ELT(VECTOR_ELT(Rshplst,i),6, allocVector(INTSXP,1)); INTEGER(VECTOR_ELT(VECTOR_ELT(Rshplst,i),2))[0]=psShape->nSHPType; INTEGER(VECTOR_ELT(VECTOR_ELT(Rshplst,i),3))[0]=psShape->nVertices; INTEGER(VECTOR_ELT(VECTOR_ELT(Rshplst,i),4))[0]=psShape->nParts; INTEGER(VECTOR_ELT(VECTOR_ELT(Rshplst,i),6))[0]=psShape->nShapeId; REAL(VECTOR_ELT(VECTOR_ELT(Rshplst,i),5))[0]=psShape->dfXMin; REAL(VECTOR_ELT(VECTOR_ELT(Rshplst,i),5))[1]=psShape->dfYMin; REAL(VECTOR_ELT(VECTOR_ELT(Rshplst,i),5))[2]=psShape->dfXMax; REAL(VECTOR_ELT(VECTOR_ELT(Rshplst,i),5))[3]=psShape->dfYMax; setAttrib(VECTOR_ELT(Rshplst,i),R_NamesSymbol,shplistnms); for( j = 0; j < psShape->nVertices; j++ ) { REAL(VECTOR_ELT(VECTOR_ELT(Rshplst,i),1))[j]=psShape->padfX[j]; REAL(VECTOR_ELT(VECTOR_ELT(Rshplst,i),1))[j+psShape->nVertices]= psShape->padfY[j]; if (pz == 1) REAL(VECTOR_ELT(VECTOR_ELT(Rshplst,i),1))[j + 2*(psShape->nVertices)]=psShape->padfZ[j]; } if(psShape->nParts > 0 ){ if(psShape->nParts == 1){ INTEGER(VECTOR_ELT(VECTOR_ELT(Rshplst,i),0))[0]=0; } else{ for(j = 0; j < psShape->nParts; j++ ) { INTEGER(VECTOR_ELT(VECTOR_ELT(Rshplst,i),0))[j]= psShape->panPartStart[j]; } } } SHPDestroyObject( psShape ); } SHPClose(hSHP); UNPROTECT(pc); return(Rshplst); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) { /* * Construct error and warning messages using this buffer. * */ char error_msg[500]; int nShapeType, nEntities, i, j; int buflen; /* length of input shapefile name */ char *shapefile; /* holder for input shapefile name */ int status; /* success or failure */ /* * Not used. * */ double adfMinBound[4], adfMaxBound[4]; /* * pointer to the shapefile * */ SHPHandle hSHP; SHPObject *psShape; /* * handle for DBF file * */ DBFHandle dbh; /* * number of DBF attributes, records * */ int num_dbf_fields, num_dbf_records; /* * This structure will hold a description of each field in the DBF file. * */ typedef struct DBF_Field_Descriptor { char pszFieldName[12]; DBFFieldType field_type; } DBF_Field_Descriptor; DBF_Field_Descriptor *dbf_field; /* * stores individual values from the DBF. * */ double dbf_double_val; int dbf_integer_val; char *dbf_char_val; char error_buffer[500]; char **att_fnames; /* holds name of fie */ /* holds name of fields for the shape structure */ char *shape_fnames[2] = { "x", "y" }; /* holds name of fields for the shape structure */ char *outstruct_fnames[3] = { "Shape", "Attribute", "Type" }; /* * Matlab structure to hold all output information. * */ mxArray *out_struct; /* * Matlab structure that holds the point information. * * */ mxArray *data_struct; /* * Matlab structure that holds the attribute information. * */ mxArray *att_struct; /* * * */ mxArray *x_out, *y_out; /* * temporary matlab array * */ mxArray *mxtmp; double *x_out_ptr, *y_out_ptr; /* * Shortcuts into the output arrays. * */ double *mx_ptr, *my_ptr; int part_start; /* start of a polygon part */ int part_count; /* how many vertices in a polygon part. */ int dims[2]; size_t sizebuf; /* * This string will describe the type of shapefile. * The possibilities are currently * * MultiPoint * Point * Arc * Polygon * */ char *shapeTypeString; /* * Initialize the dbf record. * */ dbf_field = NULL; /* Check for proper number of arguments */ if (nrhs != 1) { mexErrMsgTxt("One input argument is required."); } if (nlhs != 1) { mexErrMsgTxt("One output argument is required."); } /* * Make sure the input is a proper string. * */ if ( mxIsChar(prhs[0]) != 1 ) { mexErrMsgTxt("Shapefile parameter must be a string\n" ); } if ( mxGetM(prhs[0]) != 1 ) { mexErrMsgTxt("Shapefile parameter must be a row vector, not a column string\n" ); } buflen = mxGetN(prhs[0]) + 1; shapefile = mxCalloc ( buflen, sizeof(char) ); /* * copy the string data from prhs[0] into a C string. * */ status = mxGetString ( prhs[0], shapefile, buflen ); if ( status != 0 ) { mexErrMsgTxt ( "Not enough space for shapefile argument.\n" ); } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( shapefile, "rb" ); if( hSHP == NULL ) { sprintf ( error_msg, "Unable to open:%s\n", shapefile ); mexErrMsgTxt( error_msg ); } /* -------------------------------------------------------------------- */ /* Get the needed information about the shapefile. */ /* -------------------------------------------------------------------- */ SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound ); /* * Make sure that we can handle the type. * */ switch ( nShapeType ) { case SHPT_MULTIPOINT: case SHPT_POINT: case SHPT_ARC: case SHPT_POLYGON: break; default: sprintf ( error_buffer, "Unhandled shape code %d (%s)\n", nShapeType, SHPTypeName ( nShapeType ) ); mexErrMsgTxt( error_buffer ); } /* * Create the output shape type parameter. * */ shapeTypeString = (char *) SHPTypeName ( nShapeType ); /* * Open the DBF in order to retrieve the number of fields and records. * */ dbh = DBFOpen (shapefile, "rb"); num_dbf_fields = DBFGetFieldCount ( dbh ); num_dbf_records = DBFGetRecordCount ( dbh ); /* * Allocate space for a description of each record, and populate it. * I allocate space for two extra "dummy" records that go in positions * 0 and 1. These I reserve for the xy data. * */ dbf_field = (DBF_Field_Descriptor *) mxCalloc ( num_dbf_fields, sizeof ( DBF_Field_Descriptor ) ); if ( dbf_field == NULL ) { mexErrMsgTxt("Memory allocation for DBF_Field_Descriptor failed."); } for ( j = 0; j < num_dbf_fields; ++j ) { dbf_field[j].field_type = DBFGetFieldInfo ( dbh, j, dbf_field[j].pszFieldName, NULL, NULL ); } /* * Allocate space for the datapoint structure. * */ data_struct = mxCreateStructMatrix ( nEntities, 1, 2, (const char **)shape_fnames ); /* * Allocate space for the field names for the attributes. * According to the API, each field name can have up to 12 * characters. * */ att_fnames = (char **) mxCalloc ( num_dbf_fields, sizeof(char *) ); if ( att_fnames == NULL ) { mexErrMsgTxt("Memory allocation for attribute field names failed."); } /* * Copy the attribute names, create the matlab structure. * */ for ( j = 0; j < num_dbf_fields; ++j ) { att_fnames[j] = dbf_field[j].pszFieldName; } att_struct = mxCreateStructMatrix ( nEntities, 1, num_dbf_fields, (const char **)att_fnames ); /* -------------------------------------------------------------------- */ /* Skim over the list of shapes, printing all the vertices. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nEntities; i++ ) { psShape = SHPReadObject( hSHP, i ); /* fprintf ( stdout, "Num parts = %d\n", psShape->nParts ); */ /* * Create the fields in this struct element. * We will stick in one nan for each shape part. */ dims[0] = psShape->nVertices + psShape->nParts; dims[1] = 1; x_out = mxCreateNumericArray ( 2, dims, mxDOUBLE_CLASS, mxREAL ); x_out_ptr = mxGetData ( x_out ); y_out = mxCreateNumericArray ( 2, dims, mxDOUBLE_CLASS, mxREAL ); y_out_ptr = mxGetData ( y_out ); /* * Just copy the verticies over. * */ sizebuf = mxGetElementSize ( x_out ) * psShape->nVertices; mx_ptr = x_out_ptr; my_ptr = y_out_ptr; for ( j = 0; j < psShape->nParts-1; ++j ) { part_count = psShape->panPartStart[j+1] - psShape->panPartStart[j]; sizebuf = mxGetElementSize ( x_out ) * part_count; part_start = psShape->panPartStart[j]; memcpy ( (void *) (mx_ptr), (void *) &(psShape->padfX[part_start]), sizebuf ); memcpy ( (void *) (my_ptr), (void *) &(psShape->padfY[part_start]), sizebuf ); /* * Stick a nan here to separate the parts. * */ mx_ptr[part_count] = mxGetNaN(); my_ptr[part_count] = mxGetNaN(); /* * Update the pointers to the next part. * */ mx_ptr += (part_count+1); my_ptr += (part_count+1); } /* * Do the last one * * Special case if there is only a single point? * */ if ( psShape->nParts == 0 ) { memcpy ( (void *) (mx_ptr), (void *) &(psShape->padfX[0]), sizebuf ); memcpy ( (void *) (my_ptr), (void *) &(psShape->padfY[0]), sizebuf ); } else { part_count = psShape->nVertices - psShape->panPartStart[psShape->nParts-1]; sizebuf = mxGetElementSize ( x_out ) * part_count; part_start = psShape->panPartStart[psShape->nParts-1]; memcpy ( (void *) (mx_ptr), (void *) &(psShape->padfX[part_start]), sizebuf ); memcpy ( (void *) (my_ptr), (void *) &(psShape->padfY[part_start]), sizebuf ); /* * Stick a nan here to separate the parts. * */ mx_ptr[part_count] = mxGetNaN(); my_ptr[part_count] = mxGetNaN(); } mxSetField ( data_struct, i, "x", x_out ); mxSetField ( data_struct, i, "y", y_out ); /* * Now do the attributes * */ for ( j = 0; j < num_dbf_fields; ++j ) { switch ( dbf_field[j].field_type ) { case FTString: dbf_char_val = (char *) DBFReadStringAttribute ( dbh, i, j ); mxtmp = mxCreateString ( dbf_char_val ); mxSetField ( att_struct, i, dbf_field[j].pszFieldName, mxtmp ); break; case FTDouble: dbf_double_val = DBFReadDoubleAttribute ( dbh, i, j ); mxtmp = mxCreateDoubleScalar ( dbf_double_val ); mxSetField ( att_struct, i, dbf_field[j].pszFieldName, mxtmp ); break; case FTInteger: case FTLogical: dbf_integer_val = DBFReadIntegerAttribute ( dbh, i, j ); dbf_double_val = dbf_integer_val; mxtmp = mxCreateDoubleScalar ( dbf_double_val ); mxSetField ( att_struct, i, dbf_field[j].pszFieldName, mxtmp ); break; default: sprintf ( error_buffer, "Unhandled code %d, shape %d, record %d\n", dbf_field[j].field_type, i, j ); mexErrMsgTxt("Unhandled code"); } } SHPDestroyObject( psShape ); } /* * Clean up, close up shop. * */ SHPClose( hSHP ); DBFClose ( dbh ); /* * Allocate space for the output structure. * */ out_struct = mxCreateStructMatrix ( 1, 1, 3, (const char **)outstruct_fnames ); /* * Set the fields properly. * */ mxSetField ( out_struct, 0, "Shape", data_struct ); mxSetField ( out_struct, 0, "Attribute", att_struct ); mxSetField ( out_struct, 0, "Type", mxCreateString ( shapeTypeString ) ); plhs[0] = out_struct; return; }
int main( int argc, char ** argv ) { SHPHandle hSHP; int nShapeType, nEntities, i, iPart, bValidate = 0,nInvalidCount=0; int bHeaderOnly = 0; double adfMinBound[4], adfMaxBound[4]; if( argc > 1 && strcmp(argv[1],"-validate") == 0 ) { bValidate = 1; argv++; argc--; } if( argc > 1 && strcmp(argv[1],"-ho") == 0 ) { bHeaderOnly = 1; argv++; argc--; } /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc != 2 ) { printf( "shpdump [-validate] [-ho] shp_file\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ hSHP = SHPOpen( argv[1], "rb" ); if( hSHP == NULL ) { printf( "Unable to open:%s\n", argv[1] ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Print out the file bounds. */ /* -------------------------------------------------------------------- */ SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound ); printf( "{\n" ); printf( " \"type\": \"%s\",\n", SHPTypeName( nShapeType ) ); printf( " \"shape_count\": %d,\n", nEntities ); printf( " \"bounding_box\": [%12.3f,%12.3f,%g,%g,%12.3f,%12.3f,%g,%g],\n", adfMinBound[0], adfMinBound[1], adfMinBound[2], adfMinBound[3], adfMaxBound[0], adfMaxBound[1], adfMaxBound[2], adfMaxBound[3] ); printf( " \"shapes\": [\n" ); int isFirst = 1; /* -------------------------------------------------------------------- */ /* Skim over the list of shapes, printing all the vertices. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nEntities && !bHeaderOnly; i++ ) { int j; SHPObject *psShape; psShape = SHPReadObject( hSHP, i ); if( psShape == NULL ) { fprintf( stderr, "Unable to read shape %d, terminating object reading.\n", i ); break; } if (isFirst!=1) { printf( ",\n" ); } isFirst = 0; printf( " {\n" ); printf( " \"index\": %d,\n", i ); printf( " \"type\": \"%s\",\n", SHPTypeName(psShape->nSHPType) ); printf( " \"vertex_count\": %d,\n", psShape->nVertices ); printf( " \"part_count\": %d,\n", psShape->nParts ); if( psShape->bMeasureIsUsed ) { printf( " \"measure_is_used\": true,\n" ); printf( " \"bounding_box\": [%12.3f,%12.3f, %g, %g, %12.3f,%12.3f, %g, %g],\n", psShape->dfXMin, psShape->dfYMin, psShape->dfZMin, psShape->dfMMin, psShape->dfXMax, psShape->dfYMax, psShape->dfZMax, psShape->dfMMax ); } else { printf( " \"measure_is_used\": false,\n" ); printf( " \"bounding_box\": [%12.3f,%12.3f, %g, %12.3f,%12.3f, %g],\n", psShape->dfXMin, psShape->dfYMin, psShape->dfZMin, psShape->dfXMax, psShape->dfYMax, psShape->dfZMax ); } if( psShape->nParts > 0 && psShape->panPartStart[0] != 0 ) { fprintf( stderr, "panPartStart[0] = %d, not zero as expected.\n", psShape->panPartStart[0] ); } printf( " \"parts\": [\n"); int isFirstVertex = 1; for( j = 0, iPart = 0; j < psShape->nVertices; j++ ) { const char *pszPartType = ""; if( iPart < psShape->nParts && psShape->panPartStart[iPart] == j ) { pszPartType = SHPPartTypeName( psShape->panPartType[iPart] ); iPart++; if (j != 0) { printf( "\n ]\n" ); printf( "\n },\n" ); } printf( " {\n" ); printf( " \"type\": \"%s\",\n", pszPartType ); printf( " \"vertices\": [\n" ); isFirstVertex = 1; } if (isFirstVertex!=1) { printf( ",\n" ); } isFirstVertex = 0; if( psShape->bMeasureIsUsed ) printf(" { \"x\":%f, \"y\":%f, \"z\":%g, \"m\":%g }", psShape->padfX[j], psShape->padfY[j], psShape->padfZ[j], psShape->padfM[j]); else printf(" { \"x\":%f, \"y\":%f, \"z\":%g }", psShape->padfX[j], psShape->padfY[j], psShape->padfZ[j]); } printf( " ]\n"); printf( " }\n"); printf( " ]\n"); if( bValidate ) { int nAltered = SHPRewindObject( hSHP, psShape ); if( nAltered > 0 ) { printf( " %d rings wound in the wrong direction.\n", nAltered ); nInvalidCount++; } } printf( " }" ); SHPDestroyObject( psShape ); } printf( "\n ]\n" ); printf( "}\n" ); SHPClose( hSHP ); if( bValidate ) { printf( "%d object has invalid ring orderings.\n", nInvalidCount ); } #ifdef USE_DBMALLOC malloc_dump(2); #endif exit( 0 ); }
void load_shapes( const std::string & filename_, IShapeLoadCallback & callback ) /* int load_shapes( const std::string & filename_, std::vector< ptr< Shape > > & shapes // std::vector< agg::path_storage > &shapes ) */ //int load_shapes( const char *filename, agg::path_storage &path) { // assert( shapes.empty() ); const char *filename = filename_.c_str(); SHPHandle hSHP; int nShapeType, nEntities, i, iPart, bValidate = 0,nInvalidCount=0; const char *pszPlus; double adfMinBound[4], adfMaxBound[4]; bValidate = 1; /* if( argc > 1 && strcmp(argv[1],"-validate") == 0 ) { bValidate = 1; argv++; argc--; } */ /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ /* if( argc != 2 ) { printf( "shpdump [-validate] shp_file\n" ); exit( 1 ); } */ /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ // const char *filename = "world_shape/world_adm0.shp"; /// const char *filename = "world_adm0.shp"; // fprintf( stdout, "trying to open '%s'\n", filename ); hSHP = SHPOpen( /*argv[1]*/ filename, "rb" ); if( hSHP == NULL ) { printf( "Unable to open:%s\n", filename ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Print out the file bounds. */ /* -------------------------------------------------------------------- */ SHPGetInfo( hSHP, &nEntities, &nShapeType, adfMinBound, adfMaxBound ); #if 0 printf( "Shapefile Type: %s # of Shapes: %d\n\n", SHPTypeName( nShapeType ), nEntities ); printf( "File Bounds: (%12.3f,%12.3f,%g,%g)\n" " to (%12.3f,%12.3f,%g,%g)\n", adfMinBound[0], adfMinBound[1], adfMinBound[2], adfMinBound[3], adfMaxBound[0], adfMaxBound[1], adfMaxBound[2], adfMaxBound[3] ); #endif /* ok - rather than have an array of paths for each shape we include the meta data we should just keep the paths */ /* -------------------------------------------------------------------- */ /* Skim over the list of shapes, printing all the vertices. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nEntities; i++ ) { agg::path_storage path; // ptr< Shape> shape = new Shape; // shapes.push_back( agg::path_storage() ); int j; SHPObject *psShape; psShape = SHPReadObject( hSHP, i ); #if 0 printf( "\nShape:%d (%s) nVertices=%d, nParts=%d\n" " Bounds:(%12.3f,%12.3f, %g, %g)\n" " to (%12.3f,%12.3f, %g, %g)\n", i, SHPTypeName(psShape->nSHPType), psShape->nVertices, psShape->nParts, psShape->dfXMin, psShape->dfYMin, psShape->dfZMin, psShape->dfMMin, psShape->dfXMax, psShape->dfYMax, psShape->dfZMax, psShape->dfMMax ); printf( "\n"); #endif for( j = 0, iPart = 1; j < psShape->nVertices; j++ ) { assert( iPart <= psShape->nParts); if( j == 0 ) { // definitions in shapefil.h assert( psShape->panPartType[ 0] == SHPP_RING ); // printf( "//// type %s\n", SHPPartTypeName( psShape->panPartType[0] )); //printf( "* move_to (1) %12.3f %12.3f\n", psShape->padfX[j], psShape->padfY[j]); path.move_to( psShape->padfX[j], psShape->padfY[j]); } // last item in a poly is close - gets last item ( note --- we dont want to add it again ) else if( j == psShape->nVertices - 1 ) { // printf( "* close poly (1) (ignore %12.3f %12.3f)\n", psShape->padfX[j], psShape->padfY[j]); path.close_polygon(); } else if( ( iPart < psShape->nParts && psShape->panPartStart[ iPart] - 1 == j )) { // printf( "* close poly (2) (ignore %12.3f %12.3f)\n", psShape->padfX[j], psShape->padfY[j]); path.close_polygon(); } else if( ( iPart < psShape->nParts && psShape->panPartStart[ iPart] == j )) { // only point where we increment iPart iPart++; //printf( "* move_to (2) %12.3f %12.3f\n", psShape->padfX[j], psShape->padfY[j]); path.move_to( psShape->padfX[j], psShape->padfY[j]); } else { // printf( "* line_to %12.3f %12.3f\n", psShape->padfX[j], psShape->padfY[j]); path.line_to( psShape->padfX[j], psShape->padfY[j]); } // the values seem to indicate that they are closed ... /* printf("%d %s (%12.3f,%12.3f, %g, %g) %s \n", iPart, pszPlus, psShape->padfX[j], psShape->padfY[j], psShape->padfZ[j], psShape->padfM[j], pszPartType ); */ } if( bValidate ) { int nAltered = SHPRewindObject( hSHP, psShape ); if( nAltered > 0 ) { printf( " %d rings wound in the wrong direction.\n", nAltered ); nInvalidCount++; exit( 0); } } SHPDestroyObject( psShape ); callback.add_shape( i, path ); // shapes.push_back( shape); } SHPClose( hSHP ); if( bValidate && nInvalidCount ) { printf( "%d object has invalid ring orderings.\n", nInvalidCount ); } #ifdef USE_DBMALLOC malloc_dump(2); #endif // exit( 0 ); }