def clustering_process(self, records, zoom, pix_x, pix_y): """ Iterate records and create point clusters We use a simple method that for every point, that is not within any cluster, calculate it's 'catchment' area and add it to the cluster If a point is within a cluster 'catchment' area increase point count for that cluster and recalculate clusters minimum bbox :param records: list of records. :type records: list :param zoom: zoom level of map :type zoom: int :param pix_x: pixel x of icon :type pix_x: int :param pix_y: pixel y of icon :type pix_y: int """ cluster_points = [] for record in records: # get x,y of site centroid = record.get_centroid() if not centroid: continue x = centroid.x y = centroid.y # check every point in cluster_points for pt in cluster_points: if 'minbbox' not in pt: pt['minbbox'] = pt['bbox'] if within_bbox((x, y), pt['minbbox']): # it's in the cluster 'catchment' area pt['count'] += 1 pt['minbbox'] = update_min_bbox((x, y), pt['minbbox']) break else: # point is not in the catchment area of any cluster x_range, y_range = overlapping_area(zoom, pix_x, pix_y, y) bbox = (x - x_range * 1.5, y - y_range * 1.5, x + x_range * 1.5, y + y_range * 1.5) serializer = LocationSiteClusterSerializer(record) new_cluster = { 'count': 1, 'bbox': bbox, 'coordinates': [x, y], 'record': serializer.data } cluster_points.append(new_cluster) return cluster_points
def clustering_process( collection_records, site_records, zoom, pix_x, pix_y, cluster_points=[], sites=[]): """ Iterate records and create point clusters We use a simple method that for every point, that is not within any cluster, calculate it's 'catchment' area and add it to the cluster If a point is within a cluster 'catchment' area increase point count for that cluster and recalculate clusters minimum bbox :param collection_records: collection records. :type collection_records: search query set :param site_records: site records. :type site_records: search query set :param zoom: zoom level of map :type zoom: int :param pix_x: pixel x of icon :type pix_x: int :param pix_y: pixel y of icon :type pix_y: int """ for collection in GetCollectionAbstract.queryset_gen( collection_records): # get x,y of site try: x = collection.site.geometry_point.x y = collection.site.geometry_point.y location_site = collection.site if collection.site.id in sites: continue sites.append(collection.site_id) except (ValueError, AttributeError): continue # check every point in cluster_points for pt in cluster_points: if 'minbbox' not in pt: pt['minbbox'] = pt['bbox'] if within_bbox((x, y), pt['minbbox']): # it's in the cluster 'catchment' area pt['count'] += 1 pt['minbbox'] = update_min_bbox( (x, y), pt['minbbox']) break else: # point is not in the catchment area of any cluster x_range, y_range = overlapping_area( zoom, pix_x, pix_y, y) bbox = ( x - x_range * 1.5, y - y_range * 1.5, x + x_range * 1.5, y + y_range * 1.5 ) serializer = LocationSiteClusterSerializer( location_site) new_cluster = { 'count': 1, 'bbox': bbox, 'coordinates': [x, y], 'record': serializer.data } cluster_points.append(new_cluster) return cluster_points, sites