Beispiel #1
0
    def process_chronology(self):
        """ sets the aggregatin depth for
            aggregating geospatial tiles

            aggregation depth varies between 3 and 20
            with 20 being the most fine-grain, specific
            level of spatial depth
        """
        if isinstance(self.chrono_pivot, list):
            for proj in self.chrono_pivot:
                project_key = proj['value']
                if project_key not in self.projects:
                    self.projects[project_key] = {}
                min_date = False
                max_date = False
                if 'pivot' in proj:
                    for chrono_data in proj['pivot']:
                        chrono_t = ChronoTile()
                        dates = chrono_t.decode_path_dates(
                            chrono_data['value'])
                        if isinstance(dates, dict):
                            if min_date is False:
                                min_date = dates['earliest_bce']
                                max_date = dates['latest_bce']
                            else:
                                if min_date > dates['earliest_bce']:
                                    min_date = dates['earliest_bce']
                                if max_date < dates['latest_bce']:
                                    max_date = dates['latest_bce']
                self.projects[project_key]['min_date'] = min_date
                self.projects[project_key]['max_date'] = max_date
Beispiel #2
0
 def decode_event_path(self, event_path):
     """ decodes an event path, with
         chrono_path tiles as the first
         two characters of each level, with
         the geo tile as the last character
     """
     chrono_prefix = ''
     if self.CHRONO_PREFIX_EVENT_SEP in event_path:
         event_ex = event_path.split(self.CHRONO_PREFIX_EVENT_SEP)
         chrono_prefix = event_ex[0]
         event_path = event_ex[1]
     event_path_list = event_path.split(self.LEVEL_DELIM)
     chrono_path = ''
     geo_path = ''
     for event_tile in event_path_list:
         chrono_path = self.add_to_path(event_tile[0], chrono_path,
                                        self.CHRONO_TILE_DEPTH)
         chrono_path = self.add_to_path(event_tile[1], chrono_path,
                                        self.CHRONO_TILE_DEPTH)
         geo_path = self.add_to_path(event_tile[2], geo_path,
                                     self.GEO_TILE_DEPTH)
     chrono_path = chrono_prefix + chrono_path
     ch = ChronoTile()
     gm = GlobalMercator()
     output = {
         'chrono_path': chrono_path,
         'chrono': ch.decode_path_dates(chrono_path),
         'geo_path': geo_path,
         'geo': gm.quadtree_to_lat_lon(geo_path)
     }
     return output
Beispiel #3
0
 def decode_event_path(self, event_path):
     """ decodes an event path, with
         chrono_path tiles as the first
         two characters of each level, with
         the geo tile as the last character
     """
     chrono_prefix = ''
     if self.CHRONO_PREFIX_EVENT_SEP in event_path:
         event_ex = event_path.split(self.CHRONO_PREFIX_EVENT_SEP)
         chrono_prefix = event_ex[0]
         event_path = event_ex[1]
     event_path_list = event_path.split(self.LEVEL_DELIM)
     chrono_path = ''
     geo_path = ''
     for event_tile in event_path_list:
         chrono_path = self.add_to_path(event_tile[0],
                                        chrono_path,
                                        self.CHRONO_TILE_DEPTH)
         chrono_path = self.add_to_path(event_tile[1],
                                        chrono_path,
                                        self.CHRONO_TILE_DEPTH)
         geo_path = self.add_to_path(event_tile[2],
                                     geo_path,
                                     self.GEO_TILE_DEPTH)
     chrono_path = chrono_prefix + chrono_path
     ch = ChronoTile()
     gm = GlobalMercator()
     output = {'chrono_path': chrono_path,
               'chrono': ch.decode_path_dates(chrono_path),
               'geo_path': geo_path,
               'geo': gm.quadtree_to_lat_lon(geo_path)}
     return output
    def process_chronology(self):
        """ sets the aggregatin depth for
            aggregating geospatial tiles

            aggregation depth varies between 3 and 20
            with 20 being the most fine-grain, specific
            level of spatial depth
        """
        if isinstance(self.chrono_pivot, list):
            for proj in self.chrono_pivot:
                project_key = proj['value']
                if project_key not in self.projects:
                    self.projects[project_key] = {}
                min_date = False
                max_date = False
                if 'pivot' in proj:
                    for chrono_data in proj['pivot']:
                        chrono_t = ChronoTile()
                        dates = chrono_t.decode_path_dates(chrono_data['value'])
                        if isinstance(dates, dict):
                            if min_date is False:
                                min_date = dates['earliest_bce']
                                max_date = dates['latest_bce']
                            else:
                                if min_date > dates['earliest_bce']:
                                    min_date = dates['earliest_bce']
                                if max_date < dates['latest_bce']:
                                    max_date = dates['latest_bce']
                self.projects[project_key]['min_date'] = min_date
                self.projects[project_key]['max_date'] = max_date
Beispiel #5
0
 def encode_path_from_geo_chrono(self,
                                 lat,
                                 lon,
                                 latest_bce_ce,
                                 earliest_bce_ce,
                                 chrono_prefix=''):
     """ encodes an event path from numeric lat, lon, and date values """
     gm = GlobalMercator()
     geo_path = gm.lat_lon_to_quadtree(lat, lon)
     ch = ChronoTile()
     chrono_path = ch.encode_path_from_bce_ce(latest_bce_ce, earliest_bce_ce, chrono_prefix)
     return self.encode_path_from_geo_chrono_paths(geo_path, chrono_path)
Beispiel #6
0
 def encode_path_from_geo_chrono(self,
                                 lat,
                                 lon,
                                 latest_bce_ce,
                                 earliest_bce_ce,
                                 chrono_prefix=''):
     """ encodes an event path from numeric lat, lon, and date values """
     gm = GlobalMercator()
     geo_path = gm.lat_lon_to_quadtree(lat, lon)
     ch = ChronoTile()
     chrono_path = ch.encode_path_from_bce_ce(latest_bce_ce,
                                              earliest_bce_ce,
                                              chrono_prefix)
     return self.encode_path_from_geo_chrono_paths(geo_path, chrono_path)
Beispiel #7
0
def get_form_use_life_chronotile_query_dict(raw_chrono_tile):
    """Makes a filter query for formation-use-life chrono-tile string"""
    return make_tile_query_dict(
        raw_tile_path=raw_chrono_tile,
        solr_field='form_use_life_chrono_tile',
        max_path_length=ChronoTile().MAX_TILE_DEPTH,
    )
Beispiel #8
0
 def _process_chrono(self):
     """ Finds chronological / date ranges in GeoJSON features for indexing.
     More than 1 date range per item is OK.
     """
     self.chrono_specified = False
     if 'features' in self.oc_item.json_ld:
         for feature in self.oc_item.json_ld['features']:
             bad_time = False
             try:
                 # time is in ISO 8601 time
                 iso_start = feature['when']['start']
             except KeyError:
                 bad_time = True
             try:
                 # time is in ISO 8601 time
                 iso_stop = feature['when']['stop']
             except KeyError:
                 bad_time = True
             try:
                 when_type = feature['when']['type']
             except KeyError:
                 when_type = False
             try:
                 ref_type = feature['when']['reference-type']
                 if ref_type == 'specified':
                     self.chrono_specified = True
             except KeyError:
                 ref_type = False
             if when_type == 'oc-gen:formation-use-life' \
                     and bad_time is False:
                 # convert GeoJSON-LD ISO 8601 to numeric
                 start = ISOyears().make_float_from_iso(iso_start)
                 stop = ISOyears().make_float_from_iso(iso_stop)
                 chrono_tile = ChronoTile()
                 if 'form_use_life_chrono_tile' not in self.fields:
                     self.fields['form_use_life_chrono_tile'] = []
                 if 'form_use_life_chrono_earliest' not in self.fields:
                     self.fields['form_use_life_chrono_earliest'] = []
                 if 'form_use_life_chrono_latest' not in self.fields:
                     self.fields['form_use_life_chrono_latest'] = []
                 self.fields['form_use_life_chrono_tile'].append(
                     chrono_tile.encode_path_from_bce_ce(
                         start, stop, '10M-'
                         )
                     )
                 self.fields['form_use_life_chrono_earliest'].append(start)
                 self.fields['form_use_life_chrono_latest'].append(stop)
 def _process_chrono(self):
     """ Finds chronological / date ranges in GeoJSON features for indexing.
     More than 1 date range per item is OK.
     """
     self.chrono_specified = False
     if "features" in self.oc_item.json_ld:
         for feature in self.oc_item.json_ld["features"]:
             bad_time = False
             try:
                 # time is in ISO 8601 time
                 iso_start = feature["when"]["start"]
             except KeyError:
                 bad_time = True
             try:
                 # time is in ISO 8601 time
                 iso_stop = feature["when"]["stop"]
             except KeyError:
                 bad_time = True
             try:
                 when_type = feature["when"]["type"]
             except KeyError:
                 when_type = False
             try:
                 ref_type = feature["when"]["reference-type"]
                 if ref_type == "specified":
                     self.chrono_specified = True
             except KeyError:
                 ref_type = False
             if when_type == "oc-gen:formation-use-life" and bad_time is False:
                 # convert GeoJSON-LD ISO 8601 to numeric
                 start = ISOyears().make_float_from_iso(iso_start)
                 stop = ISOyears().make_float_from_iso(iso_stop)
                 chrono_tile = ChronoTile()
                 if "form_use_life_chrono_tile" not in self.fields:
                     self.fields["form_use_life_chrono_tile"] = []
                 if "form_use_life_chrono_earliest" not in self.fields:
                     self.fields["form_use_life_chrono_earliest"] = []
                 if "form_use_life_chrono_latest" not in self.fields:
                     self.fields["form_use_life_chrono_latest"] = []
                 self.fields["form_use_life_chrono_tile"].append(
                     chrono_tile.encode_path_from_bce_ce(start, stop, "10M-")
                 )
                 self.fields["form_use_life_chrono_earliest"].append(start)
                 self.fields["form_use_life_chrono_latest"].append(stop)
Beispiel #10
0
 def encode_path_from_geo_chrono_paths(self, geo_path, chrono_path):
     """
     encodes a path bringing together a geo_path and a chrono_path
     """
     chrono_prefix = ''
     if ChronoTile().PREFIX_DELIM in chrono_path:
         # get the range prefix for the chrono_path,
         # and remove it from the path
         cpathex = chrono_path.split(ChronoTile().PREFIX_DELIM)
         chrono_prefix = cpathex[0]
         chrono_prefix += ChronoTile().PREFIX_DELIM
         chrono_path = cpathex[1]
     c_path_len = len(chrono_path)
     g_path_len = len(geo_path)
     event_levels = c_path_len / 2
     if event_levels < g_path_len:
         event_levels = g_path_len
     event_path_list = []
     chrono_i = 0
     geo_i = 0
     while len(event_path_list) < event_levels:
         if chrono_i < c_path_len:
             ctile_a = chrono_path[chrono_i]
         else:
             ctile_a = '0'
         if (chrono_i + 1) < c_path_len:
             ctile_b = chrono_path[chrono_i + 1]
         else:
             ctile_b = '0'
         chrono_i += 2
         if geo_i < g_path_len:
             geo_tile = geo_path[geo_i]
         else:
             geo_tile = '0'
         geo_i += 1
         event_tile = ctile_a + ctile_b + geo_tile
         event_path_list.append(event_tile)
     event_path = chrono_prefix + self.CHRONO_PREFIX_EVENT_SEP + self.LEVEL_DELIM.join(
         event_path_list)
     return event_path
Beispiel #11
0
 def _make_valid_options_tile_dicts(self, options_tuples):
     """Makes a list of valid tile_dicts from a list of options_tuples"""
     valid_tile_dicts = []
     for tile, count in options_tuples:
         if (self.limiting_tile is not None
             and not tile.startswith(self.limiting_tile)):
             # We're looking only for tiles within a limiting
             # tile, and the current tile is not within that.
             # So skip.
             continue
         # Parse the tile to get date ranges.
         chrono_t = ChronoTile()
         tile_dict = chrono_t.decode_path_dates(tile)
         if not isinstance(tile_dict, dict):
             # Not a valid data for some awful reason.
             continue
         if (self.exclude_before is not None 
             and tile_dict['earliest_bce'] < self.exclude_before):
             # The date range is too early.
             continue
         if (self.exclude_after is not None 
             and tile_dict['latest_bce'] > self.exclude_after):
             # The date range is too late.
             continue
         if self.min_date is None:
             self.min_date = tile_dict['earliest_bce']
         if self.max_date is None:
             self.max_date = tile_dict['latest_bce']
         if self.min_date > tile_dict['earliest_bce']:
             self.min_date = tile_dict['earliest_bce']
         if self.max_date < tile_dict['latest_bce']:
             self.max_date = tile_dict['latest_bce']
         tile_dict['tile_key'] = tile
         tile_dict['count'] = count
         valid_tile_dicts.append(tile_dict)
     return valid_tile_dicts
Beispiel #12
0
 def add_filters_json(self, request_dict):
     """ adds JSON describing search filters """
     fl = FilterLinks()
     fl.base_search_link = self.base_search_link
     filters = []
     string_fields = []  # so we have an interface for string searches
     i = 0
     for param_key, param_vals in request_dict.items():
         if param_key == 'path':
             if param_vals:
                 i += 1
                 f_entity = self.m_cache.get_entity(param_vals)
                 label = http.urlunquote_plus(param_vals)
                 act_filter = LastUpdatedOrderedDict()
                 act_filter['id'] = '#filter-' + str(i)
                 act_filter['oc-api:filter'] = 'Context'
                 act_filter['label'] = label.replace('||', ' OR ')
                 if f_entity:
                     act_filter['rdfs:isDefinedBy'] = f_entity.uri
                 # generate a request dict without the context filter
                 rem_request = fl.make_request_sub(request_dict,
                                                   param_key,
                                                   param_vals)
                 act_filter['oc-api:remove'] = fl.make_request_url(rem_request)
                 act_filter['oc-api:remove-json'] = fl.make_request_url(rem_request, '.json')
                 filters.append(act_filter)
         else:
             for param_val in param_vals:
                 i += 1
                 remove_geodeep = False
                 act_filter = LastUpdatedOrderedDict()
                 act_filter['id'] = '#filter-' + str(i)
                 if self.hierarchy_delim in param_val:
                     all_vals = param_val.split(self.hierarchy_delim)
                 else:
                     all_vals = [param_val]
                 if param_key == 'proj':
                     # projects, only care about the last item in the parameter value
                     act_filter['oc-api:filter'] = 'Project'
                     label_dict = self.make_filter_label_dict(all_vals[-1])
                     act_filter['label'] = label_dict['label']
                     if len(label_dict['entities']) == 1:
                         act_filter['rdfs:isDefinedBy'] = label_dict['entities'][0].uri
                 elif param_key == 'prop':
                     # prop, the first item is the filter-label
                     # the last is the filter
                     act_filter['label'] = False
                     if len(all_vals) < 2:
                         act_filter['oc-api:filter'] = 'Description'
                         act_filter['oc-api:filter-slug'] = all_vals[0]
                     else:
                         filt_dict = self.make_filter_label_dict(all_vals[0])
                         act_filter['oc-api:filter'] = filt_dict['label']
                         if 'slug' in filt_dict:
                             act_filter['oc-api:filter-slug'] = filt_dict['slug']
                         if filt_dict['data-type'] == 'string':
                             act_filter['label'] = 'Search Term: \'' + all_vals[-1] + '\''
                     if act_filter['label'] is False:
                         label_dict = self.make_filter_label_dict(all_vals[-1])
                         act_filter['label'] = label_dict['label']
                 elif param_key == 'type':
                     act_filter['oc-api:filter'] = 'Open Context Type'
                     if all_vals[0] in QueryMaker.TYPE_MAPPINGS:
                         type_uri = QueryMaker.TYPE_MAPPINGS[all_vals[0]]
                         label_dict = self.make_filter_label_dict(type_uri)
                         act_filter['label'] = label_dict['label']
                     else:
                         act_filter['label'] = all_vals[0]
                 elif param_key == 'q':
                     act_filter['oc-api:filter'] = self.TEXT_SEARCH_TITLE
                     act_filter['label'] = 'Search Term: \'' + all_vals[0] + '\''
                 elif param_key == 'id':
                     act_filter['oc-api:filter'] = 'Identifier Lookup'
                     act_filter['label'] = 'Identifier: \'' + all_vals[0] + '\''
                 elif param_key == 'form-chronotile':
                     act_filter['oc-api:filter'] = 'Time of formation, use, or life'
                     chrono = ChronoTile()
                     dates = chrono.decode_path_dates(all_vals[0])
                     if isinstance(dates, dict):
                         act_filter['label'] = 'Time range: ' + str(dates['earliest_bce'])
                         act_filter['label'] += ' to ' + str(dates['latest_bce'])
                 elif param_key == 'form-start':
                     act_filter['oc-api:filter'] = 'Earliest formation, use, or life date'
                     try:
                         val_date = int(float(all_vals[0]))
                     except:
                         val_date = False
                     if val_date is False:
                         act_filter['label'] = '[Invalid year]'
                     elif val_date < 0:
                         act_filter['label'] = str(val_date * -1) + ' BCE'
                     else:
                         act_filter['label'] = str(val_date) + ' CE'
                 elif param_key == 'form-stop':
                     act_filter['oc-api:filter'] = 'Latest formation, use, or life date'
                     try:
                         val_date = int(float(all_vals[0]))
                     except:
                         val_date = False
                     if val_date is False:
                         act_filter['label'] = '[Invalid year]'
                     elif val_date < 0:
                         act_filter['label'] = str(val_date * -1) + ' BCE'
                     else:
                         act_filter['label'] = str(val_date) + ' CE'
                 elif param_key == 'disc-geotile':
                     act_filter['oc-api:filter'] = 'Location of discovery or observation'
                     act_filter['label'] = self.make_geotile_filter_label(all_vals[0])
                     remove_geodeep = True
                 elif param_key == 'disc-bbox':
                     act_filter['oc-api:filter'] = 'Location of discovery or observation'
                     act_filter['label'] = self.make_bbox_filter_label(all_vals[0])
                     remove_geodeep = True
                 elif param_key == 'images':
                     act_filter['oc-api:filter'] = 'Has related media'
                     act_filter['label'] = 'Linked to images'
                 elif param_key == 'other-media':
                     act_filter['oc-api:filter'] = 'Has related media'
                     act_filter['label'] = 'Linked to media (other than images)'
                 elif param_key == 'documents':
                     act_filter['oc-api:filter'] = 'Has related media'
                     act_filter['label'] = 'Linked to documents'
                 elif param_key == 'dc-subject':
                     act_filter['oc-api:filter'] = 'Has subject metadata'
                     label_dict = self.make_filter_label_dict(all_vals[-1])
                     if len(label_dict['label']) > 0:
                         act_filter['label'] = label_dict['label']
                     if 'tdar' == all_vals[-1] or 'tdar*' == all_vals[-1]:
                         act_filter['label'] = 'tDAR defined metadata record(s)'
                     if len(label_dict['entities']) == 1:
                         act_filter['rdfs:isDefinedBy'] = label_dict['entities'][0].uri
                         if label_dict['entities'][0].vocabulary is not False:
                             act_filter['label'] += ' in ' + label_dict['entities'][0].vocabulary
                 elif param_key == 'dc-spatial':
                     act_filter['oc-api:filter'] = 'Has spatial metadata'
                     label_dict = self.make_filter_label_dict(all_vals[-1])
                     if len(label_dict['label']) > 0:
                         act_filter['label'] = label_dict['label']
                     if len(label_dict['entities']) == 1:
                         act_filter['rdfs:isDefinedBy'] = label_dict['entities'][0].uri
                         if label_dict['entities'][0].vocabulary is not False:
                             act_filter['label'] += ' in ' + label_dict['entities'][0].vocabulary
                 elif param_key == 'dc-coverage':
                     act_filter['oc-api:filter'] = 'Has coverage / period metadata'
                     label_dict = self.make_filter_label_dict(all_vals[-1])
                     if len(label_dict['label']) > 0:
                         act_filter['label'] = label_dict['label']
                     if len(label_dict['entities']) == 1:
                         act_filter['rdfs:isDefinedBy'] = label_dict['entities'][0].uri
                         if label_dict['entities'][0].vocabulary is not False:
                             act_filter['label'] += ' in ' + label_dict['entities'][0].vocabulary
                 elif param_key == 'dc-temporal':
                     act_filter['oc-api:filter'] = 'Has temporal coverage'
                     label_dict = self.make_filter_label_dict(all_vals[-1])
                     if len(label_dict['label']) > 0:
                         act_filter['label'] = label_dict['label']
                         if len(label_dict['entities']) == 1: 
                             if label_dict['entities'][0].entity_type == 'vocabulary':
                                 act_filter['label'] = 'Concepts defined by: ' + label_dict['label']
                         elif 'periodo' in all_vals[-1]:
                             act_filter['label'] = 'PeriodO defined concepts'
                     if len(label_dict['entities']) == 1:
                         act_filter['rdfs:isDefinedBy'] = label_dict['entities'][0].uri
                         if label_dict['entities'][0].vocabulary is not False\
                            and label_dict['entities'][0].vocabulary != label_dict['label']:
                             act_filter['label'] += ' in ' + label_dict['entities'][0].vocabulary
                 elif param_key == 'obj':
                     act_filter['oc-api:filter'] = 'Links (in some manner) to object'
                     label_dict = self.make_filter_label_dict(all_vals[-1])
                     if len(label_dict['label']) > 0:
                         act_filter['label'] = label_dict['label']
                     if len(label_dict['entities']) == 1:
                         act_filter['rdfs:isDefinedBy'] = label_dict['entities'][0].uri
                         if label_dict['entities'][0].vocabulary is not False:
                             act_filter['label'] += ' in ' + label_dict['entities'][0].vocabulary
                 elif param_key == 'dc-isReferencedBy':
                     act_filter['oc-api:filter'] = 'Is referenced by'
                     label_dict = self.make_filter_label_dict(all_vals[-1])
                     if len(label_dict['label']) > 0:
                         act_filter['label'] = label_dict['label']
                     if len(label_dict['entities']) == 1:
                         act_filter['rdfs:isDefinedBy'] = label_dict['entities'][0].uri
                         if label_dict['entities'][0].vocabulary is not False\
                            and label_dict['entities'][0].vocab_uri != label_dict['entities'][0].uri:
                             act_filter['label'] += ' in ' + label_dict['entities'][0].vocabulary
                 elif param_key == 'linked' and all_vals[-1] == 'dinaa-cross-ref':
                     act_filter['oc-api:filter'] = 'Has cross references'
                     act_filter['label'] = 'Links to, or with, DINAA curated site files'
                 else:
                     act_filter = False
                 if act_filter is not False:
                     rem_request = fl.make_request_sub(request_dict,
                                                       param_key,
                                                       param_val)
                     if 'geodeep' in rem_request and remove_geodeep:
                         rem_request.pop('geodeep', None)    
                     act_filter['oc-api:remove'] = fl.make_request_url(rem_request)
                     act_filter['oc-api:remove-json'] = fl.make_request_url(rem_request, '.json')
                     filters.append(act_filter)
     return filters
Beispiel #13
0
    def make_chronology_facet_options(self, solr_json):
        """Makes chronology facets from a solr_json response""" 
        chrono_path_keys = (
            configs.FACETS_SOLR_ROOT_PATH_KEYS 
            + ['form_use_life_chrono_tile']
        )
        chrono_val_count_list = utilities.get_dict_path_value(
            chrono_path_keys,
            solr_json,
            default=[]
        )
        if not len(chrono_val_count_list):
            return None
        options_tuples = utilities.get_facet_value_count_tuples(
            chrono_val_count_list
        )
        if not len(options_tuples):
            return None
        
        # Check to see if the client included any request parameters
        # that limited the chronological range of the request.
        self._set_client_earliest_latest_limits()
        
        valid_tile_dicts = self._make_valid_options_tile_dicts(
            options_tuples
        )
        if not len(valid_tile_dicts):
            # None of the chronological tiles are valid
            # given the query requirements.
            return None

        # Determine the aggregation depth needed to group chronological
        # tiles together into a reasonable number of options.
        self._get_tile_aggregation_depth(valid_tile_dicts)

        aggregate_tiles = {}
        for tile_dict in valid_tile_dicts:
            # Now aggregate the tiles.
            trim_tile_key = tile_dict['tile_key'][:self.default_aggregation_depth]
            if trim_tile_key not in aggregate_tiles:
                # Make the aggregate tile dictionary
                # object.
                chrono_t = ChronoTile()
                agg_dict = chrono_t.decode_path_dates(trim_tile_key)
                if (self.min_date is not None 
                    and agg_dict['earliest_bce'] < self.min_date):
                    # The aggregated date range looks too early, so
                    # set it to the earliest allowed.
                    agg_dict['earliest_bce'] = self.min_date
                if (self.max_date is not None 
                    and agg_dict['latest_bce'] > self.max_date):
                    # The aggregated date range looks too late, so
                    # set it to the latest date range allowed.
                    agg_dict['latest_bce'] = self.max_date
                agg_dict['tile_key'] = trim_tile_key
                agg_dict['count'] = 0
                aggregate_tiles[trim_tile_key] = agg_dict

            aggregate_tiles[trim_tile_key]['count'] += tile_dict['count']


        agg_tile_list = [tile_dict for _, tile_dict in aggregate_tiles.items()]
        
        # Now sort by earliest bce, then reversed latest bce
        # this makes puts early dates with longest timespans first
        sorted_agg_tiles = sorted(
            agg_tile_list,
            key=lambda k: (k['earliest_bce'], -k['latest_bce'])
        )

        options = []
        for tile_dict in sorted_agg_tiles:
            sl = SearchLinks(
                request_dict=copy.deepcopy(self.request_dict),
                base_search_url=self.base_search_url
            )
            # Remove non search related params.
            sl.remove_non_query_params()

            # Update the request dict for this facet option.
            sl.replace_param_value(
                'form-chronotile',
                match_old_value=None,
                new_value=tile_dict['tile_key'],
            )
            sl.replace_param_value(
                'form-start',
                match_old_value=None,
                new_value=tile_dict['earliest_bce'],
            )
            sl.replace_param_value(
                'form-stop',
                match_old_value=None,
                new_value=tile_dict['latest_bce'],
            )  
            urls = sl.make_urls_from_request_dict()
            if urls['html'] == self.current_filters_url:
                # The new URL matches our current filter
                # url, so don't add this facet option.
                continue

            option = LastUpdatedOrderedDict()
            option['id'] = urls['html']
            option['json'] = urls['json']
            option['count'] = tile_dict['count']
            option['category'] = 'oc-api:chrono-facet'
            option['start'] = ISOyears().make_iso_from_float(
                tile_dict['earliest_bce']
            )
            option['stop'] = ISOyears().make_iso_from_float(
                tile_dict['latest_bce']
            )
            properties = LastUpdatedOrderedDict()
            properties['early bce/ce'] = tile_dict['earliest_bce']
            properties['late bce/ce'] = tile_dict['latest_bce']
            option['properties'] = properties
            options.append(option)

        return options
Beispiel #14
0
 def __init__(self):
     self.CHRONO_TILE_DEPTH = ChronoTile().MAX_TILE_DEPTH
     self.GEO_TILE_DEPTH = GlobalMercator().MAX_ZOOM
     self.LEVEL_DELIM = '-'  # so as not to get confused with the chrono-path '-' prefix
     self.CHRONO_PREFIX_EVENT_SEP = 'e-'
Beispiel #15
0
    def add_non_hierarchy_filter_json(
        self,
        param_key,
        act_val,
        act_filter,
        param_config,
        request_dict,
    ):
        """Adds JSON for non-hierarchy filters.
        
        :param str param_key: Client request query parameter
        :param str act_val: URL unquoted client request 
            search value
        :param dict act_filter: Dictionary describing the
            search filter associated with the param_key 
            and act_val.
        :param dict param_config: Configuration dictionary 
            for translating the param_key and act_val into
            an act_filter.
        :param dict request_dict: Dictionary object of the GET
            request from the client. 
        """

        if param_config.get('label'):
            act_filter['label'] = param_config['label']
        elif param_config.get('label-template'):
            act_filter['label'] = param_config['label-template'].format(
                act_val=act_val)

        if param_key in ['form-start', 'form-stop']:
            # Case for filters on years.
            act_date = utilities.string_to_int(act_val)
            if act_date is None:
                act_filter['label'] = 'Invalid year. Must be integer value'
            elif act_date < 0:
                act_filter['label'] = '{} BCE'.format(act_date)
            else:
                act_filter['label'] = '{} CE'.format(act_date)

        elif param_key == 'form-chronotile':
            chrono = ChronoTile()
            dates = chrono.decode_path_dates(act_val)
            if isinstance(dates, dict):
                act_filter['label'] = 'Time range: {} to {}'.format(
                    dates['earliest_bce'],
                    dates['latest_bce'],
                )
            else:
                act_filter['label'] = 'Invalid chronology encoding'

        elif param_key == 'disc-geotile':
            act_filter['label'] = make_geotile_filter_label(act_val)

        elif param_key == 'disc-bbox':
            act_filter['label'] = make_bbox_filter_label(act_val)

        # Add the removal links.
        act_filter = self.add_links_to_act_filter(
            param_key,
            match_old_value=None,
            new_value=None,
            act_filter=act_filter,
            request_dict=request_dict,
        )
        return act_filter
 def process_solr_tiles(self, solr_tiles):
     """ processes the solr_json 
         discovery geo tiles,
         aggregating to a certain
         depth
     """
     # first aggregate counts for tile that belong togther
     aggregate_tiles = LastUpdatedOrderedDict()
     i = -1
     t = 0
     if len(solr_tiles) <= 10:
         # don't aggregate if there's not much to aggregate
         self.aggregation_depth = self.max_depth
     for tile_key in solr_tiles[::2]:
         t += 1
         i += 2
         solr_facet_count = solr_tiles[i]
         if tile_key != 'false':
             if self.limiting_tile is False:
                 ok_to_add = True
             else:
                 # constrain to show facets ONLY within
                 # the current queried tile
                 if self.limiting_tile in tile_key:
                     ok_to_add = True
                 else:
                     ok_to_add = False
             if ok_to_add:
                 # first get full date range for
                 # facets that are OK to add
                 chrono_t = ChronoTile()
                 dates = chrono_t.decode_path_dates(tile_key)
                 if isinstance(dates, dict):
                     if self.min_date is False:
                         self.min_date = dates['earliest_bce']
                         self.max_date = dates['latest_bce']
                     else:
                         if self.min_date > dates['earliest_bce']:
                             self.min_date = dates['earliest_bce']
                         if self.max_date < dates['latest_bce']:
                             self.max_date = dates['latest_bce']
                 # now aggregrate the OK to use facets
                 trim_tile_key = tile_key[:self.aggregation_depth]
                 if trim_tile_key not in aggregate_tiles:
                     aggregate_tiles[trim_tile_key] = 0
                 aggregate_tiles[trim_tile_key] += solr_facet_count
     # now generate GeoJSON for each tile region
     # print('Chronology tiles: ' + str(t) + ' reduced to ' + str(len(aggregate_tiles)))
     # --------------------------------------------
     # code to sort the list of tiles by start date and time span
     # --------------------------------------------
     sorting_ranges = []
     for tile_key, aggregate_count in aggregate_tiles.items():
         chrono_t = ChronoTile()
         dates = chrono_t.decode_path_dates(tile_key)
         dates['tile_key'] = tile_key
         sorting_ranges.append(dates)
     # now sort by earliest bce, then reversed latest bce
     # this makes puts early dates with longest timespans first
     sorted_ranges = sorted(sorting_ranges,
                            key=lambda k: (k['earliest_bce'],
                                           -k['latest_bce']))
     sorted_tiles = LastUpdatedOrderedDict()
     for sort_range in sorted_ranges:
         tile_key = sort_range['tile_key']
         sorted_tiles[tile_key] = aggregate_tiles[tile_key]
     i = 0
     for tile_key, aggregate_count in sorted_tiles.items():
         i += 1
         fl = FilterLinks()
         fl.base_request_json = self.filter_request_dict_json
         fl.spatial_context = self.spatial_context
         new_rparams = fl.add_to_request('form-chronotile',
                                         tile_key)
         record = LastUpdatedOrderedDict()
         record['id'] = fl.make_request_url(new_rparams)
         record['json'] = fl.make_request_url(new_rparams, '.json')
         record['count'] = aggregate_count
         record['category'] = 'oc-api:chrono-facet'
         chrono_t = ChronoTile()
         dates = chrono_t.decode_path_dates(tile_key)
         # convert numeric to GeoJSON-LD ISO 8601
         record['start'] = ISOyears().make_iso_from_float(dates['earliest_bce'])
         record['stop'] = ISOyears().make_iso_from_float(dates['latest_bce'])
         properties = LastUpdatedOrderedDict()
         properties['early bce/ce'] = dates['earliest_bce']
         properties['late bce/ce'] = dates['latest_bce']
         record['properties'] = properties
         self.chrono_tiles.append(record)
Beispiel #17
0
 def process_solr_tiles(self, solr_tiles):
     """ processes the solr_json 
         discovery geo tiles,
         aggregating to a certain
         depth
     """
     # first aggregate counts for tile that belong togther
     aggregate_tiles = LastUpdatedOrderedDict()
     i = -1
     t = 0
     if len(solr_tiles) <= 10:
         # don't aggregate if there's not much to aggregate
         self.aggregation_depth = self.max_depth
     for tile_key in solr_tiles[::2]:
         t += 1
         i += 2
         solr_facet_count = solr_tiles[i]
         if tile_key != 'false':
             if self.limiting_tile is False:
                 ok_to_add = True
             else:
                 # constrain to show facets ONLY within
                 # the current queried tile
                 if self.limiting_tile in tile_key:
                     ok_to_add = True
                 else:
                     ok_to_add = False
             if ok_to_add:
                 # first get full date range for
                 # facets that are OK to add
                 chrono_t = ChronoTile()
                 dates = chrono_t.decode_path_dates(tile_key)
                 if isinstance(dates, dict):
                     if self.min_date is False:
                         self.min_date = dates['earliest_bce']
                         self.max_date = dates['latest_bce']
                     else:
                         if self.min_date > dates['earliest_bce']:
                             self.min_date = dates['earliest_bce']
                         if self.max_date < dates['latest_bce']:
                             self.max_date = dates['latest_bce']
                 # now aggregrate the OK to use facets
                 trim_tile_key = tile_key[:self.aggregation_depth]
                 if trim_tile_key not in aggregate_tiles:
                     aggregate_tiles[trim_tile_key] = 0
                 aggregate_tiles[trim_tile_key] += solr_facet_count
     # now generate GeoJSON for each tile region
     # print('Chronology tiles: ' + str(t) + ' reduced to ' + str(len(aggregate_tiles)))
     # --------------------------------------------
     # code to sort the list of tiles by start date and time span
     # --------------------------------------------
     sorting_ranges = []
     for tile_key, aggregate_count in aggregate_tiles.items():
         chrono_t = ChronoTile()
         dates = chrono_t.decode_path_dates(tile_key)
         dates['tile_key'] = tile_key
         sorting_ranges.append(dates)
     # now sort by earliest bce, then reversed latest bce
     # this makes puts early dates with longest timespans first
     sorted_ranges = sorted(sorting_ranges,
                            key=lambda k:
                            (k['earliest_bce'], -k['latest_bce']))
     sorted_tiles = LastUpdatedOrderedDict()
     for sort_range in sorted_ranges:
         tile_key = sort_range['tile_key']
         sorted_tiles[tile_key] = aggregate_tiles[tile_key]
     i = 0
     for tile_key, aggregate_count in sorted_tiles.items():
         i += 1
         fl = FilterLinks()
         fl.base_request_json = self.filter_request_dict_json
         fl.spatial_context = self.spatial_context
         new_rparams = fl.add_to_request('form-chronotile', tile_key)
         record = LastUpdatedOrderedDict()
         record['id'] = fl.make_request_url(new_rparams)
         record['json'] = fl.make_request_url(new_rparams, '.json')
         record['count'] = aggregate_count
         record['category'] = 'oc-api:chrono-facet'
         chrono_t = ChronoTile()
         dates = chrono_t.decode_path_dates(tile_key)
         # convert numeric to GeoJSON-LD ISO 8601
         record['start'] = ISOyears().make_iso_from_float(
             dates['earliest_bce'])
         record['stop'] = ISOyears().make_iso_from_float(
             dates['latest_bce'])
         properties = LastUpdatedOrderedDict()
         properties['early bce/ce'] = dates['earliest_bce']
         properties['late bce/ce'] = dates['latest_bce']
         record['properties'] = properties
         self.chrono_tiles.append(record)