float CBTFile::GetMaxHeight() { n_assert(Header); DWORD HCount = GetHeightCount(); if (!HCount) return NoDataF; if (MaxHeight == NoDataF) { if (IsFloatData()) { MaxHeight = *HeightsF; float* CurrHeight = HeightsF; float* HeightStop = HeightsF + HCount; while (++CurrHeight < HeightStop) if (MaxHeight < *CurrHeight) MaxHeight = *CurrHeight; } else { short MaxHeightS = *HeightsS; short* CurrHeight = HeightsS; short* HeightStop = HeightsS + HCount; while (++CurrHeight < HeightStop) if (MaxHeightS < *CurrHeight) MaxHeightS = *CurrHeight; MaxHeight = (MaxHeightS == NoDataS) ? NoDataF : MaxHeightS * GetVerticalScale(); } n_assert2(MaxHeight != NoDataF, "Completely empty heightfield"); } return MaxHeight; }
// OutFloats must be preallocated // BT stores south-to-north column-major, but we return N-to-S row-major here void CBTFile::GetHeights(float* OutFloats, DWORD X, DWORD Z, DWORD W, DWORD H) { n_assert(Header); n_assert(OutFloats); n_assert(X < Header->Width); n_assert(Z < Header->Height); if (W == 0) W = Header->Width - X; else n_assert(X + W < Header->Width); if (H == 0) H = Header->Height - Z; else n_assert(Z + H < Header->Height); float* Dest = OutFloats; if (IsFloatData()) { n_assert(Header->DataSize == sizeof(float)); for (DWORD Row = Z; Row < Z + H; Row++) for (DWORD Col = X; Col < X + W; Col++) Dest[Row * Header->Width + Col] = HeightsF[Col * Header->Height + Header->Height - 1 - Row]; } else { n_assert(Header->DataSize == sizeof(short)); float VScale = GetVerticalScale(); for (DWORD Row = Z; Row < Z + H; Row++) for (DWORD Col = X; Col < X + W; Col++) { short Src = HeightsS[Col * Header->Height + Header->Height - 1 - Row]; Dest[Row * Header->Width + Col] = (Src == NoDataS) ? NoDataF : Src * VScale; } } }
float CBTFile::GetHeight(DWORD X, DWORD Z) const { n_assert(Header); n_assert(X < Header->Width); n_assert(Z < Header->Height); if (IsFloatData()) return GetHeightF(X, Z); else { short Height = GetHeightS(X, Z); return (Height == NoDataS) ? NoDataF : Height * GetVerticalScale(); } }
int CCopyBlock::WriteTagValues(CSVector& Tags) { ASSERT(pEO && bSrcDatalib && eSrc==CB_SelectedTag); CProfINIFile PF(CfgFiles(), (char*)CopyBlkFileName); if (!CheckCopyBlockVer(PF, true)) return 0; Strng_List sStrList; int WriteCnt = 0; char Buff[2]; Buff[0] = 0; Buff[1] = 0; PF.WrSection(TempBlockName, Buff); char* p = Buff; for (int i=0; i<Tags.GetSize(); i++) { CXM_ObjectData ObjData; CXM_Route Route; CXM_ObjectTag ObjTag(Tags[i](), TABOpt_AllInfoOnce);//TABOpt_Parms); if (pEO->XReadTaggedItem(ObjTag, ObjData, Route)) { CPkDataItem * pItem = ObjData.FirstItem(); byte cType = pItem->Type(); if (IsData(cType)) { WriteCnt++; if (IsIntData(cType) && pItem->Contains(PDI_StrList)) { const long strIndex = pItem->Value()->GetLong(); pItem->GetStrList(sStrList); pStrng pS = (sStrList.Length()>0) ? sStrList.AtIndexVal(strIndex) : NULL; if (pS) PF.WrStr(TempBlockName, Tags[i](), pS->Str()); else PF.WrLong(TempBlockName, Tags[i](), strIndex); } else if (IsStrng(cType)) PF.WrStr(TempBlockName, Tags[i](), pItem->Value()->GetString()); else if (IsFloatData(cType)) PF.WrDouble(TempBlockName, Tags[i](), pItem->Value()->GetDouble()); else PF.WrLong(TempBlockName, Tags[i](), pItem->Value()->GetLong()); } } } return WriteCnt; }
int CCopyBlock::CopyTagBlocks() { CWaitCursor Wait; // ASSERT(eSrc!=CB_List); //this src type not allowed // ASSERT(eDst!=CB_Tag); //this dst type not allowed ASSERT(pEO); CProfINIFile SrcPF(bSrcDatalib ? CfgFiles() : PrjFiles(), (char*)CopyBlkFileName); CheckCopyBlockVer(SrcPF); CProfINIFile DstPF(bDstDatalib ? CfgFiles() : PrjFiles(), (char*)CopyBlkFileName); if (!CheckCopyBlockVer(DstPF, true)) return 0; int Cnt = 0; //gs_pTheSFELib->FE_SetHoldGlobalLinks(true); //gs_Exec.SetHoldValidateData(true, true, true); gs_Exec.BeginBulkChange(); Strng Section; if (eSrc==CB_SelectedTag) Section = TempBlockName; else Section.Set("%s(%s)", sSrc(), sModelClass()); char Buff[16384]; DWORD dw = SrcPF.RdSection(Section(), Buff, sizeof(Buff)); ASSERT(dw<sizeof(Buff)-2); //section too large!!! if (eDst==CB_Block) { Strng DstSection; DstSection.Set("%s(%s)", sDst(), sModelClass()); DstPF.WrSection(DstSection(), Buff); } else { Strng_List sStrList; CXM_Route Route; CXM_ObjectData ObjData; char* p = Buff; while (p[0]) { int len = strlen(p); char* Nextp = p; Nextp += (len + 1); char* pp = strchr(p, '='); if (pp) { pp[0] = 0; char* pValue = &pp[1]; char* ppp = strchr(p, '.'); Strng PartTag; PartTag = (ppp==NULL ? p : ppp); for (int i=0; i<TagList.GetSize(); i++) { Strng WrkTag(TagList[i]()); WrkTag += PartTag; //CXM_ObjectTag ObjTag(WrkTag(), 0); //need to use TABOpt_AllInfoOnce because of tags that contain a strList! CXM_ObjectTag ObjTag(WrkTag(), TABOpt_AllInfoOnce);//0);//TABOpt_Exists);//TABOpt_Parms);//TABOpt_ValCnvsOnce); Route.Clear(); if (pEO->XReadTaggedItem(ObjTag, ObjData, Route)) { CPkDataItem * pItem = ObjData.FirstItem(); byte cType = pItem->Type(); PkDataUnion DU; if (IsStrng(cType)) DU.SetTypeString(cType, pValue); else if (IsFloatData(cType)) DU.SetTypeDouble(cType, SafeAtoF(pValue)); else if (IsIntData(cType) && pItem->Contains(PDI_StrList)) { pItem->GetStrList(sStrList); pStrng pS = sStrList.Find(pValue); //const int Indx = (pS==NULL ? 0 : sStrList.Index(pS)); const int Indx = (pS==NULL ? 0 : pS->Index()); DU.SetTypeLong(cType, Indx); } else DU.SetTypeLong(cType, SafeAtoL(pValue)); CXM_ObjectData OD(0, 0, WrkTag(), 0, DU); if (pEO->XWriteTaggedItem(OD, Route)==TOData_NotFound) LogWarning(WrkTag(), 0, "Write tag failed"); else Cnt++; //if (pEO->XWriteTaggedItem(OD, Route)!=TOData_OK) // LogWarning(WrkTag(), 0, "Write tag failed (possibly invalid data)"); } else LogWarning(WrkTag(), 0, "Unable to read tag"); } } p = Nextp; } } //TaggedObject::SetHoldValidateData(false); //gs_Exec.SetHoldValidateData(false, true, true); //gs_pTheSFELib->FE_SetHoldGlobalLinks(false); gs_Exec.EndBulkChange(); //TaggedObject::SetXWritesBusy(false); return Cnt; }