Beispiel #1
0
    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
Beispiel #2
0
    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')
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
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]
Beispiel #6
0
def _set_CSV_place_type(place: Loc.Loc):
    place.set_place_type()
    if len(place.prefix) > 0:
        place.place_type = Loc.PlaceType.PREFIX
Beispiel #7
0
    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()