Exemplo n.º 1
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
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;
}