コード例 #1
0
ファイル: ogrlibkmllayer.cpp プロジェクト: ryandavid/rotobox
OGRLIBKMLLayer::OGRLIBKMLLayer( const char *pszLayerName,
                                OGRSpatialReference * poSpatialRef,
                                OGRwkbGeometryType eGType,
                                OGRLIBKMLDataSource * poOgrDS,
                                ElementPtr poKmlRoot,
                                ContainerPtr poKmlContainer,
                                UpdatePtr poKmlUpdate,
                                const char *pszFileName,
                                int bNew,
                                int bUpdateIn ) :
    bUpdate(CPL_TO_BOOL(bUpdateIn)),
    bUpdated(false),
    nFeatures(0),
    iFeature(0),
    nFID(1),
    m_pszName(CPLStrdup(pszLayerName)),
    m_pszFileName(CPLStrdup(pszFileName)),
    m_poKmlLayer(poKmlContainer),  // Store the layers container.
    m_poKmlLayerRoot(poKmlRoot),  // Store the root element pointer.
    m_poKmlUpdate(poKmlUpdate),
    m_poOgrDS(poOgrDS),
    m_poOgrFeatureDefn(new OGRFeatureDefn(pszLayerName)),
    m_poKmlSchema(NULL),
    m_poOgrSRS(new OGRSpatialReference(NULL)),
    m_bReadGroundOverlay(CPLTestBool(
        CPLGetConfigOption("LIBKML_READ_GROUND_OVERLAY", "YES"))),
    m_bUseSimpleField(CPLTestBool(
        CPLGetConfigOption("LIBKML_USE_SIMPLEFIELD", "YES"))),
    m_bWriteRegion(false),
    m_bRegionBoundsAuto(false),
    m_dfRegionMinLodPixels(0),
    m_dfRegionMaxLodPixels(-1),
    m_dfRegionMinFadeExtent(0),
    m_dfRegionMaxFadeExtent(0),
    m_dfRegionMinX(200),
    m_dfRegionMinY(200),
    m_dfRegionMaxX(-200),
    m_dfRegionMaxY(-200),
    m_bUpdateIsFolder(false)
{
    m_poStyleTable = NULL;
    m_poOgrSRS->SetWellKnownGeogCS( "WGS84" );

    SetDescription( m_poOgrFeatureDefn->GetName() );
    m_poOgrFeatureDefn->Reference();
    m_poOgrFeatureDefn->SetGeomType( eGType );
    if( m_poOgrFeatureDefn->GetGeomFieldCount() != 0 )
        m_poOgrFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(m_poOgrSRS);

    /***** was the layer created from a DS::Open *****/
    if( !bNew )
    {
        /***** get the number of features on the layer *****/
        nFeatures = static_cast<int>(m_poKmlLayer->get_feature_array_size());

        /***** get the field config *****/
        struct fieldconfig oFC;
        get_fieldconfig( &oFC );

        /***** name field *****/
        OGRFieldDefn oOgrFieldName( oFC.namefield,OFTString );
        m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldName );

        /***** description field *****/
        OGRFieldDefn oOgrFieldDesc( oFC.descfield, OFTString );
        m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldDesc );

        /***** timestamp field *****/
        OGRFieldDefn oOgrFieldTs( oFC.tsfield, OFTDateTime );
        m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldTs );

        /*****  timespan begin field *****/
        OGRFieldDefn oOgrFieldBegin( oFC.beginfield, OFTDateTime );
        m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldBegin );

        /*****  timespan end field *****/
        OGRFieldDefn oOgrFieldEnd( oFC.endfield, OFTDateTime );
        m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldEnd );

        /*****  altitudeMode field *****/
        OGRFieldDefn oOgrFieldAltitudeMode( oFC.altitudeModefield, OFTString );
        m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldAltitudeMode );

        /***** tessellate field *****/
        OGRFieldDefn oOgrFieldTessellate( oFC.tessellatefield, OFTInteger );
        m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldTessellate );

        /***** extrude field *****/
        OGRFieldDefn oOgrFieldExtrude( oFC.extrudefield, OFTInteger );
        m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldExtrude );

        /***** visibility field *****/
        OGRFieldDefn oOgrFieldVisibility( oFC.visibilityfield, OFTInteger );
        m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldVisibility );

        /***** draw order field *****/
        OGRFieldDefn oOgrFieldDrawOrder( oFC.drawOrderfield, OFTInteger );
        m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldDrawOrder );

        /***** icon field *****/
        OGRFieldDefn oOgrFieldIcon( oFC.iconfield, OFTString );
        m_poOgrFeatureDefn->AddFieldDefn( &oOgrFieldIcon );

        /***** get the styles *****/
        if( m_poKmlLayer->IsA( kmldom::Type_Document ) )
            ParseStyles( AsDocument ( m_poKmlLayer ), &m_poStyleTable );

        /***** get the schema if the layer is a Document *****/
        if( m_poKmlLayer->IsA( kmldom::Type_Document ) )
        {
            DocumentPtr poKmlDocument = AsDocument( m_poKmlLayer );

            if( poKmlDocument->get_schema_array_size() )
            {
                m_poKmlSchema = poKmlDocument->get_schema_array_at( 0 );
                kml2FeatureDef( m_poKmlSchema, m_poOgrFeatureDefn );
            }
        }

        /***** the schema is somewhere else *****/
        if( m_poKmlSchema == NULL )
        {
            /***** try to find the correct schema *****/
            bool bHasHeading = false;
            bool bHasTilt = false;
            bool bHasRoll = false;
            bool bHasSnippet = false;
            FeaturePtr poKmlFeature = NULL;

            /***** find the first placemark *****/
            do {
                if( iFeature >= nFeatures )
                    break;

                poKmlFeature =
                    m_poKmlLayer->get_feature_array_at( iFeature++ );

                if( poKmlFeature->Type() == kmldom::Type_Placemark )
                {
                    PlacemarkPtr poKmlPlacemark = AsPlacemark( poKmlFeature );
                    if( !poKmlPlacemark->has_geometry() &&
                        poKmlPlacemark->has_abstractview() &&
                        poKmlPlacemark->get_abstractview()->
                            IsA( kmldom::Type_Camera) )
                    {
                        const CameraPtr& camera =
                            AsCamera(poKmlPlacemark->get_abstractview());
                        if( camera->has_heading() && !bHasHeading )
                        {
                            bHasHeading = true;
                            OGRFieldDefn oOgrField( oFC.headingfield, OFTReal );
                            m_poOgrFeatureDefn->AddFieldDefn( &oOgrField );
                        }
                        if( camera->has_tilt() && !bHasTilt )
                        {
                            bHasTilt = true;
                            OGRFieldDefn oOgrField( oFC.tiltfield, OFTReal );
                            m_poOgrFeatureDefn->AddFieldDefn( &oOgrField );
                        }
                        if( camera->has_roll() && !bHasRoll )
                        {
                            bHasRoll = true;
                            OGRFieldDefn oOgrField( oFC.rollfield, OFTReal );
                            m_poOgrFeatureDefn->AddFieldDefn( &oOgrField );
                        }
                    }
                }
                if( !bHasSnippet && poKmlFeature->has_snippet() )
                {
                    bHasSnippet = true;
                    OGRFieldDefn oOgrField( oFC.snippetfield, OFTString );
                    m_poOgrFeatureDefn->AddFieldDefn( &oOgrField );
                }
            } while( poKmlFeature->Type() != kmldom::Type_Placemark );

            if( iFeature <= nFeatures && poKmlFeature &&
                poKmlFeature->Type() == kmldom::Type_Placemark &&
                poKmlFeature->has_extendeddata() )
            {

                const ExtendedDataPtr poKmlExtendedData =
                    poKmlFeature->get_extendeddata();

                if( poKmlExtendedData->get_schemadata_array_size() > 0 )
                {
                    const SchemaDataPtr poKmlSchemaData =
                        poKmlExtendedData->get_schemadata_array_at( 0 );

                    if( poKmlSchemaData->has_schemaurl() )
                    {
                        std::string oKmlSchemaUrl =
                            poKmlSchemaData->get_schemaurl();
                        if( ( m_poKmlSchema = m_poOgrDS->FindSchema(
                                  oKmlSchemaUrl.c_str() ) ) )
                        {
                            kml2FeatureDef( m_poKmlSchema, m_poOgrFeatureDefn );
                        }
                    }
                }
                else if( poKmlExtendedData->get_data_array_size() > 0 )
                {
                    // Use the <Data> of the first placemark to build the
                    // feature definition.  If others have different fields,
                    // too bad...
                    const bool bLaunderFieldNames =
                        CPLTestBool(CPLGetConfigOption(
                            "LIBKML_LAUNDER_FIELD_NAMES", "YES"));
                    const size_t nDataArraySize =
                        poKmlExtendedData->get_data_array_size();
                    for( size_t i = 0; i < nDataArraySize; i++ )
                    {
                        const DataPtr& data =
                            poKmlExtendedData->get_data_array_at(i);
                        if( data->has_name() )
                        {
                            CPLString osName = std::string(data->get_name());
                            if( bLaunderFieldNames )
                                osName = LaunderFieldNames(osName);
                            OGRFieldDefn oOgrField( osName, OFTString );
                            m_poOgrFeatureDefn->AddFieldDefn( &oOgrField );
                        }
                    }
                }
            }
            iFeature = 0;
        }

        /***** check if any features are another layer *****/
        m_poOgrDS->ParseLayers( m_poKmlLayer, poSpatialRef );
    }
    /***** it was from a DS::CreateLayer *****/
    else
    {
        /***** mark the layer as updated *****/
        bUpdated = true;
    }
}