示例#1
0
void Track::GetPointLists(std::list< std::list<wxPoint> > &pointlists,
                          ViewPort &VP, const LLBBox &box )
{
    if( !IsVisible() || GetnPoints() == 0 ) return;
    Finalize();
//    OCPNStopWatch sw;
    Segments(pointlists, box, VP.view_scale_ppm);

#if 0
    if(GetnPoints() > 40000) {
        double t = sw.GetTime();
        double c = 0;
        for(std::list< std::list<wxPoint> >::iterator lines = pointlists.begin();
        lines != pointlists.end(); lines++) {
            if(lines->size() > 1)
                c += lines->size();
                continue;
        }
        printf("assemble time %f %f segments %f seg/ms\n", sw.GetTime(), c, c/t);
    }
#endif

    //    Add last segment, dynamically, maybe.....
    // we should not add this segment if it is not on the screen...
    if( IsRunning() ) {
        std::list<wxPoint> new_list;
        pointlists.push_back(new_list);
        AddPointToList(pointlists, TrackPoints.size()-1);
        wxPoint r;
        cc1->GetCanvasPointPix( gLat, gLon, &r );
        pointlists.back().push_back(r);
    }
}
示例#2
0
void Route::DeletePoint( RoutePoint *rp, bool bRenamePoints )
{
    //    n.b. must delete Selectables  and update config before deleting the point
    if( rp->m_bIsInLayer ) return;

    pSelect->DeleteAllSelectableRoutePoints( this );
    pSelect->DeleteAllSelectableRouteSegments( this );
    pConfig->DeleteWayPoint( rp );

    pRoutePointList->DeleteObject( rp );

    if( ( rp->m_GUID.Len() ) && ( wxNOT_FOUND != RoutePointGUIDList.Index( rp->m_GUID ) ) ) RoutePointGUIDList.Remove(
            rp->m_GUID );

    delete rp;

    if( bRenamePoints ) RenameRoutePoints();

    if( GetnPoints() > 1 ) {
        pSelect->AddAllSelectableRouteSegments( this );
        pSelect->AddAllSelectableRoutePoints( this );

        pConfig->UpdateRoute( this );
        RebuildGUIDList();                  // ensure the GUID list is intact and good

        FinalizeForRendering();
        UpdateSegmentDistances();
    }
}
示例#3
0
RoutePoint *Route::InsertPointAfter( RoutePoint *pRP, double rlat, double rlon,
                                     bool bRenamePoints )
{
    int nRP = pRoutePointList->IndexOf( pRP );
    if( nRP >= GetnPoints() - 1 )
        return NULL;
    nRP++;

    RoutePoint *newpoint = new RoutePoint( rlat, rlon, wxString( _T ( "diamond" ) ),
                                           GetNewMarkSequenced(), GPX_EMPTY_STRING );
    newpoint->m_bIsInRoute = true;
    newpoint->m_bDynamicName = true;
    newpoint->SetNameShown( false );

    pRoutePointList->Insert( nRP, newpoint );

    RoutePointGUIDList.Insert( pRP->m_GUID, nRP );

    if( bRenamePoints ) RenameRoutePoints();

    FinalizeForRendering();
    UpdateSegmentDistances();

    return ( newpoint );
}
示例#4
0
void Route::AddPoint( RoutePoint *pNewPoint, bool b_rename_in_sequence, bool b_deferBoxCalc )
{
    if( pNewPoint->m_bIsolatedMark ) {
        pNewPoint->m_bKeepXRoute = true;
    }
    pNewPoint->m_bIsolatedMark = false;       // definitely no longer isolated
    pNewPoint->m_bIsInRoute = true;

    RoutePoint *prev = GetLastPoint();
    pRoutePointList->Append( pNewPoint );

    if( !b_deferBoxCalc )
        FinalizeForRendering();

    if( prev )
        UpdateSegmentDistance( prev, pNewPoint );

    if( b_rename_in_sequence && pNewPoint->GetName().IsEmpty() && !pNewPoint->m_bKeepXRoute ) {
        wxString name;
        name.Printf( _T ( "%03d" ), GetnPoints() );
        pNewPoint->SetName( name );
        pNewPoint->m_bDynamicName = true;
    }
    return;
}
示例#5
0
void Track::Clone( Track *psourcetrack, int start_nPoint, int end_nPoint, const wxString & suffix)
{
    if( psourcetrack->m_bIsInLayer ) return;

    m_TrackNameString = psourcetrack->m_TrackNameString + suffix;
    m_TrackStartString = psourcetrack->m_TrackStartString;
    m_TrackEndString = psourcetrack->m_TrackEndString;

    bool b_splitting = GetnPoints() == 0;

    int startTrkSegNo;
    if( b_splitting ) startTrkSegNo = psourcetrack->GetPoint( start_nPoint )->m_GPXTrkSegNo;
    else
        startTrkSegNo = GetLastPoint()->m_GPXTrkSegNo;

    int i;
    for( i = start_nPoint; i <= end_nPoint; i++ ) {

        TrackPoint *psourcepoint = psourcetrack->GetPoint( i );
        if(psourcepoint){
            TrackPoint *ptargetpoint = new TrackPoint( psourcepoint);
            
            AddPoint( ptargetpoint );
        }
    }
}
示例#6
0
void Route::CloneTrack( Route *psourceroute, int start_nPoint, int end_nPoint, const wxString & suffix)
{
    if( psourceroute->m_bIsInLayer ) return;

    m_bIsTrack = psourceroute->m_bIsTrack;

    m_RouteNameString = psourceroute->m_RouteNameString + suffix;
    m_RouteStartString = psourceroute->m_RouteStartString;
    m_RouteEndString = psourceroute->m_RouteEndString;

    bool b_splitting = GetnPoints() == 0;

    int startTrkSegNo;
    if( b_splitting ) startTrkSegNo = psourceroute->GetPoint( start_nPoint )->m_GPXTrkSegNo;
    else
        startTrkSegNo = this->GetLastPoint()->m_GPXTrkSegNo;

    int i;
    for( i = start_nPoint; i <= end_nPoint; i++ ) {

        RoutePoint *psourcepoint = psourceroute->GetPoint( i );
        RoutePoint *ptargetpoint = new RoutePoint( psourcepoint->m_lat, psourcepoint->m_lon,
                psourcepoint->GetIconName(), psourcepoint->GetName(), GPX_EMPTY_STRING, false );

        AddPoint( ptargetpoint, false );
        
        //    This is a hack, need to undo the action of Route::AddPoint
        ptargetpoint->m_bIsInRoute = false;
        ptargetpoint->m_bIsInTrack = true;
        
        CloneAddedTrackPoint( m_pLastAddedPoint, psourcepoint );

        int segment_shift = psourcepoint->m_GPXTrkSegNo;

        if(  start_nPoint == 2 ) 
            segment_shift = psourcepoint->m_GPXTrkSegNo - 1; // continue first segment if tracks share the first point

        if( b_splitting )
            m_pLastAddedPoint->m_GPXTrkSegNo = ( psourcepoint->m_GPXTrkSegNo - startTrkSegNo ) + 1;
        else
            m_pLastAddedPoint->m_GPXTrkSegNo = startTrkSegNo + segment_shift;
    }

    FinalizeForRendering();

}
示例#7
0
Track *ActiveTrack::DoExtendDaily()
{
    Track *pExtendTrack = NULL;
    TrackPoint *pExtendPoint = NULL;

    TrackPoint *pLastPoint = GetPoint( 0 );

    wxTrackListNode *track_node = pTrackList->GetFirst();
    while( track_node ) {
        Track *ptrack = track_node->GetData();

        if( !ptrack->m_bIsInLayer && ptrack->m_GUID != m_GUID ) {
            TrackPoint *track_node = ptrack->GetLastPoint();
            if( track_node->GetCreateTime() <= pLastPoint->GetCreateTime() ) {
                if( !pExtendPoint  || track_node->GetCreateTime() > pExtendPoint->GetCreateTime() ) {
                    pExtendPoint = track_node;
                    pExtendTrack = ptrack;
                }
            }
        }
        track_node = track_node->GetNext();                         // next track
    }
    if( pExtendTrack
        && pExtendTrack->GetPoint( 0 )->GetCreateTime().FromTimezone( wxDateTime::GMT0 ).IsSameDate(pLastPoint->GetCreateTime().FromTimezone( wxDateTime::GMT0 ) ) ) {
        int begin = 1;
        if( pLastPoint->GetCreateTime() == pExtendPoint->GetCreateTime() ) begin = 2;
        pSelect->DeleteAllSelectableTrackSegments( pExtendTrack );
        wxString suffix = _T("");
        if( GetName().IsNull() ) {
            suffix = pExtendTrack->GetName();
            if( suffix.IsNull() ) suffix = wxDateTime::Today().FormatISODate();
        }
        pExtendTrack->Clone( this, begin, GetnPoints(), suffix );
        pSelect->AddAllSelectableTrackSegments( pExtendTrack );
        pSelect->DeleteAllSelectableTrackSegments( this );

        return pExtendTrack;
    } else {
        if( GetName().IsNull() )
            SetName(wxDateTime::Today().FormatISODate());
        return NULL;
    }
}
示例#8
0
void Route::DrawGLLines( ViewPort &vp, ocpnDC *dc )
{
#ifdef ocpnUSE_GL
    float pix_full_circle = WGS84_semimajor_axis_meters * mercator_k0 * 2 * PI * vp.view_scale_ppm;

    bool r1valid = false;
    wxPoint2DDouble r1;
    wxPoint2DDouble lastpoint;

    wxRoutePointListNode *node = pRoutePointList->GetFirst();
    RoutePoint *prp2 = node->GetData();
    cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &lastpoint);

    if(GetnPoints() == 1 && dc) { // single point.. make sure it shows up for highlighting
        cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &r1);
        dc->DrawLine(r1.m_x, r1.m_y, r1.m_x+2, r1.m_y+2);
        return;
    }

    //    Handle offscreen points
    LLBBox bbox = vp.GetBBox();

    // dc is passed for thicker highlighted lines (performance not very important)
    if( !dc )
        glBegin(GL_LINES);

    for(node = node->GetNext(); node; node = node->GetNext()) {
        RoutePoint *prp1 = prp2;
        prp2 = node->GetData();

        // Provisional, to properly set status of last point in route
        prp2->m_pos_on_screen = false;

        {

            wxPoint2DDouble r2;
            cc1->GetDoubleCanvasPointPix( prp2->m_lat, prp2->m_lon, &r2);
            if(wxIsNaN(r2.m_x)) {
                r1valid = false;
                continue;
            }

            lastpoint = r2;             // For active track segment to ownship

            // don't need to perform calculations or render segment
            // if both points are past any edge of the vp
            // TODO: use these optimizations for dc mode
            bool lat1l = prp1->m_lat < bbox.GetMinLat(), lat2l = prp2->m_lat < bbox.GetMinLat();
            bool lat1r = prp1->m_lat > bbox.GetMaxLat(), lat2r = prp2->m_lat > bbox.GetMaxLat();
            if( (lat1l && lat2l) || (lat1r && lat2r) ) {
                r1valid = false;
                prp1->m_pos_on_screen = false;
                continue;
            }

            bool lon1l, lon1r, lon2l, lon2r;
            TestLongitude(prp1->m_lon, bbox.GetMinLon(), bbox.GetMaxLon(), lon1l, lon1r);
            TestLongitude(prp2->m_lon, bbox.GetMinLon(), bbox.GetMaxLon(), lon2l, lon2r);
            if( (lon1l && lon2l) || (lon1r && lon2r) ) {
                r1valid = false;
                prp1->m_pos_on_screen = false;
                continue;
            }

            if(!r1valid) {
                cc1->GetDoubleCanvasPointPix( prp1->m_lat, prp1->m_lon, &r1);
                if(wxIsNaN(r1.m_x))
                    continue;
            }

            //  we must decide which way to go in longitude
            //  for projections which wrap, in this case, we will render two lines
            //  (one may often be off screen which would be nice to fix but complicate things here
            //  anyway, in some cases both points are on screen, but the route wraps to either side
            //  so two lines are needed to draw this properly

            double adder = 0;
            if( (vp.m_projection_type == PROJECTION_MERCATOR ||
                    vp.m_projection_type == PROJECTION_EQUIRECTANGULAR) ) {
                float olon = vp.clon > 0 ? vp.clon - 180 : vp.clon + 180;

                if(prp1->m_lon < prp2->m_lon) {
                    if(prp2->m_lon - prp1->m_lon < 180) {
                        if(olon > prp1->m_lon && olon < prp2->m_lon)
                            adder = pix_full_circle;
                    } else if(olon < prp1->m_lon || olon > prp2->m_lon)
                        adder = -pix_full_circle;
                } else if(prp1->m_lon - prp2->m_lon < 180) {
                    if(olon < prp1->m_lon && olon > prp2->m_lon)
                        adder = -pix_full_circle;
                } else if(olon > prp1->m_lon || olon < prp2->m_lon)
                    adder = pix_full_circle;
            }

            if( dc )
                if(adder) {
                    float adderc = cos(vp.rotation)*adder, adders = sin(vp.rotation)*adder;
                    dc->DrawLine(r1.m_x, r1.m_y, r2.m_x + adderc, r2.m_y + adders);
                    dc->DrawLine(r1.m_x - adderc, r1.m_y - adders, r2.m_x, r2.m_y);
                } else
                    dc->DrawLine(r1.m_x, r1.m_y, r2.m_x, r2.m_y);
            else {
                glVertex2f(r1.m_x, r1.m_y);
                if(adder) {
                    float adderc = cos(vp.rotation)*adder, adders = sin(vp.rotation)*adder;
                    glVertex2f(r2.m_x+adderc, r2.m_y+adders);
                    glVertex2f(r1.m_x-adderc, r1.m_y-adders);
                }
                glVertex2f(r2.m_x, r2.m_y);

                // cache screen position for arrows and points
                if(!r1valid) {
                    prp1->m_pos_on_screen = !lat1l && !lat1r && !lon1l && !lon1r;
                    prp1->m_screen_pos = r1;
                }

                prp2->m_pos_on_screen = !lat2l && !lat2r && !lon2l && !lon2r;
                prp2->m_screen_pos = r2;
            }

            r1 = r2;
            r1valid = true;
        }
    }

    if( !dc )
        glEnd();
#endif
}
示例#9
0
void Route::DrawPointWhich( ocpnDC& dc, int iPoint, wxPoint *rpn )
{
    if( iPoint <= GetnPoints() )
        GetPoint( iPoint )->Draw( dc, rpn );
}
示例#10
0
void ActiveTrack::AddPointNow( bool do_add_point )
{
    wxDateTime now = wxDateTime::Now();

    if( m_prev_dist < 0.0005 )              // avoid zero length segs
        if( !do_add_point ) return;

    if( m_prev_time.IsValid() ) if( m_prev_time == now )                    // avoid zero time segs
        if( !do_add_point ) return;

    vector2D gpsPoint( gLon, gLat );

    // The dynamic interval algorithm will gather all track points in a queue,
    // and analyze the cross track errors for each point before actually adding
    // a point to the track.

    switch( trackPointState ) {
        case firstPoint: {
            TrackPoint *pTrackPoint = AddNewPoint( gpsPoint, now.ToUTC() );
            m_lastStoredTP = pTrackPoint;
            trackPointState = secondPoint;
            do_add_point = false;
            break;
        }
        case secondPoint: {
            vector2D pPoint( gLon, gLat );
            skipPoints.push_back( pPoint );
            skipTimes.push_back( now.ToUTC() );
            trackPointState = potentialPoint;
            break;
        }
        case potentialPoint: {
            if( gpsPoint == skipPoints[skipPoints.size()-1] ) break;

            unsigned int xteMaxIndex = 0;
            double xteMax = 0;

            // Scan points skipped so far and see if anyone has XTE over the threshold.
            for( unsigned int i=0; i<skipPoints.size(); i++ ) {
                double xte = GetXTE( m_lastStoredTP->m_lat, m_lastStoredTP->m_lon, gLat, gLon, skipPoints[i].lat, skipPoints[i].lon );
                if( xte > xteMax ) {
                    xteMax = xte;
                    xteMaxIndex = i;
                }
            }
            if( xteMax > m_allowedMaxXTE ) {
                TrackPoint *pTrackPoint = AddNewPoint( skipPoints[xteMaxIndex], skipTimes[xteMaxIndex] );
                pSelect->AddSelectableTrackSegment( m_lastStoredTP->m_lat, m_lastStoredTP->m_lon,
                        pTrackPoint->m_lat, pTrackPoint->m_lon,
                        m_lastStoredTP, pTrackPoint, this );

                m_prevFixedTP = m_fixedTP;
                m_fixedTP = m_removeTP;
                m_removeTP = m_lastStoredTP;
                m_lastStoredTP = pTrackPoint;
                for( unsigned int i=0; i<=xteMaxIndex; i++ ) {
                    skipPoints.pop_front();
                    skipTimes.pop_front();
                }

                // Now back up and see if we just made 3 points in a straight line and the middle one
                // (the next to last) point can possibly be eliminated. Here we reduce the allowed
                // XTE as a function of leg length. (Half the XTE for very short legs).
                if( GetnPoints() > 2 ) {
                    double dist = DistGreatCircle( m_fixedTP->m_lat, m_fixedTP->m_lon, m_lastStoredTP->m_lat, m_lastStoredTP->m_lon );
                    double xte = GetXTE( m_fixedTP, m_lastStoredTP, m_removeTP );
                    if( xte < m_allowedMaxXTE / wxMax(1.0, 2.0 - dist*2.0) ) {
                        TrackPoints.pop_back();
                        TrackPoints.pop_back();
                        TrackPoints.push_back( m_lastStoredTP );
                        pSelect->DeletePointSelectableTrackSegments( m_removeTP );
                        pSelect->AddSelectableTrackSegment( m_fixedTP->m_lat, m_fixedTP->m_lon,
                                m_lastStoredTP->m_lat, m_lastStoredTP->m_lon,
                                m_fixedTP, m_lastStoredTP, this );
                        delete m_removeTP;
                        m_removeTP = m_fixedTP;
                        m_fixedTP = m_prevFixedTP;
                    }
                }
            }

            skipPoints.push_back( gpsPoint );
            skipTimes.push_back( now.ToUTC() );
            break;
        }
    }

    // Check if this is the last point of the track.
    if( do_add_point ) {
        TrackPoint *pTrackPoint = AddNewPoint( gpsPoint, now.ToUTC() );
        pSelect->AddSelectableTrackSegment( m_lastStoredTP->m_lat, m_lastStoredTP->m_lon,
                pTrackPoint->m_lat, pTrackPoint->m_lon,
                m_lastStoredTP, pTrackPoint, this );
    }

    m_prev_time = now;
}