Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <multires_image/multires_image_plugin.h>
00031
00032
00033 #include <cstdio>
00034
00035
00036 #include <QFileDialog>
00037 #include <QGLWidget>
00038 #include <QPalette>
00039
00040
00041 #include <ros/ros.h>
00042 #include <tf/transform_datatypes.h>
00043
00044
00045 #include <pluginlib/class_list_macros.h>
00046 PLUGINLIB_DECLARE_CLASS(mapviz_plugins, multires_image, mapviz_plugins::MultiresImagePlugin, mapviz::MapvizPlugin)
00047
00048 namespace mapviz_plugins
00049 {
00050 MultiresImagePlugin::MultiresImagePlugin() :
00051 loaded_(false),
00052 tile_set_(NULL),
00053 tile_view_(NULL),
00054 config_widget_(new QWidget()),
00055 transformed_(false)
00056 {
00057 ui_.setupUi(config_widget_);
00058
00059 QPalette p(config_widget_->palette());
00060 p.setColor(QPalette::Background, Qt::white);
00061 config_widget_->setPalette(p);
00062
00063 QPalette p2(ui_.status->palette());
00064 p2.setColor(QPalette::Text, Qt::red);
00065 ui_.status->setPalette(p2);
00066
00067 QObject::connect(ui_.browse, SIGNAL(clicked()), this, SLOT(SelectFile()));
00068 QObject::connect(ui_.path, SIGNAL(editingFinished()), this, SLOT(AcceptConfiguration()));
00069
00070 source_frame_ = "/";
00071 }
00072
00073 MultiresImagePlugin::~MultiresImagePlugin()
00074 {
00075 delete tile_view_;
00076 delete tile_set_;
00077 }
00078
00079 void MultiresImagePlugin::PrintError(const std::string& message)
00080 {
00081 if (message == ui_.status->text().toStdString())
00082 return;
00083
00084 ROS_ERROR("Error: %s", message.c_str());
00085 QPalette p(ui_.status->palette());
00086 p.setColor(QPalette::Text, Qt::red);
00087 ui_.status->setPalette(p);
00088 ui_.status->setText(message.c_str());
00089 }
00090
00091 void MultiresImagePlugin::PrintInfo(const std::string& message)
00092 {
00093 if (message == ui_.status->text().toStdString())
00094 return;
00095
00096 ROS_INFO("%s", message.c_str());
00097 QPalette p(ui_.status->palette());
00098 p.setColor(QPalette::Text, Qt::green);
00099 ui_.status->setPalette(p);
00100 ui_.status->setText(message.c_str());
00101 }
00102
00103 void MultiresImagePlugin::PrintWarning(const std::string& message)
00104 {
00105 if (message == ui_.status->text().toStdString())
00106 return;
00107
00108 ROS_WARN("%s", message.c_str());
00109 QPalette p(ui_.status->palette());
00110 p.setColor(QPalette::Text, Qt::darkYellow);
00111 ui_.status->setPalette(p);
00112 ui_.status->setText(message.c_str());
00113 }
00114
00115 void MultiresImagePlugin::AcceptConfiguration()
00116 {
00117 ROS_INFO("Accept multires image configuration.");
00118 if (tile_set_ != NULL && tile_set_->GeoReference().GeoPath() == ui_.path->text().toStdString())
00119 {
00120
00121 }
00122 else
00123 {
00124 loaded_ = false;
00125 delete tile_set_;
00126 delete tile_view_;
00127 tile_set_ = new multires_image::TileSet(ui_.path->text().toStdString());
00128
00129 if (tile_set_->Load())
00130 {
00131 loaded_ = true;
00132
00133 source_frame_ = tile_set_->GeoReference().Projection();
00134 if (source_frame_.empty() || source_frame_[0] != '/')
00135 {
00136 source_frame_ = std::string("/") + source_frame_;
00137 }
00138
00139 QPalette p(ui_.status->palette());
00140 p.setColor(QPalette::Text, Qt::green);
00141 ui_.status->setPalette(p);
00142 ui_.status->setText("OK");
00143
00144 initialized_ = true;
00145
00146 MultiresView* view = new MultiresView(tile_set_, canvas_);
00147 tile_view_ = view;
00148 }
00149 else
00150 {
00151 PrintError("Failed to load image.");
00152 delete tile_set_;
00153 tile_set_ = 0;
00154 tile_view_ = 0;
00155 }
00156 }
00157 }
00158
00159 void MultiresImagePlugin::SelectFile()
00160 {
00161 QFileDialog dialog(config_widget_, "Select Multires Image");
00162 dialog.setFileMode(QFileDialog::ExistingFile);
00163 dialog.setNameFilter(tr("Geo Files (*.geo)"));
00164
00165 dialog.exec();
00166
00167 if (dialog.result() == QDialog::Accepted && dialog.selectedFiles().count() == 1)
00168 {
00169 ui_.path->setText(dialog.selectedFiles().first());
00170 AcceptConfiguration();
00171 }
00172 }
00173
00174 QWidget* MultiresImagePlugin::GetConfigWidget(QWidget* parent)
00175 {
00176 config_widget_->setParent(parent);
00177
00178 return config_widget_;
00179 }
00180
00181 bool MultiresImagePlugin::Initialize(QGLWidget* canvas)
00182 {
00183 canvas_ = canvas;
00184
00185 return true;
00186 }
00187
00188 void MultiresImagePlugin::GetCenterPoint(double x, double y)
00189 {
00190 tf::Point point(x, y, 0);
00191 tf::Point center = inverse_transform_ * point;
00192 center_x_ = center.getX();
00193 center_y_ = center.getY();
00194 }
00195
00196 void MultiresImagePlugin::Draw(double x, double y, double scale)
00197 {
00198 if (transformed_ && tile_set_ != NULL && tile_view_ != NULL)
00199 {
00200 GetCenterPoint(x, y);
00201 tile_view_->SetView(center_x_, center_y_, 1, scale);
00202
00203 tile_view_->Draw();
00204
00205 PrintInfo("OK");
00206 }
00207 }
00208
00209 void MultiresImagePlugin::Transform()
00210 {
00211 transformed_ = false;
00212
00213 if (!loaded_)
00214 return;
00215
00216 if (!tf_manager_.GetTransform(target_frame_, source_frame_, transform_))
00217 {
00218 PrintError("Failed transform from " + source_frame_ + " to " + target_frame_);
00219 return;
00220 }
00221
00222 if (!tf_manager_.GetTransform(source_frame_, target_frame_, inverse_transform_))
00223 {
00224 PrintError("Failed inverse transform from " + target_frame_ + " to " + source_frame_);
00225 return;
00226 }
00227
00228
00229 for (int i = 0; i < tile_set_->LayerCount(); i++)
00230 {
00231 multires_image::TileSetLayer* layer = tile_set_->GetLayer(i);
00232 for (int r = 0; r < layer->RowCount(); r++)
00233 {
00234 for (int c = 0; c < layer->ColumnCount(); c++)
00235 {
00236 multires_image::Tile* tile = layer->GetTile(c, r);
00237
00238 tile->Transform(transform_);
00239 }
00240 }
00241 }
00242
00243 transformed_ = true;
00244 }
00245
00246 boost::filesystem::path MultiresImagePlugin::MakePathRelative(boost::filesystem::path path, boost::filesystem::path base)
00247 {
00248
00249 if (path.has_root_path())
00250 {
00251 if (path.root_path() != base.root_path())
00252 {
00253 return path;
00254 }
00255 else
00256 {
00257 return MakePathRelative(path.relative_path(), base.relative_path());
00258 }
00259 }
00260 else
00261 {
00262 if (base.has_root_path())
00263 {
00264 ROS_WARN("Cannot uncomplete a path relative path from a rooted base.");
00265 return path;
00266 }
00267 else
00268 {
00269 typedef boost::filesystem::path::const_iterator path_iterator;
00270 path_iterator path_it = path.begin();
00271 path_iterator base_it = base.begin();
00272 while (path_it != path.end() && base_it != base.end())
00273 {
00274 if (*path_it != *base_it)
00275 break;
00276 ++path_it;
00277 ++base_it;
00278 }
00279 boost::filesystem::path result;
00280 for (; base_it != base.end(); ++base_it)
00281 {
00282 result /= "..";
00283 }
00284 for (; path_it != path.end(); ++path_it)
00285 {
00286 result /= *path_it;
00287 }
00288 return result;
00289 }
00290 }
00291 }
00292
00293 void MultiresImagePlugin::LoadConfig(const YAML::Node& node, const std::string& path)
00294 {
00295 if (node["path"])
00296 {
00297 std::string path_string;
00298 node["path"] >> path_string;
00299
00300 boost::filesystem::path image_path(path_string);
00301 if (image_path.is_complete() == false)
00302 {
00303 boost::filesystem::path base_path(path);
00304 path_string =
00305 (path / image_path.relative_path()).normalize().string();
00306 }
00307
00308 ui_.path->setText(path_string.c_str());
00309
00310 AcceptConfiguration();
00311 }
00312 }
00313
00314 void MultiresImagePlugin::SaveConfig(YAML::Emitter& emitter, const std::string& path)
00315 {
00316 boost::filesystem::path abs_path(ui_.path->text().toStdString());
00317 boost::filesystem::path base_path(path);
00318 boost::filesystem::path rel_path = MakePathRelative(abs_path, base_path);
00319
00320 emitter << YAML::Key << "path" << YAML::Value << rel_path.string();
00321 }
00322 }
00323