Add node_type parameter to clusteredNodes for unified server-side clustering
All checks were successful
Build Docker Image / build (push) Successful in 1m31s
All checks were successful
Build Docker Image / build (push) Successful in 1m31s
This commit is contained in:
@@ -22,23 +22,46 @@ ZOOM_TO_RES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _fetch_nodes(db, transport_type=None):
|
def _fetch_nodes(db, transport_type=None, node_type=None):
|
||||||
"""Fetch nodes from database with caching."""
|
"""Fetch nodes from database with caching.
|
||||||
cache_key = f"nodes:{transport_type or 'all'}"
|
|
||||||
|
Args:
|
||||||
|
db: Database connection
|
||||||
|
transport_type: Filter by transport type (auto, rail, sea, air)
|
||||||
|
node_type: Type of nodes to fetch ('logistics', 'offer', 'supplier')
|
||||||
|
"""
|
||||||
|
cache_key = f"nodes:{transport_type or 'all'}:{node_type or 'logistics'}"
|
||||||
|
|
||||||
with _cache_lock:
|
with _cache_lock:
|
||||||
if cache_key not in _nodes_cache:
|
if cache_key not in _nodes_cache:
|
||||||
aql = """
|
# Select AQL query based on node_type
|
||||||
FOR node IN nodes
|
if node_type == 'offer':
|
||||||
FILTER node.node_type == 'logistics' OR node.node_type == null
|
aql = """
|
||||||
FILTER node.latitude != null AND node.longitude != null
|
FOR node IN nodes
|
||||||
RETURN node
|
FILTER node.node_type == 'offer'
|
||||||
"""
|
FILTER node.latitude != null AND node.longitude != null
|
||||||
|
RETURN node
|
||||||
|
"""
|
||||||
|
elif node_type == 'supplier':
|
||||||
|
aql = """
|
||||||
|
FOR node IN nodes
|
||||||
|
FILTER node.node_type == 'supplier'
|
||||||
|
FILTER node.latitude != null AND node.longitude != null
|
||||||
|
RETURN node
|
||||||
|
"""
|
||||||
|
else: # logistics (default)
|
||||||
|
aql = """
|
||||||
|
FOR node IN nodes
|
||||||
|
FILTER node.node_type == 'logistics' OR node.node_type == null
|
||||||
|
FILTER node.latitude != null AND node.longitude != null
|
||||||
|
RETURN node
|
||||||
|
"""
|
||||||
|
|
||||||
cursor = db.aql.execute(aql)
|
cursor = db.aql.execute(aql)
|
||||||
all_nodes = list(cursor)
|
all_nodes = list(cursor)
|
||||||
|
|
||||||
# Filter by transport type if specified
|
# Filter by transport type if specified (only for logistics nodes)
|
||||||
if transport_type:
|
if transport_type and node_type in (None, 'logistics'):
|
||||||
all_nodes = [
|
all_nodes = [
|
||||||
n for n in all_nodes
|
n for n in all_nodes
|
||||||
if transport_type in (n.get('transport_types') or [])
|
if transport_type in (n.get('transport_types') or [])
|
||||||
@@ -50,14 +73,21 @@ def _fetch_nodes(db, transport_type=None):
|
|||||||
return _nodes_cache[cache_key]
|
return _nodes_cache[cache_key]
|
||||||
|
|
||||||
|
|
||||||
def get_clustered_nodes(db, west, south, east, north, zoom, transport_type=None):
|
def get_clustered_nodes(db, west, south, east, north, zoom, transport_type=None, node_type=None):
|
||||||
"""
|
"""
|
||||||
Get clustered nodes for given bounding box and zoom level.
|
Get clustered nodes for given bounding box and zoom level.
|
||||||
|
|
||||||
Uses H3 hexagonal grid to group nearby nodes.
|
Uses H3 hexagonal grid to group nearby nodes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db: Database connection
|
||||||
|
west, south, east, north: Bounding box coordinates
|
||||||
|
zoom: Map zoom level
|
||||||
|
transport_type: Filter by transport type (for logistics nodes)
|
||||||
|
node_type: Type of nodes ('logistics', 'offer', 'supplier')
|
||||||
"""
|
"""
|
||||||
resolution = ZOOM_TO_RES.get(int(zoom), 5)
|
resolution = ZOOM_TO_RES.get(int(zoom), 5)
|
||||||
nodes = _fetch_nodes(db, transport_type)
|
nodes = _fetch_nodes(db, transport_type, node_type)
|
||||||
|
|
||||||
if not nodes:
|
if not nodes:
|
||||||
return []
|
return []
|
||||||
|
|||||||
@@ -191,6 +191,7 @@ class Query(graphene.ObjectType):
|
|||||||
north=graphene.Float(required=True, description="Bounding box north latitude"),
|
north=graphene.Float(required=True, description="Bounding box north latitude"),
|
||||||
zoom=graphene.Int(required=True, description="Map zoom level (0-16)"),
|
zoom=graphene.Int(required=True, description="Map zoom level (0-16)"),
|
||||||
transport_type=graphene.String(description="Filter by transport type"),
|
transport_type=graphene.String(description="Filter by transport type"),
|
||||||
|
node_type=graphene.String(description="Node type: logistics, offer, supplier"),
|
||||||
description="Get clustered nodes for map display (server-side clustering)",
|
description="Get clustered nodes for map display (server-side clustering)",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -641,10 +642,10 @@ class Query(graphene.ObjectType):
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def resolve_clustered_nodes(self, info, west, south, east, north, zoom, transport_type=None):
|
def resolve_clustered_nodes(self, info, west, south, east, north, zoom, transport_type=None, node_type=None):
|
||||||
"""Get clustered nodes for map display using server-side SuperCluster."""
|
"""Get clustered nodes for map display using server-side SuperCluster."""
|
||||||
db = get_db()
|
db = get_db()
|
||||||
clusters = get_clustered_nodes(db, west, south, east, north, zoom, transport_type)
|
clusters = get_clustered_nodes(db, west, south, east, north, zoom, transport_type, node_type)
|
||||||
return [ClusterPointType(**c) for c in clusters]
|
return [ClusterPointType(**c) for c in clusters]
|
||||||
|
|
||||||
def resolve_products(self, info):
|
def resolve_products(self, info):
|
||||||
|
|||||||
Reference in New Issue
Block a user