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

📄 qgswfsprovider.cpp

📁 一个非常好的GIS开源新版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
      complexTypeType = typeElement.attribute("type");	            if(complexTypeType.isEmpty())	{	  return 3;	}            //remove the namespace on complexTypeType      if(complexTypeType.contains(":"))	{	  complexTypeType = complexTypeType.section(":", 1, 1);	}            //find <complexType name=complexTypeType      QDomNodeList complexTypeNodeList = schemaElement.elementsByTagNameNS("http://www.w3.org/2001/XMLSchema", "complexType");      for(uint i = 0; i < complexTypeNodeList.length(); ++i)	{	  if(complexTypeNodeList.at(i).toElement().attribute("name") == complexTypeType)	    {	      complexTypeElement = complexTypeNodeList.at(i).toElement();	      break;	    }	}    }  if(complexTypeElement.isNull())    {      return 4;    }    //we have the relevant <complexType> element. Now find out the geometry and the thematic attributes  QDomNodeList attributeNodeList = complexTypeElement.elementsByTagNameNS("http://www.w3.org/2001/XMLSchema", "element");  if(attributeNodeList.size() < 1)    {      return 5;    }  for(uint i = 0; i < attributeNodeList.length(); ++i)    {      QDomElement attributeElement = attributeNodeList.at(i).toElement();      //attribute name      QString name = attributeElement.attribute("name");      //attribute type      QString type = attributeElement.attribute("type");            //is it a geometry attribute?      if(type.startsWith("gml:") && type.endsWith("PropertyType"))      {  	geometryAttribute = name;      }      else //todo: distinguish between numerical and non-numerical types	{          fields[fields.size()] = QgsField(name, QVariant::String, type);	}    }  return 0;}int QgsWFSProvider::guessAttributesFromFile(const QString& uri, QString& geometryAttribute, std::list<QString>& thematicAttributes) const{  QFile gmlFile(uri);  if(!gmlFile.open(QIODevice::ReadOnly))    {      return 1;    }  QDomDocument gmlDoc;  if(!gmlDoc.setContent(&gmlFile, true))    {      return 2; //xml file not readable or not valid    }    //find gmlCollection element  QDomElement featureCollectionElement = gmlDoc.documentElement();    //get the first feature to guess attributes  QDomNodeList featureList = featureCollectionElement.elementsByTagNameNS(GML_NAMESPACE, "featureMember");  if(featureList.size() < 1)    {      return 3; //we need at least one attribute    }  QDomElement featureElement = featureList.at(0).toElement();  QDomNode attributeNode = featureElement.firstChild().firstChild();  if(attributeNode.isNull())    {      return 4;    }  QString attributeText;  QDomElement attributeChildElement;  QString attributeChildLocalName;    while(!attributeNode.isNull())//loop over attributes    {      QString attributeNodeName = attributeNode.toElement().localName();      attributeChildElement = attributeNode.firstChild().toElement();      if(attributeChildElement.isNull())//no child element means it is a thematic attribute for sure	{	  thematicAttributes.push_back(attributeNode.toElement().localName());	  attributeNode = attributeNode.nextSibling();	  continue;	}      attributeChildLocalName = attributeChildElement.localName();      if(attributeChildLocalName == "Point" || attributeChildLocalName == "LineString" || \attributeChildLocalName == "Polygon" || attributeChildLocalName == "MultiPoint" || \attributeChildLocalName == "MultiLineString" || attributeChildLocalName == "MultiPolygon" || \	 attributeChildLocalName == "Surface" || attributeChildLocalName == "MultiSurface")	{	  geometryAttribute = attributeNode.toElement().localName(); //a geometry attribute	}      else	{	  thematicAttributes.push_back(attributeNode.toElement().localName()); //a thematic attribute	}      attributeNode = attributeNode.nextSibling();    }  return 0;}int QgsWFSProvider::getExtentFromGML2(QgsRect* extent, const QDomElement& wfsCollectionElement) const{  QDomNodeList boundedByList = wfsCollectionElement.elementsByTagNameNS(GML_NAMESPACE, "boundedBy");  if(boundedByList.length() < 1)    {      return 1;    }  QDomElement boundedByElement = boundedByList.at(0).toElement();  QDomNode childNode = boundedByElement.firstChild();  if(childNode.isNull())    {      return 2;    }  //support <gml:Box>, <gml:coordinates> and <gml:Envelope>,<gml::lowerCorner>,<gml::upperCorner>. What  //about <gml:Envelope>, <gml:pos>?  QString bboxName = childNode.localName();  if(bboxName != "Box")    {      return 3;    }  QDomNode coordinatesNode = childNode.firstChild();  if(coordinatesNode.localName() == "coordinates")    {      std::list<QgsPoint> boundingPoints;      if(readGML2Coordinates(boundingPoints, coordinatesNode.toElement()) != 0)	{	  return 5;	}            if(boundingPoints.size() != 2)	{	  return 6;	}            std::list<QgsPoint>::const_iterator it = boundingPoints.begin();      extent->setXmin(it->x());      extent->setYmin(it->y());      ++it;      extent->setXmax(it->x());      extent->setYmax(it->y());      return 0;    }  else if(coordinatesNode.localName() == "coord")    {      //first <coord> element      QDomElement xElement, yElement;      bool conversion1, conversion2; //string->double conversion success      xElement = coordinatesNode.firstChild().toElement();      yElement = xElement.nextSibling().toElement();      if(xElement.isNull() || yElement.isNull())	{	  return 7;	}      double x1 = xElement.text().toDouble(&conversion1);      double y1 = yElement.text().toDouble(&conversion2);      if(!conversion1 || !conversion2)	{	  return 8;	}            //second <coord> element      coordinatesNode = coordinatesNode.nextSibling();      xElement = coordinatesNode.firstChild().toElement();      yElement = xElement.nextSibling().toElement();      if(xElement.isNull() || yElement.isNull())	{	  return 9;	}      double x2 = xElement.text().toDouble(&conversion1);      double y2 = yElement.text().toDouble(&conversion2);      if(!conversion1 || !conversion2)	{	  return 10;	}      extent->setXmin(x1);      extent->setYmin(y1);      extent->setXmax(x2);      extent->setYmax(y2);      return 0;    }  else    {      return 11; //no valid tag for the bounding box    }}int QgsWFSProvider::setSRSFromGML2(const QDomElement& wfsCollectionElement){  QgsDebugMsg("entering QgsWFSProvider::setSRSFromGML");  //search <gml:boundedBy>  QDomNodeList boundedByList = wfsCollectionElement.elementsByTagNameNS(GML_NAMESPACE, "boundedBy");  if(boundedByList.size() < 1)    {      QgsDebugMsg("Error, could not find boundedBy element");      return 1;    }  //search <gml:Envelope>  QDomElement boundedByElem = boundedByList.at(0).toElement();  QDomNodeList boxList = boundedByElem.elementsByTagNameNS(GML_NAMESPACE, "Box");  if(boxList.size() < 1)    {      QgsDebugMsg("Error, could not find Envelope element");      return 2;    }  QDomElement boxElem = boxList.at(0).toElement();  //getAttribute 'srsName'  QString srsName = boxElem.attribute("srsName");  if(srsName.isEmpty())    {      QgsDebugMsg("Error, srsName is empty");      return 3;    }  QgsDebugMsg("srsName is: " +srsName);  //extract the EPSG id  int epsgId;  bool conversionSuccess;  if(srsName.contains("#"))//geoserver has "http://www.opengis.net/gml/srs/epsg.xml#4326"    {      epsgId = srsName.section("#", 1, 1).toInt(&conversionSuccess);      if(!conversionSuccess)	{	  return 4;	}    }  else if(srsName.contains(":"))//mapserver has "EPSG:4326"    {      epsgId = srsName.section(":", 1, 1).toInt(&conversionSuccess);      if(!conversionSuccess)	{	  return 5;	}    }  if(!mSourceSRS.createFromEpsg(epsgId))    {      QgsDebugMsg("Error, creation of QgsSpatialRefSys failed");      return 6;    }  return 0;}  int QgsWFSProvider::getFeaturesFromGML2(const QDomElement& wfsCollectionElement, const QString& geometryAttribute){  QDomNodeList featureTypeNodeList = wfsCollectionElement.elementsByTagNameNS(GML_NAMESPACE, "featureMember");  QDomElement currentFeatureMemberElem;  QDomElement layerNameElem;  QDomNode currentAttributeChild;  QDomElement currentAttributeElement;  int counter = 0;  QgsFeature* f = 0;  unsigned char* wkb = 0;  int wkbSize = 0;  QGis::WKBTYPE currentType;  QgsRect featureBBox;  GEOS_GEOM::Envelope* geosBBox;  mFeatureCount = 0;  for(int i = 0; i < featureTypeNodeList.size(); ++i)    {      f = new QgsFeature(counter);      currentFeatureMemberElem = featureTypeNodeList.at(i).toElement();      //the first child element is always <namespace:layer>      layerNameElem = currentFeatureMemberElem.firstChild().toElement();      //the children are the attributes      currentAttributeChild = layerNameElem.firstChild();      int attr = 0;      bool numeric = false;      while(!currentAttributeChild.isNull())	{	  currentAttributeElement = currentAttributeChild.toElement();	  	  if(currentAttributeElement.localName() != "boundedBy")	    {	      currentAttributeElement.text().toDouble(&numeric);	      if((currentAttributeElement.localName()) != geometryAttribute) //a normal attribute		{		  if(numeric)		    {		      f->addAttribute(attr++, QVariant(currentAttributeElement.text().toDouble()));		    }		  else		    {		      f->addAttribute(attr++, QVariant(currentAttributeElement.text()));		    }		}	      else //a geometry attribute		{		  getWkbFromGML2(currentAttributeElement, &wkb, &wkbSize, &currentType);		  mWKBType = currentType; //a more sophisticated method is necessary		  f->setGeometryAndOwnership(wkb, wkbSize);		}	    }	  currentAttributeChild = currentAttributeChild.nextSibling();	}      if(wkb && wkbSize > 0)	{	  //insert bbox and pointer to feature into search tree	  featureBBox = f->geometry()->boundingBox();	  geosBBox = new GEOS_GEOM::Envelope(featureBBox.xMin(), featureBBox.xMax(), featureBBox.yMin(), featureBBox.yMax());	  mSpatialIndex.insert(geosBBox, (void*)f);	  mEnvelopesAndFeatures.push_back(std::make_pair(geosBBox, f));	  ++mFeatureCount;	}      ++counter;    }  return 0;}int QgsWFSProvider::getWkbFromGML2(const QDomNode& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const{  QDomNode geometryChild = geometryElement.firstChild();  if(geometryChild.isNull())    {      return 1;    }  QDomElement geometryTypeElement = geometryChild.toElement();  QString geomType = geometryTypeElement.localName();  if(geomType == "Point")    {      return getWkbFromGML2Point(geometryTypeElement, wkb, wkbSize, type);    }  else if(geomType == "LineString")    {      return getWkbFromGML2LineString(geometryTypeElement, wkb, wkbSize, type);    }  else if(geomType == "Polygon")    {      return getWkbFromGML2Polygon(geometryTypeElement, wkb, wkbSize, type);    }  else if(geomType == "MultiPoint")    {      return getWkbFromGML2MultiPoint(geometryTypeElement, wkb, wkbSize, type);    }  else if(geomType == "MultiLineString")    {      return getWkbFromGML2MultiLineString(geometryTypeElement, wkb, wkbSize, type);    }  else if(geomType == "MultiPolygon")    {      return getWkbFromGML2MultiPolygon(geometryTypeElement, wkb, wkbSize, type);    }  else //unknown type    {      *wkb = 0;      *wkbSize = 0;    }  return 0;}int QgsWFSProvider::getWkbFromGML2Point(const QDomElement& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const{  QDomNodeList coordList = geometryElement.elementsByTagNameNS(GML_NAMESPACE, "coordinates");  if(coordList.size() < 1)    {      return 1;    }  QDomElement coordElement = coordList.at(0).toElement();  std::list<QgsPoint> pointCoordinate;  if(readGML2Coordinates(pointCoordinate, coordElement) != 0)    {      return 2;    }    if(pointCoordinate.size() < 1)    {      return 3;    }    std::list<QgsPoint>::const_iterator point_it = pointCoordinate.begin();  char e = QgsApplication::endian();  double x = point_it->x();  double y = point_it->y();  int size = 1 + sizeof(int) + 2 * sizeof(double);  *wkb = new unsigned char[size];  *wkbSize = size;  *type = QGis::WKBPoint;  int wkbPosition = 0; //current offset from wkb beginning (in bytes)  memcpy(&(*wkb)[wkbPosition], &e, 1);  wkbPosition += 1;  memcpy(&(*wkb)[wkbPosition], type, sizeof(int));  wkbPosition += sizeof(int);  memcpy(&(*wkb)[wkbPosition], &x, sizeof(double));  wkbPosition += sizeof(double);  memcpy(&(*wkb)[wkbPosition], &y, sizeof(double));  return 0;}int QgsWFSProvider::getWkbFromGML2Polygon(const QDomElement& geometryElement, unsigned char** wkb, int* wkbSize, QGis::WKBTYPE* type) const{  //read all the coordinates (as QgsPoint) into memory. Each linear ring has an entry in the vector  std::vector<std::list<QgsPoint> > ringCoordinates;    //read coordinates for outer boundary  QDomNodeList outerBoundaryList = geometryElement.elementsByTagNameNS(GML_NAMESPACE, "outerBoundaryIs");  if(outerBoundaryList.size() < 1) //outer ring is necessary    {      return 1;     }  QDomElement coordinatesElement = outerBoundaryList.at(0).firstChild().firstChild().toElement();  if(coordinatesElement.isNull())    {      return 2;    }  std::list<QgsPoint> exteriorPointList;  if(readGML2Coordinates(exteriorPointList, coordinatesElement) != 0)    {      return 3;    }  ringCoordinates.push_back(exteriorPointList);  //read coordinates for inner boundary  QDomNodeList innerBoundaryList = geometryElement.elementsByTagNameNS(GML_NAMESPACE, "innerBoundaryIs");  for(int i = 0; i < innerBoundaryList.size(); ++i)    {      std::list<QgsPoint> interiorPointList;      QDomElement coordinatesElement = innerBoundaryList.at(i).firstChild().firstChild().toElement();      if(coordinatesElement.isNull())	{	  return 4;	}      if(readGML2Coordinates(interiorPointList, coordinatesElement) != 0)	{	  return 5;	}      ringCoordinates.push_back(interiorPointList);     }  //calculate number of bytes to allocate  int nrings = ringCoordinates.size();  int npoints = 0;//total number of points  for(std::vector<std::list<QgsPoint> >::const_iterator it = ringCoordinates.begin(); it != ringCoordinates.end(); ++it)    {      npoints += it->size();    }   int size = 1 + 2 * sizeof(int) + nrings * sizeof(int) + 2 * npoints * sizeof(double);  *wkb = new unsigned char[size];  *wkbSize = size;  *type = QGis::WKBPolygon;  char e = QgsApplication::endian();  int wkbPosition = 0; //current offset from wkb beginning (in bytes)  int nPointsInRing = 0;  double x, y;    //fill the contents into *wkb  memcpy(&(*wkb)[wkbPosition], &e, 1);  wkbPosition += 1;  memcpy(&(*wkb)[wkbPosition], type, sizeof(int));  wkbPosition += sizeof(int);  memcpy(&(*wkb)[wkbPosition], &nrings, sizeof(int));  wkbPosition += sizeof(int);

⌨️ 快捷键说明

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