OGRShapeLayer::OGRShapeLayer

OGRShapeLayer::OGRShapeLayer( OGRShapeDataSource* poDSIn,
                              const char * pszFullNameIn,
                              SHPHandle hSHPIn, DBFHandle hDBFIn,
                              OGRSpatialReference *poSRSIn, bool bSRSSetIn,
                              bool bUpdate,
                              OGRwkbGeometryType eReqType,
                              char ** papszCreateOptions ) :
    OGRAbstractProxiedLayer(poDSIn->GetPool()),
    poDS(poDSIn),
    iNextShapeId(0),
    nTotalShapeCount(0),
    pszFullName(CPLStrdup(pszFullNameIn)),
    hSHP(hSHPIn),
    hDBF(hDBFIn),
    bUpdateAccess(bUpdate),
    eRequestedGeomType(eReqType),
    panMatchingFIDs(nullptr),
    iMatchingFID(0),
    m_poFilterGeomLastValid(nullptr),
    nSpatialFIDCount(0),
    panSpatialFIDs(nullptr),
    bHeaderDirty(false),
    bSHPNeedsRepack(false),
    bCheckedForQIX(false),
    hQIX(nullptr),
    bCheckedForSBN(false),
    hSBN(nullptr),
    bSbnSbxDeleted(false),
    bTruncationWarningEmitted(false),
    bHSHPWasNonNULL(hSHPIn != nullptr),
    bHDBFWasNonNULL(hDBFIn != nullptr),
    eFileDescriptorsState(FD_OPENED),
    bResizeAtClose(false),
    bCreateSpatialIndexAtClose(false),
    bRewindOnWrite(false),
    m_bAutoRepack(false),
    m_eNeedRepack(MAYBE)
{
    if( hSHP != nullptr )
    {
        nTotalShapeCount = hSHP->nRecords;
        if( hDBF != nullptr && hDBF->nRecords != nTotalShapeCount )
        {
            CPLDebug(
                "Shape",
                "Inconsistent record number in .shp (%d) and in .dbf (%d)",
                hSHP->nRecords, hDBF->nRecords);
        }
    }
    else if( hDBF != nullptr )
    {
        nTotalShapeCount = hDBF->nRecords;
    }
#ifdef DEBUG
    else
    {
        CPLError(CE_Fatal, CPLE_AssertionFailed,
                 "Should not happen: Both hSHP and hDBF are nullptrs");
    }
#endif

    if( !TouchLayer() )
    {
        CPLDebug("Shape", "TouchLayer in shape ctor failed. ");
    }

    if( hDBF != nullptr && hDBF->pszCodePage != nullptr )
    {
        CPLDebug( "Shape", "DBF Codepage = %s for %s",
                  hDBF->pszCodePage, pszFullName );

        // Not too sure about this, but it seems like better than nothing.
        osEncoding = ConvertCodePage( hDBF->pszCodePage );
    }

    if( hDBF != nullptr )
    {
        if( !(hDBF->nUpdateYearSince1900 == 95 &&
              hDBF->nUpdateMonth == 7 &&
              hDBF->nUpdateDay == 26) )
        {
            SetMetadataItem(
                "DBF_DATE_LAST_UPDATE",
                CPLSPrintf("%04d-%02d-%02d",
                           hDBF->nUpdateYearSince1900 + 1900,
                           hDBF->nUpdateMonth, hDBF->nUpdateDay) );
        }
        struct tm tm;
        CPLUnixTimeToYMDHMS(time(nullptr), &tm);
        DBFSetLastModifiedDate( hDBF, tm.tm_year,
                                tm.tm_mon + 1, tm.tm_mday );
    }

    const char* pszShapeEncoding =
        CSLFetchNameValue(poDS->GetOpenOptions(), "ENCODING");
    if( pszShapeEncoding == nullptr && osEncoding == "")
        pszShapeEncoding = CSLFetchNameValue( papszCreateOptions, "ENCODING" );
    if( pszShapeEncoding == nullptr )
        pszShapeEncoding = CPLGetConfigOption( "SHAPE_ENCODING", nullptr );
    if( pszShapeEncoding != nullptr )
        osEncoding = pszShapeEncoding;

    if( osEncoding != "" )
    {
        CPLDebug( "Shape", "Treating as encoding '%s'.", osEncoding.c_str() );

        if( !OGRShapeLayer::TestCapability(OLCStringsAsUTF8) )
        {
            CPLDebug( "Shape", "Cannot recode from '%s'. Disabling recoding",
                      osEncoding.c_str() );
            osEncoding = "";
        }
    }

    poFeatureDefn = SHPReadOGRFeatureDefn(
        CPLGetBasename(pszFullName),
        hSHP, hDBF, osEncoding,
        CPLFetchBool(poDS->GetOpenOptions(), "ADJUST_TYPE", false) );

    // To make sure that
    //  GetLayerDefn()->GetGeomFieldDefn(0)->GetSpatialRef() == GetSpatialRef()
    OGRwkbGeometryType eGeomType = poFeatureDefn->GetGeomType();
    if( eGeomType != wkbNone )
    {
        OGRwkbGeometryType eType = wkbUnknown;

        if( eRequestedGeomType == wkbNone )
        {
            eType = eGeomType;

            const char* pszAdjustGeomType = CSLFetchNameValueDef(
                poDS->GetOpenOptions(), "ADJUST_GEOM_TYPE", "FIRST_SHAPE");
            const bool bFirstShape = EQUAL(pszAdjustGeomType, "FIRST_SHAPE");
            const bool bAllShapes  = EQUAL(pszAdjustGeomType, "ALL_SHAPES");
            if( (hSHP != nullptr) && (hSHP->nRecords > 0) && wkbHasM(eType) &&
                (bFirstShape || bAllShapes) )
            {
                bool bMIsUsed = false;
                for( int iShape=0; iShape < hSHP->nRecords; iShape++ )
                {
                    SHPObject *psShape = SHPReadObject( hSHP, iShape );
                    if( psShape )
                    {
                        if( psShape->bMeasureIsUsed &&
                            psShape->nVertices > 0 &&
                            psShape->padfM != nullptr )
                        {
                            for( int i = 0; i < psShape->nVertices; i++ )
                            {
                                // Per the spec, if the M value is smaller than
                                // -1e38, it is a nodata value.
                                if( psShape->padfM[i] > -1e38 )
                                {
                                    bMIsUsed = true;
                                    break;
                                }
                            }
                        }

                        SHPDestroyObject(psShape);
                    }
                    if( bFirstShape || bMIsUsed )
                        break;
                }
                if( !bMIsUsed )
                    eType = OGR_GT_SetModifier(eType, wkbHasZ(eType), FALSE);
            }
        }
        else
        {
            eType = eRequestedGeomType;
        }

        OGRShapeGeomFieldDefn* poGeomFieldDefn =
            new OGRShapeGeomFieldDefn(pszFullName, eType, bSRSSetIn, poSRSIn);
        poFeatureDefn->SetGeomType(wkbNone);
        poFeatureDefn->AddGeomFieldDefn(poGeomFieldDefn, FALSE);
    }
    else if( bSRSSetIn && poSRSIn != nullptr )
    {
        poSRSIn->Release();
    }
    SetDescription( poFeatureDefn->GetName() );
    bRewindOnWrite =
        CPLTestBool(CPLGetConfigOption( "SHAPE_REWIND_ON_WRITE", "YES" ));
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值