diff --git a/README-SAMPLES.md b/README-SAMPLES.md
index 99391f42..7b50d3de 100644
--- a/README-SAMPLES.md
+++ b/README-SAMPLES.md
@@ -195,7 +195,7 @@ $
#### geotag
```
-Usage: geotag {-help|-version|-dst|-dryrun|-ascii|-verbose|-adjust value|-tz value|-delta value}+ path+
+Usage: geotag {-help|-version|-dst|-dryrun|-ascii|-remove|-verbose|-adjust value|-tz value|-delta value}+ path+
```
Geotag reads one or more GPX files and adds GPS Tages to images. _Code: [geotag.cpp](samples/geotag.cpp)_
@@ -208,6 +208,7 @@ If the path is a directory, geotag will read all the files in the directory. It
| -dst | Apply 1 hour adjustment for daylight saving time. |
| -dryrun | Read arguments and print report. Does not modify images. |
| -verbose | Report progress. |
+| -remove | Removes GPS tags from images. |
| -adjust value | Add/subtract time from image data. |
| -tz value | Specify time zone. For example PST = -8:00 |
| -delta value | Correction between Image DataTime and GPS time. |
@@ -643,4 +644,4 @@ Read an XMP packet from a file, parse and re-serialize it.
Robin Mills
robin@clanmills.com
-Revised: 2019-06-20
\ No newline at end of file
+Revised: 2020-05-01
\ No newline at end of file
diff --git a/samples/geotag.cpp b/samples/geotag.cpp
index 84061f52..0e806d35 100644
--- a/samples/geotag.cpp
+++ b/samples/geotag.cpp
@@ -87,6 +87,7 @@ public:
bool dst;
bool dryrun;
bool ascii;
+ bool remove;
Options()
{
@@ -96,6 +97,7 @@ public:
dst = false;
dryrun = false;
ascii = false;
+ remove = false;
}
virtual ~Options() {} ;
@@ -113,6 +115,7 @@ enum // keyword indices
, kwDST
, kwDRYRUN
, kwASCII
+, kwREMOVE
, kwVERBOSE
, kwADJUST
, kwTZ
@@ -790,6 +793,7 @@ int main(int argc,const char* argv[])
keywords[kwADJUST ] = "adjust";
keywords[kwTZ ] = "tz";
keywords[kwDELTA ] = "delta";
+ keywords[kwREMOVE ] = "remove";
map shorts;
shorts["-?"] = "-help";
@@ -803,6 +807,7 @@ int main(int argc,const char* argv[])
shorts["-s"] = "-delta";
shorts["-X"] = "-dryrun";
shorts["-a"] = "-ascii";
+ shorts["-r"] = "-remove";
Options options ;
options.help = sina(keywords[kwHELP ],argv) || argc < 2;
@@ -811,6 +816,7 @@ int main(int argc,const char* argv[])
options.version = sina(keywords[kwVERSION],argv);
options.dst = sina(keywords[kwDST ],argv);
options.ascii = sina(keywords[kwASCII ],argv);
+ options.remove = sina(keywords[kwASCII ],argv);
for ( int i = 1 ; !result && i < argc ; i++ ) {
const char* arg = argv[i++];
@@ -831,6 +837,7 @@ int main(int argc,const char* argv[])
case kwDRYRUN : options.dryrun = true ; break;
case kwVERBOSE : options.verbose = true ; break;
case kwASCII : options.ascii = true ; break;
+ case kwREMOVE : options.remove = true ; break;
case kwTZ : Position::tz_ = parseTZ(value);break;
case kwADJUST : Position::adjust_ = ivalue;break;
case kwDELTA : Position::deltaMax_ = ivalue;break;
@@ -881,8 +888,8 @@ int main(int argc,const char* argv[])
s-= m*60 ;
printf("tz,dst,adjust = %d,%d,%d total = %dsecs (= %d:%d:%d)\n",t,d,a,A,h,m,s);
}
-/*
- if ( options.verbose ) {
+
+ if ( options.verbose && gTimeDict.size() ) {
printf("Time Dictionary\n");
for ( TimeDict_i it = gTimeDict.begin() ; it != gTimeDict.end() ; it++ ) {
std::string sTime = getExifTime(it->first);
@@ -894,7 +901,10 @@ int main(int argc,const char* argv[])
printf("%s %s\n",sTime.c_str(), sPos.c_str());
}
}
-*/
+
+ if ( !gTimeDict.size() && gFiles.size() && !options.remove ) {
+ printf("nothing in time dictionary!\n");
+ }
for ( size_t p = 0 ; p < gFiles.size() ; p++ ) {
std::string path = gFiles[p] ;
std::string stamp ;
@@ -905,8 +915,22 @@ int main(int argc,const char* argv[])
if ( image.get() ) {
image->readMetadata();
Exiv2::ExifData& exifData = image->exifData();
+
+ // if asked to remove, cycle the metadata and remove GPSInfo
+ // you can remove and geotag in the same run
+ // this is very useful when the TZ is incorrectly set to "clean" GPS before writing new data
+ if ( options.remove ) {
+ for (Exiv2::ExifData::iterator pos = exifData.begin(); pos != exifData.end(); ++pos) {
+ if ( pos->groupName() == "GPSInfo" ) {
+ if ( options.verbose ) {
+ std::cout << "remove: " << pos->key() << std::endl;
+ }
+ if ( !options.dryrun ) exifData.erase(pos);
+ }
+ }
+ }
if ( pPos ) {
- exifData["Exif.GPSInfo.GPSProcessingMethod" ] = "65 83 67 73 73 0 0 0 72 89 66 82 73 68 45 70 73 88"; // ASCII HYBRID-FIX
+ exifData["Exif.GPSInfo.GPSProcessingMethod" ] = "charset=Ascii HYBRID-FIX";
exifData["Exif.GPSInfo.GPSVersionID" ] = "2 2 0 0";
exifData["Exif.GPSInfo.GPSMapDatum" ] = "WGS-84";
@@ -924,7 +948,9 @@ int main(int argc,const char* argv[])
printf("%s %s % 2d\n",path.c_str(),pPos->toString().c_str(),pPos->delta());
} else {
- printf("%s *** not in time dict ***\n",path.c_str());
+ if ( gTimeDict.size() ) {
+ printf("%s *** not in time dict ***\n",path.c_str());
+ }
}
if ( !options.dryrun ) image->writeMetadata();
}
diff --git a/test/data/geotag-test.out b/test/data/geotag-test.out
index 0d49855c..56af4b39 100644
--- a/test/data/geotag-test.out
+++ b/test/data/geotag-test.out
@@ -23,5 +23,5 @@ Exif.GPSInfo.GPSAltitudeRef Byte 1 Below sea level
Exif.GPSInfo.GPSAltitude Rational 1 14.3 m
Exif.GPSInfo.GPSTimeStamp Rational 3 09:54:28
Exif.GPSInfo.GPSMapDatum Ascii 7 WGS-84
-Exif.GPSInfo.GPSProcessingMethod Undefined 58 65 83 67 73 73 0 0 0 72 89 66 82 73 68 45 70 73 88
+Exif.GPSInfo.GPSProcessingMethod Undefined 18 HYBRID-FIX
Exif.GPSInfo.GPSDateStamp Ascii 20 2008:05:08 09:54:28