コード例 #1
0
void kml2field (
    OGRFeature * poOgrFeat,
    PlacemarkPtr poKmlPlacemark )
{

    const char *namefield = CPLGetConfigOption ( "LIBKML_NAME_FIELD", "Name" );
    const char *descfield =
        CPLGetConfigOption ( "LIBKML_DESCRIPTION_FIELD", "description" );
    const char *tsfield =
        CPLGetConfigOption ( "LIBKML_TIMESTAMP_FIELD", "timestamp" );
    const char *beginfield =
        CPLGetConfigOption ( "LIBKML_BEGIN_FIELD", "begin" );
    const char *endfield = CPLGetConfigOption ( "LIBKML_END_FIELD", "end" );
    const char *altitudeModefield =
        CPLGetConfigOption ( "LIBKML_ALTITUDEMODE_FIELD", "altitudeMode" );
    const char *tessellatefield =
        CPLGetConfigOption ( "LIBKML_TESSELLATE_FIELD", "tessellate" );
    const char *extrudefield =
        CPLGetConfigOption ( "LIBKML_EXTRUDE_FIELD", "extrude" );
    const char *visibilityfield =
        CPLGetConfigOption ( "LIBKML_VISIBILITY_FIELD", "visibility" );

    /***** name *****/

    if ( poKmlPlacemark->has_name (  ) ) {
        const std::string oKmlName = poKmlPlacemark->get_name (  );
        int iField = poOgrFeat->GetFieldIndex ( namefield );

        if ( iField > -1 )
            poOgrFeat->SetField ( iField, oKmlName.c_str (  ) );
    }

    /***** description *****/

    if ( poKmlPlacemark->has_description (  ) ) {
        const std::string oKmlDesc = poKmlPlacemark->get_description (  );
        int iField = poOgrFeat->GetFieldIndex ( descfield );

        if ( iField > -1 )
            poOgrFeat->SetField ( iField, oKmlDesc.c_str (  ) );
    }

    if ( poKmlPlacemark->has_timeprimitive (  ) ) {
        TimePrimitivePtr poKmlTimePrimitive =
            poKmlPlacemark->get_timeprimitive (  );

        /***** timestamp *****/

        if ( poKmlTimePrimitive->IsA ( kmldom::Type_TimeStamp ) ) {
            TimeStampPtr poKmlTimeStamp = AsTimeStamp ( poKmlTimePrimitive );

            if ( poKmlTimeStamp->has_when (  ) ) {
                const std::string oKmlWhen = poKmlTimeStamp->get_when (  );


                int iField = poOgrFeat->GetFieldIndex ( tsfield );

                if ( iField > -1 ) {
                    int nYear,
                        nMonth,
                        nDay,
                        nHour,
                        nMinute,
                        nTZ;
                    float fSecond;

                    if ( OGRParseXMLDateTime
                         ( oKmlWhen.c_str (  ), &nYear, &nMonth, &nDay, &nHour,
                           &nMinute, &fSecond, &nTZ ) )
                        poOgrFeat->SetField ( iField, nYear, nMonth, nDay,
                                              nHour, nMinute, ( int )fSecond,
                                              nTZ );
                }
            }
        }

        /***** timespan *****/

        if ( poKmlTimePrimitive->IsA ( kmldom::Type_TimeSpan ) ) {
            TimeSpanPtr poKmlTimeSpan = AsTimeSpan ( poKmlTimePrimitive );

            /***** begin *****/

            if ( poKmlTimeSpan->has_begin (  ) ) {
                const std::string oKmlWhen = poKmlTimeSpan->get_begin (  );


                int iField = poOgrFeat->GetFieldIndex ( beginfield );

                if ( iField > -1 ) {
                    int nYear,
                        nMonth,
                        nDay,
                        nHour,
                        nMinute,
                        nTZ;
                    float fSecond;

                    if ( OGRParseXMLDateTime
                         ( oKmlWhen.c_str (  ), &nYear, &nMonth, &nDay, &nHour,
                           &nMinute, &fSecond, &nTZ ) )
                        poOgrFeat->SetField ( iField, nYear, nMonth, nDay,
                                              nHour, nMinute, ( int )fSecond,
                                              nTZ );
                }
            }

            /***** end *****/

            if ( poKmlTimeSpan->has_end (  ) ) {
                const std::string oKmlWhen = poKmlTimeSpan->get_end (  );


                int iField = poOgrFeat->GetFieldIndex ( endfield );

                if ( iField > -1 ) {
                    int nYear,
                        nMonth,
                        nDay,
                        nHour,
                        nMinute,
                        nTZ;
                    float fSecond;

                    if ( OGRParseXMLDateTime
                         ( oKmlWhen.c_str (  ), &nYear, &nMonth, &nDay, &nHour,
                           &nMinute, &fSecond, &nTZ ) )
                        poOgrFeat->SetField ( iField, nYear, nMonth, nDay,
                                              nHour, nMinute, ( int )fSecond,
                                              nTZ );
                }
            }
        }
    }


    if ( poKmlPlacemark->has_geometry (  ) ) {
        GeometryPtr poKmlGeometry = poKmlPlacemark->get_geometry (  );

        /***** altitudeMode *****/


        int bIsGX = FALSE;
        int nAltitudeMode = -1;

        int iField = poOgrFeat->GetFieldIndex ( altitudeModefield );

        if ( iField > -1 ) {

            if ( kml2altitudemode_rec ( poKmlGeometry,
                                        &nAltitudeMode, &bIsGX ) ) {

                if ( !bIsGX ) {

                    switch ( nAltitudeMode ) {
                    case kmldom::ALTITUDEMODE_CLAMPTOGROUND:
                        poOgrFeat->SetField ( iField, "clampToGround" );
                        break;

                    case kmldom::ALTITUDEMODE_RELATIVETOGROUND:
                        poOgrFeat->SetField ( iField, "relativeToGround" );
                        break;

                    case kmldom::ALTITUDEMODE_ABSOLUTE:
                        poOgrFeat->SetField ( iField, "absolute" );
                        break;

                    }
                }

                else {
                    switch ( nAltitudeMode ) {
                    case kmldom::GX_ALTITUDEMODE_RELATIVETOSEAFLOOR:
                        poOgrFeat->SetField ( iField, "relativeToSeaFloor" );
                        break;

                    case kmldom::GX_ALTITUDEMODE_CLAMPTOSEAFLOOR:
                        poOgrFeat->SetField ( iField, "clampToSeaFloor" );
                        break;
                    }

                }
            }

        }

        /***** tessellate *****/

        int nTessellate = -1;

        kml2tessellate_rec ( poKmlGeometry, &nTessellate );

        iField = poOgrFeat->GetFieldIndex ( tessellatefield );
        if ( iField > -1 )
            poOgrFeat->SetField ( iField, nTessellate );

        /***** extrude *****/

        int nExtrude = -1;

        kml2extrude_rec ( poKmlGeometry, &nExtrude );

        iField = poOgrFeat->GetFieldIndex ( extrudefield );
        if ( iField > -1 )
            poOgrFeat->SetField ( iField, nExtrude );

    }

    /***** visibility *****/

    int nVisibility = -1;

    if ( poKmlPlacemark->has_visibility (  ) )
        nVisibility = poKmlPlacemark->get_visibility (  );

    int iField = poOgrFeat->GetFieldIndex ( visibilityfield );

    if ( iField > -1 )
        poOgrFeat->SetField ( iField, nVisibility );

    ExtendedDataPtr poKmlExtendedData = NULL;

    if ( poKmlPlacemark->has_extendeddata (  ) ) {
        poKmlExtendedData = poKmlPlacemark->get_extendeddata (  );

        /***** loop over the schemadata_arrays *****/

        size_t nSchemaData = poKmlExtendedData->get_schemadata_array_size (  );

        size_t iSchemaData;

        for ( iSchemaData = 0; iSchemaData < nSchemaData; iSchemaData++ ) {
            SchemaDataPtr poKmlSchemaData =
                poKmlExtendedData->get_schemadata_array_at ( iSchemaData );

            /***** loop over the simpledata array *****/

            size_t nSimpleData =
                poKmlSchemaData->get_simpledata_array_size (  );

            size_t iSimpleData;

            for ( iSimpleData = 0; iSimpleData < nSimpleData; iSimpleData++ ) {
                SimpleDataPtr poKmlSimpleData =
                    poKmlSchemaData->get_simpledata_array_at ( iSimpleData );

                /***** find the field index *****/

                int iField = -1;

                if ( poKmlSimpleData->has_name (  ) ) {
                    const string oName = poKmlSimpleData->get_name (  );
                    const char *pszName = oName.c_str (  );

                    iField = poOgrFeat->GetFieldIndex ( pszName );
                }

                /***** if it has trxt set the field *****/

                if ( iField > -1 && poKmlSimpleData->has_text (  ) ) {
                    string oText = poKmlSimpleData->get_text (  );

                    /* SerializePretty() adds a new line before the data */
                    /* ands trailing spaces. I believe this is wrong */
                    /* as it breaks round-tripping */

                    /* Trim trailing spaces */
                    while (oText.size() != 0 && oText[oText.size()-1] == ' ')
                        oText.resize(oText.size()-1);

                    /* Skip leading newline and spaces */
                    const char* pszText = oText.c_str (  );
                    if (pszText[0] == '\n')
                        pszText ++;
                    while (pszText[0] == ' ')
                        pszText ++;

                    poOgrFeat->SetField ( iField, pszText );
                }
            }
        }

        if (nSchemaData == 0 &&  poKmlExtendedData->get_data_array_size() > 0 )
        {
            int bLaunderFieldNames =
                        CSLTestBoolean(CPLGetConfigOption("LIBKML_LAUNDER_FIELD_NAMES", "YES"));
            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() && data->has_value())
                {
                    CPLString osName = data->get_name();
                    if (bLaunderFieldNames)
                        osName = OGRLIBKMLLayer::LaunderFieldNames(osName);
                    int iField = poOgrFeat->GetFieldIndex ( osName );
                    if (iField >= 0)
                    {
                        poOgrFeat->SetField ( iField, data->get_value().c_str() );
                    }
                }
            }
        }
    }

}