//--------------------------------------------------------------- IsoLine::IsoLine(double val, const GribRecord *rec_) { value = val; rec = rec_; W = rec->getNi(); H = rec->getNj(); //--------------------------------------------------------- // Génère la liste des segments. extractIsoLine(rec); if(trace.size() == 0) return; // Join the isoline segments into a nice list // Which is end-to-end continuous and unidirectional // Create a master wxList of the trace list std::list<Segment *>::iterator it; for (it=trace.begin(); it!=trace.end(); it++) { Segment *seg = *it; seg->bUsed = false; m_seglist.Append(*it); } // Isoline may be discontinuous.... // So build a list of continuous segments bool bdone = false; while(!bdone) { MySegList *ps = BuildContinuousSegment(); m_SegListList.Append(ps); MySegList::Node *node; Segment *seg; // recreate the master list, removing used segs node = m_seglist.GetFirst(); while(node) { seg = node->GetData(); if(seg->bUsed) { m_seglist.Erase(node); node = m_seglist.GetFirst(); } else node = node->GetNext(); } if(0 == m_seglist.GetCount()) bdone = true; } ///printf("create Isobar : press=%4.0f long=%d\n", pressure/100, trace.size()); }
//--------------------------------------------------------------- void IsoLine::drawIsoLine(GRIBOverlayFactory *pof, wxDC *dc, PlugIn_ViewPort *vp, bool bHiDef) { int nsegs = trace.size(); if(nsegs < 1) return; GetGlobalColor ( _T ( "UITX1" ), &isoLineColor ); #if wxUSE_GRAPHICS_CONTEXT wxGraphicsContext *pgc = NULL; #endif if(dc) { wxPen ppISO ( isoLineColor, 2 ); #if wxUSE_GRAPHICS_CONTEXT wxMemoryDC *pmdc; pmdc= wxDynamicCast(dc, wxMemoryDC); pgc = wxGraphicsContext::Create(*pmdc); pgc->SetPen(ppISO); #endif dc->SetPen(ppISO); } else { /* opengl */ #ifdef ocpnUSE_GL if(m_pixelMM > 0.2){ // pixel size large enough to render well // Enable anti-aliased lines, at best quality glEnable( GL_LINE_SMOOTH ); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glHint( GL_LINE_SMOOTH_HINT, GL_NICEST ); glLineWidth( 2 ); } else{ glLineWidth( 0.4/m_pixelMM); // set a target line width by MM } glColor4ub(isoLineColor.Red(), isoLineColor.Green(), isoLineColor.Blue(), 255/*isoLineColor.Alpha()*/); glBegin( GL_LINES ); #endif } std::list<Segment *>::iterator it; //--------------------------------------------------------- // Dessine les segments //--------------------------------------------------------- for (it=trace.begin(); it!=trace.end(); it++) { Segment *seg = *it; if(vp->m_projection_type == PI_PROJECTION_MERCATOR || vp->m_projection_type == PI_PROJECTION_EQUIRECTANGULAR) { /* skip segments that go the wrong way around the world */ double sx1 = seg->px1, sx2 = seg->px2; if(sx2 - sx1 > 180) sx2 -= 360; else if(sx1 - sx2 > 180) sx1 -= 360; if((sx1+180 < vp->clon && sx2+180 > vp->clon) || (sx1+180 > vp->clon && sx2+180 < vp->clon) || (sx1-180 < vp->clon && sx2-180 > vp->clon) || (sx1-180 > vp->clon && sx2-180 < vp->clon)) continue; } wxPoint ab; GetCanvasPixLL(vp, &ab, seg->py1, seg->px1); wxPoint cd; GetCanvasPixLL(vp, &cd, seg->py2, seg->px2); if(dc) { #if wxUSE_GRAPHICS_CONTEXT if(bHiDef && pgc) pgc->StrokeLine(ab.x, ab.y, cd.x, cd.y); else #endif dc->DrawLine(ab.x, ab.y, cd.x, cd.y); } else { /* opengl */ #ifdef ocpnUSE_GL glVertex2d(ab.x, ab.y); glVertex2d(cd.x, cd.y); #endif } } #if 0 int text_sx, text_sy; dc.GetTextExtent(_T("10000"), &text_sx, &text_sy); // double m = text_sy / 2; int label_size = text_sx; int label_space = 400; // double coef = .01; int len = label_space/4; // Allocate an array big enough wxPoint *pPoints = new wxPoint[nsegs+1]; MySegListList::Node *listnode; listnode = m_SegListList.GetFirst(); while(listnode) { MySegList *listsort = listnode->GetData(); // Fill in the array MySegList::Node *node; Segment *seg; node = listsort->GetFirst(); if(node) { seg = node->GetData(); // wxPoint ab = vp->GetMercatorPixFromLL(seg->py1, seg->px1); // wxPoint ab(0,0); wxPoint ab; GetCanvasPixLL(vp, &ab, seg->py1, seg->px1); pPoints[0] = ab; } int ip=1; while (node) { seg = node->GetData(); // wxPoint cd = vp->GetMercatorPixFromLL(seg->py2, seg->px2); // wxPoint cd(0,0); wxPoint cd; GetCanvasPixLL(vp, &cd, seg->py2, seg->px2); pPoints[ip++] = cd; node=node->GetNext(); } int np = listsort->GetCount() + 1; if(np > 1) { // Test code // dc.DrawLines(np, pPoints); GenerateSpline(np, pPoints); // Test Code // dc.DrawLines(&ocpn_wx_spline_point_list, 0, 0 ); bool bDrawing = true; wxPoint lstart; wxList::compatibility_iterator snode = ocpn_wx_spline_point_list.GetFirst(); wxPoint *point0 = (wxPoint *)snode->GetData(); snode=snode->GetNext(); while (snode) { wxPoint *point = (wxPoint *)snode->GetData(); ClipResult res = cohen_sutherland_line_clip_i ( &point0->x, &point0->y, &point->x, &point->y, 0, vp->pix_width, 0, vp->pix_height ); if ( res != Invisible ) { int dl = (int)sqrt( (double)((point0->x - point->x) * (point0->x - point->x)) +(double)((point0->y - point->y) * (point0->y - point->y))); if(bDrawing) { len += dl; if(len > label_space) { bDrawing = false; len = 0; lstart = *point; } } else { len += dl; if(len > label_size) { bDrawing = true; len = 0; } } } *point0 = *point; snode=snode->GetNext(); } ClearSplineList(); } listnode = listnode->GetNext(); // Next continuous chain } delete[] pPoints; #endif #if wxUSE_GRAPHICS_CONTEXT delete pgc; #endif if(!dc) /* opengl */ glEnd(); }
MySegList *IsoLine::BuildContinuousSegment(void) { MySegList::Node *node; Segment *seg; MySegList *ret_list = new MySegList; // Build a chain extending from the "2" end of the target segment // The joined list, side 2... MySegList segjoin2; // Add any first segment to the list node = m_seglist.GetFirst(); Segment *seg0 = node->GetData(); seg0->bUsed = true; segjoin2.Append(seg0); Segment *tseg = seg0; while(tseg) { bool badded = false; Segment *seg; node = m_seglist.GetFirst(); while (node) { seg = node->GetData(); if((!seg->bUsed) && (seg->py1 == tseg->py2) && (seg->px1 == tseg->px2)) // fits without reverse { seg->bUsed = true; segjoin2.Append(seg); badded = true; break; } else if((!seg->bUsed) && (seg->py2 == tseg->py2) && (seg->px2 == tseg->px2)) // fits, needs reverse { seg->bUsed = true; double a = seg->px2; seg->px2 = seg->px1; seg->px1 = a; double b = seg->py2; seg->py2 = seg->py1; seg->py1 = b; segjoin2.Append(seg); badded = true; break; } node = node->GetNext(); } if(badded == true) tseg = seg; else tseg = NULL; } // Build a chain extending from the "1" end of the target segment // The joined list, side 1... MySegList segjoin1; // Add the same first segment to the list node = m_seglist.GetFirst(); seg0 = node->GetData(); seg0->bUsed = true; segjoin1.Append(seg0); tseg = seg0; while(tseg) { bool badded = false; node = m_seglist.GetFirst(); while (node) { seg = node->GetData(); if((!seg->bUsed) && (seg->py2 == tseg->py1) && (seg->px2 == tseg->px1)) // fits without reverse { seg->bUsed = true; segjoin1.Append(seg); badded = true; break; } else if((!seg->bUsed) && (seg->py1 == tseg->py1) && (seg->px1 == tseg->px1)) // fits, needs reverse { seg->bUsed = true; double a = seg->px2; seg->px2 = seg->px1; seg->px1 = a; double b = seg->py2; seg->py2 = seg->py1; seg->py1 = b; segjoin1.Append(seg); badded = true; break; } node = node->GetNext(); } if(badded == true) tseg = seg; else tseg = NULL; } // Now have two lists... // Start with "1" side list, // starting from the end, and skipping the first segment int n1 = segjoin1.GetCount(); for(int i=n1 - 1 ; i > 0 ; i--) { node = segjoin1.Item( i ); seg = node->GetData(); ret_list->Append(seg); } // Now add the "2"side list int n2 = segjoin2.GetCount(); for(int i=0 ; i < n2 ; i++) { node = segjoin2.Item(i); seg = node->GetData(); ret_list->Append(seg); } // And there it is return ret_list; }
//--------------------------------------------------------------- IsoLine::IsoLine(double val, double coeff, double offset, const GribRecord *rec_) { if(wxGetDisplaySize().x > 0){ m_pixelMM = PlugInGetDisplaySizeMM() / wxGetDisplaySize().x; m_pixelMM = wxMax(.02, m_pixelMM); // protect against bad data } else m_pixelMM = 0.27; // semi-standard number... value = val/coeff-offset; rec = rec_; W = rec_->getNi(); H = rec_->getNj(); //--------------------------------------------------------- // Génère la liste des segments. extractIsoLine(rec_); value = val; if(trace.size() == 0) return; // Join the isoline segments into a nice list // Which is end-to-end continuous and unidirectional // Create a master wxList of the trace list std::list<Segment *>::iterator it; for (it=trace.begin(); it!=trace.end(); it++) { Segment *seg = *it; seg->bUsed = false; m_seglist.Append(*it); } // Isoline may be discontinuous.... // So build a list of continuous segments bool bdone = false; while(!bdone) { MySegList *ps = BuildContinuousSegment(); m_SegListList.Append(ps); MySegList::Node *node; Segment *seg; // recreate the master list, removing used segs node = m_seglist.GetFirst(); while(node) { seg = node->GetData(); if(seg->bUsed) { m_seglist.Erase(node); node = m_seglist.GetFirst(); } else node = node->GetNext(); } if(0 == m_seglist.GetCount()) bdone = true; } ///printf("create Isobar : press=%4.0f long=%d\n", pressure/100, trace.size()); }
//--------------------------------------------------------------- void IsoLine::drawIsoLine(GRIBOverlayFactory *pof, wxDC &dc, PlugIn_ViewPort *vp, bool bShowLabels, bool bHiDef) { int nsegs = trace.size(); if(nsegs < 1) return; GetGlobalColor ( _T ( "UITX1" ), &isoLineColor ); wxPen ppISO ( isoLineColor, 2 ); #if wxUSE_GRAPHICS_CONTEXT wxMemoryDC *pmdc; // pmdc = dynamic_cast<wxMemoryDC*>(&dc); pmdc= wxDynamicCast(&dc, wxMemoryDC); wxGraphicsContext *pgc = wxGraphicsContext::Create(*pmdc); pgc->SetPen(ppISO); #endif dc.SetPen(ppISO); std::list<Segment *>::iterator it; //--------------------------------------------------------- // Dessine les segments //--------------------------------------------------------- for (it=trace.begin(); it!=trace.end(); it++) { Segment *seg = *it; { // wxPoint ab = vp->GetMercatorPixFromLL(seg->py1, seg->px1); // wxPoint cd = vp->GetMercatorPixFromLL(seg->py2, seg->px2); wxPoint ab; GetCanvasPixLL(vp, &ab, seg->py1, seg->px1); wxPoint cd; GetCanvasPixLL(vp, &cd, seg->py2, seg->px2); /// ClipResult res = cohen_sutherland_line_clip_i ( &ab.x, &ab.y, &cd.x, &cd.y, /// 0, vp->pix_width, 0, vp->pix_height ); /// if ( res != Invisible ) { #if wxUSE_GRAPHICS_CONTEXT if(bHiDef && pgc) pgc->StrokeLine(ab.x, ab.y, cd.x, cd.y); else dc.DrawLine(ab.x, ab.y, cd.x, cd.y); #else dc.DrawLine(ab.x, ab.y, cd.x, cd.y); #endif } } } //#endif int text_sx, text_sy; dc.GetTextExtent(_T("10000"), &text_sx, &text_sy); // double m = text_sy / 2; int label_size = text_sx; int label_space = 400; // double coef = .01; int len = label_space/4; // Allocate an array big enough wxPoint *pPoints = new wxPoint[nsegs+1]; MySegListList::Node *listnode; listnode = m_SegListList.GetFirst(); while(listnode) { MySegList *listsort = listnode->GetData(); // Fill in the array MySegList::Node *node; Segment *seg; node = listsort->GetFirst(); if(node) { seg = node->GetData(); // wxPoint ab = vp->GetMercatorPixFromLL(seg->py1, seg->px1); // wxPoint ab(0,0); wxPoint ab; GetCanvasPixLL(vp, &ab, seg->py1, seg->px1); pPoints[0] = ab; } int ip=1; while (node) { seg = node->GetData(); // wxPoint cd = vp->GetMercatorPixFromLL(seg->py2, seg->px2); // wxPoint cd(0,0); wxPoint cd; GetCanvasPixLL(vp, &cd, seg->py2, seg->px2); pPoints[ip++] = cd; node=node->GetNext(); } int np = listsort->GetCount() + 1; if(np > 1) { // Test code // dc.DrawLines(np, pPoints); GenerateSpline(np, pPoints); // Test Code // dc.DrawLines(&ocpn_wx_spline_point_list, 0, 0 ); bool bDrawing = true; wxPoint lstart; wxList::compatibility_iterator snode = ocpn_wx_spline_point_list.GetFirst(); wxPoint *point0 = (wxPoint *)snode->GetData(); snode=snode->GetNext(); while (snode) { wxPoint *point = (wxPoint *)snode->GetData(); ClipResult res = cohen_sutherland_line_clip_i ( &point0->x, &point0->y, &point->x, &point->y, 0, vp->pix_width, 0, vp->pix_height ); if ( res != Invisible ) { int dl = (int)sqrt( (double)((point0->x - point->x) * (point0->x - point->x)) +(double)((point0->y - point->y) * (point0->y - point->y))); if(bDrawing) { len += dl; if(len > label_space) { bDrawing = false; len = 0; lstart = *point; } } else { len += dl; if(len > label_size) { bDrawing = true; len = 0; #if 0 if(bShowLabels) { double label_angle = atan2((double)(lstart.y - point->y), (double)(point->x - lstart.x)) * 180. / PI; wxString label; label.Printf(_T("%d"), (int)(value*coef+0.5)); double xs = lstart.x - (m * sin(label_angle * PI / 180.)); double ys = lstart.y - (m * cos(label_angle * PI / 180.)); dc.DrawRotatedText(label, (int)xs, (int)ys, label_angle); } #endif } } #if 0 // if(bDrawing || !bShowLabels) { if(bHiDef) dc.StrokeLine(point0->x, point0->y, point->x, point->y); else dc.DrawLine(point0->x, point0->y, point->x, point->y); } #endif } *point0 = *point; snode=snode->GetNext(); } ClearSplineList(); } listnode = listnode->GetNext(); // Next continuous chain } delete[] pPoints; #if wxUSE_GRAPHICS_CONTEXT delete pgc; #endif }