Add bounds filtering to nodes query for map-based selection
All checks were successful
Build Docker Image / build (push) Successful in 1m10s

This commit is contained in:
Ruslan Bakiev
2026-01-24 12:13:29 +07:00
parent e342d68197
commit 27b05cf362

View File

@@ -153,11 +153,19 @@ class Query(graphene.ObjectType):
transport_type=graphene.String(),
country=graphene.String(description="Filter by country name"),
search=graphene.String(description="Search by node name (case-insensitive)"),
west=graphene.Float(description="Bounding box west longitude"),
south=graphene.Float(description="Bounding box south latitude"),
east=graphene.Float(description="Bounding box east longitude"),
north=graphene.Float(description="Bounding box north latitude"),
)
nodes_count = graphene.Int(
transport_type=graphene.String(),
country=graphene.String(description="Filter by country name"),
description="Get total count of nodes (with optional transport/country filter)",
west=graphene.Float(description="Bounding box west longitude"),
south=graphene.Float(description="Bounding box south latitude"),
east=graphene.Float(description="Bounding box east longitude"),
north=graphene.Float(description="Bounding box north latitude"),
description="Get total count of nodes (with optional transport/country/bounds filter)",
)
hub_countries = graphene.List(
@@ -402,18 +410,29 @@ class Query(graphene.ObjectType):
edges=[EdgeType(**e) for e in edges],
)
def resolve_nodes(self, info, limit=None, offset=None, transport_type=None, country=None, search=None):
def resolve_nodes(self, info, limit=None, offset=None, transport_type=None, country=None, search=None,
west=None, south=None, east=None, north=None):
"""Get all logistics nodes (without edges for list view)."""
db = get_db()
# Build bounds filter if all bounds are provided
bounds_filter = ""
if west is not None and south is not None and east is not None and north is not None:
bounds_filter = """
FILTER node.latitude != null AND node.longitude != null
FILTER node.latitude >= @south AND node.latitude <= @north
FILTER node.longitude >= @west AND node.longitude <= @east
"""
# Only return logistics nodes (not buyer/seller addresses)
aql = """
aql = f"""
FOR node IN nodes
FILTER node.node_type == 'logistics' OR node.node_type == null
LET types = node.transport_types != null ? node.transport_types : []
FILTER @transport_type == null OR @transport_type IN types
FILTER @country == null OR node.country == @country
FILTER @search == null OR CONTAINS(LOWER(node.name), LOWER(@search)) OR CONTAINS(LOWER(node.country), LOWER(@search))
{bounds_filter}
SORT node.name ASC
LIMIT @offset, @limit
RETURN node
@@ -426,6 +445,10 @@ class Query(graphene.ObjectType):
'search': search,
'offset': 0 if offset is None else offset,
'limit': 1000000 if limit is None else limit,
'west': west,
'south': south,
'east': east,
'north': north,
},
)
@@ -446,18 +469,37 @@ class Query(graphene.ObjectType):
logger.info("Returning %d nodes", len(nodes))
return nodes
def resolve_nodes_count(self, info, transport_type=None, country=None):
def resolve_nodes_count(self, info, transport_type=None, country=None,
west=None, south=None, east=None, north=None):
db = get_db()
aql = """
# Build bounds filter if all bounds are provided
bounds_filter = ""
if west is not None and south is not None and east is not None and north is not None:
bounds_filter = """
FILTER node.latitude != null AND node.longitude != null
FILTER node.latitude >= @south AND node.latitude <= @north
FILTER node.longitude >= @west AND node.longitude <= @east
"""
aql = f"""
FOR node IN nodes
FILTER node.node_type == 'logistics' OR node.node_type == null
LET types = node.transport_types != null ? node.transport_types : []
FILTER @transport_type == null OR @transport_type IN types
FILTER @country == null OR node.country == @country
{bounds_filter}
COLLECT WITH COUNT INTO length
RETURN length
"""
cursor = db.aql.execute(aql, bind_vars={'transport_type': transport_type, 'country': country})
cursor = db.aql.execute(aql, bind_vars={
'transport_type': transport_type,
'country': country,
'west': west,
'south': south,
'east': east,
'north': north,
})
return next(cursor, 0)
def resolve_hub_countries(self, info):