@@ -14,26 +14,58 @@ def __init__(self, gcp_path):
1414
1515 def read (self ):
1616 if self .exists ():
17- # Read the gcp_file.txt
1817 with open (self .gcp_path , 'r' ) as f :
19- contents = [line .rstrip () for line in f ]
20-
21- # Get the spatial reference system (SRS) header from the first line
22- self .raw_srs = contents [0 ].strip ()
23- self .srs = location .parse_srs_header (self .raw_srs )
24-
25- for line in contents [1 :]:
26- if line != "" and line [0 ] != "#" :
27- parts = line .strip ().split ()
28- if len (parts ) >= 6 :
29- self .entries .append (line )
30- else :
31- log .MM_WARNING ("Malformed GCP line: %s" % line )
18+ contents = f .read ().strip ()
19+
20+ # Strip eventual BOM characters
21+ contents = contents .replace ('\ufeff ' , '' )
22+
23+ lines = list (map (str .strip , contents .split ('\n ' )))
24+ if lines :
25+ self .raw_srs = lines [0 ] # SRS
26+ self .srs = location .parse_srs_header (self .raw_srs )
27+
28+ for line in contents [1 :]:
29+ if line != "" and line [0 ] != "#" :
30+ parts = line .strip ().split ()
31+ if len (parts ) >= 6 :
32+ self .entries .append (line )
33+ else :
34+ log .MM_WARNING ("Malformed GCP line: %s" % line )
3235
3336 def iter_entries (self ):
3437 for entry in self .entries :
3538 yield self .parse_entry (entry )
3639
40+ def check_entries (self ):
41+ coords = {}
42+ gcps = {}
43+ errors = 0
44+
45+ for entry in self .iter_entries ():
46+ k = entry .coords_key ()
47+ coords [k ] = coords .get (k , 0 ) + 1
48+ if k not in gcps :
49+ gcps [k ] = []
50+ gcps [k ].append (entry )
51+
52+ for k in coords :
53+ if coords [k ] < 3 :
54+ description = "insufficient" if coords [k ] < 2 else "not ideal"
55+ for entry in gcps [k ]:
56+ log .ODM_WARNING (str (entry ))
57+ log .ODM_WARNING ("The number of images where the GCP %s has been tagged are %s" % (k , description ))
58+ log .ODM_WARNING ("You should tag at least %s more images" % (3 - coords [k ]))
59+ log .ODM_WARNING ("=====================================" )
60+ errors += 1
61+ if len (coords ) < 3 :
62+ log .ODM_WARNING ("Low number of GCPs detected (%s). For best results use at least 5." % (3 - len (coords )))
63+ log .ODM_WARNING ("=====================================" )
64+ errors += 1
65+
66+ if errors > 0 :
67+ log .ODM_WARNING ("Some issues detected with GCPs (but we're going to process this anyway)" )
68+
3769 def parse_entry (self , entry ):
3870 if entry :
3971 parts = entry .split ()
@@ -51,6 +83,25 @@ def entries_count(self):
5183 def exists (self ):
5284 return bool (self .gcp_path and os .path .exists (self .gcp_path ))
5385
86+ def make_resized_copy (self , gcp_file_output , ratio ):
87+ """
88+ Creates a new resized GCP file from an existing GCP file. If one already exists, it will be removed.
89+ :param gcp_file_output output path of new GCP file
90+ :param ratio scale GCP coordinates by this value
91+ :return path to new GCP file
92+ """
93+ output = [self .raw_srs ]
94+
95+ for entry in self .iter_entries ():
96+ entry .px *= ratio
97+ entry .py *= ratio
98+ output .append (str (entry ))
99+
100+ with open (gcp_file_output , 'w' ) as f :
101+ f .write ('\n ' .join (output ) + '\n ' )
102+
103+ return gcp_file_output
104+
54105 def wgs84_utm_zone (self ):
55106 """
56107 Finds the UTM zone where the first point of the GCP falls into
0 commit comments