From cd01d9ac5e8ae5297200514ff469c22e8d2da1e7 Mon Sep 17 00:00:00 2001 From: Varun Talwar Date: Thu, 23 Oct 2014 15:08:08 -0400 Subject: [PATCH] added networkdatasource abstraction to datasource and rearranged datasource/networkdatasource/mapzenvectortilejson functions based on the new networkdatasource abstraction --- core/dataSource/dataSource.cpp | 92 +++++++++++++++++--------------- core/dataSource/dataSource.h | 92 ++++++++++++++++++++------------ core/tileManager/tileManager.cpp | 4 +- 3 files changed, 108 insertions(+), 80 deletions(-) diff --git a/core/dataSource/dataSource.cpp b/core/dataSource/dataSource.cpp index 1a58c08c30..59748415d2 100644 --- a/core/dataSource/dataSource.cpp +++ b/core/dataSource/dataSource.cpp @@ -21,17 +21,6 @@ static const int MAX_FETCH_TRY = 3; */ static std::regex regObj; -void DataSource::ClearGeoRoots() { - for (auto& mapValue : m_JsonRoots) { - mapValue.second->clear(); - } - m_JsonRoots.clear(); -} - -size_t DataSource::JsonRootSize() { - return m_JsonRoots.size(); -} - //----Curl Helper Functions---- @@ -59,26 +48,46 @@ static void curlInit(CURLM *_curlMulti, std::string _url, std::stringstream *_ou } -//---- MapzenVectorTileJson Implementation---- +//---- DataSource Implementation---- -MapzenVectorTileJson::MapzenVectorTileJson() { - m_urlTemplate = "http://vector.mapzen.com/osm/all/[z]/[x]/[y].json"; - - // check if template is good - std::string regex_str = "([a-z\\./:0-9]+)/(\\[z\\])/(\\[x\\])/(\\[y\\])([a-z\\.]+)"; - regObj.assign(regex_str, std::regex_constants::icase); - std::sregex_iterator it(m_urlTemplate.begin(), m_urlTemplate.end(), regObj); - if(m_urlTemplate.compare((*it).str()) == 0) { - logMsg("\n***urlTemplate for MapzenVectorTileJson datasource is good.\n"); +void DataSource::clearGeoRoots() { + for (auto& mapValue : m_JsonRoots) { + mapValue.second->clear(); } + m_JsonRoots.clear(); +} + +size_t DataSource::jsonRootSize() { + return m_JsonRoots.size(); } -std::unique_ptr MapzenVectorTileJson::constructURL(const TileID& _tileCoord) { +bool DataSource::checkDataExists(const TileID& _tileID) { + if(m_JsonRoots.find(_tileID) != m_JsonRoots.end()) { + return true; + } + else { + return false; + } +} + +std::shared_ptr DataSource::getData(const TileID& _tileID) { + if(checkDataExists(_tileID)) { + return m_JsonRoots[_tileID]; + } + else { + return nullptr; + } +} + + +//---- NetworkDataSource Implementation---- + +std::unique_ptr NetworkDataSource::constructURL(const TileID& _tileCoord) { std::unique_ptr pTileUrl(nullptr); std::string xVal(std::to_string(_tileCoord.x)); std::string yVal(std::to_string(_tileCoord.y)); std::string zVal(std::to_string(_tileCoord.z)); - + std::string tileURL = m_urlTemplate; size_t pos = 0; if( (pos = tileURL.find("[x]", pos)) != std::string::npos) { @@ -106,6 +115,22 @@ std::unique_ptr MapzenVectorTileJson::constructURL(const TileID& _t return std::move(pTileUrl); } +//---- MapzenVectorTileJson Implementation---- + +MapzenVectorTileJson::MapzenVectorTileJson() { + + // Override NetworkDataSource::m_urlTemplate + m_urlTemplate = "http://vector.mapzen.com/osm/all/[z]/[x]/[y].json"; + + // check if template is good + std::string regex_str = "([a-z\\./:0-9]+)/(\\[z\\])/(\\[x\\])/(\\[y\\])([a-z\\.]+)"; + regObj.assign(regex_str, std::regex_constants::icase); + std::sregex_iterator it(m_urlTemplate.begin(), m_urlTemplate.end(), regObj); + if(m_urlTemplate.compare((*it).str()) == 0) { + logMsg("\n***urlTemplate for MapzenVectorTileJson datasource is good.\n"); + } +} + //TODO: Figure out a way to get tileIDs from curlEasy Handle!(Specifically if we are using curl multi handle). //Use of this helper method "might" be avoided if we go curleasy and c++11 async route. TileID MapzenVectorTileJson::extractIDFromUrl(const std::string& _url) { @@ -129,7 +154,7 @@ TileID MapzenVectorTileJson::extractIDFromUrl(const std::string& _url) { return TileID(xVal, yVal, zVal); } -bool MapzenVectorTileJson::LoadTile(const std::vector& _tileCoords) { +bool MapzenVectorTileJson::loadTile(const std::vector& _tileCoords) { std::vector> urls; if(_tileCoords.size() == 0) { @@ -314,22 +339,3 @@ bool MapzenVectorTileJson::LoadTile(const std::vector& _tileCoords) { urls.clear(); return true; } - -bool MapzenVectorTileJson::CheckDataExists(const TileID& _tileID) { - if(m_JsonRoots.find(_tileID) != m_JsonRoots.end()) { - return true; - } - else { - return false; - } -} - -std::shared_ptr MapzenVectorTileJson::GetData(const TileID& _tileID) { - if(CheckDataExists(_tileID)) { - return m_JsonRoots[_tileID]; - } - else { - return nullptr; - } -} - diff --git a/core/dataSource/dataSource.h b/core/dataSource/dataSource.h index 2577edb12f..a43a9a3a93 100644 --- a/core/dataSource/dataSource.h +++ b/core/dataSource/dataSource.h @@ -23,66 +23,88 @@ class TileData { }; -// TODO: divide DataSource into network and non-network dataSources. -// Same has been done on the webgl tangram. Follow the same pattern. class DataSource { protected: // map of tileIDs to json data for that tile std::map< TileID, std::shared_ptr > m_JsonRoots; - - /* m_urlTemplate needs to be defined for every network dataSource */ - std::string m_urlTemplate; - + public: + DataSource() {} + /* * Does all the curl network calls to load the tile data and fills the data associated with a tileID */ - virtual bool LoadTile(const std::vector& _tileCoords) = 0; - - /* Returns the data corresponding to a tileID */ - virtual std::shared_ptr GetData(const TileID& _tileID) = 0; - - /* Checks if data exists for a specific tileID */ - virtual bool CheckDataExists(const TileID& _tileID) = 0; - - /* - * constructs the URL for a tile based on tile coordinates/IDs. - * Used by LoadTile to construct URL + virtual bool loadTile(const std::vector& _tileCoords) = 0; + + /* + * Returns the data corresponding to a tileID */ - virtual std::unique_ptr constructURL(const TileID& _tileCoord) = 0; - - /* - * extracts tileIDs from a url - * Used by LoadTile to extract tileIDs from curl url. + virtual std::shared_ptr getData(const TileID& _tileID); + + /* + * Checks if data exists for a specific tileID */ - virtual TileID extractIDFromUrl(const std::string& _url) = 0; + virtual bool checkDataExists(const TileID& _tileID); /* * clears all data associated with this dataSource */ - void ClearGeoRoots(); - + void clearGeoRoots(); + /* * returns the number of tiles having data wrt this datasource */ - size_t JsonRootSize(); - - DataSource() {} + size_t jsonRootSize(); + virtual ~DataSource() { m_JsonRoots.clear(); } }; -//Extends DataSource class to read MapzenVectorTileJsons. -class MapzenVectorTileJson: public DataSource { +class NetworkDataSource : public DataSource { +protected: + /* + * m_urlTemplate needs to be defined for every network dataSource + */ + std::string m_urlTemplate; + + /* + * constructs the URL for a tile based on tile coordinates/IDs. + * Used by LoadTile to construct URL + */ + virtual std::unique_ptr constructURL(const TileID& _tileID); + + /* + * extracts tileIDs from a url + * Used by LoadTile to extract tileIDs from curl url. + * NOTE: every tile source will implement its own extractID as order of x,y and z can be different + * example: mapzen vector tile has z/x/y in its url + */ + virtual TileID extractIDFromUrl(const std::string& _url) = 0; public: - MapzenVectorTileJson(); - virtual std::unique_ptr constructURL(const TileID& _tileCoord) override; + NetworkDataSource() {}; + virtual ~NetworkDataSource() { + m_urlTemplate.clear(); + } +}; + +//Extends NetworkDataSource class to read MapzenVectorTileJsons. +class MapzenVectorTileJson : public NetworkDataSource { +private: virtual TileID extractIDFromUrl(const std::string& _url) override; - virtual bool LoadTile(const std::vector& _tileCoords) override; - virtual std::shared_ptr GetData(const TileID& _tileID) override; - virtual bool CheckDataExists(const TileID& _tileID) override; +public: + MapzenVectorTileJson(); + virtual bool loadTile(const std::vector& _tileCoords) override; virtual ~MapzenVectorTileJson() {} }; +class TopoJsonNetSrc : public NetworkDataSource { +}; + +class MapboxFormatNetSrc : public NetworkDataSource { +}; + +// --Support for tiled geoJson but no network (basically supports a geojson on the filesystem) +class GeoJsonFileSrc : public DataSource { +}; diff --git a/core/tileManager/tileManager.cpp b/core/tileManager/tileManager.cpp index 6da5f8bb69..e2b1ba9dd1 100644 --- a/core/tileManager/tileManager.cpp +++ b/core/tileManager/tileManager.cpp @@ -82,7 +82,7 @@ bool TileManager::updateTileSet() { for (const auto& source : m_dataSources) { logMsg("Loading tiles...\n"); - newTileLoadSuccess = source->LoadTile(m_tilesToAdd); + newTileLoadSuccess = source->loadTile(m_tilesToAdd); } if(!newTileLoadSuccess) { @@ -96,7 +96,7 @@ bool TileManager::updateTileSet() { std::unique_ptr tile(new MapTile(tileID, m_viewModule->getMapProjection())); for (const auto& source : m_dataSources) { // Get the previously fetched tile data - std::shared_ptr json = source->GetData(tileID); + std::shared_ptr json = source->getData(tileID); logMsg(" Retrieved JSON\n"); if(!json) { logMsg(" ***json root is null, tile was not read properly\n");