feat: implement geometry service with persistence layer and API documentation
All checks were successful
Build and Release / release (push) Successful in 1m33s

This commit is contained in:
2026-05-09 00:43:45 +07:00
parent b2ee16457d
commit 27c78db66d
7 changed files with 32 additions and 4 deletions

View File

@@ -67,7 +67,11 @@ WHERE g.is_deleted = false
) )
AND ( AND (
sqlc.narg('time_point')::int IS NULL OR sqlc.narg('time_point')::int IS NULL OR
int4range(g.time_start, g.time_end, '[]') @> sqlc.narg('time_point')::int int4range(g.time_start, g.time_end, '[]') && int4range(
sqlc.narg('time_point')::int - COALESCE(sqlc.narg('time_range')::int, 0),
sqlc.narg('time_point')::int + COALESCE(sqlc.narg('time_range')::int, 0),
'[]'
)
) )
AND ( AND (
sqlc.narg('entity_id')::uuid IS NULL OR sqlc.narg('entity_id')::uuid IS NULL OR

View File

@@ -756,6 +756,11 @@ const docTemplate = `{
"type": "integer", "type": "integer",
"name": "time", "name": "time",
"in": "query" "in": "query"
},
{
"type": "integer",
"name": "time_range",
"in": "query"
} }
], ],
"responses": { "responses": {

View File

@@ -749,6 +749,11 @@
"type": "integer", "type": "integer",
"name": "time", "name": "time",
"in": "query" "in": "query"
},
{
"type": "integer",
"name": "time_range",
"in": "query"
} }
], ],
"responses": { "responses": {

View File

@@ -1174,6 +1174,9 @@ paths:
- in: query - in: query
name: time name: time
type: integer type: integer
- in: query
name: time_range
type: integer
produces: produces:
- application/json - application/json
responses: responses:

View File

@@ -6,6 +6,7 @@ type SearchGeometryDto struct {
MaxLng *float64 `json:"max_lng" query:"max_lng" validate:"required,gte=-180,lte=180"` MaxLng *float64 `json:"max_lng" query:"max_lng" validate:"required,gte=-180,lte=180"`
MaxLat *float64 `json:"max_lat" query:"max_lat" validate:"required,gte=-90,lte=90"` MaxLat *float64 `json:"max_lat" query:"max_lat" validate:"required,gte=-90,lte=90"`
TimePoint *int32 `json:"time" query:"time" validate:"omitempty,number"` TimePoint *int32 `json:"time" query:"time" validate:"omitempty,number"`
TimeRange *int32 `json:"time_range" query:"time_range" validate:"omitempty,number"`
EntityID *string `json:"entity_id" query:"entity_id" validate:"omitempty,uuid"` EntityID *string `json:"entity_id" query:"entity_id" validate:"omitempty,uuid"`
ProjectID *string `json:"project_id" query:"project_id" validate:"omitempty,uuid"` ProjectID *string `json:"project_id" query:"project_id" validate:"omitempty,uuid"`
} }

View File

@@ -460,15 +460,19 @@ WHERE g.is_deleted = false
) )
AND ( AND (
$6::int IS NULL OR $6::int IS NULL OR
int4range(g.time_start, g.time_end, '[]') @> $6::int int4range(g.time_start, g.time_end, '[]') && int4range(
$6::int - COALESCE($7::int, 0),
$6::int + COALESCE($7::int, 0),
'[]'
)
) )
AND ( AND (
$7::uuid IS NULL OR $8::uuid IS NULL OR
EXISTS ( EXISTS (
SELECT 1 SELECT 1
FROM entity_geometries eg FROM entity_geometries eg
WHERE eg.geometry_id = g.id WHERE eg.geometry_id = g.id
AND eg.entity_id = $7::uuid AND eg.entity_id = $8::uuid
) )
) )
ORDER BY g.id DESC ORDER BY g.id DESC
@@ -481,6 +485,7 @@ type SearchGeometriesParams struct {
SearchMaxLng pgtype.Float8 `json:"search_max_lng"` SearchMaxLng pgtype.Float8 `json:"search_max_lng"`
SearchMaxLat pgtype.Float8 `json:"search_max_lat"` SearchMaxLat pgtype.Float8 `json:"search_max_lat"`
TimePoint pgtype.Int4 `json:"time_point"` TimePoint pgtype.Int4 `json:"time_point"`
TimeRange pgtype.Int4 `json:"time_range"`
EntityID pgtype.UUID `json:"entity_id"` EntityID pgtype.UUID `json:"entity_id"`
} }
@@ -509,6 +514,7 @@ func (q *Queries) SearchGeometries(ctx context.Context, arg SearchGeometriesPara
arg.SearchMaxLng, arg.SearchMaxLng,
arg.SearchMaxLat, arg.SearchMaxLat,
arg.TimePoint, arg.TimePoint,
arg.TimeRange,
arg.EntityID, arg.EntityID,
) )
if err != nil { if err != nil {

View File

@@ -61,6 +61,10 @@ func (s *geometryService) SearchGeometries(ctx context.Context, req *request.Sea
params.TimePoint = pgtype.Int4{Int32: *req.TimePoint, Valid: true} params.TimePoint = pgtype.Int4{Int32: *req.TimePoint, Valid: true}
} }
if req.TimeRange != nil {
params.TimeRange = pgtype.Int4{Int32: *req.TimeRange, Valid: true}
}
if req.EntityID != nil { if req.EntityID != nil {
entityId, err := convert.StringToUUID(*req.EntityID) entityId, err := convert.StringToUUID(*req.EntityID)
if err != nil { if err != nil {