Skip to content

Commit fc7002a

Browse files
author
mhugent
committedNov 26, 2007
Some cleanups in wfs provider, display the number of bytes received to entertain the user while loading
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@7658 c8812cc2-4d05-0410-92ff-de0c093fc19c

File tree

4 files changed

+51
-720
lines changed

4 files changed

+51
-720
lines changed
 

‎src/providers/wfs/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ SET(WFS_SRCS qgswfsprovider.cpp qgswfsdata.cpp)
66

77
SET (WFS_MOC_HDRS
88
qgswfsdata.h
9+
qgswfsprovider.h
910
)
1011

1112
IF(NOT MSVC)

‎src/providers/wfs/qgswfsdata.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ class QgsWFSData: public QObject
4444
@param features the features of the layer
4545
@return 0 in case of success*/
4646
int getWFSData();
47-
47+
/**Returns a pointer to the internal QHttp object (mainly for the purpose of making singal/slot connections*/
48+
const QHttp* http() const {return &mHttp;}
49+
4850
private slots:
4951
void setFinished(bool error);
5052

‎src/providers/wfs/qgswfsprovider.cpp

Lines changed: 37 additions & 682 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ int QgsWFSProvider::getFeatureGET(const QString& uri, const QString& geometryAtt
273273
return 0;
274274
#endif
275275

276-
//try the new and faster method with the expat parser
276+
//the new and faster method with the expat parser
277277
std::list<QgsFeature*> dataFeatures;
278278
std::set<QString> thematicAttributes;
279279
for(QgsFieldMap::const_iterator it = mFields.begin(); it != mFields.end(); ++it)
@@ -282,6 +282,27 @@ int QgsWFSProvider::getFeatureGET(const QString& uri, const QString& geometryAtt
282282
}
283283

284284
QgsWFSData dataReader(uri, &mExtent, &mSourceSRS, &dataFeatures, geometryAttribute, thematicAttributes, &mWKBType);
285+
QObject::connect(dataReader.http(), SIGNAL(dataReadProgress(int, int)), this, SLOT(handleWFSProgressMessage(int, int)));
286+
287+
//also connect to setStatus signal of qgisapp (if it exists)
288+
QWidget* mainWindow = 0;
289+
290+
QWidgetList topLevelWidgets = qApp->topLevelWidgets();
291+
QWidgetList::iterator it = topLevelWidgets.begin();
292+
for(; it != topLevelWidgets.end(); ++it)
293+
{
294+
if((*it)->objectName() == "QgisApp")
295+
{
296+
mainWindow = *it;
297+
break;
298+
}
299+
}
300+
301+
if(mainWindow)
302+
{
303+
QObject::connect(this, SIGNAL(dataReadProgressMessage(QString)), mainWindow, SLOT(showStatusMessage(QString)));
304+
}
305+
285306
if(dataReader.getWFSData() != 0)
286307
{
287308
qWarning("getWFSData returned with error");
@@ -1361,6 +1382,21 @@ int QgsWFSProvider::readGML2Coordinates(std::list<QgsPoint>& coords, const QDomE
13611382
return 0;
13621383
}
13631384

1385+
void QgsWFSProvider::handleWFSProgressMessage(int done, int total)
1386+
{
1387+
QString totalString;
1388+
if(total == 0)
1389+
{
1390+
totalString = "unknown";
1391+
}
1392+
else
1393+
{
1394+
totalString = QString::number(total);
1395+
}
1396+
QString message("received " + QString::number(done) + " bytes from " + totalString);
1397+
emit dataReadProgressMessage(message);
1398+
}
1399+
13641400

13651401
QString QgsWFSProvider::name() const
13661402
{
@@ -1392,684 +1428,3 @@ QGISEXTERN bool isProvider()
13921428
{
13931429
return true;
13941430
}
1395-
1396-
1397-
1398-
//methods for reading GML3. Not needed at the moment as most servers support GML2
1399-
1400-
#if 0
1401-
int QgsWFSProvider::getExtentFromGML3(QgsRect* extent, const QDomElement& wfsCollectionElement) const
1402-
{
1403-
QDomNodeList boundedByList = wfsCollectionElement.elementsByTagNameNS(GML_NAMESPACE, "boundedBy");
1404-
if(boundedByList.length() < 1)
1405-
{
1406-
return 1;
1407-
}
1408-
QDomElement boundedByElement = boundedByList.at(0).toElement();
1409-
QDomNode childNode = boundedByElement.firstChild();
1410-
if(childNode.isNull())
1411-
{
1412-
return 2;
1413-
}
1414-
1415-
//support <gml:Box>, <gml:coordinates> and <gml:Envelope>,<gml::lowerCorner>,<gml::upperCorner>. What
1416-
//about <gml:Envelope>, <gml:pos>?
1417-
QString bboxName = childNode.localName();
1418-
if(bboxName == "Envelope")
1419-
{
1420-
QDomElement envelopeElement = childNode.toElement();
1421-
QDomNodeList posList = envelopeElement.elementsByTagNameNS(GML_NAMESPACE, "pos");
1422-
if(posList.size() < 2)
1423-
{
1424-
return 3;
1425-
}
1426-
QDomElement llPosElement = posList.at(0).toElement();
1427-
QStringList llStringList = llPosElement.text().split(" ", QString::SkipEmptyParts);
1428-
QDomElement urPosElement = posList.at(1).toElement();
1429-
QStringList urStringList = urPosElement.text().split(" ", QString::SkipEmptyParts);
1430-
1431-
if(llStringList.size() < 2 || urStringList.size() < 2)
1432-
{
1433-
return 4;
1434-
}
1435-
1436-
bool conversionSuccess;
1437-
double xLeft = llStringList.at(0).toDouble(&conversionSuccess);
1438-
if(!conversionSuccess){return 5;}
1439-
double yLow = llStringList.at(1).toDouble(&conversionSuccess);
1440-
if(!conversionSuccess){return 5;}
1441-
double xRight = urStringList.at(0).toDouble(&conversionSuccess);
1442-
if(!conversionSuccess){return 5;}
1443-
double yUp = urStringList.at(1).toDouble(&conversionSuccess);
1444-
if(!conversionSuccess){return 5;}
1445-
1446-
extent->setXmin(xLeft);
1447-
extent->setYmin(yLow);
1448-
extent->setXmax(xRight);
1449-
extent->setYmax(yUp);
1450-
}
1451-
else if(bboxName == "Box")
1452-
{
1453-
QDomElement boxElement = childNode.toElement();
1454-
QDomNodeList coordinatesList = boxElement.elementsByTagNameNS(GML_NAMESPACE, "coordinates");
1455-
if(coordinatesList.length() < 1)
1456-
{
1457-
return 11;
1458-
}
1459-
QStringList coordinatesStringList = coordinatesList.at(0).toElement().text().split(" ", QString::SkipEmptyParts);
1460-
if(coordinatesStringList.size() < 2)
1461-
{
1462-
return 12;
1463-
}
1464-
QStringList lowCoordinateList = coordinatesStringList.at(0).split(",", QString::SkipEmptyParts);
1465-
if(lowCoordinateList.size() < 2)
1466-
{
1467-
return 13;
1468-
}
1469-
1470-
bool conversionSuccess;
1471-
double xLow = lowCoordinateList.at(0).toDouble(&conversionSuccess);
1472-
if(conversionSuccess)
1473-
{
1474-
extent->setXmin(xLow);
1475-
}
1476-
else
1477-
{
1478-
return 14;
1479-
}
1480-
double yLow = lowCoordinateList.at(1).toDouble(&conversionSuccess);
1481-
if(conversionSuccess)
1482-
{
1483-
extent->setYmin(yLow);
1484-
}
1485-
else
1486-
{
1487-
return 15;
1488-
}
1489-
QStringList upCoordinateList = coordinatesStringList.at(1).split(",", QString::SkipEmptyParts);
1490-
if(upCoordinateList.size() < 2)
1491-
{
1492-
return 16;
1493-
}
1494-
double xUp = upCoordinateList.at(0).toDouble(&conversionSuccess);
1495-
if(conversionSuccess)
1496-
{
1497-
extent->setXmax(xUp);
1498-
}
1499-
else
1500-
{
1501-
return 17;
1502-
}
1503-
double yUp = upCoordinateList.at(1).toDouble(&conversionSuccess);
1504-
if(conversionSuccess)
1505-
{
1506-
extent->setYmax(yUp);
1507-
}
1508-
else
1509-
{
1510-
return 18;
1511-
}
1512-
}
1513-
return 0;
1514-
}
1515-
1516-
int QgsWFSProvider::getFeaturesFromGML3(const QDomElement& wfsCollectionElement, const QString& geometryAttribute, std::vector<QgsFeature*>& features) const
1517-
{
1518-
QDomNodeList featureTypeNodeList = wfsCollectionElement.elementsByTagNameNS(GML_NAMESPACE, "featureMember");
1519-
QDomElement currentFeatureMemberElem;
1520-
QDomElement layerNameElem;
1521-
QDomNode currentAttributeChild;
1522-
QDomElement currentAttributeElement;
1523-
int counter = 0;
1524-
QgsFeature* f = 0;
1525-
unsigned char* wkb = 0;
1526-
int wkbSize = 0;
1527-
QGis::WKBTYPE currentType;
1528-
1529-
for(int i = 0; i < featureTypeNodeList.size(); ++i)
1530-
{
1531-
f = new QgsFeature(counter);
1532-
currentFeatureMemberElem = featureTypeNodeList.at(i).toElement();
1533-
//the first child element is always <namespace:layer>
1534-
layerNameElem = currentFeatureMemberElem.firstChild().toElement();
1535-
//the children are the attributes
1536-
currentAttributeChild = layerNameElem.firstChild();
1537-
while(!currentAttributeChild.isNull())
1538-
{
1539-
currentAttributeElement = currentAttributeChild.toElement();
1540-
if(currentAttributeElement.localName() != "boundedBy")
1541-
{
1542-
if((currentAttributeElement.localName()) != geometryAttribute) //a normal attribute
1543-
{
1544-
f->addAttribute(currentAttributeElement.localName(), currentAttributeElement.text(), false);
1545-
}
1546-
else //a geometry attribute
1547-
{
1548-
getWkbFromGML3(currentAttributeElement, &wkb, &wkbSize, &currentType);
1549-
mWKBType = currentType; //a more sophisticated method is necessary
1550-
f->setGeometryAndOwnership(wkb, wkbSize);
1551-
}
1552-
}
1553-
currentAttributeChild = currentAttributeChild.nextSibling();
1554-
}
1555-
if(wkb && wkbSize > 0)
1556-
{
1557-
features.push_back(f);
1558-
}
1559-
++counter;
1560-
}
1561-
return 1;
1562-
}
1563-
1564-
int QgsWFSProvider::getWkbFromGML3(const QDomNode& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const
1565-
{
1566-
QDomNode geometryChild = geometryElement.firstChild();
1567-
if(geometryChild.isNull())
1568-
{
1569-
return 1;
1570-
}
1571-
QDomElement geometryTypeElement = geometryChild.toElement();
1572-
QString geomType = geometryTypeElement.localName();
1573-
if(geomType == "Point")
1574-
{
1575-
return getWkbFromGML3Point(geometryTypeElement, wkb, wkbSize, type);
1576-
}
1577-
else if(geomType == "Polygon")
1578-
{
1579-
return getWkbFromGML3Polygon(geometryTypeElement, wkb, wkbSize, type);
1580-
}
1581-
else if(geomType == "LineString")
1582-
{
1583-
return getWkbFromGML3LineString(geometryTypeElement, wkb, wkbSize, type);
1584-
}
1585-
else if(geomType == "MultiCurve")
1586-
{
1587-
return getWkbFromGML3MultiCurve(geometryTypeElement, wkb, wkbSize, type);
1588-
}
1589-
else if(geomType == "MultiSurface")
1590-
{
1591-
return getWkbFromGML3MultiSurface(geometryTypeElement, wkb, wkbSize, type);
1592-
}
1593-
else //unknown type
1594-
{
1595-
*wkb = 0;
1596-
*wkbSize = 0;
1597-
}
1598-
return 0;
1599-
}
1600-
1601-
int QgsWFSProvider::getWkbFromGML3Point(const QDomElement& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const
1602-
{
1603-
QDomNodeList posList = geometryElement.elementsByTagNameNS(GML_NAMESPACE, "pos");
1604-
if(posList.size() < 1)
1605-
{
1606-
return 1;
1607-
}
1608-
QDomElement posElement = posList.at(0).toElement();
1609-
std::list<QgsPoint> pointCoordinate;
1610-
if(readCoordinatesFromPosList(pointCoordinate, posElement) != 0)
1611-
{
1612-
return 2;
1613-
}
1614-
1615-
if(pointCoordinate.size() < 1)
1616-
{
1617-
return 3;
1618-
}
1619-
1620-
std::list<QgsPoint>::const_iterator point_it = pointCoordinate.begin();
1621-
char e = QgsApplication::endian();
1622-
double x = point_it->x();
1623-
double y = point_it->y();
1624-
int size = 1 + sizeof(int) + 2 * sizeof(double);
1625-
*wkb = new unsigned char[size];
1626-
*wkbSize = size;
1627-
*type = QGis::WKBPoint;
1628-
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
1629-
memcpy(&(*wkb)[wkbPosition], &e, 1);
1630-
wkbPosition += 1;
1631-
memcpy(&(*wkb)[wkbPosition], type, sizeof(int));
1632-
wkbPosition += sizeof(int);
1633-
memcpy(&(*wkb)[wkbPosition], &x, sizeof(double));
1634-
wkbPosition += sizeof(double);
1635-
memcpy(&(*wkb)[wkbPosition], &y, sizeof(double));
1636-
return 0;
1637-
}
1638-
1639-
int QgsWFSProvider::getWkbFromGML3LineString(const QDomElement& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const
1640-
{
1641-
QDomNodeList posList = geometryElement.elementsByTagNameNS(GML_NAMESPACE, "posList");
1642-
if(posList.size() < 1)
1643-
{
1644-
return 1;
1645-
}
1646-
QDomElement posListElement = posList.at(0).toElement();
1647-
std::list<QgsPoint> lineCoordinates;
1648-
if(readCoordinatesFromPosList(lineCoordinates, posListElement) != 0)
1649-
{
1650-
return 2;
1651-
}
1652-
char e = QgsApplication::endian();
1653-
int size = 1 + 2 * sizeof(int) + lineCoordinates.size() * 2* sizeof(double);
1654-
*wkb = new unsigned char[size];
1655-
*wkbSize = size;
1656-
*type = QGis::WKBLineString;
1657-
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
1658-
double x, y;
1659-
int nPoints = lineCoordinates.size();
1660-
1661-
//fill the contents into *wkb
1662-
memcpy(&(*wkb)[wkbPosition], &e, 1);
1663-
wkbPosition += 1;
1664-
memcpy(&(*wkb)[wkbPosition], type, sizeof(int));
1665-
wkbPosition += sizeof(int);
1666-
memcpy(&(*wkb)[wkbPosition], &nPoints, sizeof(int));
1667-
wkbPosition += sizeof(int);
1668-
1669-
std::list<QgsPoint>::const_iterator iter;
1670-
for(iter = lineCoordinates.begin(); iter != lineCoordinates.end(); ++iter)
1671-
{
1672-
x = iter->x();
1673-
y = iter->y();
1674-
memcpy(&(*wkb)[wkbPosition], &x, sizeof(double));
1675-
wkbPosition += sizeof(double);
1676-
memcpy(&(*wkb)[wkbPosition], &y, sizeof(double));
1677-
wkbPosition += sizeof(double);
1678-
}
1679-
return 0;
1680-
}
1681-
1682-
int QgsWFSProvider::getWkbFromGML3Polygon(const QDomElement& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const
1683-
{
1684-
QDomNodeList exteriorList = geometryElement.elementsByTagNameNS(GML_NAMESPACE, "exterior");
1685-
if(exteriorList.size() < 1) //exterior ring is necessary
1686-
{
1687-
return 1;
1688-
}
1689-
//then take the <gml:interior> elements into account
1690-
QDomNodeList interiorList = geometryElement.elementsByTagNameNS(GML_NAMESPACE, "interior");
1691-
1692-
//read all the coordinates (as QgsPoint) into memory. Each linear ring has an entry in the vector
1693-
std::vector<std::list<QgsPoint> > ringCoordinates;
1694-
1695-
//exterior ring
1696-
QDomElement posListElement = exteriorList.at(0).firstChild().firstChild().toElement();
1697-
std::list<QgsPoint> exteriorPointList;
1698-
if(readCoordinatesFromPosList(exteriorPointList, posListElement) != 0)
1699-
{
1700-
return 2;
1701-
}
1702-
ringCoordinates.push_back(exteriorPointList);
1703-
1704-
//interior rings
1705-
for(int i = 0; i < interiorList.size(); ++i)
1706-
{
1707-
posListElement = interiorList.at(i).firstChild().firstChild().toElement();
1708-
std::list<QgsPoint> interiorPointList;
1709-
if(readCoordinatesFromPosList(interiorPointList, posListElement) != 0)
1710-
{
1711-
return 3;
1712-
}
1713-
ringCoordinates.push_back(interiorPointList);
1714-
}
1715-
1716-
//calculate number of bytes to allocate
1717-
int nrings = 1 + interiorList.size();
1718-
int npoints = 0;//total number of points
1719-
for(std::vector<std::list<QgsPoint> >::const_iterator it = ringCoordinates.begin(); it != ringCoordinates.end(); ++it)
1720-
{
1721-
npoints += it->size();
1722-
}
1723-
int size = 1 + 2 * sizeof(int) + nrings * sizeof(int) + 2 * npoints * sizeof(double);
1724-
*wkb = new unsigned char[size];
1725-
*wkbSize = size;
1726-
*type = QGis::WKBPolygon;
1727-
char e = QgsApplication::endian();
1728-
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
1729-
int nPointsInRing = 0;
1730-
double x, y;
1731-
1732-
//fill the contents into *wkb
1733-
memcpy(&(*wkb)[wkbPosition], &e, 1);
1734-
wkbPosition += 1;
1735-
memcpy(&(*wkb)[wkbPosition], type, sizeof(int));
1736-
wkbPosition += sizeof(int);
1737-
memcpy(&(*wkb)[wkbPosition], &nrings, sizeof(int));
1738-
wkbPosition += sizeof(int);
1739-
for(std::vector<std::list<QgsPoint> >::const_iterator it = ringCoordinates.begin(); it != ringCoordinates.end(); ++it)
1740-
{
1741-
nPointsInRing = it->size();
1742-
memcpy(&(*wkb)[wkbPosition], &nPointsInRing, sizeof(int));
1743-
wkbPosition += sizeof(int);
1744-
//iterate through the string list converting the strings to x-/y- doubles
1745-
std::list<QgsPoint>::const_iterator iter;
1746-
for(iter = it->begin(); iter != it->end(); ++iter)
1747-
{
1748-
x = iter->x();
1749-
y = iter->y();
1750-
//qWarning("currentCoordinate: " + QString::number(x) + " // " + QString::number(y));
1751-
memcpy(&(*wkb)[wkbPosition], &x, sizeof(double));
1752-
wkbPosition += sizeof(double);
1753-
memcpy(&(*wkb)[wkbPosition], &y, sizeof(double));
1754-
wkbPosition += sizeof(double);
1755-
}
1756-
}
1757-
return 0;
1758-
}
1759-
1760-
int QgsWFSProvider::getWkbFromGML3MultiSurface(const QDomElement& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const
1761-
{
1762-
//get <surfaceMembers> tag
1763-
QDomNodeList surfaceMembersList = geometryElement.elementsByTagNameNS(GML_NAMESPACE, "surfaceMembers");
1764-
if(surfaceMembersList.size() < 1)
1765-
{
1766-
return 1;
1767-
}
1768-
QDomElement surfaceMembersElement = surfaceMembersList.at(0).toElement();
1769-
1770-
QDomNodeList polygonNodeList = surfaceMembersElement.elementsByTagNameNS(GML_NAMESPACE, "Polygon");
1771-
1772-
//first list: different polygons, second list: different rings, third list: different points
1773-
std::list<std::list<std::list<QgsPoint> > > multiPolygonPoints;
1774-
QDomNodeList exteriorNodeList;
1775-
QDomElement currentExteriorElement;
1776-
QDomNodeList interiorNodeList;
1777-
QDomElement currentInteriorElement;
1778-
QDomNodeList linearRingNodeList;
1779-
QDomElement linearRingElement;
1780-
QDomNodeList posListNodeList;
1781-
QDomElement posListElement;
1782-
QDomElement currentPolygonElement;
1783-
1784-
for(int i = 0; i < polygonNodeList.size(); ++i)
1785-
{
1786-
currentPolygonElement = polygonNodeList.at(i).toElement();
1787-
std::list<std::list<QgsPoint> > currentPolygonList;
1788-
1789-
//find exterior ring
1790-
exteriorNodeList = currentPolygonElement.elementsByTagNameNS(GML_NAMESPACE, "exterior");
1791-
for(int i = 0; i < exteriorNodeList.size(); ++i) //normally only one
1792-
{
1793-
currentExteriorElement = exteriorNodeList.at(i).toElement();
1794-
linearRingNodeList = currentExteriorElement.elementsByTagNameNS(GML_NAMESPACE, "LinearRing");
1795-
if(linearRingNodeList.size() < 1)
1796-
{
1797-
continue;
1798-
}
1799-
linearRingElement = linearRingNodeList.at(i).toElement();
1800-
posListNodeList = linearRingElement.elementsByTagNameNS(GML_NAMESPACE, "posList");
1801-
if(posListNodeList.size() < 1)
1802-
{
1803-
continue;
1804-
}
1805-
posListElement = posListNodeList.at(i).toElement();
1806-
std::list<QgsPoint> ringCoordinates;
1807-
if(readCoordinatesFromPosList(ringCoordinates, posListElement) != 0)
1808-
{
1809-
continue;
1810-
}
1811-
currentPolygonList.push_back(ringCoordinates);
1812-
}
1813-
//find interior rings
1814-
interiorNodeList = currentPolygonElement.elementsByTagNameNS(GML_NAMESPACE, "interior");
1815-
for(int i = 0; i < interiorNodeList.size(); ++i)
1816-
{
1817-
currentInteriorElement = interiorNodeList.at(i).toElement();
1818-
linearRingNodeList = currentInteriorElement.elementsByTagNameNS(GML_NAMESPACE, "LinearRing");
1819-
if(linearRingNodeList.size() < 1)
1820-
{
1821-
continue;
1822-
}
1823-
linearRingElement = linearRingNodeList.at(i).toElement();
1824-
posListNodeList = linearRingElement.elementsByTagNameNS(GML_NAMESPACE, "posList");
1825-
if(posListNodeList.size() < 1)
1826-
{
1827-
continue;
1828-
}
1829-
posListElement = posListNodeList.at(i).toElement();
1830-
std::list<QgsPoint> ringCoordinates;
1831-
if(readCoordinatesFromPosList(ringCoordinates, posListElement) != 0)
1832-
{
1833-
continue;
1834-
}
1835-
currentPolygonList.push_back(ringCoordinates);
1836-
}
1837-
multiPolygonPoints.push_back(currentPolygonList);
1838-
}
1839-
1840-
int size = 1 + 2 * sizeof(int);
1841-
//calculate the wkb size
1842-
for(std::list<std::list<std::list<QgsPoint> > >::const_iterator it = multiPolygonPoints.begin(); it != multiPolygonPoints.end(); ++it)
1843-
{
1844-
size += 1 + 2 * sizeof(int);
1845-
for(std::list<std::list<QgsPoint> >::const_iterator iter = it->begin(); iter != it->end(); ++iter)
1846-
{
1847-
size += sizeof(int) + 2 * iter->size() * sizeof(double);
1848-
}
1849-
}
1850-
*wkb = new unsigned char[size];
1851-
*wkbSize = size;
1852-
*type = QGis::WKBMultiPolygon;
1853-
int polygonType = QGis::WKBPolygon;
1854-
char e = QgsApplication::endian();
1855-
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
1856-
double x, y;
1857-
int nPolygons = multiPolygonPoints.size();
1858-
int nRings;
1859-
int nPointsInRing;
1860-
1861-
//fill the contents into *wkb
1862-
memcpy(&(*wkb)[wkbPosition], &e, 1);
1863-
wkbPosition += 1;
1864-
memcpy(&(*wkb)[wkbPosition], type, sizeof(int));
1865-
wkbPosition += sizeof(int);
1866-
memcpy(&(*wkb)[wkbPosition], &nPolygons, sizeof(int));
1867-
wkbPosition += sizeof(int);
1868-
1869-
for(std::list<std::list<std::list<QgsPoint> > >::const_iterator it = multiPolygonPoints.begin(); it != multiPolygonPoints.end(); ++it)
1870-
{
1871-
memcpy(&(*wkb)[wkbPosition], &e, 1);
1872-
wkbPosition += 1;
1873-
memcpy(&(*wkb)[wkbPosition], &polygonType, sizeof(int));
1874-
wkbPosition += sizeof(int);
1875-
nRings = it->size();
1876-
memcpy(&(*wkb)[wkbPosition], &nRings, sizeof(int));
1877-
wkbPosition += sizeof(int);
1878-
for(std::list<std::list<QgsPoint> >::const_iterator iter = it->begin(); iter != it->end(); ++iter)
1879-
{
1880-
nPointsInRing = iter->size();
1881-
memcpy(&(*wkb)[wkbPosition], &nPointsInRing, sizeof(int));
1882-
wkbPosition += sizeof(int);
1883-
for(std::list<QgsPoint>::const_iterator iterator = iter->begin(); iterator != iter->end(); ++iterator)
1884-
{
1885-
x = iterator->x();
1886-
y = iterator->y();
1887-
memcpy(&(*wkb)[wkbPosition], &x, sizeof(double));
1888-
wkbPosition += sizeof(double);
1889-
memcpy(&(*wkb)[wkbPosition], &y, sizeof(double));
1890-
wkbPosition += sizeof(double);
1891-
}
1892-
}
1893-
}
1894-
return 0;
1895-
}
1896-
1897-
int QgsWFSProvider::getWkbFromGML3MultiCurve(const QDomElement& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const
1898-
{
1899-
QDomNodeList curveMembersList = geometryElement.elementsByTagNameNS(GML_NAMESPACE, "curveMembers");
1900-
if(curveMembersList.size() < 1)
1901-
{
1902-
return 1;
1903-
}
1904-
QDomElement curveMembersElement = curveMembersList.at(0).toElement();
1905-
//analyze the <LineString> tags
1906-
QDomNodeList LineStringNodeList = geometryElement.elementsByTagNameNS(GML_NAMESPACE, "LineString");
1907-
//the first list contains the lines, the second one the coordinates for each line
1908-
std::list<std::list<QgsPoint> > lineCoordinates;
1909-
QDomElement currentLineStringElement;
1910-
QDomNodeList currentPosList;
1911-
1912-
for(int i = 0; i < LineStringNodeList.size(); ++i)
1913-
{
1914-
currentLineStringElement = LineStringNodeList.at(i).toElement();
1915-
//posList element
1916-
currentPosList = currentLineStringElement.elementsByTagNameNS(GML_NAMESPACE, "posList");
1917-
if(currentPosList.size() < 1)
1918-
{
1919-
return 2;
1920-
}
1921-
std::list<QgsPoint> currentPointList;
1922-
if(readCoordinatesFromPosList(currentPointList, currentPosList.at(0).toElement()) != 0)
1923-
{
1924-
return 3;
1925-
}
1926-
lineCoordinates.push_back(currentPointList);
1927-
}
1928-
1929-
//calculate the required wkb size
1930-
int size = (lineCoordinates.size() + 1) * (1 + 2 * sizeof(int));
1931-
for(std::list<std::list<QgsPoint> >::const_iterator it = lineCoordinates.begin(); it != lineCoordinates.end(); ++it)
1932-
{
1933-
size += it->size() * 2 * sizeof(double);
1934-
}
1935-
*wkb = new unsigned char[size];
1936-
*wkbSize = size;
1937-
*type = QGis::WKBMultiLineString;
1938-
1939-
//fill the wkb content
1940-
char e = QgsApplication::endian();
1941-
int wkbPosition = 0; //current offset from wkb beginning (in bytes)
1942-
int nLines = lineCoordinates.size();
1943-
int nPoints; //number of points in a line
1944-
double x, y;
1945-
memcpy(&(*wkb)[wkbPosition], &e, 1);
1946-
wkbPosition += 1;
1947-
memcpy(&(*wkb)[wkbPosition], type, sizeof(int));
1948-
wkbPosition += sizeof(int);
1949-
memcpy(&(*wkb)[wkbPosition], &nLines, sizeof(int));
1950-
wkbPosition += sizeof(int);
1951-
for(std::list<std::list<QgsPoint> >::const_iterator it = lineCoordinates.begin(); it != lineCoordinates.end(); ++it)
1952-
{
1953-
memcpy(&(*wkb)[wkbPosition], &e, 1);
1954-
wkbPosition += 1;
1955-
memcpy(&(*wkb)[wkbPosition], type, sizeof(int));
1956-
wkbPosition += sizeof(int);
1957-
nPoints = it->size();
1958-
memcpy(&(*wkb)[wkbPosition], &nPoints, sizeof(int));
1959-
wkbPosition += sizeof(int);
1960-
for(std::list<QgsPoint>::const_iterator iter = it->begin(); iter != it->end(); ++iter)
1961-
{
1962-
x = iter->x();
1963-
//qWarning("x is: " + QString::number(x));
1964-
y = iter->y();
1965-
//qWarning("y is: " + QString::number(y));
1966-
memcpy(&(*wkb)[wkbPosition], &x, sizeof(double));
1967-
wkbPosition += sizeof(double);
1968-
memcpy(&(*wkb)[wkbPosition], &y, sizeof(double));
1969-
wkbPosition += sizeof(double);
1970-
}
1971-
}
1972-
return 0;
1973-
}
1974-
1975-
int QgsWFSProvider::readCoordinatesFromPosList(std::list<QgsPoint>& coords, const QDomElement elem) const
1976-
{
1977-
//srsDimension
1978-
int srsDimension;
1979-
int srsDiff; //difference betwen srsDimension and 2
1980-
QString srsDimensionString = elem.attributeNS(GML_NAMESPACE, "srsDimension");
1981-
if(srsDimensionString.isEmpty())
1982-
{
1983-
srsDimension = 2;
1984-
}
1985-
else
1986-
{
1987-
bool conversionSuccess;
1988-
srsDimension = srsDimensionString.toInt(&conversionSuccess);
1989-
if(!conversionSuccess)
1990-
{
1991-
srsDimension = 2;
1992-
}
1993-
}
1994-
1995-
if(srsDimension < 2)
1996-
{
1997-
return 1;
1998-
}
1999-
srsDiff = srsDimension - 2;
2000-
2001-
coords.clear();
2002-
QStringList coordinateStringList = elem.text().split(" ", QString::SkipEmptyParts);
2003-
QStringList::const_iterator iter;
2004-
2005-
bool conversionSuccess;
2006-
double currentX;
2007-
double currentY;
2008-
for(iter = coordinateStringList.constBegin(); iter != coordinateStringList.constEnd(); ++iter)
2009-
{
2010-
currentX = iter->toDouble(&conversionSuccess);
2011-
if(!conversionSuccess)
2012-
{
2013-
coords.clear();
2014-
return 1;
2015-
}
2016-
++iter;
2017-
if(iter == coordinateStringList.constEnd()) //odd number of doubles
2018-
{
2019-
coords.clear();
2020-
return 2;
2021-
}
2022-
currentY = iter->toDouble(&conversionSuccess);
2023-
if(!conversionSuccess)
2024-
{
2025-
coords.clear();
2026-
return 1;
2027-
}
2028-
for(int i = 0; i < srsDiff; ++i) //for higher dimensional entries
2029-
{
2030-
++iter;
2031-
}
2032-
coords.push_back(QgsPoint(currentX, currentY));
2033-
//qWarning("adding coordinates " + QString::number(currentX) + " // " + QString::number(currentY) + " to coordinates list");
2034-
}
2035-
return 0;
2036-
}
2037-
2038-
int QgsWFSProvider::setSRSFromGML3(const QDomElement& wfsCollectionElement)
2039-
{
2040-
QgsDebugMsg("entering QgsWFSProvider::setSRSFromGML");
2041-
//search <gml:boundedBy>
2042-
QDomNodeList boundedByList = wfsCollectionElement.elementsByTagNameNS(GML_NAMESPACE, "boundedBy");
2043-
if(boundedByList.size() < 1)
2044-
{
2045-
QgsDebugMsg("Error, could not find boundedBy element");
2046-
return 1;
2047-
}
2048-
//search <gml:Envelope>
2049-
QDomElement boundedByElem = boundedByList.at(0).toElement();
2050-
QDomNodeList envelopeList = boundedByElem.elementsByTagNameNS(GML_NAMESPACE, "Envelope");
2051-
if(envelopeList.size() < 1)
2052-
{
2053-
QgsDebugMsg("Error, could not find Envelope element");
2054-
return 2;
2055-
}
2056-
QDomElement envelopeElem = envelopeList.at(0).toElement();
2057-
//getAttribute 'srsName'
2058-
QString srsName = envelopeElem.attribute("srsName");
2059-
if(srsName.isEmpty())
2060-
{
2061-
QgsDebugMsg("Error, srsName is empty");
2062-
return 3;
2063-
}
2064-
QgsDebugMsg("srsName is: " +srsName);
2065-
mSourceSRS = new QgsSpatialRefSys();
2066-
if(!mSourceSRS->createFromOgcWmsCrs(srsName))
2067-
{
2068-
QgsDebugMsg("Error, creation of QgsSpatialRefSys failed");
2069-
delete mSourceSRS;
2070-
mSourceSRS = 0;
2071-
return 4;
2072-
}
2073-
return 0;
2074-
}
2075-
#endif //0 //methods for reading GML3

‎src/providers/wfs/qgswfsprovider.h

Lines changed: 10 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <QDomElement>
2222
#include "qgis.h"
2323
#include "qgsrect.h"
24+
#include "qgsspatialrefsys.h"
2425
#include "qgsvectordataprovider.h"
2526
#include <geos.h>
2627
#include <indexStrtree.h>
@@ -37,6 +38,7 @@ class QgsRect;
3738
/**A provider reading features from a WFS server*/
3839
class QgsWFSProvider: public QgsVectorDataProvider
3940
{
41+
Q_OBJECT
4042
public:
4143

4244
enum REQUEST_ENCODING
@@ -96,6 +98,14 @@ class QgsWFSProvider: public QgsVectorDataProvider
9698
stores them in a vector*/
9799
int getFeature(const QString& uri);
98100

101+
102+
signals:
103+
void dataReadProgressMessage(QString message);
104+
105+
private slots:
106+
/**Receives the progress signals from QgsWFSData::dataReadProgress, generates a string \
107+
and emits the dataReadProgressMessage signal*/
108+
void handleWFSProgressMessage(int done, int total);
99109

100110

101111
protected:
@@ -169,43 +179,6 @@ class QgsWFSProvider: public QgsVectorDataProvider
169179
int readGML2Coordinates(std::list<QgsPoint>& coords, const QDomElement elem) const;
170180
/**Tries to create a QgsSpatialRefSys object and assign it to mSourceSRS. Returns 0 in case of success*/
171181
int setSRSFromGML2(const QDomElement& wfsCollectionElement);
172-
173-
174-
175-
176-
177-
178-
//GML3 specific methods. Not needed at the moment as most servers support GML2
179-
#if 0
180-
/**Evaluates the <gml:boundedBy> element
181-
@return 0 in case of success*/
182-
int getExtentFromGML3(QgsRect* extent, const QDomElement& wfsCollectionElement) const;
183-
/**Turns GML into QGIS features
184-
@param wfsCollectionElement reference to the GML parent element
185-
@param geometryAttribute the name of the attribute containing the geometry
186-
@param features the vector where pointers to the features are filled (the features have to be deleted after usage)
187-
@return 0 in case of success*/
188-
int getFeaturesFromGML3(const QDomElement& wfsCollectionElement, const QString& geometryAttribute, std::vector<QgsFeature*>& features) const;
189-
/**Turns a GML geometry attribute element (and its contents) into wkb. This function delegates the work to the geometry type specific functions below.
190-
@param wkb allocated geometry data
191-
@param wkbSize size of the allocated data
192-
@param type wkb type (point/multipoint/line/multiline/polygon/multipolygon)
193-
@return 0 in case of success*/
194-
int getWkbFromGML3(const QDomNode& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const;
195-
int getWkbFromGML3Point(const QDomElement& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const;
196-
int getWkbFromGML3LineString(const QDomElement& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const;
197-
int getWkbFromGML3Polygon(const QDomElement& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const;
198-
int getWkbFromGML3MultiSurface(const QDomElement& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const;
199-
int getWkbFromGML3MultiCurve(const QDomElement& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const;
200-
/**Takes a <gml:pos> or <gml:posList> element and fills the coordinates into the passed list
201-
@param coords the list where the coordinates are filled into
202-
@param elem the <gml:pos> or <gml:posList> element
203-
@return 0 in case of success*/
204-
int readCoordinatesFromPosList(std::list<QgsPoint>& coords, const QDomElement elem) const;
205-
206-
/**Tries to create a QgsSpatialRefSys object and assign it to mSourceSRS. Returns 0 in case of success*/
207-
int setSRSFromGML3(const QDomElement& wfsCollectionElement);
208-
#endif //0 methods for GML3
209182
};
210183

211184
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.