示例#1
0
  bool UAVFlightPlan::exportToKMLFile(const std::string &f, int begin_, int end_) const {
    bool ret_val = true;
    
    if (end_ < 0 || end_ > size()) {
      end_ = size(); 
    }
  
    if (begin_ < 0 || begin_ > size()) {
      begin_ = 0;
    }
    
    const_iterator it = begin();
    
    // Advance to the first waypoint to save
    int i = 0;
    for (; i < begin_; i++, it++);

    KmlFactory* factory = KmlFactory::GetFactory();
    
    
		kmldom::DocumentPtr doc = factory->CreateDocument();
		
    for (int j = 1; i < end_ && it != end(); j++,i++, it++) {
			ostringstream name_;
			name_ << "Waypoint " << j;
			// Create a <Point> with <coordinates> from the given Vec3.
			kmlbase::Vec3 v(it->getLongitude(), it->getLatitude(), it->getAltitude());
			kmldom::PointPtr point = kmlconvenience::CreatePointFromVec3(v);
			PlacemarkPtr place = factory->CreatePlacemark();
			place->set_geometry(point);
			doc->add_feature(place);
    }
    
    
    
    // Finally create the kml
    KmlPtr kml = factory->CreateKml();
    kml->set_feature(doc);
    
    // Then the file
    KmlFilePtr kmlfile = KmlFile::CreateFromImport(kml);
    if (!kmlfile) {
      cerr << "error: could not create kml file" << endl;
      return false;
    }
    
    // And write it
    std::string kml_data;
    kmlfile->SerializeToString(&kml_data);
    if (!kmlbase::File::WriteStringToFile(kml_data, f.c_str())) {
      cerr << "error: write of " << f << " failed" << endl;
      ret_val = false;
    }
    
    return ret_val;
  }
示例#2
0
OGRErr OGRLIBKMLLayer::DeleteFeature( GIntBig nFIDIn )
{
    if( !bUpdate || !m_poKmlUpdate )
        return OGRERR_UNSUPPORTED_OPERATION;

    KmlFactory *poKmlFactory = m_poOgrDS->GetKmlFactory();
    DeletePtr poDelete = poKmlFactory->CreateDelete();
    m_poKmlUpdate->add_updateoperation(poDelete);
    PlacemarkPtr poKmlPlacemark = poKmlFactory->CreatePlacemark();
    poDelete->add_feature(poKmlPlacemark);

    const char* pszId = CPLSPrintf("%s." CPL_FRMT_GIB,
                    OGRLIBKMLGetSanitizedNCName(GetName()).c_str(), nFIDIn);
    poKmlPlacemark->set_targetid(pszId);

    /***** mark as updated *****/
    m_poOgrDS->Updated();

    return OGRERR_NONE;
}
示例#3
0
/**
 * @brief KmlExport::createTimespanPlacemark Creates a timespan placemark, which allows the
 * trajectory to be played forward in time. The placemark also contains pertinent data about
 * the vehicle's state at that timespan
 * @param timestampPoint
 * @param lastPlacemarkTime
 * @param newPlacemarkTime
 * @return Returns the placemark containing the timespan
 */
PlacemarkPtr KmlExport::createTimespanPlacemark(const LLAVCoordinates &timestampPoint, quint32 lastPlacemarkTime, quint32 newPlacemarkTime)
{
    // Create coordinates
    CoordinatesPtr coordinates = factory->CreateCoordinates();
    coordinates->add_latlngalt(timestampPoint.latitude, timestampPoint.longitude, timestampPoint.altitude);

    // Create point, using previous coordinates
    PointPtr point = factory->CreatePoint();
    point->set_extrude(true); // Extrude to ground
    point->set_altitudemode(kmldom::ALTITUDEMODE_ABSOLUTE);
    point->set_coordinates(coordinates);

    // Create the timespan
    TimeSpanPtr timeSpan = factory->CreateTimeSpan();
    QDateTime startTime = QDateTime::currentDateTimeUtc().addMSecs(lastPlacemarkTime); // FIXME: Make it a function of the realtime preferably gotten from the GPS
    QDateTime endTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime);
    timeSpan->set_begin(startTime.toString(dateTimeFormat).toStdString());
    timeSpan->set_end(endTime.toString(dateTimeFormat).toStdString());

    // Create an icon style. This arrow icon will be rotated and colored to represent velocity
    AttitudeActual::DataFields attitudeActualData = attitudeActual->getData();
    AirspeedActual::DataFields airspeedActualData = airspeedActual->getData();
    IconStylePtr iconStyle = factory->CreateIconStyle();
    iconStyle->set_color(mapVelocity2Color(airspeedActualData.CalibratedAirspeed));
    iconStyle->set_heading(attitudeActualData.Yaw + 180); //Adding 180 degrees because the arrow art points down, i.e. south.

    // Create a line style. This defines the style for the "legs" connecting the points to the ground.
    LineStylePtr lineStyle = factory->CreateLineStyle();
    lineStyle->set_color(mapVelocity2Color(timestampPoint.groundspeed));

    // Link the style to the icon
    StylePtr style = factory->CreateStyle();
    style->set_linestyle(lineStyle);
    style->set_iconstyle(iconStyle);

    // Generate the placemark with all above attributes
    PlacemarkPtr placemark = factory->CreatePlacemark();
    placemark->set_geometry(point);
    placemark->set_timeprimitive(timeSpan);
    placemark->set_name(QString("%1").arg(timeStamp / 1000.0).toStdString());
    placemark->set_visibility(true);

    // Set the placemark to use the custom rotated arrow style
    placemark->set_styleurl("#directiveArrowStyle");
    placemark->set_styleselector(style);

    // Add a nice description to the placemark
    placemark->set_description(informationString.toStdString());

    return placemark;
}
示例#4
0
void addstylestring2kml (
    const char *pszStyleString,
    StylePtr poKmlStyle,
    KmlFactory * poKmlFactory,
    PlacemarkPtr poKmlPlacemark,
    OGRFeature * poOgrFeat )
{

    LineStylePtr poKmlLineStyle = NULL;
    PolyStylePtr poKmlPolyStyle = NULL;
    IconStylePtr poKmlIconStyle = NULL;
    LabelStylePtr poKmlLabelStyle = NULL;
    
    /***** just bail now if stylestring is empty *****/

    if ( !pszStyleString || !*pszStyleString ) {
        return;
    }

    /***** create and init a style mamager with the style string *****/

    OGRStyleMgr *poOgrSM = new OGRStyleMgr;

    poOgrSM->InitStyleString ( pszStyleString );

    /***** loop though the style parts *****/

    int i;

    for ( i = 0; i < poOgrSM->GetPartCount ( NULL ); i++ ) {
        OGRStyleTool *poOgrST = poOgrSM->GetPart ( i, NULL );

        if ( !poOgrST ) {
            continue;
        }
        
        switch ( poOgrST->GetType (  ) ) {
        case OGRSTCPen:
            {
                GBool nullcheck;

                poKmlLineStyle = poKmlFactory->CreateLineStyle (  );

                OGRStylePen *poStylePen = ( OGRStylePen * ) poOgrST;

                /***** pen color *****/

                int nR,
                    nG,
                    nB,
                    nA;

                const char *pszcolor = poStylePen->Color ( nullcheck );

                if ( !nullcheck
                     && poStylePen->GetRGBFromString ( pszcolor, nR, nG, nB, nA ) ) {
                    poKmlLineStyle->set_color ( Color32 ( nA, nB, nG, nR ) );
                }
                double dfWidth = poStylePen->Width ( nullcheck );

                if ( nullcheck )
                    dfWidth = 1.0;

                poKmlLineStyle->set_width ( dfWidth );
                
                break;
            }
        case OGRSTCBrush:
            {
                GBool nullcheck;

                poKmlPolyStyle = poKmlFactory->CreatePolyStyle (  );

                OGRStyleBrush *poStyleBrush = ( OGRStyleBrush * ) poOgrST;

                /***** brush color *****/

                int nR,
                    nG,
                    nB,
                    nA;

                const char *pszcolor = poStyleBrush->ForeColor ( nullcheck );

                if ( !nullcheck
                     && poStyleBrush->GetRGBFromString ( pszcolor, nR, nG, nB, nA ) ) {
                    poKmlPolyStyle->set_color ( Color32 ( nA, nB, nG, nR ) );
                }
                

                break;
            }
        case OGRSTCSymbol:
            {
                GBool nullcheck;
                GBool nullcheck2;

                OGRStyleSymbol *poStyleSymbol = ( OGRStyleSymbol * ) poOgrST;

                /***** id (kml icon) *****/

                const char *pszId = poStyleSymbol->Id ( nullcheck );

                if ( !nullcheck ) {
                    if ( !poKmlIconStyle)
                        poKmlIconStyle = poKmlFactory->CreateIconStyle (  );

                    /***** split it at the ,'s *****/

                    char **papszTokens =
                        CSLTokenizeString2 ( pszId, ",",
                                             CSLT_HONOURSTRINGS | CSLT_STRIPLEADSPACES |
                                             CSLT_STRIPENDSPACES );

                    if ( papszTokens ) {

                        /***** for lack of a better solution just take the first one *****/
                        //todo come up with a better idea

                        if ( papszTokens[0] ) {
                            IconStyleIconPtr poKmlIcon =
                                poKmlFactory->CreateIconStyleIcon (  );
                            poKmlIcon->set_href ( papszTokens[0] );
                            poKmlIconStyle->set_icon ( poKmlIcon );
                        }

                        CSLDestroy ( papszTokens );

                    }


                }

                /***** heading *****/

                double heading = poStyleSymbol->Angle ( nullcheck );

                if ( !nullcheck ) {
                    if ( !poKmlIconStyle)
                        poKmlIconStyle = poKmlFactory->CreateIconStyle (  );
                    poKmlIconStyle->set_heading ( heading );
                }

                /***** scale *****/

                double dfScale = poStyleSymbol->Size ( nullcheck );

                if ( !nullcheck ) {
                    if ( !poKmlIconStyle)
                        poKmlIconStyle = poKmlFactory->CreateIconStyle (  );

                    poKmlIconStyle->set_scale ( dfScale );
                }

                /***** color *****/

                int nR,
                    nG,
                    nB,
                    nA;

                const char *pszcolor = poStyleSymbol->Color ( nullcheck );

                if ( !nullcheck && poOgrST->GetRGBFromString ( pszcolor, nR, nG, nB, nA ) ) {
                    poKmlIconStyle->set_color ( Color32 ( nA, nB, nG, nR ) );
                }

                /***** hotspot *****/

                double dfDx = poStyleSymbol->SpacingX ( nullcheck );
                double dfDy = poStyleSymbol->SpacingY ( nullcheck2 );

                if ( !nullcheck && !nullcheck2 ) {
                    if ( !poKmlIconStyle)
                        poKmlIconStyle = poKmlFactory->CreateIconStyle (  );

                    HotSpotPtr poKmlHotSpot = poKmlFactory->CreateHotSpot (  );

                    poKmlHotSpot->set_x ( dfDx );
                    poKmlHotSpot->set_y ( dfDy );

                    poKmlIconStyle->set_hotspot ( poKmlHotSpot );
                }
                
                break;
            }
        case OGRSTCLabel:
            {
                GBool nullcheck;
                GBool nullcheck2;
                
                poKmlLabelStyle = poKmlFactory->CreateLabelStyle (  );

                OGRStyleLabel *poStyleLabel = ( OGRStyleLabel * ) poOgrST;

                /***** color *****/

                int nR,
                    nG,
                    nB,
                    nA;

                const char *pszcolor = poStyleLabel->ForeColor ( nullcheck );

                if ( !nullcheck
                     && poStyleLabel->GetRGBFromString ( pszcolor, nR, nG, nB, nA ) ) {
                    poKmlLabelStyle->set_color ( Color32 ( nA, nB, nG, nR ) );
                }

                /***** scale *****/

                double dfScale = poStyleLabel->Stretch ( nullcheck );

                if ( !nullcheck ) {
                    dfScale /= 100.0;
                    poKmlLabelStyle->set_scale ( dfScale );
                }
                
                /***** heading *****/

                double heading = poStyleLabel->Angle ( nullcheck );

                if ( !nullcheck ) {
                    if ( !poKmlIconStyle) {
                        poKmlIconStyle = poKmlFactory->CreateIconStyle (  );
                        IconStyleIconPtr poKmlIcon = poKmlFactory->CreateIconStyleIcon (  );
                        poKmlIconStyle->set_icon ( poKmlIcon );
                    }
                    
                    poKmlIconStyle->set_heading ( heading );
                }

                /***** hotspot *****/

                double dfDx = poStyleLabel->SpacingX ( nullcheck );
                double dfDy = poStyleLabel->SpacingY ( nullcheck2 );

                if ( !nullcheck && !nullcheck2 ) {
                    if ( !poKmlIconStyle) {
                        poKmlIconStyle = poKmlFactory->CreateIconStyle (  );
                        IconStyleIconPtr poKmlIcon = poKmlFactory->CreateIconStyleIcon (  );
                        poKmlIconStyle->set_icon ( poKmlIcon );
                    }
                    
                    HotSpotPtr poKmlHotSpot = poKmlFactory->CreateHotSpot (  );

                    poKmlHotSpot->set_x ( dfDx );
                    poKmlHotSpot->set_y ( dfDy );

                    poKmlIconStyle->set_hotspot ( poKmlHotSpot );
                }

                /***** label text *****/

                const char *pszText = poStyleLabel->TextString ( nullcheck );

                if ( !nullcheck ) {
                    if ( poKmlPlacemark ) {

                        poKmlPlacemark->set_name( pszText );
                    }
                }
                    
                break;
            }
        case OGRSTCNone:
        default:
            break;
        }

        delete poOgrST;
    }

    if ( poKmlLineStyle )
        poKmlStyle->set_linestyle ( poKmlLineStyle );

    if ( poKmlPolyStyle )
        poKmlStyle->set_polystyle ( poKmlPolyStyle );

    if ( poKmlIconStyle )
        poKmlStyle->set_iconstyle ( poKmlIconStyle );

    if ( poKmlLabelStyle )
        poKmlStyle->set_labelstyle ( poKmlLabelStyle );
    
    delete poOgrSM;
}
示例#5
0
OGRLIBKMLLayer::OGRLIBKMLLayer ( const char *pszLayerName,
                                 OGRSpatialReference * poSpatialRef,
                                 OGRwkbGeometryType eGType,
                                 OGRLIBKMLDataSource * poOgrDS,
                                 ElementPtr poKmlRoot,
                                 ContainerPtr poKmlContainer,
                                 UpdatePtr poKmlUpdate,
                                 const char *pszFileName,
                                 int bNew,
                                 int bUpdateIn )
{

    m_poStyleTable = NULL;
    iFeature = 0;
    nFeatures = 0;
    nFID = 1;

    this->bUpdate = bUpdateIn;
    bUpdated = FALSE;
    m_pszName = CPLStrdup ( pszLayerName );
    m_pszFileName = CPLStrdup ( pszFileName );
    m_poOgrDS = poOgrDS;

    m_poOgrSRS = new OGRSpatialReference ( NULL );
    m_poOgrSRS->SetWellKnownGeogCS ( "WGS84" );

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

    /***** store the root element pointer *****/

    m_poKmlLayerRoot = poKmlRoot;

    /***** store the layers container *****/

    m_poKmlLayer = poKmlContainer;

    /* update container */
    m_poKmlUpdate = poKmlUpdate;

    m_poKmlSchema = NULL;

    /***** related to Region *****/

    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_bReadGroundOverlay = CPLTestBool(
        CPLGetConfigOption("LIBKML_READ_GROUND_OVERLAY", "YES"));
    m_bUseSimpleField = CPLTestBool(
        CPLGetConfigOption("LIBKML_USE_SIMPLEFIELD", "YES"));

    m_bUpdateIsFolder = FALSE;

    /***** 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 *****/

            int bHasHeading = FALSE, bHasTilt = FALSE, bHasRoll = FALSE;
            int bHasSnippet = FALSE;
            FeaturePtr poKmlFeature;

            /***** 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 (  ) ) {

                ExtendedDataPtr poKmlExtendedData = poKmlFeature->
                    get_extendeddata (  );

                if ( poKmlExtendedData->get_schemadata_array_size (  ) > 0 ) {
                    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... */
                    int bLaunderFieldNames =
                        CPLTestBool(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())
                        {
                            CPLString osName = 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;
    }

}
示例#6
0
OGRLIBKMLLayer::OGRLIBKMLLayer( const char *pszLayerName,
                                OGRwkbGeometryType eGType,
                                OGRLIBKMLDataSource * poOgrDS,
                                ElementPtr poKmlRoot,
                                ContainerPtr poKmlContainer,
                                UpdatePtr poKmlUpdate,
                                const char *pszFileName,
                                int bNew,
                                int bUpdateIn ) :
    bUpdate(CPL_TO_BOOL(bUpdateIn)),
    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(nullptr),
    m_poOgrSRS(new OGRSpatialReference(nullptr)),
    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 = nullptr;
    m_poOgrSRS->SetWellKnownGeogCS( "WGS84" );
    m_poOgrSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);

    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 );

        bool bCanSetKmlSchema = true;

        /***** 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() )
            {
                for(size_t i = 0; i < poKmlDocument->get_schema_array_size(); i++ )
                {
                    auto schema = poKmlDocument->get_schema_array_at( i );
                    if( bCanSetKmlSchema && !m_poKmlSchema )
                    {
                        m_poKmlSchema = schema;
                        bCanSetKmlSchema = false;
                    }
                    else
                    {
                        m_poKmlSchema = nullptr;
                    }
                    kml2FeatureDef( schema, m_poOgrFeatureDefn );
                }
            }
        }

        /***** the schema is somewhere else *****/
        if( bCanSetKmlSchema )
        {
            /***** try to find the correct schema *****/
            bool bHasHeading = false;
            bool bHasTilt = false;
            bool bHasRoll = false;
            bool bHasSnippet = false;
            FeaturePtr poKmlFeature = nullptr;
            const bool bLaunderFieldNames =
                CPLTestBool(CPLGetConfigOption(
                    "LIBKML_LAUNDER_FIELD_NAMES", "YES"));
            std::set<std::string> oSetSchemaAlreadyVisited;

            /***** find the first placemark *****/
            for( iFeature = 0; iFeature < nFeatures; iFeature++ )
            {
                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( 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( oSetSchemaAlreadyVisited.find(
                                        oKmlSchemaUrl) ==
                                            oSetSchemaAlreadyVisited.end() )
                                {
                                    oSetSchemaAlreadyVisited.insert(
                                        oKmlSchemaUrl);
                                    auto schema = m_poOgrDS->FindSchema(
                                            oKmlSchemaUrl.c_str() );
                                    if( schema )
                                    {
                                        if( bCanSetKmlSchema && !m_poKmlSchema )
                                        {
                                            m_poKmlSchema = schema;
                                            bCanSetKmlSchema = false;
                                        }
                                        else
                                        {
                                            m_poKmlSchema = nullptr;
                                        }
                                        kml2FeatureDef( schema, m_poOgrFeatureDefn );
                                    }
                                }
                            }
                        }
                        else if( poKmlExtendedData->get_data_array_size() > 0 )
                        {
                            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);
                                    if( m_poOgrFeatureDefn->GetFieldIndex(osName) < 0 )
                                    {
                                        OGRFieldDefn oOgrField( osName, OFTString );
                                        m_poOgrFeatureDefn->AddFieldDefn( &oOgrField );
                                    }
                                }
                            }
                        }
                    }
                }
                if( !bHasSnippet && poKmlFeature->has_snippet() )
                {
                    bHasSnippet = true;
                    OGRFieldDefn oOgrField( oFC.snippetfield, OFTString );
                    m_poOgrFeatureDefn->AddFieldDefn( &oOgrField );
                }
            }

            iFeature = 0;
        }
    }
}
示例#7
0
/**
 * @brief KmlExport::CreateLineStringPlacemark Adds a line segment which is colored according to the
 * vehicle's speed.
 * @param startPoint Beginning point along line
 * @param endPoint End point point along line
 * @return Returns the placemark containing the line segment
 */
PlacemarkPtr KmlExport::CreateLineStringPlacemark(const LLAVCoordinates &startPoint, const LLAVCoordinates &endPoint, quint32 newPlacemarkTime)
{
    CoordinatesPtr coordinates = factory->CreateCoordinates();
    coordinates->add_latlngalt(startPoint.latitude, startPoint.longitude, startPoint.altitude);
    coordinates->add_latlngalt(endPoint.latitude,   endPoint.longitude,   endPoint.altitude);

    LineStringPtr linestring = factory->CreateLineString();
    linestring->set_extrude(true); // Extrude to ground
    linestring->set_altitudemode(kmldom::ALTITUDEMODE_ABSOLUTE);
    linestring->set_coordinates(coordinates);

    StyleMapPtr styleMap = factory->CreateStyleMap();


    // Add custom balloon style (gets rid of "Directions to here...")
    // https://groups.google.com/forum/?fromgroups#!topic/kml-support-getting-started/2CqF9oiynRY
    BalloonStylePtr balloonStyle = factory->CreateBalloonStyle();
    balloonStyle->set_text("$[description]");

    {
        double currentVelocity = (startPoint.groundspeed + endPoint.groundspeed)/2;

        // Set the linestyle. The color is a function of speed.
        LineStylePtr lineStyle = factory->CreateLineStyle();
        lineStyle->set_color(mapVelocity2Color(currentVelocity));

        PolyStylePtr polyStyle = factory->CreatePolyStyle();
        polyStyle->set_color(mapVelocity2Color(currentVelocity, 100));

        // Link the style to the icon
        StylePtr style = factory->CreateStyle();
        style->set_balloonstyle(balloonStyle);
        style->set_linestyle(lineStyle);
        style->set_polystyle(polyStyle);

        PairPtr pair = factory->CreatePair();
        pair->set_styleselector(style);
        pair->set_key(kmldom::STYLESTATE_NORMAL);

        styleMap->add_pair(pair);
    }

    {
        double currentVelocity = (startPoint.groundspeed + endPoint.groundspeed)/2;

        // Set the linestyle. The color is a function of speed.
        LineStylePtr lineStyle = factory->CreateLineStyle();
        lineStyle->set_color(mapVelocity2Color(currentVelocity));

        PolyStylePtr polyStyle = factory->CreatePolyStyle();
        polyStyle->set_color(mapVelocity2Color(currentVelocity, 100));
        polyStyle->set_fill(false);

        // Link the style to the icon
        StylePtr style = factory->CreateStyle();
        style->set_balloonstyle(balloonStyle);
        style->set_linestyle(lineStyle);
        style->set_polystyle(polyStyle);

        PairPtr pair = factory->CreatePair();
        pair->set_styleselector(style);
        pair->set_key(kmldom::STYLESTATE_HIGHLIGHT);

        styleMap->add_pair(pair);
    }

    PlacemarkPtr placemark = factory->CreatePlacemark();
    placemark->set_geometry(linestring);
    placemark->set_styleselector(styleMap);
    placemark->set_visibility(true);

    // Create the timespan
    TimeSpanPtr timeSpan = factory->CreateTimeSpan();
    QDateTime startTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime); // FIXME: Make this a function of the true time, preferably gotten from the GPS
    QDateTime endTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime);
    timeSpan->set_begin(startTime.toString(dateTimeFormat).toStdString());
    timeSpan->set_end(endTime.toString(dateTimeFormat).toStdString());

    // Set the name
    QDateTime trackTime = QDateTime::currentDateTimeUtc().addMSecs(newPlacemarkTime); // FIXME: Make it a function of the realtime preferably gotten from the GPS
    placemark->set_name(trackTime.toString(dateTimeFormat).toStdString());

    // Add a nice description to the track placemark
    placemark->set_description(informationString.toStdString());

    // Set the timespan
    placemark->set_timeprimitive(timeSpan);

    return placemark;
}
示例#8
0
/**
 * @brief KmlExport::exportToKML Triggers logfile export to KML.
 */
bool KmlExport::exportToKML()
{
    bool ret = open();
    if (!ret) {
        qDebug () << "Logfile failed to open during KML export";
        return false;
    }

    // Parses logfile and generates KML document
    ret = preparseLogFile();
    if (!ret) {
        qDebug () << "Logfile preparsing failed";
        return false;
    }

    // Call parser.
    parseLogFile();

    // Add track to <Document>
    document->add_feature(trackFolder);

    // Add timespans to <Document>
    document->add_feature(timestampFolder);

    // Add ground track to <Document>
    {
        LineStringPtr linestring = factory->CreateLineString();
        linestring->set_extrude(false); // Do not extrude to ground
        linestring->set_altitudemode(kmldom::ALTITUDEMODE_CLAMPTOGROUND);
        linestring->set_coordinates(wallAxes[0]);

        MultiGeometryPtr multiGeometry = factory->CreateMultiGeometry();
        multiGeometry->add_geometry(linestring);

        PlacemarkPtr placemark = factory->CreatePlacemark();
        placemark->set_geometry(multiGeometry);
        placemark->set_styleurl("#ts_2_tb");
        placemark->set_name("Ground track");

        document->add_feature(placemark);
    }

    // Add wall axes to <Document>
    FolderPtr folder = factory->CreateFolder();
    for (int i=0; i<numberOfWallAxes; i++) {
        LineStringPtr linestring = factory->CreateLineString();
        linestring->set_extrude(false); // Do not extrude to ground
        linestring->set_altitudemode(kmldom::ALTITUDEMODE_ABSOLUTE);
        linestring->set_coordinates(wallAxes[i]);

        MultiGeometryPtr multiGeometry = factory->CreateMultiGeometry();
        multiGeometry->add_geometry(linestring);

        PlacemarkPtr placemark = factory->CreatePlacemark();
        placemark->set_geometry(multiGeometry);
        placemark->set_styleurl("#ts_1_tb");

        folder->add_feature(placemark);
        folder->set_name("Wall axes");
    }
    document->add_feature(folder);

    // Create <kml> and give it <Document>.
    KmlPtr kml = factory->CreateKml();
    kml->set_feature(document);  // kml takes ownership.

    // Serialize to XML
    std::string kml_data = kmldom::SerializePretty(kml);

    // Save to file
    if (QFileInfo(outputFileName).suffix().toLower() == "kmz") {
        if (!kmlengine::KmzFile::WriteKmz(outputFileName.toStdString().c_str(), kml_data)) {
            qDebug() << "KMZ write failed: " << outputFileName;
            QMessageBox::critical(new QWidget(),"KMZ write failed", "Failed to write KMZ file.");
            return false;
        }
    } else if (QFileInfo(outputFileName).suffix().toLower() == "kml") {
        if (!kmlbase::File::WriteStringToFile(kml_data, outputFileName.toStdString())) {
            qDebug() << "KML write failed: " << outputFileName;
            QMessageBox::critical(new QWidget(),"KML write failed", "Failed to write KML file.");
            return false;
        }
    } else {
        qDebug() << "Write failed. Invalid file name:" << outputFileName;
        QMessageBox::critical(new QWidget(),"Write failed", "Failed to write file. Invalid filename");
        return false;
    }


    return true;
}
示例#9
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() );
                    }
                }
            }
        }
    }

}
示例#10
0
void field2kml (
    OGRFeature * poOgrFeat,
    OGRLIBKMLLayer * poOgrLayer,
    KmlFactory * poKmlFactory,
    PlacemarkPtr poKmlPlacemark )
{
    int i;

    SchemaDataPtr poKmlSchemaData = poKmlFactory->CreateSchemaData (  );
    SchemaPtr poKmlSchema = poOgrLayer->GetKmlSchema (  );

    /***** set the url to the schema *****/

    if ( poKmlSchema && poKmlSchema->has_id (  ) ) {
        std::string oKmlSchemaID = poKmlSchema->get_id (  );


        std::string oKmlSchemaURL = "#";
        oKmlSchemaURL.append ( oKmlSchemaID );

        poKmlSchemaData->set_schemaurl ( oKmlSchemaURL );
    }

    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" );

    TimeSpanPtr poKmlTimeSpan = NULL;

    int nFields = poOgrFeat->GetFieldCount (  );
    int iSkip1 = -1;
    int iSkip2 = -1;

    for ( i = 0; i < nFields; i++ ) {

        /***** if the field is set to skip, do so *****/

        if ( i == iSkip1 || i == iSkip2 )
            continue;

        /***** if the field isn't set just bail now *****/

        if ( !poOgrFeat->IsFieldSet ( i ) )
            continue;

        OGRFieldDefn *poOgrFieldDef = poOgrFeat->GetFieldDefnRef ( i );
        OGRFieldType type = poOgrFieldDef->GetType (  );
        const char *name = poOgrFieldDef->GetNameRef (  );

        SimpleDataPtr poKmlSimpleData = NULL;
        int year,
            month,
            day,
            hour,
            min,
            sec,
            tz;

        switch ( type ) {

        case OFTString:        //     String of ASCII chars
            {
                char* pszUTF8String = OGRLIBKMLSanitizeUTF8String(
                                        poOgrFeat->GetFieldAsString ( i ));
                /***** name *****/

                if ( EQUAL ( name, namefield ) ) {
                    poKmlPlacemark->set_name ( pszUTF8String );
                    CPLFree( pszUTF8String );
                    continue;
                }

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

                else if ( EQUAL ( name, descfield ) ) {
                    poKmlPlacemark->set_description ( pszUTF8String );
                    CPLFree( pszUTF8String );
                    continue;
                }

                /***** altitudemode *****/

                else if ( EQUAL ( name, altitudeModefield ) ) {
                    const char *pszAltitudeMode = pszUTF8String ;

                    int isGX = FALSE;
                    int iAltitudeMode = kmldom::ALTITUDEMODE_CLAMPTOGROUND;

                    if ( EQUAL ( pszAltitudeMode, "clampToGround" ) )
                        iAltitudeMode = kmldom::ALTITUDEMODE_CLAMPTOGROUND;

                    else if ( EQUAL ( pszAltitudeMode, "relativeToGround" ) )
                        iAltitudeMode = kmldom::ALTITUDEMODE_RELATIVETOGROUND;

                    else if ( EQUAL ( pszAltitudeMode, "absolute" ) )
                        iAltitudeMode = kmldom::ALTITUDEMODE_ABSOLUTE;

                    else if ( EQUAL ( pszAltitudeMode, "relativeToSeaFloor" ) ) {
                        iAltitudeMode =
                            kmldom::GX_ALTITUDEMODE_RELATIVETOSEAFLOOR;
                        isGX = TRUE;
                    }

                    else if ( EQUAL ( pszAltitudeMode, "clampToSeaFloor" ) ) {
                        iAltitudeMode =
                            kmldom::GX_ALTITUDEMODE_CLAMPTOSEAFLOOR;
                        isGX = TRUE;
                    }


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

                        ogr2altitudemode_rec ( poKmlGeometry, iAltitudeMode,
                                               isGX );

                    }

                    CPLFree( pszUTF8String );

                    continue;
                }
                
                /***** timestamp *****/

                else if ( EQUAL ( name, tsfield ) ) {

                    TimeStampPtr poKmlTimeStamp =
                        poKmlFactory->CreateTimeStamp (  );
                    poKmlTimeStamp->set_when ( pszUTF8String  );
                    poKmlPlacemark->set_timeprimitive ( poKmlTimeStamp );

                    CPLFree( pszUTF8String );

                    continue;
                }

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

                if ( EQUAL ( name, beginfield ) ) {

                    if ( !poKmlTimeSpan ) {
                        poKmlTimeSpan = poKmlFactory->CreateTimeSpan (  );
                        poKmlPlacemark->set_timeprimitive ( poKmlTimeSpan );
                    }

                    poKmlTimeSpan->set_begin ( pszUTF8String );

                    CPLFree( pszUTF8String );

                    continue;

                }

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

                else if ( EQUAL ( name, endfield ) ) {

                    if ( !poKmlTimeSpan ) {
                        poKmlTimeSpan = poKmlFactory->CreateTimeSpan (  );
                        poKmlPlacemark->set_timeprimitive ( poKmlTimeSpan );
                    }

                    poKmlTimeSpan->set_end ( pszUTF8String );

                    CPLFree( pszUTF8String );

                    continue;
                }
                
                /***** other *****/

                poKmlSimpleData = poKmlFactory->CreateSimpleData (  );
                poKmlSimpleData->set_name ( name );
                poKmlSimpleData->set_text ( pszUTF8String );

                CPLFree( pszUTF8String );

                break;
            }

        case OFTDate:          //   Date
            {
                poOgrFeat->GetFieldAsDateTime ( i, &year, &month, &day,
                                                &hour, &min, &sec, &tz );

                int iTimeField;

                for ( iTimeField = i + 1; iTimeField < nFields; iTimeField++ ) {
                    if ( iTimeField == iSkip1 || iTimeField == iSkip2 )
                        continue;

                    OGRFieldDefn *poOgrFieldDef2 =
                        poOgrFeat->GetFieldDefnRef ( i );
                    OGRFieldType type2 = poOgrFieldDef2->GetType (  );
                    const char *name2 = poOgrFieldDef2->GetNameRef (  );

                    if ( EQUAL ( name2, name ) && type2 == OFTTime &&
                         ( EQUAL ( name, tsfield ) ||
                           EQUAL ( name, beginfield ) ||
                           EQUAL ( name, endfield ) ) ) {

                        int year2,
                            month2,
                            day2,
                            hour2,
                            min2,
                            sec2,
                            tz2;

                        poOgrFeat->GetFieldAsDateTime ( iTimeField, &year2,
                                                        &month2, &day2, &hour2,
                                                        &min2, &sec2, &tz2 );

                        hour = hour2;
                        min = min2;
                        sec = sec2;
                        tz = tz2;

                        if ( 0 > iSkip1 )
                            iSkip1 = iTimeField;
                        else
                            iSkip2 = iTimeField;
                    }
                }

                goto Do_DateTime;

            }


        case OFTTime:          //   Time
            {
                poOgrFeat->GetFieldAsDateTime ( i, &year, &month, &day,
                                                &hour, &min, &sec, &tz );

                int iTimeField;

                for ( iTimeField = i + 1; iTimeField < nFields; iTimeField++ ) {
                    if ( iTimeField == iSkip1 || iTimeField == iSkip2 )
                        continue;

                    OGRFieldDefn *poOgrFieldDef2 =
                        poOgrFeat->GetFieldDefnRef ( i );
                    OGRFieldType type2 = poOgrFieldDef2->GetType (  );
                    const char *name2 = poOgrFieldDef2->GetNameRef (  );

                    if ( EQUAL ( name2, name ) && type2 == OFTTime &&
                         ( EQUAL ( name, tsfield ) ||
                           EQUAL ( name, beginfield ) ||
                           EQUAL ( name, endfield ) ) ) {

                        int year2,
                            month2,
                            day2,
                            hour2,
                            min2,
                            sec2,
                            tz2;

                        poOgrFeat->GetFieldAsDateTime ( iTimeField, &year2,
                                                        &month2, &day2, &hour2,
                                                        &min2, &sec2, &tz2 );

                        year = year2;
                        month = month2;
                        day = day2;

                        if ( 0 > iSkip1 )
                            iSkip1 = iTimeField;
                        else
                            iSkip2 = iTimeField;
                    }
                }

                goto Do_DateTime;

            }

        case OFTDateTime:      //  Date and Time
            {
                poOgrFeat->GetFieldAsDateTime ( i, &year, &month, &day,
                                                &hour, &min, &sec, &tz );

              Do_DateTime:
                /***** timestamp *****/

                if ( EQUAL ( name, tsfield ) ) {

                    char *timebuf = OGRGetXMLDateTime ( year, month, day, hour,
                                                        min, sec, tz );

                    TimeStampPtr poKmlTimeStamp =
                        poKmlFactory->CreateTimeStamp (  );
                    poKmlTimeStamp->set_when ( timebuf );
                    poKmlPlacemark->set_timeprimitive ( poKmlTimeStamp );
                    CPLFree( timebuf );

                    continue;
                }

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

                if ( EQUAL ( name, beginfield ) ) {

                    char *timebuf = OGRGetXMLDateTime ( year, month, day, hour,
                                                        min, sec, tz );

                    if ( !poKmlTimeSpan ) {
                        poKmlTimeSpan = poKmlFactory->CreateTimeSpan (  );
                        poKmlPlacemark->set_timeprimitive ( poKmlTimeSpan );
                    }

                    poKmlTimeSpan->set_begin ( timebuf );
                    CPLFree( timebuf );

                    continue;

                }

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

                else if ( EQUAL ( name, endfield ) ) {

                    char *timebuf = OGRGetXMLDateTime ( year, month, day, hour,
                                                        min, sec, tz );


                    if ( !poKmlTimeSpan ) {
                        poKmlTimeSpan = poKmlFactory->CreateTimeSpan (  );
                        poKmlPlacemark->set_timeprimitive ( poKmlTimeSpan );
                    }

                    poKmlTimeSpan->set_end ( timebuf );
                    CPLFree( timebuf );

                    continue;
                }

                /***** other *****/

                poKmlSimpleData = poKmlFactory->CreateSimpleData (  );
                poKmlSimpleData->set_name ( name );
                poKmlSimpleData->set_text ( poOgrFeat->
                                            GetFieldAsString ( i ) );

                break;
            }

        case OFTInteger:       //    Simple 32bit integer

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

            if ( EQUAL ( name, extrudefield ) ) {

                if ( poKmlPlacemark->has_geometry (  )
                     && -1 < poOgrFeat->GetFieldAsInteger ( i ) ) {
                    GeometryPtr poKmlGeometry =
                        poKmlPlacemark->get_geometry (  );
                    ogr2extrude_rec ( poOgrFeat->GetFieldAsInteger ( i ),
                                      poKmlGeometry );
                }
                continue;
            }

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


            if ( EQUAL ( name, tessellatefield ) ) {

                if ( poKmlPlacemark->has_geometry (  )
                     && -1 < poOgrFeat->GetFieldAsInteger ( i ) ) {
                    GeometryPtr poKmlGeometry =
                        poKmlPlacemark->get_geometry (  );
                    ogr2tessellate_rec ( poOgrFeat->GetFieldAsInteger ( i ),
                                         poKmlGeometry );
                }

                continue;
            }


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

            if ( EQUAL ( name, visibilityfield ) ) {
                if ( -1 < poOgrFeat->GetFieldAsInteger ( i ) )
                    poKmlPlacemark->set_visibility ( poOgrFeat->
                                                     GetFieldAsInteger ( i ) );

                continue;
            }

            /***** other *****/

            poKmlSimpleData = poKmlFactory->CreateSimpleData (  );
            poKmlSimpleData->set_name ( name );
            poKmlSimpleData->set_text ( poOgrFeat->GetFieldAsString ( i ) );

            break;

        case OFTReal:          //   Double Precision floating point
        {
            poKmlSimpleData = poKmlFactory->CreateSimpleData (  );
            poKmlSimpleData->set_name ( name );

            char* pszStr = CPLStrdup( poOgrFeat->GetFieldAsString ( i ) );
            /* Use point as decimal separator */
            char* pszComma = strchr(pszStr, ',');
            if (pszComma)
                *pszComma = '.';
            poKmlSimpleData->set_text ( pszStr );
            CPLFree(pszStr);

            break;
        }

        case OFTStringList:    //     Array of strings
        case OFTIntegerList:   //    List of 32bit integers
        case OFTRealList:   //    List of doubles
        case OFTBinary:        //     Raw Binary data
        case OFTWideStringList:    //     deprecated
        default:

        /***** other *****/

            poKmlSimpleData = poKmlFactory->CreateSimpleData (  );
            poKmlSimpleData->set_name ( name );
            poKmlSimpleData->set_text ( poOgrFeat->GetFieldAsString ( i ) );

            break;
        }
        poKmlSchemaData->add_simpledata ( poKmlSimpleData );
    }

    /***** dont add it to the placemark unless there is data *****/

    if ( poKmlSchemaData->get_simpledata_array_size (  ) > 0 ) {
        ExtendedDataPtr poKmlExtendedData =
            poKmlFactory->CreateExtendedData (  );
        poKmlExtendedData->add_schemadata ( poKmlSchemaData );
        poKmlPlacemark->set_extendeddata ( poKmlExtendedData );
    }

    return;
}