38
46
#define QGISEXTERN extern "C"
41
QgsDelimitedTextProvider::QgsDelimitedTextProvider(QString uri)
42
:mDataSourceUri(uri), mMinMaxCacheDirty(true)
49
QgsDelimitedTextProvider::QgsDelimitedTextProvider(QString uri)
50
: mDataSourceUri(uri),
51
mMinMaxCacheDirty(true)
44
53
// Get the file name and mDelimiter out of the uri
45
54
mFileName = uri.left(uri.find("?"));
46
55
// split the string up on & to get the individual parameters
47
56
QStringList parameters = QStringList::split("&", uri.mid(uri.find("?")));
49
std::cerr << "Parameter count after split on &" << parameters.size() << std::endl;
58
std::cerr << "Parameter count after split on &" << parameters.
51
61
// get the individual parameters and assign values
52
62
QStringList temp = parameters.grep("delimiter=");
53
mDelimiter = temp.size() ?temp[0].mid(temp[0].find("=") +1):"";
63
mDelimiter = temp.size()? temp[0].mid(temp[0].find("=") + 1) : "";
54
64
temp = parameters.grep("xField=");
55
mXField = temp.size() ?temp[0].mid(temp[0].find("=") +1):"";
65
mXField = temp.size()? temp[0].mid(temp[0].find("=") + 1) : "";
56
66
temp = parameters.grep("yField=");
57
mYField = temp.size() ?temp[0].mid(temp[0].find("=") +1):"";
67
mYField = temp.size()? temp[0].mid(temp[0].find("=") + 1) : "";
68
// Decode the parts of the uri. Good if someone entered '=' as a delimiter, for instance.
69
QUrl::decode(mFileName);
70
QUrl::decode(mDelimiter);
71
QUrl::decode(mXField);
72
QUrl::decode(mYField);
59
std::cerr << "Data source uri is " << uri << std::endl;
60
std::cerr << "Delimited text file is: " << mFileName << std::endl;
61
std::cerr << "Delimiter is: " << mDelimiter << std::endl;
62
std::cerr << "xField is: " << mXField << std::endl;
63
std::cerr << "yField is: " << mYField << std::endl;
74
std::cerr << "Data source uri is " << (const char *)uri.local8Bit() << std::endl;
75
std::cerr << "Delimited text file is: " << (const char *)mFileName.local8Bit() << std::endl;
76
std::cerr << "Delimiter is: " << (const char *)mDelimiter.local8Bit() << std::endl;
77
std::cerr << "xField is: " << (const char *)mXField.local8Bit() << std::endl;
78
std::cerr << "yField is: " << (const char *)mYField.local8Bit() << std::endl;
65
80
// Set the selection rectangle to null
66
81
mSelectionRectangle = 0;
67
82
// assume the layer is invalid until proven otherwise
69
if(!mFileName.isEmpty() && !mDelimiter.isEmpty() && !mXField.isEmpty() && !mYField.isEmpty()){
84
if (!mFileName.isEmpty() && !mDelimiter.isEmpty() && !mXField.isEmpty() &&
70
87
// check to see that the file exists and perform some sanity checks
71
if(QFile::exists(mFileName)){
88
if (QFile::exists(mFileName))
72
90
// Open the file and get number of rows, etc. We assume that the
73
91
// file has a header row and process accordingly. Caller should make
74
92
// sure the the delimited file is properly formed.
75
93
mFile = new QFile(mFileName);
76
if ( mFile->open( IO_ReadOnly ) ) {
77
QTextStream stream( mFile );
94
if (mFile->open(IO_ReadOnly))
96
QTextStream stream(mFile);
79
98
mNumberFeatures = 0;
81
100
int lineNumber = 0;
82
101
// set the initial extent
83
mExtent = new QgsRect(9999999999999.0,9999999999999.0,-9999999999999.0,-9999999999999.0);
84
while ( !stream.atEnd() ) {
102
mExtent = new QgsRect();
103
mExtent->setMinimal(); // This defeats normalization
104
while (!stream.atEnd())
86
line = stream.readLine(); // line of text excluding '\n'
87
if(mNumberFeatures++ == 0){
107
line = stream.readLine(); // line of text excluding '\n', default local 8 bit encoding.
108
if (mNumberFeatures++ == 0)
88
110
// Get the fields from the header row and store them in the
91
std::cerr << "Attempting to split the input line: " << line <<
92
" using delimiter " << mDelimiter << std::endl;
114
cerr << "Attempting to split the input line: " << (const char *)line.local8Bit() <<
115
" using delimiter " << (const char *)mDelimiter.local8Bit() << std::endl;
94
QStringList fieldList = QStringList::split(QRegExp(mDelimiter), line, true);
117
QStringList fieldList =
118
QStringList::split(QRegExp(mDelimiter), line, true);
96
std::cerr << "Split line into " << fieldList.size() << " parts" << std::endl;
120
std::cerr << "Split line into " << fieldList.
121
size() << " parts" << std::endl;
98
123
// We don't know anything about a text based field other
99
124
// than its name. All fields are assumed to be text
100
125
int fieldPos = 0;
101
for ( QStringList::Iterator it = fieldList.begin(); it != fieldList.end(); ++it )
126
for (QStringList::Iterator it = fieldList.begin();
127
it != fieldList.end(); ++it)
103
129
QString field = *it;
104
if(field.length() > 0)
106
attributeFields.push_back(QgsField(*it, "Text"));
107
fieldPositions[*it] = fieldPos++;
108
// check to see if this field matches either the x or y field
112
std::cerr << "Found x field " << *it << std::endl;
119
std::cerr << "Found y field " << *it << std::endl;
124
std::cerr << "Adding field: " << *it << std::endl;
130
if (field.length() > 0)
132
attributeFields.push_back(QgsField(*it, "Text"));
133
fieldPositions[*it] = fieldPos++;
134
// check to see if this field matches either the x or y field
138
std::cerr << "Found x field " << (const char *)(*it).local8Bit() << std::endl;
145
std::cerr << "Found y field " << (const char *)(*it).local8Bit() << std::endl;
150
std::cerr << "Adding field: " << (const char *)(*it).local8Bit() << std::endl;
130
std::cerr << "Field count for the delimited text file is " << attributeFields.size() << std::endl;
157
cerr << "Field count for the delimited text file is " <<
158
attributeFields.size() << std::endl;
134
163
// examine the x,y and update extents
135
164
// std::cout << line << std::endl;
136
165
// split the line on the delimiter
137
QStringList parts = QStringList::split(QRegExp(mDelimiter), line, true);
167
QStringList::split(QRegExp(mDelimiter), line, true);
138
168
//if(parts.size() == attributeFields.size())
140
170
// // we can populate attributes if required
225
for(int i=0;i<fieldCount();i++)
260
for (int i = 0; i < fieldCount(); i++)
227
262
delete mMinMaxCache[i];
229
delete[] mMinMaxCache;
264
delete[]mMinMaxCache;
233
268
* Get the first feature resutling from a select operation
234
269
* @return QgsFeature
236
QgsFeature *QgsDelimitedTextProvider::getFirstFeature( bool fetchAttributes)
271
QgsFeature * QgsDelimitedTextProvider::getFirstFeature(bool fetchAttributes)
242
std::cerr << "getting first feature\n";
244
ogrLayer->ResetReading();
245
OGRFeature *feat = ogrLayer->GetNextFeature();
248
std::cerr << "First feature is not null\n";
252
std::cerr << "First feature is null\n";
255
f = new QgsFeature(feat->GetFID());
256
f->setGeometry(getGeometryPointer(feat));
258
getFeatureAttributes(feat, f);
273
QgsFeature *f = new QgsFeature;
275
reset(); // reset back to first feature
277
if ( getNextFeature_( *f, fetchAttributes ) )
285
} // QgsDelimitedTextProvider::getFirstFeature(bool fetchAttributes)
289
insure double value is properly translated into locate endian-ness
267
* Get the next feature resulting from a select operation
268
* Return 0 if there are no features in the selection set
271
bool QgsDelimitedTextProvider::getNextFeature(QgsFeature &feature, bool fetchAttributes)
273
// We must manually check each point to see if it is within the
274
// selection rectangle
280
QTextStream stream( mFile );
282
if ( !stream.atEnd() ) {
284
std::cerr << "Stream read" << std::endl;
286
line = stream.readLine(); // line of text excluding '\n'
287
// create the geometry from the x, y fields
288
QStringList parts = QStringList::split(QRegExp(mDelimiter), line, true);
289
// Get the x and y values, first checking to make sure they
291
QString sX = parts[fieldPositions[mXField]];
292
QString sY = parts[fieldPositions[mYField]];
293
std::cerr << "x ,y " << sX << ", " << sY << std::endl;
296
double x = sX.toDouble(&xOk);
297
double y = sY.toDouble(&yOk);
300
if(mSelectionRectangle == 0)
302
// no selection in place
306
// check to see if point is in bounds
307
processPoint = boundsCheck(x, y);
311
std::cerr << "Processing " << x << ", " << y << std::endl;
313
wkbPoint *geometry = new wkbPoint;
314
geometry->byteOrder = endian();
315
geometry->wkbType = 1;
318
feature.setGeometry((unsigned char *)geometry, sizeof(wkbPoint));
319
feature.setValid(true);
320
// get the attributes if requested
322
for(int fi =0; fi < attributeFields.size(); fi++)
324
feature.addAttribute(attributeFields.at(fi).name(), parts[fi]);
328
QString sX = parts[fieldPositions[mXField]];
332
feature.setValid(false);
336
// Return true since the read was successful. The feature itself
337
// may be invalid for various reasons
342
std::cerr << "Stream is at end" << std::endl;
344
// Return false since read of next feature failed
346
// Set the feature to invalid
347
feature.setValid(false);
352
QString sReturn = returnValue?"true":"false" ;
353
std::cerr << "Returning " << sReturn << " from getNextFeature" << std::endl;
359
* Get the next feature resulting from a select operation
360
* Return 0 if there are no features in the selection set
363
QgsFeature *QgsDelimitedTextProvider::getNextFeature(bool fetchAttributes)
365
// We must manually check each point to see if it is within the
366
// selection rectangle
371
QTextStream stream( mFile );
373
if ( !stream.atEnd() ) {
374
line = stream.readLine(); // line of text excluding '\n'
375
// create the geometry from the x, y fields
376
QStringList parts = QStringList::split(QRegExp(mDelimiter), line, true);
377
// Get the x and y values, first checking to make sure they
379
QString sX = parts[fieldPositions[mXField]];
380
QString sY = parts[fieldPositions[mYField]];
381
//std::cout << "x ,y " << sX << ", " << sY << std::endl;
384
double x = sX.toDouble(&xOk);
385
double y = sY.toDouble(&yOk);
388
if(mSelectionRectangle == 0)
390
// no selection in place
394
// check to see if point is in bounds
395
processPoint = boundsCheck(x, y);
398
// we need to continue to read until we get a hit in the
399
// selection rectangle or the EOF is reached
400
while(!stream.atEnd() && !processPoint)
403
line = stream.readLine();
405
// create the geometry from the x, y fields
406
parts = QStringList::split(QRegExp(mDelimiter), line, true);
407
// Get the x and y values, first checking to make sure they
409
sX = parts[fieldPositions[mXField]];
410
sY = parts[fieldPositions[mYField]];
411
//std::cout << "x ,y " << sX << ", " << sY << std::endl;
414
x = sX.toDouble(&xOk);
415
y = sY.toDouble(&yOk);
418
processPoint = boundsCheck(x, y);
426
//std::cout << "Processing " << x << ", " << y << std::endl;
429
unsigned char * geometry = new unsigned char[sizeof(wkbPt)];
430
geometry[0] = endian();
432
void *ptr = geometry+1;
433
memcpy((void*)(geometry +1), &type, 4);
434
memcpy((void*)(geometry +5), &x, sizeof(x));
435
memcpy((void*)(geometry +13), &y, sizeof(y));
437
geometry->byteOrder = endian();
438
geometry->wkbType = 1;
442
f = new QgsFeature();
443
f->setGeometry(geometry, sizeof(wkbPt));
444
//std::cerr << "Setting feature id to " << mFid << std::endl;
445
f->setFeatureId(mFid++);
446
// get the attributes if requested
448
// add the attributes to the attribute map
449
for(int fi =0; fi < attributeFields.size(); fi++)
451
f->addAttribute(attributeFields.at(fi).name(), parts[fi]);
464
QgsFeature * QgsDelimitedTextProvider::getNextFeature(std::list<int>& attlist)
466
// We must manually check each point to see if it is within the
467
// selection rectangle
472
QTextStream stream( mFile );
474
if ( !stream.atEnd() ) {
475
line = stream.readLine(); // line of text excluding '\n'
476
// create the geometry from the x, y fields
477
QStringList parts = QStringList::split(QRegExp(mDelimiter), line, true);
478
// Get the x and y values, first checking to make sure they
480
QString sX = parts[fieldPositions[mXField]];
481
QString sY = parts[fieldPositions[mYField]];
482
//std::cout << "x ,y " << sX << ", " << sY << std::endl;
485
double x = sX.toDouble(&xOk);
486
double y = sY.toDouble(&yOk);
489
if(mSelectionRectangle == 0)
491
// no selection in place
495
// check to see if point is in bounds
496
processPoint = boundsCheck(x, y);
499
// we need to continue to read until we get a hit in the
500
// selection rectangle or the EOF is reached
501
while(!stream.atEnd() && !processPoint)
504
line = stream.readLine();
506
// create the geometry from the x, y fields
507
parts = QStringList::split(QRegExp(mDelimiter), line, true);
508
// Get the x and y values, first checking to make sure they
510
sX = parts[fieldPositions[mXField]];
511
sY = parts[fieldPositions[mYField]];
512
//std::cout << "x ,y " << sX << ", " << sY << std::endl;
515
x = sX.toDouble(&xOk);
516
y = sY.toDouble(&yOk);
519
processPoint = boundsCheck(x, y);
527
//std::cout << "Processing " << x << ", " << y << std::endl;
530
unsigned char * geometry = new unsigned char[sizeof(wkbPt)];
531
geometry[0] = endian();
533
void *ptr = geometry+1;
534
memcpy((void*)(geometry +1), &type, 4);
535
memcpy((void*)(geometry +5), &x, sizeof(x));
536
memcpy((void*)(geometry +13), &y, sizeof(y));
538
geometry->byteOrder = endian();
539
geometry->wkbType = 1;
543
f = new QgsFeature();
544
f->setGeometry(geometry, sizeof(wkbPt));
545
//std::cerr << "Setting feature id to " << mFid << std::endl;
546
f->setFeatureId(mFid++);
548
// add the attributes to the attribute map
549
for(std::list<int>::iterator iter=attlist.begin();iter!=attlist.end();++iter)
551
f->addAttribute(attributeFields.at(*iter).name(), parts[*iter]);
294
translateDouble_( double d )
302
// break double into byte sized chunks
305
to.char_val[7] = from.char_val[0];
306
to.char_val[6] = from.char_val[1];
307
to.char_val[5] = from.char_val[2];
308
to.char_val[4] = from.char_val[3];
309
to.char_val[3] = from.char_val[4];
310
to.char_val[2] = from.char_val[5];
311
to.char_val[1] = from.char_val[6];
312
to.char_val[0] = from.char_val[7];
316
} // translateDouble_
320
QgsDelimitedTextProvider::getNextFeature_( QgsFeature & feature,
322
std::list<int> const * desiredAttributes )
324
// before we do anything else, assume that there's something wrong with
326
feature.setValid( false );
328
QTextStream textStream( mFile );
330
if ( ! textStream.atEnd() )
332
QString line = textStream.readLine(); // Default local 8 bit encoding
334
// lex the tokens from the current data line
335
QStringList tokens = QStringList::split(QRegExp(mDelimiter), line, true);
340
int xFieldPos = fieldPositions[mXField];
341
int yFieldPos = fieldPositions[mYField];
343
double x = tokens[xFieldPos].toDouble( &xOk );
344
double y = tokens[yFieldPos].toDouble( &yOk );
348
// if the user has selected an area, constrain iterator to
349
// features that are within that area
350
if ( mSelectionRectangle && ! boundsCheck(x,y) )
352
bool foundFeature = false;
354
while ( ! textStream.atEnd() &&
357
if ( boundsCheck(x,y) )
363
++mFid; // since we're skipping to next feature,
366
line = textStream.readLine();
368
tokens = QStringList::split(QRegExp(mDelimiter), line, true);
370
x = tokens[xFieldPos].toDouble( &xOk );
371
y = tokens[yFieldPos].toDouble( &yOk );
374
// there were no other features from the current one forward
375
// that were within the selection region
376
if ( ! foundFeature )
382
// at this point, one way or another, the current feature values
384
feature.setValid( true );
386
++mFid; // increment to next feature ID
388
feature.setFeatureId( mFid );
390
unsigned char * geometry = new unsigned char[sizeof(wkbPoint)];
392
buffer.setRawData( (const char*)geometry, sizeof(wkbPoint) ); // buffer
397
QDataStream s( buffer, IO_WriteOnly ); // open on buffers's data
401
case QgsDataProvider::NDR :
402
// we're on a little-endian platform, so tell the data
403
// stream to use that
404
s.setByteOrder( QDataStream::LittleEndian );
405
s << (Q_UINT8)1; // 1 is for little-endian
407
case QgsDataProvider::XDR :
408
// don't change byte order since QDataStream is big endian by default
409
s << (Q_UINT8)0; // 0 is for big-endian
412
qDebug( "%s:%d unknown endian", __FILE__, __LINE__ );
417
s << (Q_UINT32)1; // 1 is for WKBPoint
422
// XXX Umm, does the feature own the wkbPoint now?
423
feature.setGeometry( geometry, sizeof(wkbPoint) );
425
// ensure that the buffer doesn't delete the data on us
426
buffer.resetRawData( (const char*)geometry, sizeof(wkbPoint) );
428
if ( getAttributes && ! desiredAttributes )
430
for (int fi = 0; fi < attributeFields.size(); fi++)
432
feature.addAttribute(attributeFields[fi].name(), tokens[fi]);
435
// regardless of whether getAttributes is true or not, if the
436
// programmer went through the trouble of passing in such a list of
437
// attribute fields, then obviously they want them
438
else if ( desiredAttributes )
440
for ( std::list<int>::const_iterator i = desiredAttributes->begin();
441
i != desiredAttributes->end();
444
feature.addAttribute(attributeFields[*i].name(), tokens[*i]);
450
} // if able to get x and y coordinates
452
} // ! textStream EOF
456
} // getNextFeature_( QgsFeature & feature )
461
Get the next feature resulting from a select operation
462
Return 0 if there are no features in the selection set
463
* @return false if unable to get the next feature
465
bool QgsDelimitedTextProvider::getNextFeature(QgsFeature & feature,
466
bool fetchAttributes)
468
return getNextFeature_( feature, fetchAttributes );
469
} // QgsDelimitedTextProvider::getNextFeature
473
QgsFeature * QgsDelimitedTextProvider::getNextFeature(bool fetchAttributes)
475
QgsFeature * f = new QgsFeature;
477
if ( getNextFeature( *f, fetchAttributes ) )
485
} // QgsDelimitedTextProvider::getNextFeature(bool fetchAttributes)
489
QgsFeature * QgsDelimitedTextProvider::getNextFeature(std::list<int> const & desiredAttributes )
491
QgsFeature * f = new QgsFeature;
493
if ( getNextFeature_( *f, true, &desiredAttributes ) )
502
} // QgsDelimitedTextProvider::getNextFeature(std::list < int >&attlist)
562
508
* Select features based on a bounding rectangle. Features can be retrieved
563
509
* with calls to getFirstFeature and getNextFeature.
564
510
* @param mbr QgsRect containing the extent to use in selecting features
566
void QgsDelimitedTextProvider::select(QgsRect *rect, bool useIntersect)
512
void QgsDelimitedTextProvider::select(QgsRect * rect, bool useIntersect)
569
515
// Setting a spatial filter doesn't make much sense since we have to
775
721
bool QgsDelimitedTextProvider::boundsCheck(double x, double y)
777
723
bool inBounds = (((x < mSelectionRectangle->xMax()) &&
778
(x > mSelectionRectangle->xMin())) &&
779
((y < mSelectionRectangle->yMax()) &&
780
(y > mSelectionRectangle->yMin())));
781
// QString hit = inBounds?"true":"false";
724
(x > mSelectionRectangle->xMin())) &&
725
((y < mSelectionRectangle->yMax()) &&
726
(y > mSelectionRectangle->yMin())));
727
// QString hit = inBounds?"true":"false";
783
// std::cerr << "Checking if " << x << ", " << y << " is in " <<
784
//mSelectionRectangle->stringRep().ascii() << ": " << hit.ascii() << std::endl;
729
// std::cerr << "Checking if " << x << ", " << y << " is in " <<
730
//mSelectionRectangle->stringRep().ascii() << ": " << hit.ascii() << std::endl;
787
bool QgsDelimitedTextProvider::supportsSaveAsShapefile()
734
int QgsDelimitedTextProvider::capabilities() const
736
return QgsVectorDataProvider::SaveAsShapefile;
792
740
bool QgsDelimitedTextProvider::saveAsShapefile()
794
742
// save the layer as a shapefile
795
743
QString driverName = "ESRI Shapefile";
796
744
OGRSFDriver *poDriver;
797
745
OGRRegisterAll();
798
poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName((const char *)driverName );
747
OGRSFDriverRegistrar::GetRegistrar()->
748
GetDriverByName((const char *)driverName.local8Bit());
799
749
bool returnValue = true;
800
if( poDriver != NULL )
750
if (poDriver != NULL)
802
752
// get a name for the shapefile
803
753
// Get a file to process, starting at the current directory
804
754
// Set inital dir to last used in delimited text plugin
805
755
QSettings settings;
807
QString shapefileName = QFileDialog::getSaveFileName(
808
settings.readEntry("/Qgis/delimited_text_plugin/text_path","./"),
809
"Shapefiles (*.shp)",
812
"Save delimited text layer as shapefile" );
814
if(!shapefileName.isNull())
757
QString shapefileName;
758
QString filter = QString("Shapefiles (*.shp)");
759
QString dirName = settings.readEntry("/Qgis/delimited_text_plugin/text_path", "./");
761
QgsEncodingFileDialog* openFileDialog = new QgsEncodingFileDialog(dirName,
764
QString("save file dialog"),
767
// allow for selection of more than one file
768
openFileDialog->setMode(QFileDialog::AnyFile);
769
openFileDialog->setCaption(tr("Save layer as..."));
772
if (openFileDialog->exec() == QDialog::Accepted)
774
shapefileName = openFileDialog->selectedFile();
775
enc = openFileDialog->encoding();
782
if (!shapefileName.isNull())
816
784
// add the extension if not present
817
if(shapefileName.find(".shp") == -1)
785
if (shapefileName.find(".shp") == -1)
819
787
shapefileName += ".shp";
821
789
OGRDataSource *poDS;
822
// create the data source
823
poDS = poDriver->CreateDataSource( (const char *)shapefileName, NULL );
790
// create the data source, use local8Bit() for filename
791
poDS = poDriver->CreateDataSource((const char *) shapefileName.local8Bit(), NULL);
826
std::cerr << "created datasource" << std::endl;
827
// datasource created, now create the output layer
794
QTextCodec* saveCodec = QTextCodec::codecForName(enc.local8Bit());
798
qWarning("error finding QTextCodec in QgsDelimitedTextProvider::saveAsShapefile()");
800
saveCodec = QTextCodec::codecForLocale();
803
std::cerr << "created datasource" << std::endl;
804
// datasource created, now create the output layer, use selected encoding.
828
805
OGRLayer *poLayer;
829
poLayer = poDS->CreateLayer((const char *)shapefileName.left(shapefileName.find(".shp")), NULL, static_cast<OGRwkbGeometryType>(1), NULL );
830
if( poLayer != NULL )
806
poLayer = poDS->CreateLayer(saveCodec->fromUnicode(shapefileName.
807
left(shapefileName.find(".shp"))), NULL,
808
static_cast < OGRwkbGeometryType > (1), NULL);
832
std::cerr << "created layer" << std::endl;
811
std::cerr << "created layer" << std::endl;
833
812
// calculate the field lengths
834
813
int *lengths = getFieldLengths();
835
814
// create the fields
836
std::cerr << "creating " << attributeFields.size() << " fields" << std::endl;
837
for(int i = 0; i < attributeFields.size(); i++)
815
std::cerr << "creating " << attributeFields.
816
size() << " fields" << std::endl;
817
for (int i = 0; i < attributeFields.size(); i++)
839
819
// check the field length - if > 10 we need to truncate it
840
820
QgsField attrField = attributeFields[i];
841
if(attrField.name().length() > 10)
821
if (attrField.name().length() > 10)
843
823
attrField = attrField.name().left(10);
845
825
// all fields are created as string (for now)
846
OGRFieldDefn fld(attrField.name(), OFTString);
826
OGRFieldDefn fld(saveCodec->fromUnicode(attrField.name()), OFTString);
847
827
// set the length for the field -- but we don't know what it is...
848
828
fld.SetWidth(lengths[i]);
849
829
// create the field
850
std::cerr << "creating field " << attrField.name() << " width length " << lengths[i] << std::endl;
851
if(poLayer->CreateField(&fld) != OGRERR_NONE)
830
std::cerr << "creating field " << (const char *)attrField.
831
name().local8Bit() << " width length " << lengths[i] << std::endl;
832
if (poLayer->CreateField(&fld) != OGRERR_NONE)
853
QMessageBox::warning(0, "Error", "Error creating field " + attrField.name());
834
QMessageBox::warning(0, "Error",
835
"Error creating field " + attrField.name());
856
838
// read the delimited text file and create the features
857
std::cerr << "Done creating fields" << std::endl;
839
std::cerr << "Done creating fields" << std::endl;
860
QTextStream stream( mFile );
842
QTextStream stream(mFile);
862
while ( !stream.atEnd() ) {
844
while (!stream.atEnd())
863
846
line = stream.readLine(); // line of text excluding '\n'
864
std::cerr << line << std::endl;
847
std::cerr << (const char *)line.local8Bit() << std::endl;
865
848
// split the line
866
QStringList parts = QStringList::split(QRegExp(mDelimiter), line, true);
867
std::cerr << "Split line into " << parts.size() << std::endl;
850
QStringList::split(QRegExp(mDelimiter), line, true);
851
std::cerr << "Split line into " << parts.size() << std::endl;
869
853
// create the feature
870
854
OGRFeature *poFeature;
872
poFeature = new OGRFeature( poLayer->GetLayerDefn() );
856
poFeature = new OGRFeature(poLayer->GetLayerDefn());
874
858
// iterate over the parts and set the fields
875
std::cerr << "Setting the field values" << std::endl;
859
std::cerr << "Setting the field values" << std::endl;
876
860
// set limit - we will ignore extra fields on the line
877
861
int limit = attributeFields.size();
879
if(parts.size() < limit){
863
if (parts.size() < limit)
881
866
// this is bad - not enough values where supplied on the line
882
867
// TODO We should inform the user about this...
887
for ( int i = 0; i < limit; i++ )
889
if(parts[i] != QString::null)
891
std::cerr << "Setting " << i << " " << attributeFields[i].name() << " to " << parts[i] << std::endl;
892
poFeature->SetField(attributeFields[i].name(), parts[i]);
872
for (int i = 0; i < limit; i++)
874
if (parts[i] != QString::null)
876
std::cerr << "Setting " << i << " " << (const char *)attributeFields[i].
877
name().local8Bit() << " to " << (const char *)parts[i].local8Bit() << std::endl;
878
poFeature->SetField(saveCodec->fromUnicode(attributeFields[i].name()),
879
saveCodec->fromUnicode(parts[i]));
884
poFeature->SetField(saveCodec->fromUnicode(attributeFields[i].name()), "");
887
std::cerr << "Field values set" << std::endl;
889
OGRPoint *poPoint = new OGRPoint();
890
QString sX = parts[fieldPositions[mXField]];
891
QString sY = parts[fieldPositions[mYField]];
892
poPoint->setX(sX.toDouble());
893
poPoint->setY(sY.toDouble());
894
std::cerr << "Setting geometry" << std::endl;
896
poFeature->SetGeometryDirectly(poPoint);
897
if (poLayer->CreateFeature(poFeature) != OGRERR_NONE)
899
std::cerr << "Failed to create feature in shapefile" << std::
897
poFeature->SetField(attributeFields[i].name(), "");
904
std::cerr << "Added feature" << std::endl;
900
std::cerr << "Field values set" << std::endl;
902
OGRPoint *poPoint = new OGRPoint();
903
QString sX = parts[fieldPositions[mXField]];
904
QString sY = parts[fieldPositions[mYField]];
905
poPoint->setX(sX.toDouble());
906
poPoint->setY(sY.toDouble());
907
std::cerr << "Setting geometry" << std::endl;
909
poFeature->SetGeometryDirectly(poPoint);
910
if(poLayer->CreateFeature(poFeature) != OGRERR_NONE)
912
std::cerr << "Failed to create feature in shapefile" << std::endl;
916
std::cerr << "Added feature" << std::endl;
926
QMessageBox::warning(0,"Error", "Layer creation failed");
914
QMessageBox::warning(0, "Error", "Layer creation failed");
932
QMessageBox::warning(0, "Error creating shapefile",
933
"The shapefile could not be created (" + shapefileName + ")");
920
QMessageBox::warning(0, "Error creating shapefile",
921
"The shapefile could not be created (" +
922
shapefileName + ")");