24 #include <QNetworkRequest>
25 #include <QNetworkReply>
26 #include <QProgressDialog>
37 const QString& typeName,
38 const QString& geometryAttribute,
41 , mTypeName( typeName )
42 , mGeometryAttribute( geometryAttribute )
44 , mCurrentFeature( 0 )
46 , mCurrentWKBSize( 0 )
49 for (
int i = 0; i < fields.
size(); i++ )
57 if ( index != -1 && index <
mTypeName.length() )
73 XML_SetUserData( p,
this );
80 QNetworkRequest request(
mUri );
83 connect( reply, SIGNAL( finished() ),
this, SLOT(
setFinished() ) );
84 connect( reply, SIGNAL( downloadProgress( qint64, qint64 ) ),
this, SLOT(
handleProgressEvent( qint64, qint64 ) ) );
87 QProgressDialog* progressDialog = 0;
88 QWidget* mainWindow = 0;
89 QWidgetList topLevelWidgets = qApp->topLevelWidgets();
90 for ( QWidgetList::iterator it = topLevelWidgets.begin(); it != topLevelWidgets.end(); ++it )
92 if (( *it )->objectName() ==
"QgisApp" )
100 progressDialog =
new QProgressDialog(
tr(
"Loading GML data\n%1" ).arg(
mTypeName ),
tr(
"Abort" ), 0, 0, mainWindow );
101 progressDialog->setWindowModality( Qt::ApplicationModal );
102 connect(
this, SIGNAL(
dataReadProgress(
int ) ), progressDialog, SLOT( setValue(
int ) ) );
103 connect(
this, SIGNAL(
totalStepsUpdate(
int ) ), progressDialog, SLOT( setMaximum(
int ) ) );
104 connect( progressDialog, SIGNAL( canceled() ),
this, SLOT(
setFinished() ) );
105 progressDialog->show();
115 QByteArray readData = reply->readAll();
116 if ( readData.size() > 0 )
118 if ( XML_Parse( p, readData.constData(), readData.size(), atEnd ) == 0 )
120 XML_Error errorCode = XML_GetErrorCode( p );
121 QString errorString =
tr(
"Error: %1 on line %2, column %3" )
122 .arg( XML_ErrorString( errorCode ) )
123 .arg( XML_GetCurrentLineNumber( p ) )
124 .arg( XML_GetCurrentColumnNumber( p ) );
128 QCoreApplication::processEvents();
131 QNetworkReply::NetworkError replyError = reply->error();
132 QString replyErrorString = reply->errorString();
135 delete progressDialog;
140 tr(
"GML Getfeature network request failed with error: %1" ).arg( replyErrorString ),
169 XML_Parser p = XML_ParserCreateNS( NULL,
NS_SEPARATOR );
170 XML_SetUserData( p,
this );
174 XML_Parse( p, data.constData(), data.size(), atEnd );
189 if ( totalSteps < 0 )
201 QString elementName( QString::fromUtf8( el ) );
203 QStringList splitName = elementName.split(
NS_SEPARATOR );
204 QString localName = splitName.last();
205 QString ns = splitName.size() > 1 ? splitName.first() :
"";
283 QString elementName( QString::fromUtf8( el ) );
285 QStringList splitName = elementName.split(
NS_SEPARATOR );
286 QString localName = splitName.last();
287 QString ns = splitName.size() > 1 ? splitName.first() :
"";
302 switch ( att_it.value().second.type() )
304 case QVariant::Double:
310 case QVariant::LongLong:
363 QList<QgsPoint> pointList;
384 unsigned char* wkb = 0;
386 QList<unsigned char*> wkbList;
387 QList<int> wkbSizeList;
388 if (
getPointWKB( &wkb, &wkbSize, *( pointList.begin() ) ) != 0 )
407 QList<QgsPoint> pointList;
426 unsigned char* wkb = 0;
428 QList<unsigned char*> wkbList;
429 QList<int> wkbSizeList;
430 if (
getLineWKB( &wkb, &wkbSize, pointList ) != 0 )
447 QList<QgsPoint> pointList;
452 unsigned char* wkb = 0;
454 if (
getRingWKB( &wkb, &wkbSize, pointList ) != 0 )
511 mStringCash.append( QString::fromUtf8( chars, len ) );
518 while ( attr[i] != NULL )
520 if ( strcmp( attr[i],
"srsName" ) == 0 )
522 QString epsgString( attr[i+1] );
523 QString epsgNrString;
524 if ( epsgString.startsWith(
"http" ) )
526 epsgNrString = epsgString.section(
"#", 1, 1 );
530 epsgNrString = epsgString.section(
":", 1, 1 );
533 int eNr = epsgNrString.toInt( &conversionOk );
549 while ( attr[i] != NULL )
551 if ( attributeName.compare( attr[i] ) == 0 )
553 return QString( attr[i+1] );
562 QList<QgsPoint> points;
568 if ( points.size() < 2 )
573 r.
set( points[0], points[1] );
581 QStringList tuples = coordString.split(
mTupleSeparator, QString::SkipEmptyParts );
582 QStringList tuples_coordinates;
584 bool conversionSuccess;
586 QStringList::const_iterator tupleIterator;
587 for ( tupleIterator = tuples.constBegin(); tupleIterator != tuples.constEnd(); ++tupleIterator )
590 if ( tuples_coordinates.size() < 2 )
594 x = tuples_coordinates.at( 0 ).toDouble( &conversionSuccess );
595 if ( !conversionSuccess )
599 y = tuples_coordinates.at( 1 ).toDouble( &conversionSuccess );
600 if ( !conversionSuccess )
604 points.push_back(
QgsPoint( x, y ) );
611 int wkbSize = 1 +
sizeof( int ) + 2 *
sizeof(
double );
613 *wkb =
new unsigned char[wkbSize];
615 double x = point.
x();
616 double y = point.
y();
619 memcpy( &( *wkb )[wkbPosition], &
mEndian, 1 );
621 memcpy( &( *wkb )[wkbPosition], &type,
sizeof(
int ) );
622 wkbPosition +=
sizeof( int );
623 memcpy( &( *wkb )[wkbPosition], &x,
sizeof(
double ) );
624 wkbPosition +=
sizeof( double );
625 memcpy( &( *wkb )[wkbPosition], &y,
sizeof(
double ) );
631 int wkbSize = 1 + 2 *
sizeof( int ) + lineCoordinates.size() * 2 *
sizeof( double );
633 *wkb =
new unsigned char[wkbSize];
637 int nPoints = lineCoordinates.size();
640 memcpy( &( *wkb )[wkbPosition], &
mEndian, 1 );
642 memcpy( &( *wkb )[wkbPosition], &type,
sizeof(
int ) );
643 wkbPosition +=
sizeof( int );
644 memcpy( &( *wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
645 wkbPosition +=
sizeof( int );
647 QList<QgsPoint>::const_iterator iter;
648 for ( iter = lineCoordinates.begin(); iter != lineCoordinates.end(); ++iter )
652 memcpy( &( *wkb )[wkbPosition], &x,
sizeof(
double ) );
653 wkbPosition +=
sizeof( double );
654 memcpy( &( *wkb )[wkbPosition], &y,
sizeof(
double ) );
655 wkbPosition +=
sizeof( double );
662 int wkbSize =
sizeof( int ) + ringCoordinates.size() * 2 *
sizeof( double );
664 *wkb =
new unsigned char[wkbSize];
667 int nPoints = ringCoordinates.size();
668 memcpy( &( *wkb )[wkbPosition], &nPoints,
sizeof(
int ) );
669 wkbPosition +=
sizeof( int );
671 QList<QgsPoint>::const_iterator iter;
672 for ( iter = ringCoordinates.begin(); iter != ringCoordinates.end(); ++iter )
676 memcpy( &( *wkb )[wkbPosition], &x,
sizeof(
double ) );
677 wkbPosition +=
sizeof( double );
678 memcpy( &( *wkb )[wkbPosition], &y,
sizeof(
double ) );
679 wkbPosition +=
sizeof( double );
697 memcpy( &(
mCurrentWKB[pos] ), &type,
sizeof(
int ) );
698 pos +=
sizeof( int );
699 memcpy( &(
mCurrentWKB[pos] ), &numLines,
sizeof(
int ) );
700 pos +=
sizeof( int );
731 memcpy( &(
mCurrentWKB[pos] ), &type,
sizeof(
int ) );
732 pos +=
sizeof( int );
733 memcpy( &(
mCurrentWKB[pos] ), &numPoints,
sizeof(
int ) );
734 pos +=
sizeof( int );
765 memcpy( &(
mCurrentWKB[pos] ), &type,
sizeof(
int ) );
766 pos +=
sizeof( int );
767 memcpy( &(
mCurrentWKB[pos] ), &numRings,
sizeof(
int ) );
768 pos +=
sizeof( int );
800 memcpy( &(
mCurrentWKB[pos] ), &type,
sizeof(
int ) );
801 pos +=
sizeof( int );
802 memcpy( &(
mCurrentWKB[pos] ), &numPolys,
sizeof(
int ) );
803 pos +=
sizeof( int );
806 QList< QList<unsigned char*> >::iterator outerWkbIt;
807 QList< QList<int> >::iterator outerSizeIt;
808 QList< unsigned char* >::iterator innerWkbIt;
809 QList< int >::iterator innerSizeIt;
819 memcpy( &(
mCurrentWKB[pos] ), &polygonType,
sizeof(
int ) );
820 pos +=
sizeof( int );
821 numRings = outerWkbIt->size();
822 memcpy( &(
mCurrentWKB[pos] ), &numRings,
sizeof(
int ) );
823 pos +=
sizeof( int );
825 innerWkbIt = outerWkbIt->begin();
826 innerSizeIt = outerSizeIt->begin();
827 for ( ; innerWkbIt != outerWkbIt->end(); ++innerWkbIt, ++innerSizeIt )
829 memcpy( &(
mCurrentWKB[pos] ), *innerWkbIt, *innerSizeIt );
831 delete[] *innerWkbIt;
846 foreach (
int i, list )
863 bool bboxInitialised =
false;
865 for (
int i = 0; i <
mFeatures.size(); ++i )
868 if ( !currentFeature )
872 currentGeometry = currentFeature->
geometry();
873 if ( currentGeometry )
875 if ( !bboxInitialised )
878 bboxInitialised =
true;
QgsFeatureId id() const
Get the feature id for this feature.
void unionRect(const QgsRectangle &rect)
updates rectangle to include passed argument
QgsRectangle mCurrentExtent
A rectangle specified with double values.
int createMultiLineFromFragments()
Creates a multiline from the information in mCurrentWKBFragments and mCurrentWKBFragmentSizes.
bool isEmpty() const
test if rectangle is empty
void setMinimal()
Set a rectangle so that min corner is at max.
QgsApplication::endian_t mEndian
QString mGeometryAttribute
Name of geometry attribute.
int createMultiPolygonFromFragments()
static void start(void *data, const XML_Char *el, const XML_Char **attr)
int getFeatures(const QString &uri, QGis::WkbType *wkbType, QgsRectangle *extent=0)
Does the Http GET request to the wfs server.
QgsFeature * mCurrentFeature
QgsGeometry * geometry() const
Get the geometry object associated with this feature.
void characters(const XML_Char *chars, int len)
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
void setAttributes(const QgsAttributes &attrs)
bool setAttribute(int field, const QVariant &attr)
Set an attribute by id.
WkbType
Used for symbology operations.
void dataReadProgress(int progress)
int getLineWKB(unsigned char **wkb, int *size, const QList< QgsPoint > &lineCoordinates) const
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
static endian_t endian()
Returns whether this machine uses big or little endian.
void endElement(const XML_Char *el)
QString mCurrentFeatureId
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
void totalStepsUpdate(int totalSteps)
QString mCoordinateSeparator
Coordinate separator for coordinate strings.
void set(const QgsPoint &p1, const QgsPoint &p2)
Set the rectangle from two QgsPoints. The rectangle is.
void setGeometry(const QgsGeometry &geom)
Set this feature's geometry from another QgsGeometry object (deep copy)
void dataProgressAndSteps(int progress, int totalSteps)
QgsGml(const QString &typeName, const QString &geometryAttribute, const QgsFields &fields)
unsigned char * mCurrentWKB
The total WKB for a feature.
static void chars(void *data, const XML_Char *chars, int len)
QString mTupleSeparator
Tuple separator for coordinate strings.
int createPolygonFromFragments()
int getRingWKB(unsigned char **wkb, int *size, const QList< QgsPoint > &ringCoordinates) const
A class to represent a point geometry.
int totalWKBFragmentSize() const
Adds all the integers contained in mCurrentWKBFragmentSizes.
static void end(void *data, const XML_Char *el)
QStack< ParseMode > mParseModeStack
Keep track about the most important nested elements.
int createBBoxFromCoordinateString(QgsRectangle &bb, const QString &coordString) const
Creates a rectangle from a coordinate string.
const QString GML_NAMESPACE
void setValid(bool validity)
Set the validity of the feature.
QgsRectangle boundingBox()
Returns the bounding box of this feature.
int createMultiPointFromFragments()
static QgsNetworkAccessManager * instance()
returns a pointer to the single instance
QMap< QgsFeatureId, QgsFeature * > mFeatures
The features of the layer, map of feature maps for each feature type.
QVector< QVariant > QgsAttributes
void startElement(const XML_Char *el, const XML_Char **attr)
XML handler methods.
void handleProgressEvent(qint64 progress, qint64 totalSteps)
Takes progress value and total steps and emit signals 'dataReadProgress' and 'totalStepUpdate'.
QString readAttribute(const QString &attributeName, const XML_Char **attr) const
Reads attribute as string.
int size() const
Return number of items.
static QgsGeometry * fromRect(const QgsRectangle &rect)
construct geometry from a rectangle
bool mFinished
True if the request is finished.
QList< QList< unsigned char * > > mCurrentWKBFragments
WKB intermediate storage during parsing.
int getPointWKB(unsigned char **wkb, int *size, const QgsPoint &) const
QgsRectangle mExtent
Bounding box of the layer.
int readEpsgFromAttribute(int &epsgNr, const XML_Char **attr) const
Reads attribute srsName="EpsgCrsId:...".
QList< QList< int > > mCurrentWKBFragmentSizes
Similar to mCurrentWKB, but only the size.
int pointsFromCoordinateString(QList< QgsPoint > &points, const QString &coordString) const
Creates a set of points from a coordinate string.
QMap< QString, QPair< int, QgsField > > mThematicAttributes
int mCurrentWKBSize
The total WKB size for a feature.
QMap< QgsFeatureId, QString > mIdMap
Stores the relation between provider ids and WFS server ids.
QString mStringCash
This contains the character data if an important element has been encountered.
void setGeometryAndOwnership(unsigned char *geom, size_t length)
Set this feature's geometry from WKB.
void calculateExtentFromFeatures()
This function evaluates the layer bounding box from the features and sets it to mExtent.