Beispiel #1
0
VALUE shape_object::destroy(VALUE self)
{
  shape_object *object = unwrap(self);

  CHECK_VALID_HANDLE(object->value());

  if (object->value()) {
    SHPDestroyObject(object->value());
    object->_handle = NULL;
  }

  return Qnil;
}
Beispiel #2
0
bool compareSHP(SHPHandle iSHP, int iRecord, SHPHandle jSHP, int jRecord, bool print)
{
SHPObject       *piShape;
SHPObject       *pjShape;
int             j;
int             mismatch;

        mismatch = 0;

        piShape = SHPReadObject( iSHP, iRecord );
        pjShape = SHPReadObject( jSHP, jRecord );

        if( print )
            printf("Vertices %d / %d\n", piShape->nVertices, pjShape->nVertices);

        if( piShape->nVertices != pjShape->nVertices )
            return( true );

        for( j = 0; j < piShape->nVertices; j++ )
        {
            const char  *pszPartType = "";

            if( piShape->padfX[j] != pjShape->padfX[j] )
                mismatch++;
            if( piShape->padfY[j] != pjShape->padfY[j] )
                mismatch++;
            if( piShape->padfZ[j] != pjShape->padfZ[j] )
                mismatch++;
            if( piShape->padfM[j] != pjShape->padfM[j] )
                mismatch++;
        }
        SHPDestroyObject( piShape );
        SHPDestroyObject( pjShape );

        if( print )
            printf("Mismatches %d\n", mismatch);

        return( mismatch? true:false );
}
Beispiel #3
0
static void SHPTreeNodeSearchAndDump( SHPTree * hTree,
                                      double *padfBoundsMin,
                                      double *padfBoundsMax )

{
    int		*panHits, nShapeCount, i;

/* -------------------------------------------------------------------- */
/*      Perform the search for likely candidates.  These are shapes     */
/*      that fall into a tree node whose bounding box intersects our    */
/*      area of interest.                                               */
/* -------------------------------------------------------------------- */
    panHits = SHPTreeFindLikelyShapes( hTree, padfBoundsMin, padfBoundsMax,
                                       &nShapeCount );

/* -------------------------------------------------------------------- */
/*      Read all of these shapes, and establish whether the shape's     */
/*      bounding box actually intersects the area of interest.  Note    */
/*      that the bounding box could intersect the area of interest,     */
/*      and the shape itself still not cross it but we don't try to     */
/*      address that here.                                              */
/* -------------------------------------------------------------------- */
    for( i = 0; i < nShapeCount; i++ )
    {
        SHPObject	*psObject;

        psObject = SHPReadObject( hTree->hSHP, panHits[i] );
        if( psObject == NULL )
            continue;
        
        if( !SHPCheckBoundsOverlap( padfBoundsMin, padfBoundsMax,
                                    &(psObject->dfXMin),
                                    &(psObject->dfXMax),
                                    hTree->nDimension ) )
        {
            printf( "Shape %d: not in area of interest, but fetched.\n",
                    panHits[i] );
        }
        else
        {
            printf( "Shape %d: appears to be in area of interest.\n",
                    panHits[i] );
        }

        SHPDestroyObject( psObject );
    }

    if( nShapeCount == 0 )
        printf( "No shapes found in search.\n" );
}
int writePoint(JNIEnv * env, SHPHandle hSHP, DBFHandle hDBF, int index, double latitude, double longitude, jstring name, jdouble height, int apples)
{
    SHPObject *oSHP = SHPCreateSimpleObject(SHPT_POINT, 1, &longitude, &latitude, NULL);
    SHPWriteObject(hSHP, -1, oSHP);
    const char *nativeName = (*env)->GetStringUTFChars(env, name, 0);
    DBFWriteStringAttribute(hDBF, index, 0, nativeName);
    (*env)->ReleaseStringUTFChars(env, name, nativeName);
    DBFWriteDoubleAttribute(hDBF, index, 1, height);
    DBFWriteIntegerAttribute(hDBF, index, 2, apples);

    SHPDestroyObject(oSHP);

    return 0;
}
// ---------------------------------------------------------------------------
// 
// -----------
int	bSHPTable::WriteVal(int o, int f, void* val){
	if((o=CountRecords()+1)){
		o=0;
	}
SHPObject*	obj=vxs2shape(o-1,(*(ivertices**)val));
	if(!obj){
		return(-1);
	}
	if(SHPWriteObject(_shp,o-1,obj)){
	}
	else{
	}
	SHPDestroyObject(obj);
	return(0);
}
Beispiel #6
0
 /**
  * Add a new geometry (shape object) to the Shapefile. You have to call
  * this first for every new shape. After that you call add_attribute()
  * for all the attributes.
  *
  * @param shp_object A pointer to the shape object to be added. The object
  *                   will be freed for you by calling SHPDestroyObject()!
  * @exception Osmium::Exception::IllegalGeometry If shp_object is NULL or
  *                   the type of geometry does not fit the type of the
  *                   shapefile.
  */
 void add_geometry(SHPObject* shp_object) {
     if (!shp_object || shp_object->nSHPType != m_shp_handle->nShapeType) {
         throw Osmium::Exception::IllegalGeometry();
     }
     m_current_shape = SHPWriteObject(m_shp_handle, -1, shp_object);
     if (m_current_shape == -1 && errno == EINVAL) {
         // second chance if likely cause is having reached the 2GB limit
         close();
         m_sequence_number++;
         open();
         m_current_shape = SHPWriteObject(m_shp_handle, -1, shp_object);
     }
     if (m_current_shape == -1) {
         throw std::runtime_error("error writing to shapefile");
     }
     SHPDestroyObject(shp_object);
 }
Beispiel #7
0
// A partir del trazo, genera y guarda el vector correspondiente en formato SHAPE
void vect::agregarShape(vector<Point2f> trazo, int altura, SHPHandle sh, transformGeo *objGeo, Point pA, DBFHandle dbf) {
    vector<Point2f> l;
    for(vector<Point2f>::iterator it = trazo.begin(); it != trazo.end(); ++it)
    {
        Point2f p = *it;
        double xi = pA.x+p.x-1.0;
        double yi = pA.y+p.y-1.0;
        double xp= objGeo->getX(xi, yi);
        double yp = objGeo->getY(xi, yi);
        Point2f pi = Point2f(xp,yp);
        l.push_back(pi);
    }
    SHPObject *objShp = toArc(l, altura);
    int polyid = SHPWriteObject(sh, -1, objShp);
    DBFWriteDoubleAttribute(dbf, polyid, 0, 0.0);
    cout<<polyid<<".,,"<<endl;
    SHPDestroyObject(objShp);
}
Beispiel #8
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 );
}
void surfaceVectorField::WriteShapePoint(double xpt, double ypt, double spd, long dir, long view_dir, long map_dir)
{
     long NumRecord;
	double zpt=0;
     SHPObject *pSHP;

     pSHP=SHPCreateObject(SHPT_POINT, -1, 0, NULL, NULL, 1, &xpt, &ypt, &zpt, NULL);
     SHPWriteObject(hSHP, -1, pSHP);
     SHPDestroyObject(pSHP);

	NumRecord = DBFGetRecordCount(hDBF);
//	DBFWriteDoubleAttribute(hDBF, NumRecord, 0, xpt);
//   DBFWriteDoubleAttribute(hDBF, NumRecord, 1, ypt);
//	DBFWriteIntegerAttribute(hDBF, NumRecord, 2, spd);
//   DBFWriteIntegerAttribute(hDBF, NumRecord, 3, dir);
	DBFWriteDoubleAttribute(hDBF, NumRecord, 0, spd);
     DBFWriteIntegerAttribute(hDBF, NumRecord, 1, dir);
     DBFWriteIntegerAttribute(hDBF, NumRecord, 2, view_dir);
     DBFWriteIntegerAttribute(hDBF, NumRecord, 3, map_dir);
}
Beispiel #10
0
OGRFeature *OGRShapeLayer::FetchShape(int iShapeId)

{
    OGRFeature *poFeature;

    if (m_poFilterGeom != NULL && hSHP != NULL ) 
    {
        SHPObject   *psShape;
        
        psShape = SHPReadObject( hSHP, iShapeId );

        // do not trust degenerate bounds or bounds on null shapes.
        if( psShape == NULL || psShape->dfXMin == psShape->dfXMax
            || psShape->dfYMin == psShape->dfYMax 
            || psShape->nSHPType == SHPT_NULL )
        {
            poFeature = SHPReadOGRFeature( hSHP, hDBF, poFeatureDefn,
                                           iShapeId, psShape );
        }
        else if( m_sFilterEnvelope.MaxX < psShape->dfXMin 
                 || m_sFilterEnvelope.MaxY < psShape->dfYMin
                 || psShape->dfXMax  < m_sFilterEnvelope.MinX
                 || psShape->dfYMax < m_sFilterEnvelope.MinY ) 
        {
            SHPDestroyObject(psShape);
            poFeature = NULL;
        } 
        else 
        {
            poFeature = SHPReadOGRFeature( hSHP, hDBF, poFeatureDefn,
                                           iShapeId, psShape );
        }                
    } 
    else 
    {
        poFeature = SHPReadOGRFeature( hSHP, hDBF, poFeatureDefn,
                                       iShapeId, NULL );
    }    
    
    return poFeature;
}
Beispiel #11
0
static void SplitCoastlines2( int show, struct source *arc, SHPHandle shp_arc_out, DBFHandle dbf_arc_out )
{
  int count = arc->shape_count;
  for( int i=0; i<count; i++ )
  {
    SHPObject *obj = source_get_shape( arc, i );
    int way_id = DBFReadIntegerAttribute( arc->dbf, i, 2 );
    
    if( obj->nVertices <= MAX_NODES_PER_ARC )
    {
      int new_id = SHPWriteObject( shp_arc_out, -1, obj );
      if( new_id < 0 ) { fprintf( stderr, "Output failure: %m\n"); exit(1); }
      DBFWriteIntegerAttribute( dbf_arc_out, new_id, 0, way_id );
      DBFWriteIntegerAttribute( dbf_arc_out, new_id, 1, show );
      DBFWriteIntegerAttribute( dbf_arc_out, new_id, 2, obj->nVertices < 4 );  /* Flag not real objects */
      source_release_shape(arc, obj);
      continue;
    }
    int arcs = (obj->nVertices / MAX_NODES_PER_ARC) + 1;
    int len = (obj->nVertices / arcs) + 1;
//    printf( "Splitting object with %d vertices, len=%d, arcs=%d\n", obj->nVertices, len, arcs );
    
    for( int j=0; j<arcs; j++ )
    {
      int this_len = (j==arcs-1)? obj->nVertices - (j*len): len+1;
//      printf( "Subobject start=%d, length=%d\n", j*len, this_len );
      SHPObject *new_obj = SHPCreateSimpleObject( SHPT_ARC, this_len, &obj->padfX[j*len], &obj->padfY[j*len], &obj->padfZ[j*len] );
      int new_id = SHPWriteObject( shp_arc_out, -1, new_obj );
      if( new_id < 0 ) { fprintf( stderr, "Output failure: %m\n"); exit(1); }
      DBFWriteIntegerAttribute( dbf_arc_out, new_id, 0, way_id );
      DBFWriteIntegerAttribute( dbf_arc_out, new_id, 1, show );
      DBFWriteIntegerAttribute( dbf_arc_out, new_id, 2, 0 );
      SHPDestroyObject(new_obj);
    }
    source_release_shape(arc, obj);
  }
}
Beispiel #12
0
int main(int argc, char * argv [])
{
	int n_records, i, j;
	char * tc_path = argv[1];
	char * fl_dir  = argv[2];
	char fl_path [256];
	
	printf("%s\n", tc_path);
	printf("%s\n", fl_dir);
	
	SHPHandle
	HSHP_polygon = SHPOpen(tc_path, "rb");
	if(!HSHP_polygon){
		puts("Couldn't open tc_path");
		return 0;
	}
	SHPGetInfo(HSHP_polygon, &n_records, NULL, NULL, NULL);
	printf("n_records: %d\n", n_records);
	
	SHPObject* shapes [n_records];
	for(i = 0; i < n_records; i++){
		shapes[i] = SHPReadObject(HSHP_polygon, i);
		if(!shapes[i]){
			puts("Failed reading shape object.");
			return 0;
		}
	}
	SHPClose(HSHP_polygon);
	
	struct dirent *entry;
	DIR *dp;
	
	dp = opendir(fl_dir);
	if (dp == NULL) {
		perror("opendir: Path does not exist or could not be read.");
		return 0;
	}
	
	while ((entry = readdir(dp)))
	{
		sprintf(fl_path, "%s/%s", fl_dir, entry->d_name);
		printf("%s\n",fl_path);
		char end [8];
		                 
		strncpy(end, fl_path + strlen(fl_path) - 3, 3);
		printf("END -- %s\n", end);
		if( strcmp(end, "shp") != 0)
			continue;
		
		
		
		SHPHandle 
		HSHP_fl = SHPOpen(fl_path, "rb");
		if(!HSHP_fl){
			puts("Couldn't open fl_path");
			continue;
		}
		SHPObject * fline = SHPReadObject(HSHP_fl, 0);
		if(!fline){
			puts("Error reading flight line.");
			return 0;
		}
		
		for(i = 0; i < n_records; i++){
			SHPObject * shape = shapes[i];
			
			for(j = 0; j < shape->nVertices; j++){
				if(pointInPolygon(fline, shape->padfX[j], shape->padfY[j])){
					printf("\t%d\n", i);
					break;
				}
			}
		}
		
		SHPDestroyObject(fline);
		SHPClose(HSHP_fl);
	}
	
	closedir(dp);
	return 0;
}
Beispiel #13
0
static void SHPTreeNodeDump( SHPTree * psTree,
                             SHPTreeNode * psTreeNode,
                             const char * pszPrefix,
                             int nExpandShapes )

{
    char	szNextPrefix[150];
    int		i;

    strcpy( szNextPrefix, pszPrefix );
    if( strlen(pszPrefix) < sizeof(szNextPrefix) - 3 )
        strcat( szNextPrefix, "  " );

    printf( "%s( SHPTreeNode\n", pszPrefix );

/* -------------------------------------------------------------------- */
/*      Emit the bounds.                                                */
/* -------------------------------------------------------------------- */
    printf( "%s  Min = (", pszPrefix );
    EmitCoordinate( psTreeNode->adfBoundsMin, psTree->nDimension );
    printf( ")\n" );
    
    printf( "%s  Max = (", pszPrefix );
    EmitCoordinate( psTreeNode->adfBoundsMax, psTree->nDimension );
    printf( ")\n" );

/* -------------------------------------------------------------------- */
/*      Emit the list of shapes on this node.                           */
/* -------------------------------------------------------------------- */
    if( nExpandShapes )
    {
        printf( "%s  Shapes(%d):\n", pszPrefix, psTreeNode->nShapeCount );
        for( i = 0; i < psTreeNode->nShapeCount; i++ )
        {
            SHPObject	*psObject;

            psObject = SHPReadObject( psTree->hSHP,
                                      psTreeNode->panShapeIds[i] );
            assert( psObject != NULL );
            if( psObject != NULL )
            {
                EmitShape( psObject, szNextPrefix, psTree->nDimension );
            }

            SHPDestroyObject( psObject );
        }
    }
    else
    {
        printf( "%s  Shapes(%d): ", pszPrefix, psTreeNode->nShapeCount );
        for( i = 0; i < psTreeNode->nShapeCount; i++ )
        {
            printf( "%d ", psTreeNode->panShapeIds[i] );
        }
        printf( "\n" );
    }

/* -------------------------------------------------------------------- */
/*      Emit subnodes.                                                  */
/* -------------------------------------------------------------------- */
    for( i = 0; i < psTreeNode->nSubNodes; i++ )
    {
        if( psTreeNode->apsSubNode[i] != NULL )
            SHPTreeNodeDump( psTree, psTreeNode->apsSubNode[i],
                             szNextPrefix, nExpandShapes );
    }
    
    printf( "%s)\n", pszPrefix );

    return;
}
Beispiel #14
0
SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
               double *padfBoundsMin, double *padfBoundsMax )

{
    SHPTree	*psTree;

    if( padfBoundsMin == NULL && hSHP == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Allocate the tree object                                        */
/* -------------------------------------------------------------------- */
    psTree = (SHPTree *) malloc(sizeof(SHPTree));

    psTree->hSHP = hSHP;
    psTree->nMaxDepth = nMaxDepth;
    psTree->nDimension = nDimension;

/* -------------------------------------------------------------------- */
/*      If no max depth was defined, try to select a reasonable one     */
/*      that implies approximately 8 shapes per node.                   */
/* -------------------------------------------------------------------- */
    if( psTree->nMaxDepth == 0 && hSHP != NULL )
    {
        int	nMaxNodeCount = 1;
        int	nShapeCount;

        SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL );
        while( nMaxNodeCount*4 < nShapeCount )
        {
            psTree->nMaxDepth += 1;
            nMaxNodeCount = nMaxNodeCount * 2;
        }
    }

/* -------------------------------------------------------------------- */
/*      Allocate the root node.                                         */
/* -------------------------------------------------------------------- */
    psTree->psRoot = SHPTreeNodeCreate( padfBoundsMin, padfBoundsMax );

/* -------------------------------------------------------------------- */
/*      Assign the bounds to the root node.  If none are passed in,     */
/*      use the bounds of the provided file otherwise the create        */
/*      function will have already set the bounds.                      */
/* -------------------------------------------------------------------- */
    if( padfBoundsMin == NULL )
    {
        SHPGetInfo( hSHP, NULL, NULL,
                    psTree->psRoot->adfBoundsMin, 
                    psTree->psRoot->adfBoundsMax );
    }

/* -------------------------------------------------------------------- */
/*      If we have a file, insert all it's shapes into the tree.        */
/* -------------------------------------------------------------------- */
    if( hSHP != NULL )
    {
        int	iShape, nShapeCount;
        
        SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL );

        for( iShape = 0; iShape < nShapeCount; iShape++ )
        {
            SHPObject	*psShape;
            
            psShape = SHPReadObject( hSHP, iShape );
            SHPTreeAddShapeId( psTree, psShape );
            SHPDestroyObject( psShape );
        }
    }        

    return psTree;
}
Beispiel #15
0
static void WritePolygonShapefile( const char * pszShapefile,
                                   SDTSTransfer * poTransfer, 
                                   const char * pszMODN )

{
    SDTSPolygonReader *poPolyReader;

/* -------------------------------------------------------------------- */
/*      Fetch a reference to the indexed polygon reader.                */
/* -------------------------------------------------------------------- */
    poPolyReader = (SDTSPolygonReader *) 
        poTransfer->GetLayerIndexedReader( poTransfer->FindLayer( pszMODN ) );
    
    if( poPolyReader == NULL )
    {
        fprintf( stderr, "Failed to open %s.\n",
                 poTransfer->GetCATD()->GetModuleFilePath( pszMODN ) );
        return;
    }

/* -------------------------------------------------------------------- */
/*      Assemble polygon geometries from all the line layers.           */
/* -------------------------------------------------------------------- */
    poPolyReader->AssembleRings( poTransfer, poTransfer->FindLayer(pszMODN) );
    
/* -------------------------------------------------------------------- */
/*      Create the Shapefile.                                           */
/* -------------------------------------------------------------------- */
    SHPHandle   hSHP;

    hSHP = SHPCreate( pszShapefile, SHPT_POLYGON );
    if( hSHP == NULL )
    {
        fprintf( stderr, "Unable to create shapefile `%s'\n",
                 pszShapefile );
        return;
    }

/* -------------------------------------------------------------------- */
/*      Create the database file, and our basic set of attributes.      */
/* -------------------------------------------------------------------- */
    DBFHandle   hDBF;
    int         nSDTSRecordField;
    char        szDBFFilename[1024];

    sprintf( szDBFFilename, "%s.dbf", pszShapefile );

    hDBF = DBFCreate( szDBFFilename );
    if( hDBF == NULL )
    {
        fprintf( stderr, "Unable to create shapefile .dbf for `%s'\n",
                 pszShapefile );
        return;
    }

    nSDTSRecordField = DBFAddField( hDBF, "SDTSRecId", FTInteger, 8, 0 );

    char  **papszModRefs = poPolyReader->ScanModuleReferences();
    AddPrimaryAttrToDBFSchema( hDBF, poTransfer, papszModRefs );
    CSLDestroy( papszModRefs );

/* ==================================================================== */
/*      Process all the polygon features in the module.                 */
/* ==================================================================== */
    SDTSRawPolygon      *poRawPoly;

    poPolyReader->Rewind();
    while( (poRawPoly = (SDTSRawPolygon *) poPolyReader->GetNextFeature())
           != NULL )
    {
        int             iShape;

/* -------------------------------------------------------------------- */
/*      Write out a shape with the vertices.                            */
/* -------------------------------------------------------------------- */
        SHPObject       *psShape;

        psShape = SHPCreateObject( SHPT_POLYGON, -1, poRawPoly->nRings,
                                   poRawPoly->panRingStart, NULL,
                                   poRawPoly->nVertices,
                                   poRawPoly->padfX, 
                                   poRawPoly->padfY, 
                                   poRawPoly->padfZ,
                                   NULL );

        iShape = SHPWriteObject( hSHP, -1, psShape );

        SHPDestroyObject( psShape );

/* -------------------------------------------------------------------- */
/*      Write out the attributes.                                       */
/* -------------------------------------------------------------------- */
        DBFWriteIntegerAttribute( hDBF, iShape, nSDTSRecordField,
                                  poRawPoly->oModId.nRecord );
        WritePrimaryAttrToDBF( hDBF, iShape, poTransfer, poRawPoly );

        if( !poPolyReader->IsIndexed() )
            delete poRawPoly;
    }

/* -------------------------------------------------------------------- */
/*      Close, and cleanup.                                             */
/* -------------------------------------------------------------------- */
    DBFClose( hDBF );
    SHPClose( hSHP );
}    
Beispiel #16
0
static void WritePointShapefile( const char * pszShapefile,
                                 SDTSTransfer * poTransfer,
                                 const char * pszMODN )

{
    SDTSPointReader     *poPointReader;

/* -------------------------------------------------------------------- */
/*      Fetch a reference to the indexed Pointgon reader.                */
/* -------------------------------------------------------------------- */
    poPointReader = (SDTSPointReader *) 
        poTransfer->GetLayerIndexedReader( poTransfer->FindLayer( pszMODN ) );
    
    if( poPointReader == NULL )
    {
        fprintf( stderr, "Failed to open %s.\n",
                 poTransfer->GetCATD()->GetModuleFilePath( pszMODN ) );
        return;
    }

    poPointReader->Rewind();

/* -------------------------------------------------------------------- */
/*      Create the Shapefile.                                           */
/* -------------------------------------------------------------------- */
    SHPHandle   hSHP;

    hSHP = SHPCreate( pszShapefile, SHPT_POINT );
    if( hSHP == NULL )
    {
        fprintf( stderr, "Unable to create shapefile `%s'\n",
                 pszShapefile );
        return;
    }

/* -------------------------------------------------------------------- */
/*      Create the database file, and our basic set of attributes.      */
/* -------------------------------------------------------------------- */
    DBFHandle   hDBF;
    int         nAreaField, nSDTSRecordField;
    char        szDBFFilename[1024];

    sprintf( szDBFFilename, "%s.dbf", pszShapefile );

    hDBF = DBFCreate( szDBFFilename );
    if( hDBF == NULL )
    {
        fprintf( stderr, "Unable to create shapefile .dbf for `%s'\n",
                 pszShapefile );
        return;
    }

    nSDTSRecordField = DBFAddField( hDBF, "SDTSRecId", FTInteger, 8, 0 );
    nAreaField = DBFAddField( hDBF, "AreaId", FTString, 12, 0 );
    
    char  **papszModRefs = poPointReader->ScanModuleReferences();
    AddPrimaryAttrToDBFSchema( hDBF, poTransfer, papszModRefs );
    CSLDestroy( papszModRefs );

/* ==================================================================== */
/*      Process all the line features in the module.                    */
/* ==================================================================== */
    SDTSRawPoint        *poRawPoint;
        
    while( (poRawPoint = poPointReader->GetNextPoint()) != NULL )
    {
        int             iShape;
        
/* -------------------------------------------------------------------- */
/*      Write out a shape with the vertices.                            */
/* -------------------------------------------------------------------- */
        SHPObject       *psShape;

        psShape = SHPCreateSimpleObject( SHPT_POINT, 1,
                                         &(poRawPoint->dfX),
                                         &(poRawPoint->dfY),
                                         &(poRawPoint->dfZ) );

        iShape = SHPWriteObject( hSHP, -1, psShape );

        SHPDestroyObject( psShape );

/* -------------------------------------------------------------------- */
/*      Write out the attributes.                                       */
/* -------------------------------------------------------------------- */
        char    szID[13];

        DBFWriteIntegerAttribute( hDBF, iShape, nSDTSRecordField,
                                  poRawPoint->oModId.nRecord );
        
        sprintf( szID, "%s:%ld",
                 poRawPoint->oAreaId.szModule,
                 poRawPoint->oAreaId.nRecord );
        DBFWriteStringAttribute( hDBF, iShape, nAreaField, szID );

        WritePrimaryAttrToDBF( hDBF, iShape, poTransfer, poRawPoint );

        if( !poPointReader->IsIndexed() )
            delete poRawPoint;
    }

/* -------------------------------------------------------------------- */
/*      Close, and cleanup.                                             */
/* -------------------------------------------------------------------- */
    DBFClose( hDBF );
    SHPClose( hSHP );
}    
Beispiel #17
0
static int FindGeoLocPosition( GDALGeoLocTransformInfo *psTransform,
                               double dfGeoX, double dfGeoY,
                               int nStartX, int nStartY, 
                               double *pdfFoundX, double *pdfFoundY )

{
    double adfPathX[5000], adfPathY[5000];

    if( psTransform->padfGeoLocX == NULL )
        return FALSE;

    int nXSize = psTransform->nGeoLocXSize;
    int nYSize = psTransform->nGeoLocYSize;
    int nStepCount = 0;

    // Start in center if we don't have any provided info.
    if( nStartX < 0 || nStartY < 0 
        || nStartX >= nXSize || nStartY >= nYSize )
    {
        nStartX = nXSize / 2;
        nStartY = nYSize / 2;
    }

    nStartX = MIN(nStartX,nXSize-2);
    nStartY = MIN(nStartY,nYSize-2);

    int iX = nStartX, iY = nStartY;
    int iLastX = -1, iLastY = -1;
    int iSecondLastX = -1, iSecondLastY = -1;

    while( nStepCount < MAX(nXSize,nYSize) )
    {
        int iXNext = -1, iYNext = -1;
        double dfDeltaXRight, dfDeltaYRight, dfDeltaXDown, dfDeltaYDown;

        double *padfThisX = psTransform->padfGeoLocX + iX + iY * nXSize;
        double *padfThisY = psTransform->padfGeoLocY + iX + iY * nXSize;

        double dfDeltaX = dfGeoX - *padfThisX;
        double dfDeltaY = dfGeoY - *padfThisY;

        if( iX == nXSize-1 )
        {
            dfDeltaXRight = *(padfThisX) - *(padfThisX-1);
            dfDeltaYRight = *(padfThisY) - *(padfThisY-1);
        }
        else
        {
            dfDeltaXRight = *(padfThisX+1) - *padfThisX;
            dfDeltaYRight = *(padfThisY+1) - *padfThisY;
        }

        if( iY == nYSize - 1 )
        {
            dfDeltaXDown = *(padfThisX) - *(padfThisX-nXSize);
            dfDeltaYDown = *(padfThisY) - *(padfThisY-nXSize);
        }
        else
        {
            dfDeltaXDown = *(padfThisX+nXSize) - *padfThisX;
            dfDeltaYDown = *(padfThisY+nXSize) - *padfThisY;
        }

        double dfRightProjection = 
            (dfDeltaXRight * dfDeltaX + dfDeltaYRight * dfDeltaY) 
            / (dfDeltaXRight*dfDeltaXRight + dfDeltaYRight*dfDeltaYRight);

        double dfDownProjection = 
            (dfDeltaXDown * dfDeltaX + dfDeltaYDown * dfDeltaY) 
            / (dfDeltaXDown*dfDeltaXDown + dfDeltaYDown*dfDeltaYDown);

        // Are we in our target cell?
        if( dfRightProjection >= 0.0 && dfRightProjection < 1.0 
            && dfDownProjection >= 0.0 && dfDownProjection < 1.0 )
        {
            *pdfFoundX = iX + dfRightProjection;
            *pdfFoundY = iY + dfDownProjection;

            return TRUE;
        }
            
        if( ABS(dfRightProjection) > ABS(dfDownProjection) )
        {
            // Do we want to move right? 
            if( dfRightProjection > 1.0 && iX < nXSize-1 )
            {
                iXNext = iX + MAX(1,(int)(dfRightProjection - nStepCount)/2);
                iYNext = iY;
            }
            
            // Do we want to move left? 
            else if( dfRightProjection < 0.0 && iX > 0 )
            {
                iXNext = iX - MAX(1,(int)(ABS(dfRightProjection) - nStepCount)/2);
                iYNext = iY;
            }
            
            // Do we want to move down.
            else if( dfDownProjection > 1.0 && iY < nYSize-1 )
            {
                iXNext = iX;
                iYNext = iY + MAX(1,(int)(dfDownProjection - nStepCount)/2);
            }
            
            // Do we want to move up? 
            else if( dfDownProjection < 0.0 && iY > 0 )
            {
                iXNext = iX;
                iYNext = iY - MAX(1,(int)(ABS(dfDownProjection) - nStepCount)/2);
            }
            
            // We aren't there, and we have no where to go
            else
            {
                return FALSE;
            }
        }
        else
        {
            // Do we want to move down.
            if( dfDownProjection > 1.0 && iY < nYSize-1 )
            {
                iXNext = iX;
                iYNext = iY + MAX(1,(int)(dfDownProjection - nStepCount)/2);
            }
            
            // Do we want to move up? 
            else if( dfDownProjection < 0.0 && iY > 0 )
            {
                iXNext = iX;
                iYNext = iY - MAX(1,(int)(ABS(dfDownProjection) - nStepCount)/2);
            }
            
            // Do we want to move right? 
            else if( dfRightProjection > 1.0 && iX < nXSize-1 )
            {
                iXNext = iX + MAX(1,(int)(dfRightProjection - nStepCount)/2);
                iYNext = iY;
            }
            
            // Do we want to move left? 
            else if( dfRightProjection < 0.0 && iX > 0 )
            {
                iXNext = iX - MAX(1,(int)(ABS(dfRightProjection) - nStepCount)/2);
                iYNext = iY;
            }
            
            // We aren't there, and we have no where to go
            else
            {
                return FALSE;
            }
        }
                adfPathX[nStepCount] = iX;
        adfPathY[nStepCount] = iY;

        nStepCount++;
        iX = MAX(0,MIN(iXNext,nXSize-1));
        iY = MAX(0,MIN(iYNext,nYSize-1));

        if( iX == iSecondLastX && iY == iSecondLastY )
        {
            // Are we *near* our target cell?
            if( dfRightProjection >= -1.0 && dfRightProjection < 2.0
                && dfDownProjection >= -1.0 && dfDownProjection < 2.0 )
            {
                *pdfFoundX = iX + dfRightProjection;
                *pdfFoundY = iY + dfDownProjection;
                
                return TRUE;
            }

#ifdef SHAPE_DEBUG
            if( hSHP != NULL )
            {
                SHPObject *hObj;
                
                hObj = SHPCreateSimpleObject( SHPT_ARC, nStepCount,
                                              adfPathX, adfPathY, NULL );
                SHPWriteObject( hSHP, -1, hObj );
                SHPDestroyObject( hObj );
                
                int iShape = DBFGetRecordCount( hDBF );
                DBFWriteDoubleAttribute( hDBF, iShape, 0, dfGeoX );
                DBFWriteDoubleAttribute( hDBF, iShape, 1, dfGeoY );
            }
#endif             
            //CPLDebug( "GeoL", "Looping at step (%d) on search for %g,%g.", 
            //          nStepCount, dfGeoX, dfGeoY );
            return FALSE;
        }

        iSecondLastX = iLastX;
        iSecondLastY = iLastY;

        iLastX = iX;
        iLastY = iY;

    }

    //CPLDebug( "GeoL", "Exceeded step count max (%d) on search for %g,%g.", 
    //          MAX(nXSize,nYSize), 
    //          dfGeoX, dfGeoY );
    
#ifdef SHAPE_DEBUG
    if( hSHP != NULL )
    {
        SHPObject *hObj;

        hObj = SHPCreateSimpleObject( SHPT_ARC, nStepCount,
                                      adfPathX, adfPathY, NULL );
        SHPWriteObject( hSHP, -1, hObj );
        SHPDestroyObject( hObj );

        int iShape = DBFGetRecordCount( hDBF );
        DBFWriteDoubleAttribute( hDBF, iShape, 0, dfGeoX );
        DBFWriteDoubleAttribute( hDBF, iShape, 1, dfGeoY );
    }
#endif
              
    return FALSE;
}
Beispiel #18
0
OGRErr OGRShapeLayer::Repack()

{
    if( !bUpdateAccess )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
            "The REPACK operation is not permitted on a read-only shapefile." );
        return OGRERR_FAILURE;
    }
    
    if( hDBF == NULL )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "Attempt to repack a shapefile with no .dbf file not supported.");
        return OGRERR_FAILURE;
    }
    
/* -------------------------------------------------------------------- */
/*      Build a list of records to be dropped.                          */
/* -------------------------------------------------------------------- */
    int *panRecordsToDelete = (int *) 
        CPLMalloc(sizeof(int)*(nTotalShapeCount+1));
    int nDeleteCount = 0;
    int iShape = 0;
    OGRErr eErr = OGRERR_NONE;

    for( iShape = 0; iShape < nTotalShapeCount; iShape++ )
    {
        if( DBFIsRecordDeleted( hDBF, iShape ) )
            panRecordsToDelete[nDeleteCount++] = iShape;
    }
    panRecordsToDelete[nDeleteCount] = -1;

/* -------------------------------------------------------------------- */
/*      If there are no records marked for deletion, we take no         */
/*      action.                                                         */
/* -------------------------------------------------------------------- */
    if( nDeleteCount == 0 )
    {
        CPLFree( panRecordsToDelete );
        return OGRERR_NONE;
    }

/* -------------------------------------------------------------------- */
/*      Find existing filenames with exact case (see #3293).            */
/* -------------------------------------------------------------------- */
    CPLString osDirname(CPLGetPath(pszFullName));
    CPLString osBasename(CPLGetBasename(pszFullName));
    
    CPLString osDBFName, osSHPName, osSHXName;
    char **papszCandidates = CPLReadDir( osDirname );
    int i = 0;
    while(papszCandidates != NULL && papszCandidates[i] != NULL)
    {
        CPLString osCandidateBasename = CPLGetBasename(papszCandidates[i]);
        CPLString osCandidateExtension = CPLGetExtension(papszCandidates[i]);
        if (osCandidateBasename.compare(osBasename) == 0)
        {
            if (EQUAL(osCandidateExtension, "dbf"))
                osDBFName = CPLFormFilename(osDirname, papszCandidates[i], NULL);
            else if (EQUAL(osCandidateExtension, "shp"))
                osSHPName = CPLFormFilename(osDirname, papszCandidates[i], NULL);
            else if (EQUAL(osCandidateExtension, "shx"))
                osSHXName = CPLFormFilename(osDirname, papszCandidates[i], NULL);
        }
        
        i++;
    }
    CSLDestroy(papszCandidates);
    papszCandidates = NULL;
    
    if (osDBFName.size() == 0)
    {
        /* Should not happen, really */
        CPLFree( panRecordsToDelete );
        return OGRERR_FAILURE;
    }
    
/* -------------------------------------------------------------------- */
/*      Cleanup any existing spatial index.  It will become             */
/*      meaningless when the fids change.                               */
/* -------------------------------------------------------------------- */
    if( CheckForQIX() )
        DropSpatialIndex();

/* -------------------------------------------------------------------- */
/*      Create a new dbf file, matching the old.                        */
/* -------------------------------------------------------------------- */
    DBFHandle hNewDBF = NULL;
    
    CPLString oTempFile(CPLFormFilename(osDirname, osBasename, NULL));
    oTempFile += "_packed.dbf";

    hNewDBF = DBFCloneEmpty( hDBF, oTempFile );
    if( hNewDBF == NULL )
    {
        CPLFree( panRecordsToDelete );

        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to create temp file %s.", 
                  oTempFile.c_str() );
        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Copy over all records that are not deleted.                     */
/* -------------------------------------------------------------------- */
    int iDestShape = 0;
    int iNextDeletedShape = 0;

    for( iShape = 0; 
         iShape < nTotalShapeCount && eErr == OGRERR_NONE; 
         iShape++ )
    {
        if( panRecordsToDelete[iNextDeletedShape] == iShape )
            iNextDeletedShape++;
        else
        {
            void *pTuple = (void *) DBFReadTuple( hDBF, iShape );
            if( pTuple == NULL )
                eErr = OGRERR_FAILURE;
            else if( !DBFWriteTuple( hNewDBF, iDestShape++, pTuple ) )
                eErr = OGRERR_FAILURE;
        }                           
    }

    if( eErr != OGRERR_NONE )
    {
        CPLFree( panRecordsToDelete );
        VSIUnlink( oTempFile );
        return eErr;
    }

/* -------------------------------------------------------------------- */
/*      Cleanup the old .dbf and rename the new one.                    */
/* -------------------------------------------------------------------- */
    DBFClose( hDBF );
    DBFClose( hNewDBF );
    hDBF = hNewDBF = NULL;
    
    VSIUnlink( osDBFName );
        
    if( VSIRename( oTempFile, osDBFName ) != 0 )
    {
        CPLDebug( "Shape", "Can not rename DBF file: %s", VSIStrerror( errno ) );
        CPLFree( panRecordsToDelete );
        return OGRERR_FAILURE;
    }
    
/* -------------------------------------------------------------------- */
/*      Now create a shapefile matching the old one.                    */
/* -------------------------------------------------------------------- */
    if( hSHP != NULL )
    {
        SHPHandle hNewSHP = NULL;
        
        if (osSHPName.size() == 0 || osSHXName.size() == 0)
        {
            /* Should not happen, really */
            CPLFree( panRecordsToDelete );
            return OGRERR_FAILURE;
        }

        oTempFile = CPLFormFilename(osDirname, osBasename, NULL);
        oTempFile += "_packed.shp";

        hNewSHP = SHPCreate( oTempFile, hSHP->nShapeType );
        if( hNewSHP == NULL )
        {
            CPLFree( panRecordsToDelete );
            return OGRERR_FAILURE;
        }

/* -------------------------------------------------------------------- */
/*      Copy over all records that are not deleted.                     */
/* -------------------------------------------------------------------- */
        iNextDeletedShape = 0;

        for( iShape = 0; 
             iShape < nTotalShapeCount && eErr == OGRERR_NONE; 
             iShape++ )
        {
            if( panRecordsToDelete[iNextDeletedShape] == iShape )
                iNextDeletedShape++;
            else
            {
                SHPObject *hObject;

                hObject = SHPReadObject( hSHP, iShape );
                if( hObject == NULL )
                    eErr = OGRERR_FAILURE;
                else if( SHPWriteObject( hNewSHP, -1, hObject ) == -1 )
                    eErr = OGRERR_FAILURE;

                if( hObject )
                    SHPDestroyObject( hObject );
            }
        }

        if( eErr != OGRERR_NONE )
        {
            CPLFree( panRecordsToDelete );
            VSIUnlink( CPLResetExtension( oTempFile, "shp" ) );
            VSIUnlink( CPLResetExtension( oTempFile, "shx" ) );
            return eErr;
        }

/* -------------------------------------------------------------------- */
/*      Cleanup the old .shp/.shx and rename the new one.               */
/* -------------------------------------------------------------------- */
        SHPClose( hSHP );
        SHPClose( hNewSHP );
        hSHP = hNewSHP = NULL;

        VSIUnlink( osSHPName );
        VSIUnlink( osSHXName );

        oTempFile = CPLResetExtension( oTempFile, "shp" );
        if( VSIRename( oTempFile, osSHPName ) != 0 )
        {
            CPLDebug( "Shape", "Can not rename SHP file: %s", VSIStrerror( errno ) );
            CPLFree( panRecordsToDelete );
            return OGRERR_FAILURE;
        }
    
        oTempFile = CPLResetExtension( oTempFile, "shx" );
        if( VSIRename( oTempFile, osSHXName ) != 0 )
        {
            CPLDebug( "Shape", "Can not rename SHX file: %s", VSIStrerror( errno ) );
            CPLFree( panRecordsToDelete );
            return OGRERR_FAILURE;
        }
    }
    
    CPLFree( panRecordsToDelete );
    panRecordsToDelete = NULL;

/* -------------------------------------------------------------------- */
/*      Reopen the shapefile                                            */
/*                                                                      */
/* We do not need to reimplement OGRShapeDataSource::OpenFile() here    */  
/* with the fully featured error checking.                              */
/* If all operations above succeeded, then all necessery files are      */
/* in the right place and accessible.                                   */
/* -------------------------------------------------------------------- */
    CPLAssert( NULL == hSHP );
    CPLAssert( NULL == hDBF && NULL == hNewDBF );
    
    CPLPushErrorHandler( CPLQuietErrorHandler );
    
    const char* pszAccess = NULL;
    if( bUpdateAccess )
        pszAccess = "r+";
    else
        pszAccess = "r";
    
    hSHP = SHPOpen ( CPLResetExtension( pszFullName, "shp" ) , pszAccess );
    hDBF = DBFOpen ( CPLResetExtension( pszFullName, "dbf" ) , pszAccess );
    
    CPLPopErrorHandler();
    
    if( NULL == hSHP || NULL == hDBF )
    {
        CPLString osMsg(CPLGetLastErrorMsg());
        CPLError( CE_Failure, CPLE_OpenFailed, "%s", osMsg.c_str() );

        return OGRERR_FAILURE;
    }

/* -------------------------------------------------------------------- */
/*      Update total shape count.                                       */
/* -------------------------------------------------------------------- */
    nTotalShapeCount = hDBF->nRecords;

    return OGRERR_NONE;
}
Beispiel #19
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 );
}
Beispiel #20
0
int main( int argc, char ** argv )

{
    SHPHandle	old_SHP, new_SHP;
    DBFHandle   old_DBF, new_DBF;
    int		nShapeType, nEntities, nVertices, nParts, *panParts, i, iPart;
    double	*padVertices, adBounds[4];
    const char 	*pszPlus;
    DBFFieldType  idfld_type;
    int		idfld, nflds;
    char	kv[257] = "";
    char	idfldName[120] = "";
    char	fldName[120] = "";
    char	shpFileName[120] = "";
    char	dbfFileName[120] = "";
    char	*DBFRow = NULL;
    int		Cpan[2] = { 0,0 };
    int		byRing = 1;
    PT		oCentrd, ringCentrd;
    SHPObject	*psCShape, *cent_pt;
    double	oArea = 0.0, oLen = 0.0;

    if( argc < 2 )
    {
	printf( "shpdata shp_file \n" );
	exit( 1 );
    }
    
    old_SHP = SHPOpen (argv[1], "rb" );
    old_DBF = DBFOpen (argv[1], "rb");
    if( old_SHP == NULL || old_DBF == NULL )
    {
	printf( "Unable to open old files:%s\n", argv[1] );
	exit( 1 );
    }

    SHPGetInfo( old_SHP, &nEntities, &nShapeType, NULL, NULL );
    for( i = 0; i < nEntities; i++ )
    {
	int		res ;

	psCShape = SHPReadObject( old_SHP, i );

        if ( byRing == 1 ) {
          int 	   ring, prevStart, ringDir;
	  double   ringArea;

          prevStart = psCShape->nVertices;
          for ( ring = (psCShape->nParts - 1); ring >= 0; ring-- ) {
	    SHPObject 	*psO;
	    int		j, numVtx, rStart;
            
            rStart = psCShape->panPartStart[ring];
            if ( ring == (psCShape->nParts -1) )
              { numVtx = psCShape->nVertices - rStart; }
             else
              { numVtx = psCShape->panPartStart[ring+1] - rStart; }
              
            printf ("(shpdata) Ring(%d) (%d for %d) \n", ring, rStart, numVtx);              
	    psO = SHPClone ( psCShape, ring,  ring + 1 );

            ringDir = SHPRingDir_2d ( psO, 0 );
            ringArea = RingArea_2d (psO->nVertices,(double*) psO->padfX,
            	 (double*) psO->padfY);
            RingCentroid_2d ( psO->nVertices, (double*) psO->padfX, 
     		(double*) psO->padfY, &ringCentrd, &ringArea);  

            	 
            printf ("(shpdata)  Ring %d, %f Area %d dir \n", 
           	ring, ringArea, ringDir );

	    SHPDestroyObject ( psO );
            printf ("(shpdata) End Ring \n");
           }  /* (ring) [0,nParts  */

          }  /* by ring   */

	   oArea = SHPArea_2d ( psCShape );
	   oLen = SHPLength_2d ( psCShape ); 
	   oCentrd = SHPCentrd_2d ( psCShape );
           printf ("(shpdata) Part (%d) %f Area  %f length, C (%f,%f)\n",
           	 i, oArea, oLen, oCentrd.x, oCentrd.y );
    }

    SHPClose( old_SHP );

    DBFClose( old_DBF );

    printf ("\n");
}
bool getPolysFromShapefile(QString const &fileShp,
                           QList<QList<Vec2d> > &listPolygons)
{
    SHPHandle hSHP = SHPOpen(fileShp.toLocal8Bit().data(),"rb");
    if(hSHP == NULL)   {
        qDebug() << "ERROR: Could not open shape file";
        return false;
    }

    if(hSHP->nShapeType != SHPT_POLYGON)   {
        qDebug() << "ERROR: Wrong shape file type:";
        qDebug() << "ERROR: Expected POLYGON";
        return false;
    }

    size_t nRecords = hSHP->nRecords;
    double xMax = hSHP->adBoundsMax[0];
    double yMax = hSHP->adBoundsMax[1];
    double xMin = hSHP->adBoundsMin[0];
    double yMin = hSHP->adBoundsMin[1];
    qDebug() << "INFO: Bounds: x: " << xMin << "<>" << xMax;
    qDebug() << "INFO: Bounds: y: " << yMin << "<>" << yMax;
    qDebug() << "INFO: Found " << nRecords << "POLYGONS";
    qDebug() << "INFO: Reading in data...";

    qDebug() << "INFO: Creating color list...";
    QStringList listColors;
    for(size_t i=0; i < nRecords; i++)   {
        QString strColor = QString::number(i,16);
        while(strColor.length() < 6)   {    // pad with zeros
            strColor.prepend("0");
        }
        strColor.prepend("#");
        listColors.push_back(strColor);
    }

    // create a list of polygons we can paint
    SHPObject * pSHPObj;

    for(size_t i=0; i < nRecords; i++)
    {   // for each object
        pSHPObj = SHPReadObject(hSHP,i);
        size_t nParts = pSHPObj->nParts;

        // build a list of start and end pts
        QList<int> listStartPts;
        QList<int> listEndB4Pts;
        for(size_t j=0; j < nParts-1; j++)   {
            listStartPts.push_back(pSHPObj->panPartStart[j]);
            listEndB4Pts.push_back(pSHPObj->panPartStart[j+1]);
        }
        listStartPts.push_back(pSHPObj->panPartStart[nParts-1]);
        listEndB4Pts.push_back(pSHPObj->nVertices);

        // build polys from start/end pts
        for(int j=0; j < listStartPts.size(); j++)
        {
            QList<Vec2d> listPts;
            size_t sIx = listStartPts[j];
            size_t eIx = listEndB4Pts[j];

            for(size_t k=sIx; k < eIx; k++)   {
                listPts.push_back(Vec2d(pSHPObj->padfX[k]+180,
                                        (pSHPObj->padfY[k]-90)*-1,
                                        QColor(listColors[i])));
            }
            listPolygons.push_back(listPts);
        }
        SHPDestroyObject(pSHPObj);
    }
    SHPClose(hSHP);

    return true;
}
Beispiel #22
0
//----------------------------------------------------------------------------
int ShapefileReader::RequestData(
                                 vtkInformation* vtkNotUsed( request ),
                                 vtkInformationVector** vtkNotUsed(inputVector),
                                 vtkInformationVector* outputVector)
{
  vtkInformation* outInfo = outputVector->GetInformationObject(0);
  vtkPolyData* polydata = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));

  if (illegalFileName()){
    return 0;
  }

  if (incompleteSrcFiles()){
    return 0;
  }

  SHPHandle shpHandle = SHPOpen(this->FileName, "rb");
  int fileType = 0;

  if (shpHandle == NULL){
    vtkErrorMacro("shp file read failed.");
    return 0;
  }

  vtkDebugMacro("file type: " << shpHandle->nShapeType);

  switch (shpHandle->nShapeType) {
    case SHPT_NULL:
      vtkErrorMacro("NULL Object type." << this->FileName);
      SHPClose(shpHandle);
      return 0;
      break;
    case SHPT_POINT:
    case SHPT_POINTZ:
    case SHPT_POINTM:
    case SHPT_MULTIPOINT:
    case SHPT_MULTIPOINTZ:
    case SHPT_MULTIPOINTM:
      fileType = POINTOBJ;
      break;
    case SHPT_ARC:
    case SHPT_ARCZ:
    case SHPT_ARCM:
      fileType = LINEOBJ;
      break;
    case SHPT_POLYGON:
    case SHPT_POLYGONZ:
    case SHPT_POLYGONM:
      fileType = FACEOBJ;
      break;
    case SHPT_MULTIPATCH:
      fileType = MESHOBJ;
      break;
    default:
      vtkErrorMacro("Unknown Object type." << this->FileName);
      SHPClose(shpHandle);
      return 0;
  }

  int pCount=0, pStart=0, pEnd=0;
  int vTracker = 0, pid=0;
  SHPObject* shpObj;

  vtkSmartPointer<vtkPoints> pts = vtkSmartPointer<vtkPoints>::New();
  vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkCellArray> strips = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkCellArray> pLines = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkCellArray> verts = vtkSmartPointer<vtkCellArray>::New();
  vtkSmartPointer<vtkTriangleFilter> tFilter = vtkSmartPointer<vtkTriangleFilter>::New();
  vtkSmartPointer<vtkStripper> stripper = vtkSmartPointer<vtkStripper>::New();
  vtkSmartPointer<vtkPolyData> pdRaw = vtkSmartPointer<vtkPolyData>::New();
  vtkSmartPointer<vtkPolyData> pdRefined = vtkSmartPointer<vtkPolyData>::New();

  //looping through all records in file
  for (int rIndex = 0; rIndex < shpHandle->nRecords; rIndex++){
    
    shpObj = SHPReadObject(shpHandle, rIndex);

    //making sure shp object type is consistent with file type
    if (shpObj->nSHPType != shpHandle->nShapeType){
      vtkErrorMacro("Inconsistent shape type of record: " << rIndex 
        << " in file " << this->FileName);
      continue;
    }

    pCount = shpObj->nParts;
    
    switch (fileType){
    case POINTOBJ:{

      vtkIdType *ids = new vtkIdType[shpObj->nVertices];

      for (int vIndex = 0; vIndex < shpObj->nVertices; vIndex++){
        pts->InsertPoint(pid,shpObj->padfX[vIndex],
                             shpObj->padfY[vIndex],
                             shpObj->padfZ[vIndex]);
        ids[vIndex] = pid++;
      }
      verts->InsertNextCell(shpObj->nVertices, ids);
      delete ids;
      ids = NULL;
      break;

    }
    case LINEOBJ:{
      
      for (int pIndex = 0; pIndex < pCount; pIndex++){
        pStart = shpObj->panPartStart[pIndex];

        if (pIndex == (pCount-1)){
          pEnd = shpObj->nVertices;
        }else{
          pEnd = shpObj->panPartStart[pIndex+1];
        }

        vtkSmartPointer<vtkPolyLine> pLine = vtkSmartPointer<vtkPolyLine>::New();
        pLine->GetPointIds()->SetNumberOfIds(pEnd-pStart); 

        for (int vIndex = pStart; vIndex < pEnd; vIndex++){
          pts->InsertNextPoint(shpObj->padfX[vIndex],
                               shpObj->padfY[vIndex],
                               shpObj->padfZ[vIndex]);
          pLine->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
        }
        pLines->InsertNextCell(pLine);
        vTracker += pEnd-pStart;
      }
      break;

    }
    case FACEOBJ:{

      for (int pIndex = 0; pIndex < pCount; pIndex++){
        pStart = shpObj->panPartStart[pIndex];

        if (pIndex == (pCount-1)){
          pEnd = shpObj->nVertices;
        }else{
          pEnd = shpObj->panPartStart[pIndex+1];
        }
        vtkSmartPointer<vtkPolygon> poly = vtkSmartPointer<vtkPolygon>::New();
        vtkSmartPointer<vtkPolyLine> pLine = vtkSmartPointer<vtkPolyLine>::New();
        poly->GetPointIds()->SetNumberOfIds(pEnd-pStart); 
        pLine->GetPointIds()->SetNumberOfIds(pEnd-pStart); 

        for (int vIndex = pStart; vIndex < pEnd; vIndex++){
          pts->InsertNextPoint(shpObj->padfX[vIndex],
                               shpObj->padfY[vIndex],
                               shpObj->padfZ[vIndex]);
          poly->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
          pLine->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
        }

        polys->InsertNextCell(poly);
        pLines->InsertNextCell(pLine);
        vTracker += pEnd-pStart;
      }
      break;

    }
    case MESHOBJ:{

      switch (*(shpObj->panPartType)){

      case SHPP_TRISTRIP:{
        for (int pIndex = 0; pIndex < pCount; pIndex++){
          pStart = shpObj->panPartStart[pIndex];

          if (pIndex == (pCount-1)){
            pEnd = shpObj->nVertices;
          }else{
            pEnd = shpObj->panPartStart[pIndex+1];
          }

          vtkSmartPointer<vtkTriangleStrip> strip = vtkSmartPointer<vtkTriangleStrip>::New();
          strip->GetPointIds()->SetNumberOfIds(pEnd-pStart);

          for (int vIndex = pStart; vIndex < pEnd; vIndex++){
            pts->InsertNextPoint(shpObj->padfX[vIndex],
                                 shpObj->padfY[vIndex],
                                 shpObj->padfZ[vIndex]);
            strip->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
          }

          strips->InsertNextCell(strip);
          vTracker += pEnd-pStart;
        }
        break;
      }//SHPP_TRISTRIP
      case SHPP_TRIFAN:{
        for (int pIndex = 0; pIndex < pCount; pIndex++){
          pStart = shpObj->panPartStart[pIndex];

          if (pIndex == (pCount-1)){
            pEnd = shpObj->nVertices;
          }else{
            pEnd = shpObj->panPartStart[pIndex+1];
          }

          vtkSmartPointer<vtkTriangleStrip> strip = vtkSmartPointer<vtkTriangleStrip>::New();
          strip->GetPointIds()->SetNumberOfIds(pEnd-pStart);

          for (int vIndex = pStart; vIndex < pEnd; vIndex++){
            pts->InsertNextPoint(shpObj->padfX[vIndex],
                                 shpObj->padfY[vIndex],
                                 shpObj->padfZ[vIndex]);
            strip->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
          }

          strips->InsertNextCell(strip);
          vTracker += pEnd-pStart;
        }
        break;
      }//SHPP_TRIFAN
      case SHPP_OUTERRING:
      case SHPP_INNERRING:
      case SHPP_FIRSTRING:
      case SHPP_RING:{
        for (int pIndex = 0; pIndex < pCount; pIndex++){
        pStart = shpObj->panPartStart[pIndex];

        if (pIndex == (pCount-1)){
          pEnd = shpObj->nVertices;
        }else{
          pEnd = shpObj->panPartStart[pIndex+1];
        }
        vtkSmartPointer<vtkPolygon> poly = vtkSmartPointer<vtkPolygon>::New();
        vtkSmartPointer<vtkPolyLine> pLine = vtkSmartPointer<vtkPolyLine>::New();
        poly->GetPointIds()->SetNumberOfIds(pEnd-pStart); 
        pLine->GetPointIds()->SetNumberOfIds(pEnd-pStart); 

        for (int vIndex = pStart; vIndex < pEnd; vIndex++){
          pts->InsertNextPoint(shpObj->padfX[vIndex],
                               shpObj->padfY[vIndex],
                               shpObj->padfZ[vIndex]);
          poly->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
          pLine->GetPointIds()->SetId(vIndex-pStart, vTracker+vIndex-pStart);
        }

        polys->InsertNextCell(poly);
        pLines->InsertNextCell(pLine);
        vTracker += pEnd-pStart;
      }
      break;
      }//rings
      }//panPartType
      break;
    
    }//MESHOBJ
    }//fileType

    SHPDestroyObject(shpObj);
  }// rIndex
  SHPClose(shpHandle);
  
  DBFHandle dbfHandle = DBFOpen(this->FileName, "rb");
  int fieldCount = DBFGetFieldCount(dbfHandle);
  
  for (int fieldIndex = 0; fieldIndex < fieldCount; fieldIndex++){
    
    DBFFieldType fieldType;
    const char *typeName;
    char nativeFieldType;
    char pszFieldName[12];
    int pnWidth=0, pnDecimals=0, recordCount=0;

    nativeFieldType = DBFGetNativeFieldType(dbfHandle, fieldIndex);
    fieldType = DBFGetFieldInfo(dbfHandle, fieldIndex, pszFieldName, &pnWidth, &pnDecimals);
    recordCount = DBFGetRecordCount(dbfHandle);

    vtkDebugMacro("record count: " << recordCount);

    switch (fieldType){
    case FTString:{

      vtkSmartPointer<vtkStringArray> cellData = vtkSmartPointer<vtkStringArray>::New();

      cellData->SetName(pszFieldName);
      
      for (int recordIndex = 0; recordIndex < recordCount; recordIndex++){
        if (DBFIsAttributeNULL(dbfHandle, recordIndex, fieldIndex)){
          cellData->InsertNextValue("NULL");
        }else{
          cellData->InsertNextValue(DBFReadStringAttribute(dbfHandle, recordIndex, fieldIndex));
        }
      }
      
      polydata->GetCellData()->AddArray(cellData);

      break;
    }
    case FTInteger:{

      vtkSmartPointer<vtkIntArray> cellData = vtkSmartPointer<vtkIntArray>::New();

      cellData->SetName(pszFieldName);
      
      for (int recordIndex = 0; recordIndex < recordCount; recordIndex++){
        if (DBFIsAttributeNULL(dbfHandle, recordIndex, fieldIndex)){
          cellData->InsertNextValue(0);
        }else{
          cellData->InsertNextValue(DBFReadIntegerAttribute(dbfHandle, recordIndex, fieldIndex));
        }
      }
      
      polydata->GetCellData()->AddArray(cellData);

      break;
    }
    case FTDouble:{

      vtkSmartPointer<vtkDoubleArray> cellData = vtkSmartPointer<vtkDoubleArray>::New();

      cellData->SetName(pszFieldName);
      
      for (int recordIndex = 0; recordIndex < recordCount; recordIndex++){
        if (DBFIsAttributeNULL(dbfHandle, recordIndex, fieldIndex)){
          cellData->InsertNextValue(0.0);
        }else{
          cellData->InsertNextValue(DBFReadDoubleAttribute(dbfHandle, recordIndex, fieldIndex));
        }
      }
      
      polydata->GetCellData()->AddArray(cellData);

      break;
    }
    case FTLogical:{
      //what is this? lack of sample data!
      break;
    }
    case FTInvalid:{
      vtkErrorMacro("Invalid DBF field type");
      break;
    }    
    }
  }

  DBFClose(dbfHandle);

  
  //pdRaw->SetPoints(pts);
  //pdRaw->SetPolys(polys);
  //pdRaw->SetLines(pLines);
  //pdRaw->SetVerts(verts);

  //tFilter->SetInput(pdRaw);
  //tFilter->Update();
  //pdRefined = tFilter->GetOutput();

  //polydata->SetPoints(pdRefined->GetPoints());
  //polydata->SetPolys(pdRefined->GetPolys());
  //polydata->SetLines(pdRefined->GetLines());
  //polydata->SetVerts(pdRefined->GetVerts());
  
  
  polydata->SetPoints(pts);
  polydata->SetLines(pLines);
  polydata->SetVerts(verts);
  polydata->SetStrips(strips);

  return 1;
}
Beispiel #23
0
static void Test_WriteArcPoly( int nSHPType, const char *pszFilename )

{
    SHPHandle	hSHPHandle;
    SHPObject	*psShape;
    double	x[100], y[100], z[100], m[100];
    int		anPartStart[100];
    int		anPartType[100], *panPartType;
    int		i, iShape;

    hSHPHandle = SHPCreate( pszFilename, nSHPType );

    if( nSHPType == SHPT_MULTIPATCH )
        panPartType = anPartType;
    else
        panPartType = NULL;

    for( iShape = 0; iShape < 3; iShape++ )
    {
        x[0] = 1.0;
        y[0] = 1.0+iShape*3;
        x[1] = 2.0;
        y[1] = 1.0+iShape*3;
        x[2] = 2.0;
        y[2] = 2.0+iShape*3;
        x[3] = 1.0;
        y[3] = 2.0+iShape*3;
        x[4] = 1.0;
        y[4] = 1.0+iShape*3;

        for( i = 0; i < 5; i++ )
        {
            z[i] = iShape * 10 + i + 3.35;
            m[i] = iShape * 10 + i + 4.45;
        }
        
        psShape = SHPCreateObject( nSHPType, -1, 0, NULL, NULL,
                                   5, x, y, z, m );
        SHPWriteObject( hSHPHandle, -1, psShape );
        SHPDestroyObject( psShape );
    }

/* -------------------------------------------------------------------- */
/*      Do a multi part polygon (shape).  We close it, and have two     */
/*      inner rings.                                                    */
/* -------------------------------------------------------------------- */
    x[0] = 0.0;
    y[0] = 0.0;
    x[1] = 0;
    y[1] = 100;
    x[2] = 100;
    y[2] = 100;
    x[3] = 100;
    y[3] = 0;
    x[4] = 0;
    y[4] = 0;

    x[5] = 10;
    y[5] = 20;
    x[6] = 30;
    y[6] = 20;
    x[7] = 30;
    y[7] = 40;
    x[8] = 10;
    y[8] = 40;
    x[9] = 10;
    y[9] = 20;

    x[10] = 60;
    y[10] = 20;
    x[11] = 90;
    y[11] = 20;
    x[12] = 90;
    y[12] = 40;
    x[13] = 60;
    y[13] = 40;
    x[14] = 60;
    y[14] = 20;

    for( i = 0; i < 15; i++ )
    {
        z[i] = i;
        m[i] = i*2;
    }

    anPartStart[0] = 0;
    anPartStart[1] = 5;
    anPartStart[2] = 10;

    anPartType[0] = SHPP_RING;
    anPartType[1] = SHPP_INNERRING;
    anPartType[2] = SHPP_INNERRING;
    
    psShape = SHPCreateObject( nSHPType, -1, 3, anPartStart, panPartType,
                               15, x, y, z, m );
    SHPWriteObject( hSHPHandle, -1, psShape );
    SHPDestroyObject( psShape );
    

    SHPClose( hSHPHandle );
}
Beispiel #24
0
int main( int argc, char ** argv )

{
    SHPHandle	hSHP, cSHP;
    int		nShapeType, i, nEntities, nShpInFile;
    SHPObject	*shape;

/* -------------------------------------------------------------------- */
/*      Display a usage message.                                        */
/* -------------------------------------------------------------------- */
    if( argc != 3 )
    {
	printf( "shpcat from_shpfile to_shpfile\n" );
	exit( 1 );
    }

/* -------------------------------------------------------------------- */
/*      Open the passed shapefile.                                      */
/* -------------------------------------------------------------------- */
    hSHP = SHPOpen( argv[1], "rb" );

    if( hSHP == NULL )
    {
	printf( "Unable to open:%s\n", argv[1] );
	exit( 1 );
    }
    
    SHPGetInfo( hSHP, &nEntities, &nShapeType, NULL, NULL );
    fprintf(stderr,"Opened From File %s, with %d shapes\n",argv[1],nEntities);

/* -------------------------------------------------------------------- */
/*      Open the passed shapefile.                                      */
/* -------------------------------------------------------------------- */
    cSHP = SHPOpen( argv[2], "rb+" );

    if( cSHP == NULL )
    {
	printf( "Unable to open:%s\n", argv[2] );
	exit( 1 );
    }
    
    SHPGetInfo( cSHP, &nShpInFile, NULL, NULL, NULL );
    fprintf(stderr,"Opened to file %s with %d shapes, ready to add %d\n",
            argv[2],nShpInFile,nEntities);

/* -------------------------------------------------------------------- */
/*	Skim over the list of shapes, printing all the vertices.	*/
/* -------------------------------------------------------------------- */
    for( i = 0; i < nEntities; i++ )
    {
        shape = SHPReadObject( hSHP, i );
        SHPWriteObject( cSHP, -1, shape );
        SHPDestroyObject ( shape );

    }

    SHPClose( hSHP );
    SHPClose( cSHP );

    exit( 0 );
}
Beispiel #25
0
void Builder::print_shpObjects()
{
  QgsDebugMsg( QString( "Number of primitives: %1" ).arg( shpObjects.size() ) );
  QgsDebugMsg( QString( "Number of text fields: %1" ).arg( textObjects.size() ) );
  QgsDebugMsg( QString( "Number of inserts fields: %1" ).arg( insertObjects.size() ) );

  SHPHandle hSHP;

  if ( fname.endsWith( ".shp", Qt::CaseInsensitive ) )
  {
    QString fn( fname.mid( fname.length() - 4 ) );

    outputdbf = fn + ".dbf";
    outputshp = fn + ".shp";
    outputtdbf = fn + "_texts.dbf";
    outputtshp = fn + "_texts.shp";
    outputidbf = fn + "_inserts.dbf";
    outputishp = fn + "_inserts.shp";
  }
  else
  {
    outputdbf = outputtdbf = outputidbf = fname + ".dbf";
    outputshp = outputtshp = outputishp = fname + ".shp";
  }

  DBFHandle dbffile = DBFCreate( outputdbf.toUtf8() );
  DBFAddField( dbffile, "myid", FTInteger, 10, 0 );

  hSHP = SHPCreate( outputshp.toUtf8(), shapefileType );

  QgsDebugMsg( "Writing to main shp file..." );

  for ( int i = 0; i < shpObjects.size(); i++ )
  {
    SHPWriteObject( hSHP, -1, shpObjects[i] );
    SHPDestroyObject( shpObjects[i] );
    DBFWriteIntegerAttribute( dbffile, i, 0, i );
  }

  SHPClose( hSHP );
  DBFClose( dbffile );

  QgsDebugMsg( "Done!" );

  if ( !textObjects.isEmpty() )
  {
    SHPHandle thSHP;

    DBFHandle Tdbffile = DBFCreate( outputtdbf.toUtf8() );
    thSHP = SHPCreate( outputtshp.toUtf8(), SHPT_POINT );

    DBFAddField( Tdbffile, "tipx", FTDouble, 20, 10 );
    DBFAddField( Tdbffile, "tipy", FTDouble, 20, 10 );
    DBFAddField( Tdbffile, "tipz", FTDouble, 20, 10 );
    DBFAddField( Tdbffile, "tapx", FTDouble, 20, 10 );
    DBFAddField( Tdbffile, "tapy", FTDouble, 20, 10 );
    DBFAddField( Tdbffile, "tapz", FTDouble, 20, 10 );
    DBFAddField( Tdbffile, "height", FTDouble, 20, 10 );
    DBFAddField( Tdbffile, "scale", FTDouble, 20, 10 );
    DBFAddField( Tdbffile, "flags", FTInteger, 10, 0 );
    DBFAddField( Tdbffile, "hjust", FTInteger, 10, 0 );
    DBFAddField( Tdbffile, "vjust", FTInteger, 10, 0 );
    DBFAddField( Tdbffile, "text", FTString, 50, 0 );
    DBFAddField( Tdbffile, "style", FTString, 50, 0 );
    DBFAddField( Tdbffile, "angle", FTDouble, 20, 10 );

    QgsDebugMsg( "Writing Texts' shp File..." );

    for ( int i = 0; i < textObjects.size(); i++ )
    {
      SHPObject *psObject;
      double x = textObjects[i].ipx;
      double y = textObjects[i].ipy;
      double z = textObjects[i].ipz;
      psObject = SHPCreateObject( SHPT_POINT, i, 0, NULL, NULL, 1, &x, &y, &z, NULL );

      SHPWriteObject( thSHP, -1, psObject );

      DBFWriteDoubleAttribute( Tdbffile, i, 0, textObjects[i].ipx );
      DBFWriteDoubleAttribute( Tdbffile, i, 1, textObjects[i].ipy );
      DBFWriteDoubleAttribute( Tdbffile, i, 2, textObjects[i].ipz );

      DBFWriteDoubleAttribute( Tdbffile, i, 3, textObjects[i].apx );
      DBFWriteDoubleAttribute( Tdbffile, i, 4, textObjects[i].apy );
      DBFWriteDoubleAttribute( Tdbffile, i, 5, textObjects[i].apz );

      DBFWriteDoubleAttribute( Tdbffile, i, 6, textObjects[i].height );
      DBFWriteDoubleAttribute( Tdbffile, i, 7, textObjects[i].xScaleFactor );
      DBFWriteIntegerAttribute( Tdbffile, i, 8, textObjects[i].textGenerationFlags );

      DBFWriteIntegerAttribute( Tdbffile, i, 9, textObjects[i].hJustification );
      DBFWriteIntegerAttribute( Tdbffile, i, 10, textObjects[i].vJustification );

      DBFWriteStringAttribute( Tdbffile, i, 11, textObjects[i].text.c_str() );
      DBFWriteStringAttribute( Tdbffile, i, 12, textObjects[i].style.c_str() );

      DBFWriteDoubleAttribute( Tdbffile, i, 13, textObjects[i].angle );

      SHPDestroyObject( psObject );
    }
    SHPClose( thSHP );
    DBFClose( Tdbffile );

    QgsDebugMsg( "Done!" );
  }

  if ( !insertObjects.isEmpty() )
  {
    SHPHandle ihSHP;

    DBFHandle Idbffile = DBFCreate( outputidbf.toUtf8() );
    ihSHP = SHPCreate( outputishp.toUtf8(), SHPT_POINT );

    DBFAddField( Idbffile, "name", FTString, 200, 0 );
    DBFAddField( Idbffile, "ipx", FTDouble, 20, 10 );
    DBFAddField( Idbffile, "ipy", FTDouble, 20, 10 );
    DBFAddField( Idbffile, "ipz", FTDouble, 20, 10 );
    DBFAddField( Idbffile, "sx", FTDouble, 20, 10 );
    DBFAddField( Idbffile, "sy", FTDouble, 20, 10 );
    DBFAddField( Idbffile, "sz", FTDouble, 20, 10 );
    DBFAddField( Idbffile, "angle", FTDouble, 20, 10 );
    DBFAddField( Idbffile, "cols", FTInteger, 20, 0 );
    DBFAddField( Idbffile, "rows", FTInteger, 20, 0 );
    DBFAddField( Idbffile, "colsp", FTDouble, 20, 10 );
    DBFAddField( Idbffile, "rowsp", FTDouble, 20, 10 );

    QgsDebugMsg( "Writing Insert' shp File..." );

    for ( int i = 0; i < insertObjects.size(); i++ )
    {
      SHPObject *psObject;
      double &x = insertObjects[i].ipx;
      double &y = insertObjects[i].ipy;
      double &z = insertObjects[i].ipz;
      psObject = SHPCreateObject( SHPT_POINT, i, 0, NULL, NULL, 1, &x, &y, &z, NULL );

      SHPWriteObject( ihSHP, -1, psObject );

      int c = 0;
      DBFWriteStringAttribute( Idbffile, i, c++, insertObjects[i].name.c_str() );
      DBFWriteDoubleAttribute( Idbffile, i, c++, insertObjects[i].ipx );
      DBFWriteDoubleAttribute( Idbffile, i, c++, insertObjects[i].ipy );
      DBFWriteDoubleAttribute( Idbffile, i, c++, insertObjects[i].ipz );
      DBFWriteDoubleAttribute( Idbffile, i, c++, insertObjects[i].sx );
      DBFWriteDoubleAttribute( Idbffile, i, c++, insertObjects[i].sy );
      DBFWriteDoubleAttribute( Idbffile, i, c++, insertObjects[i].sz );
      DBFWriteDoubleAttribute( Idbffile, i, c++, insertObjects[i].angle );
      DBFWriteIntegerAttribute( Idbffile, i, c++, insertObjects[i].cols );
      DBFWriteIntegerAttribute( Idbffile, i, c++, insertObjects[i].rows );
      DBFWriteDoubleAttribute( Idbffile, i, c++, insertObjects[i].colSp );
      DBFWriteDoubleAttribute( Idbffile, i, c++, insertObjects[i].rowSp );

      SHPDestroyObject( psObject );
    }
    SHPClose( ihSHP );
    DBFClose( Idbffile );

    QgsDebugMsg( "Done!" );
  }
}
Beispiel #26
0
    SHPCreateTree( SHPHandle hSHP, int nDimension, int nMaxDepth,
                   double *padfBoundsMin, double *padfBoundsMax )

{
    SHPTree	*psTree;

    if( padfBoundsMin == NULL && hSHP == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Allocate the tree object                                        */
/* -------------------------------------------------------------------- */
    psTree = (SHPTree *) malloc(sizeof(SHPTree));
    if( NULL == psTree )
    {
        return NULL;
    }

    psTree->hSHP = hSHP;
    psTree->nMaxDepth = nMaxDepth;
    psTree->nDimension = nDimension;
    psTree->nTotalCount = 0;

/* -------------------------------------------------------------------- */
/*      If no max depth was defined, try to select a reasonable one     */
/*      that implies approximately 8 shapes per node.                   */
/* -------------------------------------------------------------------- */
    if( psTree->nMaxDepth == 0 && hSHP != NULL )
    {
        int	nMaxNodeCount = 1;
        int	nShapeCount;

        SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL );
        while( nMaxNodeCount*4 < nShapeCount )
        {
            psTree->nMaxDepth += 1;
            nMaxNodeCount = nMaxNodeCount * 2;
        }

#ifdef USE_CPL
        CPLDebug( "Shape",
                  "Estimated spatial index tree depth: %d",
                  psTree->nMaxDepth );
#endif

        /* NOTE: Due to problems with memory allocation for deep trees,
         * automatically estimated depth is limited up to 12 levels.
         * See Ticket #1594 for detailed discussion.
         */
        if( psTree->nMaxDepth > MAX_DEFAULT_TREE_DEPTH )
        {
            psTree->nMaxDepth = MAX_DEFAULT_TREE_DEPTH;

#ifdef USE_CPL
            CPLDebug( "Shape",
                      "Falling back to max number of allowed index tree levels (%d).",
                      MAX_DEFAULT_TREE_DEPTH );
#endif
        }
    }

/* -------------------------------------------------------------------- */
/*      Allocate the root node.                                         */
/* -------------------------------------------------------------------- */
    psTree->psRoot = SHPTreeNodeCreate( padfBoundsMin, padfBoundsMax );
    if( NULL == psTree->psRoot )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Assign the bounds to the root node.  If none are passed in,     */
/*      use the bounds of the provided file otherwise the create        */
/*      function will have already set the bounds.                      */
/* -------------------------------------------------------------------- */
    assert( NULL != psTree );
    assert( NULL != psTree->psRoot );
	
    if( padfBoundsMin == NULL )
    {
        SHPGetInfo( hSHP, NULL, NULL,
                    psTree->psRoot->adfBoundsMin, 
                    psTree->psRoot->adfBoundsMax );
    }

/* -------------------------------------------------------------------- */
/*      If we have a file, insert all it's shapes into the tree.        */
/* -------------------------------------------------------------------- */
    if( hSHP != NULL )
    {
        int	iShape, nShapeCount;
        
        SHPGetInfo( hSHP, &nShapeCount, NULL, NULL, NULL );

        for( iShape = 0; iShape < nShapeCount; iShape++ )
        {
            SHPObject	*psShape;
            
            psShape = SHPReadObject( hSHP, iShape );
            if( psShape != NULL )
            {
                SHPTreeAddShapeId( psTree, psShape );
                SHPDestroyObject( psShape );
            }
        }
    }        

    return psTree;
}
Beispiel #27
0
bool ShapelibProxy::query(const std::string &handle, std::string &errorMessage, 
   const std::string &whereClause, const std::string &labelFormat,
   LocationType minClip, LocationType maxClip, const CoordinateTransformation* pCoordinateTransformation)
{
   std::map<std::string, ShapelibHandle>::iterator iter = mHandles.find(handle);
   if (iter == mHandles.end())
   {
      errorMessage = "Could not find handle";
      return false;
   }
   ShapelibHandle& shapelibHandle = iter->second;

   if (!whereClause.empty())
   {
      errorMessage = "Shapelib does not support where clauses";
      return false;
   }

   std::string formattedLabel = preprocessFormatString(shapelibHandle, labelFormat);

   int count = 0;
   ArcProxyLib::FeatureType featureType = ArcProxyLib::UNKNOWN;
   if (!getTypeAndCount(shapelibHandle, errorMessage, featureType, count))
   {
      return false;
   }

   for (int i = 0; i < count; ++i)
   {
      SHPObject* pShpObject = SHPReadObject(shapelibHandle.getShpHandle(), i);
      if (pShpObject == NULL)
      {
         continue;
      }

      // Convert from shapefile coordinates to application coordinates.
      double minX = pShpObject->dfXMin;
      double maxX = pShpObject->dfXMax;
      double minY = pShpObject->dfYMin;
      double maxY = pShpObject->dfYMax;
      if (pCoordinateTransformation != NULL)
      {
         if (pCoordinateTransformation->translateShapeToApp(minX, minY, minX, minY) == false ||
            pCoordinateTransformation->translateShapeToApp(maxX, maxY, maxX, maxY) == false)
         {
            errorMessage = "Coordinate transformation failed for bounding box. Check the .prj file and try again.";
            return false;
         }
      }

      QRectF objectRect(QPointF(minY, minX), QPointF(maxY, maxX));
      QRectF clipRect(QPointF(minClip.mX, minClip.mY), QPointF(maxClip.mX, maxClip.mY));

      if ((clipRect.isEmpty() == true) ||
         ((objectRect.isEmpty() == true) && (clipRect.contains(objectRect.topLeft()) == true)) ||
         (objectRect.intersects(clipRect) == true))
      {
         ArcProxyLib::Feature feature;
         feature.setType(featureType);

         std::vector<std::pair<double, double> > vertices(pShpObject->nVertices);
         for (int vertex = 0; vertex < pShpObject->nVertices; ++vertex)
         {
            // Convert from shapefile coordinates to application coordinates.
            double vertexX = pShpObject->padfX[vertex];
            double vertexY = pShpObject->padfY[vertex];
            if (pCoordinateTransformation != NULL)
            {
               if (pCoordinateTransformation->translateShapeToApp(vertexX, vertexY, vertexX, vertexY) == false)
               {
                  errorMessage = "Coordinate transformation failed for vertex. Check the .prj file and try again.";
                  return false;
               }
            }

            vertices[vertex] = std::make_pair(vertexY, vertexX);
         }

         feature.setVertices(vertices);

         for (int path = 0; path < pShpObject->nParts; ++path)
         {
            feature.addPathAtIndex(pShpObject->panPartStart[path]);
         }

         feature.setLabel(std::for_each(formattedLabel.begin(), formattedLabel.end(), ShapelibFormatStringProcessor(
            shapelibHandle, i)).getProcessedString());

         std::vector<std::string> attributes;
         int fieldCount = DBFGetFieldCount(shapelibHandle.getDbfHandle());
         for (int field = 0; field < fieldCount; ++field)
         {
            std::string name;
            std::string type;
            std::string value;
            if (getFieldAttributes(shapelibHandle, name, type, value, field, i))
            {
               attributes.push_back(value);
            }
         }
         feature.setAttributes(attributes);
         emit featureLoaded(feature);
      }

      SHPDestroyObject(pShpObject);
   }

   return true;
}
Beispiel #28
0
countries_v
shape_load_countries(const char* filename) {

    countries_v countries;
    kv_init(countries);

    double  adfMinBound[4],
            adfMaxBound[4];

    // Read file
    SHPHandle hSHP = SHPOpen( filename, "rb" );
    if(hSHP == NULL) goto end_loading;

    // Print shape bounds
    int country_count, shapes_vype;
    SHPGetInfo( hSHP, &country_count, &shapes_vype, adfMinBound, adfMaxBound );
    
    fprintf(stderr, "Load %d countries\n", country_count);
    // Iterate through countries
    for(int i = 0; i < country_count; i++ ) {
                        
        SHPObject *shp = SHPReadObject(hSHP, i);
        if(shp == NULL) goto end_loading;

        if(shp->nParts == 0) continue;

        // first part starts at point 0
        if(shp->panPartStart[0] != 0) goto end_loading;

        // collect parts of country
        shapes_v shapes;
        kv_init(shapes);
        shapes.min = (point_t){shp->dfXMin, shp->dfYMin};
        shapes.max = (point_t){shp->dfXMax, shp->dfYMax};

        uint32_t parts = shp->nParts;
        double k = 0.0;
        for (uint32_t j=0; j<parts; j++) {
            // start index
            uint32_t s = shp->panPartStart[j];
            // end index - start of next minus one, or end
            uint32_t e = (j+1 < parts) ?
                shp->panPartStart[j+1]:
                shp->nVertices;
            shape_v shape;
            kv_init(shape);
            // collect points of part
            for(uint32_t i=s; i<e; i++){
                point_t p = (point_t){shp->padfX[i], shp->padfY[i]};
                kv_push(point_t, shape, p);
                // cumulitive average for center
                if(k>=1.0) {
                    shapes.center.x = (k-1.0)/k*shapes.center.x + p.x/k;
                    shapes.center.y = (k-1.0)/k*shapes.center.y + p.y/k;
                }else {
                    shapes.center.x = p.x;
                    shapes.center.y = p.y;
                }
                k+=1.0;
            }
            kv_push(shape_v, shapes, shape);
        }
        SHPDestroyObject( shp );
        kv_push(shapes_v, countries, shapes);
    }
    SHPClose( hSHP );

end_loading:
    return countries;
}
Beispiel #29
0
int main(){
  int entityCount;
  int shapeType;
  double padfMinBound[4];
  double padfMaxBound[4];
  int i;
  int use_gal = 1;
  int use_dist = 0;
  //For josh
  //char sf_name[] = "/home/joshua/FultonCoData/Fultoncombinednd_10.shp";
  //for sumanth
  //char sf_name[] = "/home/sumanth/Documents/eDemocracy/Files/Fultoncombinednd.shp";
  //for alice
 char sf_name[]= "/home/altheacynara/Documents/saltLakeData/tl_2008_49035_tabblock.shp";
  // char sf_name[]="/home/altheacynara/Documents/fultonData/Fultoncombinednd.shp";
  //Eventually, this won't be hardcoded

  SHPHandle handle = SHPOpen(sf_name, "rb");


  int fn_len = strlen(sf_name);
  char svg_filename[fn_len];
  char gal_filename[fn_len];
  char dst_filename[fn_len];
  FILE *svg;
  strcpy(svg_filename, sf_name);
  strcpy(gal_filename, sf_name);
  strcpy(dst_filename, sf_name);
  svg_filename[fn_len-2] = 'v';
  svg_filename[fn_len-1] = 'g';
  gal_filename[fn_len-3] = 'G';
  gal_filename[fn_len-2] = 'A';
  gal_filename[fn_len-1] = 'L';
  dst_filename[fn_len-3] = 'd';
  dst_filename[fn_len-2] = 's';
  dst_filename[fn_len-1] = 't';
  //I know, the above isn't really robust enough.
  //Should be improved upon when the file name is no longer hardcoded

  SHPGetInfo(handle, &entityCount, &shapeType, padfMinBound, padfMaxBound);
 
  SHPObject **shapeList = malloc(entityCount*sizeof(SHPObject *));
  //neighborList neighbors[entityCount];
  struct neighbor_list *NLIST;
  double xCentList[entityCount];
  double yCentList[entityCount];
  double areaList[entityCount];
  //populate the shapeList
  for(i=0; i<entityCount; i++){
    shapeList[i] = SHPReadObject(handle,i);
  }
  printf("Shapelist populated.\n");
  //delete file if it exists
  remove(svg_filename);
  //set up the SVG file pointer
  svg = fopen(svg_filename, "a+");
  printf("SVG file opened for writing.\n");
  //write header
  svg_header(svg);
  printf("SVG header printed.\n");
  //Call colorArrange:
  int ndists=5;
  int *colorArray = malloc(entityCount*sizeof(int));
  colorArrange(colorArray,entityCount,ndists, dst_filename);

  //write individual polygons
  for(i=0; i<entityCount; i++){
    svg_polygon(*shapeList[i], svg, use_dist, colorArray);
  }
  printf("Polygons all printed.\n");


  if(use_gal){
    FILE *gal;
    int block, num_neigh, nblocks, temp_neigh;
    int count=0;
    gal= fopen(gal_filename, "r");
    if(gal==NULL){
      printf("Error: Could not open GAL file.\n");
      return -1;
    }
    fscanf(gal, "%d", &nblocks);
    
    if(nblocks==entityCount){
       printf("GAL block count matches shapefile block count. Proceeding...\n");
    }else{
      printf("GAL block count does not match. Exiting...\n");
      exit(EXIT_FAILURE);
    }
	  
    NLIST = malloc(nblocks * sizeof(struct neighbor_list));
	  
    while(fscanf(gal, "%d %d", &block, &num_neigh) != EOF)
      {
	NLIST[block].num_neighbors = num_neigh;
	if(num_neigh != 0)
	  { 
	    count=0;
	    NLIST[block].neighbors = malloc(num_neigh * sizeof(int));
	    while(count < num_neigh)
	      {
		fscanf(gal, "%d", &temp_neigh);
		NLIST[block].neighbors[count] = temp_neigh;
		count++;
	      }
	  }
      }

    //Debugging: print the neighbor list of all blocks
    /*int i,j;
      for(i=0;i<nblocks;i++)
      {
      printf("%d %d\n", i, NLIST[i].num_neighbors);
      if(NLIST[i].num_neighbors > 0)
      for(j=0;j<NLIST[i].num_neighbors;j++)
      printf("%d ", NLIST[i].neighbors[j]);
      printf("\n");
      }*/

    //find centroids for every block
    for(i=0; i<entityCount; i++){
      int lastPoint;
      int status;
      SHPObject block = *shapeList[i];
      //Note that we're going to disregard holes, etc.
      if(block.nParts>1){
	lastPoint = block.panPartStart[1]-1;
      }else{
	lastPoint = block.nVertices-1;
      }
      status = polyCentroid(block.padfX, block.padfY, lastPoint, 
			    xCentList+i, yCentList+i, areaList+i);
    }
    printf("Centroids calculated.\n");

    //write paths from centroid to centroid
    fputs("\t</g>\n", svg);
    fputs("\t<g\n\t\tid=\"layer2\">\n", svg);
    for(i=0; i<entityCount; i++){
      svg_neighbors(*shapeList[i], NLIST[i], xCentList, yCentList, svg);
    }
    //svg_neighbors(*shapeList[20], NLIST[20], xCentList, yCentList, svg);
    printf("Contiguity paths drawn.\n");

    //this is the section that's screwing up
    //Free NLIST
    for(i=0; i<entityCount; i++)
      {
        printf("i is %d\n", i);
        printf("NLIST[i]\n");
        free(NLIST[i].neighbors);
        NLIST[i].neighbors = NULL;
      }
    free(NLIST);
    NLIST = NULL;
    fclose(gal);
    //end section that's screwing up
  }
  
  //write footer
  svg_footer(svg);
  printf("SVG footer printed.\n");
  for(i=0; i<entityCount; i++){
    SHPDestroyObject(shapeList[i]);
  }
  SHPClose(handle);
  fclose(svg);
  free(colorArray);
  return 0;
}
Beispiel #30
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;
}