⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qgsdelimitedtextprovider.cpp

📁 一个非常好的GIS开源新版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************  qgsdelimitedtextprovider.cpp -  Data provider for delimted text  -------------------          begin                : 2004-02-27          copyright            : (C) 2004 by Gary E.Sherman          email                : sherman at mrcc.com ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************//* $Id: qgsdelimitedtextprovider.cpp 7452 2007-11-18 09:35:31Z g_j_m $ */#include "qgsdelimitedtextprovider.h"#include <QtGlobal>#include <QFile>#include <QDataStream>#include <QTextStream>#include <QStringList>#include <QMessageBox>#include <QSettings>#include <QRegExp>#include <QUrl>#include "qgsapplication.h"#include "qgsdataprovider.h"#include "qgsfeature.h"#include "qgsfield.h"#include "qgslogger.h"#include "qgsmessageoutput.h"#include "qgsrect.h"#include "qgsspatialrefsys.h"#include "qgis.h"static const QString TEXT_PROVIDER_KEY = "delimitedtext";static const QString TEXT_PROVIDER_DESCRIPTION = "Delimited text data provider";QgsDelimitedTextProvider::QgsDelimitedTextProvider(QString uri)    : QgsVectorDataProvider(uri),       mXFieldIndex(-1), mYFieldIndex(-1),      mShowInvalidLines(true){  // Get the file name and mDelimiter out of the uri  mFileName = uri.left(uri.find("?"));  // split the string up on & to get the individual parameters  QStringList parameters = QStringList::split("&", uri.mid(uri.find("?")));    QgsDebugMsg("Parameter count after split on &" + QString::number(parameters.size()));    // get the individual parameters and assign values  QStringList temp = parameters.grep("delimiter=");  mDelimiter = temp.size()? temp[0].mid(temp[0].find("=") + 1) : "";  temp = parameters.grep("delimiterType=");  mDelimiterType = temp.size()? temp[0].mid(temp[0].find("=") + 1) : "";  temp = parameters.grep("xField=");  QString xField = temp.size()? temp[0].mid(temp[0].find("=") + 1) : "";  temp = parameters.grep("yField=");  QString yField = temp.size()? temp[0].mid(temp[0].find("=") + 1) : "";  // Decode the parts of the uri. Good if someone entered '=' as a delimiter, for instance.  mFileName  = QUrl::fromPercentEncoding(mFileName.toUtf8());  mDelimiter = QUrl::fromPercentEncoding(mDelimiter.toUtf8());  mDelimiterType = QUrl::fromPercentEncoding(mDelimiterType.toUtf8());  xField    = QUrl::fromPercentEncoding(xField.toUtf8());  yField    = QUrl::fromPercentEncoding(yField.toUtf8());    QgsDebugMsg("Data source uri is " + uri);  QgsDebugMsg("Delimited text file is: " + mFileName);  QgsDebugMsg("Delimiter is: " + mDelimiter);  QgsDebugMsg("Delimiter type is: " + mDelimiterType);  QgsDebugMsg("xField is: " + xField);  QgsDebugMsg("yField is: " + yField);    // if delimiter contains some special characters, convert them  if (mDelimiterType == "regexp")    mDelimiterRegexp = QRegExp(mDelimiter);  else    mDelimiter.replace("\\t", "\t"); // replace "\t" with a real tabulator    // Set the selection rectangle to null  mSelectionRectangle = QgsRect();  // assume the layer is invalid until proven otherwise  mValid = false;  if (mFileName.isEmpty() || mDelimiter.isEmpty() || xField.isEmpty() || yField.isEmpty())  {    // uri is invalid so the layer must be too...    QString("Data source is invalid");    return;  }  // check to see that the file exists and perform some sanity checks  if (!QFile::exists(mFileName))  {    QgsDebugMsg("Data source " + dataSourceUri() + " doesn't exist");    return;  }        // Open the file and get number of rows, etc. We assume that the  // file has a header row and process accordingly. Caller should make  // sure the the delimited file is properly formed.  mFile = new QFile(mFileName);  if (!mFile->open(QIODevice::ReadOnly))  {    QgsDebugMsg("Data source " + dataSourceUri() + " could not be opened");    delete mFile;    return;  }    // now we have the file opened and ready for parsing    // set the initial extent  mExtent = QgsRect();    QMap<int, bool> couldBeInt;  QMap<int, bool> couldBeDouble;    mStream = new QTextStream(mFile);  QString line;  mNumberFeatures = 0;  int lineNumber = 0;  bool firstPoint = true;  bool hasFields = false;  while (!mStream->atEnd())  {    lineNumber++;    line = mStream->readLine(); // line of text excluding '\n', default local 8 bit encoding.    if (!hasFields)    {      // Get the fields from the header row and store them in the       // fields vector      QgsDebugMsg("Attempting to split the input line: " + line + " using delimiter " + mDelimiter);            QStringList fieldList;      if (mDelimiterType == "regexp")        fieldList = line.split(mDelimiterRegexp);      else        fieldList = line.split(mDelimiter);      QgsDebugMsg("Split line into " + QString::number(fieldList.size()) + " parts");            // We don't know anything about a text based field other      // than its name. All fields are assumed to be text      int fieldPos = 0;      for (QStringList::Iterator it = fieldList.begin();            it != fieldList.end(); ++it)      {        QString field = *it;        if (field.length() > 0)        {          // for now, let's set field type as text          attributeFields[fieldPos] = QgsField(*it, QVariant::String, "Text");                    // check to see if this field matches either the x or y field           if (xField == *it)          {            QgsDebugMsg("Found x field: " + (*it));            mXFieldIndex = fieldPos;          }          else if (yField == *it)          {            QgsDebugMsg("Found y field: " + (*it));            mYFieldIndex = fieldPos;          }                      QgsDebugMsg("Adding field: " + (*it));          // assume that the field could be integer or double          couldBeInt.insert(fieldPos, true);          couldBeDouble.insert(fieldPos, true);          fieldPos++;        }      }      QgsDebugMsg("Field count for the delimited text file is " + QString::number(attributeFields.size()));      hasFields = true;    }    else if (mXFieldIndex != -1 && mYFieldIndex != -1)    {      mNumberFeatures++;            // split the line on the delimiter      QStringList parts;      if (mDelimiterType == "regexp")        parts = line.split(mDelimiterRegexp);      else        parts = line.split(mDelimiter);      // Skip malformed lines silently. Report line number with getNextFeature()      if (attributeFields.size() != parts.size())      {        continue;      }            // Get the x and y values, first checking to make sure they      // aren't null.      QString sX = parts[mXFieldIndex];      QString sY = parts[mYFieldIndex];            bool xOk = true;      bool yOk = true;      double x = sX.toDouble(&xOk);      double y = sY.toDouble(&yOk);      if (xOk && yOk)      {        if (!firstPoint)        {          mExtent.combineExtentWith(x,y);        }        else        { // Extent for the first point is just the first point          mExtent.set(x,y,x,y);          firstPoint = false;        }      }            int i = 0;      for (QStringList::iterator it = parts.begin(); it != parts.end(); ++it, ++i)      {        // try to convert attribute values to integer and double        if (couldBeInt[i])        {          it->toInt(&couldBeInt[i]);        }        if (couldBeDouble[i])        {          it->toDouble(&couldBeDouble[i]);        }      }    }  }    // now it's time to decide the types for the fields  for (QgsFieldMap::iterator it = attributeFields.begin(); it != attributeFields.end(); ++it)  {    if (couldBeInt[it.key()])    {      it->setType(QVariant::Int);      it->setTypeName("integer");    }    else if (couldBeDouble[it.key()])    {      it->setType(QVariant::Double);      it->setTypeName("double");    }  }  if (mXFieldIndex != -1 && mYFieldIndex != -1)  {    QgsDebugMsg("Data store is valid");    QgsDebugMsg("Number of features " + QString::number(mNumberFeatures));    QgsDebugMsg("Extents " + mExtent.stringRep());        mValid = true;  }  else  {    QgsDebugMsg("Data store is invalid. Specified x,y fields do not match those in the database");  }  QgsDebugMsg("Done checking validity");}QgsDelimitedTextProvider::~QgsDelimitedTextProvider(){  mFile->close();  delete mFile;  delete mStream;}QString QgsDelimitedTextProvider::storageType() const{  return "Delimited text file";}bool QgsDelimitedTextProvider::getNextFeature(QgsFeature& feature)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -