/** * a_geotag_create_waypoint_positioned: * @filename: The image file to process * @coord: The location for positioning the Waypoint * @name: Returns a name for the Waypoint (can be NULL) * * Returns: An allocated Waypoint or NULL if Waypoint could not be generated * * Here EXIF processing is used to get non position related information (i.e. just the comment) * */ VikWaypoint* a_geotag_create_waypoint_positioned ( const gchar *filename, VikCoord coord, gdouble alt, gchar **name ) { *name = NULL; VikWaypoint *wp = vik_waypoint_new(); wp->visible = TRUE; wp->coord = coord; wp->altitude = alt; ExifData *ed = exif_data_new_from_file ( filename ); // Set info from exif values if ( ed ) { wp->comment = geotag_get_exif_comment ( ed ); gchar str[128]; ExifEntry *ee; // Name ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_TITLE); if ( ee ) { exif_entry_get_value ( ee, str, 128 ); *name = g_strdup ( str ); } // Finished with EXIF exif_data_free ( ed ); } vik_waypoint_set_image ( wp, filename ); return wp; }
/** * a_geotag_waypoint_positioned: * @filename: The image file to process * @coord: The location for positioning the Waypoint * @name: Returns a name for the Waypoint (can be NULL) * @waypoint: An existing waypoint to update (can be NULL to generate a new waypoint) * * Returns: An allocated waypoint if the input waypoint is NULL, * otherwise the passed in waypoint is updated * * Here EXIF processing is used to get non position related information (i.e. just the comment) * */ VikWaypoint* a_geotag_waypoint_positioned ( const gchar *filename, VikCoord coord, gdouble alt, gchar **name, VikWaypoint *wp ) { *name = NULL; if ( wp == NULL ) { // Need to create waypoint wp = vik_waypoint_new(); wp->visible = TRUE; } wp->coord = coord; wp->altitude = alt; #ifdef HAVE_LIBGEXIV2 GExiv2Metadata *gemd = gexiv2_metadata_new (); if ( gexiv2_metadata_open_path ( gemd, filename, NULL ) ) { wp->comment = geotag_get_exif_comment ( gemd ); if ( gexiv2_metadata_has_tag ( gemd, "Exif.Image.XPTitle" ) ) *name = g_strdup ( gexiv2_metadata_get_tag_interpreted_string ( gemd, "Exif.Image.XPTitle" ) ); } metadata_free ( gemd ); #else #ifdef HAVE_LIBEXIF ExifData *ed = exif_data_new_from_file ( filename ); // Set info from exif values if ( ed ) { wp->comment = geotag_get_exif_comment ( ed ); gchar str[128]; ExifEntry *ee; // Name ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_TITLE); if ( ee ) { exif_entry_get_value ( ee, str, 128 ); *name = g_strdup ( str ); } // Finished with EXIF exif_data_free ( ed ); } #endif #endif vik_waypoint_set_image ( wp, filename ); return wp; }
/** * a_geotag_create_waypoint_from_file: * @filename: The image file to process * @vcmode: The current location mode to use in the positioning of Waypoint * @name: Returns a name for the Waypoint (can be NULL) * * Returns: An allocated Waypoint or NULL if Waypoint could not be generated (e.g. no EXIF info) * */ VikWaypoint* a_geotag_create_waypoint_from_file ( const gchar *filename, VikCoordMode vcmode, gchar **name ) { // Default return values (for failures) *name = NULL; VikWaypoint *wp = NULL; // TODO use log? //ExifLog *log = NULL; // open image with libexif ExifData *ed = exif_data_new_from_file ( filename ); // Detect EXIF load failure if ( !ed ) // return with no Waypoint return wp; struct LatLon ll; gchar str[128]; ExifEntry *ee; ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_VERSION_ID); // Confirm this has a GPS Id - normally "2.0.0.0" or "2.2.0.0" if ( ! ( ee && ee->components == 4 ) ) goto MyReturn; // Could test for these versions explicitly but may have byte order issues... //if ( ! ( ee->data[0] == 2 && ee->data[2] == 0 && ee->data[3] == 0 ) ) // goto MyReturn; ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_MAP_DATUM); if ( ! ( ee && ee->components > 0 && ee->format == EXIF_FORMAT_ASCII ) ) goto MyReturn; // If map datum specified - only deal in WGS-84 - the defacto standard if ( ee && ee->components > 0 ) { exif_entry_get_value ( ee, str, 128 ); if ( strncmp (str, "WGS-84", 6) ) goto MyReturn; } // // Lat & Long is necessary to form a waypoint. // ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LATITUDE); if ( ! ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) ) goto MyReturn; ll.lat = Rational2Double ( ee->data, exif_format_get_size(ee->format), exif_data_get_byte_order(ed) ); ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LATITUDE_REF); if ( ee ) { exif_entry_get_value ( ee, str, 128 ); if ( str[0] == 'S' ) ll.lat = -ll.lat; } ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LONGITUDE); if ( ! ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) ) goto MyReturn; ll.lon = Rational2Double ( ee->data, exif_format_get_size(ee->format), exif_data_get_byte_order(ed) ); ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LONGITUDE_REF); if ( ee ) { exif_entry_get_value ( ee, str, 128 ); if ( str[0] == 'W' ) ll.lon = -ll.lon; } // // Not worried if none of the other fields exist, as can default the values to something // gdouble alt = VIK_DEFAULT_ALTITUDE; ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_ALTITUDE); if ( ee && ee->components == 1 && ee->format == EXIF_FORMAT_RATIONAL ) { alt = Rational2Double ( ee->data, 0, exif_data_get_byte_order(ed) ); ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_ALTITUDE_REF); if ( ee && ee->components == 1 && ee->format == EXIF_FORMAT_BYTE && ee->data[0] == 1 ) alt = -alt; } // Name ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_TITLE); if ( ee ) { exif_entry_get_value ( ee, str, 128 ); *name = g_strdup ( str ); } // // Now create Waypoint with acquired information // wp = vik_waypoint_new(); wp->visible = TRUE; // Set info from exif values // Location vik_coord_load_from_latlon ( &(wp->coord), vcmode, &ll ); // Altitude wp->altitude = alt; wp->comment = geotag_get_exif_comment ( ed ); vik_waypoint_set_image ( wp, filename ); MyReturn: // Finished with EXIF exif_data_free ( ed ); return wp; }
/** * a_geotag_create_waypoint_from_file: * @filename: The image file to process * @vcmode: The current location mode to use in the positioning of Waypoint * @name: Returns a name for the Waypoint (can be NULL) * * Returns: An allocated Waypoint or NULL if Waypoint could not be generated (e.g. no EXIF info) * */ VikWaypoint* a_geotag_create_waypoint_from_file ( const gchar *filename, VikCoordMode vcmode, gchar **name ) { // Default return values (for failures) *name = NULL; VikWaypoint *wp = NULL; #ifdef HAVE_LIBGEXIV2 GExiv2Metadata *gemd = gexiv2_metadata_new (); if ( gexiv2_metadata_open_path ( gemd, filename, NULL ) ) { gdouble lat; gdouble lon; gdouble alt; if ( gexiv2_metadata_get_gps_info ( gemd, &lon, &lat, &alt ) ) { struct LatLon ll; ll.lat = lat; ll.lon = lon; // // Now create Waypoint with acquired information // wp = vik_waypoint_new(); wp->visible = TRUE; // Set info from exif values // Location vik_coord_load_from_latlon ( &(wp->coord), vcmode, &ll ); // Altitude wp->altitude = alt; if ( gexiv2_metadata_has_tag ( gemd, "Exif.Image.XPTitle" ) ) *name = g_strdup ( gexiv2_metadata_get_tag_interpreted_string ( gemd, "Exif.Image.XPTitle" ) ); wp->comment = geotag_get_exif_comment ( gemd ); // Direction VikWaypointImageDirectionRef ref = WP_IMAGE_DIRECTION_REF_TRUE; if ( gexiv2_metadata_has_tag ( gemd, EXIF_GPS_IMGDIR_REF ) ) { gchar* ref_str = gexiv2_metadata_get_tag_interpreted_string(gemd, EXIF_GPS_IMGDIR_REF); if ( ref_str && g_ascii_strncasecmp ("M", ref_str, 1) == 0 ) ref = WP_IMAGE_DIRECTION_REF_MAGNETIC; g_free ( ref_str ); } if ( gexiv2_metadata_has_tag ( gemd, EXIF_GPS_IMGDIR ) ) { gint nom; gint den; gdouble direction = NAN; if ( gexiv2_metadata_get_exif_tag_rational (gemd, EXIF_GPS_IMGDIR, &nom, &den) ) if ( den != 0 ) direction = (gdouble)nom/(gdouble)den; if ( !isnan(direction) ) vik_waypoint_set_image_direction_info ( wp, direction, ref ); } vik_waypoint_set_image ( wp, filename ); } } metadata_free ( gemd ); #else #ifdef HAVE_LIBEXIF // TODO use log? //ExifLog *log = NULL; // open image with libexif ExifData *ed = exif_data_new_from_file ( filename ); // Detect EXIF load failure if ( !ed ) // return with no Waypoint return wp; struct LatLon ll; gchar str[128]; ExifEntry *ee; ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_VERSION_ID); // Confirm this has a GPS Id - normally "2.0.0.0" or "2.2.0.0" if ( ! ( ee && ee->components == 4 ) ) goto MyReturn; // Could test for these versions explicitly but may have byte order issues... //if ( ! ( ee->data[0] == 2 && ee->data[2] == 0 && ee->data[3] == 0 ) ) // goto MyReturn; ll = get_latlon ( ed ); // Hopefully won't have valid images at 0,0! if ( ll.lat == 0.0 && ll.lon == 0.0 ) goto MyReturn; // // Not worried if none of the other fields exist, as can default the values to something // gdouble alt = VIK_DEFAULT_ALTITUDE; ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_ALTITUDE); if ( ee && ee->components == 1 && ee->format == EXIF_FORMAT_RATIONAL ) { alt = Rational2Double ( ee->data, 0, exif_data_get_byte_order(ed) ); ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_ALTITUDE_REF); if ( ee && ee->components == 1 && ee->format == EXIF_FORMAT_BYTE && ee->data[0] == 1 ) alt = -alt; } // Name ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_TITLE); if ( ee ) { exif_entry_get_value ( ee, str, 128 ); *name = g_strdup ( str ); } // // Now create Waypoint with acquired information // wp = vik_waypoint_new(); wp->visible = TRUE; // Set info from exif values // Location vik_coord_load_from_latlon ( &(wp->coord), vcmode, &ll ); // Altitude wp->altitude = alt; wp->comment = geotag_get_exif_comment ( ed ); vik_waypoint_set_image ( wp, filename ); MyReturn: // Finished with EXIF exif_data_free ( ed ); #endif #endif return wp; }