@@ -30,9 +30,12 @@ TESSERACT_COMMON_IGNORE_WARNINGS_PUSH
3030#include < console_bridge/console.h>
3131#include < cassert>
3232#include < iostream>
33+ #include < mutex>
3334#include < boost/serialization/nvp.hpp>
3435#include < boost/serialization/shared_ptr.hpp>
3536#include < boost/serialization/vector.hpp>
37+ #include < boost/algorithm/string/classification.hpp>
38+ #include < boost/algorithm/string/split.hpp>
3639TESSERACT_COMMON_IGNORE_WARNINGS_POP
3740
3841#include < tesseract_common/resource_locator.h>
@@ -49,6 +52,111 @@ void ResourceLocator::serialize(Archive& /*ar*/, const unsigned int /*version*/)
4952{
5053}
5154
55+ GeneralResourceLocator::GeneralResourceLocator ()
56+ {
57+ // This was added to allow user defined resource path
58+ // When using this within a snap you can map host ros package paths to this environment variable
59+ char * tesseract_resource_paths = std::getenv (" TESSERACT_RESOURCE_PATH" );
60+ if (tesseract_resource_paths != nullptr )
61+ {
62+ std::vector<std::string> tokens;
63+ #ifndef _WIN32
64+ boost::split (tokens, tesseract_resource_paths, boost::is_any_of (" :" ), boost::token_compress_on);
65+ #else
66+ boost::split (tokens, tesseract_resource_paths, boost::is_any_of (" ;" ), boost::token_compress_on);
67+ #endif
68+ for (const auto & token : tokens)
69+ {
70+ tesseract_common::fs::path d (token);
71+ if (tesseract_common::fs::is_directory (d) && tesseract_common::fs::exists (d))
72+ {
73+ std::string dir_name = d.filename ().string ();
74+ if (package_paths_.find (dir_name) == package_paths_.end ())
75+ package_paths_[dir_name] = token;
76+ }
77+ else
78+ {
79+ CONSOLE_BRIDGE_logWarn (" Package Path does not exist: %s" , token.c_str ());
80+ }
81+ }
82+ }
83+
84+ char * ros_package_paths = std::getenv (" ROS_PACKAGE_PATH" );
85+ if (ros_package_paths != nullptr )
86+ {
87+ std::vector<std::string> tokens;
88+ #ifndef _WIN32
89+ boost::split (tokens, ros_package_paths, boost::is_any_of (" :" ), boost::token_compress_on);
90+ #else
91+ boost::split (tokens, ros_package_paths, boost::is_any_of (" ;" ), boost::token_compress_on);
92+ #endif
93+ for (const auto & token : tokens)
94+ {
95+ tesseract_common::fs::path d (token);
96+ if (tesseract_common::fs::is_directory (d) && tesseract_common::fs::exists (d))
97+ {
98+ std::string dir_name = d.filename ().string ();
99+ if (package_paths_.find (dir_name) == package_paths_.end ())
100+ package_paths_[dir_name] = token;
101+ }
102+ else
103+ {
104+ CONSOLE_BRIDGE_logError (" Package Path does not exist: &s" , token.c_str ());
105+ }
106+ }
107+ }
108+ }
109+
110+ std::shared_ptr<Resource> GeneralResourceLocator::locateResource (const std::string& url) const
111+ {
112+ std::string mod_url = url;
113+ if (url.find (" file:///" ) == 0 )
114+ {
115+ mod_url.erase (0 , strlen (" file://" ));
116+ size_t pos = mod_url.find (' /' );
117+ if (pos == std::string::npos)
118+ return nullptr ;
119+ }
120+ else if (url.find (" package://" ) == 0 )
121+ {
122+ mod_url.erase (0 , strlen (" package://" ));
123+ size_t pos = mod_url.find (' /' );
124+ if (pos == std::string::npos)
125+ return nullptr ;
126+
127+ std::string package = mod_url.substr (0 , pos);
128+ mod_url.erase (0 , pos);
129+
130+ auto find_package = package_paths_.find (package);
131+ if (find_package != package_paths_.end ())
132+ {
133+ mod_url = find_package->second + mod_url;
134+ }
135+ else
136+ {
137+ CONSOLE_BRIDGE_logError (" Failed to find package resource %s for %s" , package.c_str (), url.c_str ());
138+ return nullptr ;
139+ }
140+ }
141+
142+ if (!tesseract_common::fs::path (mod_url).is_complete ())
143+ {
144+ CONSOLE_BRIDGE_logWarn (" Resource not handled: %s" , mod_url.c_str ());
145+ return nullptr ;
146+ }
147+
148+ return std::make_shared<SimpleLocatedResource>(url, mod_url, std::make_shared<GeneralResourceLocator>(*this ));
149+ }
150+
151+ bool GeneralResourceLocator::operator ==(const GeneralResourceLocator& /* rhs*/ ) const { return true ; }
152+ bool GeneralResourceLocator::operator !=(const GeneralResourceLocator& /* rhs*/ ) const { return false ; }
153+
154+ template <class Archive >
155+ void GeneralResourceLocator::serialize (Archive& ar, const unsigned int /* version*/ )
156+ {
157+ ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP (ResourceLocator);
158+ }
159+
52160bool Resource::operator ==(const Resource& /* rhs*/ ) const { return true ; }
53161bool Resource::operator !=(const Resource& /* rhs*/ ) const { return false ; }
54162
@@ -213,8 +321,10 @@ void BytesResource::serialize(Archive& ar, const unsigned int /*version*/)
213321
214322#include < tesseract_common/serialization.h>
215323TESSERACT_SERIALIZE_ARCHIVES_INSTANTIATE (tesseract_common::ResourceLocator)
324+ TESSERACT_SERIALIZE_ARCHIVES_INSTANTIATE(tesseract_common::GeneralResourceLocator)
216325TESSERACT_SERIALIZE_ARCHIVES_INSTANTIATE(tesseract_common::Resource)
217326TESSERACT_SERIALIZE_ARCHIVES_INSTANTIATE(tesseract_common::SimpleLocatedResource)
218327TESSERACT_SERIALIZE_ARCHIVES_INSTANTIATE(tesseract_common::BytesResource)
328+ BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_common::GeneralResourceLocator)
219329BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_common::SimpleLocatedResource)
220330BOOST_CLASS_EXPORT_IMPLEMENT(tesseract_common::BytesResource)
0 commit comments