cannot pass image geolocation file (geo.txt) into project

very likely an ignorant question here… but when using pyodm, I am unable to pass or have odm recognize an image geolocation file (geo.txt). This works using the normal webodm and CLI approaches as long as I have it in the root of my project folder, but cannot resolve this with pyodm. When creating a task I used the --geo argument passing the geo.txt absolute path with no success either.

Any help would be much appreciated!

import glob
import os
from pyodm import Node, exceptions
node = Node("localhost", 3000)
    # Get all JPG files in directory
    files = glob.glob("*.JPG") + glob.glob("*.jpg") + glob.glob("*.JPEG") + glob.glob("*.jpeg") + glob.glob("*.txt")
    geolist = glob.glob("*geo.txt")
    print("Uploading images...")
    task = node.create_task(files, {'orthophoto-resolution': 15, 'ignore-gsd': True, 'gps-accuracy': 0.05, 'use-hybrid-bundle-adjustment': True, 'fast-orthophoto': True, 'skip-3dmodel': True, 'time': True, 'geo': geolist})
        def print_status(task_info):
            msecs = task_info.processing_time
            seconds = int((msecs / 1000) % 60)
            minutes = int((msecs / (1000 * 60)) % 60)
            hours = int((msecs / (1000 * 60 * 60)) % 24)
            print("Task is running: %02d:%02d:%02d" % (hours, minutes, seconds), end="\r")
        print("Task completed, downloading results...")
        # Retrieve results
        def print_download(progress):
            print("Download: %s%%" % progress, end="\r")
        task.download_assets(outputdir, progress_callback=print_download)
        print("Assets saved in output/results directory")
    except exceptions.TaskFailedError as e:
except exceptions.NodeConnectionError as e:
    print("Cannot connect: %s" % e)
except exceptions.OdmError as e:
    print("Error: %s" % e)
1 Like

No need to specify the --geo option; simply naming your file geo.txt and adding its path to your files list should do the trick.

1 Like

Hi Piero - really appreciate the reply. That is what I tried initially but it was being recognized as being a gcp file, even though it’s named “geo.txt”.

Mm, were you running the latest version of ODM/NodeODM? The latest version of NodeODM shouldn’t even expose the geo option: NodeODM/odmInfo.js at 1aae1e4957bd174079151d851dae23ab8b1d3c1d · OpenDroneMap/NodeODM · GitHub

here is the…

{‘version’: ‘2.1.2’, ‘task_queue_count’: 0, ‘total_memory’: 18880630784, ‘available_memory’: 18163216384, ‘cpu_cores’: 4, ‘max_images’: None, ‘max_parallel_tasks’: 1, ‘engine’: ‘odm’, ‘engine_version’: ‘2.3.3’, ‘odm_version’: ‘?’}

Uploading images…
{‘uuid’: ‘9484e3d0-4b1f-45e6-991d-cb9242bb2711’, ‘name’: ‘Task of 2021-01-03T16:18:57.658Z’, ‘date_created’: datetime.datetime(2021, 1, 3, 16, 18, 57), ‘processing_time’: 1, ‘status’: <TaskStatus.RUNNING: 20>, ‘last_error’: ‘’, ‘options’: [{‘name’: ‘use-hybrid-bundle-adjustment’, ‘value’: True}, {‘name’: ‘skip-3dmodel’, ‘value’: True}, {‘name’: ‘ignore-gsd’, ‘value’: True}, {‘name’: ‘fast-orthophoto’, ‘value’: True}, {‘name’: ‘orthophoto-resolution’, ‘value’: 15}, {‘name’: ‘gps-accuracy’, ‘value’: 0.05}], ‘images_count’: 6, ‘progress’: 0, ‘output’: []}
[INFO] Fast orthophoto is turned on, automatically setting --skip-3dmodel
[INFO] Initializing ODM - Sun Jan 03 16:18:58 2021
[INFO] ==============
[INFO] build_overviews: False
[INFO] camera_lens: auto
[INFO] cameras: {}
[INFO] crop: 3
[INFO] debug: False
[INFO] dem_decimation: 1
[INFO] dem_euclidean_map: False
[INFO] dem_gapfill_steps: 3
[INFO] dem_resolution: 5
[INFO] depthmap_resolution: 640
[INFO] dsm: False
[INFO] dtm: False
[INFO] end_with: odm_report
[INFO] fast_orthophoto: True
[INFO] feature_quality: high
[INFO] feature_type: sift
[INFO] force_gps: False
[INFO] gcp: /var/www/data/9484e3d0-4b1f-45e6-991d-cb9242bb2711/gcp/geo.txt
[INFO] geo: None
[INFO] gps_accuracy: 0.05
[INFO] ignore_gsd: True
[INFO] matcher_distance: 0
[INFO] matcher_neighbors: 8
[INFO] matcher_type: flann
[INFO] max_concurrency: 4
[INFO] merge: all
[INFO] mesh_octree_depth: 11
[INFO] mesh_size: 200000
[INFO] min_num_features: 8000
[INFO] name: 9484e3d0-4b1f-45e6-991d-cb9242bb2711
[INFO] opensfm_depthmap_method: PATCH_MATCH
[INFO] opensfm_depthmap_min_consistent_views: 3
[INFO] opensfm_depthmap_min_patch_sd: 1
[INFO] optimize_disk_space: False
[INFO] orthophoto_compression: DEFLATE
[INFO] orthophoto_cutline: False
[INFO] orthophoto_no_tiled: False
[INFO] orthophoto_png: False
[INFO] orthophoto_resolution: 15.0
[INFO] pc_classify: False
[INFO] pc_csv: False
[INFO] pc_ept: False
[INFO] pc_filter: 2.5
[INFO] pc_las: False
[INFO] pc_quality: medium
[INFO] pc_rectify: False
[INFO] pc_sample: 0
[INFO] primary_band: auto
[INFO] project_path: /var/www/data
[INFO] radiometric_calibration: none
[INFO] rerun: None
[INFO] rerun_all: False
[INFO] rerun_from: None
[INFO] resize_to: 2048
[INFO] skip_3dmodel: True
[INFO] skip_band_alignment: False
[INFO] sm_cluster: None
[INFO] smrf_scalar: 1.25
[INFO] smrf_slope: 0.15
[INFO] smrf_threshold: 0.5
[INFO] smrf_window: 18.0
[INFO] split: 999999
[INFO] split_overlap: 150
[INFO] texturing_data_term: gmi
[INFO] texturing_outlier_removal_type: gauss_clamping
[INFO] texturing_skip_global_seam_leveling: False
[INFO] texturing_skip_local_seam_leveling: False
[INFO] texturing_tone_mapping: none
[INFO] tiles: False
[INFO] time: False
[INFO] use_3dmesh: False
[INFO] use_exif: False
[INFO] use_fixed_camera_params: False
[INFO] use_hybrid_bundle_adjustment: True
[INFO] use_opensfm_dense: False
[INFO] verbose: False
[INFO] ==============
[INFO] Running dataset stage
[INFO] Loading dataset from: /var/www/data/9484e3d0-4b1f-45e6-991d-cb9242bb2711/images
[INFO] Loading 6 images
[INFO] Wrote images database: /var/www/data/9484e3d0-4b1f-45e6-991d-cb9242bb2711/images.json
[INFO] Found 6 usable images
[INFO] Parsing SRS header: EPSG:26904
[WARNING] Malformed GCP line: DSC04234.JPG 667018.568 6581111.428 325.163884
[WARNING] Malformed GCP line: DSC04235.JPG 667125.5328 6581103.183 324.700938
[WARNING] Malformed GCP line: DSC04864.JPG 669465.478 6581997.929 330.889978
[WARNING] Malformed GCP line: DSC04865.JPG 669569.9596 6582005.862 330.231767
Traceback (most recent call last):
File “/code/”, line 69, in
File “/code/stages/”, line 83, in execute
File “/code/opendm/”, line 342, in run
self.process(self.args, outputs)
File “/code/stages/”, line 157, in process
File “/code/opendm/”, line 79, in georeference_with_gcp
raise RuntimeError(“This GCP file does not have any entries. Are the entries entered in the proper format?”)
RuntimeError: This GCP file does not have any entries. Are the entries entered in the proper format?

Mm now that I think about it, this might be a bug.

I’ll have a look at this in the next few days.



1 Like

This should be fixed with Add support for geo files by pierotofy · Pull Request #140 · OpenDroneMap/NodeODM · GitHub

After updating, the API version should read 2.1.3. With it, you can pass a geo.txt file along with the images and it should be picked up. :+1:

Thanks for reporting the problem!


that did the trick… thanks again!


Can you post a sample geo.txt format for better understanding of what to do

1 Like

Indeed, see if this link helps:

1 Like

Hello there. I know this is a VERY ignorant question (sigh…) but am trying to figure out exactly what the geo.txt file format should be. It would be great if a sample txt file could be posted here. Thanks!

1 Like


Check the documentation:
Image Geolocation Files — OpenDroneMap 2.6.0 documentation