// read map image data ------------------------------------------------------ void __fastcall TPlot::ReadMapData(AnsiString file) { TJPEGImage *image=new TJPEGImage; AnsiString s; trace(3,"ReadMapData\n"); try { image->LoadFromFile(file); } catch (Exception &exception) { ShowMsg(s.sprintf("map file read error: %s",file)); ShowLegend(NULL); return; } MapImage->Assign(image); MapImageFile=file; MapSize[0]=MapImage->Width; MapSize[1]=MapImage->Height; delete image; ReadMapTag(file); BtnShowMap->Down=true; MapAreaDialog->UpdateField(); UpdatePlot(); }
// read solution status ----------------------------------------------------- void __fastcall TPlot::ReadSolStat(TStrings *files, int sel) { AnsiString s; gtime_t ts,te; double tint; int i,n=0; char *paths[MAXNFILE],id[32]; trace(3,"ReadSolStat\n"); freesolstatbuf(SolStat+sel); for (i=0;i<MAXNFILE;i++) paths[i]=path_str[i]; TimeSpan(&ts,&te,&tint); for (i=0;i<files->Count&&n<MAXNFILE;i++) { strcpy(paths[n++],U2A(files->Strings[i]).c_str()); } ShowMsg(s.sprintf("reading %s...",paths[0])); ShowLegend(NULL); readsolstatt(paths,n,ts,te,tint,SolStat+sel); UpdateSatList(); }
// read elevation mask data ------------------------------------------------- void __fastcall TPlot::ReadElMaskData(AnsiString file) { AnsiString s; FILE *fp; double az0=0.0,el0=0.0,az1,el1; int i,j; char buff[256]; trace(3,"ReadElMaskData\n"); for (i=0;i<=360;i++) ElMaskData[i]=0.0; if (!(fp=fopen(file.c_str(),"r"))) { ShowMsg(s.sprintf("no el mask data: %s...",file.c_str())); ShowLegend(NULL); return; } while (fgets(buff,sizeof(buff),fp)) { if (buff[0]=='%'||sscanf(buff,"%lf %lf",&az1,&el1)<2) continue; if (az0<az1&&az1<=360.0&&0.0<=el1&&el1<=90.0) { for (j=(int)az0;j<=(int)az1;j++) ElMaskData[j]=el0*D2R; } az0=az1; el0=el1; } fclose(fp); UpdatePlot(); }
// connect to external sources ---------------------------------------------- void __fastcall TPlot::Connect(void) { AnsiString s; char *cmd,*path,buff[MAXSTRPATH],*name[2]={"",""},*p; int i,mode=STR_MODE_R; trace(3,"Connect\n"); if (ConnectState) return; for (i=0;i<2;i++) { if (RtStream[i]==STR_NONE ) continue; else if (RtStream[i]==STR_SERIAL ) path=StrPaths[i][0].c_str(); else if (RtStream[i]==STR_FILE ) path=StrPaths[i][2].c_str(); else if (RtStream[i]<=STR_NTRIPCLI) path=StrPaths[i][1].c_str(); else continue; if (RtStream[i]==STR_FILE||!SolData[i].cyclic||SolData[i].nmax!=RtBuffSize+1) { Clear(); initsolbuf(SolData+i,1,RtBuffSize+1); } if (RtStream[i]==STR_SERIAL) mode|=STR_MODE_W; strcpy(buff,path); if ((p=strstr(buff,"::"))) *p='\0'; if ((p=strstr(buff,"/:"))) *p='\0'; if ((p=strstr(buff,"@"))) name[i]=p+1; else name[i]=buff; if (!stropen(Stream+i,RtStream[i],mode,path)) { ShowMsg(s.sprintf("connect error: %s",name)); ShowLegend(NULL); trace(1,"stream open error: ch=%d type=%d path=%s\n",i+1,RtStream[i],path); continue; } strsettimeout(Stream+i,RtTimeOutTime,RtReConnTime); if (StrCmdEna[i][0]) { cmd=StrCmds[i][0].c_str(); strwrite(Stream+i,(unsigned char *)cmd,strlen(cmd)); } ConnectState=1; } if (!ConnectState) return; if (Title!="") Caption=Title; else Caption=s.sprintf("CONNECT %s %s",name[0],name[1]); BtnConnect->Down=true; BtnSol1 ->Down=*name[0]; BtnSol2 ->Down=*name[1]; BtnSol12 ->Down=false; BtnShowTrack->Down=true; BtnFixHoriz->Down=true; UpdateEnable(); UpdateTime(); UpdatePlot(); }
// read observation data ---------------------------------------------------- void __fastcall TPlot::ReadObs(TStrings *files) { obs_t obs={0}; nav_t nav={0}; sta_t sta={0}; AnsiString s; char file[1024]; int i,nobs; trace(3,"ReadObs\n"); if (files->Count<=0) return; ReadWaitStart(); ShowLegend(NULL); if ((nobs=ReadObsRnx(files,&obs,&nav,&sta))<=0) { ReadWaitEnd(); return; } ClearObs(); Obs=obs; Nav=nav; Sta=sta; SimObs=0; UpdateObs(nobs); UpdateMp(); if (ObsFiles!=files) { ObsFiles->Assign(files); } NavFiles->Clear(); strcpy(file,U2A(files->Strings[0]).c_str()); Caption=s.sprintf("%s%s",file,files->Count>1?"...":""); BtnSol1->Down=true; time2gpst(Obs.data[0].time,&Week); SolIndex[0]=SolIndex[1]=ObsIndex=0; if (PlotType<PLOT_OBS||PLOT_DOP<PlotType) { UpdateType(PLOT_OBS); } else { UpdatePlotType(); } FitTime(); ReadWaitEnd(); UpdateObsType(); UpdateTime(); UpdatePlot(); }
// update time-information for observation-data plot ------------------------ void __fastcall TPlot::UpdateTimeObs(void) { AnsiString msgs1[]={" OBS=L1/2 "," L1 "," L2 "," L1/2/5 "," L1/5 ",""," L5 "}; AnsiString msgs2[]={" SNR=...45.","..40.","..35.","..30.","..25 ",""," <25 "}; AnsiString msgs3[]={" SYS=GPS ","GLO ","GAL ","QZS ","BDS ","SBS ",""}; AnsiString msgs4[]={" MP=..0.6","..0.3","..0.0..","-0.3..","-0.6..","",""}; AnsiString msg,msgs[8],s; double azel[MAXOBS*2],dop[4]={0}; int i,ns=0,no=0,ind=ObsIndex; char tstr[64]; trace(3,"UpdateTimeObs\n"); if (BtnSol1->Down&&0<=ind&&ind<NObs) { for (i=IndexObs[ind];i<Obs.n&&i<IndexObs[ind+1];i++,no++) { if (SatMask[Obs.data[i].sat-1]||!SatSel[Obs.data[i].sat-1]) continue; if (El[i]<ElMask*D2R) continue; if (ElMaskP&&El[i]<ElMaskData[(int)(Az[i]*R2D+0.5)]) continue; azel[ ns*2]=Az[i]; azel[1+ns*2]=El[i]; ns++; } } if (ns>=0) { dops(ns,azel,ElMask*D2R,dop); TimeStr(Obs.data[IndexObs[ind]].time,3,1,tstr); msg.sprintf("[1]%s : N=%d ",tstr,no); if (PlotType==PLOT_DOP) { msgs[0].sprintf("NSAT=%d",ns); msgs[1].sprintf(" GDOP=%.1f",dop[0]); msgs[2].sprintf(" PDOP=%.1f",dop[1]); msgs[3].sprintf(" HDOP=%.1f",dop[2]); msgs[4].sprintf(" VDOP=%.1f",dop[3]); } else if (PlotType<=PLOT_SKY&&ObsType->ItemIndex==0) { msg+=s.sprintf("NSAT=%d ",ns); for (i=0;i<7;i++) msgs[i]=SimObs?msgs3[i]:msgs1[i]; } else if (PlotType==PLOT_MPS) { msg+=s.sprintf("NSAT=%d ",ns); for (i=0;i<7;i++) msgs[i]=msgs4[i]; } else { msg+=s.sprintf("NSAT=%d ",ns); for (i=0;i<7;i++) msgs[i]=SimObs?msgs3[i]:msgs2[i]; } } ShowMsg(msg); ShowLegend(msgs); }
// update time-information for solution plot -------------------------------- void __fastcall TPlot::UpdateTimeSol(void) { const char *unit[]={"m","m/s","m/s2"},*u; const char *sol[]={"","FIX","FLOAT","SBAS","DGPS","Single","PPP"}; AnsiString msg,msgs[8],s; sol_t *data; double xyz[3],pos[3],r,az,el; int sel=BtnSol1->Down||!BtnSol2->Down?0:1,ind=SolIndex[sel]; char tstr[64]; trace(3,"UpdateTimeSol\n"); if ((BtnSol1->Down||BtnSol2->Down||BtnSol12->Down)&& (data=getsol(SolData+sel,ind))) { if (!ConnectState) msg.sprintf("[%d]",sel+1); else msg="[R]"; TimeStr(data->time,2,1,tstr); msg+=tstr; msg+=" : "; if (PLOT_SOLP<=PlotType&&PlotType<=PLOT_SOLA) { PosToXyz(data->time,data->rr,data->type,xyz); u=unit[PlotType-PLOT_SOLP]; msg+=s.sprintf("E=%7.4f%s N=%7.4f%s U=%7.4f%s Q=", xyz[0],u,xyz[1],u,xyz[2],u); } else if (PlotType==PLOT_NSAT) { msg+=s.sprintf("NS=%d AGE=%.1f RATIO=%.1f Q=",data->ns,data->age, data->ratio); } else if (!data->type) { ecef2pos(data->rr,pos); msg+=LatLonStr(pos,9)+s.sprintf(" %9.4fm Q=",pos[2]); } else { r=norm(data->rr,3); az=norm(data->rr,2)<=1E-12?0.0:atan2(data->rr[0],data->rr[1])*R2D; el=r<=1E-12?0.0:asin(data->rr[2]/r)*R2D; msg+=s.sprintf("B=%.3fm D=%6.2f" CHARDEG " %5.2f" CHARDEG " Q=", r,az<0.0?az+360.0:az,el); } if (1<=data->stat&&data->stat<=6) { msgs[data->stat-1]=s.sprintf("%d:%s",data->stat,sol[data->stat]); } } ShowMsg(msg); ShowLegend(msgs); }
// update statistics-information for observation-data plot ------------------ void __fastcall TPlot::UpdateInfoObs(void) { AnsiString msgs0[]={" NSAT"," GDOP"," PDOP"," HDOP"," VDOP","",""}; AnsiString msgs1[]={" OBS=L1/2 "," L1 "," L2 "," L1/2/5 "," L1/5 ",""," L5 "}; AnsiString msgs2[]={" SNR=...45.","..40.","..35.","..30.","..25 ",""," <25 "}; AnsiString msgs3[]={" SYS=GPS ","GLO ","GAL ","QZS ","BDS ","SBS ",""}; AnsiString msgs4[]={" MP=..0.6","..0.3","..0.0..","-0.3..","-0.6..","",""}; AnsiString msg,msgs[8]; gtime_t ts={0},te={0},t,tp={0}; int i,n=0,ne=0; char s1[64],s2[64]; trace(3,"UpdateInfoObs:\n"); if (BtnSol1->Down) { for (i=0;i<Obs.n;i++) { t=Obs.data[i].time; if (ts.time==0) ts=t; te=t; if (tp.time==0||timediff(t,tp)>TTOL) ne++; n++; tp=t; } } if (n>0) { TimeStr(ts,0,0,s1); TimeStr(te,0,1,s2); msg.sprintf("[1]%s-%s : EP=%d N=%d",s1,s2+(TimeLabel?5:0),ne,n); for (i=0;i<7;i++) { if (PlotType==PLOT_DOP) { msgs[i]=msgs0[i]; } else if (PlotType<=PLOT_SKY&&ObsType->ItemIndex==0) { msgs[i]=SimObs?msgs3[i]:msgs1[i]; } else if (PlotType==PLOT_MPS) { msgs[i]=msgs4[i]; } else { msgs[i]=SimObs?msgs3[i]:msgs2[i]; } } } ShowMsg(msg); ShowLegend(msgs); }
// read navigation data ----------------------------------------------------- void __fastcall TPlot::ReadNav(TStrings *files) { AnsiString s; gtime_t ts,te; double tint; char navfile[1024],*opt=RnxOpts.c_str(); int i; trace(3,"ReadNav\n"); if (files->Count<=0) return; ReadWaitStart(); ShowLegend(NULL); TimeSpan(&ts,&te,&tint); freenav(&Nav,0xFF); ShowMsg("reading nav data..."); Application->ProcessMessages(); for (i=0;i<files->Count;i++) { strcpy(navfile,U2A(files->Strings[i]).c_str()); readrnxt(navfile,1,ts,te,tint,opt,NULL,&Nav,NULL); } uniqnav(&Nav); if (Nav.n<=0&&Nav.ng<=0&&Nav.ns<=0) { ShowMsg(s.sprintf("no nav message: %s...",files->Strings[0].c_str())); ReadWaitEnd(); return; } if (NavFiles!=files) { NavFiles->Assign(files); } UpdateObs(NObs); UpdateMp(); ReadWaitEnd(); UpdatePlot(); }
// Helper method to get the layout properties from the PrintLayout xml resource. void MgPrintLayout::GetLayoutPropertiesFromXml(MgXmlUtil* pXmlUtil) { CHECKNULL(pXmlUtil, L"MgPrintLayout.GetLayoutPropertiesFromXml()"); MG_TRY() // Retrieve values from the xml document DOMElement* root = pXmlUtil->GetRootNode(); CHECKNULL(root, L"MgPrintLayout.GetLayoutProperitesFromXml()"); // DOMElement* pageProperties = pXmlUtil->GetElementNode(root, "PageProperties"); DOMElement* backgroundColor = pXmlUtil->GetElementNode(root, "BackgroundColor"); wstring szRed; pXmlUtil->GetElementValue(backgroundColor, "Red", szRed); wstring szGreen; pXmlUtil->GetElementValue(backgroundColor, "Green", szGreen); wstring szBlue; pXmlUtil->GetElementValue(backgroundColor, "Blue", szBlue); DOMElement* layoutProperties = pXmlUtil->GetElementNode(root, "LayoutProperties"); wstring szShowTitle; pXmlUtil->GetElementValue(layoutProperties, "ShowTitle", szShowTitle, false); wstring szShowLegend; pXmlUtil->GetElementValue(layoutProperties, "ShowLegend", szShowLegend, false); wstring szShowScalebar; pXmlUtil->GetElementValue(layoutProperties, "ShowScaleBar", szShowScalebar, false); wstring szShowNorthArrow; pXmlUtil->GetElementValue(layoutProperties, "ShowNorthArrow", szShowNorthArrow, false); wstring szShowUrl; pXmlUtil->GetElementValue(layoutProperties, "ShowURL", szShowUrl, false); wstring szShowDateTime; pXmlUtil->GetElementValue(layoutProperties, "ShowDateTime", szShowDateTime, false); wstring szShowCustomLogos; pXmlUtil->GetElementValue(layoutProperties, "ShowCustomLogos", szShowCustomLogos, false); wstring szShowCustomText; pXmlUtil->GetElementValue(layoutProperties, "ShowCustomText", szShowCustomText, false); DOMNode* customLogosNode = pXmlUtil->GetElementNode(root, "CustomLogos", false); if (NULL != customLogosNode) { DOMNodeList* customLogosNodeList = pXmlUtil->GetNodeList(customLogosNode, "Logo"); if (NULL != customLogosNodeList) { for (XMLSize_t i = 0; i < customLogosNodeList->getLength(); ++i) { MgCustomLogoInfo logoInfo; wstring positionX; wstring positionY; wstring positionUnits; wstring resId; wstring name; wstring sizeWidth; wstring sizeHeight; wstring sizeUnits; wstring rotation; DOMNode* logoNode = customLogosNodeList->item(i); DOMNode* logoPositionNode = pXmlUtil->GetElementNode(logoNode, "Position", false); if (NULL != logoPositionNode) { pXmlUtil->GetElementValue(logoPositionNode, "Left", positionX, false); pXmlUtil->GetElementValue(logoPositionNode, "Bottom", positionY, false); pXmlUtil->GetElementValue(logoPositionNode, "Units", positionUnits, false); if (!positionUnits.empty() && positionUnits != L"meters" && positionUnits != L"inches" && positionUnits != L"percent") { // invalid print layout position units throw new MgInvalidPrintLayoutPositionUnitsException(L"MgPrintLayout.GetLayoutPropertiesFromXml", __LINE__, __WFILE__, NULL, L"", NULL); } } pXmlUtil->GetElementValue(logoNode, "ResourceId", resId, false); pXmlUtil->GetElementValue(logoNode, "Name", name, false); DOMNode* logoSizeNode = pXmlUtil->GetElementNode(logoNode, "Size", false); if (NULL != logoSizeNode) { pXmlUtil->GetElementValue(logoSizeNode, "Width", sizeWidth, false); pXmlUtil->GetElementValue(logoSizeNode, "Height", sizeHeight, false); pXmlUtil->GetElementValue(logoSizeNode, "Units", sizeUnits, false); if (!sizeUnits.empty() && sizeUnits != L"inches" && sizeUnits != L"meters") { // invalid print layout size units throw new MgInvalidPrintLayoutSizeUnitsException(L"MgPrintLayout.GetLayoutPropertiesFromXml", __LINE__, __WFILE__, NULL, L"", NULL); } } pXmlUtil->GetElementValue(logoNode, "Rotation", rotation, false); logoInfo.SetX( MgUtil::StringToDouble(positionX) ); logoInfo.SetY( MgUtil::StringToDouble(positionY) ); logoInfo.SetPositionUnits( positionUnits ); logoInfo.SetResourceId( resId ); logoInfo.SetName( name ); logoInfo.SetWidth( MgUtil::StringToDouble(sizeWidth) ); logoInfo.SetHeight( MgUtil::StringToDouble(sizeHeight) ); logoInfo.SetSizeUnits( sizeUnits ); logoInfo.SetRotation( MgUtil::StringToDouble(rotation) ); CustomLogos().push_back(logoInfo); } } } DOMNode* customTextNode = pXmlUtil->GetElementNode(root, "CustomText", false); if (NULL != customTextNode) { DOMNodeList* customTextNodeList = pXmlUtil->GetNodeList(customTextNode, "Text"); if (NULL != customTextNodeList) { for (XMLSize_t i = 0; i < customTextNodeList->getLength(); ++i) { MgCustomTextInfo textInfo; wstring positionX; wstring positionY; wstring positionUnits; wstring value; wstring fontName; wstring fontHeight; wstring fontSizeUnits; DOMNode* textNode = customTextNodeList->item(i); DOMNode* textPositionNode = pXmlUtil->GetElementNode(textNode, "Position", false); if (NULL != textPositionNode) { pXmlUtil->GetElementValue(textPositionNode, "Left", positionX, false); pXmlUtil->GetElementValue(textPositionNode, "Bottom", positionY, false); pXmlUtil->GetElementValue(textPositionNode, "Units", positionUnits, false); if (!positionUnits.empty() && positionUnits != L"percent" && positionUnits != L"meters" && positionUnits != L"inches") { // invalid print layout position units throw new MgInvalidPrintLayoutPositionUnitsException(L"MgPrintLayout.GetLayoutPropertiesFromXml", __LINE__, __WFILE__, NULL, L"", NULL); } } DOMNode* fontNode = pXmlUtil->GetElementNode(textNode, "Font", false); if (NULL != fontNode) { pXmlUtil->GetElementValue(fontNode, "Name", fontName, false); pXmlUtil->GetElementValue(fontNode, "Height", fontHeight, false); pXmlUtil->GetElementValue(fontNode, "Units", fontSizeUnits, false); if (!fontSizeUnits.empty() && fontSizeUnits != L"points" && fontSizeUnits != L"meters" && fontSizeUnits != L"inches") { // invalid print layout font size units throw new MgInvalidPrintLayoutFontSizeUnitsException(L"MgPrintLayout.GetLayoutPropertiesFromXml", __LINE__, __WFILE__, NULL, L"", NULL); } } pXmlUtil->GetElementValue(textNode, "Value", value, false); textInfo.SetX( MgUtil::StringToDouble( positionX ) ); textInfo.SetY( MgUtil::StringToDouble( positionY ) ); textInfo.SetPositionUnits( positionUnits ); textInfo.SetValue( value ); textInfo.SetFontName( fontName ); textInfo.SetFontHeight( MgUtil::StringToDouble( fontHeight ) ); textInfo.SetSizeUnits( fontSizeUnits ); CustomText().push_back(textInfo); } } } // Set MgPrintLayout values INT32 nRed = MgUtil::StringToInt32( szRed ); INT32 nGreen = MgUtil::StringToInt32( szGreen ); INT32 nBlue = MgUtil::StringToInt32( szBlue ); m_bgColor = new MgColor(nRed, nGreen, nBlue, 255); ShowTitle() = MgUtil::StringToBoolean( szShowTitle ); ShowLegend() = MgUtil::StringToBoolean( szShowLegend ); ShowScalebar() = MgUtil::StringToBoolean( szShowScalebar ); ShowNorthArrow() = MgUtil::StringToBoolean( szShowNorthArrow ); ShowUrl() = MgUtil::StringToBoolean( szShowUrl ); ShowDateTime() = MgUtil::StringToBoolean( szShowDateTime ); ShowCustomLogos() = MgUtil::StringToBoolean( szShowCustomLogos ); ShowCustomText() = MgUtil::StringToBoolean( szShowCustomText ); MG_CATCH_AND_THROW(L"MgPrintLayout.GetLayoutPropertiesFromXml") }
// update statistics-information for solution plot -------------------------- void __fastcall TPlot::UpdateInfoSol(void) { AnsiString msg,msgs[8],s; TIMEPOS *pos=NULL,*pos1,*pos2; sol_t *data; gtime_t ts={0},te={0}; double r[3],b,bl[2]={1E9,0.0}; int i,j,n=0,nq[8]={0},sel=BtnSol1->Down||!BtnSol2->Down?0:1; char s1[64],s2[64]; trace(3,"UpdateInfoSol:\n"); if (BtnSol1->Down||BtnSol2->Down) { pos=SolToPos(SolData+sel,-1,0,0); } else if (BtnSol12->Down) { pos1=SolToPos(SolData ,-1,0,0); pos2=SolToPos(SolData+1,-1,0,0); pos=pos1->diff(pos2,0); delete pos1; delete pos2; } if (pos) { for (i=0;i<pos->n;i++) { if (ts.time==0) ts=pos->t[i]; te=pos->t[i]; nq[pos->q[i]]++; n++; } delete pos; } for (i=0;data=getsol(SolData+sel,i);i++) { if (data->type) { b=norm(data->rr,3); } else if (norm(SolData[sel].rb,3)>0.0) { for (j=0;j<3;j++) r[j]=data->rr[j]-SolData[sel].rb[j]; b=norm(r,3); } else b=0.0; if (b<bl[0]) bl[0]=b; if (b>bl[1]) bl[1]=b; } if (n>0) { if (!ConnectState) msg.sprintf("[%d]",sel+1); else msg="[R]"; TimeStr(ts,0,0,s1); TimeStr(te,0,1,s2); msg+=s.sprintf("%s-%s : N=%d",s1,s2+(TimeLabel?5:0),n); if (bl[0]+100.0<bl[1]) { msg+=s.sprintf(" B=%.1f-%.1fkm",bl[0]/1E3,bl[1]/1E3); } else { msg+=s.sprintf(" B=%.1fkm",bl[0]/1E3); } msg+=" Q="; for (i=1;i<=6;i++) { if (nq[i]<=0) continue; msgs[i-1].sprintf("%d:%d(%.1f%%) ",i,nq[i],(double)nq[i]/n*100.0); } } ShowMsg(msg); ShowLegend(msgs); }
// read solutions ----------------------------------------------------------- void __fastcall TPlot::ReadSol(TStrings *files, int sel) { solbuf_t sol={0}; AnsiString s; gtime_t ts,te; double tint; int i,n=0; char *paths[MAXNFILE]={""}; trace(3,"ReadSol: sel=%d\n",sel); if (files->Count<=0) return; ReadWaitStart(); for (i=0;i<files->Count&&n<MAXNFILE;i++) { paths[n++]=files->Strings[i].c_str(); } TimeSpan(&ts,&te,&tint); ShowMsg(s.sprintf("reading %s...",paths[0])); ShowLegend(NULL); if (!readsolt(paths,n,ts,te,tint,0,&sol)) { ShowMsg(s.sprintf("no solution data : %s...",paths[0])); ShowLegend(NULL); ReadWaitEnd(); return; } freesolbuf(SolData+sel); SolData[sel]=sol; if (SolFiles[sel]!=files) { SolFiles[sel]->Assign(files); } Caption=""; ReadSolStat(files,sel); for (i=0;i<2;i++) { if (SolFiles[i]->Count==0) continue; Caption=Caption+SolFiles[i]->Strings[0]+(SolFiles[i]->Count>1?"... ":" "); } BtnSol12->Down=False; if (sel==0) BtnSol1->Down=true; else BtnSol2->Down=true; if (sel==0||SolData[0].n<=0) { time2gpst(SolData[sel].data[0].time,&Week); UpdateOrigin(); } SolIndex[0]=SolIndex[1]=ObsIndex=0; if (PlotType>PLOT_NSAT) { UpdateType(PLOT_TRK); } else { UpdatePlotType(); } FitTime(); if (AutoScale&&PlotType<=PLOT_SOLA) { FitRange(1); } else { SetRange(1,YRange); } UpdateTime(); UpdatePlot(); ReadWaitEnd(); }
// update observation data index, azimuth/elevation, satellite list --------- void __fastcall TPlot::UpdateObs(int nobs) { AnsiString s; prcopt_t opt=prcopt_default; gtime_t time; sol_t sol={0}; double pos[3],rr[3],e[3],azel[MAXOBS*2]={0},rs[6],dts[2],var; int i,j,k,svh,per,per_=-1; char msg[128]; trace(3,"UpdateObs\n"); delete [] IndexObs; IndexObs=NULL; delete [] Az; Az=NULL; delete [] El; El=NULL; NObs=0; if (nobs<=0) return; IndexObs=new int[nobs]; Az=new double[Obs.n]; El=new double[Obs.n]; opt.err[0]=900.0; ReadWaitStart(); ShowLegend(NULL); for (i=0;i<Obs.n;i=j) { time=Obs.data[i].time; for (j=i;j<Obs.n;j++) { if (timediff(Obs.data[j].time,time)>TTOL) break; } IndexObs[NObs++]=i; if (Nav.n<=0&&Nav.ng<=0&&Nav.ns<=0) { for (k=0;k<j-i;k++) Az[i+k]=El[i+k]=0.0; continue; } if (RcvPos==0) { pntpos(Obs.data+i,j-i,&Nav,&opt,&sol,azel,NULL,msg); } else { if (RcvPos==1) { // lat/lon/height for (k=0;k<3;k++) pos[k]=OOPos[k]; pos2ecef(pos,rr); } else { // rinex header position for (k=0;k<3;k++) rr[k]=Sta.pos[k]; ecef2pos(rr,pos); } for (k=0;k<j-i;k++) { azel[k*2]=azel[1+k*2]=0.0; if (!satpos(time,time,Obs.data[i+k].sat,EPHOPT_BRDC,&Nav,rs,dts, &var,&svh)) continue; if (geodist(rs,rr,e)>0.0) satazel(pos,e,azel+k*2); } } for (k=0;k<j-i;k++) { Az[i+k]=azel[ k*2]; El[i+k]=azel[1+k*2]; if (Az[i+k]<0.0) Az[i+k]+=2.0*PI; } per=(i+1)*100/Obs.n; if (per!=per_) { ShowMsg(s.sprintf("updating azimuth/elevation... (%d%%)",(per_=per))); Application->ProcessMessages(); } } IndexObs[NObs]=Obs.n; UpdateSatList(); ReadWaitEnd(); }
// update Multipath ------------------------------------------------------------ void __fastcall TPlot::UpdateMp(void) { AnsiString s; obsd_t *data; double lam1,lam2,I,C,B; int i,j,k,f1,f2,sat,sys,per,per_=-1,n; trace(3,"UpdateMp\n"); for (i=0;i<NFREQ+NEXOBS;i++) { delete [] Mp[i]; Mp[i]=NULL; } if (Obs.n<=0) return; for (i=0;i<NFREQ+NEXOBS;i++) { Mp[i]=new double[Obs.n]; } ReadWaitStart(); ShowLegend(NULL); for (i=0;i<Obs.n;i++) { data=Obs.data+i; sys=satsys(data->sat,NULL); for (j=0;j<NFREQ+NEXOBS;j++) { Mp[j][i]=0.0; code2obs(data->code[j],&f1); if (sys==SYS_CMP) { if (f1==5) f1=2; /* B2 */ else if (f1==4) f1=3; /* B3 */ } if (sys==SYS_GAL) f2=f1==1?3:1; /* E1/E5a */ else if (sys==SYS_SBS) f2=f1==1?3:1; /* L1/L5 */ else if (sys==SYS_CMP) f2=f1==1?2:1; /* B1/B2 */ else f2=f1==1?2:1; /* L1/L2 */ lam1=satwavelen(data->sat,f1-1,&Nav); lam2=satwavelen(data->sat,f2-1,&Nav); if (lam1==0.0||lam2==0.0) continue; if (data->P[j]!=0.0&&data->L[j]!=0.0&&data->L[f2-1]) { C=SQR(lam1)/(SQR(lam1)-SQR(lam2)); I=lam1*data->L[j]-lam2*data->L[f2-1]; Mp[j][i]=data->P[j]-lam1*data->L[j]+2.0*C*I; } } } for (sat=1;sat<=MAXSAT;sat++) for (i=0;i<NFREQ+NEXOBS;i++) { sys=satsys(sat,NULL); for (j=k=n=0,B=0.0;j<Obs.n;j++) { if (Obs.data[j].sat!=sat) continue; code2obs(Obs.data[j].code[i],&f1); if (sys==SYS_CMP) { if (f1==5) f1=2; /* B2 */ else if (f1==4) f1=3; /* B3 */ } if (sys==SYS_GAL) f2=f1==1?3:1; else if (sys==SYS_CMP) f2=f1==1?2:1; else f2=f1==1?2:1; if ((Obs.data[j].LLI[i]&1)||(Obs.data[j].LLI[f2-1]&1)|| fabs(Mp[i][j]-B)>THRES_SLIP) { for (;k<j;k++) if (Obs.data[k].sat==sat) Mp[i][k]-=B; B=Mp[i][j]; n=1; k=j; } else { if (n==0) k=j; B+=(Mp[i][j]-B)/++n; } } if (n>0) { for (;k<j;k++) if (Obs.data[k].sat==sat) Mp[i][k]-=B; } per=sat*100/MAXSAT; if (per!=per_) { ShowMsg(s.sprintf("updating multipath... (%d%%)",(per_=per))); Application->ProcessMessages(); } } ReadWaitEnd(); }
// generate visibility data ---------------------------------------------------- void __fastcall TPlot::GenVisData(void) { gtime_t time,ts,te; obsd_t data={{0}}; sta_t sta={0}; double tint,r,pos[3],rr[3],rs[6],e[3],azel[2]; int i,j,nobs=0; char name[16]; trace(3,"GenVisData\n"); ClearObs(); SimObs=1; ts=TimeStart; te=TimeEnd; tint=TimeInt; matcpy(pos,OOPos,3,1); pos2ecef(pos,rr); ReadWaitStart(); ShowLegend(NULL); ShowMsg("generating satellite visibility..."); Application->ProcessMessages(); for (time=ts;timediff(time,te)<=0.0;time=timeadd(time,tint)) { for (i=0;i<MAXSAT;i++) { satno2id(i+1,name); if (!tle_pos(time,name,"","",&TLEData,NULL,rs)) continue; if ((r=geodist(rs,rr,e))<=0.0) continue; if (satazel(pos,e,azel)<=0.0) continue; if (Obs.n>=Obs.nmax) { Obs.nmax=Obs.nmax<=0?4096:Obs.nmax*2; Obs.data=(obsd_t *)realloc(Obs.data,sizeof(obsd_t)*Obs.nmax); if (!Obs.data) { Obs.n=Obs.nmax=0; break; } } data.time=time; data.sat=i+1; for (j=0;j<NFREQ;j++) { data.P[j]=data.L[j]=0.0; data.code[j]=CODE_NONE; } data.code[0]=CODE_L1C; Obs.data[Obs.n++]=data; } if (++nobs>=MAX_SIMOBS) break; } if (Obs.n<=0) { ReadWaitEnd(); ShowMsg("no satellite visibility"); return; } UpdateObs(nobs); Caption="Satellite Visibility (Predicted)"; BtnSol1->Down=true; time2gpst(Obs.data[0].time,&Week); SolIndex[0]=SolIndex[1]=ObsIndex=0; if (PlotType<PLOT_OBS||PLOT_DOP<PlotType) { UpdateType(PLOT_OBS); } else { UpdatePlotType(); } FitTime(); ReadWaitEnd(); UpdateObsType(); UpdateTime(); UpdatePlot(); }