Skip to content

Commit

Permalink
Merge pull request #254 from mleotta/dev/use-new-kwiver-geo_conv
Browse files Browse the repository at this point in the history
convert to using new KWIVER geographic functions
  • Loading branch information
mleotta committed Aug 3, 2017
2 parents e9d12d4 + 1b52b42 commit 48ea683
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 133 deletions.
7 changes: 7 additions & 0 deletions doc/rel_notes/0.11.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ Overall
track_set is now a base class and is generalized to support other types of
tracks, like moving object tracks.

* Replaced use of the geo_map vital algorithm with the new geodetic conversion
functions and data structures provided in KWIVER. The new approach still
uses plugins (e.g. PROJ4) but only supports one backend at a time that is
globally accessible throughout KWIVER. There is no more need to explicitly
pass a geo_map object around. New data structures, like geo_point, know
how to convert themselves into different coordinate systems.


Fixes since v0.10.0
------------------
Expand Down
5 changes: 0 additions & 5 deletions examples/kwiver_fmv_set_1/maptk_bundle_adjust_tracks.conf
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ track_filter:core:min_track_length = 50
# Path to write a file containing filtered feature tracks
filtered_track_file =

# Algorithm to use for 'geo_mapper'.
# Must be one of the following options:
# - proj
geo_mapper:type = proj

# This file contains the geographical location of the origin of the local
# cartesian coordinate system used in the camera and landmark files. This file
# is use for input and output. If the files exists it will be read to define
Expand Down
5 changes: 0 additions & 5 deletions examples/kwiver_wami_set_1/maptk_bundle_adjust_tracks.conf
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,6 @@ camera_sample_rate = 1
# Path to write a file containing filtered feature tracks
filtered_track_file =

# Algorithm to use for 'geo_mapper'.
# Must be one of the following options:
# - proj
geo_mapper:type = proj

# This file contains the geographical location of the origin of the local
# cartesian coordinate system used in the camera and landmark files. This file
# is use for input and output. If the files exists it will be read to define
Expand Down
44 changes: 25 additions & 19 deletions maptk/geo_reference_points_io.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "geo_reference_points_io.h"
#include <vital/exceptions.h>
#include <vital/io/eigen_io.h>
#include <vital/types/geodesy.h>
#include <vital/vital_foreach.h>
#include <vital/logger/logger.h>

Expand Down Expand Up @@ -73,9 +74,7 @@ void load_reference_file(vital::path_t const& reference_file,
vital::frame_id_t frm;
vital::vector_2d feat_loc;
vital::vector_3d vec(0,0,0);
double x, y;
int zone;
bool northp;

// used to stream file lines into data types
std::istringstream ss;

Expand All @@ -85,8 +84,9 @@ void load_reference_file(vital::path_t const& reference_file,
// Mean position of all landmarks.
vital::vector_3d mean(0,0,0);

// If the zone is invalid then use the reference points to compute a new origin
const bool set_lgcs_origin = (lgcs.utm_origin_zone() == -1);
// If the origin is invalid then use the reference points to compute a new origin
const bool set_lgcs_origin = lgcs.origin().is_empty();
int crs = lgcs.origin().crs();

// TODO: put in try-catch around >>'s in case we have an ill-formatted file,
// or there's a parse error
Expand All @@ -99,20 +99,20 @@ void load_reference_file(vital::path_t const& reference_file,
// input landmarks are given in lon/lat/alt format (ignoring alt for now)
ss >> vec;

// When this is called the first time, setzone is given a -1, which is the
// default for the function.
lgcs.geo_map_algo()->latlon_to_utm(vec.y(), vec.x(), x, y, zone, northp,
lgcs.utm_origin_zone());
vec[0] = x; vec[1] = y; vec[2] = vec.z();
mean += vec;

// Use the zone of the first input landmark as the base zone from which we
// interpret all other geo-positions with respect to.
if (set_lgcs_origin)
vital::vector_2d lon_lat(vec.x(), vec.y());
vital::geo_point gp(lon_lat, vital::SRID::lat_lon_WGS84);
if ( lgcs.origin().is_empty() )
{
LOG_DEBUG(logger, "lgcs origin zone: " << zone );
lgcs.set_utm_origin_zone(zone);
auto zone = vital::utm_ups_zone( lon_lat );
crs = (zone.north ? vital::SRID::UTM_WGS84_north : vital::SRID::UTM_WGS84_south) + zone.number;
LOG_DEBUG(logger, "lgcs origin zone: " << zone.number );
lgcs.set_origin( vital::geo_point( gp.location( crs ), crs ) );
}
vital::vector_2d utm = gp.location(crs);

vec[0] = utm.x();
vec[1] = utm.y();
mean += vec;

reference_lms[cur_id] = vital::landmark_sptr(new vital::landmark_d(vec));

Expand All @@ -138,7 +138,8 @@ void load_reference_file(vital::path_t const& reference_file,
{
// Initialize lgcs center
mean /= static_cast<double>(reference_lms.size());
lgcs.set_utm_origin(mean);
lgcs.set_origin( vital::geo_point( vital::vector_2d( mean.x(), mean.y() ), crs ) );
lgcs.set_origin_altitude( mean.z() );
LOG_DEBUG(logger, "mean position (lgcs origin): " << mean.transpose());
}

Expand All @@ -147,7 +148,12 @@ void load_reference_file(vital::path_t const& reference_file,
LOG_INFO(logger, "transforming ground control points to local coordinates");
VITAL_FOREACH(vital::landmark_map::map_landmark_t::value_type & p, reference_lms)
{
dynamic_cast<vital::landmark_d*>(p.second.get())->set_loc(p.second->loc() - lgcs.utm_origin());
auto loc = p.second->loc();
auto origin_pt = lgcs.origin().location();
loc[0] -= origin_pt[0];
loc[1] -= origin_pt[1];
loc[2] -= lgcs.origin_altitude();
dynamic_cast<vital::landmark_d*>(p.second.get())->set_loc(loc);
}

ref_landmarks = std::make_shared<vital::simple_landmark_map>(reference_lms);
Expand Down
97 changes: 43 additions & 54 deletions maptk/local_geo_cs.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <iomanip>

#include <vital/vital_foreach.h>
#include <vital/types/geodesy.h>
#include <vital/video_metadata/video_metadata_traits.h>

#define _USE_MATH_DEFINES
Expand All @@ -65,26 +66,33 @@ namespace maptk {

/// Constructor
local_geo_cs
::local_geo_cs(algo::geo_map_sptr alg)
: geo_map_algo_(alg),
utm_origin_(0.0, 0.0, 0.0),
utm_origin_zone_(-1)
::local_geo_cs()
: geo_origin_(),
origin_alt_(0.0)
{
}


/// Set the geographic coordinate origin
void
local_geo_cs
::set_origin(const geo_point& origin)
{
// convert the origin point into WGS84 UTM for the appropriate zone
vector_2d lon_lat = origin.location( SRID::lat_lon_WGS84 );
auto zone = utm_ups_zone( lon_lat );
int crs = (zone.north ? SRID::UTM_WGS84_north : SRID::UTM_WGS84_south) + zone.number;
geo_origin_ = geo_point(origin.location(crs), crs);
}


/// Use the pose data provided by metadata to update camera pose
void
local_geo_cs
::update_camera(vital::video_metadata const& md,
vital::simple_camera& cam,
vital::rotation_d const& rot_offset) const
{
if( !geo_map_algo_ )
{
return;
}

if( md.has( vital::VITAL_META_SENSOR_YAW_ANGLE) &&
md.has( vital::VITAL_META_SENSOR_PITCH_ANGLE) &&
md.has( vital::VITAL_META_SENSOR_ROLL_ANGLE) )
Expand All @@ -103,16 +111,13 @@ ::update_camera(vital::video_metadata const& md,
md.has( vital::VITAL_META_SENSOR_ALTITUDE) )
{
double alt = md.find( vital::VITAL_META_SENSOR_ALTITUDE ).as_double();
vital::geo_lat_lon gll;
md.find( vital::VITAL_META_SENSOR_LOCATION ).data( gll );

// TODO: Possibly add a positional offset optional parameter, also.
double x,y;
int zone;
bool is_north_hemi;
geo_map_algo_->latlon_to_utm(gll.latitude(), gll.longitude(),
x, y, zone, is_north_hemi, utm_origin_zone_);
cam.set_center(vector_3d(x, y, alt) - utm_origin_);
vital::geo_point gloc;
md.find( vital::VITAL_META_SENSOR_LOCATION ).data( gloc );

// get the location in the same UTM zone as the origin
vector_2d loc = gloc.location(geo_origin_.crs());
loc -= geo_origin_.location();
cam.set_center(vector_3d(loc.x(), loc.y(), alt - origin_alt_));
}
}

Expand All @@ -123,22 +128,17 @@ local_geo_cs
::update_metadata(vital::simple_camera const& cam,
vital::video_metadata& md) const
{
if( !geo_map_algo_ )
{
return;
}
double yaw, pitch, roll;
cam.rotation().get_yaw_pitch_roll(yaw, pitch, roll);
yaw *= rad2deg;
pitch *= rad2deg;
roll *= rad2deg;
vital::vector_3d c = cam.get_center() + utm_origin_;
double lat, lon;
geo_map_algo_->utm_to_latlon(c.x(), c.y(), utm_origin_zone_, true,
lat, lon);
vital::vector_3d c = cam.get_center();
vital::geo_point gc(vector_2d(c.x(), c.y()) + geo_origin_.location(),
geo_origin_.crs());
vector_2d lon_lat = gc.location(SRID::lat_lon_WGS84);

vital::geo_lat_lon latlon( lat, lon );
md.add( NEW_METADATA_ITEM( VITAL_META_SENSOR_LOCATION, latlon ) );
md.add( NEW_METADATA_ITEM( VITAL_META_SENSOR_LOCATION, lon_lat ) );
md.add( NEW_METADATA_ITEM( VITAL_META_SENSOR_ALTITUDE, c.z() ) );
md.add( NEW_METADATA_ITEM( VITAL_META_SENSOR_YAW_ANGLE, yaw ) );
md.add( NEW_METADATA_ITEM( VITAL_META_SENSOR_PITCH_ANGLE, pitch ) );
Expand All @@ -154,12 +154,8 @@ read_local_geo_cs_from_file(local_geo_cs& lgcs,
std::ifstream ifs(file_path);
double lat, lon, alt;
ifs >> lat >> lon >> alt;
double x,y;
int zone;
bool is_north_hemi;
lgcs.geo_map_algo()->latlon_to_utm(lat, lon, x, y, zone, is_north_hemi);
lgcs.set_utm_origin_zone(zone);
lgcs.set_utm_origin(kwiver::vital::vector_3d(x, y, alt));
lgcs.set_origin( geo_point( vector_2d(lon, lat), SRID::lat_lon_WGS84) );
lgcs.set_origin_altitude( alt );
}


Expand All @@ -169,16 +165,12 @@ write_local_geo_cs_to_file(local_geo_cs const& lgcs,
vital::path_t const& file_path)
{
// write out the origin of the local coordinate system
double easting = lgcs.utm_origin()[0];
double northing = lgcs.utm_origin()[1];
double altitude = lgcs.utm_origin()[2];
int zone = lgcs.utm_origin_zone();
double lat, lon;
lgcs.geo_map_algo()->utm_to_latlon(easting, northing, zone, true, lat, lon);
auto lon_lat = lgcs.origin().location( SRID::lat_lon_WGS84 );
std::ofstream ofs(file_path);
if (ofs)
{
ofs << std::setprecision(12) << lat << " " << lon << " " << altitude;
ofs << std::setprecision(12) << lon_lat[1] << " " << lon_lat[0]
<< " " << lgcs.origin_altitude();
}
}

Expand All @@ -197,7 +189,7 @@ initialize_cameras_with_metadata(std::map<vital::frame_id_t,
simple_camera active_cam(base_camera);

bool update_local_origin = false;
if( lgcs.utm_origin_zone() < 0 && !md_map.empty())
if( lgcs.origin().is_empty() && !md_map.empty())
{
// if a local coordinate system has not been established,
// use the coordinates of the first camera
Expand All @@ -213,15 +205,11 @@ initialize_cameras_with_metadata(std::map<vital::frame_id_t,
if( md &&
md->has( vital::VITAL_META_SENSOR_LOCATION ) )
{
vital::geo_lat_lon gll;
md->find( vital::VITAL_META_SENSOR_LOCATION ).data( gll );
double x,y;
int zone;
bool is_north_hemi;
lgcs.geo_map_algo()->latlon_to_utm(gll.latitude(), gll.longitude(),
x, y, zone, is_north_hemi);
lgcs.set_utm_origin_zone(zone);
lgcs.set_utm_origin(vital::vector_3d(x, y, 0.0));
vital::geo_point gloc;
md->find( vital::VITAL_META_SENSOR_LOCATION ).data( gloc );

lgcs.set_origin( gloc );
lgcs.set_origin_altitude( 0.0 );
update_local_origin = true;
}
}
Expand All @@ -244,7 +232,8 @@ initialize_cameras_with_metadata(std::map<vital::frame_id_t,
mean[2] = 0.0;

// shift the UTM origin to the mean of the cameras easting and northing
lgcs.set_utm_origin(lgcs.utm_origin() + mean);
vector_2d mean_xy( mean.x(), mean.y() );
lgcs.set_origin( geo_point( lgcs.origin().location() + mean_xy, lgcs.origin().crs() ) );

// shift all cameras to the new coordinate system.
typedef std::map<frame_id_t, camera_sptr>::value_type cam_map_val_t;
Expand All @@ -265,7 +254,7 @@ update_metadata_from_cameras(std::map<frame_id_t, camera_sptr> const& cam_map,
local_geo_cs const& lgcs,
std::map<frame_id_t, vital::video_metadata_sptr>& md_map)
{
if( lgcs.utm_origin_zone() < 0 )
if( lgcs.origin().is_empty() )
{
// TODO throw an exception here?
vital::logger_handle_t
Expand Down
39 changes: 18 additions & 21 deletions maptk/local_geo_cs.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@

#include <maptk/maptk_export.h>

#include <vital/algo/geo_map.h>
#include <vital/types/camera.h>
#include <vital/types/geo_point.h>
#include <vital/types/rotation.h>
#include <vital/video_metadata/video_metadata.h>
#include <vital/vital_types.h>
Expand All @@ -59,22 +59,22 @@ class MAPTK_EXPORT local_geo_cs
{
public:
/// Constructor
explicit local_geo_cs(vital::algo::geo_map_sptr alg);
local_geo_cs();

/// Set the local UTM coordinate origin
void set_utm_origin(const vital::vector_3d& origin) { utm_origin_ = origin; }

/// Set the local UTM origin zone
void set_utm_origin_zone(int zone) { utm_origin_zone_ = zone; }
/// Set the geographic coordinate origin
/**
* Internally converts this coordinate to WGS84 UTM
*/
void set_origin(const vital::geo_point& origin);

/// Access the local UTM coordinate origin
const vital::vector_3d& utm_origin() const { return utm_origin_; }
/// Set the altitude of the origin (in meters)
void set_origin_altitude(double alt) { origin_alt_ = alt; }

/// Access the local UTM origin zone
int utm_origin_zone() const { return utm_origin_zone_; }
/// Access the geographic coordinate of the origin
const vital::geo_point& origin() const { return geo_origin_; }

/// Access the geographic mapping algorithm
vital::algo::geo_map_sptr geo_map_algo() const { return geo_map_algo_; }
/// Access the geographic coordinate altituded (in meters)
int origin_altitude() const { return origin_alt_; }

/// Use the pose data provided by metadata to update camera pose
/**
Expand All @@ -91,22 +91,19 @@ class MAPTK_EXPORT local_geo_cs
vital::video_metadata& md) const;

private:
/// An algorithm provided to compute geographic transformations
vital::algo::geo_map_sptr geo_map_algo_;

/// The local coordinates origin in UTM (easting, northing, altitude)
vital::vector_3d utm_origin_;
/// The local coordinates origin
vital::geo_point geo_origin_;

/// The UTM zone number containing the UTM origin
int utm_origin_zone_;
/// altitude of the local coordinate origin
double origin_alt_;
};


/// Read a local_geo_cs from a text file
/**
* The file format is the geographic origin in latitude (deg), longitude (deg),
* and altitude (m) in space delimited ASCII value. These values are read
* into an existing local_geo_cs with a valid geo_map algorithm instance.
* into an existing local_geo_cs.
*
* \param [in,out] lgcs The local geographic coordinate system that is
* updated with the origin in the file.
Expand Down
Loading

0 comments on commit 48ea683

Please sign in to comment.