Exemple #1
0
 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;
     }
 }
Exemple #2
0
/* -------------------------------------------------------------------- */
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 );
}
Exemple #3
0
/* -------------------------------------------------------------------- */
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 );
            }
        }
}
Exemple #4
0
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;
}
Exemple #5
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 );
}
Exemple #6
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;
}
Exemple #7
0
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;
}
Exemple #8
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);
}
Exemple #9
0
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;

}
Exemple #10
0
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 );
}
Exemple #11
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 );
}