/* ---- This file is part of SECONDO. Copyright (C) 2004, University in Hagen, Department of Computer Science, Database Systems for New Applications. SECONDO 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. SECONDO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SECONDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---- //paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}] //[TOC] [\tableofcontents] //[_] [\_] [1] Implementation of the GPXFileReader January-April, 2012. Matthias Roth [TOC] 1 Overview This implementation file contains the implementation of the class ~GPXFileReader~. This class reads the data from a gpx-file. 2 Defines and includes */ #include "GPXFileReader.h" #include "../TemporalNet/TemporalNetAlgebra.h" #include #include #include #include #include #include "satof.h" namespace mapmatch { /* 3 class GPXFileReader Reads the data from a gpx-file 3.1 Constructor / Destructor */ // Constructor GPXFileReader::GPXFileReader() :m_pXMLDoc(NULL) { } // Destructor GPXFileReader::~GPXFileReader() { Free(); } void GPXFileReader::Free(void) { if (m_pXMLDoc != NULL) xmlFreeDoc(m_pXMLDoc); m_pXMLDoc = NULL; } void GPXFileReader::Init(void) { Free(); } /* 3.2 GPXFileReader::Open Opens the file and checks, if it is a valid GPX file */ bool GPXFileReader::Open(std::string strFileName) { Init(); assert(m_pXMLDoc == NULL); m_pXMLDoc = xmlParseFile(strFileName.c_str()); if (m_pXMLDoc == NULL) { cmsg.error() << "Failed to read " << strFileName << endl; cmsg.send(); return false; } xmlNodePtr pCurNode = xmlDocGetRootElement(m_pXMLDoc); if (pCurNode == NULL) { cmsg.error() << "Failed to read " << strFileName << endl; cmsg.send(); xmlFreeDoc(m_pXMLDoc); m_pXMLDoc = NULL; return false; } if (xmlStrcmp(pCurNode->name, (const xmlChar *) "gpx") != 0) { cmsg.error() << "Not a gpx document " << strFileName << endl; cmsg.send(); xmlFreeDoc(m_pXMLDoc); m_pXMLDoc = NULL; return false; } return true; } void GPXFileReader::ParseTrk(xmlNodePtr pNode) { if (pNode == NULL) return; xmlNodePtr pCurChild = GetFirstTrkSegNode(pNode); while (pCurChild != NULL) { ParseTrkSeg(pCurChild); pCurChild = GetNextTrkSegNode(pCurChild); } } void GPXFileReader::ParseTrkSeg(xmlNodePtr pNode) { if (pNode == NULL) return; xmlNodePtr pCurChild = GetFirstTrkPtNode(pNode); while (pCurChild != NULL) { SGPXTrkPointData Data; if (ParseTrkPt(pCurChild, Data)) NewData(Data); pCurChild = GetNextTrkPtNode(pCurChild); } } xmlNodePtr GPXFileReader::GetFirstTrkNode(void) { if (m_pXMLDoc == NULL) return NULL; xmlNodePtr pCurNode = xmlDocGetRootElement(m_pXMLDoc); if (pCurNode != NULL) { pCurNode = pCurNode->xmlChildrenNode; while (pCurNode != NULL) { if (xmlStrcmp(pCurNode->name, (const xmlChar *) "trk") == 0) { return pCurNode; } pCurNode = pCurNode->next; } } return NULL; } xmlNodePtr GPXFileReader::GetNextTrkNode(const xmlNodePtr pTrkNode) { xmlNodePtr pNext = NULL; if (pTrkNode != NULL) { pNext = pTrkNode->next; while (pNext != NULL) { if (xmlStrcmp(pNext->name, (const xmlChar *) "trk") == 0) return pNext; pNext = pNext->next; } } return pNext; } xmlNodePtr GPXFileReader::GetFirstTrkSegNode(const xmlNodePtr pTrkNode) { if (pTrkNode == NULL) return NULL; else { xmlNodePtr pCurChild = pTrkNode->xmlChildrenNode; while (pCurChild != NULL) { if (xmlStrcmp(pCurChild->name, (const xmlChar *) "trkseg") == 0) { return pCurChild; } pCurChild = pCurChild->next; } return NULL; } } xmlNodePtr GPXFileReader::GetNextTrkSegNode(const xmlNodePtr pTrkSegNode) { xmlNodePtr pNext = NULL; if (pTrkSegNode != NULL) { pNext = pTrkSegNode->next; while (pNext != NULL) { if (xmlStrcmp(pNext->name, (const xmlChar *) "trkseg") == 0) return pNext; pNext = pNext->next; } } return pNext; } xmlNodePtr GPXFileReader::GetFirstTrkPtNode(const xmlNodePtr pTrkSegNode) { if (pTrkSegNode == NULL) return NULL; else { xmlNodePtr pCurChild = pTrkSegNode->xmlChildrenNode; while (pCurChild != NULL) { if (xmlStrcmp(pCurChild->name, (const xmlChar *) "trkpt") == 0) { return pCurChild; } pCurChild = pCurChild->next; } return NULL; } } xmlNodePtr GPXFileReader::GetNextTrkPtNode(const xmlNodePtr pTrkPtNode) { xmlNodePtr pNext = NULL; if (pTrkPtNode != NULL) { pNext = pTrkPtNode->next; while(pNext != NULL) { if (xmlStrcmp(pNext->name, (const xmlChar *) "trkpt") == 0) return pNext; pNext = pNext->next; } } return pNext; } static int convStrToInt (const char* pszStr) { if (pszStr == NULL) return 0; return atoi(pszStr); } static double convStrToDouble (const char* pszStr) { if (pszStr == NULL) return 0.0; return satof(pszStr); } bool GPXFileReader::ParseTrkPt(xmlNodePtr pNode, SGPXTrkPointData& rTrkPointData) { if (pNode == NULL) return false; SGPXTrkPointData TrkPointData; double dLat = 0.0; double dLon = 0.0; xmlChar* pLat = xmlGetProp(pNode, (const xmlChar *) "lat"); if (pLat != NULL) { dLat = convStrToDouble((const char*)pLat); //dLat *= m_dScale; xmlFree(pLat); } else { return false; } xmlChar* pLon = xmlGetProp(pNode, (const xmlChar *) "lon"); if (pLon != NULL) { dLon = convStrToDouble((const char*)pLon); //dLon *= m_dScale; xmlFree(pLon); } else { return false; } TrkPointData.m_Point.Set(dLon, dLat); xmlNodePtr pCurChild = pNode->xmlChildrenNode; while (pCurChild != NULL) { if (xmlStrcmp(pCurChild->name, (const xmlChar *) "time" ) == 0) { xmlChar* pTime = xmlNodeGetContent(pCurChild); if (pTime != NULL) { // YEAR-MONTH-DAYTHOUR:MIN:SECZ // replace T by - // remove Z std::string strTime((const char*)pTime); std::string::size_type nPos = strTime.find('T'); if (nPos > 0) { strTime.replace(nPos, 1, "-"); } if (strTime.length() > 0 && strTime[strTime.length() - 1] == 'Z') { strTime.erase(strTime.length() - 1, 1); } TrkPointData.m_Time.ReadFrom(strTime.c_str()); xmlFree(pTime); } } else if (xmlStrcmp(pCurChild->name, (const xmlChar *) "fix") == 0) { xmlChar* pFix = xmlNodeGetContent(pCurChild); if (xmlStrcmp(pFix, (const xmlChar *) "none") == 0) { TrkPointData.m_nFix.Set(0); } else if (xmlStrcmp(pFix, (const xmlChar *) "2d") == 0) { TrkPointData.m_nFix.Set(2); } else if (xmlStrcmp(pFix, (const xmlChar *) "3d") == 0) { TrkPointData.m_nFix.Set(3); } else if (xmlStrcmp(pFix, (const xmlChar *) "dgps") == 0) { TrkPointData.m_nFix.Set(4); } else if (xmlStrcmp(pFix, (const xmlChar *) "pps") == 0) { // military signal TrkPointData.m_nFix.Set(5); } xmlFree(pFix); } else if (xmlStrcmp(pCurChild->name, (const xmlChar *) "sat") == 0) { xmlChar* pSat = xmlNodeGetContent(pCurChild); TrkPointData.m_nSat.Set(convStrToInt((const char*)pSat)); xmlFree(pSat); } else if (xmlStrcmp(pCurChild->name, (const xmlChar *) "hdop") == 0) { xmlChar* pHDOP = xmlNodeGetContent(pCurChild); TrkPointData.m_dHDOP.Set(convStrToDouble((const char*)pHDOP)); xmlFree(pHDOP); } else if (xmlStrcmp(pCurChild->name, (const xmlChar *) "vdop") == 0) { xmlChar* pVDOP = xmlNodeGetContent(pCurChild); TrkPointData.m_dVDOP.Set(convStrToDouble((const char*)pVDOP)); xmlFree(pVDOP); } else if (xmlStrcmp(pCurChild->name, (const xmlChar *) "pdop") == 0) { xmlChar* pPDOP = xmlNodeGetContent(pCurChild); TrkPointData.m_dPDOP.Set(convStrToDouble((const char*)pPDOP)); xmlFree(pPDOP); } else if (xmlStrcmp(pCurChild->name, (const xmlChar *) "course") == 0) { xmlChar* pCourse = xmlNodeGetContent(pCurChild); TrkPointData.m_dCourse.Set(convStrToDouble((const char*)pCourse)); xmlFree(pCourse); } else if (xmlStrcmp(pCurChild->name, (const xmlChar *) "speed") == 0) { xmlChar* pSpeed = xmlNodeGetContent(pCurChild); TrkPointData.m_dSpeed.Set(convStrToDouble((const char*)pSpeed)); xmlFree(pSpeed); } else if (xmlStrcmp(pCurChild->name, (const xmlChar *) "ele") == 0) { xmlChar* pElevation = xmlNodeGetContent(pCurChild); TrkPointData.m_dElevation.Set( convStrToDouble((const char*)pElevation)); xmlFree(pElevation); } pCurChild = pCurChild->next; } rTrkPointData = TrkPointData; return true; } void GPXFileReader::NewData(const SGPXTrkPointData& /*rData*/) { #if 0 if (m_pMPoint != NULL) { // Point UPoint ActUPoint(Interval(rData.m_Time, rData.m_Time, true, true), rData.m_Point, rData.m_Point); m_pMPoint->Add(ActUPoint); } if (m_pMFix != NULL) { // Fix UInt ActUFix(Interval(rData.m_Time, rData.m_Time, true, true), rData.m_nFix, rData.m_nFix); m_pMFix->Add(ActUFix); } if (m_pMSat != NULL) { // Sat UInt ActUSat(Interval(rData.m_Time, rData.m_Time, true, true), rData.m_nSat, rData.m_nSat); m_pMSat->Add(ActUSat); } if (m_pMHDOP != NULL) { // HDOP UReal ActUHDop(Interval(rData.m_Time, rData.m_Time, true, true), rData.m_dHDOP, rData.m_dHDOP); m_pMHDOP->Add(ActUHDop); } // VDOP if (m_pMVDOP != NULL) { UReal ActUVDop(Interval(rData.m_Time, rData.m_Time, true, true), rData.m_dVDOP, rData.m_dVDOP); m_pMVDOP->Add(ActUVDop); } // PDOP if (m_pMPDOP != NULL) { UReal ActUPDOP(Interval(rData.m_Time, rData.m_Time, true, true), rData.m_dPDOP, rData.m_dPDOP); m_pMPDOP->Add(ActUPDOP); } #endif } TrkPointIteratorPtr GPXFileReader::GetTrkPointIterator(void) { if (m_pXMLDoc == NULL) return TrkPointIteratorPtr(); return TrkPointIteratorPtr(new CTrkPointIterator(this)); } /* 3.4 struct GPXFileReader::SGPXTrkPointData */ GPXFileReader::SGPXTrkPointData::SGPXTrkPointData() :m_Time(0.0), m_Point(false), m_nFix(false), m_nSat(false), m_dHDOP(false), m_dVDOP(false), m_dPDOP(false), m_dCourse(false), m_dSpeed(false), m_dElevation(false) { m_Time.SetDefined(false); } GPXFileReader::SGPXTrkPointData::SGPXTrkPointData(const SGPXTrkPointData& rData) :m_Time(rData.m_Time), m_Point(rData.m_Point), m_nFix(rData.m_nFix), m_nSat(rData.m_nSat), m_dHDOP(rData.m_dHDOP), m_dVDOP(rData.m_dVDOP), m_dPDOP(rData.m_dPDOP), m_dCourse(rData.m_dCourse), m_dSpeed(rData.m_dSpeed), m_dElevation(rData.m_dElevation) { } GPXFileReader::SGPXTrkPointData& GPXFileReader::SGPXTrkPointData::operator=( const SGPXTrkPointData& rData) { if (&rData != this) { m_Time = rData.m_Time; m_Point = rData.m_Point; m_nFix = rData.m_nFix; m_nSat = rData.m_nSat; m_dHDOP = rData.m_dHDOP; m_dVDOP = rData.m_dVDOP; m_dPDOP = rData.m_dPDOP; m_dCourse = rData.m_dCourse; m_dSpeed = rData.m_dSpeed; m_dElevation = rData.m_dElevation; } return *this; } /* 4 class CTrkPointIterator Iterator for Trk-points */ CTrkPointIterator::CTrkPointIterator() :m_pReader(NULL), m_pCurrentTrk(NULL), m_pCurrentTrkSeg(NULL), m_pCurrentTrkPt(NULL) { } CTrkPointIterator::CTrkPointIterator(GPXFileReader* pReader) :m_pReader(pReader), m_pCurrentTrk(NULL), m_pCurrentTrkSeg(NULL), m_pCurrentTrkPt(NULL) { if (m_pReader != NULL) { m_pCurrentTrk = m_pReader->GetFirstTrkNode(); while (m_pCurrentTrk != NULL) { m_pCurrentTrkSeg = m_pReader->GetFirstTrkSegNode(m_pCurrentTrk); while (m_pCurrentTrkSeg != NULL) { m_pCurrentTrkPt = m_pReader->GetFirstTrkPtNode(m_pCurrentTrkSeg); if (m_pCurrentTrkPt != NULL) return; m_pCurrentTrkSeg = m_pReader->GetNextTrkSegNode(m_pCurrentTrkSeg); } m_pCurrentTrk = m_pReader->GetNextTrkNode(m_pCurrentTrk); } } } CTrkPointIterator::~CTrkPointIterator() { m_pReader = NULL; m_pCurrentTrk = NULL; m_pCurrentTrkSeg = NULL; m_pCurrentTrkPt = NULL; } bool CTrkPointIterator::GetCurrent(GPXFileReader::SGPXTrkPointData& rData) { if (m_pReader != NULL && m_pCurrentTrkPt != NULL) { return m_pReader->ParseTrkPt(m_pCurrentTrkPt, rData); } else { return false; } } void CTrkPointIterator::Next(void) { if (m_pReader != NULL) { m_pCurrentTrkPt = m_pReader->GetNextTrkPtNode(m_pCurrentTrkPt); while (m_pCurrentTrkPt == NULL && m_pCurrentTrk != NULL) { m_pCurrentTrkSeg = m_pReader->GetNextTrkSegNode(m_pCurrentTrkSeg); if (m_pCurrentTrkSeg != NULL) { m_pCurrentTrkPt = m_pReader->GetFirstTrkPtNode(m_pCurrentTrkSeg); } else { m_pCurrentTrk = m_pReader->GetNextTrkNode(m_pCurrentTrk); m_pCurrentTrkSeg = m_pReader->GetFirstTrkSegNode(m_pCurrentTrk); m_pCurrentTrkPt = m_pReader->GetFirstTrkPtNode(m_pCurrentTrkSeg); } } } } } // end of namespace mapmatch