Add server-side clustering with pysupercluster
Some checks failed
Build Docker Image / build (push) Failing after 2m14s

This commit is contained in:
Ruslan Bakiev
2026-01-14 10:12:39 +07:00
parent e15976382e
commit 7efa753092
3 changed files with 206 additions and 1 deletions

View File

@@ -6,6 +6,7 @@ import requests
import graphene
from django.conf import settings
from .arango_client import get_db, ensure_graph
from .cluster_index import get_clustered_nodes, invalidate_cache
logger = logging.getLogger(__name__)
@@ -80,6 +81,16 @@ class ProductRouteOptionType(graphene.ObjectType):
routes = graphene.List(RoutePathType)
class ClusterPointType(graphene.ObjectType):
"""Cluster or individual point for map display."""
id = graphene.String(description="UUID for points, 'cluster-N' for clusters")
latitude = graphene.Float()
longitude = graphene.Float()
count = graphene.Int(description="1 for single point, >1 for cluster")
expansion_zoom = graphene.Int(description="Zoom level to expand cluster")
name = graphene.String(description="Node name (only for single points)")
class Query(graphene.ObjectType):
"""Root query."""
MAX_EXPANSIONS = 20000
@@ -161,6 +172,17 @@ class Query(graphene.ObjectType):
description="Find routes from product offer nodes to destination",
)
clustered_nodes = graphene.List(
ClusterPointType,
west=graphene.Float(required=True, description="Bounding box west longitude"),
south=graphene.Float(required=True, description="Bounding box south latitude"),
east=graphene.Float(required=True, description="Bounding box east longitude"),
north=graphene.Float(required=True, description="Bounding box north latitude"),
zoom=graphene.Int(required=True, description="Map zoom level (0-16)"),
transport_type=graphene.String(description="Filter by transport type"),
description="Get clustered nodes for map display (server-side clustering)",
)
@staticmethod
def _build_routes(db, from_uuid, to_uuid, limit):
"""Shared helper to compute K shortest routes between two nodes."""
@@ -740,6 +762,12 @@ class Query(graphene.ObjectType):
return found_routes
def resolve_clustered_nodes(self, info, west, south, east, north, zoom, transport_type=None):
"""Get clustered nodes for map display using server-side SuperCluster."""
db = get_db()
clusters = get_clustered_nodes(db, west, south, east, north, zoom, transport_type)
return [ClusterPointType(**c) for c in clusters]
schema = graphene.Schema(query=Query)