#include "graticulecreator.h" #include #include #include #include #include #include #include #include GraticuleCreator::GraticuleCreator(QString theOutputFileName,ShapeType theType) { std::cout << "GraticuleCreator constructor called with " << theOutputFileName.toLocal8Bit().data() << " for output file " << std::endl; /* Open and prepare output files */ createDbf(theOutputFileName); createShapeFile(theOutputFileName,theType); writeProjectionFile(theOutputFileName); } GraticuleCreator::~GraticuleCreator() { DBFClose( mDbfHandle ); SHPClose( mShapeHandle ); } /* DbfName need not include the file extension. */ void GraticuleCreator::createDbf (QString mDbfName ) { //remove the path part of the dbf name QFileInfo myFileInfo( mDbfName ); QString myBaseString = myFileInfo.dirPath()+QString("/")+myFileInfo.baseName(); // excludes any extension //create the dbf mDbfHandle = DBFCreate( myBaseString+".dbf" ); //create an index field named after the base part of the file name DBFAddField( mDbfHandle, myBaseString+"_id", FTInteger, 11, 0 ); //create a second arbitary attribute field DBFAddField( mDbfHandle, "Date", FTString, 12, 0 ); //close the dbf DBFClose( mDbfHandle ); //reopen mDbfHandle = DBFOpen( myBaseString+".dbf", "r+b" ); //exit this fn giving return; } void GraticuleCreator::createShapeFile(QString theFileName , ShapeType theType) { switch (theType) { case POINT: mShapeHandle = SHPCreate(theFileName, SHPT_POINT ); break; case LINE: mShapeHandle = SHPCreate(theFileName, SHPT_ARC ); break; default: //POLYGON mShapeHandle = SHPCreate(theFileName, SHPT_POLYGON); } return; } void GraticuleCreator::writeDbfRecord ( int theRecordIdInt, QString theLabel) { //std::cerr << "writeDbfRecord : " << theRecordIdInt << " - " << theLabel.toLocal8Bit().data(); if (! DBFWriteIntegerAttribute(mDbfHandle, theRecordIdInt, 0, theRecordIdInt)) { std::cerr << "DBFWriteIntegerAttribute failed. : " << theRecordIdInt << " - " << theRecordIdInt << std::endl; //exit(ERR_DBFWRITEINTEGERATTRIBUTE); } if (!theLabel.isNull()) { if (! DBFWriteStringAttribute(mDbfHandle, theRecordIdInt, 1, theLabel)) { std::cerr << "DBFWriteStringAttribute failed. : " << theRecordIdInt << " - " << theLabel.toLocal8Bit().data() < xmax //so that when reprojecting the graticule will warp properly //so first we need to work out how many intersections there are... // long myXIntersectionCount = static_cast((theXEndPointDouble - theXOriginDouble) / theXIntervalDouble)+1; long myYIntersectionCount = static_cast((theYEndPointDouble - theYOriginDouble) / theYIntervalDouble)+1; // //Longitude loop // myXArrayDouble = (double *)malloc(myYIntersectionCount * sizeof(double)); myYArrayDouble = (double *)malloc(myYIntersectionCount * sizeof(double)); for (double myXDouble = theXOriginDouble;myXDouble <=theXEndPointDouble;myXDouble+=theXIntervalDouble) { long myVertexNo=0; for (double myYDouble=theYOriginDouble;myYDouble<=theYEndPointDouble;myYDouble+=theYIntervalDouble) { myXArrayDouble[myVertexNo]=myXDouble; myYArrayDouble[myVertexNo]=myYDouble; ++myVertexNo; } writeDbfRecord(myRecordInt,"testing"); writeLine( myRecordInt, myYIntersectionCount, myXArrayDouble, myYArrayDouble); ++myRecordInt; } delete myXArrayDouble; delete myYArrayDouble; // //Latitude loop // myXArrayDouble = (double *)malloc(myXIntersectionCount * sizeof(double)); myYArrayDouble = (double *)malloc(myXIntersectionCount * sizeof(double)); for (double myYDouble=theYOriginDouble;myYDouble<=theYEndPointDouble;myYDouble+=theYIntervalDouble) { long myVertexNo=0; for (double myXDouble=theXOriginDouble;myXDouble<=theXEndPointDouble;myXDouble+=theXIntervalDouble) { myXArrayDouble[myVertexNo]=myXDouble; myYArrayDouble[myVertexNo]=myYDouble; ++myVertexNo; } writeDbfRecord(myRecordInt,"testing"); writeLine( myRecordInt,myXIntersectionCount, myXArrayDouble, myYArrayDouble); ++myRecordInt; } delete myXArrayDouble; delete myYArrayDouble; // write a proj file for the graticule } //TODO: check for rediculous intervals! void GraticuleCreator::generatePolygonGraticule( double theXIntervalDouble, double theYIntervalDouble, double theXOriginDouble, double theYOriginDouble, double theXEndPointDouble, double theYEndPointDouble) { int myRecordInt=0; //create the arrays for storing the coordinates double * myXArrayDouble; double * myYArrayDouble; //we want out graticule to be made of short line segments rather tban //long ones that imply span xmin <-> xmax //so that when reprojecting the graticule will warp properly //so first we need to work out how many intersections there are... // long myXVertexCount = 5; // four vertices of the sqaure for each cell, plus end at start long myYVertexCount = 5; // //Longitude loop // myXArrayDouble = (double *)malloc(myYVertexCount * sizeof(double)); myYArrayDouble = (double *)malloc(myYVertexCount * sizeof(double)); for (double myXDouble = theXOriginDouble ; myXDouble < theXEndPointDouble ; myXDouble+=theXIntervalDouble) { for (double myYDouble=theYOriginDouble;myYDouble<=theYEndPointDouble;myYDouble+=theYIntervalDouble) { //top left of rect myXArrayDouble[0]=myXDouble; myYArrayDouble[0]=myYDouble; //top right myXArrayDouble[1]=myXDouble+theXIntervalDouble; myYArrayDouble[1]=myYDouble; //bottom right myXArrayDouble[2]=myXDouble+theXIntervalDouble; myYArrayDouble[2]=myYDouble+theYIntervalDouble; //bottom left myXArrayDouble[3]=myXDouble; myYArrayDouble[3]=myYDouble+theYIntervalDouble; //return to top left myXArrayDouble[4]=myXDouble; myYArrayDouble[4]=myYDouble; writeDbfRecord(myRecordInt,"testing"); writePolygon( myRecordInt, myYVertexCount, myXArrayDouble, myYArrayDouble); ++myRecordInt; } } delete myXArrayDouble; delete myYArrayDouble; // write a proj file for the graticule } /* read from fp and generate point shapefile to mDbfHandle/mShapeHandle */ void GraticuleCreator::generatePoints (QString theInputFileName) { QFile myFile( theInputFileName ); if ( myFile.open( QIODevice::ReadOnly ) ) { QTextStream myStream( &myFile ); QString myLineString; int myRecordInt = 0; while ( !myStream.atEnd() ) { // line of text excluding '\n' myLineString = myStream.readLine(); //tokenise the line so we can get coords and records QStringList myQStringList = QStringList::split("\t",myLineString,true); if (myQStringList.size()==4) { QString myDateQString = myQStringList[1]; QString myLatQString = myQStringList[2]; QString myLongQString = myQStringList[3]; //convert items 3 and 4 to lat and long... //TODO - continue here... double x=myLongQString.toDouble(); double y=myLatQString.toDouble(); //create the dbf and shape recs std::cerr << "Writing record: " << myDateQString.toLocal8Bit().data() << " - " << x << " - " << y << std::endl; writeDbfRecord( myRecordInt, myDateQString); writePoint( myRecordInt, x, y); myRecordInt++; } } myFile.close(); } }