diff --git a/arcgis.go b/arcgis.go index 2c17be59..99b20a8a 100644 --- a/arcgis.go +++ b/arcgis.go @@ -1088,18 +1088,20 @@ func updateSummaryTables(ctx context.Context, org *models.Organization) { log.Info().Int("resolution", i).Msg("Working summary layer") cellToCount := make(map[h3.Cell]int, 0) for _, p := range point_locations { - p, err := getPoint(p.Geometry) + if p.H3cell.IsNull() { + continue + } + cell, err := toH3Cell(p.H3cell.MustGet()) if err != nil { log.Error().Err(err).Msg("Failed to get geometry point") continue } - cell, err := h3.LatLngToCell(p, i) + scaled, err := cell.Parent(i) if err != nil { - log.Error().Err(err).Msg("Failed to get cell") + log.Error().Err(err).Int("resolution", i).Msg("Failed to get cell's parent at resolution") continue } - //log.Info().Float64("X", p.GeometryX).Float64("Y", p.GeometryY).Str("cell", cell.String()).Msg("Converted lat/lng") - cellToCount[cell] = cellToCount[cell] + 1 + cellToCount[scaled] = cellToCount[scaled] + 1 } var to_insert []bob.Mod[*dialect.InsertQuery] = make([]bob.Mod[*dialect.InsertQuery], 0) to_insert = append(to_insert, im.Into("h3_aggregation", "cell", "resolution", "count_", "type_", "organization_id", "geometry")) @@ -1620,5 +1622,3 @@ func exportFieldseekerLayer(ctx context.Context, org *models.Organization, fssyn log.Info().Uint("inserts", stats.Inserts).Uint("updates", stats.Updates).Uint("no change", stats.Unchanged).Str("layer", layer.Name).Msg("Finished layer") return stats, nil } - - diff --git a/db/dbinfo/fieldseeker.pointlocation.bob.go b/db/dbinfo/fieldseeker.pointlocation.bob.go index e029258e..9319d3d7 100644 --- a/db/dbinfo/fieldseeker.pointlocation.bob.go +++ b/db/dbinfo/fieldseeker.pointlocation.bob.go @@ -447,6 +447,15 @@ var FieldseekerPointlocations = Table[ Generated: false, AutoIncr: false, }, + H3cell: column{ + Name: "h3cell", + DBType: "h3index", + Default: "GENERATED", + Comment: "", + Nullable: true, + Generated: true, + AutoIncr: false, + }, }, Indexes: fieldseekerPointlocationIndexes{ PointlocationPkey: index{ @@ -541,11 +550,12 @@ type fieldseekerPointlocationColumns struct { Geospatial column Version column OrganizationID column + H3cell column } func (c fieldseekerPointlocationColumns) 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.Symbology, c.Externalid, c.Nextactiondatescheduled, c.Larvinspectinterval, c.Zone2, c.Locationnumber, c.Globalid, c.Stype, c.Lastinspectdate, c.Lastinspectbreeding, c.Lastinspectavglarvae, c.Lastinspectavgpupae, c.Lastinspectlstages, c.Lastinspectactiontaken, c.Lastinspectfieldspecies, c.Lasttreatdate, c.Lasttreatproduct, c.Lasttreatqty, c.Lasttreatqtyunit, c.Lastinspectactivity, c.Lasttreatactivity, c.Lastinspectconditions, c.Waterorigin, c.X, c.Y, c.Assignedtech, c.Creationdate, c.Creator, c.Editdate, c.Editor, c.Jurisdiction, c.DeactivateReason, c.Scalarpriority, c.Sourcestatus, 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.Symbology, c.Externalid, c.Nextactiondatescheduled, c.Larvinspectinterval, c.Zone2, c.Locationnumber, c.Globalid, c.Stype, c.Lastinspectdate, c.Lastinspectbreeding, c.Lastinspectavglarvae, c.Lastinspectavgpupae, c.Lastinspectlstages, c.Lastinspectactiontaken, c.Lastinspectfieldspecies, c.Lasttreatdate, c.Lasttreatproduct, c.Lasttreatqty, c.Lasttreatqtyunit, c.Lastinspectactivity, c.Lasttreatactivity, c.Lastinspectconditions, c.Waterorigin, c.X, c.Y, c.Assignedtech, c.Creationdate, c.Creator, c.Editdate, c.Editor, c.Jurisdiction, c.DeactivateReason, c.Scalarpriority, c.Sourcestatus, c.Geometry, c.Geospatial, c.Version, c.OrganizationID, c.H3cell, } } diff --git a/db/dbinfo/fieldseeker.servicerequest.bob.go b/db/dbinfo/fieldseeker.servicerequest.bob.go index ec5161d7..cf973996 100644 --- a/db/dbinfo/fieldseeker.servicerequest.bob.go +++ b/db/dbinfo/fieldseeker.servicerequest.bob.go @@ -825,6 +825,15 @@ var FieldseekerServicerequests = Table[ Generated: false, AutoIncr: false, }, + H3cell: column{ + Name: "h3cell", + DBType: "h3index", + Default: "GENERATED", + Comment: "", + Nullable: true, + Generated: true, + AutoIncr: false, + }, }, Indexes: fieldseekerServicerequestIndexes{ ServicerequestPkey: index{ @@ -961,11 +970,12 @@ type fieldseekerServicerequestColumns struct { Geospatial column Version column OrganizationID column + H3cell column } func (c fieldseekerServicerequestColumns) AsSlice() []column { return []column{ - c.Objectid, c.Recdatetime, c.Source, c.Entrytech, c.Priority, c.Supervisor, c.Assignedtech, c.Status, c.Clranon, c.Clrfname, c.Clrphone1, c.Clrphone2, c.Clremail, c.Clrcompany, c.Clraddr1, c.Clraddr2, c.Clrcity, c.Clrstate, c.Clrzip, c.Clrother, c.Clrcontpref, c.Reqcompany, c.Reqaddr1, c.Reqaddr2, c.Reqcity, c.Reqstate, c.Reqzip, c.Reqcrossst, c.Reqsubdiv, c.Reqmapgrid, c.Reqpermission, c.Reqtarget, c.Reqdescr, c.Reqnotesfortech, c.Reqnotesforcust, c.Reqfldnotes, c.Reqprogramactions, c.Datetimeclosed, c.Techclosed, c.SRNumber, c.Reviewed, c.Reviewedby, c.Revieweddate, c.Accepted, c.Accepteddate, c.Rejectedby, c.Rejecteddate, c.Rejectedreason, c.Duedate, c.Acceptedby, c.Comments, c.Estcompletedate, c.Nextaction, c.Recordstatus, c.Globalid, c.CreatedUser, c.CreatedDate, c.LastEditedUser, c.LastEditedDate, c.Firstresponsedate, c.Responsedaycount, c.Allowed, c.Xvalue, c.Yvalue, c.Validx, c.Validy, c.Externalid, c.Externalerror, c.Pointlocid, c.Notified, c.Notifieddate, c.Scheduled, c.Scheduleddate, c.Dog, c.SchedulePeriod, c.ScheduleNotes, c.Spanish, c.Creationdate, c.Creator, c.Editdate, c.Editor, c.Issuesreported, c.Jurisdiction, c.Notificationtimestamp, c.Zone, c.Zone2, c.Geometry, c.Geospatial, c.Version, c.OrganizationID, + c.Objectid, c.Recdatetime, c.Source, c.Entrytech, c.Priority, c.Supervisor, c.Assignedtech, c.Status, c.Clranon, c.Clrfname, c.Clrphone1, c.Clrphone2, c.Clremail, c.Clrcompany, c.Clraddr1, c.Clraddr2, c.Clrcity, c.Clrstate, c.Clrzip, c.Clrother, c.Clrcontpref, c.Reqcompany, c.Reqaddr1, c.Reqaddr2, c.Reqcity, c.Reqstate, c.Reqzip, c.Reqcrossst, c.Reqsubdiv, c.Reqmapgrid, c.Reqpermission, c.Reqtarget, c.Reqdescr, c.Reqnotesfortech, c.Reqnotesforcust, c.Reqfldnotes, c.Reqprogramactions, c.Datetimeclosed, c.Techclosed, c.SRNumber, c.Reviewed, c.Reviewedby, c.Revieweddate, c.Accepted, c.Accepteddate, c.Rejectedby, c.Rejecteddate, c.Rejectedreason, c.Duedate, c.Acceptedby, c.Comments, c.Estcompletedate, c.Nextaction, c.Recordstatus, c.Globalid, c.CreatedUser, c.CreatedDate, c.LastEditedUser, c.LastEditedDate, c.Firstresponsedate, c.Responsedaycount, c.Allowed, c.Xvalue, c.Yvalue, c.Validx, c.Validy, c.Externalid, c.Externalerror, c.Pointlocid, c.Notified, c.Notifieddate, c.Scheduled, c.Scheduleddate, c.Dog, c.SchedulePeriod, c.ScheduleNotes, c.Spanish, c.Creationdate, c.Creator, c.Editdate, c.Editor, c.Issuesreported, c.Jurisdiction, c.Notificationtimestamp, c.Zone, c.Zone2, c.Geometry, c.Geospatial, c.Version, c.OrganizationID, c.H3cell, } } diff --git a/db/dbinfo/fieldseeker.trapdata.bob.go b/db/dbinfo/fieldseeker.trapdata.bob.go index 9de37a74..94712d67 100644 --- a/db/dbinfo/fieldseeker.trapdata.bob.go +++ b/db/dbinfo/fieldseeker.trapdata.bob.go @@ -429,6 +429,15 @@ var FieldseekerTrapdata = Table[ Generated: false, AutoIncr: false, }, + H3cell: column{ + Name: "h3cell", + DBType: "h3index", + Default: "GENERATED", + Comment: "", + Nullable: true, + Generated: true, + AutoIncr: false, + }, }, Indexes: fieldseekerTrapdatumIndexes{ TrapdataPkey: index{ @@ -521,11 +530,12 @@ type fieldseekerTrapdatumColumns struct { Geospatial column Version column OrganizationID column + H3cell column } func (c fieldseekerTrapdatumColumns) AsSlice() []column { return []column{ - c.Objectid, c.Traptype, c.Trapactivitytype, c.Startdatetime, c.Enddatetime, c.Comments, c.Idbytech, c.Sortbytech, c.Processed, c.Sitecond, c.Locationname, c.Recordstatus, c.Reviewed, c.Reviewedby, c.Revieweddate, c.Trapcondition, c.Trapnights, c.Zone, c.Zone2, c.Globalid, c.CreatedUser, c.CreatedDate, c.LastEditedUser, c.LastEditedDate, c.Srid, c.Fieldtech, c.Gatewaysync, c.LocID, c.Voltage, c.Winddir, c.Windspeed, c.Avetemp, c.Raingauge, c.LR, c.Field, c.Vectorsurvtrapdataid, c.Vectorsurvtraplocationid, c.Creationdate, c.Creator, c.Editdate, c.Editor, c.Lure, c.Geometry, c.Geospatial, c.Version, c.OrganizationID, + c.Objectid, c.Traptype, c.Trapactivitytype, c.Startdatetime, c.Enddatetime, c.Comments, c.Idbytech, c.Sortbytech, c.Processed, c.Sitecond, c.Locationname, c.Recordstatus, c.Reviewed, c.Reviewedby, c.Revieweddate, c.Trapcondition, c.Trapnights, c.Zone, c.Zone2, c.Globalid, c.CreatedUser, c.CreatedDate, c.LastEditedUser, c.LastEditedDate, c.Srid, c.Fieldtech, c.Gatewaysync, c.LocID, c.Voltage, c.Winddir, c.Windspeed, c.Avetemp, c.Raingauge, c.LR, c.Field, c.Vectorsurvtrapdataid, c.Vectorsurvtraplocationid, c.Creationdate, c.Creator, c.Editdate, c.Editor, c.Lure, c.Geometry, c.Geospatial, c.Version, c.OrganizationID, c.H3cell, } } diff --git a/db/dbinfo/fieldseeker.treatment.bob.go b/db/dbinfo/fieldseeker.treatment.bob.go index 13f82b20..df9a36db 100644 --- a/db/dbinfo/fieldseeker.treatment.bob.go +++ b/db/dbinfo/fieldseeker.treatment.bob.go @@ -537,6 +537,15 @@ var FieldseekerTreatments = Table[ Generated: false, AutoIncr: false, }, + H3cell: column{ + Name: "h3cell", + DBType: "h3index", + Default: "GENERATED", + Comment: "", + Nullable: true, + Generated: true, + AutoIncr: false, + }, }, Indexes: fieldseekerTreatmentIndexes{ TreatmentPkey: index{ @@ -641,11 +650,12 @@ type fieldseekerTreatmentColumns struct { Geospatial column Version column OrganizationID column + H3cell column } func (c fieldseekerTreatmentColumns) AsSlice() []column { return []column{ - c.Objectid, c.Activity, c.Treatarea, c.Areaunit, c.Product, c.Qty, c.Qtyunit, c.Method, c.Equiptype, c.Comments, c.Avetemp, c.Windspeed, c.Winddir, c.Raingauge, c.Startdatetime, c.Enddatetime, c.InspID, c.Reviewed, c.Reviewedby, c.Revieweddate, c.Locationname, c.Zone, c.Warningoverride, c.Recordstatus, c.Zone2, c.Treatacres, c.Tirecount, c.Cbcount, c.Containercount, c.Globalid, c.Treatmentlength, c.Treatmenthours, c.Treatmentlengthunits, c.Linelocid, c.Pointlocid, c.Polygonlocid, c.Srid, c.Sdid, c.Barrierrouteid, c.Ulvrouteid, c.Fieldtech, c.Ptaid, c.Flowrate, c.Habitat, c.Treathectares, c.Invloc, c.TempSitecond, c.Sitecond, c.Totalcostprodcut, c.Creationdate, c.Creator, c.Editdate, c.Editor, c.Targetspecies, c.Geometry, c.Geospatial, c.Version, c.OrganizationID, + c.Objectid, c.Activity, c.Treatarea, c.Areaunit, c.Product, c.Qty, c.Qtyunit, c.Method, c.Equiptype, c.Comments, c.Avetemp, c.Windspeed, c.Winddir, c.Raingauge, c.Startdatetime, c.Enddatetime, c.InspID, c.Reviewed, c.Reviewedby, c.Revieweddate, c.Locationname, c.Zone, c.Warningoverride, c.Recordstatus, c.Zone2, c.Treatacres, c.Tirecount, c.Cbcount, c.Containercount, c.Globalid, c.Treatmentlength, c.Treatmenthours, c.Treatmentlengthunits, c.Linelocid, c.Pointlocid, c.Polygonlocid, c.Srid, c.Sdid, c.Barrierrouteid, c.Ulvrouteid, c.Fieldtech, c.Ptaid, c.Flowrate, c.Habitat, c.Treathectares, c.Invloc, c.TempSitecond, c.Sitecond, c.Totalcostprodcut, c.Creationdate, c.Creator, c.Editdate, c.Editor, c.Targetspecies, c.Geometry, c.Geospatial, c.Version, c.OrganizationID, c.H3cell, } } diff --git a/db/factory/bobfactory_main.bob.go b/db/factory/bobfactory_main.bob.go index 29b86e21..17d2a5a8 100644 --- a/db/factory/bobfactory_main.bob.go +++ b/db/factory/bobfactory_main.bob.go @@ -585,6 +585,7 @@ func (f *Factory) FromExistingFieldseekerPointlocation(m *models.FieldseekerPoin 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 { @@ -1238,6 +1239,7 @@ func (f *Factory) FromExistingFieldseekerServicerequest(m *models.FieldseekerSer 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 { @@ -1484,6 +1486,7 @@ func (f *Factory) FromExistingFieldseekerTrapdatum(m *models.FieldseekerTrapdatu 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 { @@ -1632,6 +1635,7 @@ func (f *Factory) FromExistingFieldseekerTreatment(m *models.FieldseekerTreatmen 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 { diff --git a/db/factory/fieldseeker.pointlocation.bob.go b/db/factory/fieldseeker.pointlocation.bob.go index 39f9071b..201db192 100644 --- a/db/factory/fieldseeker.pointlocation.bob.go +++ b/db/factory/fieldseeker.pointlocation.bob.go @@ -88,6 +88,7 @@ type FieldseekerPointlocationTemplate struct { Geospatial func() null.Val[string] Version func() int32 OrganizationID func() int32 + H3cell func() null.Val[string] r fieldseekerPointlocationR f *Factory @@ -484,6 +485,9 @@ func (o FieldseekerPointlocationTemplate) Build() *models.FieldseekerPointlocati if o.OrganizationID != nil { m.OrganizationID = o.OrganizationID() } + if o.H3cell != nil { + m.H3cell = o.H3cell() + } o.setModelRels(m) @@ -683,6 +687,7 @@ func (m fieldseekerPointlocationMods) RandomizeAllColumns(f *faker.Faker) Fields FieldseekerPointlocationMods.RandomGeospatial(f), FieldseekerPointlocationMods.RandomVersion(f), FieldseekerPointlocationMods.RandomOrganizationID(f), + FieldseekerPointlocationMods.RandomH3cell(f), } } @@ -3120,6 +3125,59 @@ func (m fieldseekerPointlocationMods) RandomOrganizationID(f *faker.Faker) Field }) } +// Set the model columns to this value +func (m fieldseekerPointlocationMods) H3cell(val null.Val[string]) FieldseekerPointlocationMod { + return FieldseekerPointlocationModFunc(func(_ context.Context, o *FieldseekerPointlocationTemplate) { + o.H3cell = func() null.Val[string] { return val } + }) +} + +// Set the Column from the function +func (m fieldseekerPointlocationMods) H3cellFunc(f func() null.Val[string]) FieldseekerPointlocationMod { + return FieldseekerPointlocationModFunc(func(_ context.Context, o *FieldseekerPointlocationTemplate) { + o.H3cell = f + }) +} + +// Clear any values for the column +func (m fieldseekerPointlocationMods) UnsetH3cell() FieldseekerPointlocationMod { + return FieldseekerPointlocationModFunc(func(_ context.Context, o *FieldseekerPointlocationTemplate) { + 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 fieldseekerPointlocationMods) RandomH3cell(f *faker.Faker) FieldseekerPointlocationMod { + return FieldseekerPointlocationModFunc(func(_ context.Context, o *FieldseekerPointlocationTemplate) { + 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 fieldseekerPointlocationMods) RandomH3cellNotNull(f *faker.Faker) FieldseekerPointlocationMod { + return FieldseekerPointlocationModFunc(func(_ context.Context, o *FieldseekerPointlocationTemplate) { + o.H3cell = func() null.Val[string] { + if f == nil { + f = &defaultFaker + } + + val := random_string(f) + return null.From(val) + } + }) +} + func (m fieldseekerPointlocationMods) WithParentsCascading() FieldseekerPointlocationMod { return FieldseekerPointlocationModFunc(func(ctx context.Context, o *FieldseekerPointlocationTemplate) { if isDone, _ := fieldseekerPointlocationWithParentsCascadingCtx.Value(ctx); isDone { diff --git a/db/factory/fieldseeker.servicerequest.bob.go b/db/factory/fieldseeker.servicerequest.bob.go index ee638743..bbc25592 100644 --- a/db/factory/fieldseeker.servicerequest.bob.go +++ b/db/factory/fieldseeker.servicerequest.bob.go @@ -130,6 +130,7 @@ type FieldseekerServicerequestTemplate struct { Geospatial func() null.Val[string] Version func() int32 OrganizationID func() int32 + H3cell func() null.Val[string] r fieldseekerServicerequestR f *Factory @@ -820,6 +821,9 @@ func (o FieldseekerServicerequestTemplate) Build() *models.FieldseekerServicereq if o.OrganizationID != nil { m.OrganizationID = o.OrganizationID() } + if o.H3cell != nil { + m.H3cell = o.H3cell() + } o.setModelRels(m) @@ -1061,6 +1065,7 @@ func (m fieldseekerServicerequestMods) RandomizeAllColumns(f *faker.Faker) Field FieldseekerServicerequestMods.RandomGeospatial(f), FieldseekerServicerequestMods.RandomVersion(f), FieldseekerServicerequestMods.RandomOrganizationID(f), + FieldseekerServicerequestMods.RandomH3cell(f), } } @@ -5724,6 +5729,59 @@ func (m fieldseekerServicerequestMods) RandomOrganizationID(f *faker.Faker) Fiel }) } +// Set the model columns to this value +func (m fieldseekerServicerequestMods) H3cell(val null.Val[string]) FieldseekerServicerequestMod { + return FieldseekerServicerequestModFunc(func(_ context.Context, o *FieldseekerServicerequestTemplate) { + o.H3cell = func() null.Val[string] { return val } + }) +} + +// Set the Column from the function +func (m fieldseekerServicerequestMods) H3cellFunc(f func() null.Val[string]) FieldseekerServicerequestMod { + return FieldseekerServicerequestModFunc(func(_ context.Context, o *FieldseekerServicerequestTemplate) { + o.H3cell = f + }) +} + +// Clear any values for the column +func (m fieldseekerServicerequestMods) UnsetH3cell() FieldseekerServicerequestMod { + return FieldseekerServicerequestModFunc(func(_ context.Context, o *FieldseekerServicerequestTemplate) { + 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 fieldseekerServicerequestMods) RandomH3cell(f *faker.Faker) FieldseekerServicerequestMod { + return FieldseekerServicerequestModFunc(func(_ context.Context, o *FieldseekerServicerequestTemplate) { + 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 fieldseekerServicerequestMods) RandomH3cellNotNull(f *faker.Faker) FieldseekerServicerequestMod { + return FieldseekerServicerequestModFunc(func(_ context.Context, o *FieldseekerServicerequestTemplate) { + o.H3cell = func() null.Val[string] { + if f == nil { + f = &defaultFaker + } + + val := random_string(f) + return null.From(val) + } + }) +} + func (m fieldseekerServicerequestMods) WithParentsCascading() FieldseekerServicerequestMod { return FieldseekerServicerequestModFunc(func(ctx context.Context, o *FieldseekerServicerequestTemplate) { if isDone, _ := fieldseekerServicerequestWithParentsCascadingCtx.Value(ctx); isDone { diff --git a/db/factory/fieldseeker.trapdata.bob.go b/db/factory/fieldseeker.trapdata.bob.go index 658febea..9916136e 100644 --- a/db/factory/fieldseeker.trapdata.bob.go +++ b/db/factory/fieldseeker.trapdata.bob.go @@ -86,6 +86,7 @@ type FieldseekerTrapdatumTemplate struct { Geospatial func() null.Val[string] Version func() int32 OrganizationID func() int32 + H3cell func() null.Val[string] r fieldseekerTrapdatumR f *Factory @@ -468,6 +469,9 @@ func (o FieldseekerTrapdatumTemplate) Build() *models.FieldseekerTrapdatum { if o.OrganizationID != nil { m.OrganizationID = o.OrganizationID() } + if o.H3cell != nil { + m.H3cell = o.H3cell() + } o.setModelRels(m) @@ -665,6 +669,7 @@ func (m fieldseekerTrapdatumMods) RandomizeAllColumns(f *faker.Faker) Fieldseeke FieldseekerTrapdatumMods.RandomGeospatial(f), FieldseekerTrapdatumMods.RandomVersion(f), FieldseekerTrapdatumMods.RandomOrganizationID(f), + FieldseekerTrapdatumMods.RandomH3cell(f), } } @@ -2996,6 +3001,59 @@ func (m fieldseekerTrapdatumMods) RandomOrganizationID(f *faker.Faker) Fieldseek }) } +// Set the model columns to this value +func (m fieldseekerTrapdatumMods) H3cell(val null.Val[string]) FieldseekerTrapdatumMod { + return FieldseekerTrapdatumModFunc(func(_ context.Context, o *FieldseekerTrapdatumTemplate) { + o.H3cell = func() null.Val[string] { return val } + }) +} + +// Set the Column from the function +func (m fieldseekerTrapdatumMods) H3cellFunc(f func() null.Val[string]) FieldseekerTrapdatumMod { + return FieldseekerTrapdatumModFunc(func(_ context.Context, o *FieldseekerTrapdatumTemplate) { + o.H3cell = f + }) +} + +// Clear any values for the column +func (m fieldseekerTrapdatumMods) UnsetH3cell() FieldseekerTrapdatumMod { + return FieldseekerTrapdatumModFunc(func(_ context.Context, o *FieldseekerTrapdatumTemplate) { + 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 fieldseekerTrapdatumMods) RandomH3cell(f *faker.Faker) FieldseekerTrapdatumMod { + return FieldseekerTrapdatumModFunc(func(_ context.Context, o *FieldseekerTrapdatumTemplate) { + 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 fieldseekerTrapdatumMods) RandomH3cellNotNull(f *faker.Faker) FieldseekerTrapdatumMod { + return FieldseekerTrapdatumModFunc(func(_ context.Context, o *FieldseekerTrapdatumTemplate) { + o.H3cell = func() null.Val[string] { + if f == nil { + f = &defaultFaker + } + + val := random_string(f) + return null.From(val) + } + }) +} + func (m fieldseekerTrapdatumMods) WithParentsCascading() FieldseekerTrapdatumMod { return FieldseekerTrapdatumModFunc(func(ctx context.Context, o *FieldseekerTrapdatumTemplate) { if isDone, _ := fieldseekerTrapdatumWithParentsCascadingCtx.Value(ctx); isDone { diff --git a/db/factory/fieldseeker.treatment.bob.go b/db/factory/fieldseeker.treatment.bob.go index fbde2bfb..862bb58e 100644 --- a/db/factory/fieldseeker.treatment.bob.go +++ b/db/factory/fieldseeker.treatment.bob.go @@ -98,6 +98,7 @@ type FieldseekerTreatmentTemplate struct { Geospatial func() null.Val[string] Version func() int32 OrganizationID func() int32 + H3cell func() null.Val[string] r fieldseekerTreatmentR f *Factory @@ -564,6 +565,9 @@ func (o FieldseekerTreatmentTemplate) Build() *models.FieldseekerTreatment { if o.OrganizationID != nil { m.OrganizationID = o.OrganizationID() } + if o.H3cell != nil { + m.H3cell = o.H3cell() + } o.setModelRels(m) @@ -773,6 +777,7 @@ func (m fieldseekerTreatmentMods) RandomizeAllColumns(f *faker.Faker) Fieldseeke FieldseekerTreatmentMods.RandomGeospatial(f), FieldseekerTreatmentMods.RandomVersion(f), FieldseekerTreatmentMods.RandomOrganizationID(f), + FieldseekerTreatmentMods.RandomH3cell(f), } } @@ -3740,6 +3745,59 @@ func (m fieldseekerTreatmentMods) RandomOrganizationID(f *faker.Faker) Fieldseek }) } +// Set the model columns to this value +func (m fieldseekerTreatmentMods) H3cell(val null.Val[string]) FieldseekerTreatmentMod { + return FieldseekerTreatmentModFunc(func(_ context.Context, o *FieldseekerTreatmentTemplate) { + o.H3cell = func() null.Val[string] { return val } + }) +} + +// Set the Column from the function +func (m fieldseekerTreatmentMods) H3cellFunc(f func() null.Val[string]) FieldseekerTreatmentMod { + return FieldseekerTreatmentModFunc(func(_ context.Context, o *FieldseekerTreatmentTemplate) { + o.H3cell = f + }) +} + +// Clear any values for the column +func (m fieldseekerTreatmentMods) UnsetH3cell() FieldseekerTreatmentMod { + return FieldseekerTreatmentModFunc(func(_ context.Context, o *FieldseekerTreatmentTemplate) { + 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 fieldseekerTreatmentMods) RandomH3cell(f *faker.Faker) FieldseekerTreatmentMod { + return FieldseekerTreatmentModFunc(func(_ context.Context, o *FieldseekerTreatmentTemplate) { + 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 fieldseekerTreatmentMods) RandomH3cellNotNull(f *faker.Faker) FieldseekerTreatmentMod { + return FieldseekerTreatmentModFunc(func(_ context.Context, o *FieldseekerTreatmentTemplate) { + o.H3cell = func() null.Val[string] { + if f == nil { + f = &defaultFaker + } + + val := random_string(f) + return null.From(val) + } + }) +} + func (m fieldseekerTreatmentMods) WithParentsCascading() FieldseekerTreatmentMod { return FieldseekerTreatmentModFunc(func(ctx context.Context, o *FieldseekerTreatmentTemplate) { if isDone, _ := fieldseekerTreatmentWithParentsCascadingCtx.Value(ctx); isDone { diff --git a/db/migrations/00022_h3cell_fieldseeker_tables.sql b/db/migrations/00022_h3cell_fieldseeker_tables.sql index 7b6cf8b2..851376df 100644 --- a/db/migrations/00022_h3cell_fieldseeker_tables.sql +++ b/db/migrations/00022_h3cell_fieldseeker_tables.sql @@ -1,9 +1,11 @@ -- +goose Up ALTER TABLE fieldseeker.pointlocation ADD COLUMN h3cell h3index GENERATED ALWAYS AS (h3_latlng_to_cell(geospatial, 15)) STORED; ALTER TABLE fieldseeker.servicerequest ADD COLUMN h3cell h3index GENERATED ALWAYS AS (h3_latlng_to_cell(geospatial, 15)) STORED; +ALTER TABLE fieldseeker.trapdata ADD COLUMN h3cell h3index GENERATED ALWAYS AS (h3_latlng_to_cell(geospatial, 15)) STORED; ALTER TABLE fieldseeker.treatment ADD COLUMN h3cell h3index GENERATED ALWAYS AS (h3_latlng_to_cell(geospatial, 15)) STORED; -- +goose Down ALTER TABLE fieldseeker.pointlocation DROP COLUMN h3cell; ALTER TABLE fieldseeker.servicerequest DROP COLUMN h3cell; +ALTER TABLE fieldseeker.trapdata DROP COLUMN h3cell; ALTER TABLE fieldseeker.treatment DROP COLUMN h3cell; diff --git a/db/models/fieldseeker.pointlocation.bob.go b/db/models/fieldseeker.pointlocation.bob.go index a7e44da4..7aa99cdb 100644 --- a/db/models/fieldseeker.pointlocation.bob.go +++ b/db/models/fieldseeker.pointlocation.bob.go @@ -120,6 +120,7 @@ type FieldseekerPointlocation 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 fieldseekerPointlocationR `db:"-" ` } @@ -142,7 +143,7 @@ type fieldseekerPointlocationR struct { func buildFieldseekerPointlocationColumns(alias string) fieldseekerPointlocationColumns { return fieldseekerPointlocationColumns{ ColumnsExpr: expr.NewColumnsExpr( - "objectid", "name", "zone", "habitat", "priority", "usetype", "active", "description", "accessdesc", "comments", "symbology", "externalid", "nextactiondatescheduled", "larvinspectinterval", "zone2", "locationnumber", "globalid", "stype", "lastinspectdate", "lastinspectbreeding", "lastinspectavglarvae", "lastinspectavgpupae", "lastinspectlstages", "lastinspectactiontaken", "lastinspectfieldspecies", "lasttreatdate", "lasttreatproduct", "lasttreatqty", "lasttreatqtyunit", "lastinspectactivity", "lasttreatactivity", "lastinspectconditions", "waterorigin", "x", "y", "assignedtech", "creationdate", "creator", "editdate", "editor", "jurisdiction", "deactivate_reason", "scalarpriority", "sourcestatus", "geometry", "geospatial", "version", "organization_id", + "objectid", "name", "zone", "habitat", "priority", "usetype", "active", "description", "accessdesc", "comments", "symbology", "externalid", "nextactiondatescheduled", "larvinspectinterval", "zone2", "locationnumber", "globalid", "stype", "lastinspectdate", "lastinspectbreeding", "lastinspectavglarvae", "lastinspectavgpupae", "lastinspectlstages", "lastinspectactiontaken", "lastinspectfieldspecies", "lasttreatdate", "lasttreatproduct", "lasttreatqty", "lasttreatqtyunit", "lastinspectactivity", "lasttreatactivity", "lastinspectconditions", "waterorigin", "x", "y", "assignedtech", "creationdate", "creator", "editdate", "editor", "jurisdiction", "deactivate_reason", "scalarpriority", "sourcestatus", "geometry", "geospatial", "version", "organization_id", "h3cell", ).WithParent("fieldseeker.pointlocation"), tableAlias: alias, Objectid: psql.Quote(alias, "objectid"), @@ -193,6 +194,7 @@ func buildFieldseekerPointlocationColumns(alias string) fieldseekerPointlocation Geospatial: psql.Quote(alias, "geospatial"), Version: psql.Quote(alias, "version"), OrganizationID: psql.Quote(alias, "organization_id"), + H3cell: psql.Quote(alias, "h3cell"), } } @@ -247,6 +249,7 @@ type fieldseekerPointlocationColumns struct { Geospatial psql.Expression Version psql.Expression OrganizationID psql.Expression + H3cell psql.Expression } func (c fieldseekerPointlocationColumns) Alias() string { @@ -1606,6 +1609,7 @@ type fieldseekerPointlocationWhere[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 (fieldseekerPointlocationWhere[Q]) AliasedAs(alias string) fieldseekerPointlocationWhere[Q] { @@ -1662,6 +1666,7 @@ func buildFieldseekerPointlocationWhere[Q psql.Filterable](cols fieldseekerPoint 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), } } diff --git a/db/models/fieldseeker.servicerequest.bob.go b/db/models/fieldseeker.servicerequest.bob.go index df144bc1..7c4cab03 100644 --- a/db/models/fieldseeker.servicerequest.bob.go +++ b/db/models/fieldseeker.servicerequest.bob.go @@ -204,6 +204,7 @@ type FieldseekerServicerequest 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 fieldseekerServicerequestR `db:"-" ` } @@ -226,7 +227,7 @@ type fieldseekerServicerequestR struct { func buildFieldseekerServicerequestColumns(alias string) fieldseekerServicerequestColumns { return fieldseekerServicerequestColumns{ ColumnsExpr: expr.NewColumnsExpr( - "objectid", "recdatetime", "source", "entrytech", "priority", "supervisor", "assignedtech", "status", "clranon", "clrfname", "clrphone1", "clrphone2", "clremail", "clrcompany", "clraddr1", "clraddr2", "clrcity", "clrstate", "clrzip", "clrother", "clrcontpref", "reqcompany", "reqaddr1", "reqaddr2", "reqcity", "reqstate", "reqzip", "reqcrossst", "reqsubdiv", "reqmapgrid", "reqpermission", "reqtarget", "reqdescr", "reqnotesfortech", "reqnotesforcust", "reqfldnotes", "reqprogramactions", "datetimeclosed", "techclosed", "sr_number", "reviewed", "reviewedby", "revieweddate", "accepted", "accepteddate", "rejectedby", "rejecteddate", "rejectedreason", "duedate", "acceptedby", "comments", "estcompletedate", "nextaction", "recordstatus", "globalid", "created_user", "created_date", "last_edited_user", "last_edited_date", "firstresponsedate", "responsedaycount", "allowed", "xvalue", "yvalue", "validx", "validy", "externalid", "externalerror", "pointlocid", "notified", "notifieddate", "scheduled", "scheduleddate", "dog", "schedule_period", "schedule_notes", "spanish", "creationdate", "creator", "editdate", "editor", "issuesreported", "jurisdiction", "notificationtimestamp", "zone", "zone2", "geometry", "geospatial", "version", "organization_id", + "objectid", "recdatetime", "source", "entrytech", "priority", "supervisor", "assignedtech", "status", "clranon", "clrfname", "clrphone1", "clrphone2", "clremail", "clrcompany", "clraddr1", "clraddr2", "clrcity", "clrstate", "clrzip", "clrother", "clrcontpref", "reqcompany", "reqaddr1", "reqaddr2", "reqcity", "reqstate", "reqzip", "reqcrossst", "reqsubdiv", "reqmapgrid", "reqpermission", "reqtarget", "reqdescr", "reqnotesfortech", "reqnotesforcust", "reqfldnotes", "reqprogramactions", "datetimeclosed", "techclosed", "sr_number", "reviewed", "reviewedby", "revieweddate", "accepted", "accepteddate", "rejectedby", "rejecteddate", "rejectedreason", "duedate", "acceptedby", "comments", "estcompletedate", "nextaction", "recordstatus", "globalid", "created_user", "created_date", "last_edited_user", "last_edited_date", "firstresponsedate", "responsedaycount", "allowed", "xvalue", "yvalue", "validx", "validy", "externalid", "externalerror", "pointlocid", "notified", "notifieddate", "scheduled", "scheduleddate", "dog", "schedule_period", "schedule_notes", "spanish", "creationdate", "creator", "editdate", "editor", "issuesreported", "jurisdiction", "notificationtimestamp", "zone", "zone2", "geometry", "geospatial", "version", "organization_id", "h3cell", ).WithParent("fieldseeker.servicerequest"), tableAlias: alias, Objectid: psql.Quote(alias, "objectid"), @@ -319,6 +320,7 @@ func buildFieldseekerServicerequestColumns(alias string) fieldseekerServicereque Geospatial: psql.Quote(alias, "geospatial"), Version: psql.Quote(alias, "version"), OrganizationID: psql.Quote(alias, "organization_id"), + H3cell: psql.Quote(alias, "h3cell"), } } @@ -415,6 +417,7 @@ type fieldseekerServicerequestColumns struct { Geospatial psql.Expression Version psql.Expression OrganizationID psql.Expression + H3cell psql.Expression } func (c fieldseekerServicerequestColumns) Alias() string { @@ -2656,6 +2659,7 @@ type fieldseekerServicerequestWhere[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 (fieldseekerServicerequestWhere[Q]) AliasedAs(alias string) fieldseekerServicerequestWhere[Q] { @@ -2754,6 +2758,7 @@ func buildFieldseekerServicerequestWhere[Q psql.Filterable](cols fieldseekerServ 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), } } diff --git a/db/models/fieldseeker.trapdata.bob.go b/db/models/fieldseeker.trapdata.bob.go index c58e7dd2..24166a68 100644 --- a/db/models/fieldseeker.trapdata.bob.go +++ b/db/models/fieldseeker.trapdata.bob.go @@ -116,6 +116,7 @@ type FieldseekerTrapdatum 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 fieldseekerTrapdatumR `db:"-" ` } @@ -138,7 +139,7 @@ type fieldseekerTrapdatumR struct { func buildFieldseekerTrapdatumColumns(alias string) fieldseekerTrapdatumColumns { return fieldseekerTrapdatumColumns{ ColumnsExpr: expr.NewColumnsExpr( - "objectid", "traptype", "trapactivitytype", "startdatetime", "enddatetime", "comments", "idbytech", "sortbytech", "processed", "sitecond", "locationname", "recordstatus", "reviewed", "reviewedby", "revieweddate", "trapcondition", "trapnights", "zone", "zone2", "globalid", "created_user", "created_date", "last_edited_user", "last_edited_date", "srid", "fieldtech", "gatewaysync", "loc_id", "voltage", "winddir", "windspeed", "avetemp", "raingauge", "lr", "field", "vectorsurvtrapdataid", "vectorsurvtraplocationid", "creationdate", "creator", "editdate", "editor", "lure", "geometry", "geospatial", "version", "organization_id", + "objectid", "traptype", "trapactivitytype", "startdatetime", "enddatetime", "comments", "idbytech", "sortbytech", "processed", "sitecond", "locationname", "recordstatus", "reviewed", "reviewedby", "revieweddate", "trapcondition", "trapnights", "zone", "zone2", "globalid", "created_user", "created_date", "last_edited_user", "last_edited_date", "srid", "fieldtech", "gatewaysync", "loc_id", "voltage", "winddir", "windspeed", "avetemp", "raingauge", "lr", "field", "vectorsurvtrapdataid", "vectorsurvtraplocationid", "creationdate", "creator", "editdate", "editor", "lure", "geometry", "geospatial", "version", "organization_id", "h3cell", ).WithParent("fieldseeker.trapdata"), tableAlias: alias, Objectid: psql.Quote(alias, "objectid"), @@ -187,6 +188,7 @@ func buildFieldseekerTrapdatumColumns(alias string) fieldseekerTrapdatumColumns Geospatial: psql.Quote(alias, "geospatial"), Version: psql.Quote(alias, "version"), OrganizationID: psql.Quote(alias, "organization_id"), + H3cell: psql.Quote(alias, "h3cell"), } } @@ -239,6 +241,7 @@ type fieldseekerTrapdatumColumns struct { Geospatial psql.Expression Version psql.Expression OrganizationID psql.Expression + H3cell psql.Expression } func (c fieldseekerTrapdatumColumns) Alias() string { @@ -1556,6 +1559,7 @@ type fieldseekerTrapdatumWhere[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 (fieldseekerTrapdatumWhere[Q]) AliasedAs(alias string) fieldseekerTrapdatumWhere[Q] { @@ -1610,6 +1614,7 @@ func buildFieldseekerTrapdatumWhere[Q psql.Filterable](cols fieldseekerTrapdatum 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), } } diff --git a/db/models/fieldseeker.treatment.bob.go b/db/models/fieldseeker.treatment.bob.go index 699d6641..4e024452 100644 --- a/db/models/fieldseeker.treatment.bob.go +++ b/db/models/fieldseeker.treatment.bob.go @@ -140,6 +140,7 @@ type FieldseekerTreatment 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 fieldseekerTreatmentR `db:"-" ` } @@ -162,7 +163,7 @@ type fieldseekerTreatmentR struct { func buildFieldseekerTreatmentColumns(alias string) fieldseekerTreatmentColumns { return fieldseekerTreatmentColumns{ ColumnsExpr: expr.NewColumnsExpr( - "objectid", "activity", "treatarea", "areaunit", "product", "qty", "qtyunit", "method", "equiptype", "comments", "avetemp", "windspeed", "winddir", "raingauge", "startdatetime", "enddatetime", "insp_id", "reviewed", "reviewedby", "revieweddate", "locationname", "zone", "warningoverride", "recordstatus", "zone2", "treatacres", "tirecount", "cbcount", "containercount", "globalid", "treatmentlength", "treatmenthours", "treatmentlengthunits", "linelocid", "pointlocid", "polygonlocid", "srid", "sdid", "barrierrouteid", "ulvrouteid", "fieldtech", "ptaid", "flowrate", "habitat", "treathectares", "invloc", "temp_sitecond", "sitecond", "totalcostprodcut", "creationdate", "creator", "editdate", "editor", "targetspecies", "geometry", "geospatial", "version", "organization_id", + "objectid", "activity", "treatarea", "areaunit", "product", "qty", "qtyunit", "method", "equiptype", "comments", "avetemp", "windspeed", "winddir", "raingauge", "startdatetime", "enddatetime", "insp_id", "reviewed", "reviewedby", "revieweddate", "locationname", "zone", "warningoverride", "recordstatus", "zone2", "treatacres", "tirecount", "cbcount", "containercount", "globalid", "treatmentlength", "treatmenthours", "treatmentlengthunits", "linelocid", "pointlocid", "polygonlocid", "srid", "sdid", "barrierrouteid", "ulvrouteid", "fieldtech", "ptaid", "flowrate", "habitat", "treathectares", "invloc", "temp_sitecond", "sitecond", "totalcostprodcut", "creationdate", "creator", "editdate", "editor", "targetspecies", "geometry", "geospatial", "version", "organization_id", "h3cell", ).WithParent("fieldseeker.treatment"), tableAlias: alias, Objectid: psql.Quote(alias, "objectid"), @@ -223,6 +224,7 @@ func buildFieldseekerTreatmentColumns(alias string) fieldseekerTreatmentColumns Geospatial: psql.Quote(alias, "geospatial"), Version: psql.Quote(alias, "version"), OrganizationID: psql.Quote(alias, "organization_id"), + H3cell: psql.Quote(alias, "h3cell"), } } @@ -287,6 +289,7 @@ type fieldseekerTreatmentColumns struct { Geospatial psql.Expression Version psql.Expression OrganizationID psql.Expression + H3cell psql.Expression } func (c fieldseekerTreatmentColumns) Alias() string { @@ -1856,6 +1859,7 @@ type fieldseekerTreatmentWhere[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 (fieldseekerTreatmentWhere[Q]) AliasedAs(alias string) fieldseekerTreatmentWhere[Q] { @@ -1922,6 +1926,7 @@ func buildFieldseekerTreatmentWhere[Q psql.Filterable](cols fieldseekerTreatment 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), } } diff --git a/geometry.go b/geometry.go deleted file mode 100644 index 53351928..00000000 --- a/geometry.go +++ /dev/null @@ -1,26 +0,0 @@ -package main -import ( - "encoding/json" - "errors" - //"fmt" - - "github.com/stephenafamo/bob/types" - "github.com/uber/h3-go/v4" -) -func getPoint(geom types.JSON[json.RawMessage]) (h3.LatLng, error) { - /* - I need to figure out how to convert from the weird bob - type of types.JSON[json.RawMessage] to a X/Y coordinate to - here, but I need an Internet connection to do that effectively. - */ - return h3.LatLng{}, errors.New("need to implement this") - /* - msg, err := geom.Value() - if err != nil { - return h3.LatLng{}, fmt.Errorf("Can't get underlying JSON value: %w", err) - } - x := msg.Get("x") - y := msg.Get("y") - return h3.NewLatLng(x, y), nil - */ -} diff --git a/go.mod b/go.mod index c35ea302..709c9e64 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/stephenafamo/bob v0.42.0 github.com/stephenafamo/scan v0.7.0 github.com/tidwall/geojson v1.4.5 - github.com/uber/h3-go/v4 v4.3.0 + github.com/uber/h3-go/v4 v4.4.0 github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07 golang.org/x/crypto v0.42.0 ) diff --git a/go.sum b/go.sum index 3be312f0..adf9caa4 100644 --- a/go.sum +++ b/go.sum @@ -224,6 +224,8 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+F github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/uber/h3-go/v4 v4.3.0 h1:5y5je8gu6+1pGzGo8soiudmgE3WJzfJRWdy0yhc3+HY= github.com/uber/h3-go/v4 v4.3.0/go.mod h1:EyZ/EWguHlheIBcshTAMmQPYcaGKVvJ4qlzEHzC0BkU= +github.com/uber/h3-go/v4 v4.4.0 h1:sCHcZHvIKEbdt4rY5ZVs2HDNlCy2wXeJ98vAbz+iLok= +github.com/uber/h3-go/v4 v4.4.0/go.mod h1:c94kwXZNHVWkZGIN+y9dV81YVEttypqJpOjsmXGr68Y= github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07 h1:mJdDDPblDfPe7z7go8Dvv1AJQDI3eQ/5xith3q2mFlo= github.com/wasilibs/go-pgquery v0.0.0-20250409022910-10ac41983c07/go.mod h1:Ak17IJ037caFp4jpCw/iQQ7/W74Sqpb1YuKJU6HTKfM= github.com/wasilibs/wazero-helpers v0.0.0-20240620070341-3dff1577cd52 h1:OvLBa8SqJnZ6P+mjlzc2K7PM22rRUPE1x32G9DTPrC4= diff --git a/h3.go b/h3.go index c42d4826..ef1feec4 100644 --- a/h3.go +++ b/h3.go @@ -22,6 +22,13 @@ func h3ToBoundsGeoJSON(c h3.Cell) (string, error) { } */ +func toH3Cell(s string) (h3.Cell, error) { + c := h3.CellFromString(s) + if !c.IsValid() { + return c, fmt.Errorf("Invalid cell definition '%s'", s) + } + return c, nil +} func h3ToGeoJSON(indexes []h3.Cell) (interface{}, error) { featureCollection, err := geojson2h3.ToFeatureCollection(indexes) if err != nil { diff --git a/html.go b/html.go index a2bc2a06..562907de 100644 --- a/html.go +++ b/html.go @@ -493,15 +493,20 @@ func htmlSource(w http.ResponseWriter, r *http.Request, user *models.User, id uu return } treatment_models := modelTreatment(treatments) + latlng, err := s.H3Cell.LatLng() + if err != nil { + respondError(w, "Failed to get latlng", err, http.StatusInternalServerError) + return + } data := ContentSource{ Inspections: inspections, MapData: ComponentMap{ - Center: s.LatLng, + Center: latlng, //GeoJSON: MapboxToken: MapboxToken, Markers: []MapMarker{ MapMarker{ - LatLng: s.LatLng, + LatLng: latlng, }, }, Zoom: 13, diff --git a/model_conversion.go b/model_conversion.go index 73232318..8c232e67 100644 --- a/model_conversion.go +++ b/model_conversion.go @@ -38,11 +38,11 @@ type BreedingSourceDetail struct { Symbology string `json:"symbology"` // Geographical Data - LatLng h3.LatLng `json:"latlng"` - Zone string `json:"zone"` - Zone2 string `json:"zone2"` - Jurisdiction string `json:"jurisdiction"` - AccessDescription string `json:"accessDescription"` + H3Cell h3.Cell `json:"h3cell"` + Zone string `json:"zone"` + Zone2 string `json:"zone2"` + Jurisdiction string `json:"jurisdiction"` + AccessDescription string `json:"accessDescription"` // Inspection Data LarvaeInspectInterval int16 `json:"larvaeInspectInterval"` @@ -134,10 +134,9 @@ type TrapData struct { Voltage float64 `json:"voltage"` // Location Data - GeometryX float64 `json:"geometryX"` - GeometryY float64 `json:"geometryY"` - Zone string `json:"zone"` - Zone2 string `json:"zone2"` + H3Cell h3.Cell `json:"h3cell"` + Zone string `json:"zone"` + Zone2 string `json:"zone2"` // Vector Survey IDs VectorSurveyTrapDataID string `json:"vectorSurveyTrapDataId"` @@ -210,9 +209,12 @@ func toTemplateTraps(locations []sql.TrapLocationBySourceIDRow, trap_data []sql. func toTemplateTrapData(trap_data models.FieldseekerTrapdatumSlice) ([]TrapData, error) { var results []TrapData for _, r := range trap_data { - geometry, err := getPoint(r.Geometry) + if r.H3cell.IsNull() { + continue + } + cell, err := toH3Cell(r.H3cell.MustGet()) if err != nil { - log.Error().Err(err).Msg("Failed to get geometry for trap data") + log.Error().Err(err).Msg("Failed to get location for trap data") continue } results = append(results, TrapData{ @@ -259,10 +261,9 @@ func toTemplateTrapData(trap_data models.FieldseekerTrapdatumSlice) ([]TrapData, Voltage: r.Voltage.GetOr(0), // Location Data - GeometryX: geometry.Lng, - GeometryY: geometry.Lat, - Zone: r.Zone.GetOr(""), - Zone2: r.Zone2.GetOr(""), + H3Cell: cell, + Zone: r.Zone.GetOr(""), + Zone2: r.Zone2.GetOr(""), // Vector Survey IDs VectorSurveyTrapDataID: r.Vectorsurvtrapdataid.GetOr(""), @@ -331,9 +332,13 @@ func fsIntToBool(val null.Val[int16]) bool { // toTemplateBreedingSource transforms the DB model into the display model func toTemplateBreedingSource(source *models.FieldseekerPointlocation) *BreedingSourceDetail { - lat_lng, err := getPoint(source.Geometry) + if source.H3cell.IsNull() { + log.Error().Msg("h3 cell is null") + return nil + } + cell, err := toH3Cell(source.H3cell.MustGet()) if err != nil { - log.Error().Err(err).Msg("Failed to get point from point location") + log.Error().Err(err).Msg("Failed to get h3 cell from point location") return nil } return &BreedingSourceDetail{ @@ -361,7 +366,7 @@ func toTemplateBreedingSource(source *models.FieldseekerPointlocation) *Breeding Symbology: source.Symbology.GetOr(""), // Geographical Data - LatLng: lat_lng, + H3Cell: cell, Zone: source.Zone.GetOr(""), Zone2: source.Zone2.GetOr(""), Jurisdiction: source.Jurisdiction.GetOr(""),