11from geograpy .locator import LocationContext , Location , City , Country , Region
2- from openresearch .event import Event
32from smw .pagefixer import PageFixerManager
43from ormigrate .fixer import ORFixer
5- from smw .rating import Rating , RatingType
4+ from smw .rating import Rating , RatingType , EntityRating
65
76
87class LocationFixer (ORFixer ):
@@ -23,41 +22,21 @@ def __init__(self,pageFixerManager):
2322 '''
2423 super (LocationFixer , self ).__init__ (pageFixerManager )
2524 LocationFixer .locationContext = self .getORLocationContext ()
26-
27- def fixEventRecords (self , events :list ):
28- """
29- Gets list of dicts (list of events) and tries to fix the location entries
30- """
31- count = 0
32- stats = {}
33- for event_unfixed in events :
34- event , errors = self .fixEventRecord (event_unfixed )
35- print (errors )
36- if errors is not None :
37- for error in errors .keys ():
38- if error in stats :
39- stats [error ]+= 1
40- else :
41- stats [error ]= 1
42- print (stats )
4325
44- def fixEvents (self , events : list ):
26+ def fix (self ,rating : EntityRating ):
4527 '''
46- fixes the location of the given events
47-
48- Args:
49- events(list): list of Event objects that should be fixed
28+ tries fixing the location entries of the given entity
5029 '''
51- for event in events :
52- self .fixEvent ( event )
30+ eventRecord = rating . getRecord ()
31+ self .fixEventRecord ( eventRecord )
5332
54- def fixEvent (self , event :Event ):
33+ def fixEventRecord (self , event :dict , errors : dict = None , bestFit = True ):
5534 '''
56- fixes the location of the given event
35+ Args:
36+ event(dict): event records containing the location values that should be fixed
37+ errors(dict): dictonary containing the errors of the given event record → new errors are added to the dict
38+ bestFit(bool): If true the best/closed fit for a location is chosen (e.g. city with highest population). Otherwise a fix is only applied if the location can be identified with certainty.
5739 '''
58- self .fixEventRecord (event .__dict__ )
59-
60- def fixEventRecord (self , event :dict , errors = None ):
6140 # event location values
6241 if errors is None :
6342 errors = {}
@@ -115,21 +94,22 @@ def fixEventRecord(self, event:dict, errors=None):
11594 cities = list (filter (
11695 lambda x : 'wikidataid' in x .country .__dict__ and x .country .wikidataid in countryids ,
11796 cities ))
118- if len (cities ) == 1 :
97+ if len (cities ) > 0 :
11998 # city can be identified (Could still be incorrect)
120- final_city = cities [0 ]
99+ if len (cities ) > 1 :
100+ errors ["city_unclear" ] = f"City '{ event_city } ' matches against multiple cities in the LocationCorpus. Other location information are not sufficient enough to clearly identify the city"
101+ cities = sorted (cities ,key = lambda city :0 if 'population' not in city .__dict__ or city .population is None else int (city .population ), reverse = True )
102+ final_city = cities [0 ]
121103 if isinstance (final_city ,City ):
122104 event [self .CITY ]= self .getPageTitle (final_city )
123105 event [self .REGION ] = self .getPageTitle (final_city .region )
124106 event [self .COUNTRY ] = self .getPageTitle (final_city .country )
125107 errors ["complete" ]= "Location of event complete"
126108 return event , errors
127- elif len ( cities ) == 0 :
109+ else :
128110 # No matching city -> Two possibilities: event location information incorrect or locations missing in LocationCorpus
129111 errors ["city_unknown" ]= f"City '{ event_city } ' could not be matched against a city in the LocationCorpus with the given region and country. Either location information are incorrect or location is missing in the corpus."
130112 #return None, errors
131- else :
132- errors ["city_unclear" ]= f"City '{ event_city } ' matches against multiple cities in the LocationCorpus. Other location information are not sufficient enough to clearly identify the city"
133113 else :
134114 # event_city is not the LocationCorpus
135115 isPossiblyMisplaced = True
@@ -314,11 +294,17 @@ def getPageTitle(location:Location):
314294 pageTitle = location .name
315295 return pageTitle
316296
317- @ classmethod
318- def getRating ( cls , eventRecord ):
297+
298+ def rate ( self , rating : EntityRating ):
319299 '''
320300 get the pain Rating for the given eventRecord
321301 '''
302+ eventRecord = rating .getRecord ()
303+ arating = self .getRating (eventRecord )
304+ rating .set (arating .pain , arating .reason , arating .hint )
305+
306+ @classmethod
307+ def getRating (cls , eventRecord ):
322308 painrating = None
323309 city = None
324310 region = None
@@ -329,24 +315,24 @@ def getRating(cls, eventRecord):
329315 if cls .COUNTRY in eventRecord : country = eventRecord [cls .COUNTRY ]
330316 if not city and not region and not country :
331317 # location is not defined
332- painrating = Rating (7 , RatingType .missing ,f'Locations are not defined' )
318+ painrating = Rating (7 , RatingType .missing ,f'Locations are not defined' )
333319 else :
334320 if 'locationContext' in cls .__dict__ :
335321 cities = cls .__dict__ ['locationContext' ].getCities (city )
336322 regions = cls .__dict__ ['locationContext' ].getCities (region )
337323 countries = cls .__dict__ ['locationContext' ].getCities (country )
338324 if cities and regions and countries :
339325 # all locations are recognized
340- painrating = Rating (1 ,RatingType .ok ,f'Locations are valid. (Country: { country } , Region: { region } , City:{ city } )' )
326+ painrating = Rating (1 ,RatingType .ok ,f'Locations are valid. (Country: { country } , Region: { region } , City:{ city } )' )
341327 elif not cities :
342328 # City is not valid
343- painrating = Rating (6 , RatingType .invalid ,f'City is not recognized. (City:{ city } )' )
329+ painrating = Rating (6 , RatingType .invalid ,f'City is not recognized. (City:{ city } )' )
344330 elif not regions :
345331 # City is valid but region is not
346- painrating = Rating (5 , RatingType .invalid ,f'Region is not recognized. (Country: { country } , Region: { region } , City:{ city } )' )
332+ painrating = Rating (5 , RatingType .invalid ,f'Region is not recognized. (Country: { country } , Region: { region } , City:{ city } )' )
347333 else :
348334 # City and region are valid but country is not
349- painrating = Rating (3 , RatingType .invalid ,f'Country is not recognized. (Country: { country } , Region: { region } , City:{ city } )' )
335+ painrating = Rating (3 , RatingType .invalid ,f'Country is not recognized. (Country: { country } , Region: { region } , City:{ city } )' )
350336 return painrating
351337
352338 @staticmethod
0 commit comments