2004-04-05 20:53:17 +00:00
|
|
|
#include "graticulecreator.h"
|
|
|
|
#include <stdio.h>
|
2005-07-03 00:18:14 +00:00
|
|
|
#include <cassert>
|
2004-04-05 20:53:17 +00:00
|
|
|
#include <qtextstream.h>
|
|
|
|
#include <iostream>
|
2005-07-03 00:18:14 +00:00
|
|
|
#include <fstream>
|
2004-04-05 20:53:17 +00:00
|
|
|
#include <qfileinfo.h>
|
|
|
|
#include <qstringlist.h>
|
2005-07-03 00:18:14 +00:00
|
|
|
#include <qgis.h>
|
2004-11-09 01:04:00 +00:00
|
|
|
GraticuleCreator::GraticuleCreator(QString theOutputFileName,
|
|
|
|
double theXIntervalDouble,
|
|
|
|
double theYIntervalDouble,
|
|
|
|
double theXOriginDouble,
|
|
|
|
double theYOriginDouble,
|
|
|
|
double theXEndPointDouble,
|
|
|
|
double theYEndPointDouble
|
|
|
|
)
|
2004-04-05 20:53:17 +00:00
|
|
|
{
|
2005-09-16 23:30:38 +00:00
|
|
|
std::cout << "GraticuleCreator constructor called with " << theOutputFileName.local8Bit()
|
2004-04-06 07:17:03 +00:00
|
|
|
<< " for output file and " << theXIntervalDouble << "," << theYIntervalDouble << " for x,y interval " << std::endl;
|
2005-07-03 00:18:14 +00:00
|
|
|
DBFHandle myDbfHandle; /* handle for dBase file */
|
|
|
|
SHPHandle myShapeHandle; /* handle for shape files .shx and .shp */
|
2004-04-05 20:53:17 +00:00
|
|
|
/* Open and prepare output files */
|
|
|
|
myDbfHandle = createDbf(theOutputFileName);
|
|
|
|
myShapeHandle = createShapeFile(theOutputFileName);
|
2005-07-03 00:18:14 +00:00
|
|
|
writeProjectionFile(theOutputFileName);
|
2004-04-05 20:53:17 +00:00
|
|
|
//test the write point routine....
|
2004-04-05 23:11:52 +00:00
|
|
|
//generatePoints(theInputFileName,myDbfHandle,myShapeHandle);
|
2004-11-09 01:04:00 +00:00
|
|
|
generateGraticule(myDbfHandle,
|
|
|
|
myShapeHandle,
|
|
|
|
theXIntervalDouble,
|
|
|
|
theYIntervalDouble,
|
|
|
|
theXOriginDouble,
|
|
|
|
theYOriginDouble,
|
|
|
|
theXEndPointDouble,
|
|
|
|
theYEndPointDouble);
|
2004-04-05 20:53:17 +00:00
|
|
|
DBFClose( myDbfHandle );
|
|
|
|
SHPClose( myShapeHandle );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* DbfName need not include the file extension. */
|
|
|
|
DBFHandle GraticuleCreator::createDbf (QString theDbfName )
|
|
|
|
{
|
|
|
|
DBFHandle myDbfHandle;
|
|
|
|
//remove the path part of the dbf name
|
|
|
|
QFileInfo myFileInfo( theDbfName );
|
2004-05-13 09:54:18 +00:00
|
|
|
QString myBaseString = myFileInfo.dirPath()+QString("/")+myFileInfo.baseName(); // excludes any extension
|
2004-04-05 20:53:17 +00:00
|
|
|
//create the dbf
|
|
|
|
myDbfHandle = DBFCreate( myBaseString+".dbf" );
|
|
|
|
//create an index field named after the base part of the file name
|
|
|
|
|
|
|
|
DBFAddField( myDbfHandle, myBaseString+"_id", FTInteger, 11, 0 );
|
|
|
|
//create a second arbitary attribute field
|
|
|
|
DBFAddField( myDbfHandle, "Date", FTString, 12, 0 );
|
|
|
|
//close the dbf
|
|
|
|
DBFClose( myDbfHandle );
|
|
|
|
//reopen
|
|
|
|
myDbfHandle = DBFOpen( myBaseString+".dbf", "r+b" );
|
|
|
|
//exit this fn giving
|
|
|
|
return myDbfHandle;
|
|
|
|
}
|
|
|
|
|
|
|
|
SHPHandle GraticuleCreator::createShapeFile(QString theFileName )
|
|
|
|
{
|
|
|
|
SHPHandle myShapeHandle;
|
2004-04-06 07:17:03 +00:00
|
|
|
//myShapeHandle = SHPCreate(theFileName, SHPT_POINT );
|
|
|
|
myShapeHandle = SHPCreate(theFileName, SHPT_ARC );
|
2004-04-05 20:53:17 +00:00
|
|
|
return myShapeHandle;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GraticuleCreator::writeDbfRecord (DBFHandle theDbfHandle, int theRecordIdInt, QString theLabel)
|
|
|
|
{
|
|
|
|
|
|
|
|
|
2005-09-16 23:30:38 +00:00
|
|
|
std::cerr << "writeDbfRecord : " << theRecordIdInt << " - " << theLabel.local8Bit();
|
2004-04-05 20:53:17 +00:00
|
|
|
if (! DBFWriteIntegerAttribute(theDbfHandle, theRecordIdInt, 0, theRecordIdInt))
|
|
|
|
{
|
|
|
|
std::cerr << "DBFWriteIntegerAttribute failed. : " << theRecordIdInt << " - " << theRecordIdInt << std::endl;
|
|
|
|
|
|
|
|
//exit(ERR_DBFWRITEINTEGERATTRIBUTE);
|
|
|
|
}
|
2005-09-16 23:30:38 +00:00
|
|
|
if (!theLabel.isNull())
|
2004-04-05 20:53:17 +00:00
|
|
|
{
|
|
|
|
if (! DBFWriteStringAttribute(theDbfHandle, theRecordIdInt, 1, theLabel))
|
|
|
|
{
|
2005-09-16 23:30:38 +00:00
|
|
|
std::cerr << "DBFWriteStringAttribute failed. : " << theRecordIdInt << " - " << theLabel.local8Bit() <<std::endl;
|
2004-04-05 20:53:17 +00:00
|
|
|
//exit(ERR_DBFWRITEINTEGERATTRIBUTE);
|
|
|
|
}
|
|
|
|
std::cerr << " - OK! " << std::endl;
|
|
|
|
}
|
|
|
|
//DBFWriteIntegerAttribute(theDbfHandle, theRecordIdInt, 0, theRecordIdInt);
|
|
|
|
//DBFWriteStringAttribute(theDbfHandle, theRecordIdInt, 1, theLabel);
|
|
|
|
}
|
|
|
|
|
2005-07-03 00:18:14 +00:00
|
|
|
void GraticuleCreator::writeProjectionFile(QString theFileName )
|
|
|
|
{
|
|
|
|
// Write a WGS 84 projection file for the shapefile
|
|
|
|
theFileName = theFileName.replace(".shp",".prj");
|
|
|
|
std::ofstream of(theFileName);
|
|
|
|
if(!of.fail())
|
|
|
|
{
|
2005-09-16 23:30:38 +00:00
|
|
|
of << GEOWKT.local8Bit()
|
2005-07-03 00:18:14 +00:00
|
|
|
<< std::endl;
|
|
|
|
of.close();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2004-04-06 07:17:03 +00:00
|
|
|
void GraticuleCreator::writePoint(SHPHandle theShapeHandle, int theRecordInt, double theXDouble, double theYDouble )
|
2004-04-05 20:53:17 +00:00
|
|
|
{
|
|
|
|
SHPObject * myShapeObject;
|
2004-04-06 07:17:03 +00:00
|
|
|
myShapeObject = SHPCreateObject( SHPT_POINT, theRecordInt, 0, NULL, NULL, 1, &theXDouble, &theYDouble, NULL, NULL );
|
2004-04-05 20:53:17 +00:00
|
|
|
SHPWriteObject( theShapeHandle, -1, myShapeObject );
|
|
|
|
SHPDestroyObject( myShapeObject );
|
|
|
|
}
|
|
|
|
|
2004-04-06 07:17:03 +00:00
|
|
|
void GraticuleCreator::writeLine(SHPHandle theShapeHandle,
|
2004-04-05 20:53:17 +00:00
|
|
|
int theRecordInt,
|
|
|
|
int theCoordinateCountInt,
|
|
|
|
double * theXArrayDouble,
|
|
|
|
double * theYArrayDouble )
|
|
|
|
{
|
|
|
|
SHPObject * myShapeObject;
|
|
|
|
myShapeObject = SHPCreateObject( SHPT_ARC,
|
|
|
|
theRecordInt,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
theCoordinateCountInt,
|
|
|
|
theXArrayDouble,
|
|
|
|
theYArrayDouble,
|
|
|
|
NULL,
|
|
|
|
NULL );
|
|
|
|
SHPWriteObject( theShapeHandle, -1, myShapeObject );
|
|
|
|
SHPDestroyObject( myShapeObject );
|
|
|
|
}
|
|
|
|
|
2004-04-05 23:11:52 +00:00
|
|
|
//TODO: check for rediculous intervals!
|
2004-11-09 01:04:00 +00:00
|
|
|
void GraticuleCreator::generateGraticule(DBFHandle theDbfHandle,
|
|
|
|
SHPHandle theShapeHandle,
|
|
|
|
double theXIntervalDouble,
|
|
|
|
double theYIntervalDouble,
|
|
|
|
double theXOriginDouble,
|
|
|
|
double theYOriginDouble,
|
|
|
|
double theXEndPointDouble,
|
|
|
|
double theYEndPointDouble)
|
2004-04-05 23:11:52 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
int myRecordInt=0;
|
2004-04-06 07:17:03 +00:00
|
|
|
//create the arrays for storing the coordinates
|
|
|
|
double * myXArrayDouble;
|
|
|
|
double * myYArrayDouble;
|
2005-04-10 07:04:07 +00:00
|
|
|
//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 myXIntersectionCount = ((theXEndPointDouble - theXOriginDouble) / theXIntervalDouble)+1;
|
|
|
|
long myYIntersectionCount = ((theYEndPointDouble - theYOriginDouble) / theYIntervalDouble)+1;
|
|
|
|
|
2004-04-06 07:17:03 +00:00
|
|
|
|
2004-04-05 23:11:52 +00:00
|
|
|
//
|
|
|
|
//Longitude loop
|
|
|
|
//
|
2005-04-10 07:04:07 +00:00
|
|
|
myXArrayDouble = (double *)malloc(myYIntersectionCount * sizeof(double));
|
|
|
|
myYArrayDouble = (double *)malloc(myYIntersectionCount * sizeof(double));
|
2004-11-09 01:04:00 +00:00
|
|
|
for (double myXDouble = theXOriginDouble;myXDouble <=theXEndPointDouble;myXDouble+=theXIntervalDouble)
|
2004-04-05 23:11:52 +00:00
|
|
|
{
|
2005-04-10 07:04:07 +00:00
|
|
|
long myVertexNo=0;
|
|
|
|
for (double myYDouble=theYOriginDouble;myYDouble<=theYEndPointDouble;myYDouble+=theYIntervalDouble)
|
|
|
|
{
|
|
|
|
myXArrayDouble[myVertexNo]=myXDouble;
|
|
|
|
myYArrayDouble[myVertexNo]=myYDouble;
|
|
|
|
++myVertexNo;
|
|
|
|
}
|
2004-04-06 07:17:03 +00:00
|
|
|
writeDbfRecord(theDbfHandle,myRecordInt,"testing");
|
2005-04-10 07:04:07 +00:00
|
|
|
writeLine(theShapeHandle, myRecordInt, myYIntersectionCount, myXArrayDouble, myYArrayDouble);
|
|
|
|
|
2004-04-06 07:17:03 +00:00
|
|
|
++myRecordInt;
|
2004-04-05 23:11:52 +00:00
|
|
|
}
|
2005-04-10 07:04:07 +00:00
|
|
|
delete myXArrayDouble;
|
|
|
|
delete myYArrayDouble;
|
2004-04-05 23:11:52 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
//Latitude loop
|
|
|
|
//
|
2005-04-10 07:04:07 +00:00
|
|
|
myXArrayDouble = (double *)malloc(myXIntersectionCount * sizeof(double));
|
|
|
|
myYArrayDouble = (double *)malloc(myXIntersectionCount * sizeof(double));
|
2004-11-09 01:04:00 +00:00
|
|
|
for (double myYDouble=theYOriginDouble;myYDouble<=theYEndPointDouble;myYDouble+=theYIntervalDouble)
|
2004-04-05 23:11:52 +00:00
|
|
|
{
|
2005-04-10 07:04:07 +00:00
|
|
|
long myVertexNo=0;
|
|
|
|
for (double myXDouble=theXOriginDouble;myXDouble<=theXEndPointDouble;myXDouble+=theXIntervalDouble)
|
|
|
|
{
|
|
|
|
myXArrayDouble[myVertexNo]=myXDouble;
|
|
|
|
myYArrayDouble[myVertexNo]=myYDouble;
|
|
|
|
++myVertexNo;
|
|
|
|
}
|
2004-04-05 23:11:52 +00:00
|
|
|
|
2004-04-06 07:17:03 +00:00
|
|
|
writeDbfRecord(theDbfHandle,myRecordInt,"testing");
|
2005-04-10 07:04:07 +00:00
|
|
|
writeLine(theShapeHandle, myRecordInt,myXIntersectionCount, myXArrayDouble, myYArrayDouble);
|
2004-04-05 23:11:52 +00:00
|
|
|
|
2004-04-06 07:17:03 +00:00
|
|
|
++myRecordInt;
|
2004-04-05 23:11:52 +00:00
|
|
|
}
|
|
|
|
|
2004-04-06 07:17:03 +00:00
|
|
|
delete myXArrayDouble;
|
|
|
|
delete myYArrayDouble;
|
2005-07-03 00:18:14 +00:00
|
|
|
// write a proj file for the graticule
|
|
|
|
|
2004-04-05 23:11:52 +00:00
|
|
|
}
|
2004-04-05 20:53:17 +00:00
|
|
|
|
|
|
|
/* read from fp and generate point shapefile to theDbfHandle/theShapeHandle */
|
|
|
|
void GraticuleCreator::generatePoints (QString theInputFileName, DBFHandle theDbfHandle, SHPHandle theShapeHandle)
|
|
|
|
{
|
|
|
|
QFile myFile( theInputFileName );
|
|
|
|
if ( myFile.open( IO_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...
|
2004-04-06 07:17:03 +00:00
|
|
|
double x=myLongQString.toDouble();
|
|
|
|
double y=myLatQString.toDouble();
|
2004-04-05 20:53:17 +00:00
|
|
|
//create the dbf and shape recs
|
2005-09-16 23:30:38 +00:00
|
|
|
std::cerr << "Writing record: " << myDateQString.local8Bit() << " - " << x << " - " << y << std::endl;
|
2004-04-05 20:53:17 +00:00
|
|
|
writeDbfRecord(theDbfHandle, myRecordInt, myDateQString);
|
|
|
|
writePoint(theShapeHandle, myRecordInt, x, y);
|
|
|
|
myRecordInt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
myFile.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|