Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
Application of patch from ticket #3259 - support WKT field in delimited
text plugin.
commit 0dc370a39c7349d85859fac462e91e346bf8fb83
    Modified context help to reflect addition of WKT capability to the
    delimited text plugin.
    Tightened up the delimited text dialog a bit.
commit 25484867621d6b4760952a8f00a07d253273ecfd
    Added *.wkt to file open filter
commit 9f16a276b6b2ecbea2eebede50e3275a1df0389b
    Patch for providing wkt support in delimited text plugin

git-svn-id: http://svn.osgeo.org/qgis/trunk@14781 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
gsherman committed Nov 29, 2010
1 parent 5a28acc commit f404e0f
Show file tree
Hide file tree
Showing 7 changed files with 600 additions and 308 deletions.
42 changes: 33 additions & 9 deletions resources/context_help/QgsDelimitedTextPluginGui-en_US
Expand Up @@ -4,6 +4,7 @@ Loads and displays delimited text files containing x,y coordinates.
<p>
<a href="#re">Requirements</a><br/>
<a href="#example">Example of a valid text file</a><br/>
<a href="#wkt_example">Example of a valid text file with a WKT field</a><br/>
<a href="#notes">Notes</a><br/>

<a name="re">
Expand All @@ -12,24 +13,47 @@ Loads and displays delimited text files containing x,y coordinates.
To view a delimited text file as layer, the text file must contain:
<ol>
<li>A delimited header row of field names. This must be the first line in the text file.</li>
<li>The header row must contain an X and Y field. These fields can have any name.</li>
<li>The header row must contain an X and Y field <em>or</em> a Well Known Text (WKT) field. These fields can have any name.</li>
<li>The <B>x</B> and <B>y</B> coordinates must be specified as a number. The coordinate system is not important.</li>
<li>A WKT field must be in the standard format.
</ol>
<a name="example">
<h4>Example of a valid text file</h4>
<h4>Example of a valid text file with x and y fields</h4>
</a>
X;Y;ELEV<br/>
-300120;7689960;13<br/>
-654360;7562040;52<br/>
1640;7512840;3<br/>
[...]<br/>
<tt>
X;Y;ELEV<br/>
-300120;7689960;13<br/>
-654360;7562040;52<br/>
1640;7512840;3<br/>
[...]<br/>
</tt>
<a name="wkt_example">
<h4>Example of a valid text file with a WKT field</h4>
</a>
<tt>
id|wkt<br/>
1|POINT(172.0702250 -43.6031036)<br/>
2|POINT(172.0702250 -43.6031036)<br/>
3|POINT(172.1543206 -43.5731302)<br/>
4|POINT(171.9282585 -43.5493308)<br/>
5|POINT(171.8827359 -43.5875983)<br/>
</tt>
<a name="notes">
<h4>Notes</h4>
</a>
<ol>
<li>The example text file uses <b>;</b> as delimiter. Any character can be used to delimit the fields.</li>
<li>The example text file:</li>
<ul>
<li> Uses <b>;</b> as delimiter. Any character can be used to delimit the fields.</li>
<li>The first row is the header row. It contains the fields X, Y and ELEV.</li>
<li>No quotes (") are used to delimit text fields.</li>
<li>The x coordinates are contained in the X field.</li>
<li>The y coordinates are contained in the Y field.</li>
</ol>
</ul>
<li>The example text file with WKT:</li>
<ul>
<li>Has two fields defined in the header row: id and wkt.
<li>Uses <b>|</b> as a delimiter.</li>
<li>Specifies each point using the WKT notation
</ul>
</ol>
2 changes: 1 addition & 1 deletion src/plugins/delimited_text/qgsdelimitedtextplugin.cpp
Expand Up @@ -102,7 +102,7 @@ void QgsDelimitedTextPlugin::initGui()
setCurrentTheme( "" );
myQActionPointer->setWhatsThis( tr( "Add a delimited text file as a map layer. "
"The file must have a header row containing the field names. "
"X and Y fields are required and must contain coordinates in decimal units." ) );
"The file must either contain X and Y fields with coordinates in decimal units or a WKT field." ) );
// Connect the action to the run
connect( myQActionPointer, SIGNAL( triggered() ), this, SLOT( run() ) );
// Add the icon to the toolbar
Expand Down
173 changes: 128 additions & 45 deletions src/plugins/delimited_text/qgsdelimitedtextplugingui.cpp
Expand Up @@ -33,7 +33,7 @@ QgsDelimitedTextPluginGui::QgsDelimitedTextPluginGui( QgisInterface * _qI, QWidg
setupUi( this );
pbnOK = buttonBox->button( QDialogButtonBox::Ok );

enableAccept();
updateFieldsAndEnable();

// at startup, fetch the last used delimiter and directory from
// settings
Expand All @@ -58,22 +58,23 @@ QgsDelimitedTextPluginGui::QgsDelimitedTextPluginGui( QgisInterface * _qI, QWidg

cmbXField->setDisabled( true );
cmbYField->setDisabled( true );
cmbWktField->setDisabled( true );

connect( txtFilePath, SIGNAL( textChanged( QString ) ), this, SLOT( enableAccept() ) );
connect( txtFilePath, SIGNAL( textChanged( QString ) ), this, SLOT( updateFieldsAndEnable() ) );

connect( delimiterSelection, SIGNAL( toggled( bool ) ), this, SLOT( enableAccept() ) );
connect( delimiterPlain, SIGNAL( toggled( bool ) ), this, SLOT( enableAccept() ) );
connect( delimiterRegexp, SIGNAL( toggled( bool ) ), this, SLOT( enableAccept() ) );
connect( delimiterSelection, SIGNAL( toggled( bool ) ), this, SLOT( updateFieldsAndEnable() ) );
connect( delimiterPlain, SIGNAL( toggled( bool ) ), this, SLOT( updateFieldsAndEnable() ) );
connect( delimiterRegexp, SIGNAL( toggled( bool ) ), this, SLOT( updateFieldsAndEnable() ) );

connect( cbxDelimSpace, SIGNAL( stateChanged( int ) ), this, SLOT( enableAccept() ) );
connect( cbxDelimTab, SIGNAL( stateChanged( int ) ), this, SLOT( enableAccept() ) );
connect( cbxDelimSemicolon, SIGNAL( stateChanged( int ) ), this, SLOT( enableAccept() ) );
connect( cbxDelimComma, SIGNAL( stateChanged( int ) ), this, SLOT( enableAccept() ) );
connect( cbxDelimColon, SIGNAL( stateChanged( int ) ), this, SLOT( enableAccept() ) );
connect( cbxDelimSpace, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );
connect( cbxDelimTab, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );
connect( cbxDelimSemicolon, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );
connect( cbxDelimComma, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );
connect( cbxDelimColon, SIGNAL( stateChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );

connect( txtDelimiter, SIGNAL( editingFinished() ), this, SLOT( enableAccept() ) );
connect( txtDelimiter, SIGNAL( editingFinished() ), this, SLOT( updateFieldsAndEnable() ) );

connect( rowCounter, SIGNAL( valueChanged( int ) ), this, SLOT( enableAccept() ) );
connect( rowCounter, SIGNAL( valueChanged( int ) ), this, SLOT( updateFieldsAndEnable() ) );
}

QgsDelimitedTextPluginGui::~QgsDelimitedTextPluginGui()
Expand Down Expand Up @@ -103,12 +104,23 @@ void QgsDelimitedTextPluginGui::on_buttonBox_accepted()
.arg( txtDelimiter->text() )
.arg( delimiterType );

if ( !cmbXField->currentText().isEmpty() && !cmbYField->currentText().isEmpty() )
{
uri += QString( "&xField=%1&yField=%2" )
.arg( cmbXField->currentText() )
.arg( cmbYField->currentText() );
}
if( geomTypeXY->isChecked())
{
if ( !cmbXField->currentText().isEmpty() && !cmbYField->currentText().isEmpty() )
{
uri += QString( "&xField=%1&yField=%2" )
.arg( cmbXField->currentText() )
.arg( cmbYField->currentText() );
}
}
else
{
if( ! cmbWktField->currentText().isEmpty() )
{
uri += QString( "&wktField=%1" )
.arg( cmbWktField->currentText() );
}
}

int skipLines = rowCounter->value();
if ( skipLines > 0 )
Expand Down Expand Up @@ -177,23 +189,59 @@ QStringList QgsDelimitedTextPluginGui::splitLine( QString line )
return fieldList;
}

bool QgsDelimitedTextPluginGui::haveValidFileAndDelimiters()
{

bool valid = true;
// If there is no valid file or field delimiters than cannot determine fields
if ( txtFilePath->text().isEmpty() || !QFile( txtFilePath->text() ).exists() )
{
valid = false;
}
else if ( delimiterSelection->isChecked() )
{
valid =
cbxDelimSpace->isChecked() ||
cbxDelimTab->isChecked() ||
cbxDelimSemicolon->isChecked() ||
cbxDelimComma->isChecked() ||
cbxDelimColon->isChecked();
}
else
{
valid = !txtDelimiter->text().isEmpty();
}
return valid;
}

void QgsDelimitedTextPluginGui::updateFieldLists()
{
// Update the x and y field dropdown boxes
QgsDebugMsg( "Updating field lists" );

disconnect( cmbXField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( enableAccept() ) );
disconnect( cmbYField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( enableAccept() ) );
disconnect( cmbWktField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( enableAccept() ) );
disconnect(geomTypeXY, SIGNAL(toggled(bool)), cmbXField, SLOT(setEnabled(bool)));
disconnect(geomTypeXY, SIGNAL(toggled(bool)), cmbYField, SLOT(setEnabled(bool)));
disconnect(geomTypeXY, SIGNAL(toggled(bool)), cmbWktField, SLOT(setDisabled(bool)));

QString columnX = cmbXField->currentText();
QString columnY = cmbYField->currentText();
QString columnWkt = cmbWktField->currentText();

// clear the field lists
cmbXField->clear();
cmbYField->clear();
cmbWktField->clear();

geomTypeXY->setEnabled( false );
geomTypeWKT->setEnabled( false );
cmbXField->setEnabled( false );
cmbYField->setEnabled( false );
cmbWktField->setEnabled( false );

if( ! haveValidFileAndDelimiters()) return;

QFile file( txtFilePath->text() );
if ( !file.open( QIODevice::ReadOnly ) )
Expand All @@ -220,6 +268,8 @@ void QgsDelimitedTextPluginGui::updateFieldLists()
//
// We don't know anything about a text based field other
// than its name. All fields are assumed to be text
bool haveFields = false;

foreach( QString field, fieldList )
{
if (( field.left( 1 ) == "'" || field.left( 1 ) == "\"" ) &&
Expand All @@ -233,10 +283,28 @@ void QgsDelimitedTextPluginGui::updateFieldLists()

cmbXField->addItem( field );
cmbYField->addItem( field );
cmbWktField->addItem( field );
haveFields = true;
}

cmbXField->setEnabled( cmbXField->count() > 0 );
cmbYField->setEnabled( cmbYField->count() > 0 );
int indexWkt = -1;
if( ! columnWkt.isEmpty() )
{
indexWkt = cmbWktField->findText( columnWkt );
}
if( indexWkt < 0 )
{
indexWkt = cmbWktField->findText("wkt", Qt::MatchContains );
}
if( indexWkt < 0 )
{
indexWkt = cmbWktField->findText("geometry", Qt::MatchContains );
}
if( indexWkt < 0 )
{
indexWkt = cmbWktField->findText("shape", Qt::MatchContains );
}
cmbWktField->setCurrentIndex( indexWkt);

int indexX = -1;
if ( !columnX.isEmpty() )
Expand Down Expand Up @@ -274,8 +342,28 @@ void QgsDelimitedTextPluginGui::updateFieldLists()

cmbYField->setCurrentIndex( indexY );

connect( cmbXField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( enableAccept() ) );
connect( cmbYField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( enableAccept() ) );

bool isXY = (geomTypeXY->isChecked() && indexX >= 0 && indexY >= 0) || indexWkt < 0;

geomTypeXY->setChecked( isXY );
geomTypeWKT->setChecked( ! isXY );

if( haveFields )
{
geomTypeXY->setEnabled(true);
geomTypeWKT->setEnabled(true);
cmbXField->setEnabled( isXY );
cmbYField->setEnabled( isXY );
cmbWktField->setEnabled( ! isXY );


connect( cmbXField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( enableAccept() ) );
connect( cmbYField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( enableAccept() ) );
connect( cmbWktField, SIGNAL( currentIndexChanged( int ) ), this, SLOT( enableAccept() ) );
connect(geomTypeXY, SIGNAL(toggled(bool)), cmbXField, SLOT(setEnabled(bool)));
connect(geomTypeXY, SIGNAL(toggled(bool)), cmbYField, SLOT(setEnabled(bool)));
connect(geomTypeXY, SIGNAL(toggled(bool)), cmbWktField, SLOT(setDisabled(bool)));
}

// clear the sample text box
tblSample->clear();
Expand Down Expand Up @@ -318,41 +406,36 @@ void QgsDelimitedTextPluginGui::getOpenFileName()
this,
tr( "Choose a delimited text file to open" ),
settings.value( "/Plugin-DelimitedText/text_path", "./" ).toString(),
"Text files (*.txt *.csv);; All files (* *.*)" );
"Text files (*.txt *.csv);; Well Known Text files (*.wkt);; All files (* *.*)" );

// set path
txtFilePath->setText( s );
}

void QgsDelimitedTextPluginGui::enableAccept()
void QgsDelimitedTextPluginGui::updateFieldsAndEnable()
{
bool enabled = false;
updateFieldLists();
enableAccept();
}

if ( txtFilePath->text().isEmpty() || !QFile( txtFilePath->text() ).exists() )
{
enabled = false;
}
else if ( delimiterSelection->isChecked() )
{
enabled =
cbxDelimSpace->isChecked() ||
cbxDelimTab->isChecked() ||
cbxDelimSemicolon->isChecked() ||
cbxDelimComma->isChecked() ||
cbxDelimColon->isChecked();
}
else
{
enabled = !txtDelimiter->text().isEmpty();
}
void QgsDelimitedTextPluginGui::enableAccept()
{

// If the geometry type field is enabled then there must be
// a valid file, and it must be
bool enabled = haveValidFileAndDelimiters();

if ( enabled )
{
updateFieldLists();

enabled = ( cmbXField->currentText().isEmpty() && cmbYField->currentText().isEmpty() )
|| ( !cmbXField->currentText().isEmpty() && !cmbYField->currentText().isEmpty() && cmbXField->currentText() != cmbYField->currentText() );
if( geomTypeXY->isChecked() )
{
enabled = !( cmbXField->currentText().isEmpty() || cmbYField->currentText().isEmpty() || cmbXField->currentText() == cmbYField->currentText() );
}
else
{
enabled = !cmbWktField->currentText().isEmpty();
}
}

pbnOK->setEnabled( enabled );
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/delimited_text/qgsdelimitedtextplugingui.h
Expand Up @@ -34,6 +34,7 @@ class QgsDelimitedTextPluginGui : public QDialog, private Ui::QgsDelimitedTextPl
QStringList splitLine( QString line );

private:
bool haveValidFileAndDelimiters();
void updateFieldLists();
void getOpenFileName();

Expand All @@ -47,6 +48,7 @@ class QgsDelimitedTextPluginGui : public QDialog, private Ui::QgsDelimitedTextPl
void on_btnBrowseForFile_clicked();

public slots:
void updateFieldsAndEnable();
void enableAccept();

signals:
Expand Down

0 comments on commit f404e0f

Please sign in to comment.