diff --git a/ChangeLog b/ChangeLog index c4431322395..6a071444b2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,9 @@ QGIS Change Log ------------------------------------------------------------------------------ Version 0.6 'Simon' .... development version +2004-11-27 [larsl] 0.5.0devel30 +** Fixed feature addition in GPX layers, it now works again + 2004-11-22 [mcoletti] 0.5.0devel29 ** QgsProject properties now re-designed to be similar to QSettings diff --git a/configure.in b/configure.in index 32aa4717866..8b1be727b7b 100644 --- a/configure.in +++ b/configure.in @@ -26,7 +26,7 @@ dnl --------------------------------------------------------------------------- MAJOR_VERSION=0 MINOR_VERSION=5 MICRO_VERSION=0 -EXTRA_VERSION=29 +EXTRA_VERSION=30 if test $EXTRA_VERSION -eq 0; then VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION} else diff --git a/providers/gpx/gpsdata.h b/providers/gpx/gpsdata.h index 1f53af9855f..287cc24d9dc 100644 --- a/providers/gpx/gpsdata.h +++ b/providers/gpx/gpsdata.h @@ -216,7 +216,7 @@ class GPSData { static void releaseData(const QString& filename); - /** operator<< is our friend. */ + /** operator<< is our friend. For debugging, not for file I/O. */ friend std::ostream& operator<<(std::ostream& os, const GPSData& d); protected: diff --git a/providers/gpx/qgsgpxprovider.cpp b/providers/gpx/qgsgpxprovider.cpp index e00636fe51e..2086d659eef 100644 --- a/providers/gpx/qgsgpxprovider.cpp +++ b/providers/gpx/qgsgpxprovider.cpp @@ -44,9 +44,9 @@ #endif -const char* QgsGPXProvider::attr[] = { "Name", "Elevation", "Symbol", "Number", - "Comment", "Description", "Source", - "URL", "URL name" }; +const char* QgsGPXProvider::attr[] = { "name", "elevation", "symbol", "number", + "comment", "description", "source", + "url", "url name" }; QgsGPXProvider::QgsGPXProvider(QString uri) : mDataSourceUri(uri), @@ -78,7 +78,7 @@ QgsGPXProvider::QgsGPXProvider(QString uri) : mDataSourceUri(uri), else if (mFeatureType == RouteType || mFeatureType == TrackType) { mGeomType = 2; for (int i = 0; i < 8; ++i) - mAllAttributes.push_back(7); + mAllAttributes.push_back(i); attributeFields.push_back(QgsField(attr[NumAttr], "text")); } attributeFields.push_back(QgsField(attr[CmtAttr], "text")); @@ -532,17 +532,173 @@ bool QgsGPXProvider::isValid(){ bool QgsGPXProvider::addFeatures(std::list flist) { + + // add all the features for (std::list::const_iterator iter = flist.begin(); iter != flist.end(); ++iter) { if (!addFeature(*iter)) return false; } + + // write back to file + QDomDocument qdd; + data->fillDom(qdd); + QFile file(mFileName); + if (!file.open(IO_WriteOnly)) + return false; + QTextStream ostr(&file); + ostr<getGeometry(); + int featureId; + bool success = false; + GPSObject* obj = NULL; + const std::vector& attrs(f->attributeMap()); + + // is it a waypoint? + if (mFeatureType == WaypointType && geo != NULL && geo[1] == 1) { + + // add geometry + Waypoint wpt; + std::memcpy(&wpt.lon, geo+5, sizeof(double)); + std::memcpy(&wpt.lat, geo+13, sizeof(double)); + + // add waypoint-specific attributes + for (int i = 0; i < attrs.size(); ++i) { + if (attrs[i].fieldName() == attr[EleAttr]) { + bool eleIsOK; + double ele = attrs[i].fieldValue().toDouble(&eleIsOK); + if (eleIsOK) + wpt.ele = ele; + } + else if (attrs[i].fieldName() == attr[SymAttr]) { + wpt.sym = attrs[i].fieldValue(); + } + } + + featureId = data->addWaypoint(wpt); + success = true; + obj = &(data->getWaypoint(featureId)); + } + + // is it a route? + if (mFeatureType == RouteType && geo != NULL && geo[1] == 2) { + + Route rte; + + // reset bounds + rte.xMin = std::numeric_limits::max(); + rte.xMax = -std::numeric_limits::max(); + rte.yMin = std::numeric_limits::max(); + rte.yMax = -std::numeric_limits::max(); + + // add geometry + int nPoints; + std::memcpy(&nPoints, geo + 5, 4); + for (int i = 0; i < nPoints; ++i) { + double lat, lon; + std::memcpy(&lon, geo + 9 + 16 * i, sizeof(double)); + std::memcpy(&lat, geo + 9 + 16 * i + 8, sizeof(double)); + Routepoint rtept; + rtept.lat = lat; + rtept.lon = lon; + rte.points.push_back(rtept); + rte.xMin = rte.xMin < lon ? rte.xMin : lon; + rte.xMax = rte.xMax > lon ? rte.xMax : lon; + rte.yMin = rte.yMin < lat ? rte.yMin : lat; + rte.yMax = rte.yMax > lat ? rte.yMax : lat; + } + + // add route-specific attributes + for (int i = 0; i < attrs.size(); ++i) { + if (attrs[i].fieldName() == attr[NumAttr]) { + bool numIsOK; + long num = attrs[i].fieldValue().toLong(&numIsOK); + if (numIsOK) + rte.number = num; + } + } + + featureId = data->addRoute(rte); + success = true; + obj = &(data->getRoute(featureId)); + } + + // is it a track? + if (mFeatureType == TrackType && geo != NULL && geo[1] == 2) { + + Track trk; + TrackSegment trkseg; + + // reset bounds + trk.xMin = std::numeric_limits::max(); + trk.xMax = -std::numeric_limits::max(); + trk.yMin = std::numeric_limits::max(); + trk.yMax = -std::numeric_limits::max(); + + // add geometry + int nPoints; + std::memcpy(&nPoints, geo + 5, 4); + for (int i = 0; i < nPoints; ++i) { + double lat, lon; + std::memcpy(&lon, geo + 9 + 16 * i, sizeof(double)); + std::memcpy(&lat, geo + 9 + 16 * i + 8, sizeof(double)); + Trackpoint trkpt; + trkpt.lat = lat; + trkpt.lon = lon; + trkseg.points.push_back(trkpt); + trk.xMin = trk.xMin < lon ? trk.xMin : lon; + trk.xMax = trk.xMax > lon ? trk.xMax : lon; + trk.yMin = trk.yMin < lat ? trk.yMin : lat; + trk.yMax = trk.yMax > lat ? trk.yMax : lat; + } + + // add track-specific attributes + for (int i = 0; i < attrs.size(); ++i) { + if (attrs[i].fieldName() == attr[NumAttr]) { + bool numIsOK; + long num = attrs[i].fieldValue().toLong(&numIsOK); + if (numIsOK) + trk.number = num; + } + } + + trk.segments.push_back(trkseg); + featureId = data->addTrack(trk); + success = true; + obj = &(data->getTrack(featureId)); + } + + + // add common attributes + if (obj) { + for (int i = 0; i < attrs.size(); ++i) { + if (attrs[i].fieldName() == attr[NameAttr]) { + obj->name = attrs[i].fieldValue(); + } + else if (attrs[i].fieldName() == attr[CmtAttr]) { + obj->cmt = attrs[i].fieldValue(); + } + else if (attrs[i].fieldName() == attr[DscAttr]) { + obj->desc = attrs[i].fieldValue(); + } + else if (attrs[i].fieldName() == attr[SrcAttr]) { + obj->src = attrs[i].fieldValue(); + } + else if (attrs[i].fieldName() == attr[URLAttr]) { + obj->url = attrs[i].fieldValue(); + } + else if (attrs[i].fieldName() == attr[URLNameAttr]) { + obj->urlname = attrs[i].fieldValue(); + } + } + } + + return success; } diff --git a/providers/gpx/qgsgpxprovider.h b/providers/gpx/qgsgpxprovider.h index 061de50d626..989c9566165 100644 --- a/providers/gpx/qgsgpxprovider.h +++ b/providers/gpx/qgsgpxprovider.h @@ -148,7 +148,7 @@ public: */ bool boundsCheck(double x, double y); - bool supportsFeatureAddition(){return false;} + bool supportsFeatureAddition(){return true;} private: