📄 qgswfsdata.cpp
字号:
/*************************************************************************** qgswfsdata.cpp -------------------------------------- Date : Sun Sep 16 12:19:51 AKDT 2007 Copyright : (C) 2007 by Gary E. Sherman Email : sherman at mrcc dot 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. * * * ***************************************************************************/#include "qgswfsdata.h"#include "qgsrect.h"#include "qgsspatialrefsys.h"#include <QBuffer>#include <QUrl>//just for a test//#include <QProgressDialog>const char NS_SEPARATOR = '?';const QString GML_NAMESPACE = "http://www.opengis.net/gml";QgsWFSData::QgsWFSData(const QString& uri, QgsRect* extent, QgsSpatialRefSys* srs, std::list<QgsFeature*>* features, const QString& geometryAttribute, const std::set<QString>& thematicAttributes, QGis::WKBTYPE* wkbType): QObject(), mUri(uri), mExtent(extent), mSrs(srs), mFeatures(features), mGeometryAttribute(geometryAttribute), mThematicAttributes(thematicAttributes), mWkbType(wkbType), mFinished(false), mFeatureCount(0){ //qWarning("Name of the geometry attribute is:"); //qWarning(mGeometryAttribute.toLocal8Bit().data()); //find out mTypeName from uri QStringList arguments = uri.split("&"); QStringList::const_iterator it; for(it = arguments.constBegin(); it != arguments.constEnd(); ++it) { if(it->startsWith("TYPENAME", Qt::CaseInsensitive)) { mTypeName = it->section("=", 1, 1); qWarning("mTypeName is:"); qWarning(mTypeName.toLocal8Bit().data()); } } mEndian = QgsApplication::endian(); QObject::connect(&mHttp, SIGNAL(done(bool)), this, SLOT(setFinished(bool)));}QgsWFSData::~QgsWFSData(){}QgsWFSData::QgsWFSData(){}int QgsWFSData::getWFSData(){ XML_Parser p = XML_ParserCreateNS(NULL, NS_SEPARATOR); XML_SetUserData(p, this); XML_SetElementHandler(p, QgsWFSData::start, QgsWFSData::end); XML_SetCharacterDataHandler(p, QgsWFSData::chars); //separate host from query string QUrl requestUrl(mUri); int portNr = requestUrl.port(); if(portNr != -1) { mHttp.setHost(requestUrl.host(), portNr); } else { mHttp.setHost(requestUrl.host()); } mHttp.get(mUri); //loop to read the data QByteArray readData; int atEnd = 0; qWarning("Entering loop"); while(!mFinished || mHttp.bytesAvailable() > 0) { if(mFinished) { atEnd = 1; } if(mHttp.bytesAvailable() != 0) { readData = mHttp.readAll(); XML_Parse(p, readData.data(), readData.size(), atEnd); } qApp->processEvents(QEventLoop::ExcludeUserInputEvents); } qWarning("Left loop"); return 0; //soon}void QgsWFSData::setFinished(bool error){ if(error) { //qWarning("Finished with error"); //qWarning(mHttp.errorString().toLocal8Bit().data()); } else { //qWarning("Finished without error"); } mFinished = true;}void QgsWFSData::startElement(const XML_Char* el, const XML_Char** attr){ QString elementName(el); QString localName = elementName.section(NS_SEPARATOR, 1, 1); if(elementName == GML_NAMESPACE + NS_SEPARATOR + "coordinates") { mParseModeStack.push(QgsWFSData::coordinate); mStringCash.clear(); mCoordinateSeparator = readCsFromAttribute(attr); mTupleSeparator = readTsFromAttribute(attr); } else if(localName == mGeometryAttribute) { mParseModeStack.push(QgsWFSData::geometry); } else if(mParseModeStack.size() == 0 && elementName == GML_NAMESPACE + NS_SEPARATOR + "boundedBy") { mParseModeStack.push(QgsWFSData::boundingBox); } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "featureMember") { mCurrentFeature = new QgsFeature(mFeatureCount); mAttributeIndex = 0; mParseModeStack.push(QgsWFSData::featureMember); } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "Box" && mParseModeStack.top() == QgsWFSData::boundingBox) { //read attribute srsName="EPSG:26910" int epsgNr; if(readEpsgFromAttribute(epsgNr, attr) != 0) { qWarning("error, could not get epsg id"); } //qWarning(("epsg id is: " + QString::number(epsgNr)).toLocal8Bit().data()); if(mSrs) { if(!mSrs->createFromEpsg(epsgNr)) { qWarning("Creation of srs from epsg failed"); } } } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "Polygon") { std::list<unsigned char*> wkbList; std::list<int> wkbSizeList; mCurrentWKBFragments.push_back(wkbList); mCurrentWKBFragmentSizes.push_back(wkbSizeList); } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiPoint") { mParseModeStack.push(QgsWFSData::multiPoint); //we need one nested list for intermediate WKB std::list<unsigned char*> wkbList; std::list<int> wkbSizeList; mCurrentWKBFragments.push_back(wkbList); mCurrentWKBFragmentSizes.push_back(wkbSizeList); } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiLineString") { mParseModeStack.push(QgsWFSData::multiLine); //we need one nested list for intermediate WKB std::list<unsigned char*> wkbList; std::list<int> wkbSizeList; mCurrentWKBFragments.push_back(wkbList); mCurrentWKBFragmentSizes.push_back(wkbSizeList); } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiPolygon") { mParseModeStack.push(QgsWFSData::multiPolygon); } else if(mParseModeStack.size() == 1 && mParseModeStack.top() == QgsWFSData::featureMember && mThematicAttributes.find(localName) != mThematicAttributes.end()) { mParseModeStack.push(QgsWFSData::attribute); mAttributeName = localName; mStringCash.clear(); }}void QgsWFSData::endElement(const XML_Char* el){ QString elementName(el); QString localName = elementName.section(NS_SEPARATOR, 1, 1); if(elementName == GML_NAMESPACE + NS_SEPARATOR + "coordinates") { if(!mParseModeStack.empty()) { mParseModeStack.pop(); } } else if(localName == mAttributeName) { if(!mParseModeStack.empty()) { mParseModeStack.pop(); } mCurrentFeature->addAttribute(mAttributeIndex, QVariant(mStringCash)); ++mAttributeIndex; } else if(localName == mGeometryAttribute) { if(!mParseModeStack.empty()) { mParseModeStack.pop(); } } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "boundedBy" && mParseModeStack.top() == QgsWFSData::boundingBox) { //create bounding box from mStringCash if(createBBoxFromCoordinateString(mExtent, mStringCash) != 0) { qWarning("creation of bounding box failed"); } if(!mParseModeStack.empty()) { mParseModeStack.pop(); } } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "featureMember") { mCurrentFeature->setGeometryAndOwnership(mCurrentWKB, mCurrentWKBSize); mFeatures->push_back(mCurrentFeature); ++mFeatureCount; //qWarning("Removing featureMember from stack"); mParseModeStack.pop(); } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "Point") { std::list<QgsPoint> pointList; if(pointsFromCoordinateString(pointList, mStringCash, mCoordinateSeparator, mTupleSeparator) != 0) { //error } if(mParseModeStack.top() != QgsWFSData::multiPoint) { //directly add WKB point to the feature if(getPointWKB(&mCurrentWKB, &mCurrentWKBSize, *(pointList.begin())) != 0) { //error } *mWkbType = QGis::WKBPoint; } else //multipoint, add WKB as fragment { unsigned char* wkb = 0; int wkbSize = 0; std::list<unsigned char*> wkbList; std::list<int> wkbSizeList; if(getPointWKB(&wkb, &wkbSize, *(pointList.begin())) != 0) { //error } mCurrentWKBFragments.rbegin()->push_back(wkb); mCurrentWKBFragmentSizes.rbegin()->push_back(wkbSize); //wkbList.push_back(wkb); //wkbSizeList.push_back(wkbSize); //mCurrentWKBFragments.push_back(wkbList); //mCurrentWKBFragmentSizes.push_back(wkbSizeList); } } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "LineString") { //add WKB point to the feature std::list<QgsPoint> pointList; if(pointsFromCoordinateString(pointList, mStringCash, mCoordinateSeparator, mTupleSeparator) != 0) { //error } if(mParseModeStack.top() != QgsWFSData::multiLine) { if(getLineWKB(&mCurrentWKB, &mCurrentWKBSize, pointList) != 0) { //error } *mWkbType = QGis::WKBLineString; } else //multiline, add WKB as fragment { unsigned char* wkb = 0; int wkbSize = 0; std::list<unsigned char*> wkbList; std::list<int> wkbSizeList; if(getLineWKB(&wkb, &wkbSize, pointList) != 0) { //error } mCurrentWKBFragments.rbegin()->push_back(wkb); mCurrentWKBFragmentSizes.rbegin()->push_back(wkbSize); //wkbList.push_back(wkb); //wkbSizeList.push_back(wkbSize); //mCurrentWKBFragments.push_back(wkbList); //mCurrentWKBFragmentSizes.push_back(wkbSizeList); } } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "LinearRing") { std::list<QgsPoint> pointList; if(pointsFromCoordinateString(pointList, mStringCash, mCoordinateSeparator, mTupleSeparator) != 0) { //error } unsigned char* wkb; int wkbSize; if(getRingWKB(&wkb, &wkbSize, pointList) != 0) { //error } mCurrentWKBFragments.rbegin()->push_back(wkb); mCurrentWKBFragmentSizes.rbegin()->push_back(wkbSize); } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "Polygon") { *mWkbType = QGis::WKBPolygon; if(mParseModeStack.top() != QgsWFSData::multiPolygon) { createPolygonFromFragments(); } } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiPoint") { if(!mParseModeStack.empty()) { mParseModeStack.pop(); } createMultiPointFromFragments(); } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiLineString") { if(!mParseModeStack.empty()) { mParseModeStack.pop(); } createMultiLineFromFragments(); } else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "MultiPolygon") { if(!mParseModeStack.empty()) { mParseModeStack.pop(); } createMultiPolygonFromFragments(); }}void QgsWFSData::characters(const XML_Char* chars, int len){ //save chars in mStringCash attribute mode or coordinate mode if(mParseModeStack.size() == 0) { return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -