Example #1
0
OGRGeometry *OGRLinearRing::clone() const

{
    OGRLinearRing *poNewLinearRing = new OGRLinearRing();
    poNewLinearRing->assignSpatialReference( getSpatialReference() );

    poNewLinearRing->setPoints( nPointCount, paoPoints, padfZ, padfM );
    poNewLinearRing->flags = flags;

    return poNewLinearRing;
}
Example #2
0
OGRErr OGRPolygon::importFromWKTListOnly( char ** ppszInput,
                                          int bHasZ, int bHasM,
                                          OGRRawPoint*& paoPoints,
                                          int& nMaxPoints,
                                          double*& padfZ )

{
    char szToken[OGR_WKT_TOKEN_MAX] = {};
    const char *pszInput = *ppszInput;

    // Skip first '('.
    pszInput = OGRWktReadToken( pszInput, szToken );
    if( EQUAL(szToken, "EMPTY") )
    {
        *ppszInput = (char*) pszInput;
        return OGRERR_NONE;
    }
    if( !EQUAL(szToken, "(") )
        return OGRERR_CORRUPT_DATA;

/* ==================================================================== */
/*      Read each ring in turn.  Note that we try to reuse the same     */
/*      point list buffer from ring to ring to cut down on              */
/*      allocate/deallocate overhead.                                   */
/* ==================================================================== */
    int nMaxRings = 0;
    double *padfM = NULL;

    do
    {
        const char* pszNext = OGRWktReadToken( pszInput, szToken );
        if( EQUAL(szToken, "EMPTY") )
        {
/* -------------------------------------------------------------------- */
/*      Do we need to grow the ring array?                              */
/* -------------------------------------------------------------------- */
            if( oCC.nCurveCount == nMaxRings )
            {
                nMaxRings = nMaxRings * 2 + 1;
                oCC.papoCurves = static_cast<OGRCurve **>(
                    CPLRealloc(oCC.papoCurves,
                               nMaxRings * sizeof(OGRLinearRing*)));
            }
            oCC.papoCurves[oCC.nCurveCount] = new OGRLinearRing();
            oCC.nCurveCount++;

            pszInput = OGRWktReadToken( pszNext, szToken );
            if( !EQUAL(szToken, ",") )
                break;

            continue;
        }

/* -------------------------------------------------------------------- */
/*      Read points for one ring from input.                            */
/* -------------------------------------------------------------------- */
        int nPoints = 0;
        int flagsFromInput = flags;
        if( flagsFromInput == 0 )
        {
            // Flags was not set, this is not called by us.
            if( bHasM )
                flagsFromInput |= OGR_G_MEASURED;
            if( bHasZ )
                flagsFromInput |= OGR_G_3D;
        }

        pszInput = OGRWktReadPointsM( pszInput, &paoPoints, &padfZ, &padfM,
                                      &flagsFromInput,
                                      &nMaxPoints, &nPoints );
        if( pszInput == NULL || nPoints == 0 )
        {
            CPLFree(padfM);
            return OGRERR_CORRUPT_DATA;
        }
        if( (flagsFromInput & OGR_G_3D) && !(flags & OGR_G_3D) )
        {
            flags |= OGR_G_3D;
            bHasZ = TRUE;
        }
        if( (flagsFromInput & OGR_G_MEASURED) && !(flags & OGR_G_MEASURED) )
        {
            flags |= OGR_G_MEASURED;
            bHasM = TRUE;
        }

/* -------------------------------------------------------------------- */
/*      Do we need to grow the ring array?                              */
/* -------------------------------------------------------------------- */
        if( oCC.nCurveCount == nMaxRings )
        {
            nMaxRings = nMaxRings * 2 + 1;
            oCC.papoCurves = static_cast<OGRCurve **>(
                CPLRealloc(oCC.papoCurves, nMaxRings * sizeof(OGRLinearRing*)));
        }

/* -------------------------------------------------------------------- */
/*      Create the new ring, and assign to ring list.                   */
/* -------------------------------------------------------------------- */
        OGRLinearRing* poLR = new OGRLinearRing();
        oCC.papoCurves[oCC.nCurveCount] = poLR;

        if( bHasM && bHasZ )
            poLR->setPoints(nPoints, paoPoints, padfZ, padfM);
        else if( bHasM )
            poLR->setPointsM(nPoints, paoPoints, padfM);
        else if( bHasZ )
            poLR->setPoints(nPoints, paoPoints, padfZ);
        else
            poLR->setPoints(nPoints, paoPoints);

        oCC.nCurveCount++;

/* -------------------------------------------------------------------- */
/*      Read the delimiter following the ring.                          */
/* -------------------------------------------------------------------- */

        pszInput = OGRWktReadToken( pszInput, szToken );
    } while( szToken[0] == ',' );

    CPLFree( padfM );

/* -------------------------------------------------------------------- */
/*      freak if we don't get a closing bracket.                        */
/* -------------------------------------------------------------------- */

    if( szToken[0] != ')' )
        return OGRERR_CORRUPT_DATA;

    *ppszInput = const_cast<char *>(pszInput);
    return OGRERR_NONE;
}
Example #3
0
OGRFeature *OGRIdrisiLayer::GetNextRawFeature()
{
    while(TRUE)
    {
        if (eGeomType == wkbPoint)
        {
            double dfId;
            double dfX, dfY;
            if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfX, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfY, sizeof(double), 1, fp) != 1)
            {
                return NULL;
            }
            CPL_LSBPTR64(&dfId);
            CPL_LSBPTR64(&dfX);
            CPL_LSBPTR64(&dfY);

            if (m_poFilterGeom != NULL &&
                (dfX < m_sFilterEnvelope.MinX ||
                 dfX > m_sFilterEnvelope.MaxX ||
                 dfY < m_sFilterEnvelope.MinY ||
                 dfY > m_sFilterEnvelope.MaxY))
            {
                nNextFID ++;
                continue;
            }

            OGRPoint* poGeom = new OGRPoint(dfX, dfY);
            if (poSRS)
                poGeom->assignSpatialReference(poSRS);
            OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
            poFeature->SetField(0, dfId);
            poFeature->SetFID(nNextFID ++);
            poFeature->SetGeometryDirectly(poGeom);
            ReadAVLLine(poFeature);
            return poFeature;
        }
        else if (eGeomType == wkbLineString)
        {
            double dfId;
            double dfMinXShape, dfMaxXShape, dfMinYShape, dfMaxYShape;
            unsigned int nNodes;

            if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMinXShape, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMaxXShape, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMinYShape, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMaxYShape, sizeof(double), 1, fp) != 1)
            {
                return NULL;
            }
            CPL_LSBPTR64(&dfId);
            CPL_LSBPTR64(&dfMinXShape);
            CPL_LSBPTR64(&dfMaxXShape);
            CPL_LSBPTR64(&dfMinYShape);
            CPL_LSBPTR64(&dfMaxYShape);

            if (VSIFReadL(&nNodes, sizeof(unsigned int), 1, fp) != 1)
            {
                return NULL;
            }
            CPL_LSBPTR32(&nNodes);

            if (nNodes > 100 * 1000 * 1000)
                return NULL;

            if (m_poFilterGeom != NULL &&
                (dfMaxXShape < m_sFilterEnvelope.MinX ||
                 dfMinXShape > m_sFilterEnvelope.MaxX ||
                 dfMaxYShape < m_sFilterEnvelope.MinY ||
                 dfMinYShape > m_sFilterEnvelope.MaxY))
            {
                nNextFID ++;
                VSIFSeekL(fp, sizeof(OGRRawPoint) * nNodes, SEEK_CUR);
                continue;
            }

            OGRRawPoint* poRawPoints = (OGRRawPoint*)VSIMalloc2(sizeof(OGRRawPoint), nNodes);
            if (poRawPoints == NULL)
            {
                return NULL;
            }

            if ((unsigned int)VSIFReadL(poRawPoints, sizeof(OGRRawPoint), nNodes, fp) != nNodes)
            {
                VSIFree(poRawPoints);
                return NULL;
            }

#if defined(CPL_MSB)
            for(unsigned int iNode=0; iNode<nNodes; iNode++)
            {
                CPL_LSBPTR64(&poRawPoints[iNode].x);
                CPL_LSBPTR64(&poRawPoints[iNode].y);
            }
#endif

            OGRLineString* poGeom = new OGRLineString();
            poGeom->setPoints(nNodes, poRawPoints, NULL);

            VSIFree(poRawPoints);

            if (poSRS)
                poGeom->assignSpatialReference(poSRS);
            OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
            poFeature->SetField(0, dfId);
            poFeature->SetFID(nNextFID ++);
            poFeature->SetGeometryDirectly(poGeom);
            ReadAVLLine(poFeature);
            return poFeature;
        }
        else /* if (eGeomType == wkbPolygon) */
        {
            double dfId;
            double dfMinXShape, dfMaxXShape, dfMinYShape, dfMaxYShape;
            unsigned int nParts;
            unsigned int nTotalNodes;

            if (VSIFReadL(&dfId, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMinXShape, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMaxXShape, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMinYShape, sizeof(double), 1, fp) != 1 ||
                VSIFReadL(&dfMaxYShape, sizeof(double), 1, fp) != 1)
            {
                return NULL;
            }
            CPL_LSBPTR64(&dfId);
            CPL_LSBPTR64(&dfMinXShape);
            CPL_LSBPTR64(&dfMaxXShape);
            CPL_LSBPTR64(&dfMinYShape);
            CPL_LSBPTR64(&dfMaxYShape);
            if (VSIFReadL(&nParts, sizeof(unsigned int), 1, fp) != 1 ||
                VSIFReadL(&nTotalNodes, sizeof(unsigned int), 1, fp) != 1)
            {
                return NULL;
            }
            CPL_LSBPTR32(&nParts);
            CPL_LSBPTR32(&nTotalNodes);

            if (nParts > 100000 || nTotalNodes > 100 * 1000 * 1000)
                return NULL;

            if (m_poFilterGeom != NULL &&
                (dfMaxXShape < m_sFilterEnvelope.MinX ||
                 dfMinXShape > m_sFilterEnvelope.MaxX ||
                 dfMaxYShape < m_sFilterEnvelope.MinY ||
                 dfMinYShape > m_sFilterEnvelope.MaxY))
            {
                VSIFSeekL(fp, sizeof(unsigned int) * nParts + sizeof(OGRRawPoint) * nTotalNodes, SEEK_CUR);
                nNextFID ++;
                continue;
            }

            OGRRawPoint* poRawPoints = (OGRRawPoint*)VSIMalloc2(sizeof(OGRRawPoint), nTotalNodes);
            if (poRawPoints == NULL)
            {
                return NULL;
            }
            unsigned int* panNodesCount = NULL;
            if( nParts > 1 )
            {
                panNodesCount = (unsigned int *)CPLMalloc(sizeof(unsigned int) * nParts);
                if (VSIFReadL(panNodesCount, sizeof(unsigned int) * nParts, 1, fp) != 1)
                {
                    VSIFree(poRawPoints);
                    VSIFree(panNodesCount);
                    return NULL;
                }
#if defined(CPL_MSB)
                for(unsigned int iPart=0; iPart < nParts; iPart ++)
                {
                    CPL_LSBPTR32(&panNodesCount[iPart]);
                }
#endif
            }
            else
            {
                unsigned int nNodes;
                if (VSIFReadL(&nNodes, sizeof(unsigned int) * nParts, 1, fp) != 1)
                {
                    VSIFree(poRawPoints);
                    return NULL;
                }
                CPL_LSBPTR32(&nNodes);
                if( nNodes != nTotalNodes )
                {
                    VSIFree(poRawPoints);
                    return NULL;
                }
            }

            unsigned int iPart;
            OGRPolygon* poGeom = new OGRPolygon();
            for(iPart = 0; iPart < nParts; iPart ++)
            {
                unsigned int nNodes = (nParts > 1) ? panNodesCount[iPart] : nTotalNodes;
                if (nNodes > nTotalNodes ||
                    (unsigned int)VSIFReadL(poRawPoints, sizeof(OGRRawPoint), nNodes, fp) != nNodes)
                {
                    VSIFree(poRawPoints);
                    VSIFree(panNodesCount);
                    delete poGeom;
                    return NULL;
                }

#if defined(CPL_MSB)
                for(unsigned int iNode=0; iNode<nNodes; iNode++)
                {
                    CPL_LSBPTR64(&poRawPoints[iNode].x);
                    CPL_LSBPTR64(&poRawPoints[iNode].y);
                }
#endif

                OGRLinearRing* poLR = new OGRLinearRing();
                poGeom->addRingDirectly(poLR);
                poLR->setPoints(nNodes, poRawPoints, NULL);
            }

            VSIFree(poRawPoints);
            VSIFree(panNodesCount);

            if (poSRS)
                poGeom->assignSpatialReference(poSRS);
            OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
            poFeature->SetField(0, dfId);
            poFeature->SetFID(nNextFID ++);
            poFeature->SetGeometryDirectly(poGeom);
            ReadAVLLine(poFeature);
            return poFeature;
        }
    }
}
Example #4
0
OGRFeature * OGRSDTSLayer::GetNextUnfilteredFeature()

{
/* -------------------------------------------------------------------- */
/*      If not done before we need to assemble the geometry for a       */
/*      polygon layer.                                                  */
/* -------------------------------------------------------------------- */
    if( poTransfer->GetLayerType(iLayer) == SLTPoly )
    {
        ((SDTSPolygonReader *) poReader)->AssembleRings(poTransfer,iLayer);
    }

/* -------------------------------------------------------------------- */
/*      Fetch the next sdts style feature object from the reader.       */
/* -------------------------------------------------------------------- */
    SDTSFeature *poSDTSFeature = poReader->GetNextFeature();
    OGRFeature  *poFeature;

    if( poSDTSFeature == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Create the OGR feature.                                         */
/* -------------------------------------------------------------------- */
    poFeature = new OGRFeature( poFeatureDefn );

    m_nFeaturesRead++;

    switch( poTransfer->GetLayerType(iLayer) )
    {
/* -------------------------------------------------------------------- */
/*      Translate point feature specific information and geometry.      */
/* -------------------------------------------------------------------- */
      case SLTPoint:
      {
          SDTSRawPoint  *poPoint = (SDTSRawPoint *) poSDTSFeature;

          poFeature->SetGeometryDirectly( new OGRPoint( poPoint->dfX,
                                                        poPoint->dfY,
                                                        poPoint->dfZ ) );
      }
      break;

/* -------------------------------------------------------------------- */
/*      Translate line feature specific information and geometry.       */
/* -------------------------------------------------------------------- */
      case SLTLine:
      {
          SDTSRawLine   *poLine = (SDTSRawLine *) poSDTSFeature;
          OGRLineString *poOGRLine = new OGRLineString();

          poOGRLine->setPoints( poLine->nVertices,
                                poLine->padfX, poLine->padfY, poLine->padfZ );
          poFeature->SetGeometryDirectly( poOGRLine );
          poFeature->SetField( "SNID", (int) poLine->oStartNode.nRecord );
          poFeature->SetField( "ENID", (int) poLine->oEndNode.nRecord );
      }
      break;

/* -------------------------------------------------------------------- */
/*      Translate polygon feature specific information and geometry.    */
/* -------------------------------------------------------------------- */
      case SLTPoly:
      {
          SDTSRawPolygon *poPoly = (SDTSRawPolygon *) poSDTSFeature;
          OGRPolygon *poOGRPoly = new OGRPolygon();

          for( int iRing = 0; iRing < poPoly->nRings; iRing++ )
          {
              OGRLinearRing *poRing = new OGRLinearRing();
              int           nVertices;

              if( iRing == poPoly->nRings - 1 )
                  nVertices = poPoly->nVertices - poPoly->panRingStart[iRing];
              else
                  nVertices = poPoly->panRingStart[iRing+1]
                            - poPoly->panRingStart[iRing];

              poRing->setPoints( nVertices,
                                 poPoly->padfX + poPoly->panRingStart[iRing],
                                 poPoly->padfY + poPoly->panRingStart[iRing],
                                 poPoly->padfZ + poPoly->panRingStart[iRing] );

              poOGRPoly->addRingDirectly( poRing );
          }

          poFeature->SetGeometryDirectly( poOGRPoly );
      }
      break;

      default:
        break;
    }

/* -------------------------------------------------------------------- */
/*      Set attributes for any indicated attribute records.             */
/* -------------------------------------------------------------------- */
    int         iAttrRecord;

    for( iAttrRecord = 0;
         iAttrRecord < poSDTSFeature->nAttributes;
         iAttrRecord++)
    {
        DDFField        *poSR;

        poSR = poTransfer->GetAttr( poSDTSFeature->paoATID+iAttrRecord );
        if( poSR != NULL )
            AssignAttrRecordToFeature( poFeature, poTransfer, poSR );
    }

/* -------------------------------------------------------------------- */
/*      If this record is an attribute record, attach the local         */
/*      attributes.                                                     */
/* -------------------------------------------------------------------- */
    if( poTransfer->GetLayerType(iLayer) == SLTAttr )
    {
        AssignAttrRecordToFeature( poFeature, poTransfer,
                                   ((SDTSAttrRecord *) poSDTSFeature)->poATTR);
    }

/* -------------------------------------------------------------------- */
/*      Translate the record id.                                        */
/* -------------------------------------------------------------------- */
    poFeature->SetFID( poSDTSFeature->oModId.nRecord );
    poFeature->SetField( 0, (int) poSDTSFeature->oModId.nRecord );
    if( poFeature->GetGeometryRef() != NULL )
        poFeature->GetGeometryRef()->assignSpatialReference(
            poDS->GetSpatialRef() );

    if( !poReader->IsIndexed() )
        delete poSDTSFeature;

    return poFeature;
}
OGRErr OGRMultiPolygon::importFromWkt( char ** ppszInput )

{
    char        szToken[OGR_WKT_TOKEN_MAX];
    const char  *pszInput = *ppszInput;
    OGRErr      eErr = OGRERR_NONE;

    /* -------------------------------------------------------------------- */
    /*      Clear existing rings.                                           */
    /* -------------------------------------------------------------------- */
    empty();

    /* -------------------------------------------------------------------- */
    /*      Read and verify the MULTIPOLYGON keyword token.                 */
    /* -------------------------------------------------------------------- */
    pszInput = OGRWktReadToken( pszInput, szToken );

    if( !EQUAL(szToken,getGeometryName()) )
        return OGRERR_CORRUPT_DATA;

    /* -------------------------------------------------------------------- */
    /*      The next character should be a ( indicating the start of the    */
    /*      list of polygons.                                               */
    /* -------------------------------------------------------------------- */
    pszInput = OGRWktReadToken( pszInput, szToken );

    if( EQUAL(szToken,"EMPTY") )
    {
        *ppszInput = (char *) pszInput;
        return OGRERR_NONE;
    }

    if( szToken[0] != '(' )
        return OGRERR_CORRUPT_DATA;

    /* -------------------------------------------------------------------- */
    /*      If the next token is EMPTY, then verify that we have proper     */
    /*      EMPTY format will a trailing closing bracket.                   */
    /* -------------------------------------------------------------------- */
    OGRWktReadToken( pszInput, szToken );
    if( EQUAL(szToken,"EMPTY") )
    {
        pszInput = OGRWktReadToken( pszInput, szToken );
        pszInput = OGRWktReadToken( pszInput, szToken );

        *ppszInput = (char *) pszInput;

        if( !EQUAL(szToken,")") )
            return OGRERR_CORRUPT_DATA;
        else
            return OGRERR_NONE;
    }

    /* ==================================================================== */
    /*      Read each polygon in turn.  Note that we try to reuse the same  */
    /*      point list buffer from ring to ring to cut down on              */
    /*      allocate/deallocate overhead.                                   */
    /* ==================================================================== */
    OGRRawPoint *paoPoints = NULL;
    int         nMaxPoints = 0;
    double      *padfZ = NULL;

    do
    {
        OGRPolygon      *poPolygon = new OGRPolygon();

        /* -------------------------------------------------------------------- */
        /*      The next character should be a ( indicating the start of the    */
        /*      list of polygons.                                               */
        /* -------------------------------------------------------------------- */
        pszInput = OGRWktReadToken( pszInput, szToken );
        if( szToken[0] != '(' )
        {
            eErr = OGRERR_CORRUPT_DATA;
            delete poPolygon;
            break;
        }

        /* -------------------------------------------------------------------- */
        /*      Loop over each ring in this polygon.                            */
        /* -------------------------------------------------------------------- */
        do
        {
            int     nPoints = 0;

            /* -------------------------------------------------------------------- */
            /*      Read points for one line from input.                            */
            /* -------------------------------------------------------------------- */
            pszInput = OGRWktReadPoints( pszInput, &paoPoints, &padfZ, &nMaxPoints,
                                         &nPoints );

            if( pszInput == NULL )
            {
                eErr = OGRERR_CORRUPT_DATA;
                break;
            }

            /* -------------------------------------------------------------------- */
            /*      Create the new line, and add to collection.                     */
            /* -------------------------------------------------------------------- */
            OGRLinearRing       *poLine;

            poLine = new OGRLinearRing();
            poLine->setPoints( nPoints, paoPoints, padfZ );

            poPolygon->addRingDirectly( poLine );

            /* -------------------------------------------------------------------- */
            /*      Read the delimeter following the ring.                          */
            /* -------------------------------------------------------------------- */

            pszInput = OGRWktReadToken( pszInput, szToken );
        } while( szToken[0] == ',' && eErr == OGRERR_NONE );

        /* -------------------------------------------------------------------- */
        /*      Verify that we have a closing bracket.                          */
        /* -------------------------------------------------------------------- */
        if( eErr == OGRERR_NONE )
        {
            if( szToken[0] != ')' )
                eErr = OGRERR_CORRUPT_DATA;
            else
                pszInput = OGRWktReadToken( pszInput, szToken );
        }

        /* -------------------------------------------------------------------- */
        /*      Add the polygon to the MULTIPOLYGON.                            */
        /* -------------------------------------------------------------------- */
        if( eErr == OGRERR_NONE )
            eErr = addGeometryDirectly( poPolygon );
        else
            delete poPolygon;

    } while( szToken[0] == ',' && eErr == OGRERR_NONE );

    /* -------------------------------------------------------------------- */
    /*      freak if we don't get a closing bracket.                        */
    /* -------------------------------------------------------------------- */
    CPLFree( paoPoints );
    CPLFree( padfZ );

    if( eErr != OGRERR_NONE )
        return eErr;

    if( szToken[0] != ')' )
        return OGRERR_CORRUPT_DATA;

    *ppszInput = (char *) pszInput;
    return OGRERR_NONE;
}
OGRGeometry *OGRGRASSLayer::GetFeatureGeometry ( long nFeatureId, int *cat )
{
    CPLDebug ( "GRASS", "OGRGRASSLayer::GetFeatureGeometry nFeatureId = %d", nFeatureId );

    int cidx = paFeatureIndex[(int)nFeatureId];

    int type, id;
    Vect_cidx_get_cat_by_index ( poMap, iLayerIndex, cidx, cat, &type, &id );

    //CPLDebug ( "GRASS", "cat = %d type = %d id = %d", *cat, type, id );

    OGRGeometry *poOGR = NULL;
    int bIs3D = Vect_is_3d(poMap);

    switch ( type ) {
	case GV_POINT:
        {
	    Vect_read_line ( poMap, poPoints, poCats, id);
            if (bIs3D)
                poOGR = new OGRPoint( poPoints->x[0], poPoints->y[0], poPoints->z[0] );
            else
                poOGR = new OGRPoint( poPoints->x[0], poPoints->y[0] );
        }
        break;
	    
	case GV_LINE:
	case GV_BOUNDARY:
        {
	    Vect_read_line ( poMap, poPoints, poCats, id);
	    OGRLineString *poOGRLine = new OGRLineString();
            if (bIs3D)
                poOGRLine->setPoints( poPoints->n_points, 
                                      poPoints->x, poPoints->y, poPoints->z );
            else
                poOGRLine->setPoints( poPoints->n_points, 
                                      poPoints->x, poPoints->y );

            poOGR = poOGRLine;
        }
        break;

	case GV_AREA:
        {
	    Vect_get_area_points ( poMap, id, poPoints );
	    
	    OGRPolygon 		*poOGRPoly;
	    poOGRPoly = new OGRPolygon();

	    OGRLinearRing       *poRing;
	    poRing = new OGRLinearRing();
            if (bIs3D)
                poRing->setPoints( poPoints->n_points,
                                poPoints->x, poPoints->y, poPoints->z );
            else
                poRing->setPoints( poPoints->n_points,
                                poPoints->x, poPoints->y ); 

	    poOGRPoly->addRingDirectly( poRing );

	    // Islands
	    int nisles = Vect_get_area_num_isles ( poMap, id );
	    for ( int i = 0; i < nisles; i++ ) {
		int isle =  Vect_get_area_isle ( poMap, id, i );
		Vect_get_isle_points ( poMap, isle, poPoints );

		poRing = new OGRLinearRing();
                if (bIs3D)
                    poRing->setPoints( poPoints->n_points,
                                    poPoints->x, poPoints->y, poPoints->z );
                else
                    poRing->setPoints( poPoints->n_points,
                                    poPoints->x, poPoints->y );

		poOGRPoly->addRingDirectly( poRing );
	    }
	    
	    poOGR = poOGRPoly;
        }   
        break;

	default: // Should not happen
        {
	    CPLError( CE_Failure, CPLE_AppDefined, "Unknown GRASS feature type.");
	    return NULL;
        }
    }
	    
    return poOGR;
}
Example #7
0
OGRErr OGRPGeoLayer::createFromShapeBin( GByte *pabyShape, 
                                         OGRGeometry **ppoGeom,
                                         int nBytes )

{
    *ppoGeom = NULL;

    if( nBytes < 1 )
        return OGRERR_FAILURE;

    int nSHPType = pabyShape[0];


//    CPLDebug( "PGeo", 
//              "Shape type read from PGeo data is nSHPType = %d", 
//              nSHPType );

/* -------------------------------------------------------------------- */
/*      type 50 appears to just be an alias for normal line             */
/*      strings. (#1484)                                                */
/*      Type 51 appears to just be an alias for normal polygon. (#3100) */
/*      TODO: These types include additional attributes including       */
/*      non-linear segments and such. They should be handled.           */
/* -------------------------------------------------------------------- */
    switch( nSHPType )
    {
      case 50:
        nSHPType = SHPT_ARC;
        break;
      case 51:
        nSHPType = SHPT_POLYGON;
        break;
      case 52:
        nSHPType = SHPT_POINT;
        break;
      case 53:
        nSHPType = SHPT_MULTIPOINT;
        break;
      case 54:
        nSHPType = SHPT_MULTIPATCH;
    }

/* ==================================================================== */
/*  Extract vertices for a Polygon or Arc.				*/
/* ==================================================================== */
    if(    nSHPType == SHPT_ARC
        || nSHPType == SHPT_ARCZ
        || nSHPType == SHPT_ARCM
        || nSHPType == SHPT_ARCZM
        || nSHPType == SHPT_POLYGON 
        || nSHPType == SHPT_POLYGONZ
        || nSHPType == SHPT_POLYGONM
        || nSHPType == SHPT_POLYGONZM
        || nSHPType == SHPT_MULTIPATCH 
        || nSHPType == SHPT_MULTIPATCHM)
    {
        GInt32         nPoints, nParts;
        int            i, nOffset;
        GInt32         *panPartStart;

        if (nBytes < 44)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Corrupted Shape : nBytes=%d, nSHPType=%d", nBytes, nSHPType);
            return OGRERR_FAILURE;
        }

/* -------------------------------------------------------------------- */
/*      Extract part/point count, and build vertex and part arrays      */
/*      to proper size.                                                 */
/* -------------------------------------------------------------------- */
	memcpy( &nPoints, pabyShape + 40, 4 );
	memcpy( &nParts, pabyShape + 36, 4 );

	CPL_LSBPTR32( &nPoints );
	CPL_LSBPTR32( &nParts );

        if (nPoints < 0 || nParts < 0 ||
            nPoints > 50 * 1000 * 1000 || nParts > 10 * 1000 * 1000)
        {
            CPLError(CE_Failure, CPLE_AppDefined, "Corrupted Shape : nPoints=%d, nParts=%d.",
                     nPoints, nParts);
            return OGRERR_FAILURE;
        }

        int bHasZ = (  nSHPType == SHPT_POLYGONZ
                    || nSHPType == SHPT_POLYGONZM
                    || nSHPType == SHPT_ARCZ
                    || nSHPType == SHPT_ARCZM
                    || nSHPType == SHPT_MULTIPATCH 
                    || nSHPType == SHPT_MULTIPATCHM );

        int bIsMultiPatch = ( nSHPType == SHPT_MULTIPATCH || nSHPType == SHPT_MULTIPATCHM );

        /* With the previous checks on nPoints and nParts, */
        /* we should not overflow here and after */
        /* since 50 M * (16 + 8 + 8) = 1 600 MB */
        int nRequiredSize = 44 + 4 * nParts + 16 * nPoints;
        if ( bHasZ )
        {
            nRequiredSize += 16 + 8 * nPoints;
        }
        if( bIsMultiPatch )
        {
            nRequiredSize += 4 * nParts;
        }
        if (nRequiredSize > nBytes)
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Corrupted Shape : nPoints=%d, nParts=%d, nBytes=%d, nSHPType=%d",
                     nPoints, nParts, nBytes, nSHPType);
            return OGRERR_FAILURE;
        }

        panPartStart = (GInt32 *) VSICalloc(nParts,sizeof(GInt32));
        if (panPartStart == NULL)
        {
            CPLError(CE_Failure, CPLE_OutOfMemory,
                     "Not enough memory for shape (nPoints=%d, nParts=%d)", nPoints, nParts);
            return OGRERR_FAILURE;
        }

/* -------------------------------------------------------------------- */
/*      Copy out the part array from the record.                        */
/* -------------------------------------------------------------------- */
	memcpy( panPartStart, pabyShape + 44, 4 * nParts );
	for( i = 0; i < nParts; i++ )
	{
            CPL_LSBPTR32( panPartStart + i );

            /* We check that the offset is inside the vertex array */
            if (panPartStart[i] < 0 ||
                panPartStart[i] >= nPoints)
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Corrupted Shape : panPartStart[%d] = %d, nPoints = %d",
                         i, panPartStart[i], nPoints); 
                CPLFree(panPartStart);
                return OGRERR_FAILURE;
            }
            if (i > 0 && panPartStart[i] <= panPartStart[i-1])
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Corrupted Shape : panPartStart[%d] = %d, panPartStart[%d] = %d",
                         i, panPartStart[i], i - 1, panPartStart[i - 1]); 
                CPLFree(panPartStart);
                return OGRERR_FAILURE;
            }
	}

	nOffset = 44 + 4*nParts;

/* -------------------------------------------------------------------- */
/*      If this is a multipatch, we will also have parts types.  For    */
/*      now we ignore and skip past them.                               */
/* -------------------------------------------------------------------- */
        if( bIsMultiPatch )
            nOffset += 4*nParts;
        
/* -------------------------------------------------------------------- */
/*      Copy out the vertices from the record.                          */
/* -------------------------------------------------------------------- */
        double *padfX = (double *) VSIMalloc(sizeof(double)*nPoints);
        double *padfY = (double *) VSIMalloc(sizeof(double)*nPoints);
        double *padfZ = (double *) VSICalloc(sizeof(double),nPoints);
        if (padfX == NULL || padfY == NULL || padfZ == NULL)
        {
            CPLFree( panPartStart );
            CPLFree( padfX );
            CPLFree( padfY );
            CPLFree( padfZ );
            CPLError(CE_Failure, CPLE_OutOfMemory,
                     "Not enough memory for shape (nPoints=%d, nParts=%d)", nPoints, nParts);
            return OGRERR_FAILURE;
        }

	for( i = 0; i < nPoints; i++ )
	{
	    memcpy(padfX + i, pabyShape + nOffset + i * 16, 8 );
	    memcpy(padfY + i, pabyShape + nOffset + i * 16 + 8, 8 );
            CPL_LSBPTR64( padfX + i );
            CPL_LSBPTR64( padfY + i );
	}

        nOffset += 16*nPoints;
        
/* -------------------------------------------------------------------- */
/*      If we have a Z coordinate, collect that now.                    */
/* -------------------------------------------------------------------- */
        if( bHasZ )
        {
            for( i = 0; i < nPoints; i++ )
            {
                memcpy( padfZ + i, pabyShape + nOffset + 16 + i*8, 8 );
                CPL_LSBPTR64( padfZ + i );
            }

            nOffset += 16 + 8*nPoints;
        }

/* -------------------------------------------------------------------- */
/*      Build corresponding OGR objects.                                */
/* -------------------------------------------------------------------- */
        if(    nSHPType == SHPT_ARC 
            || nSHPType == SHPT_ARCZ
            || nSHPType == SHPT_ARCM
            || nSHPType == SHPT_ARCZM )
        {
/* -------------------------------------------------------------------- */
/*      Arc - As LineString                                             */
/* -------------------------------------------------------------------- */
            if( nParts == 1 )
            {
                OGRLineString *poLine = new OGRLineString();
                *ppoGeom = poLine;

                poLine->setPoints( nPoints, padfX, padfY, padfZ );
            }

/* -------------------------------------------------------------------- */
/*      Arc - As MultiLineString                                        */
/* -------------------------------------------------------------------- */
            else
            {
                OGRMultiLineString *poMulti = new OGRMultiLineString;
                *ppoGeom = poMulti;

                for( i = 0; i < nParts; i++ )
                {
                    OGRLineString *poLine = new OGRLineString;
                    int nVerticesInThisPart;

                    if( i == nParts-1 )
                        nVerticesInThisPart = nPoints - panPartStart[i];
                    else
                        nVerticesInThisPart = 
                            panPartStart[i+1] - panPartStart[i];

                    poLine->setPoints( nVerticesInThisPart, 
                                       padfX + panPartStart[i], 
                                       padfY + panPartStart[i], 
                                       padfZ + panPartStart[i] );

                    poMulti->addGeometryDirectly( poLine );
                }
            }
        } /* ARC */

/* -------------------------------------------------------------------- */
/*      Polygon                                                         */
/* -------------------------------------------------------------------- */
        else if(    nSHPType == SHPT_POLYGON
                 || nSHPType == SHPT_POLYGONZ
                 || nSHPType == SHPT_POLYGONM
                 || nSHPType == SHPT_POLYGONZM )
        {
            OGRPolygon *poMulti = new OGRPolygon;
            *ppoGeom = poMulti;

            for( i = 0; i < nParts; i++ )
            {
                OGRLinearRing *poRing = new OGRLinearRing;
                int nVerticesInThisPart;

                if( i == nParts-1 )
                    nVerticesInThisPart = nPoints - panPartStart[i];
                else
                    nVerticesInThisPart = 
                        panPartStart[i+1] - panPartStart[i];

                poRing->setPoints( nVerticesInThisPart, 
                                   padfX + panPartStart[i], 
                                   padfY + panPartStart[i], 
                                   padfZ + panPartStart[i] );

                poMulti->addRingDirectly( poRing );
            }
        } /* polygon */

/* -------------------------------------------------------------------- */
/*      Multipatch                                                      */
/* -------------------------------------------------------------------- */
        else if( bIsMultiPatch )
        {
            /* return to this later */
        } 

        CPLFree( panPartStart );
        CPLFree( padfX );
        CPLFree( padfY );
        CPLFree( padfZ );

        if( !bHasZ )
            (*ppoGeom)->setCoordinateDimension( 2 );

        return OGRERR_NONE;
    }

/* ==================================================================== */
/*  Extract vertices for a MultiPoint.					*/
/* ==================================================================== */
    else if(    nSHPType == SHPT_MULTIPOINT
             || nSHPType == SHPT_MULTIPOINTM
             || nSHPType == SHPT_MULTIPOINTZ
             || nSHPType == SHPT_MULTIPOINTZM )
    {
#ifdef notdef
	int32		nPoints;
	int    		i, nOffset;

	memcpy( &nPoints, psSHP->pabyRec + 44, 4 );
	if( bBigEndian ) SwapWord( 4, &nPoints );

	psShape->nVertices = nPoints;
        psShape->padfX = (double *) calloc(nPoints,sizeof(double));
        psShape->padfY = (double *) calloc(nPoints,sizeof(double));
        psShape->padfZ = (double *) calloc(nPoints,sizeof(double));
        psShape->padfM = (double *) calloc(nPoints,sizeof(double));

	for( i = 0; i < nPoints; i++ )
	{
	    memcpy(psShape->padfX+i, psSHP->pabyRec + 48 + 16 * i, 8 );
	    memcpy(psShape->padfY+i, psSHP->pabyRec + 48 + 16 * i + 8, 8 );

	    if( bBigEndian ) SwapWord( 8, psShape->padfX + i );
	    if( bBigEndian ) SwapWord( 8, psShape->padfY + i );
	}

        nOffset = 48 + 16*nPoints;
        
/* -------------------------------------------------------------------- */
/*	Get the X/Y bounds.						*/
/* -------------------------------------------------------------------- */
        memcpy( &(psShape->dfXMin), psSHP->pabyRec + 8 +  4, 8 );
        memcpy( &(psShape->dfYMin), psSHP->pabyRec + 8 + 12, 8 );
        memcpy( &(psShape->dfXMax), psSHP->pabyRec + 8 + 20, 8 );
        memcpy( &(psShape->dfYMax), psSHP->pabyRec + 8 + 28, 8 );

	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMin) );
	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMin) );
	if( bBigEndian ) SwapWord( 8, &(psShape->dfXMax) );
	if( bBigEndian ) SwapWord( 8, &(psShape->dfYMax) );

/* -------------------------------------------------------------------- */
/*      If we have a Z coordinate, collect that now.                    */
/* -------------------------------------------------------------------- */
        if( psShape->nSHPType == SHPT_MULTIPOINTZ || psShape->nSHPType == SHPT_MULTIPOINTZM )
        {
            memcpy( &(psShape->dfZMin), psSHP->pabyRec + nOffset, 8 );
            memcpy( &(psShape->dfZMax), psSHP->pabyRec + nOffset + 8, 8 );
            
            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMin) );
            if( bBigEndian ) SwapWord( 8, &(psShape->dfZMax) );
            
            for( i = 0; i < nPoints; i++ )
            {
                memcpy( psShape->padfZ + i,
                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
                if( bBigEndian ) SwapWord( 8, psShape->padfZ + i );
            }

            nOffset += 16 + 8*nPoints;
        }

/* -------------------------------------------------------------------- */
/*      If we have a M measure value, then read it now.  We assume      */
/*      that the measure can be present for any shape if the size is    */
/*      big enough, but really it will only occur for the Z shapes      */
/*      (options), and the M shapes.                                    */
/* -------------------------------------------------------------------- */
        if( psSHP->panRecSize[hEntity]+8 >= nOffset + 16 + 8*nPoints )
        {
            memcpy( &(psShape->dfMMin), psSHP->pabyRec + nOffset, 8 );
            memcpy( &(psShape->dfMMax), psSHP->pabyRec + nOffset + 8, 8 );
            
            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMin) );
            if( bBigEndian ) SwapWord( 8, &(psShape->dfMMax) );
            
            for( i = 0; i < nPoints; i++ )
            {
                memcpy( psShape->padfM + i,
                        psSHP->pabyRec + nOffset + 16 + i*8, 8 );
                if( bBigEndian ) SwapWord( 8, psShape->padfM + i );
            }
        }
#endif
    }

/* ==================================================================== */
/*      Extract vertices for a point.                                   */
/* ==================================================================== */
    else if(    nSHPType == SHPT_POINT
             || nSHPType == SHPT_POINTM
             || nSHPType == SHPT_POINTZ
             || nSHPType == SHPT_POINTZM )
    {
        int	nOffset;
        double  dfX, dfY, dfZ = 0;

        int bHasZ = (nSHPType == SHPT_POINTZ || nSHPType == SHPT_POINTZM);

        if (nBytes < 4 + 8 + 8 + ((nSHPType == SHPT_POINTZ) ? 8 : 0))
        {
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Corrupted Shape : nBytes=%d, nSHPType=%d", nBytes, nSHPType);
            return OGRERR_FAILURE;
        }
        
	memcpy( &dfX, pabyShape + 4, 8 );
	memcpy( &dfY, pabyShape + 4 + 8, 8 );

        CPL_LSBPTR64( &dfX );
        CPL_LSBPTR64( &dfY );
        nOffset = 20 + 8;
        
        if( bHasZ )
        {
            memcpy( &dfZ, pabyShape + 4 + 16, 8 );
            CPL_LSBPTR64( &dfZ );
        }

        *ppoGeom = new OGRPoint( dfX, dfY, dfZ );

        if( !bHasZ )
            (*ppoGeom)->setCoordinateDimension( 2 );

        return OGRERR_NONE;
    }

    char* pszHex = CPLBinaryToHex( nBytes, pabyShape );
    CPLDebug( "PGEO", "Unsupported geometry type:%d\nnBytes=%d, hex=%s",
              nSHPType, nBytes, pszHex );
    CPLFree(pszHex);

    return OGRERR_FAILURE;
}