Fill in correct data about the district

This commit is contained in:
Eli Ribble 2026-02-16 15:26:41 +00:00
parent a1cc2dbaff
commit f859e372c6
No known key found for this signature in database
9 changed files with 244 additions and 66 deletions

View file

@ -240,6 +240,15 @@ var ImportDistricts = Table[
Generated: true,
AutoIncr: false,
},
Area4326SQM: column{
Name: "area_4326_sqm",
DBType: "numeric",
Default: "GENERATED",
Comment: "",
Nullable: true,
Generated: true,
AutoIncr: false,
},
},
Indexes: importDistrictIndexes{
DistrictPkey: index{
@ -312,11 +321,12 @@ type importDistrictColumns struct {
Geom4326 column
Centroid4326 column
Extent4326 column
Area4326SQM column
}
func (c importDistrictColumns) AsSlice() []column {
return []column{
c.Gid, c.ID, c.Website, c.Contact, c.Address, c.Regionid, c.PostalCod, c.Phone1, c.Fax1, c.Agency, c.Code1, c.City1, c.ShapeLeng, c.Address2, c.GeneralMG, c.City2, c.PostalC1, c.Fax2, c.Phone2, c.ShapeLe1, c.ShapeArea, c.Geom, c.Geom4326, c.Centroid4326, c.Extent4326,
c.Gid, c.ID, c.Website, c.Contact, c.Address, c.Regionid, c.PostalCod, c.Phone1, c.Fax1, c.Agency, c.Code1, c.City1, c.ShapeLeng, c.Address2, c.GeneralMG, c.City2, c.PostalC1, c.Fax2, c.Phone2, c.ShapeLe1, c.ShapeArea, c.Geom, c.Geom4326, c.Centroid4326, c.Extent4326, c.Area4326SQM,
}
}

View file

@ -2624,6 +2624,7 @@ func (f *Factory) FromExistingImportDistrict(m *models.ImportDistrict) *ImportDi
o.Geom4326 = func() null.Val[string] { return m.Geom4326 }
o.Centroid4326 = func() null.Val[string] { return m.Centroid4326 }
o.Extent4326 = func() null.Val[string] { return m.Extent4326 }
o.Area4326SQM = func() null.Val[decimal.Decimal] { return m.Area4326SQM }
ctx := context.Background()
if m.R.ImportDistrictGidOrganization != nil {

View file

@ -62,6 +62,7 @@ type ImportDistrictTemplate struct {
Geom4326 func() null.Val[string]
Centroid4326 func() null.Val[string]
Extent4326 func() null.Val[string]
Area4326SQM func() null.Val[decimal.Decimal]
r importDistrictR
f *Factory
@ -285,6 +286,9 @@ func (o ImportDistrictTemplate) Build() *models.ImportDistrict {
if o.Extent4326 != nil {
m.Extent4326 = o.Extent4326()
}
if o.Area4326SQM != nil {
m.Area4326SQM = o.Area4326SQM()
}
o.setModelRels(m)
@ -449,6 +453,7 @@ func (m importDistrictMods) RandomizeAllColumns(f *faker.Faker) ImportDistrictMo
ImportDistrictMods.RandomGeom4326(f),
ImportDistrictMods.RandomCentroid4326(f),
ImportDistrictMods.RandomExtent4326(f),
ImportDistrictMods.RandomArea4326SQM(f),
}
}
@ -1755,6 +1760,59 @@ func (m importDistrictMods) RandomExtent4326NotNull(f *faker.Faker) ImportDistri
})
}
// Set the model columns to this value
func (m importDistrictMods) Area4326SQM(val null.Val[decimal.Decimal]) ImportDistrictMod {
return ImportDistrictModFunc(func(_ context.Context, o *ImportDistrictTemplate) {
o.Area4326SQM = func() null.Val[decimal.Decimal] { return val }
})
}
// Set the Column from the function
func (m importDistrictMods) Area4326SQMFunc(f func() null.Val[decimal.Decimal]) ImportDistrictMod {
return ImportDistrictModFunc(func(_ context.Context, o *ImportDistrictTemplate) {
o.Area4326SQM = f
})
}
// Clear any values for the column
func (m importDistrictMods) UnsetArea4326SQM() ImportDistrictMod {
return ImportDistrictModFunc(func(_ context.Context, o *ImportDistrictTemplate) {
o.Area4326SQM = 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 importDistrictMods) RandomArea4326SQM(f *faker.Faker) ImportDistrictMod {
return ImportDistrictModFunc(func(_ context.Context, o *ImportDistrictTemplate) {
o.Area4326SQM = func() null.Val[decimal.Decimal] {
if f == nil {
f = &defaultFaker
}
val := random_decimal_Decimal(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 importDistrictMods) RandomArea4326SQMNotNull(f *faker.Faker) ImportDistrictMod {
return ImportDistrictModFunc(func(_ context.Context, o *ImportDistrictTemplate) {
o.Area4326SQM = func() null.Val[decimal.Decimal] {
if f == nil {
f = &defaultFaker
}
val := random_decimal_Decimal(f)
return null.From(val)
}
})
}
func (m importDistrictMods) WithParentsCascading() ImportDistrictMod {
return ImportDistrictModFunc(func(ctx context.Context, o *ImportDistrictTemplate) {
if isDone, _ := importDistrictWithParentsCascadingCtx.Value(ctx); isDone {

View file

@ -51,6 +51,7 @@ type ImportDistrict struct {
Geom4326 null.Val[string] `db:"geom_4326,generated" `
Centroid4326 null.Val[string] `db:"centroid_4326,generated" `
Extent4326 null.Val[string] `db:"extent_4326,generated" `
Area4326SQM null.Val[decimal.Decimal] `db:"area_4326_sqm,generated" `
R importDistrictR `db:"-" `
}
@ -73,7 +74,7 @@ type importDistrictR struct {
func buildImportDistrictColumns(alias string) importDistrictColumns {
return importDistrictColumns{
ColumnsExpr: expr.NewColumnsExpr(
"gid", "id", "website", "contact", "address", "regionid", "postal_cod", "phone1", "fax1", "agency", "code1", "city1", "shape_leng", "address2", "general_mg", "city2", "postal_c_1", "fax2", "phone2", "shape_le_1", "shape_area", "geom", "geom_4326", "centroid_4326", "extent_4326",
"gid", "id", "website", "contact", "address", "regionid", "postal_cod", "phone1", "fax1", "agency", "code1", "city1", "shape_leng", "address2", "general_mg", "city2", "postal_c_1", "fax2", "phone2", "shape_le_1", "shape_area", "geom", "geom_4326", "centroid_4326", "extent_4326", "area_4326_sqm",
).WithParent("import.district"),
tableAlias: alias,
Gid: psql.Quote(alias, "gid"),
@ -101,6 +102,7 @@ func buildImportDistrictColumns(alias string) importDistrictColumns {
Geom4326: psql.Quote(alias, "geom_4326"),
Centroid4326: psql.Quote(alias, "centroid_4326"),
Extent4326: psql.Quote(alias, "extent_4326"),
Area4326SQM: psql.Quote(alias, "area_4326_sqm"),
}
}
@ -132,6 +134,7 @@ type importDistrictColumns struct {
Geom4326 psql.Expression
Centroid4326 psql.Expression
Extent4326 psql.Expression
Area4326SQM psql.Expression
}
func (c importDistrictColumns) Alias() string {
@ -944,6 +947,7 @@ type importDistrictWhere[Q psql.Filterable] struct {
Geom4326 psql.WhereNullMod[Q, string]
Centroid4326 psql.WhereNullMod[Q, string]
Extent4326 psql.WhereNullMod[Q, string]
Area4326SQM psql.WhereNullMod[Q, decimal.Decimal]
}
func (importDistrictWhere[Q]) AliasedAs(alias string) importDistrictWhere[Q] {
@ -977,6 +981,7 @@ func buildImportDistrictWhere[Q psql.Filterable](cols importDistrictColumns) imp
Geom4326: psql.WhereNull[Q, string](cols.Geom4326),
Centroid4326: psql.WhereNull[Q, string](cols.Centroid4326),
Extent4326: psql.WhereNull[Q, string](cols.Extent4326),
Area4326SQM: psql.WhereNull[Q, decimal.Decimal](cols.Area4326SQM),
}
}

View file

@ -19,42 +19,79 @@
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1><i class="bi bi-geo-alt-fill text-primary me-2"></i> District Settings</h1>
<button class="btn btn-primary"><i class="bi bi-save me-2"></i>Save Changes</button>
<h1>
<i class="bi bi-geo-alt-fill text-primary me-2"></i> District
Settings
</h1>
<button class="btn btn-primary">
<i class="bi bi-save me-2"></i>Save Changes
</button>
</div>
<map-district
district-id="{{.District.GID}}"
centroid="{{.District.Centroid|json}}"
xmin="{{.District.XMin}}"
ymin="{{.District.YMin}}"
xmax="{{.District.XMax}}"
ymax="{{.District.YMax}}"
tegola="{{.URL.Tegola}}"></map-district>
district-id="{{ .District.GID }}"
centroid="{{ .District.Centroid|json }}"
xmin="{{ .District.XMin }}"
ymin="{{ .District.YMin }}"
xmax="{{ .District.XMax }}"
ymax="{{ .District.YMax }}"
tegola="{{ .URL.Tegola }}"
></map-district>
<div class="row">
<!-- Basic Information -->
<div class="col-md-6">
<div class="card settings-card">
<div class="card-header bg-light">
<h5><i class="bi bi-building me-2"></i> Organization Information</h5>
<h5>
<i class="bi bi-building me-2"></i> Organization Information
</h5>
</div>
<div class="card-body">
<div class="mb-3">
<label for="agencyName" class="form-label"><i class="bi bi-briefcase me-1"></i> Agency Name</label>
<input type="text" class="form-control" id="agencyName" value="Central District Water Authority">
<label for="agencyName" class="form-label"
><i class="bi bi-briefcase me-1"></i> Agency Name</label
>
<input
type="text"
class="form-control"
id="agencyName"
value="{{ .District.Agency }}"
/>
</div>
<div class="mb-3">
<label for="website" class="form-label"><i class="bi bi-globe me-1"></i> Website</label>
<input type="url" class="form-control" id="website" value="https://cdwa.example.org">
<label for="website" class="form-label"
><i class="bi bi-globe me-1"></i> Website</label
>
<input
type="url"
class="form-control"
id="website"
value="{{ .District.Website }}"
/>
</div>
<div class="mb-3">
<label for="generalManager" class="form-label"><i class="bi bi-person-badge me-1"></i> General Manager Name</label>
<input type="text" class="form-control" id="generalManager" value="Jane Smithson">
<label for="generalManager" class="form-label"
><i class="bi bi-person-badge me-1"></i> General Manager
Name</label
>
<input
type="text"
class="form-control"
id="generalManager"
value="{{ .District.GeneralManager }}"
/>
</div>
<div class="mb-3">
<label for="contactPerson" class="form-label"><i class="bi bi-person me-1"></i> Contact Person</label>
<input type="text" class="form-control" id="contactPerson" value="John Doe">
<label for="contactPerson" class="form-label"
><i class="bi bi-person me-1"></i> Contact Person</label
>
<input
type="text"
class="form-control"
id="contactPerson"
value="{{ .District.Contact }}"
/>
</div>
</div>
</div>
@ -64,34 +101,80 @@
<div class="col-md-6">
<div class="card settings-card">
<div class="card-header bg-light">
<h5><i class="bi bi-telephone me-2"></i> Contact Information</h5>
<h5>
<i class="bi bi-telephone me-2"></i> Contact Information
</h5>
</div>
<div class="card-body">
<div class="mb-3">
<label for="address" class="form-label"><i class="bi bi-geo me-1"></i> Address</label>
<input type="text" class="form-control" id="address" value="123 Main Street, Suite 400">
<label for="address" class="form-label"
><i class="bi bi-geo me-1"></i> Address</label
>
<input
type="text"
class="form-control"
id="address"
value="{{ .District.Address }}"
/>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="city" class="form-label"><i class="bi bi-building me-1"></i> City</label>
<input type="text" class="form-control" id="city" value="Centerville">
<label for="city" class="form-label"
><i class="bi bi-building me-1"></i> City</label
>
<input
type="text"
class="form-control"
id="city"
value="{{ .District.City1 }},{{ .District.City2 }}"
/>
</div>
<div class="col-md-6 mb-3">
<label for="postalCode" class="form-label"><i class="bi bi-mailbox me-1"></i> Postal Code</label>
<input type="text" class="form-control" id="postalCode" value="12345">
<label for="postalCode" class="form-label"
><i class="bi bi-mailbox me-1"></i> Postal Code</label
>
<input
type="text"
class="form-control"
id="postalCode"
value="{{ .District.PostalCode }}"
/>
</div>
</div>
<div class="mb-3">
<label for="phoneNumber" class="form-label"><i class="bi bi-telephone me-1"></i> Phone Number (Primary)</label>
<input type="tel" class="form-control" id="phoneNumber" value="(555) 123-4567">
<label for="phoneNumber" class="form-label"
><i class="bi bi-telephone me-1"></i> Phone Number
(Primary)</label
>
<input
type="tel"
class="form-control"
id="phoneNumber"
value="{{ .District.Phone1 }}"
/>
</div>
<div class="mb-3">
<label for="secondaryPhone" class="form-label"><i class="bi bi-telephone-plus me-1"></i> Phone Number (Secondary)</label>
<input type="tel" class="form-control" id="secondaryPhone" value="(555) 987-6543">
<label for="secondaryPhone" class="form-label"
><i class="bi bi-telephone-plus me-1"></i> Phone Number
(Secondary)</label
>
<input
type="tel"
class="form-control"
id="secondaryPhone"
value="{{ .District.Phone2 }}"
/>
</div>
<div class="mb-3">
<label for="faxNumber" class="form-label"><i class="bi bi-printer me-1"></i> Fax Number</label>
<input type="tel" class="form-control" id="faxNumber" value="(555) 765-4321">
<label for="faxNumber" class="form-label"
><i class="bi bi-printer me-1"></i> Fax Number</label
>
<input
type="tel"
class="form-control"
id="faxNumber"
value="{{ .District.Fax }}"
/>
</div>
</div>
</div>
@ -106,19 +189,16 @@
<div class="card-body">
<div class="row">
<div class="col-md-6 mb-3">
<label for="totalArea" class="form-label"><i class="bi bi-rulers me-1"></i> Total Area (square kilometers)</label>
<input type="number" class="form-control" id="totalArea" value="1250">
</div>
<div class="col-md-6 mb-3">
<label for="countiesServed" class="form-label"><i class="bi bi-pin-map me-1"></i> Counties Served</label>
<select class="form-select" id="countiesServed" multiple size="3">
<option selected>Franklin County</option>
<option selected>Jefferson County</option>
<option selected>Washington County</option>
<option>Lincoln County</option>
<option>Adams County</option>
</select>
<small class="form-text text-muted">Hold Ctrl (or Cmd) to select multiple counties</small>
<label for="totalArea" class="form-label"
><i class="bi bi-rulers me-1"></i> Total Area (square
meters)</label
>
<input
type="number"
class="form-control"
id="totalArea"
value="{{ .District.SurfaceAreaMetersSquare }}"
/>
</div>
</div>
</div>
@ -126,10 +206,10 @@
</div>
</div>
<div class="d-flex justify-content-end mt-3">
<!--<div class="d-flex justify-content-end mt-3">
<button class="btn btn-secondary me-2"><i class="bi bi-x-circle me-1"></i> Cancel</button>
<button class="btn btn-primary"><i class="bi bi-save me-1"></i> Save Changes</button>
</div>
</div>-->
</div>
</div>
</div>

View file

@ -32,7 +32,6 @@
Manage Users
<i class="bi bi-arrow-right ms-1"></i>
</a>
<span class="last-updated">23 users</span>
</div>
</div>
</div>
@ -57,7 +56,6 @@
Manage Products
<i class="bi bi-arrow-right ms-1"></i>
</a>
<span class="last-updated">12 active products</span>
</div>
</div>
</div>
@ -83,7 +81,6 @@
Manage Integrations
<i class="bi bi-arrow-right ms-1"></i>
</a>
<span class="last-updated">3 active connections</span>
</div>
</div>
</div>
@ -101,7 +98,10 @@
Manage your district location and information.
</p>
<div class="d-flex justify-content-between align-items-center">
<a href="{{ .URL.SettingDistrict }}" class="btn btn-outline-danger">
<a
href="{{ .URL.SettingDistrict }}"
class="btn btn-outline-danger"
>
Manage District
<i class="bi bi-arrow-right ms-1"></i>
</a>
@ -127,7 +127,6 @@
Manage Notifications
<i class="bi bi-arrow-right ms-1"></i>
</a>
<span class="last-updated">5 active alerts</span>
</div>
</div>
</div>
@ -149,7 +148,6 @@
Manage Settings
<i class="bi bi-arrow-right ms-1"></i>
</a>
<span class="last-updated">Updated yesterday</span>
</div>
</div>
</div>

View file

@ -150,7 +150,7 @@ func bulkGeocode(ctx context.Context, txn bob.Tx, file models.FileuploadFile, po
FROM import.district d
JOIN organization o ON d.gid = o.import_district_gid
WHERE o.id = p.organization_id
AND ST_Contains(d.geom, p.geom)
AND ST_Contains(d.geom_4326, p.geom)
)
)
WHERE p.geom IS NOT NULL;`

View file

@ -15,12 +15,25 @@ import (
)
type contentDistrict struct {
Centroid string `db:"st_asgeojson"`
GID int32 `db:"gid"`
XMin float32 `db:"st_xmin"`
YMin float32 `db:"st_ymin"`
XMax float32 `db:"st_xmax"`
YMax float32 `db:"st_ymax"`
Address string `db:"address"`
Agency string `db:"agency"`
Centroid string `db:"st_asgeojson"`
Contact string `db:"contact"`
City1 string `db:"city1"`
City2 string `db:"city2"`
Fax string `db:"fax1"`
GID int32 `db:"gid"`
Phone1 string `db:"phone1"`
Phone2 string `db:"phone2"`
GeneralManager string `db:"general_mg"`
PostalCode string `db:"postal_c_1"`
ShapeArea string `db:"shape_area"`
SurfaceAreaMetersSquare string `db:"area_4326_sqm"`
Website string `db:"website"`
XMin float32 `db:"st_xmin"`
XMax float32 `db:"st_xmax"`
YMin float32 `db:"st_ymin"`
YMax float32 `db:"st_ymax"`
}
type contentSettingDistrict struct {
District contentDistrict
@ -61,7 +74,19 @@ func getSettingDistrict(w http.ResponseWriter, r *http.Request, u *models.User)
district, err = bob.One[contentDistrict](ctx, db.PGInstance.BobDB, psql.Select(
sm.From("import.district"),
sm.Columns(
"address",
"agency",
"area_4326_sqm",
"city1",
"city2",
"contact",
"fax1",
"general_mg",
"gid",
"phone1",
"phone2",
"postal_c_1",
"website",
psql.F("ST_AsGeoJSON", "centroid_4326"),
psql.F("ST_XMin", "extent_4326"),
psql.F("ST_YMin", "extent_4326"),

View file

@ -20,3 +20,4 @@ GRANT ALL PRIVILEGES ON SCHEMA public TO $1;
ALTER TABLE import.district ADD COLUMN geom_4326 geometry(MultiPolygon,4326) GENERATED ALWAYS AS (ST_Transform(geom, 4326)) STORED;
ALTER TABLE import.district ADD COLUMN centroid_4326 geometry(Point,4326) GENERATED ALWAYS AS (ST_Transform(ST_Centroid(geom), 4326)) STORED;
ALTER TABLE import.district ADD COLUMN extent_4326 geometry(Polygon,4326) GENERATED ALWAYS AS (ST_Transform(ST_Envelope(geom), 4326)) STORED;
ALTER TABLE import.district ADD COLUMN area_4326_sqm numeric GENERATED ALWAYS AS (ST_Area(ST_Transform(geom, 4326)::geography)) STORED;