multires_image_plugin.cpp
Go to the documentation of this file.
1 // *****************************************************************************
2 //
3 // Copyright (c) 2014, Southwest Research Institute® (SwRI®)
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Southwest Research Institute® (SwRI®) nor the
14 // names of its contributors may be used to endorse or promote products
15 // derived from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 // *****************************************************************************
29 
31 
32 // C++ standard libraries
33 #include <cstdio>
34 
35 // QT libraries
36 #include <QFileDialog>
37 #include <QGLWidget>
38 #include <QPalette>
39 
40 // ROS libraries
41 #include <ros/ros.h>
42 #include <tf/transform_datatypes.h>
43 
44 // Declare plugin
47 
48 namespace mapviz_plugins
49 {
50  MultiresImagePlugin::MultiresImagePlugin() :
51  loaded_(false),
52  tile_set_(NULL),
53  tile_view_(NULL),
54  config_widget_(new QWidget()),
55  transformed_(false),
56  offset_x_(0.0),
57  offset_y_(0.0)
58  {
59  ui_.setupUi(config_widget_);
60 
61  QPalette p(config_widget_->palette());
62  p.setColor(QPalette::Background, Qt::white);
63  config_widget_->setPalette(p);
64 
65  QPalette p2(ui_.status->palette());
66  p2.setColor(QPalette::Text, Qt::red);
67  ui_.status->setPalette(p2);
68 
69  QObject::connect(ui_.browse, SIGNAL(clicked()), this, SLOT(SelectFile()));
70  QObject::connect(ui_.path, SIGNAL(editingFinished()), this, SLOT(AcceptConfiguration()));
71  QObject::connect(ui_.x_offset_spin_box, SIGNAL(valueChanged(double)), this, SLOT(SetXOffset(double)));
72  QObject::connect(ui_.y_offset_spin_box, SIGNAL(valueChanged(double)), this, SLOT(SetYOffset(double)));
73 
74  source_frame_ = "/";
75  }
76 
78  {
79  delete tile_view_;
80  delete tile_set_;
81  }
82 
83  void MultiresImagePlugin::PrintError(const std::string& message)
84  {
85  if (message == ui_.status->text().toStdString())
86  return;
87 
88  ROS_ERROR("Error: %s", message.c_str());
89  QPalette p(ui_.status->palette());
90  p.setColor(QPalette::Text, Qt::red);
91  ui_.status->setPalette(p);
92  ui_.status->setText(message.c_str());
93  }
94 
95  void MultiresImagePlugin::PrintInfo(const std::string& message)
96  {
97  if (message == ui_.status->text().toStdString())
98  return;
99 
100  ROS_INFO("%s", message.c_str());
101  QPalette p(ui_.status->palette());
102  p.setColor(QPalette::Text, Qt::green);
103  ui_.status->setPalette(p);
104  ui_.status->setText(message.c_str());
105  }
106 
107  void MultiresImagePlugin::PrintWarning(const std::string& message)
108  {
109  if (message == ui_.status->text().toStdString())
110  return;
111 
112  ROS_WARN("%s", message.c_str());
113  QPalette p(ui_.status->palette());
114  p.setColor(QPalette::Text, Qt::darkYellow);
115  ui_.status->setPalette(p);
116  ui_.status->setText(message.c_str());
117  }
118 
120  {
121  ROS_INFO("Accept multires image configuration.");
122  if (tile_set_ != NULL && tile_set_->GeoReference().GeoPath() == ui_.path->text().toStdString())
123  {
124  // Nothing to do.
125  }
126  else
127  {
128  loaded_ = false;
129  delete tile_set_;
130  delete tile_view_;
131  tile_set_ = new multires_image::TileSet(ui_.path->text().toStdString());
132 
133  if (tile_set_->Load())
134  {
135  loaded_ = true;
136 
138  if (source_frame_.empty() || source_frame_[0] != '/')
139  {
140  source_frame_ = std::string("/") + source_frame_;
141  }
142 
143  QPalette p(ui_.status->palette());
144  p.setColor(QPalette::Text, Qt::green);
145  ui_.status->setPalette(p);
146  ui_.status->setText("OK");
147 
148  initialized_ = true;
149 
151  tile_view_ = view;
152  }
153  else
154  {
155  PrintError("Failed to load image.");
156  delete tile_set_;
157  tile_set_ = 0;
158  tile_view_ = 0;
159  }
160  }
161  }
162 
164  {
165  QFileDialog dialog(config_widget_, "Select Multires Image");
166  dialog.setFileMode(QFileDialog::ExistingFile);
167  dialog.setNameFilter(tr("Geo Files (*.geo)"));
168 
169  dialog.exec();
170 
171  if (dialog.result() == QDialog::Accepted && dialog.selectedFiles().count() == 1)
172  {
173  ui_.path->setText(dialog.selectedFiles().first());
175  }
176  }
177 
178 
179  void MultiresImagePlugin::SetXOffset(double offset_x)
180  {
181  offset_x_ = offset_x;
182  }
183 
184  void MultiresImagePlugin::SetYOffset(double offset_y)
185  {
186  offset_y_ = offset_y;
187  }
188 
189  QWidget* MultiresImagePlugin::GetConfigWidget(QWidget* parent)
190  {
191  config_widget_->setParent(parent);
192 
193  return config_widget_;
194  }
195 
196  bool MultiresImagePlugin::Initialize(QGLWidget* canvas)
197  {
198  canvas_ = canvas;
199 
200  return true;
201  }
202 
203  void MultiresImagePlugin::GetCenterPoint(double x, double y)
204  {
205  tf::Point point(x, y, 0);
206  tf::Point center = inverse_transform_ * point;
207  center_x_ = center.getX();
208  center_y_ = center.getY();
209  }
210 
211  void MultiresImagePlugin::Draw(double x, double y, double scale)
212  {
213  if (transformed_ && tile_set_ != NULL && tile_view_ != NULL)
214  {
215  GetCenterPoint(x, y);
216  tile_view_->SetView(center_x_, center_y_, 1, scale);
217 
218  tile_view_->Draw();
219 
220  PrintInfo("OK");
221  }
222  }
223 
225  {
226  transformed_ = false;
227 
228  if (!loaded_)
229  return;
230 
232  {
233  PrintError("Failed transform from " + source_frame_ + " to " + target_frame_);
234  return;
235  }
236 
238  {
239  PrintError("Failed inverse transform from " + target_frame_ + " to " + source_frame_);
240  return;
241  }
242 
243  // Add in user-specified offset to map
248 
249  // Set relative positions of tile points based on tf transform
250  for (int i = 0; i < tile_set_->LayerCount(); i++)
251  {
253  for (int r = 0; r < layer->RowCount(); r++)
254  {
255  for (int c = 0; c < layer->ColumnCount(); c++)
256  {
257  multires_image::Tile* tile = layer->GetTile(c, r);
258 
259  tile->Transform(transform_, offset);
260  }
261  }
262  }
263 
264  transformed_ = true;
265  }
266 
267  boost::filesystem::path MultiresImagePlugin::MakePathRelative(boost::filesystem::path path, boost::filesystem::path base)
268  {
269  // Borrowed from: https://svn.boost.org/trac/boost/ticket/1976#comment:2
270  if (path.has_root_path())
271  {
272  if (path.root_path() != base.root_path())
273  {
274  return path;
275  }
276  else
277  {
278  return MakePathRelative(path.relative_path(), base.relative_path());
279  }
280  }
281  else
282  {
283  if (base.has_root_path())
284  {
285  ROS_WARN("Cannot uncomplete a path relative path from a rooted base.");
286  return path;
287  }
288  else
289  {
290  typedef boost::filesystem::path::const_iterator path_iterator;
291  path_iterator path_it = path.begin();
292  path_iterator base_it = base.begin();
293  while (path_it != path.end() && base_it != base.end())
294  {
295  if (*path_it != *base_it)
296  break;
297  ++path_it;
298  ++base_it;
299  }
300  boost::filesystem::path result;
301  for (; base_it != base.end(); ++base_it)
302  {
303  result /= "..";
304  }
305  for (; path_it != path.end(); ++path_it)
306  {
307  result /= *path_it;
308  }
309  return result;
310  }
311  }
312  }
313 
314  void MultiresImagePlugin::LoadConfig(const YAML::Node& node, const std::string& path)
315  {
316  if (node["path"])
317  {
318  std::string path_string;
319  node["path"] >> path_string;
320 
321  boost::filesystem::path image_path(path_string);
322  if (image_path.is_complete() == false)
323  {
324  boost::filesystem::path base_path(path);
325  path_string =
326  (path / image_path.relative_path()).normalize().string();
327  }
328 
329  ui_.path->setText(path_string.c_str());
330 
332  }
333 
334  if (node["offset_x"])
335  {
336  node["offset_x"] >> offset_x_;
337  ui_.x_offset_spin_box->setValue(offset_x_);
338  }
339  if (node["offset_y"])
340  {
341  node["offset_y"] >> offset_y_;
342  ui_.y_offset_spin_box->setValue(offset_y_);
343  }
344  }
345 
346  void MultiresImagePlugin::SaveConfig(YAML::Emitter& emitter, const std::string& path)
347  {
348  boost::filesystem::path abs_path(ui_.path->text().toStdString());
349  boost::filesystem::path base_path(path);
350  boost::filesystem::path rel_path = MakePathRelative(abs_path, base_path);
351 
352  emitter << YAML::Key << "path" << YAML::Value << rel_path.string();
353  emitter << YAML::Key << "offset_x" << YAML::Value << offset_x_;
354  emitter << YAML::Key << "offset_y" << YAML::Value << offset_y_;
355  }
356 }
357 
#define NULL
std::string Projection() const
swri_transform_util::TransformManager tf_manager_
void SaveConfig(YAML::Emitter &emitter, const std::string &path)
QWidget * GetConfigWidget(QWidget *parent)
std::string GeoPath() const
swri_transform_util::Transform inverse_transform_
swri_transform_util::GeoReference & GeoReference()
Definition: tile_set.h:59
void PrintError(const std::string &message)
TFSIMD_FORCE_INLINE const tfScalar & getY() const
result
std::string target_frame_
void SetYOffset(double latitude_offset)
#define ROS_WARN(...)
static tf::Quaternion createIdentityQuaternion()
void LoadConfig(const YAML::Node &node, const std::string &path)
std::string source_frame_
void PrintWarning(const std::string &message)
#define ROS_INFO(...)
swri_transform_util::Transform transform_
boost::filesystem::path MakePathRelative(boost::filesystem::path path, boost::filesystem::path base)
TFSIMD_FORCE_INLINE Vector3 & normalize()
void SetView(double x, double y, double radius, double scale)
bool GetTransform(const std::string &target_frame, const std::string &source_frame, const ros::Time &time, Transform &transform) const
TFSIMD_FORCE_INLINE const tfScalar & getX() const
void PrintInfo(const std::string &message)
TileSetLayer * GetLayer(int layer)
Definition: tile_set.h:61
Tile * GetTile(int column, int row)
void Draw(double x, double y, double scale)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
void Transform(const swri_transform_util::Transform &transform)
Definition: tile.cpp:211
#define ROS_ERROR(...)


multires_image
Author(s): Marc Alban
autogenerated on Thu Jun 6 2019 19:25:29