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  center_x_(0.0),
53  center_y_(0.0),
54  offset_x_(0.0),
55  offset_y_(0.0),
56  tile_set_(NULL),
57  tile_view_(NULL),
58  config_widget_(new QWidget()),
59  transformed_(false)
60  {
61  ui_.setupUi(config_widget_);
62 
63  QPalette p(config_widget_->palette());
64  p.setColor(QPalette::Background, Qt::white);
65  config_widget_->setPalette(p);
66 
67  QPalette p2(ui_.status->palette());
68  p2.setColor(QPalette::Text, Qt::red);
69  ui_.status->setPalette(p2);
70 
71  QObject::connect(ui_.browse, SIGNAL(clicked()), this, SLOT(SelectFile()));
72  QObject::connect(ui_.path, SIGNAL(editingFinished()), this, SLOT(AcceptConfiguration()));
73  QObject::connect(ui_.x_offset_spin_box, SIGNAL(valueChanged(double)), this, SLOT(SetXOffset(double)));
74  QObject::connect(ui_.y_offset_spin_box, SIGNAL(valueChanged(double)), this, SLOT(SetYOffset(double)));
75 
76  source_frame_ = "/";
77  }
78 
80  {
81  delete tile_view_;
82  delete tile_set_;
83  }
84 
85  void MultiresImagePlugin::PrintError(const std::string& message)
86  {
87  if (message == ui_.status->text().toStdString())
88  return;
89 
90  ROS_ERROR("Error: %s", message.c_str());
91  QPalette p(ui_.status->palette());
92  p.setColor(QPalette::Text, Qt::red);
93  ui_.status->setPalette(p);
94  ui_.status->setText(message.c_str());
95  }
96 
97  void MultiresImagePlugin::PrintInfo(const std::string& message)
98  {
99  if (message == ui_.status->text().toStdString())
100  return;
101 
102  ROS_INFO("%s", message.c_str());
103  QPalette p(ui_.status->palette());
104  p.setColor(QPalette::Text, Qt::green);
105  ui_.status->setPalette(p);
106  ui_.status->setText(message.c_str());
107  }
108 
109  void MultiresImagePlugin::PrintWarning(const std::string& message)
110  {
111  if (message == ui_.status->text().toStdString())
112  return;
113 
114  ROS_WARN("%s", message.c_str());
115  QPalette p(ui_.status->palette());
116  p.setColor(QPalette::Text, Qt::darkYellow);
117  ui_.status->setPalette(p);
118  ui_.status->setText(message.c_str());
119  }
120 
122  {
123  ROS_INFO("Accept multires image configuration.");
124  if (tile_set_ != NULL && tile_set_->GeoReference().GeoPath() == ui_.path->text().toStdString())
125  {
126  // Nothing to do.
127  }
128  else
129  {
130  loaded_ = false;
131  delete tile_set_;
132  delete tile_view_;
133  tile_set_ = new multires_image::TileSet(ui_.path->text().toStdString());
134 
135  if (tile_set_->Load())
136  {
137  loaded_ = true;
138 
140  if (source_frame_.empty() || source_frame_[0] != '/')
141  {
142  source_frame_ = std::string("/") + source_frame_;
143  }
144 
145  QPalette p(ui_.status->palette());
146  p.setColor(QPalette::Text, Qt::green);
147  ui_.status->setPalette(p);
148  ui_.status->setText("OK");
149 
150  initialized_ = true;
151 
153  tile_view_ = view;
154  }
155  else
156  {
157  PrintError("Failed to load image.");
158  delete tile_set_;
159  tile_set_ = 0;
160  tile_view_ = 0;
161  }
162  }
163  }
164 
166  {
167  QFileDialog dialog(config_widget_, "Select Multires Image");
168  dialog.setFileMode(QFileDialog::ExistingFile);
169  dialog.setNameFilter(tr("Geo Files (*.geo)"));
170 
171  dialog.exec();
172 
173  if (dialog.result() == QDialog::Accepted && dialog.selectedFiles().count() == 1)
174  {
175  ui_.path->setText(dialog.selectedFiles().first());
177  }
178  }
179 
180 
181  void MultiresImagePlugin::SetXOffset(double offset_x)
182  {
183  offset_x_ = offset_x;
184  }
185 
186  void MultiresImagePlugin::SetYOffset(double offset_y)
187  {
188  offset_y_ = offset_y;
189  }
190 
191  QWidget* MultiresImagePlugin::GetConfigWidget(QWidget* parent)
192  {
193  config_widget_->setParent(parent);
194 
195  return config_widget_;
196  }
197 
198  bool MultiresImagePlugin::Initialize(QGLWidget* canvas)
199  {
200  canvas_ = canvas;
201 
202  return true;
203  }
204 
205  void MultiresImagePlugin::GetCenterPoint(double x, double y)
206  {
207  tf::Point point(x, y, 0);
208  tf::Point center = inverse_transform_ * point;
209  center_x_ = center.getX();
210  center_y_ = center.getY();
211  }
212 
213  void MultiresImagePlugin::Draw(double x, double y, double scale)
214  {
215  if (transformed_ && tile_set_ != NULL && tile_view_ != NULL)
216  {
217  GetCenterPoint(x, y);
218  tile_view_->SetView(center_x_, center_y_, 1, scale);
219 
220  tile_view_->Draw();
221 
222  PrintInfo("OK");
223  }
224  }
225 
227  {
228  transformed_ = false;
229 
230  if (!loaded_)
231  return;
232 
233  if (!tf_manager_->GetTransform(target_frame_, source_frame_, transform_))
234  {
235  PrintError("Failed transform from " + source_frame_ + " to " + target_frame_);
236  return;
237  }
238 
240  {
241  PrintError("Failed inverse transform from " + target_frame_ + " to " + source_frame_);
242  return;
243  }
244 
245  // Add in user-specified offset to map
250 
251  // Set relative positions of tile points based on tf transform
252  for (int i = 0; i < tile_set_->LayerCount(); i++)
253  {
255  for (int r = 0; r < layer->RowCount(); r++)
256  {
257  for (int c = 0; c < layer->ColumnCount(); c++)
258  {
259  multires_image::Tile* tile = layer->GetTile(c, r);
260 
261  tile->Transform(transform_, offset);
262  }
263  }
264  }
265 
266  transformed_ = true;
267  }
268 
269  boost::filesystem::path MultiresImagePlugin::MakePathRelative(boost::filesystem::path path, boost::filesystem::path base)
270  {
271  // Borrowed from: https://svn.boost.org/trac/boost/ticket/1976#comment:2
272  if (path.has_root_path())
273  {
274  if (path.root_path() != base.root_path())
275  {
276  return path;
277  }
278  else
279  {
280  return MakePathRelative(path.relative_path(), base.relative_path());
281  }
282  }
283  else
284  {
285  if (base.has_root_path())
286  {
287  ROS_WARN("Cannot uncomplete a path relative path from a rooted base.");
288  return path;
289  }
290  else
291  {
292  typedef boost::filesystem::path::const_iterator path_iterator;
293  path_iterator path_it = path.begin();
294  path_iterator base_it = base.begin();
295  while (path_it != path.end() && base_it != base.end())
296  {
297  if (*path_it != *base_it)
298  break;
299  ++path_it;
300  ++base_it;
301  }
302  boost::filesystem::path result;
303  for (; base_it != base.end(); ++base_it)
304  {
305  result /= "..";
306  }
307  for (; path_it != path.end(); ++path_it)
308  {
309  result /= *path_it;
310  }
311  return result;
312  }
313  }
314  }
315 
316  void MultiresImagePlugin::LoadConfig(const YAML::Node& node, const std::string& path)
317  {
318  if (node["path"])
319  {
320  std::string path_string;
321  node["path"] >> path_string;
322 
323  boost::filesystem::path image_path(path_string);
324  if (image_path.is_complete() == false)
325  {
326  boost::filesystem::path base_path(path);
327  path_string =
328  (path / image_path.relative_path()).normalize().string();
329  }
330 
331  ui_.path->setText(path_string.c_str());
332 
334  }
335 
336  if (node["offset_x"])
337  {
338  node["offset_x"] >> offset_x_;
339  ui_.x_offset_spin_box->setValue(offset_x_);
340  }
341  if (node["offset_y"])
342  {
343  node["offset_y"] >> offset_y_;
344  ui_.y_offset_spin_box->setValue(offset_y_);
345  }
346  }
347 
348  void MultiresImagePlugin::SaveConfig(YAML::Emitter& emitter, const std::string& path)
349  {
350  boost::filesystem::path abs_path(ui_.path->text().toStdString());
351  boost::filesystem::path base_path(path);
352  boost::filesystem::path rel_path = MakePathRelative(abs_path, base_path);
353 
354  emitter << YAML::Key << "path" << YAML::Value << rel_path.string();
355  emitter << YAML::Key << "offset_x" << YAML::Value << offset_x_;
356  emitter << YAML::Key << "offset_y" << YAML::Value << offset_y_;
357  }
358 }
359 
#define NULL
std::string Projection() const
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)
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)
swri_transform_util::TransformManagerPtr tf_manager_
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 Fri Mar 19 2021 02:44:42