ogrpolygon.cpp

来自「在linux环境下」· C++ 代码 · 共 837 行 · 第 1/2 页

CPP
837
字号
    if( eByteOrder == wkbNDR )        b3D = pabyData[4] & 0x80 || pabyData[2] & 0x80;    else        b3D = pabyData[1] & 0x80 || pabyData[3] & 0x80;/* -------------------------------------------------------------------- *//*      Do we already have some rings?                                  *//* -------------------------------------------------------------------- */    if( nRingCount != 0 )    {        for( int iRing = 0; iRing < nRingCount; iRing++ )            delete papoRings[iRing];        OGRFree( papoRings );        papoRings = NULL;    }    /* -------------------------------------------------------------------- *//*      Get the ring count.                                             *//* -------------------------------------------------------------------- */    memcpy( &nRingCount, pabyData + 5, 4 );        if( OGR_SWAP( eByteOrder ) )        nRingCount = CPL_SWAP32(nRingCount);    papoRings = (OGRLinearRing **) OGRMalloc(sizeof(void*) * nRingCount);    nDataOffset = 9;    if( nSize != -1 )        nSize -= nDataOffset;/* -------------------------------------------------------------------- *//*      Get the rings.                                                  *//* -------------------------------------------------------------------- */    for( int iRing = 0; iRing < nRingCount; iRing++ )    {        OGRErr  eErr;                papoRings[iRing] = new OGRLinearRing();        eErr = papoRings[iRing]->_importFromWkb( eByteOrder, b3D,                                                 pabyData + nDataOffset,                                                 nSize );        if( eErr != OGRERR_NONE )        {            nRingCount = iRing;            return eErr;        }        if( nSize != -1 )            nSize -= papoRings[iRing]->_WkbSize( b3D );        nDataOffset += papoRings[iRing]->_WkbSize( b3D );    }        return OGRERR_NONE;}/************************************************************************//*                            exportToWkb()                             *//*                                                                      *//*      Build a well known binary representation of this object.        *//************************************************************************/OGRErr  OGRPolygon::exportToWkb( OGRwkbByteOrder eByteOrder,                                 unsigned char * pabyData ){    int         nOffset;    int         b3D = getCoordinateDimension() == 3;    /* -------------------------------------------------------------------- *//*      Set the byte order.                                             *//* -------------------------------------------------------------------- */    pabyData[0] = (unsigned char) eByteOrder;/* -------------------------------------------------------------------- *//*      Set the geometry feature type.                                  *//* -------------------------------------------------------------------- */    GUInt32 nGType = getGeometryType();        if( eByteOrder == wkbNDR )        nGType = CPL_LSBWORD32( nGType );    else        nGType = CPL_MSBWORD32( nGType );    memcpy( pabyData + 1, &nGType, 4 );    /* -------------------------------------------------------------------- *//*      Copy in the raw data.                                           *//* -------------------------------------------------------------------- */    if( OGR_SWAP( eByteOrder ) )    {        int     nCount;        nCount = CPL_SWAP32( nRingCount );        memcpy( pabyData+5, &nCount, 4 );    }    else    {        memcpy( pabyData+5, &nRingCount, 4 );    }        nOffset = 9;    /* ==================================================================== *//*      Serialize each of the rings.                                    *//* ==================================================================== */    for( int iRing = 0; iRing < nRingCount; iRing++ )    {        papoRings[iRing]->_exportToWkb( eByteOrder, b3D,                                        pabyData + nOffset );        nOffset += papoRings[iRing]->_WkbSize(b3D);    }        return OGRERR_NONE;}/************************************************************************//*                           importFromWkt()                            *//*                                                                      *//*      Instantiate from well known text format.  Currently this is     *//*      `POLYGON ((x y, x y, ...),(x y, ...),...)'.                     *//************************************************************************/OGRErr OGRPolygon::importFromWkt( char ** ppszInput ){    char        szToken[OGR_WKT_TOKEN_MAX];    const char  *pszInput = *ppszInput;    int         iRing;/* -------------------------------------------------------------------- *//*      Clear existing rings.                                           *//* -------------------------------------------------------------------- */    if( nRingCount > 0 )    {        for( iRing = 0; iRing < nRingCount; iRing++ )            delete papoRings[iRing];                nRingCount = 0;        CPLFree( papoRings );    }/* -------------------------------------------------------------------- *//*      Read and verify the ``POLYGON'' keyword token.                  *//* -------------------------------------------------------------------- */    pszInput = OGRWktReadToken( pszInput, szToken );    if( !EQUAL(szToken,"POLYGON") )        return OGRERR_CORRUPT_DATA;/* -------------------------------------------------------------------- *//*      The next character should be a ( indicating the start of the    *//*      list of rings.                                                  *//* -------------------------------------------------------------------- */    pszInput = OGRWktReadToken( pszInput, szToken );    if( szToken[0] != '(' )        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.                                   *//* ==================================================================== */    OGRRawPoint *paoPoints = NULL;    int         nMaxPoints = 0, nMaxRings = 0;    double      *padfZ = NULL;        do    {        int     nPoints = 0;/* -------------------------------------------------------------------- *//*      Read points for one ring from input.                            *//* -------------------------------------------------------------------- */        pszInput = OGRWktReadPoints( pszInput, &paoPoints, &padfZ, &nMaxPoints,                                     &nPoints );        if( pszInput == NULL )        {            CPLFree( paoPoints );            return OGRERR_CORRUPT_DATA;        }        /* -------------------------------------------------------------------- *//*      Do we need to grow the ring array?                              *//* -------------------------------------------------------------------- */        if( nRingCount == nMaxRings )        {            nMaxRings = nMaxRings * 2 + 1;            papoRings = (OGRLinearRing **)                CPLRealloc(papoRings, nMaxRings * sizeof(OGRLinearRing*));        }/* -------------------------------------------------------------------- *//*      Create the new ring, and assign to ring list.                   *//* -------------------------------------------------------------------- */        papoRings[nRingCount] = new OGRLinearRing();        papoRings[nRingCount]->setPoints( nPoints, paoPoints, padfZ );        nRingCount++;/* -------------------------------------------------------------------- *//*      Read the delimeter following the ring.                          *//* -------------------------------------------------------------------- */                pszInput = OGRWktReadToken( pszInput, szToken );    } while( szToken[0] == ',' );/* -------------------------------------------------------------------- *//*      freak if we don't get a closing bracket.                        *//* -------------------------------------------------------------------- */    CPLFree( paoPoints );    CPLFree( padfZ );       if( szToken[0] != ')' )        return OGRERR_CORRUPT_DATA;        *ppszInput = (char *) pszInput;    return OGRERR_NONE;}/************************************************************************//*                            exportToWkt()                             *//*                                                                      *//*      Translate this structure into it's well known text format       *//*      equivelent.  This could be made alot more CPU efficient!        *//************************************************************************/OGRErr OGRPolygon::exportToWkt( char ** ppszDstText ){    char        **papszRings;    int         iRing, nCumulativeLength = 0;    OGRErr      eErr;/* -------------------------------------------------------------------- *//*      Build a list of strings containing the stuff for each ring.     *//* -------------------------------------------------------------------- */    papszRings = (char **) CPLCalloc(sizeof(char *),nRingCount);    for( iRing = 0; iRing < nRingCount; iRing++ )    {        eErr = papoRings[iRing]->exportToWkt( &(papszRings[iRing]) );        if( eErr != OGRERR_NONE )            return eErr;        CPLAssert( EQUALN(papszRings[iRing],"LINEARRING (", 12) );        nCumulativeLength += strlen(papszRings[iRing] + 11);    }    /* -------------------------------------------------------------------- *//*      Allocate exactly the right amount of space for the              *//*      aggregated string.                                              *//* -------------------------------------------------------------------- */    *ppszDstText = (char *) VSIMalloc(nCumulativeLength + nRingCount + 11);    if( *ppszDstText == NULL )        return OGRERR_NOT_ENOUGH_MEMORY;/* -------------------------------------------------------------------- *//*      Build up the string, freeing temporary strings as we go.        *//* -------------------------------------------------------------------- */    strcpy( *ppszDstText, "POLYGON (" );    for( iRing = 0; iRing < nRingCount; iRing++ )    {                                                                   if( iRing > 0 )            strcat( *ppszDstText, "," );                strcat( *ppszDstText, papszRings[iRing] + 11 );        VSIFree( papszRings[iRing] );    }    strcat( *ppszDstText, ")" );    CPLFree( papszRings );    return OGRERR_NONE;}/************************************************************************//*                              get_Area()                              *//************************************************************************/double OGRPolygon::get_Area(){    // notdef ... correct later.        return 0.0;}/************************************************************************//*                              Centroid()                              *//************************************************************************/int OGRPolygon::Centroid( OGRPoint * ){    // notdef ... not implemented yet.        return OGRERR_FAILURE;}/************************************************************************//*                           PointOnSurface()                           *//************************************************************************/int OGRPolygon::PointOnSurface( OGRPoint * ){    // notdef ... not implemented yet.        return OGRERR_FAILURE;}/************************************************************************//*                            getEnvelope()                             *//************************************************************************/void OGRPolygon::getEnvelope( OGREnvelope * psEnvelope ){    OGREnvelope         oRingEnv;        if( nRingCount == 0 )        return;    papoRings[0]->getEnvelope( psEnvelope );    for( int iRing = 1; iRing < nRingCount; iRing++ )    {        papoRings[iRing]->getEnvelope( &oRingEnv );        if( psEnvelope->MinX > oRingEnv.MinX )            psEnvelope->MinX = oRingEnv.MinX;        if( psEnvelope->MinY > oRingEnv.MinY )            psEnvelope->MinY = oRingEnv.MinY;        if( psEnvelope->MaxX < oRingEnv.MaxX )            psEnvelope->MaxX = oRingEnv.MaxX;        if( psEnvelope->MaxY < oRingEnv.MaxY )            psEnvelope->MaxY = oRingEnv.MaxY;    }}/************************************************************************//*                               Equal()                                *//************************************************************************/OGRBoolean OGRPolygon::Equal( OGRGeometry * poOther ){    OGRPolygon *poOPoly = (OGRPolygon *) poOther;    if( poOther == this )        return TRUE;        if( poOther->getGeometryType() != getGeometryType() )        return FALSE;    if( getNumInteriorRings() != poOPoly->getNumInteriorRings() )        return FALSE;    if( !getExteriorRing()->Equal( poOPoly->getExteriorRing() ) )        return FALSE;        // we should eventually test the SRS.    for( int iRing = 0; iRing < getNumInteriorRings(); iRing++ )    {        if( !getInteriorRing(iRing)->Equal(poOPoly->getInteriorRing(iRing)) )            return FALSE;    }    return TRUE;}/************************************************************************//*                             transform()                              *//************************************************************************/OGRErr OGRPolygon::transform( OGRCoordinateTransformation *poCT ){#ifdef DISABLE_OGRGEOM_TRANSFORM    return OGRERR_FAILURE;#else    for( int iRing = 0; iRing < nRingCount; iRing++ )    {        OGRErr  eErr;        eErr = papoRings[iRing]->transform( poCT );        if( eErr != OGRERR_NONE )        {            if( iRing != 0 )            {                CPLDebug("OGR",                          "OGRPolygon::transform() failed for a ring other\n"                         "than the first, meaning some rings are transformed\n"                         "and some are not!\n" );                return OGRERR_FAILURE;            }            return eErr;        }    }    assignSpatialReference( poCT->GetTargetCS() );    return OGRERR_NONE;#endif}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?