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

📄 qgsgpxprovider.cpp

📁 一个非常好的GIS开源新版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************      qgsgpxprovider.cpp  -  Data provider for GPS eXchange files                             -------------------    begin                : 2004-04-14    copyright            : (C) 2004 by Lars Luthman    email                : larsl@users.sourceforge.net    Partly based on qgsdelimitedtextprovider.cpp, (C) 2004 Gary E. Sherman ***************************************************************************//*************************************************************************** *                                                                         * *   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.                                   * *                                                                         * ***************************************************************************//* $Id: qgsgpxprovider.cpp 8257 2008-03-21 00:45:50Z jef $ */#include <algorithm>#include <iostream>#include <limits>#include <cstring>#include <cmath>// Changed #include <qapp.h> to <qapplication.h>. Apparently some// debian distros do not include the qapp.h wrapper and the compilation// fails. [gsherman]#include <QApplication>#include <QFile>#include <QTextStream>#include <QObject>#include "qgis.h"#include "qgsapplication.h"#include "qgsdataprovider.h"#include "qgsfeature.h"#include "qgsfield.h"#include "qgsgeometry.h"#include "qgsspatialrefsys.h"#include "qgsrect.h"#include "qgsgpxprovider.h"#include "gpsdata.h"#include "qgslogger.h"const char* QgsGPXProvider::attr[] = { "name", "elevation", "symbol", "number",				       "comment", "description", "source", 				       "url", "url name" };const QString GPX_KEY = "gpx";const QString GPX_DESCRIPTION = QObject::tr("GPS eXchange format provider");QgsGPXProvider::QgsGPXProvider(QString uri) :         QgsVectorDataProvider(uri){  // assume that it won't work  mValid = false;    // we always use UTF-8  mEncoding = QTextCodec::codecForName("utf8");    // get the filename and the type parameter from the URI  int fileNameEnd = uri.find('?');  if (fileNameEnd == -1 || uri.mid(fileNameEnd + 1, 5) != "type=") {    QgsLogger::warning(tr("Bad URI - you need to specify the feature type."));    return;  }  QString typeStr = uri.mid(fileNameEnd + 6);  mFeatureType = (typeStr == "waypoint" ? WaypointType :		  (typeStr == "route" ? RouteType : TrackType));    // set up the attributes and the geometry type depending on the feature type  attributeFields[NameAttr] = QgsField(attr[NameAttr], QVariant::String, "text");  if (mFeatureType == WaypointType) {    attributeFields[EleAttr] = QgsField(attr[EleAttr], QVariant::Double, "double");    attributeFields[SymAttr] = QgsField(attr[SymAttr], QVariant::String, "text");  }  else if (mFeatureType == RouteType || mFeatureType == TrackType) {    attributeFields[NumAttr] = QgsField(attr[NumAttr], QVariant::Int, "int");  }  attributeFields[CmtAttr] = QgsField(attr[CmtAttr], QVariant::String, "text");  attributeFields[DscAttr] = QgsField(attr[DscAttr], QVariant::String, "text");  attributeFields[SrcAttr] = QgsField(attr[SrcAttr], QVariant::String, "text");  attributeFields[URLAttr] = QgsField(attr[URLAttr], QVariant::String, "text");  attributeFields[URLNameAttr] = QgsField(attr[URLNameAttr], QVariant::String, "text");  mFileName = uri.left(fileNameEnd);  // set the selection rectangle to null  mSelectionRectangle = 0;    // parse the file  data = GPSData::getData(mFileName);  if (data == 0) {    return;  }  mValid = true;}QgsGPXProvider::~QgsGPXProvider(){  GPSData::releaseData(mFileName);}QString QgsGPXProvider::storageType() const{  return tr("GPS eXchange file");}int QgsGPXProvider::capabilities() const{  return QgsVectorDataProvider::AddFeatures |         QgsVectorDataProvider::DeleteFeatures |         QgsVectorDataProvider::ChangeAttributeValues;}bool QgsGPXProvider::getNextFeature(QgsFeature& feature){  bool result = false;    QgsAttributeList::const_iterator iter;    if (mFeatureType == WaypointType)     {      // go through the list of waypoints and return the first one that is in      // the bounds rectangle      for (; mWptIter != data->waypointsEnd(); ++mWptIter) 	{	  const Waypoint* wpt;	  wpt = &(*mWptIter);	  if (boundsCheck(wpt->lon, wpt->lat)) 	    {	      feature.setFeatureId(wpt->id);	      result = true;	      	      // some wkb voodoo	      if(mFetchGeom)		{		  char* geo = new char[21];		  std::memset(geo, 0, 21);		  geo[0] = QgsApplication::endian();		  geo[geo[0] == QgsApplication::NDR ? 1 : 4] = QGis::WKBPoint;		  std::memcpy(geo+5, &wpt->lon, sizeof(double));		  std::memcpy(geo+13, &wpt->lat, sizeof(double));		  feature.setGeometryAndOwnership((unsigned char *)geo, sizeof(wkbPoint));		}	      feature.setValid(true);	        // add attributes if they are wanted	      for (iter = mAttributesToFetch.begin(); iter != mAttributesToFetch.end(); ++iter) 		{		  switch (*iter) 		    {        case NameAttr:          feature.addAttribute(NameAttr, QVariant(wpt->name));		      break;        case EleAttr:		      if (wpt->ele != -std::numeric_limits<double>::max())            feature.addAttribute(EleAttr, QVariant(wpt->ele));		      break;		    case SymAttr:          feature.addAttribute(SymAttr, QVariant(wpt->sym));		      break;        case CmtAttr:          feature.addAttribute(CmtAttr, QVariant(wpt->cmt));		      break;		    case DscAttr:          feature.addAttribute(DscAttr, QVariant(wpt->desc));		      break;		    case SrcAttr:          feature.addAttribute(SrcAttr, QVariant(wpt->src));		      break;		    case URLAttr:          feature.addAttribute(URLAttr, QVariant(wpt->url));		      break;		    case URLNameAttr:          feature.addAttribute(URLNameAttr, QVariant(wpt->urlname));		      break;		    }		}	      	      ++mWptIter;	      break;	    }	}    }    else if (mFeatureType == RouteType)     {      // go through the routes and return the first one that is in the bounds      // rectangle      for (; mRteIter != data->routesEnd(); ++mRteIter) 	{	  const Route* rte;	  rte = &(*mRteIter);	  	  if (rte->points.size() == 0)	    continue;	  const QgsRect& b(*mSelectionRectangle);	  if ((rte->xMax >= b.xMin()) && (rte->xMin <= b.xMax()) &&	      (rte->yMax >= b.yMin()) && (rte->yMin <= b.yMax())) {	    feature.setFeatureId(rte->id);	    result = true;	    	    // some wkb voodoo	    if(mFetchGeom)	      {		int nPoints = rte->points.size();		char* geo = new char[9 + 16 * nPoints];		std::memset(geo, 0, 9 + 16 * nPoints);		geo[0] = QgsApplication::endian();		geo[geo[0] == QgsApplication::NDR ? 1 : 4] = QGis::WKBLineString;		std::memcpy(geo + 5, &nPoints, 4);		for (uint i = 0; i < rte->points.size(); ++i) {		  std::memcpy(geo + 9 + 16 * i, &rte->points[i].lon, sizeof(double));		  std::memcpy(geo + 9 + 16 * i + 8, &rte->points[i].lat, sizeof(double));		}		feature.setGeometryAndOwnership((unsigned char *)geo, 9 + 16 * nPoints);	      }	    feature.setValid(true);	    	    // add attributes if they are wanted	    for (iter = mAttributesToFetch.begin(); iter != mAttributesToFetch.end(); ++iter)       {        switch (*iter)        {          case NameAttr:            feature.addAttribute(NameAttr, QVariant(rte->name));            break;          case NumAttr:            if (rte->number != std::numeric_limits<int>::max())              feature.addAttribute(NumAttr, QVariant(rte->number));            break;          case CmtAttr:            feature.addAttribute(CmtAttr, QVariant(rte->cmt));            break;          case DscAttr:            feature.addAttribute(DscAttr, QVariant(rte->desc));            break;          case SrcAttr:            feature.addAttribute(SrcAttr, QVariant(rte->src));            break;          case URLAttr:            feature.addAttribute(URLAttr, QVariant(rte->url));            break;          case URLNameAttr:            feature.addAttribute(URLNameAttr, QVariant(rte->urlname));            break;        }      }	    	    ++mRteIter;	    break;	  }	}    }    else if (mFeatureType == TrackType)     {      // go through the tracks and return the first one that is in the bounds      // rectangle      for (; mTrkIter != data->tracksEnd(); ++mTrkIter) 	{	  const Track* trk;	  trk = &(*mTrkIter);	            QgsLogger::debug("GPX feature track segments: ", trk->segments.size(), __FILE__, __FUNCTION__, __LINE__);	  if (trk->segments.size() == 0)	    continue;          // A track consists of several segments. Add all those segments into one.          int totalPoints = 0;;          for (std::vector<TrackSegment>::size_type i = 0; i < trk->segments.size(); i ++)          {            totalPoints += trk->segments[i].points.size();          }	  if (totalPoints == 0)	    continue;          QgsDebugMsg("GPX feature track total points: " + QString::number(totalPoints));	  const QgsRect& b(*mSelectionRectangle);	  if ((trk->xMax >= b.xMin()) && (trk->xMin <= b.xMax()) &&	      (trk->yMax >= b.yMin()) && (trk->yMin <= b.yMax())) {	    feature.setFeatureId(trk->id);	    result = true;	    	    // some wkb voodoo	    if(mFetchGeom)	      {		char* geo = new char[9 + 16 * totalPoints];                if (!geo)                {                  QgsDebugMsg("Too large track!!!");                  return false;                }		std::memset(geo, 0, 9 + 16 * totalPoints);		geo[0] = QgsApplication::endian();		geo[geo[0] == QgsApplication::NDR ? 1 : 4] = QGis::WKBLineString;                std::memcpy(geo + 5, &totalPoints, 4);                int thisPoint = 0;                for(std::vector<TrackSegment>::size_type k = 0; k < trk->segments.size(); k++)                {                  int nPoints = trk->segments[k].points.size();                  for (int i = 0; i < nPoints; ++i) 		  {		    std::memcpy(geo + 9 + 16 * thisPoint,     &trk->segments[k].points[i].lon, sizeof(double));		    std::memcpy(geo + 9 + 16 * thisPoint + 8, &trk->segments[k].points[i].lat, sizeof(double));                    thisPoint++;		  }                }		feature.setGeometryAndOwnership((unsigned char *)geo, 9 + 16 * totalPoints);	      }	    feature.setValid(true);	    	    // add attributes if they are wanted	    for (iter = mAttributesToFetch.begin(); iter != mAttributesToFetch.end(); ++iter)       {        switch (*iter)        {          case NameAttr:            feature.addAttribute(NameAttr, QVariant(trk->name));            break;          case NumAttr:            if (trk->number != std::numeric_limits<int>::max())              feature.addAttribute(NumAttr, QVariant(trk->number));            break;          case CmtAttr:            feature.addAttribute(CmtAttr, QVariant(trk->cmt));            break;          case DscAttr:            feature.addAttribute(DscAttr, QVariant(trk->desc));            break;          case SrcAttr:            feature.addAttribute(SrcAttr, QVariant(trk->src));            break;          case URLAttr:            feature.addAttribute(URLAttr, QVariant(trk->url));            break;          case URLNameAttr:            feature.addAttribute(URLNameAttr, QVariant(trk->urlname));            break;        }      }	          ++mTrkIter;	    break;	  }	}    }  return result;}void QgsGPXProvider::select(QgsAttributeList fetchAttributes,                            QgsRect rect,                            bool fetchGeometry,                            bool useIntersect){  if(rect.isEmpty())    {      mSelectionRectangle = new QgsRect(extent());    }  else    {      mSelectionRectangle = new QgsRect(rect);    }  mAttributesToFetch = fetchAttributes;  mFetchGeom = fetchGeometry;    reset();}// Return the extent of the layerQgsRect QgsGPXProvider::extent(){  return data->getExtent();}/**  * Return the feature type */QGis::WKBTYPE QgsGPXProvider::geometryType() const{  if (mFeatureType == WaypointType)    return QGis::WKBPoint;    if (mFeatureType == RouteType || mFeatureType == TrackType)    return QGis::WKBLineString;    return QGis::WKBUnknown;}/** 

⌨️ 快捷键说明

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