📄 qgsdelimitedtextprovider.cpp
字号:
{ // before we do anything else, assume that there's something wrong with // the feature feature.setValid( false ); while ( ! mStream->atEnd() ) { double x = 0.0; double y = 0.0; QString line = mStream->readLine(); // Default local 8 bit encoding // lex the tokens from the current data line QStringList tokens; if (mDelimiterType == "regexp") tokens = line.split(mDelimiterRegexp); else tokens = line.split(mDelimiter); bool xOk = false; bool yOk = false; // Skip indexing malformed lines. if (attributeFields.size() == tokens.size()) { x = tokens[mXFieldIndex].toDouble( &xOk ); y = tokens[mYFieldIndex].toDouble( &yOk ); } if (! (xOk && yOk)) { // Accumulate any lines that weren't ok, to report on them // later, and look at the next line in the file, but only if // we need to. QgsDebugMsg("Malformed line : " + line); if (mShowInvalidLines) mInvalidLines << line; continue; } // Give every valid line in the file an id, even if it's not // in the current extent or bounds. ++mFid; // increment to next feature ID // skip the feature if it's out of current bounds if (! boundsCheck(x,y)) continue; // at this point, one way or another, the current feature values // are valid feature.setValid( true ); feature.setFeatureId( mFid ); QByteArray buffer; QDataStream s( &buffer, QIODevice::WriteOnly ); // open on buffers's data switch ( QgsApplication::endian() ) { case QgsApplication::NDR : // we're on a little-endian platform, so tell the data // stream to use that s.setByteOrder( QDataStream::LittleEndian ); s << (Q_UINT8)1; // 1 is for little-endian break; case QgsApplication::XDR : // don't change byte order since QDataStream is big endian by default s << (Q_UINT8)0; // 0 is for big-endian break; default : qDebug( "%s:%d unknown endian", __FILE__, __LINE__ ); //delete [] geometry; return false; } s << (Q_UINT32)QGis::WKBPoint; s << x; s << y; unsigned char* geometry = new unsigned char[buffer.size()]; memcpy(geometry, buffer.data(), buffer.size()); feature.setGeometryAndOwnership( geometry, sizeof(wkbPoint) ); for ( QgsAttributeList::const_iterator i = mAttributesToFetch.begin(); i != mAttributesToFetch.end(); ++i ) { QVariant val; switch (attributeFields[*i].type()) { case QVariant::Int: val = QVariant(tokens[*i].toInt()); break; case QVariant::Double: val = QVariant(tokens[*i].toDouble()); break; default: val = QVariant(tokens[*i]); break; } feature.addAttribute(*i, val); } // We have a good line, so return return true; } // ! textStream EOF // End of the file. If there are any lines that couldn't be // loaded, display them now. if (mShowInvalidLines && !mInvalidLines.isEmpty()) { mShowInvalidLines = false; QgsMessageOutput* output = QgsMessageOutput::createMessageOutput(); output->setTitle(tr("Error")); output->setMessage(tr("Note: the following lines were not loaded because Qgis was " "unable to determine values for the x and y coordinates:\n"), QgsMessageOutput::MessageText); output->appendMessage("Start of invalid lines."); for (int i = 0; i < mInvalidLines.size(); ++i) output->appendMessage(mInvalidLines.at(i)); output->appendMessage("End of invalid lines."); output->showMessage(); // We no longer need these lines. mInvalidLines.empty(); } return false;} // getNextFeaturevoid QgsDelimitedTextProvider::select(QgsAttributeList fetchAttributes, QgsRect rect, bool fetchGeometry, bool useIntersect){ mSelectionRectangle = rect; mAttributesToFetch = fetchAttributes; mFetchGeom = fetchGeometry; if(rect.isEmpty()) { mSelectionRectangle = mExtent; } else { mSelectionRectangle = rect; } reset();}// Return the extent of the layerQgsRect QgsDelimitedTextProvider::extent(){ return mExtent;}/** * Return the feature type */QGis::WKBTYPE QgsDelimitedTextProvider::geometryType() const{ return QGis::WKBPoint;}/** * Return the feature type */long QgsDelimitedTextProvider::featureCount() const{ return mNumberFeatures;}/** * Return the number of fields */uint QgsDelimitedTextProvider::fieldCount() const{ return attributeFields.size();}const QgsFieldMap & QgsDelimitedTextProvider::fields() const{ return attributeFields;}void QgsDelimitedTextProvider::reset(){ // Reset feature id to 0 mFid = 0; // Skip ahead one line since first record is always assumed to be // the header record mStream->seek(0); mStream->readLine();}bool QgsDelimitedTextProvider::isValid(){ return mValid;}/** * Check to see if the point is within the selection rectangle */bool QgsDelimitedTextProvider::boundsCheck(double x, double y){ // no selection rectangle => always in the bounds if (mSelectionRectangle.isEmpty()) return true; return (x <= mSelectionRectangle.xMax()) && (x >= mSelectionRectangle.xMin()) && (y <= mSelectionRectangle.yMax()) && (y >= mSelectionRectangle.yMin());}int QgsDelimitedTextProvider::capabilities() const{ return 0;}QgsSpatialRefSys QgsDelimitedTextProvider::getSRS(){ // TODO: make provider projection-aware return QgsSpatialRefSys(); // return default SRS}QString QgsDelimitedTextProvider::name() const{ return TEXT_PROVIDER_KEY;} // ::name()QString QgsDelimitedTextProvider::description() const{ return TEXT_PROVIDER_DESCRIPTION;} // QgsDelimitedTextProvider::name()/** * Class factory to return a pointer to a newly created * QgsDelimitedTextProvider object */QGISEXTERN QgsDelimitedTextProvider *classFactory(const QString *uri){ return new QgsDelimitedTextProvider(*uri);}/** Required key function (used to map the plugin to a data store type)*/QGISEXTERN QString providerKey(){ return TEXT_PROVIDER_KEY;}/** * Required description function */QGISEXTERN QString description(){ return TEXT_PROVIDER_DESCRIPTION;}/** * Required isProvider function. Used to determine if this shared library * is a data provider plugin */QGISEXTERN bool isProvider(){ return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -