-// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
+// Copyright (C) 2014-2015 EDF-R&D
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
#include <HYDROData_PolylineXY.h>
#include <HYDROData_Polyline3D.h>
#include <HYDROData_Bathymetry.h>
-#include <HYDROData_LandCover.h>
#include <HYDROData_Profile.h>
#include <HYDROData_Iterator.h>
+#include <HYDROData_LandCoverMap.h>
#include <QFile>
#include <QFileInfo>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <BRep_Tool.hxx>
+#include <BRepTools.hxx>
#include <Precision.hxx>
#include <Handle_Geom_Curve.hxx>
#include <Handle_Geom_Line.hxx>
#include <ShapeFix_Shape.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <QColor>
+#include <BRepTopAdaptor_FClass2d.hxx>
+#include <TopExp.hxx>
+#ifdef WIN32
+ #pragma warning( disable: 4996 )
+#endif
HYDROData_ShapeFile::HYDROData_ShapeFile() : myHSHP(NULL)
{
void HYDROData_ShapeFile::Export(const QString& aFileName,
NCollection_Sequence<Handle_HYDROData_PolylineXY> aPolyXYSeq,
NCollection_Sequence<Handle_HYDROData_Polyline3D> aPoly3DSeq,
- NCollection_Sequence<Handle_HYDROData_LandCover> aLCSeq,
QStringList& aNonExpList)
{
SHPHandle hSHPHandle;
for (int i = 1; i <= aPolyXYSeq.Size(); i++)
if (WriteObjectPolyXY(hSHPHandle, aPolyXYSeq(i)) != 1)
aNonExpList.append(aPolyXYSeq(i)->GetName());
-
}
else if (aPolyXYSeq.IsEmpty() && !aPoly3DSeq.IsEmpty())
{
if (WriteObjectPoly3D(hSHPHandle, aPoly3DSeq(i)) != 1)
aNonExpList.append(aPoly3DSeq(i)->GetName());
}
- else if (aPolyXYSeq.IsEmpty() && aPoly3DSeq.IsEmpty() && !aLCSeq.IsEmpty())
+ if (hSHPHandle->nRecords > 0)
+ SHPClose( hSHPHandle );
+ else
{
- hSHPHandle = SHPCreate( aFileName.toAscii().data(), SHPT_POLYGON );
- for (int i = 1; i <= aLCSeq.Size(); i++)
- if (WriteObjectLC(hSHPHandle, aLCSeq(i)) != 1)
- aNonExpList.append(aLCSeq(i)->GetName());
+ SHPClose( hSHPHandle );
+ QString aFN = aFileName.simplified();
+ remove (aFN.toStdString().c_str());
+ remove (aFN.replace( ".shp", ".shx", Qt::CaseInsensitive).toStdString().c_str());
}
- SHPClose( hSHPHandle );
+}
+void HYDROData_ShapeFile::Export(const QString& aFileName,
+ const Handle_HYDROData_LandCoverMap& aLCM, QStringList& aNonExpList)
+{
+ SHPHandle hSHPHandle;
+ if ( !aLCM.IsNull() && !aLCM->IsEmpty())
+ {
+ hSHPHandle = SHPCreate( aFileName.toAscii().data(), SHPT_POLYGON );
+ HYDROData_LandCoverMap::Explorer It( aLCM );
+ for( ; It.More(); It.Next())
+ {
+ TopoDS_Face aFace = It.Face();
+ if (WriteObjectPolygon(hSHPHandle, aFace) != 1)
+ aNonExpList.append(aLCM->GetName() + "_" + QString::number(It.Index()));
+ }
+ }
+ if (hSHPHandle->nRecords > 0)
+ SHPClose( hSHPHandle );
+ else
+ {
+ SHPClose( hSHPHandle );
+ QString aFN = aFileName.simplified();
+ remove (aFN.toStdString().c_str());
+ remove (aFN.replace( ".shp", ".shx", Qt::CaseInsensitive).toStdString().c_str());
+ }
}
+
int HYDROData_ShapeFile::WriteObjectPolyXY(SHPHandle theShpHandle, Handle_HYDROData_PolylineXY thePoly )
{
SHPObject *aSHPObj;
return 1;
}
-int HYDROData_ShapeFile::WriteObjectLC(SHPHandle theShpHandle, Handle_HYDROData_LandCover theLC )
+int HYDROData_ShapeFile::WriteObjectPolygon(SHPHandle theShpHandle, const TopoDS_Shape& theInputShape )
{
- TopoDS_Shape aSh = theLC->GetShape();
- if (aSh.IsNull())
+ if (theInputShape.IsNull())
return 0;
- TopExp_Explorer anEdgeEx(aSh, TopAbs_EDGE);
+ TopExp_Explorer anEdgeEx(theInputShape, TopAbs_EDGE);
for (; anEdgeEx.More(); anEdgeEx.Next())
{
TopoDS_Edge E = TopoDS::Edge(anEdgeEx.Current());
}
}
- if (aSh.ShapeType() == TopAbs_FACE)
+ if (theInputShape.ShapeType() == TopAbs_FACE)
{
- ProcessFace(TopoDS::Face(aSh), theShpHandle);
+ ProcessFace(TopoDS::Face(theInputShape), theShpHandle);
}
- else if (aSh.ShapeType() == TopAbs_COMPOUND)
+ else if (theInputShape.ShapeType() == TopAbs_COMPOUND)
{
- TopExp_Explorer Ex(aSh, TopAbs_FACE);
+ TopExp_Explorer Ex(theInputShape, TopAbs_FACE);
for (; Ex.More(); Ex.Next())
{
TopoDS_Face aF = TopoDS::Face(Ex.Current());
void HYDROData_ShapeFile::ProcessFace(TopoDS_Face theFace, SHPHandle theShpHandle)
{
+ if (theFace.ShapeType() != TopAbs_FACE)
+ return;
SHPObject *aSHPObj;
std::vector<double> x, y;
std::vector<int> anPartStart;
- if (theFace.ShapeType() == TopAbs_FACE)
+ TopoDS_Wire OuterW = BRepTools::OuterWire(theFace);
+ NCollection_Sequence<TopoDS_Wire> aWires;
+
+ //write an outer wire first
+ aWires.Append(OuterW);
+ TopExp_Explorer Ex(theFace, TopAbs_WIRE);
+ for (; Ex.More(); Ex.Next())
{
- TopExp_Explorer Ex(theFace, TopAbs_WIRE);
- int NbWires = 0;
- for (; Ex.More(); Ex.Next())
+ TopoDS_Wire aW = TopoDS::Wire(Ex.Current());
+ if (aW.IsEqual(OuterW))
+ continue;
+ aWires.Append(aW);
+ }
+
+ //TopExp_Explorer Ex(theFace, TopAbs_WIRE);
+ int NbWires = 0;
+ for (int k = 1; k <= aWires.Length(); k++)
+ {
+ TopoDS_Wire aW = aWires(k);
+ if (aW.IsNull())
+ continue;
+ NbWires++;
+ if (aW.Orientation() == TopAbs_INTERNAL)
+ //cant write internal wires/edges
+ continue;
+ // Try to reorder edges
+ Handle(ShapeFix_Wire) aSFW = new ShapeFix_Wire( aW, theFace, Precision::Confusion() );
+ aSFW->ModifyTopologyMode() = Standard_False;
+ aSFW->ModifyGeometryMode() = Standard_False;
+ aSFW->FixReorder();
+ Handle(ShapeExtend_WireData) aSEWD = aSFW->WireData();
+ Standard_Integer nbE = aSEWD->NbEdges();
+ if (nbE == 0)
+ continue;
+ //
+ anPartStart.push_back(x.size());
+ NCollection_Sequence<gp_Pnt2d> aPnts;
+ for (Standard_Integer i = 1; i <= nbE; i++)
{
- TopoDS_Wire aW = TopoDS::Wire(Ex.Current());
- if (aW.IsNull())
+ TopoDS_Edge E = aSEWD->Edge(i);
+ TopoDS_Vertex aV = TopExp::LastVertex(E, 1);
+ if (aV.IsNull())
continue;
- NbWires++;
- anPartStart.push_back(x.size());
- TopExp_Explorer aVEx(aW, TopAbs_VERTEX);
- NCollection_Sequence<gp_Pnt2d> aPnts;
- for (; aVEx.More(); aVEx.Next())
- {
- TopoDS_Vertex aV = TopoDS::Vertex(aVEx.Current());
- if (aV.IsNull())
- continue;
- gp_Pnt P = BRep_Tool::Pnt(aV);
- aPnts.Append(gp_Pnt2d(P.X(), P.Y()));
- }
- NCollection_Sequence<gp_Pnt2d> aNPnts;
- aNPnts.Append(aPnts.First());
- for (int j = 1; j <= aPnts.Size() - 1; j++)
- {
- if (!aPnts(j).IsEqual(aPnts(j + 1), Precision::Confusion()))
- aNPnts.Append(aPnts(j + 1));
- }
-
- for (int j = 1; j <= aNPnts.Size(); j++)
- {
- x.push_back( aNPnts(j).X());
- y.push_back( aNPnts(j).Y());
- }
- //x.push_back( aNPnts(1).X());
- //y.push_back( aNPnts(1).Y());
+ gp_Pnt P = BRep_Tool::Pnt(aV);
+ aPnts.Append(gp_Pnt2d(P.X(), P.Y()));
+ }
+ NCollection_Sequence<gp_Pnt2d> aNPnts;
+ aNPnts.Append(aPnts.First());
+ for (int j = 1; j <= aPnts.Size() - 1; j++)
+ {
+ if (!aPnts(j).IsEqual(aPnts(j + 1), Precision::Confusion()))
+ aNPnts.Append(aPnts(j + 1));
+ }
+ //assume that the orientation of extrenal wire & internal wires is correct
+ //so just write all points "as-is"
+ //External wire will be written in clockwise direction
+ //any other wires (holes) - in anticlockwise direction
+ for (int j = 1; j <= aNPnts.Size(); j++)
+ {
+ x.push_back( aNPnts(j).X());
+ y.push_back( aNPnts(j).Y());
}
-
- aSHPObj = SHPCreateObject( SHPT_POLYGON, -1, NbWires, &anPartStart[0], NULL, x.size(), &x[0], &y[0], NULL, NULL );
- SHPWriteObject( theShpHandle, -1, aSHPObj );
- SHPDestroyObject( aSHPObj );
+ x.push_back( aNPnts(1).X());
+ y.push_back( aNPnts(1).Y());
}
- else
- return;
+
+ aSHPObj = SHPCreateObject( SHPT_POLYGON, -1, NbWires, &anPartStart[0], NULL, x.size(), &x[0], &y[0], NULL, NULL );
+ SHPWriteObject( theShpHandle, -1, aSHPObj );
+ SHPDestroyObject( aSHPObj );
+
}
-void HYDROData_ShapeFile::Parse1(SHPHandle theHandle)
+bool HYDROData_ShapeFile::Parse(SHPHandle theHandle, ShapeType theType, int& theShapeTypeOfFile)
{
int aShapeType;
mySHPObjects.clear();
SHPGetInfo( theHandle, NULL, &aShapeType, NULL, NULL );
- if (aShapeType == 5)
+ theShapeTypeOfFile = aShapeType;
+ bool ToRead = (theType == ShapeType_Polyline && (aShapeType == 3 || aShapeType == 13 || aShapeType == 23)) ||
+ (theType == ShapeType_Polygon && aShapeType == 5);
+ if (ToRead)
{
for (int i = 0; i < theHandle->nRecords; i++)
mySHPObjects.push_back(SHPReadObject(theHandle, i));
+ return true;
}
+ else
+ return false;
}
-void HYDROData_ShapeFile::ProcessSHP(SHPObject* anObj, int i, TopoDS_Face& F)
+void HYDROData_ShapeFile::ReadSHPPolygon(SHPObject* anObj, int i, TopoDS_Face& F)
{
+ if (!anObj)
+ return;
TopoDS_Wire W;
TopoDS_Edge E;
int nParts = anObj->nParts;
gp_Pln pln(gp_Pnt(0,0,0), gp_Dir(0,0,1));
- BRepBuilderAPI_MakeFace aFBuilder(pln);
//Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
//sfs->FixFaceTool()->FixOrientationMode() = 1;
-
+ TopTools_SequenceOfShape aWires;
for ( int i = 0 ; i < nParts ; i++ )
{
BRepBuilderAPI_MakeWire aBuilder;
aBuilder.Build();
W = TopoDS::Wire(aBuilder.Shape());
- W.Reverse();
- aFBuilder.Add(W);
+ W.Orientation(TopAbs_FORWARD);
+ BRepBuilderAPI_MakeFace aDB(pln, W);
+ TopoDS_Face aDummyFace = TopoDS::Face(aDB.Shape());
+ BRepTopAdaptor_FClass2d FClass(aDummyFace, Precision::PConfusion());
+ if ( i == 0 && FClass.PerformInfinitePoint() == TopAbs_OUT)
+ W.Reverse();
+ if ( i > 0 && FClass.PerformInfinitePoint() != TopAbs_IN)
+ W.Reverse();
+
+ aWires.Append(W);
}
+
+ BRepBuilderAPI_MakeFace aFBuilder(pln, TopoDS::Wire(aWires(1)));
+ for (int i = 2; i <= aWires.Length(); i++)
+ aFBuilder.Add(TopoDS::Wire(aWires(i)));
+ F = TopoDS::Face(aFBuilder.Shape());
- aFBuilder.Build();
- TopoDS_Face DF = aFBuilder.Face();
- BRepLib::BuildCurves3d(DF);
- bool IsInf = DF.Infinite();
- if(!DF.IsNull())
- {
- //sfs->Init ( DF );
- //sfs->Perform();
- F = DF; //TopoDS::Face(sfs->Shape());
- }
+ BRepLib::BuildCurves3d(F);
}
-bool HYDROData_ShapeFile::ImportLandCovers(const QString theFileName, QStringList& thePolygonsList, TopTools_SequenceOfShape& theFaces)
+int HYDROData_ShapeFile::ImportPolygons(const QString theFileName, QStringList& thePolygonsList, TopTools_SequenceOfShape& theFaces, int& theShapeTypeOfFile)
{
Free();
+ int Stat = TryOpenShapeFile(theFileName);
+ if (Stat != 0)
+ return Stat;
myHSHP = SHPOpen( theFileName.toAscii().data(), "rb" );
- Parse1(myHSHP);
- for (int i = 0; i < mySHPObjects.size(); i++)
+ if (!Parse(myHSHP, HYDROData_ShapeFile::ShapeType_Polygon, theShapeTypeOfFile))
+ return 0;
+ for (size_t i = 0; i < mySHPObjects.size(); i++)
thePolygonsList.append("polygon_" + QString::number(i + 1));
TopoDS_Face aF;
if (myHSHP->nShapeType == 5)
{
- for (int i = 0; i < mySHPObjects.size(); i++)
+ for (size_t i = 0; i < mySHPObjects.size(); i++)
{
- ProcessSHP(mySHPObjects[i], i, aF);
+ ReadSHPPolygon(mySHPObjects[i], i, aF);
theFaces.Append(aF);
}
- return true;
+ return 1;
}
else
- return false;
+ return 0;
}
void HYDROData_ShapeFile::Free()
}
-void HYDROData_ShapeFile::ProcessSHPPolyXY(Handle(HYDROData_Document) theDocument, SHPObject* anObj, QString theFileName,
+void HYDROData_ShapeFile::ReadSHPPolyXY(Handle(HYDROData_Document) theDocument, SHPObject* anObj, QString theFileName,
int theInd, NCollection_Sequence<Handle_HYDROData_Entity>& theEntities)
{
}
-void HYDROData_ShapeFile::ProcessSHPPoly3D(Handle(HYDROData_Document) theDocument, SHPObject* anObj, QString theFileName,
+void HYDROData_ShapeFile::ReadSHPPoly3D(Handle(HYDROData_Document) theDocument, SHPObject* anObj, QString theFileName,
int theInd, NCollection_Sequence<Handle_HYDROData_Entity>& theEntities)
{
Handle(HYDROData_PolylineXY) aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( theDocument->CreateObject( KIND_POLYLINEXY ) );
aPolylineObj->SetPolylineXY (aPolylineXY, false);
aPolylineObj->SetAltitudeObject(aBath);
- aPolylineObj->SetBorderColor( HYDROData_Polyline3D::DefaultBorderColor() );
+ aPolylineObj->SetBorderColor( aPolylineObj->DefaultBorderColor() );
aPolylineObj->SetName( aPoly3DName );
aPolylineObj->Update();
}
-void HYDROData_ShapeFile::Parse2(SHPHandle theHandle)
-{
- int aShapeType;
- mySHPObjects.clear();
- SHPGetInfo( theHandle, NULL, &aShapeType, NULL, NULL );
- if (aShapeType == 3 || aShapeType == 13 || aShapeType == 23)
- {
- for (int i = 0; i < theHandle->nRecords; i++)
- mySHPObjects.push_back(SHPReadObject(theHandle, i));
- }
-}
-bool HYDROData_ShapeFile::ImportPolylines(Handle(HYDROData_Document) theDocument, const QString& theFileName, NCollection_Sequence<Handle_HYDROData_Entity>& theEntities)
+
+int HYDROData_ShapeFile::ImportPolylines(Handle(HYDROData_Document) theDocument, const QString& theFileName,
+ NCollection_Sequence<Handle_HYDROData_Entity>& theEntities, int& theShapeTypeOfFile)
{
+ //Free();
+ int aStat = TryOpenShapeFile(theFileName);
+ if (aStat != 0)
+ return aStat;
+
HYDROData_Iterator anIter( theDocument );
int anInd = 0;
QStringList anExistingNames;
QFileInfo aFileInfo(theFileName);
QString aBaseFileName = aFileInfo.baseName();
- Parse2(aHSHP);
- bool aStat = false;
+ if (!Parse(aHSHP, HYDROData_ShapeFile::ShapeType_Polyline, theShapeTypeOfFile))
+ return 0;
if (aHSHP->nShapeType == 3 || aHSHP->nShapeType == 23)
{
anInd = 0;
for (size_t i = 0; i < mySHPObjects.size(); i++ )
{
- ProcessSHPPolyXY(theDocument, mySHPObjects[i], aBaseFileName, anAllowedIndexes[i], theEntities);
+ ReadSHPPolyXY(theDocument, mySHPObjects[i], aBaseFileName, anAllowedIndexes[i], theEntities);
}
- aStat = true;
+ aStat = 1;
}
else if (aHSHP->nShapeType == 13)
{
anInd++;
}
for (size_t i = 0; i < mySHPObjects.size(); i++ )
- ProcessSHPPoly3D(theDocument, mySHPObjects[i], aBaseFileName, anAllowedIndexes[i], theEntities);
- aStat = true;
+ ReadSHPPoly3D(theDocument, mySHPObjects[i], aBaseFileName, anAllowedIndexes[i], theEntities);
+ aStat = 1;
}
else
{
- aStat = false;
+ aStat = 0;
}
for (size_t i = 0; i < mySHPObjects.size(); i++ )
mySHPObjects.clear();
SHPClose(aHSHP);
return aStat;
+}
+
+QString HYDROData_ShapeFile::GetShapeTypeName(int theType)
+{
+ switch (theType)
+ {
+ case 0:
+ return "null shape";
+ case 1:
+ return "point (unsupported by HYDRO)";
+ case 3:
+ return "arc/polyline (supported by HYDRO)";
+ case 5:
+ return "polygon (supported by HYDRO)";
+ case 8:
+ return "multipoint (unsupported by HYDRO)";
+ case 11:
+ return "pointZ (unsupported by HYDRO)";
+ case 13:
+ return "arcZ/polyline (supported by HYDRO)";
+ case 15:
+ return "polygonZ (unsupported by HYDRO)";
+ case 18:
+ return "multipointZ (unsupported by HYDRO)";
+ case 21:
+ return "pointM (unsupported by HYDRO)";
+ case 23:
+ return "arcM/polyline (supported by HYDRO)";
+ case 25:
+ return "polygonM (unsupported by HYDRO)";
+ case 28:
+ return "multipointM (unsupported by HYDRO)";
+ case 31:
+ return "multipatch (unsupported by HYDRO)";
+ default:
+ return "unknown";
+ }
+}
+
+int HYDROData_ShapeFile::TryOpenShapeFile(QString theFileName)
+{
+ QString aSHPfile = theFileName.simplified();
+ QString aSHXfile = theFileName.simplified().replace( ".shp", ".shx", Qt::CaseInsensitive);
+ FILE* pFileSHP = NULL;
+ pFileSHP = fopen (aSHPfile.toAscii().data(), "r");
+ FILE* pFileSHX = NULL;
+ pFileSHX = fopen (aSHXfile.toAscii().data(), "r");
+
+ if (pFileSHP == NULL || pFileSHX == NULL)
+ {
+ if (pFileSHP == NULL)
+ return -1;
+ if (pFileSHX == NULL)
+ return -2;
+ }
+
+ fclose (pFileSHP);
+ fclose (pFileSHX);
+ return 0;
+}
+
+
+bool HYDROData_ShapeFile::CheckDBFFileExisting(const QString& theSHPFilePath, QString& thePathToDBFFile)
+{
+ QString aSHPfile = theSHPFilePath.simplified();
+ QString aDBFfile = theSHPFilePath.simplified().replace( ".shp", ".dbf", Qt::CaseInsensitive);
+ FILE* pFileDBF = NULL;
+ pFileDBF = fopen (aDBFfile.toAscii().data(), "r");
+
+ if (pFileDBF == NULL)
+ {
+ return false;
+ }
+
+ fclose (pFileDBF);
+ thePathToDBFFile = aDBFfile;
+ return true;
+}
+
+
+bool HYDROData_ShapeFile::DBF_OpenDBF(const QString& thePathToDBFFile)
+{
+ myHDBF = DBFOpen( thePathToDBFFile.toAscii().data(), "r" );
+ if(myHDBF != NULL)
+ return true;
+ else
+ return false;
+}
+
+int HYDROData_ShapeFile::DBF_GetNbFields()
+{
+ if(myHDBF == NULL)
+ return 0;
+ return DBFGetFieldCount(myHDBF);
+}
+
+void HYDROData_ShapeFile::DBF_CloseDBF()
+{
+ if(myHDBF != NULL)
+ DBFClose( myHDBF );
+}
+
+QStringList HYDROData_ShapeFile::DBF_GetFieldList()
+{
+ QStringList FieldList;
+ int nWidth, nDecimals;
+ char chField[12];
+
+ for( int i = 0; i < DBFGetFieldCount(myHDBF); i++ )
+ {
+ DBFFieldType eType;
+ eType = DBFGetFieldInfo( myHDBF, i, chField, &nWidth, &nDecimals );
+ FieldList.append(QString(chField));
+ }
+
+ return FieldList;
+}
+
+void HYDROData_ShapeFile::DBF_GetFieldTypeList(std::vector<DBF_FieldType>& FTVect)
+{
+ int nWidth, nDecimals;
+ char chField[12];
+ DBF_FieldType FT;
+ for( int i = 0; i < DBFGetFieldCount(myHDBF); i++ )
+ {
+ DBFFieldType eType;
+ eType = DBFGetFieldInfo( myHDBF, i, chField, &nWidth, &nDecimals );
+ if( eType == FTString )
+ FT = DBF_FieldType_String;
+ else if( eType == FTInteger )
+ FT = DBF_FieldType_Integer;
+ else if( eType == FTDouble )
+ FT = DBF_FieldType_Double;
+ else if( eType == FTInvalid )
+ FT = DBF_FieldType_Invalid;
+
+ FTVect.push_back(FT);
+ }
+
+}
+
+int HYDROData_ShapeFile::DBF_GetNbRecords()
+{
+ if(myHDBF == NULL)
+ return 0;
+ return DBFGetRecordCount(myHDBF);
+}
+
+void HYDROData_ShapeFile::DBF_GetAttributeList(int theIndexOfField, std::vector<DBF_AttrValue>& theAttrV)
+{
+ int nWidth, nDecimals;
+ char chField[12];
+
+ for( int i = 0; i < DBFGetRecordCount(myHDBF); i++ )
+ {
+ DBFFieldType eType;
+ DBF_AttrValue anAttr;
+ eType = DBFGetFieldInfo( myHDBF, theIndexOfField, chField, &nWidth, &nDecimals );
+
+ if( DBFIsAttributeNULL( myHDBF, i, theIndexOfField ) )
+ {
+ anAttr.myIsNull = true;
+ DBF_FieldType FT = DBF_FieldType_None;
+ if( eType == FTString )
+ FT = DBF_FieldType_String;
+ else if( eType == FTInteger )
+ FT = DBF_FieldType_Integer;
+ else if( eType == FTDouble )
+ FT = DBF_FieldType_Double;
+ else if( eType == FTInvalid )
+ FT = DBF_FieldType_Invalid;
+ anAttr.myFieldType = FT;
+ }
+ else
+ {
+ switch( eType )
+ {
+ case FTString:
+ {
+ const char* chAttr = DBFReadStringAttribute( myHDBF, i, theIndexOfField );
+ anAttr.myIsNull = false;
+ anAttr.myFieldType = DBF_FieldType_String;
+ anAttr.myRawValue = chAttr;
+ anAttr.myStrVal = QString(chAttr);
+ break;
+ }
+
+ case FTInteger:
+ {
+ int iAttr = DBFReadIntegerAttribute( myHDBF, i, theIndexOfField );
+ anAttr.myIsNull = false;
+ anAttr.myFieldType = DBF_FieldType_Integer;
+ anAttr.myRawValue = DBFReadStringAttribute( myHDBF, i, theIndexOfField );
+ anAttr.myIntVal = iAttr;
+ break;
+ }
+
+ case FTDouble:
+ {
+ double dAttr = DBFReadDoubleAttribute( myHDBF, i, theIndexOfField );
+ anAttr.myIsNull = false;
+ anAttr.myFieldType = DBF_FieldType_Double;
+ anAttr.myRawValue = DBFReadStringAttribute( myHDBF, i, theIndexOfField );
+ anAttr.myDoubleVal = dAttr;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ theAttrV.push_back(anAttr);
+ }
+
+}
+
+bool HYDROData_ShapeFile::DBF_WriteFieldAndValues(const QString& theFileName, const QString& theFieldName, DBF_FieldType theType, const std::vector<DBF_AttrValue>& theAttrV, bool bUseRawValue)
+{
+ // Check that given field type is equal to field types of attributes values
+ for (size_t i = 0; i < theAttrV.size(); i++)
+ {
+ if (theAttrV[i].myFieldType != theType)
+ return false;
+ }
+
+ DBFHandle hDBF;
+ hDBF = DBFCreate( theFileName.toStdString().c_str() );
+ if( hDBF == NULL )
+ return false;
+
+ if (theType != DBF_FieldType_String && theType != DBF_FieldType_Integer && theType != DBF_FieldType_Double)
+ {
+ DBFClose( hDBF );
+ return false; //cant handle any other cases
+ }
+
+ int nWidth = 20;
+ switch( theType )
+ {
+ case DBF_FieldType_String:
+ {
+ DBFAddField (hDBF, theFieldName.toStdString().c_str(), FTString, nWidth, 0);
+ break;
+ }
+
+ case DBF_FieldType_Integer:
+ {
+ DBFAddField (hDBF, theFieldName.toStdString().c_str(), FTInteger, nWidth, 0);
+ break;
+ }
+
+ case DBF_FieldType_Double:
+ {
+ DBFAddField (hDBF, theFieldName.toStdString().c_str(), FTDouble, nWidth, 0);
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (DBFGetFieldCount( hDBF ) != 1)
+ {
+ DBFClose( hDBF );
+ return false;
+ }
+ if (DBFGetRecordCount( hDBF ) != 0)
+ {
+ DBFClose( hDBF );
+ return false;
+ }
+ int stat = -1;
+
+ if (bUseRawValue)
+ {
+ for (size_t i = 0; i < theAttrV.size(); i++)
+ {
+ if (!theAttrV[i].myIsNull)
+ stat = DBFWriteStringAttribute(hDBF, (int)i, 0, theAttrV[i].myRawValue.c_str());
+ else
+ stat = DBFWriteNULLAttribute(hDBF, (int)i, 0 );
+
+ if (stat != 1)
+ {
+ DBFClose( hDBF );
+ return false;
+ }
+ }
+ }
+ else
+ {
+ for (size_t i = 0; i < theAttrV.size(); i++)
+ {
+ if (!theAttrV[i].myIsNull)
+ switch( theType )
+ {
+ case DBF_FieldType_String:
+ {
+ stat = DBFWriteStringAttribute(hDBF, (int)i, 0, theAttrV[i].myStrVal.toStdString().c_str());
+ break;
+ }
+
+ case DBF_FieldType_Integer:
+ {
+ stat = DBFWriteIntegerAttribute(hDBF, (int)i, 0, theAttrV[i].myIntVal);
+ break;
+ }
+
+ case DBF_FieldType_Double:
+ {
+ stat = DBFWriteDoubleAttribute(hDBF, (int)i, 0, theAttrV[i].myDoubleVal);
+ break;
+ }
+ default:
+ break;
+ }
+ else
+ stat = DBFWriteNULLAttribute(hDBF, (int)i, 0 );
+
+ if (stat != 1)
+ {
+ DBFClose( hDBF );
+ return false;
+ }
+ }
+ }
+
+ DBFClose( hDBF );
+ return true;
+
}
\ No newline at end of file