def get_replacement(self, dct, town_entry: str, place: Loc.Loc): """ Check global_replace dictionary to see if we've already found a match for this location. Update place structure with prefix and found location #Args: dct: global replacement dictionary town_entry: entry to lookup place: Loc structure #Returns: Return geoid of location if found, else None place will be filled out with replacement location """ entry = dct.get(town_entry) if entry: place.prefix, geoid = ReplacementDictionary.parse_replacement_entry( entry) else: return None if len(geoid) > 0: self.geodata.find_geoid(geoid, place) place.set_place_type() else: self.logger.debug( f'Replacement GEOID NOT found [{town_entry}] entry=[{entry}]') place.result_type = GeoUtil.Result.DELETE # If prefix then add commas if len(place.prefix) > 0: place.prefix_commas = ',' return geoid
def write_updated_place(self, place: Loc.Loc, original_entry): """ Write out this updated location and lat/lon to ancestry file output If place result_type was DELETE, do not write out location Write to diagnostic file as well if enabled #Args: place: Updated location original_entry: Original file entry """ self.geodata.geo_files.geodb.set_display_names(place) place.original_entry = place.get_long_name( self.geodata.geo_files.output_replace_dct) prefix = GeoUtil.capwords(self.place.prefix) if self.diagnostics: self.in_diag_file.write(f'{GeoUtil.capwords(original_entry)}\n') if place.result_type != GeoUtil.Result.DELETE: # self.logger.debug(f'Write Updated - name={place.name} pref=[{place.prefix}]') self.ancestry_file_handler.write_updated( prefix + place.prefix_commas + place.original_entry, place) self.ancestry_file_handler.write_lat_lon(lat=place.lat, lon=place.lon) text = prefix + place.prefix_commas + place.original_entry + '\n' # text = str(text.encode('utf-8', errors='replace')) if self.diagnostics: self.out_diag_file.write(text) else: # self.logger.debug('zero len, no output') if self.diagnostics: self.out_diag_file.write('DELETE\n')
def _create_enclosed_by(self, place: Loc.Loc): """ Create EnclosedBy elements in Dictionary for CSV file :return: None """ self.logger.debug(f'\nCREATE ENCLOSURE FOR {place.original_entry}') enclosure_place: Loc.Loc = copy.copy(place) enclosure_place.id = '' # Move up to enclosure level success = self._move_up_level(enclosure_place=enclosure_place, idx=_get_dict_idx(enclosure_place)) if success: place.enclosed_by = enclosure_place.id self._update_enclosure_id(place) return
def add_place(self, place: Loc.Loc): """ Create a CSV node in Dictionary for specified place with the following: Place (ID), Title, Name, Type, latitude, longitude, enclosed_by Call create_csv_node for each place in the ancestry file #Args: place: Loc.Loc location """ if place.original_entry == '': return csv_row = [''] * 11 _set_CSV_place_type(place) if place.id == '': _set_CSV_place_type(place) place.id = self._get_hierarchy_key(place) place.set_place_type_text() csv_row[CSVEntry.PLACE_ID] = place.id csv_row[CSVEntry.ENCLOSED_BY] = place.enclosed_by csv_row[CSVEntry.TITLE] = place.prefix + place.prefix_commas + place.original_entry csv_row[CSVEntry.FEAT] = place.feature csv_row[CSVEntry.LAT] = f'{float(place.lat):.4f}' csv_row[CSVEntry.LON] = f'{float(place.lon):.4f}' csv_row[CSVEntry.ADMIN2_ID] = place.admin2_id csv_row[CSVEntry.ADMIN1_ID] = place.admin1_id csv_row[CSVEntry.ISO] = place.country_iso csv_row[CSVEntry.NAME] = _get_csv_name(place) csv_row[CSVEntry.TYPE] = place.result_type_text # There is a separate dictionary for each entity tier (prefix, city, adm2, adm1, country) key = self._get_hierarchy_key(place) dict_idx = _get_dict_idx(place) if dict_idx == 0: # This node is at country level - so no enclosure place.enclosed_by = '' csv_row[CSVEntry.ENCLOSED_BY] = '' if place.enclosed_by != '': # Validate enclosure if hierarchy_level(key) <= hierarchy_level(csv_row[CSVEntry.ENCLOSED_BY]) and hierarchy_level(key) > 0: msg = f'Incorrect Enclosure for [{place.original_entry}]. Key= [{key}] Enclosure= [{csv_row[CSVEntry.ENCLOSED_BY]}]' self.logger.warning(msg) elif hierarchy_level(key) < hierarchy_level(csv_row[CSVEntry.ENCLOSED_BY]) and hierarchy_level(key) == 0: msg = f'Incorrect Enclosure for [{place.original_entry}]. Key= [{key}] Enclosure= [{csv_row[CSVEntry.ENCLOSED_BY]}]' self.logger.warning(msg) # See if this is a synthetic ID or Ancestry ID if '_' in place.id or len(place.id)<4: # Synthetic ID. We created this place ID. It has no ancestry events tied to it and is lower priority # than an Ancestry place ID (which has events). Only add it if we don't already have an Ancestry Place ID res = self.hierarchy_dictionaries[dict_idx].get(key.upper()) if res is None: # Nothing there, add this row self.hierarchy_dictionaries[dict_idx][key.upper()] = csv_row else: # An ancestry node is already there so use existing place.id = res[CSVEntry.PLACE_ID] else: # Place ID came from the Ancestry data and takes priority since it is already linked to # events. Add this self.hierarchy_dictionaries[dict_idx][key.upper()] = csv_row
def _retrieve_csv_place(hierarchy_dictionaries, geodata, place: Loc.Loc, key, idx): """ Lookup key in dictionary and fill in place with data from dictionary entry #Args: hierarchy_dictionaries: geodata: place: key: idx: #Returns: Fills in place with data from dictionary entry """ # 0Place (ID), 1Title, 2Name, 3Type, 4latitude, 5longitude, 6enclosed_by row = hierarchy_dictionaries[idx].get(key) key_tokens = key.split("_") place.place_type = len(key_tokens) - 1 # self.logger.debug(f'{row}') place.feature = row[CSVEntry.FEAT] place.original_entry = row[CSVEntry.TITLE] place.country_iso = row[CSVEntry.ISO] place.country_name = geodata.geo_files.geodb.get_country_name(place.country_iso) place.enclosed_by = row[CSVEntry.ENCLOSED_BY] place.lat: float = float(row[CSVEntry.LAT]) place.lon: float = float(row[CSVEntry.LON]) place.admin2_id = row[CSVEntry.ADMIN2_ID] place.admin1_id = row[CSVEntry.ADMIN1_ID] place.admin1_name = str(geodata.geo_files.geodb.get_admin1_name(place)) place.admin2_name = str(geodata.geo_files.geodb.get_admin2_name(place)) if place.admin2_name is None: place.admin2_name = '' if place.admin1_name is None: place.admin1_name = '' tokens = place.original_entry.split(',') if len(tokens) > 3: place.city1 = tokens[-4] if len(tokens) > 4: place.prefix = tokens[-5] place.id = row[CSVEntry.PLACE_ID]
def _set_CSV_place_type(place: Loc.Loc): place.set_place_type() if len(place.prefix) > 0: place.place_type = Loc.PlaceType.PREFIX
def display_result(self, place: Loc.Loc): """ Display result details for a town entry Enable buttons so user can either click Skip, or edit the item and Click Verify. Args: place: Returns: None """ place.set_types_as_string() place.status = f'{place.result_type_text} {self.result_text_list.get(place.result_type)} ' TKHelper.enable_buttons(self.w.review_buttons) # Enable action buttons based on type of result if place.result_type == GeoUtil.Result.MULTIPLE_MATCHES or \ place.result_type == GeoUtil.Result.NO_MATCH or \ place.result_type == GeoUtil.Result.NO_COUNTRY: # Result requires user action # Disable the Save & Map button until an item is found. Set Verify as preferred button self.set_save_button_allowed(False) TKHelper.set_preferred_button(self.w.verify_button, self.w.review_buttons, "Preferred.TButton") elif place.result_type == GeoUtil.Result.NOT_SUPPORTED: # Country Not supported - set Skip as preferred button TKHelper.set_preferred_button(self.w.skip_button, self.w.review_buttons, "Preferred.TButton") else: # Found a match - enable save. Set Save as preferred button self.set_save_button_allowed(True) # Enable save button TKHelper.set_preferred_button(self.w.save_button, self.w.review_buttons, "Preferred.TButton") # Display status and color based on success self.set_status_text(place.get_status()) if place.result_type in GeoUtil.successful_match: if place.place_type == Loc.PlaceType.CITY: self.w.status.configure(style="Good.TLabel") else: self.w.status.configure(style="GoodCounty.TLabel") else: self.w.status.configure(style="Error.TLabel") # If more than one result, set Verify as preferred button # TODO - clean this up so we don't have multiple mechanisms to set status if len(place.georow_list) > 1: TKHelper.set_preferred_button(self.w.verify_button, self.w.review_buttons, "Preferred.TButton") self.set_save_button_allowed(False) if len(place.georow_list) > 0: # Display matches in listbox self.w.tree.focus() # Set focus to listbox self.display_georow_list(place) else: # No matches self.w.user_entry.focus() # Set focus to text edit widget self.display_one_georow(place.status_detail, place.geoid, score=9999, feat='') # Display GEDCOM person and event that this location refers to self.w.ged_event_info.text = f'{self.ancestry_file_handler.get_name(self.ancestry_file_handler.id)}: ' \ f'{self.ancestry_file_handler.event_name} {self.ancestry_file_handler.date}' self.w.root.update_idletasks()