00001
00002
00003
00004
00005
00006
00007 #include <labust/gearth/CaddyKML.hpp>
00008 #include <kml/dom.h>
00009 #include <iostream>
00010 #include <math.h>
00011 #include <labust/tools/GeoUtilities.hpp>
00012 #include <kml/engine/feature_visitor.h>
00013 #include <sstream>
00014 #include <string>
00015 #include <iostream>
00016
00017 #include <ros/ros.h>
00018
00019 using namespace labust::gearth;
00020
00021 CaddyKML::CaddyKML():
00022 factory(kmldom::KmlFactory::GetFactory()),
00023 filename("caddy_rt.kml"),
00024 kmlFile(filename.c_str(),std::fstream::out),
00025 runFlag(true)
00026 {
00027 ros::NodeHandle ph("~");
00028 std::string name("RefreshLink.kml");
00029 ph.param("KMLFileName",filename,filename);
00030 ph.param("RefreshLinkName",name,name);
00031 double refreshInterval(1);
00032 ph.param("RefreshInterval",refreshInterval,refreshInterval);
00033
00034 labust::gearth::writeLinkKML(name, filename,refreshInterval);
00035 ROS_INFO("Create the Google Network File.");
00036
00037 kmlFile.open(filename.c_str(),std::fstream::out);
00038 kmlFile.close();
00039 ROS_INFO("Create the KML file.");
00040
00041 std::string vcolor("0xFF0000FF");
00042 ph.param("diver_path_color",vcolor,vcolor);
00043
00044 vcolor.erase(0,2);
00045 vehicle.setColor(vcolor);
00046 path.setColor(vcolor);
00047
00048 int max_elements(200);
00049 ph.param("diver_path_length",max_elements,max_elements);
00050 path.setMaxElements(max_elements);
00051 platformPath.setMaxElements(max_elements);
00052
00053 int segments(20);
00054 ph.param("path_segment_length",segments,segments);
00055 path.setSegmentSize(segments);
00056 platformPath.setSegmentSize(segments);
00057 path.setTransparencyDecrement(uint8_t(256/(max_elements/segments)));
00058 platformPath.setTransparencyDecrement(uint8_t(256/(max_elements/segments)));
00059
00060
00061 std::string scolor("0xFF00FFFF");
00062 ph.param("platform_color",scolor,scolor);
00063
00064 scolor.erase(0,2);
00065 ship.setColor(scolor);
00066 platformPath.setColor(scolor);
00067
00068 double len(10);
00069 ph.param("diver_length",len,len);
00070 vehicle.setId("Diver");
00071 path.setId("DiverPath");
00072 vehicle.setLength(len);
00073 ph.param("platform_length",len,10.0);
00074 ship.setId("Platform");
00075 platformPath.setId("PlatformPath");
00076 ship.setLength(len);
00077
00078 worker = boost::thread(boost::bind(&CaddyKML::run,this));
00079 }
00080
00081 CaddyKML::~CaddyKML()
00082 {
00083 runFlag = false;
00084 worker.join();
00085 };
00086
00087 void CaddyKML::write()
00088 {
00089 using namespace kmldom;
00090
00091 folder = factory->CreateDocument();
00092 vehicle.addToDocument(folder);
00093 ship.addToDocument(folder);
00094 path.addToDocument(folder);
00095 platformPath.addToDocument(folder);
00096 if (opRegion) addOpRegionToDocument(folder);
00097 addVarianceRegion(diver,folder);
00098 addVarianceRegion(platform,folder);
00099
00100 folder->set_name("Real-Time tracking");
00101 KmlPtr kml(factory->CreateKml());
00102 kml->set_feature(folder);
00103
00104 kmlFile.open(filename.c_str(),std::fstream::out);
00105 if (kmlFile.is_open())
00106 {
00107 kmlFile<<kmldom::SerializePretty(kml);
00108 kmlFile.close();
00109 }
00110 else
00111 {
00112 std::cerr<<"Cannot open kmlfile."<<std::endl;
00113 }
00114 }
00115
00116 void CaddyKML::addVarianceRegion(const auv_msgs::NavSts& nav, kmldom::DocumentPtr document)
00117 {
00118
00119
00120 if ((sqrt(nav.position_variance.north) > 1000) || (sqrt(nav.position_variance.east) > 1000)) return;
00121
00122 kmldom::CoordinatesPtr coords(factory->CreateCoordinates());
00123
00124 std::pair<double, double > latlon= labust::tools::meter2deg(
00125 sqrt(nav.position_variance.north),
00126 sqrt(nav.position_variance.east),
00127 nav.global_position.latitude);
00128
00129 std::pair<double, double > refs= labust::tools::meter2deg(
00130 0.25,
00131 0.25,
00132 nav.global_position.latitude);
00133
00134 std::vector <std::pair<double, double> > negatives;
00135 for(double x=-latlon.first; x<=latlon.first; x+=refs.first)
00136 {
00137 double y1 = (x/latlon.first);
00138 y1 = latlon.second*latlon.second*(1- y1*y1);
00139 if (y1 < 0) continue;
00140 double y2 = -sqrt(y1);
00141 y1 = sqrt(y1);
00142 coords->add_latlng(nav.global_position.latitude + x,
00143 nav.global_position.longitude + y1);
00144 negatives.push_back(std::make_pair(nav.global_position.latitude + x,
00145 nav.global_position.longitude + y2));
00146 }
00147
00148 for (auto it=negatives.rbegin(); it!=negatives.rend(); ++it)
00149 {
00150 coords->add_latlng(it->first,it->second);
00151 }
00152
00153
00154 kmldom::LinearRingPtr ring(factory->CreateLinearRing());
00155
00156 ring->set_coordinates(coords);
00157 ring->set_tessellate(false);
00158 kmldom::OuterBoundaryIsPtr boundary(factory->CreateOuterBoundaryIs());
00159 boundary->set_linearring(ring);
00160 kmldom::PolygonPtr poly(factory->CreatePolygon());
00161 poly->set_outerboundaryis(boundary);
00162 poly->set_tessellate(false);
00163
00164
00165 kmldom::PolyStylePtr poly_style(factory->CreatePolyStyle());
00166 poly_style->set_fill(false);
00167
00168
00169 kmldom::StylePtr style(factory->CreateStyle());
00170 style->set_polystyle(poly_style);
00171
00172 style->set_id("RegionPolygonStyle");
00173
00174 kmldom::PlacemarkPtr region(factory->CreatePlacemark());
00175 region->set_name("PositionVariance");
00176 region->set_geometry(poly);
00177 region->set_styleurl("#RegionPolygonStyle");
00178 document->add_feature(region);
00179 document->add_styleselector(style);
00180 }
00181
00182 void CaddyKML::addOpRegionToDocument(kmldom::DocumentPtr document)
00183 {
00184
00185 kmldom::LinearRingPtr ring(factory->CreateLinearRing());
00186 kmldom::CoordinatesPtr coords(factory->CreateCoordinates());
00187
00188 for (int i=0; i<opRegion->get_coordinates_array_size();++i)
00189 coords->add_vec3(opRegion->get_coordinates_array_at(i));
00190
00191 ring->set_coordinates(coords);
00192 ring->set_tessellate(false);
00193 kmldom::OuterBoundaryIsPtr boundary(factory->CreateOuterBoundaryIs());
00194 boundary->set_linearring(ring);
00195 kmldom::PolygonPtr poly(factory->CreatePolygon());
00196 poly->set_outerboundaryis(boundary);
00197 poly->set_tessellate(false);
00198
00199
00200 kmldom::PolyStylePtr poly_style(factory->CreatePolyStyle());
00201 poly_style->set_fill(false);
00202
00203
00204 kmldom::StylePtr style(factory->CreateStyle());
00205 style->set_polystyle(poly_style);
00206
00207 style->set_id("RegionPolygonStyle");
00208
00209 kmldom::PlacemarkPtr region(factory->CreatePlacemark());
00210 region->set_name("Operating region");
00211 region->set_geometry(poly);
00212 region->set_styleurl("#RegionPolygonStyle");
00213 document->add_feature(region);
00214 document->add_styleselector(style);
00215 }
00216
00217 void CaddyKML::setDiverOrigin(const geometry_msgs::Point::ConstPtr& point)
00218 {
00219
00220 if ((point->x != diverOrigin.get_latitude()) ||
00221 (point->y != diverOrigin.get_longitude()))
00222 {
00223 diverOrigin = kmlbase::Vec3(point->y, point->x, 0);
00224 opRegion.reset(factory->CreateCoordinates());
00225 for(double i=0; i<2*M_PI; i+=0.2)
00226 {
00227 std::pair<double, double > latlon=std::make_pair(0.008*cos(i),0.008*sin(i));
00228 opRegion->add_latlng(point->x + latlon.first,
00229 point->y + latlon.second);
00230 }
00231
00232 opRegion->add_vec3(opRegion->get_coordinates_array_at(0));
00233 }
00234 }
00235
00236 void CaddyKML::run()
00237 {
00238 ros::Rate rate(5);
00239
00240 while (runFlag)
00241 {
00242 rate.sleep();
00243 boost::mutex::scoped_lock(kml_mux);
00244 this->write();
00245
00246 }
00247 }
00248