gis/internal/repository/postgres/district.go

66 lines
1.7 KiB
Go

package postgres
import (
"context"
"gis/internal/domain"
"github.com/google/uuid"
)
// ListAllObservations returns every observation for a dataset ordered by
// (kato_code, date). Unlike ListObservations it is unpaginated: it backs GeoJSON
// assembly, where all of a dataset's observations are needed at once.
func (r *DatasetRepository) ListAllObservations(ctx context.Context, datasetID uuid.UUID) ([]domain.Observation, error) {
rows, err := r.pool.Query(ctx,
`SELECT `+observationColumns+`
FROM dataset_observations
WHERE dataset_id = $1
ORDER BY kato_code, date`,
datasetID)
if err != nil {
return nil, mapError(err)
}
defer rows.Close()
out := make([]domain.Observation, 0)
for rows.Next() {
o, err := scanObservation(rows)
if err != nil {
return nil, mapError(err)
}
out = append(out, o)
}
return out, mapError(rows.Err())
}
// DistrictGeometriesByKato returns the districts whose KATO codes are in katos,
// keyed by KATO, with each boundary serialized as a GeoJSON geometry object in
// EPSG:4326. KATO codes with no matching district are simply absent from the
// result map.
func (r *DatasetRepository) DistrictGeometriesByKato(ctx context.Context, katos []string) (map[string]domain.District, error) {
out := make(map[string]domain.District)
if len(katos) == 0 {
return out, nil
}
rows, err := r.pool.Query(ctx,
`SELECT kato, name, ST_AsGeoJSON(coordinates)::jsonb
FROM districts
WHERE kato = ANY($1)`,
katos)
if err != nil {
return nil, mapError(err)
}
defer rows.Close()
for rows.Next() {
var d domain.District
if err := rows.Scan(&d.Kato, &d.Name, &d.Geometry); err != nil {
return nil, mapError(err)
}
out[d.Kato] = d
}
return out, mapError(rows.Err())
}