Add aggregation map for traps

This also makes the first time I've done a Mapbox map within a web
component. It's not officially supported according to:

https://github.com/mapbox/mapbox-gl-js/issues/12796

but I found a codepen that had a working example:

https://codepen.io/keichan34/pen/ZEKqeEj?editors=1111
This commit is contained in:
Eli Ribble 2026-01-15 20:25:00 +00:00
parent 08c6a7f884
commit 948f967a16
No known key found for this signature in database
10 changed files with 356 additions and 115 deletions

View file

@ -321,6 +321,15 @@ var FieldseekerTraplocations = Table[
Generated: false,
AutoIncr: false,
},
H3cell: column{
Name: "h3cell",
DBType: "h3index",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
},
Indexes: fieldseekerTraplocationIndexes{
TraplocationPkey: index{
@ -401,11 +410,12 @@ type fieldseekerTraplocationColumns struct {
Geospatial column
Version column
OrganizationID column
H3cell column
}
func (c fieldseekerTraplocationColumns) AsSlice() []column {
return []column{
c.Objectid, c.Name, c.Zone, c.Habitat, c.Priority, c.Usetype, c.Active, c.Description, c.Accessdesc, c.Comments, c.Externalid, c.Nextactiondatescheduled, c.Zone2, c.Locationnumber, c.Globalid, c.CreatedUser, c.CreatedDate, c.LastEditedUser, c.LastEditedDate, c.Gatewaysync, c.Route, c.SetDow, c.RouteOrder, c.Vectorsurvsiteid, c.Creationdate, c.Creator, c.Editdate, c.Editor, c.H3R7, c.H3R8, c.Geometry, c.Geospatial, c.Version, c.OrganizationID,
c.Objectid, c.Name, c.Zone, c.Habitat, c.Priority, c.Usetype, c.Active, c.Description, c.Accessdesc, c.Comments, c.Externalid, c.Nextactiondatescheduled, c.Zone2, c.Locationnumber, c.Globalid, c.CreatedUser, c.CreatedDate, c.LastEditedUser, c.LastEditedDate, c.Gatewaysync, c.Route, c.SetDow, c.RouteOrder, c.Vectorsurvsiteid, c.Creationdate, c.Creator, c.Editdate, c.Editor, c.H3R7, c.H3R8, c.Geometry, c.Geospatial, c.Version, c.OrganizationID, c.H3cell,
}
}

View file

@ -197,12 +197,14 @@ func (e *Audiodatatype) Scan(value any) error {
const (
H3aggregationtypeMosquitosource H3aggregationtype = "MosquitoSource"
H3aggregationtypeServicerequest H3aggregationtype = "ServiceRequest"
H3aggregationtypeTrap H3aggregationtype = "Trap"
)
func AllH3aggregationtype() []H3aggregationtype {
return []H3aggregationtype{
H3aggregationtypeMosquitosource,
H3aggregationtypeServicerequest,
H3aggregationtypeTrap,
}
}
@ -215,7 +217,8 @@ func (e H3aggregationtype) String() string {
func (e H3aggregationtype) Valid() bool {
switch e {
case H3aggregationtypeMosquitosource,
H3aggregationtypeServicerequest:
H3aggregationtypeServicerequest,
H3aggregationtypeTrap:
return true
default:
return false

View file

@ -1680,6 +1680,7 @@ func (f *Factory) FromExistingFieldseekerTraplocation(m *models.FieldseekerTrapl
o.Geospatial = func() null.Val[string] { return m.Geospatial }
o.Version = func() int32 { return m.Version }
o.OrganizationID = func() int32 { return m.OrganizationID }
o.H3cell = func() null.Val[string] { return m.H3cell }
ctx := context.Background()
if m.R.Organization != nil {

View file

@ -74,6 +74,7 @@ type FieldseekerTraplocationTemplate struct {
Geospatial func() null.Val[string]
Version func() int32
OrganizationID func() int32
H3cell func() null.Val[string]
r fieldseekerTraplocationR
f *Factory
@ -372,6 +373,9 @@ func (o FieldseekerTraplocationTemplate) Build() *models.FieldseekerTraplocation
if o.OrganizationID != nil {
m.OrganizationID = o.OrganizationID()
}
if o.H3cell != nil {
m.H3cell = o.H3cell()
}
o.setModelRels(m)
@ -561,6 +565,7 @@ func (m fieldseekerTraplocationMods) RandomizeAllColumns(f *faker.Faker) Fieldse
FieldseekerTraplocationMods.RandomGeospatial(f),
FieldseekerTraplocationMods.RandomVersion(f),
FieldseekerTraplocationMods.RandomOrganizationID(f),
FieldseekerTraplocationMods.RandomH3cell(f),
}
}
@ -2256,6 +2261,59 @@ func (m fieldseekerTraplocationMods) RandomOrganizationID(f *faker.Faker) Fields
})
}
// Set the model columns to this value
func (m fieldseekerTraplocationMods) H3cell(val null.Val[string]) FieldseekerTraplocationMod {
return FieldseekerTraplocationModFunc(func(_ context.Context, o *FieldseekerTraplocationTemplate) {
o.H3cell = func() null.Val[string] { return val }
})
}
// Set the Column from the function
func (m fieldseekerTraplocationMods) H3cellFunc(f func() null.Val[string]) FieldseekerTraplocationMod {
return FieldseekerTraplocationModFunc(func(_ context.Context, o *FieldseekerTraplocationTemplate) {
o.H3cell = f
})
}
// Clear any values for the column
func (m fieldseekerTraplocationMods) UnsetH3cell() FieldseekerTraplocationMod {
return FieldseekerTraplocationModFunc(func(_ context.Context, o *FieldseekerTraplocationTemplate) {
o.H3cell = nil
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is sometimes null
func (m fieldseekerTraplocationMods) RandomH3cell(f *faker.Faker) FieldseekerTraplocationMod {
return FieldseekerTraplocationModFunc(func(_ context.Context, o *FieldseekerTraplocationTemplate) {
o.H3cell = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
// Generates a random value for the column using the given faker
// if faker is nil, a default faker is used
// The generated value is never null
func (m fieldseekerTraplocationMods) RandomH3cellNotNull(f *faker.Faker) FieldseekerTraplocationMod {
return FieldseekerTraplocationModFunc(func(_ context.Context, o *FieldseekerTraplocationTemplate) {
o.H3cell = func() null.Val[string] {
if f == nil {
f = &defaultFaker
}
val := random_string(f)
return null.From(val)
}
})
}
func (m fieldseekerTraplocationMods) WithParentsCascading() FieldseekerTraplocationMod {
return FieldseekerTraplocationModFunc(func(ctx context.Context, o *FieldseekerTraplocationTemplate) {
if isDone, _ := fieldseekerTraplocationWithParentsCascadingCtx.Value(ctx); isDone {

View file

@ -0,0 +1,5 @@
-- +goose Up
ALTER TYPE H3AggregationType ADD VALUE 'Trap' AFTER 'ServiceRequest';
-- +goose Down
ALTER TYPE H3AggregationType DROP VALUE 'Trap';

View file

@ -0,0 +1,5 @@
-- +goose Up
ALTER TABLE fieldseeker.traplocation ADD COLUMN h3cell h3index GENERATED ALWAYS AS (h3_latlng_to_cell(geospatial, 15)) STORED;
-- +goose Down
ALTER TABLE fieldseeker.traplocation DROP COLUMN h3cell;

View file

@ -92,6 +92,7 @@ type FieldseekerTraplocation struct {
Geospatial null.Val[string] `db:"geospatial" `
Version int32 `db:"version,pk" `
OrganizationID int32 `db:"organization_id" `
H3cell null.Val[string] `db:"h3cell,generated" `
R fieldseekerTraplocationR `db:"-" `
}
@ -114,7 +115,7 @@ type fieldseekerTraplocationR struct {
func buildFieldseekerTraplocationColumns(alias string) fieldseekerTraplocationColumns {
return fieldseekerTraplocationColumns{
ColumnsExpr: expr.NewColumnsExpr(
"objectid", "name", "zone", "habitat", "priority", "usetype", "active", "description", "accessdesc", "comments", "externalid", "nextactiondatescheduled", "zone2", "locationnumber", "globalid", "created_user", "created_date", "last_edited_user", "last_edited_date", "gatewaysync", "route", "set_dow", "route_order", "vectorsurvsiteid", "creationdate", "creator", "editdate", "editor", "h3r7", "h3r8", "geometry", "geospatial", "version", "organization_id",
"objectid", "name", "zone", "habitat", "priority", "usetype", "active", "description", "accessdesc", "comments", "externalid", "nextactiondatescheduled", "zone2", "locationnumber", "globalid", "created_user", "created_date", "last_edited_user", "last_edited_date", "gatewaysync", "route", "set_dow", "route_order", "vectorsurvsiteid", "creationdate", "creator", "editdate", "editor", "h3r7", "h3r8", "geometry", "geospatial", "version", "organization_id", "h3cell",
).WithParent("fieldseeker.traplocation"),
tableAlias: alias,
Objectid: psql.Quote(alias, "objectid"),
@ -151,6 +152,7 @@ func buildFieldseekerTraplocationColumns(alias string) fieldseekerTraplocationCo
Geospatial: psql.Quote(alias, "geospatial"),
Version: psql.Quote(alias, "version"),
OrganizationID: psql.Quote(alias, "organization_id"),
H3cell: psql.Quote(alias, "h3cell"),
}
}
@ -191,6 +193,7 @@ type fieldseekerTraplocationColumns struct {
Geospatial psql.Expression
Version psql.Expression
OrganizationID psql.Expression
H3cell psql.Expression
}
func (c fieldseekerTraplocationColumns) Alias() string {
@ -1256,6 +1259,7 @@ type fieldseekerTraplocationWhere[Q psql.Filterable] struct {
Geospatial psql.WhereNullMod[Q, string]
Version psql.WhereMod[Q, int32]
OrganizationID psql.WhereMod[Q, int32]
H3cell psql.WhereNullMod[Q, string]
}
func (fieldseekerTraplocationWhere[Q]) AliasedAs(alias string) fieldseekerTraplocationWhere[Q] {
@ -1298,6 +1302,7 @@ func buildFieldseekerTraplocationWhere[Q psql.Filterable](cols fieldseekerTraplo
Geospatial: psql.WhereNull[Q, string](cols.Geospatial),
Version: psql.Where[Q, int32](cols.Version),
OrganizationID: psql.Where[Q, int32](cols.OrganizationID),
H3cell: psql.WhereNull[Q, string](cols.H3cell),
}
}