Beispiel #1
0
 def make_min_size_region(self, region_dict):
     """ widens a coordinate pair based on maximum distance
         between points
         
         this makes a square (on a mercator projection) bounding box
         region. it will have different real-world distances in the
         east west direction between the northern and southern sides
     """
     min_distance = self.max_geo_range * 0.05
     gm = GlobalMercator()
     # measure the north south distance
     mid_lat = (region_dict['min_lat'] + region_dict['max_lat']) / 2
     mid_lon = (region_dict['min_lon'] + region_dict['max_lon']) / 2
     ns_diag_dist = gm.distance_on_unit_sphere(region_dict['min_lat'],
                                               mid_lon,
                                               region_dict['max_lat'],
                                               mid_lon)
     ew_diag_dist = gm.distance_on_unit_sphere(mid_lat,
                                               region_dict['min_lon'],
                                               mid_lat,
                                               region_dict['max_lon'])
     if ns_diag_dist < min_distance:
         # the north-south distance is too small, so widen it.
         # first, find a point south of the mid lat, at the right distance
         new_lat_s = gm.get_point_by_distance_from_point(mid_lat,
                                                         mid_lon,
                                                         (min_distance / 2),
                                                         180)
         # second, find a point north of the mid lat, at the right distance
         new_lat_n = gm.get_point_by_distance_from_point(mid_lat,
                                                         mid_lon,
                                                         (min_distance / 2),
                                                         0)
         region_dict['min_lat'] = new_lat_s['lat']
         region_dict['max_lat'] = new_lat_n['lat']
     if ew_diag_dist < min_distance:
         # the east-west distance is too small, so widen it.
         # first, find a point south of the mid lat, at the right distance
         new_lon_w = gm.get_point_by_distance_from_point(mid_lat,
                                                         mid_lon,
                                                         (min_distance / 2),
                                                         270)
         # second, find a point north of the mid lat, at the right distance
         new_lon_e = gm.get_point_by_distance_from_point(mid_lat,
                                                         mid_lon,
                                                         (min_distance / 2),
                                                         90)
         region_dict['min_lon'] = new_lon_w['lon']
         region_dict['max_lon'] = new_lon_e['lon']
     return region_dict
Beispiel #2
0
 def make_min_size_region(self, region_dict):
     """ widens a coordinate pair based on maximum distance
         between points
         
         this makes a square (on a mercator projection) bounding box
         region. it will have different real-world distances in the
         east west direction between the northern and southern sides
     """
     min_distance = self.max_geo_range * 0.05
     gm = GlobalMercator()
     # measure the north south distance
     mid_lat = (region_dict['min_lat'] + region_dict['max_lat']) / 2
     mid_lon = (region_dict['min_lon'] + region_dict['max_lon']) / 2
     ns_diag_dist = gm.distance_on_unit_sphere(region_dict['min_lat'],
                                               mid_lon,
                                               region_dict['max_lat'],
                                               mid_lon)
     ew_diag_dist = gm.distance_on_unit_sphere(mid_lat,
                                               region_dict['min_lon'],
                                               mid_lat,
                                               region_dict['max_lon'])
     if ns_diag_dist < min_distance:
         # the north-south distance is too small, so widen it.
         # first, find a point south of the mid lat, at the right distance
         new_lat_s = gm.get_point_by_distance_from_point(mid_lat,
                                                         mid_lon,
                                                         (min_distance / 2),
                                                         180)
         # second, find a point north of the mid lat, at the right distance
         new_lat_n = gm.get_point_by_distance_from_point(mid_lat,
                                                         mid_lon,
                                                         (min_distance / 2),
                                                         0)
         region_dict['min_lat'] = new_lat_s['lat']
         region_dict['max_lat'] = new_lat_n['lat']
     if ew_diag_dist < min_distance:
         # the east-west distance is too small, so widen it.
         # first, find a point south of the mid lat, at the right distance
         new_lon_w = gm.get_point_by_distance_from_point(mid_lat,
                                                         mid_lon,
                                                         (min_distance / 2),
                                                         270)
         # second, find a point north of the mid lat, at the right distance
         new_lon_e = gm.get_point_by_distance_from_point(mid_lat,
                                                         mid_lon,
                                                         (min_distance / 2),
                                                         90)
         region_dict['min_lon'] = new_lon_w['lon']
         region_dict['max_lon'] = new_lon_e['lon']
     return region_dict
Beispiel #3
0
 def make_geo_meta(self, project_uuid, sub_projs=False):
     output = False
     self.project_uuid = project_uuid
     if sub_projs is False:
         # check if there are subjects in this project
         pr = ProjectRels()
         sub_projs = pr.get_sub_projects(project_uuid)
     if sub_projs is False:
         uuids = [project_uuid]
     else:
         uuids = []
         for sub_proj in sub_projs:
             uuids.append(sub_proj.uuid)
         uuids.append(project_uuid)
     self.get_geo_range(uuids)
     if self.geo_range is False:
         pass
         if self.print_progress:
             print('Range fail: ' + str(self.geo_range) )
     else:
         if self.print_progress:
             print('Working on range: ' + str(self.geo_range) )
         min_lon_lat = [self.geo_range['longitude__min'],
                        self.geo_range['latitude__min']]
         max_lon_lat = [self.geo_range['longitude__max'],
                        self.geo_range['latitude__max']]
         min_point = np.fromiter(min_lon_lat, np.dtype('float'))
         max_point = np.fromiter(max_lon_lat, np.dtype('float'))
         gm = GlobalMercator()
         self.max_geo_range = gm.distance_on_unit_sphere(min_point[1],
                                                         min_point[0],
                                                         max_point[1],
                                                         max_point[0])
         if self.print_progress:
             print('Max geo range: ' + str(self.max_geo_range))
         if self.max_geo_range == 0:
             # only 1 geopoint known for the project
             proc_centroids = []
             proc_centroid = {}
             proc_centroid['index'] = 0
             proc_centroid['id'] = 1
             proc_centroid['num_points'] = 1
             proc_centroid['cent_lon'] = self.geo_range['longitude__min']
             proc_centroid['cent_lat'] = self.geo_range['latitude__max']
             proc_centroid['box'] = False
             proc_centroids.append(proc_centroid)
         else:
             # need to cluster geo data
             proc_centroids = self.cluster_geo(uuids)
         self.make_geo_objs(proc_centroids)
         output = True
     return output
Beispiel #4
0
 def make_geo_meta(self, project_uuid, sub_projs=False):
     output = False
     self.project_uuid = project_uuid
     if sub_projs is False:
         # check if there are subjects in this project
         pr = ProjectRels()
         sub_projs = pr.get_sub_projects(project_uuid)
     if sub_projs is False:
         uuids = [project_uuid]
     else:
         uuids = []
         for sub_proj in sub_projs:
             uuids.append(sub_proj.uuid)
         uuids.append(project_uuid)
     self.get_geo_range(uuids)
     if self.geo_range is False:
         pass
         if self.print_progress:
             print('Range fail: ' + str(self.geo_range) )
     else:
         if self.print_progress:
             print('Working on range: ' + str(self.geo_range) )
         min_lon_lat = [self.geo_range['longitude__min'],
                        self.geo_range['latitude__min']]
         max_lon_lat = [self.geo_range['longitude__max'],
                        self.geo_range['latitude__max']]
         min_point = np.fromiter(min_lon_lat, np.dtype('float'))
         max_point = np.fromiter(max_lon_lat, np.dtype('float'))
         gm = GlobalMercator()
         self.max_geo_range = gm.distance_on_unit_sphere(min_point[1],
                                                         min_point[0],
                                                         max_point[1],
                                                         max_point[0])
         if self.print_progress:
             print('Max geo range: ' + str(self.max_geo_range))
         if self.max_geo_range == 0:
             # only 1 geopoint known for the project
             proc_centroids = []
             proc_centroid = {}
             proc_centroid['index'] = 0
             proc_centroid['id'] = 1
             proc_centroid['num_points'] = 1
             proc_centroid['cent_lon'] = self.geo_range['longitude__min']
             proc_centroid['cent_lat'] = self.geo_range['latitude__max']
             proc_centroid['box'] = False
             proc_centroids.append(proc_centroid)
         else:
             # need to cluster geo data
             proc_centroids = self.cluster_geo(uuids)
         self.make_geo_objs(proc_centroids)
         output = True
     return output
Beispiel #5
0
 def check_ok_cluster(self, proc_centroid, centroids, uuids):
     """ checks to see if the proc_centroid is an OK
         cluster, based on the number of items it
         contains or if it is far from all other centroids
     """
     ok_cluster = True  # default to this being a good cluster
     if proc_centroid['num_points'] < 2:
         # the cluster has only 1 point, meaning it may be too small
         db_multiple = self.check_ok_cluster_for_lone_point(uuids,
                                                            proc_centroid['max_lon'],
                                                            proc_centroid['max_lat'])
         if db_multiple is False:
             # not many records, 
             # OK now check if it is far from other points
             single_far = True
             for o_centroid in centroids:
                 o_lon = o_centroid[0]
                 o_lat = o_centroid[1]
                 if o_lon != proc_centroid['cent_lon'] \
                    and o_lat != proc_centroid['cent_lat']:
                     # not the same centroid, so check distance
                     gm = GlobalMercator()
                     cent_dist = gm.distance_on_unit_sphere(o_lat,
                                                            o_lon,
                                                            proc_centroid['cent_lat'],
                                                            proc_centroid['cent_lon'])
                     if cent_dist < 1000:
                         if cent_dist < self.MIN_CLUSTER_SIZE_KM \
                            or cent_dist < (self.max_geo_range * .1):
                             # we found a case where this point is close
                             # to another centroid
                             single_far = False
             if single_far is False:
                 ok_cluster = False
     if self.print_progress and ok_cluster is False:
         message = 'Cluster Loop: ' + str(proc_centroid['cluster_loop']) + ', cluster: ' + str(proc_centroid['index']) +  ' '
         message += ' has few items, too close with other centroids.'
         print(message)
     return ok_cluster
Beispiel #6
0
 def check_ok_cluster(self, proc_centroid, centroids, uuids):
     """ checks to see if the proc_centroid is an OK
         cluster, based on the number of items it
         contains or if it is far from all other centroids
     """
     ok_cluster = True  # default to this being a good cluster
     if proc_centroid['num_points'] < 2:
         # the cluster has only 1 point, meaning it may be too small
         db_multiple = self.check_ok_cluster_for_lone_point(uuids,
                                                            proc_centroid['max_lon'],
                                                            proc_centroid['max_lat'])
         if db_multiple is False:
             # not many records, 
             # OK now check if it is far from other points
             single_far = True
             for o_centroid in centroids:
                 o_lon = o_centroid[0]
                 o_lat = o_centroid[1]
                 if o_lon != proc_centroid['cent_lon'] \
                    and o_lat != proc_centroid['cent_lat']:
                     # not the same centroid, so check distance
                     gm = GlobalMercator()
                     cent_dist = gm.distance_on_unit_sphere(o_lat,
                                                            o_lon,
                                                            proc_centroid['cent_lat'],
                                                            proc_centroid['cent_lon'])
                     if cent_dist < 1000:
                         if cent_dist < self.MIN_CLUSTER_SIZE_KM \
                            or cent_dist < (self.max_geo_range * .1):
                             # we found a case where this point is close
                             # to another centroid
                             single_far = False
             if single_far is False:
                 ok_cluster = False
     if self.print_progress and ok_cluster is False:
         message = 'Cluster Loop: ' + str(proc_centroid['cluster_loop']) + ', cluster: ' + str(proc_centroid['index']) +  ' '
         message += ' has few items, too close with other centroids.'
         print(message)
     return ok_cluster
    def _distance_determine_aggregation_depth(self, valid_tile_tuples):
        """Uses distance between to recalibrate aggregation depth in tiles"""
        if len(valid_tile_tuples) < 2:
            return self.default_aggregation_depth

        lons = []
        lats = []
        gm = GlobalMercator()
        for tile, _ in valid_tile_tuples:
            geo_coords = gm.quadtree_to_geojson_lon_lat(tile)
            # Remember geojson ordering of the coordinates (lon, lat)
            lons.append(geo_coords[0])
            lats.append(geo_coords[1])

        max_distance = gm.distance_on_unit_sphere(
            min(lats),
            min(lons),
            max(lats),
            max(lons),
        )
        # Converts the maximum distance between points into a zoom level
        # appropriate for tile aggregation. Seems to work well.
        return gm.ZoomForPixelSize(max_distance) + 3
 def get_geotile_scope(self, solr_tiles):
     """ find the most specific tile shared by the whole dataset """
     geo_tiles = []
     bound_list = []
     max_distance = 0
     lat_lon_min_max = [{
         'min': None,
         'max': None
     }, {
         'min': None,
         'max': None
     }]
     for tile_key in solr_tiles[::2]:
         if tile_key[:6] != '211111':
             # a bit of a hack to exclude display of
             # erroroneous data without spatial reference
             geo_tiles.append(tile_key)
             gm = GlobalMercator()
             bounds = gm.quadtree_to_lat_lon(tile_key)
             lat_lon_min_max = self.get_min_max(lat_lon_min_max, bounds)
             bound_list.append(bounds)
     if len(geo_tiles) > 0:
         test_tile = geo_tiles[0]  # we compare against the first tile
         tile_len = len(test_tile)  # size of the tile
         in_all_geotiles = True
         i = 0
         while (i < tile_len and in_all_geotiles):
             if i > 0:
                 test_val = str(test_tile[0:i])
             else:
                 test_val = str(test_tile[0])
             for geo_tile in geo_tiles:
                 if i > len(geo_tile):
                     in_all_geotiles = False
                 else:
                     if i > 0:
                         geo_tile_part = geo_tile[0:i]
                     else:
                         geo_tile_part = geo_tile[0]
                     if test_val != geo_tile_part:
                         in_all_geotiles = False
             if in_all_geotiles:
                 # ok! we have somthing that is still in all tiles
                 self.geotile_scope = test_val
                 i += 1
     if isinstance(self.geotile_scope, str):
         self.aggregation_depth += round(len(self.geotile_scope) * 1, 0)
         self.aggregation_depth = int(self.aggregation_depth)
         if self.aggregation_depth < 6:
             self.aggregation_depth = 6
     if self.aggregation_depth >= 6 and len(bound_list) >= 2:
         gm = GlobalMercator()
         max_distance = gm.distance_on_unit_sphere(
             lat_lon_min_max[0]['min'], lat_lon_min_max[1]['min'],
             lat_lon_min_max[0]['max'], lat_lon_min_max[1]['max'])
         if max_distance == 0:
             self.aggregation_depth = 10
         else:
             # converts the maximum distance between points into a zoom level
             # appropriate for tile aggregation. seems to work well.
             self.aggregation_depth = gm.ZoomForPixelSize(max_distance) + 3
             # print('now: ' + str(self.aggregation_depth) + ' for ' + str(max_distance))
             if self.aggregation_depth > self.max_depth:
                 self.aggregation_depth = self.max_depth
             if self.aggregation_depth < 6:
                 self.aggregation_depth = 6
     return self.geotile_scope