diff --git a/h3utils/h3.go b/h3utils/h3.go
index c5c6082d..7ba4510a 100644
--- a/h3utils/h3.go
+++ b/h3utils/h3.go
@@ -5,7 +5,7 @@ import (
"strings"
"github.com/Gleipnir-Technology/go-geojson2h3/v2"
- "github.com/tidwall/geojson"
+ //"github.com/tidwall/geojson"
"github.com/uber/h3-go/v4"
)
@@ -37,29 +37,6 @@ func H3ToGeoJSON(indexes []h3.Cell) (interface{}, error) {
return featureCollection.JSON(), nil
}
-func main2() {
- resolution := 9
- object, err := geojson.Parse(`{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"shape":"Polygon","name":"Unnamed Layer","category":"default"},"geometry":{"type":"Polygon","coordinates":[[[-73.901303,40.756892],[-73.893924,40.743755],[-73.871476,40.756278],[-73.863378,40.764175],[-73.871444,40.768467],[-73.879852,40.760014],[-73.885515,40.764045],[-73.891522,40.761054],[-73.901303,40.756892]]]},"id":"a6ca1b7e-9ddf-4425-ad07-8a895f7d6ccf"}]}`, nil)
- if err != nil {
- panic(err)
- }
-
- indexes, err := geojson2h3.ToH3(resolution, object)
- if err != nil {
- panic(err)
- }
- for _, index := range indexes {
- fmt.Printf("h3index: %s\n", index.String())
- }
-
- featureCollection, err := geojson2h3.ToFeatureCollection(indexes)
- if err != nil {
- panic(err)
- }
- fmt.Println("Polyfill:")
- fmt.Println(featureCollection.JSON())
-}
-
// Given a cell at a smaller resolution remap it to the larger resolution
func scaleCell(cell h3.Cell, resolution int) (h3.Cell, error) {
r := cell.Resolution()
diff --git a/platform/district.go b/platform/district.go
index d76945a8..a2950342 100644
--- a/platform/district.go
+++ b/platform/district.go
@@ -39,7 +39,7 @@ func DistrictForLocation(ctx context.Context, lng float64, lat float64) (*models
return nil, errors.New("too many organizations")
}
}
-func MatchDistrict(ctx context.Context, longitude, latitude *float64, images []ImageUpload) (*int32, error) {
+func MatchDistrict(ctx context.Context, longitude, latitude float64, images []ImageUpload) (*int32, error) {
var err error
var org *models.Organization
for _, image := range images {
@@ -58,7 +58,7 @@ func MatchDistrict(ctx context.Context, longitude, latitude *float64, images []I
return &org.ID, nil
}
}
- if longitude == nil || latitude == nil {
+ if longitude == 0 || latitude == 0 {
org, err = DistrictCatchall(ctx)
if err != nil {
return nil, fmt.Errorf("get catchall: %w", err)
@@ -66,7 +66,7 @@ func MatchDistrict(ctx context.Context, longitude, latitude *float64, images []I
log.Debug().Int32("id", org.ID).Msg("No location from images, no latlng for the report itself, using catchall")
return &org.ID, nil
}
- org, err = DistrictForLocation(ctx, *longitude, *latitude)
+ org, err = DistrictForLocation(ctx, longitude, latitude)
if err != nil {
log.Warn().Err(err).Msg("Failed to get district for location")
return nil, fmt.Errorf("Failed to get district for location: %w", err)
@@ -76,9 +76,9 @@ func MatchDistrict(ctx context.Context, longitude, latitude *float64, images []I
if err != nil {
return nil, fmt.Errorf("get catchall: %w", err)
}
- log.Debug().Err(err).Float64("lng", *longitude).Float64("lat", *latitude).Int32("id", org.ID).Msg("No district match by report location, using catchall")
+ log.Debug().Err(err).Float64("lng", longitude).Float64("lat", latitude).Int32("id", org.ID).Msg("No district match by report location, using catchall")
return &org.ID, nil
}
- log.Debug().Err(err).Int32("org_id", org.ID).Float64("lng", *longitude).Float64("lat", *latitude).Msg("Found district match by report location")
+ log.Debug().Err(err).Int32("org_id", org.ID).Float64("lng", longitude).Float64("lat", latitude).Msg("Found district match by report location")
return &org.ID, nil
}
diff --git a/platform/latlng.go b/platform/latlng.go
index 157e65db..3703e9dc 100644
--- a/platform/latlng.go
+++ b/platform/latlng.go
@@ -1,13 +1,7 @@
package platform
import (
- "errors"
- "fmt"
-
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
- "github.com/Gleipnir-Technology/nidus-sync/h3utils"
- "github.com/rs/zerolog/log"
- "github.com/uber/h3-go/v4"
)
type LatLng struct {
@@ -17,41 +11,3 @@ type LatLng struct {
AccuracyValue float64
AccuracyType enums.PublicreportAccuracytype
}
-
-func (l LatLng) Resolution() uint {
- switch l.AccuracyType {
- // These accuracy_type strings come from the Mapbox Geocoding API definition and
- // are far from scientific
- case enums.PublicreportAccuracytypeRooftop:
- return 14
- case enums.PublicreportAccuracytypeParcel:
- return 13
- case enums.PublicreportAccuracytypePoint:
- return 13
- case enums.PublicreportAccuracytypeInterpolated:
- return 12
- case enums.PublicreportAccuracytypeApproximate:
- return 11
- case enums.PublicreportAccuracytypeIntersection:
- return 10
- // This is a special indicator that we got our location from the browser measurements
- case enums.PublicreportAccuracytypeBrowser:
- return uint(h3utils.MeterAccuracyToH3Resolution(l.AccuracyValue))
- default:
- log.Warn().Str("accuracy-type", string(l.AccuracyType)).Msg("unrecognized accuracy type, this indicates either a weird client or misbehaving web page. Defaulting to resolution 13")
- return 13
- }
-}
-func (l LatLng) H3Cell() (*h3.Cell, error) {
- if l.Longitude == nil || l.Latitude == nil {
- return nil, errors.New("nil lat/lng")
- }
- result, err := h3utils.GetCell(*l.Longitude, *l.Latitude, int(l.Resolution()))
- return &result, err
-}
-func (l LatLng) GeometryQuery() (string, error) {
- if l.Longitude == nil || l.Latitude == nil {
- return "", errors.New("nil lat/lng")
- }
- return fmt.Sprintf("ST_Point(%f, %f, 4326)", *l.Longitude, *l.Latitude), nil
-}
diff --git a/platform/publicreport.go b/platform/publicreport.go
index b5654bb1..2fb175ea 100644
--- a/platform/publicreport.go
+++ b/platform/publicreport.go
@@ -84,8 +84,8 @@ func PublicReportMessageCreate(ctx context.Context, user User, report_id, messag
func PublicReportReporterUpdated(ctx context.Context, org_id int32, report_id string) {
event.Updated(event.TypeRMOReport, org_id, report_id)
}
-func ReportNuisanceCreate(ctx context.Context, setter_report models.PublicreportReportSetter, setter_nuisance models.PublicreportNuisanceSetter, latlng LatLng, address Address, images []ImageUpload) (*models.PublicreportReport, error) {
- return reportCreate(ctx, setter_report, latlng, address, images, func(ctx context.Context, txn bob.Executor, report_id int32) error {
+func ReportNuisanceCreate(ctx context.Context, setter_report models.PublicreportReportSetter, setter_nuisance models.PublicreportNuisanceSetter, location types.Location, address Address, images []ImageUpload) (*models.PublicreportReport, error) {
+ return reportCreate(ctx, setter_report, location, address, images, func(ctx context.Context, txn bob.Executor, report_id int32) error {
setter_nuisance.ReportID = omit.From(report_id)
_, err := models.PublicreportNuisances.Insert(&setter_nuisance).One(ctx, txn)
if err != nil {
@@ -95,8 +95,8 @@ func ReportNuisanceCreate(ctx context.Context, setter_report models.Publicreport
})
}
-func ReportWaterCreate(ctx context.Context, setter_report models.PublicreportReportSetter, setter_water models.PublicreportWaterSetter, latlng LatLng, address Address, images []ImageUpload) (*models.PublicreportReport, error) {
- return reportCreate(ctx, setter_report, latlng, address, images, func(ctx context.Context, txn bob.Executor, report_id int32) error {
+func ReportWaterCreate(ctx context.Context, setter_report models.PublicreportReportSetter, setter_water models.PublicreportWaterSetter, location types.Location, address Address, images []ImageUpload) (*models.PublicreportReport, error) {
+ return reportCreate(ctx, setter_report, location, address, images, func(ctx context.Context, txn bob.Executor, report_id int32) error {
setter_water.ReportID = omit.From(report_id)
_, err := models.PublicreportWaters.Insert(&setter_water).One(ctx, txn)
if err != nil {
@@ -108,7 +108,7 @@ func ReportWaterCreate(ctx context.Context, setter_report models.PublicreportRep
type funcSetReportDetail = func(context.Context, bob.Executor, int32) error
-func reportCreate(ctx context.Context, setter_report models.PublicreportReportSetter, latlng LatLng, address Address, images []ImageUpload, detail_setter funcSetReportDetail) (result *models.PublicreportReport, err error) {
+func reportCreate(ctx context.Context, setter_report models.PublicreportReportSetter, location types.Location, address Address, images []ImageUpload, detail_setter funcSetReportDetail) (result *models.PublicreportReport, err error) {
txn, err := db.PGInstance.BobDB.BeginTx(ctx, nil)
if err != nil {
return nil, fmt.Errorf("create txn: %w", err)
@@ -123,10 +123,10 @@ func reportCreate(ctx context.Context, setter_report models.PublicreportReportSe
// If we've got an locality value it was set by geocoding so we should save it
var a *models.Address
- if address.Locality != "" && latlng.Latitude != nil && latlng.Longitude != nil {
+ if address.Locality != "" && location.Latitude != 0 && location.Longitude != 0 {
a, err = geocode.EnsureAddress(ctx, txn, address, types.Location{
- Latitude: *latlng.Latitude,
- Longitude: *latlng.Longitude,
+ Latitude: location.Latitude,
+ Longitude: location.Longitude,
})
if err != nil {
return nil, fmt.Errorf("Failed to ensure address: %w", err)
@@ -138,7 +138,7 @@ func reportCreate(ctx context.Context, setter_report models.PublicreportReportSe
return nil, fmt.Errorf("Failed to save image uploads: %w", err)
}
var organization_id *int32
- organization_id, err = MatchDistrict(ctx, latlng.Longitude, latlng.Latitude, images)
+ organization_id, err = MatchDistrict(ctx, location.Longitude, location.Latitude, images)
if err != nil {
log.Warn().Err(err).Msg("Failed to match district")
}
@@ -153,9 +153,9 @@ func reportCreate(ctx context.Context, setter_report models.PublicreportReportSe
if err != nil {
return nil, fmt.Errorf("Failed to create report database record: %w", err)
}
- if latlng.Latitude != nil && latlng.Longitude != nil {
- h3cell, _ := latlng.H3Cell()
- geom_query, _ := latlng.GeometryQuery()
+ if location.Latitude != 0 && location.Longitude != 0 {
+ h3cell, _ := location.H3Cell()
+ geom_query, _ := location.GeometryQuery()
_, err = psql.Update(
um.Table("publicreport.report"),
um.SetCol("h3cell").ToArg(h3cell),
diff --git a/platform/types/address.go b/platform/types/address.go
index ff41a983..a6e3fb67 100644
--- a/platform/types/address.go
+++ b/platform/types/address.go
@@ -8,11 +8,11 @@ import (
type Address struct {
Country string `db:"country" json:"country"`
- GID string `db:"gid" json:"gid"`
+ GID string `db:"gid" json:"gid" schema:"gid"`
Locality string `db:"locality" json:"locality"`
Number string `db:"number" json:"number"`
PostalCode string `db:"postal_code" json:"postal_code"`
- Raw string `db:"raw" json:"raw"`
+ Raw string `db:"raw" json:"raw" schema:"raw"`
Region string `db:"region" json:"region"`
Street string `db:"street" json:"street"`
Unit string `db:"unit" json:"unit"`
diff --git a/platform/types/location.go b/platform/types/location.go
index d1cd4efb..b5fda97f 100644
--- a/platform/types/location.go
+++ b/platform/types/location.go
@@ -2,13 +2,33 @@ package types
import (
"fmt"
+
+ "github.com/Gleipnir-Technology/nidus-sync/h3utils"
+ //"github.com/rs/zerolog/log"
+ "github.com/uber/h3-go/v4"
)
type Location struct {
- Latitude float64 `db:"latitude" json:"latitude"`
- Longitude float64 `db:"longitude" json:"longitude"`
+ Accuracy *float32 `db:"accuracy" json:"accuracy" schema:"accuracy"`
+ Latitude float64 `db:"latitude" json:"latitude" schema:"latitude"`
+ Longitude float64 `db:"longitude" json:"longitude" schema:"longitude"`
}
func (l Location) String() string {
return fmt.Sprintf("%f %f", l.Longitude, l.Latitude)
}
+
+func (l Location) Resolution() uint {
+ if l.Accuracy != nil {
+ return uint(h3utils.MeterAccuracyToH3Resolution(float64(*l.Accuracy)))
+ } else {
+ return uint(0)
+ }
+}
+func (l Location) H3Cell() (*h3.Cell, error) {
+ result, err := h3utils.GetCell(l.Longitude, l.Latitude, int(l.Resolution()))
+ return &result, err
+}
+func (l Location) GeometryQuery() (string, error) {
+ return fmt.Sprintf("ST_Point(%f, %f, 4326)", l.Longitude, l.Latitude), nil
+}
diff --git a/resource/nuisance.go b/resource/nuisance.go
index 7166fe1c..c1aa72bc 100644
--- a/resource/nuisance.go
+++ b/resource/nuisance.go
@@ -2,10 +2,8 @@ package resource
import (
"context"
- "fmt"
"net/http"
"slices"
- "strconv"
"time"
"github.com/Gleipnir-Technology/nidus-sync/db/enums"
@@ -13,6 +11,7 @@ import (
"github.com/Gleipnir-Technology/nidus-sync/html"
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
"github.com/Gleipnir-Technology/nidus-sync/platform"
+ "github.com/Gleipnir-Technology/nidus-sync/platform/types"
"github.com/aarondl/opt/omit"
"github.com/aarondl/opt/omitnull"
"github.com/rs/zerolog/log"
@@ -32,84 +31,25 @@ type nuisance struct {
ID string `json:"id"`
URI string `json:"uri"`
}
-type nuisanceForm struct {
- AdditionalInfo string `schema:"additional-info"`
- AddressGID string `schema:"address-gid"`
- Address string `schema:"address"`
- Duration string `schema:"duration"`
- Latitude string `schema:"latitude"`
- Longitude string `schema:"longitude"`
- LatlngAccuracyType string `schema:"latlng-accuracy-type"`
- LatlngAccuracyValue string `schema:"latlng-accuracy-value"`
- MapZoom string `schema:"map-zoom"`
- SourceStagnant bool `schema:"source-stagnant"`
- SourceContainer bool `schema:"source-container"`
- SourceDescription string `schema:"source-description"`
- SourceGutters bool `schema:"source-gutters"`
- SourceLocations []string `schema:"source-location"`
- TODEarly bool `schema:"tod-early"`
- TODDay bool `schema:"tod-day"`
- TODEvening bool `schema:"tod-evening"`
- TODNight bool `schema:"tod-night"`
+type Locator struct {
+ Address types.Address `schema:"address"`
+ Location types.Location `schema:"location"`
}
-
-func parseLatLng(r *http.Request) (platform.LatLng, error) {
- result := platform.LatLng{
- AccuracyType: enums.PublicreportAccuracytypeNone,
- AccuracyValue: 0.0,
- Latitude: nil,
- Longitude: nil,
- MapZoom: 0.0,
- }
- latitude_str := r.FormValue("latitude")
- longitude_str := r.FormValue("longitude")
- latlng_accuracy_type_str := r.PostFormValue("latlng-accuracy-type")
- latlng_accuracy_value_str := r.PostFormValue("latlng-accuracy-value")
- map_zoom_str := r.PostFormValue("map-zoom")
-
- var err error
- if latlng_accuracy_type_str != "" {
- err := result.AccuracyType.Scan(latlng_accuracy_type_str)
- if err != nil {
- return result, fmt.Errorf("Failed to parse accuracy type '%s': %w", latlng_accuracy_type_str, err)
- }
- }
- if latlng_accuracy_value_str != "" {
- var t float64
- t, err = strconv.ParseFloat(latlng_accuracy_value_str, 32)
- if err != nil {
- return result, fmt.Errorf("Failed to parse latlng_accuracy_value '%s': %w", latlng_accuracy_value_str, err)
- }
- result.AccuracyValue = float64(t)
- }
-
- if latitude_str != "" {
- var t float64
- t, err = strconv.ParseFloat(latitude_str, 64)
- if err != nil {
- return result, fmt.Errorf("Failed to parse latitude '%s': %w", latitude_str, err)
- }
- result.Latitude = &t
- }
- if longitude_str != "" {
- var t float64
- t, err := strconv.ParseFloat(longitude_str, 64)
- if err != nil {
- return result, fmt.Errorf("Failed to parse longitude '%s': %w", longitude_str, err)
- }
- result.Longitude = &t
- }
-
- if map_zoom_str != "" {
- var t float64
- t, err = strconv.ParseFloat(map_zoom_str, 32)
- if err != nil {
- return result, fmt.Errorf("Failed to parse map_zoom_str '%s': %w", map_zoom_str, err)
- } else {
- result.MapZoom = float32(t)
- }
- }
- return result, nil
+type nuisanceForm struct {
+ AdditionalInfo string `schema:"additional-info"`
+ Duration string `schema:"duration"`
+ Location types.Location `schema:"location"`
+ Locator Locator `schema:"locator"`
+ MapZoom string `schema:"map-zoom"`
+ SourceStagnant bool `schema:"source-stagnant"`
+ SourceContainer bool `schema:"source-container"`
+ SourceDescription string `schema:"source-description"`
+ SourceGutters bool `schema:"source-gutters"`
+ SourceLocations []string `schema:"source-location"`
+ TODEarly bool `schema:"tod-early"`
+ TODDay bool `schema:"tod-day"`
+ TODEvening bool `schema:"tod-evening"`
+ TODNight bool `schema:"tod-night"`
}
func (res *nuisanceR) Create(ctx context.Context, r *http.Request, n nuisanceForm) (*nuisance, *nhttp.ErrorWithStatus) {
@@ -120,22 +60,25 @@ func (res *nuisanceR) Create(ctx context.Context, r *http.Request, n nuisanceFor
is_location_pool := slices.Contains(n.SourceLocations, "pool-area")
is_location_other := slices.Contains(n.SourceLocations, "other")
- latlng, err := parseLatLng(r)
-
- err = duration.Scan(n.Duration)
+ err := duration.Scan(n.Duration)
if err != nil {
log.Warn().Err(err).Str("duration_str", n.Duration).Msg("Failed to interpret 'duration'")
}
uploads, err := html.ExtractImageUploads(r)
- log.Info().Int("len", len(uploads)).Msg("extracted uploads")
+ log.Info().Int("len", len(uploads)).Msg("extracted nuisance uploads")
if err != nil {
return nil, nhttp.NewError("Failed to extract image uploads: %w", err)
}
address := platform.Address{
- GID: n.AddressGID,
- Raw: n.Address,
+ GID: n.Locator.Address.GID,
+ Raw: n.Locator.Address.Raw,
}
+ accuracy := float32(0.0)
+ if n.Location.Accuracy != nil {
+ accuracy = *n.Location.Accuracy
+ }
+ log.Info().Str("address.raw", address.Raw).Str("address.gid", address.GID).Msg("making nuisance")
setter_report := models.PublicreportReportSetter{
//AddressID: omitnull.From(latlng.Cell.String()),
AddressCountry: omit.From(""),
@@ -148,11 +91,11 @@ func (res *nuisanceR) Create(ctx context.Context, r *http.Request, n nuisanceFor
AddressStreet: omit.From(""),
Created: omit.From(time.Now()),
//H3cell: omitnull.From(latlng.Cell.String()),
- LatlngAccuracyType: omit.From(latlng.AccuracyType),
- LatlngAccuracyValue: omit.From(float32(latlng.AccuracyValue)),
+ LatlngAccuracyType: omit.From(enums.PublicreportAccuracytypeBrowser),
+ LatlngAccuracyValue: omit.From(accuracy),
//Location: omitnull.From(fmt.Sprintf("ST_GeometryFromText(Point(%s %s))", longitude, latitude)),
Location: omitnull.FromPtr[string](nil),
- MapZoom: omit.From(latlng.MapZoom),
+ MapZoom: omit.From(float32(0.0)),
//OrganizationID: omitnull.FromPtr(organization_id),
//PublicID: omit.From(public_id),
ReporterEmail: omit.From(""),
@@ -179,7 +122,7 @@ func (res *nuisanceR) Create(ctx context.Context, r *http.Request, n nuisanceFor
TodEvening: omit.From(n.TODEvening),
TodNight: omit.From(n.TODNight),
}
- report, err := platform.ReportNuisanceCreate(ctx, setter_report, setter_nuisance, latlng, address, uploads)
+ report, err := platform.ReportNuisanceCreate(ctx, setter_report, setter_nuisance, n.Location, address, uploads)
if err != nil {
return nil, nhttp.NewError("create nuisance report: %w", err)
}
diff --git a/resource/water.go b/resource/water.go
index 948b25e7..d5e97021 100644
--- a/resource/water.go
+++ b/resource/water.go
@@ -10,9 +10,10 @@ import (
"github.com/Gleipnir-Technology/nidus-sync/html"
nhttp "github.com/Gleipnir-Technology/nidus-sync/http"
"github.com/Gleipnir-Technology/nidus-sync/platform"
+ "github.com/Gleipnir-Technology/nidus-sync/platform/types"
"github.com/aarondl/opt/omit"
- //"github.com/aarondl/opt/omitnull"
- //"github.com/rs/zerolog/log"
+ "github.com/aarondl/opt/omitnull"
+ "github.com/rs/zerolog/log"
)
func Water(r *router) *waterR {
@@ -25,69 +26,64 @@ type waterR struct {
router *router
}
type water struct {
- ID string `json:"id"`
+ District string `json:"district"`
+ ID string `json:"id"`
+ URI string `json:"uri"`
}
type waterForm struct {
- AccessComments string `schema:"access-comments"`
- AccessDog bool `schema:"access-dog"`
- AccessFence bool `schema:"access-fence"`
- AccessGate bool `schema:"access-gate"`
- AccessLocked bool `schema:"access-locked"`
- AccessOther bool `schema:"access-other"`
- AddressRaw string `schema:"address"`
- AddressCountry string `schema:"address-country"`
- AddressLocality string `schema:"address-locality"`
- AddressNumber string `schema:"address-number"`
- AddressPostalCode string `schema:"address-postalcode"`
- AddressRegion string `schema:"address-region"`
- AddressStreet string `schema:"address-street"`
- Comments string `schema:"comments"`
- HasAdult bool `schema:"has-adult"`
- HasBackyardPermission bool `schema:"backyard-permission"`
- HasLarvae bool `schema:"has-larvae"`
- HasPupae bool `schema:"has-pupae"`
- IsReporterConfidential bool `schema:"reporter-confidential"`
- IsReporter_owner bool `schema:"property-ownership"`
- OwnerEmail string `schema:"owner-email"`
- OwnerName string `schema:"owner-name"`
- OwnerPhone string `schema:"owner-phone"`
+ AccessComments string `schema:"access-comments"`
+ AccessDog bool `schema:"access-dog"`
+ AccessFence bool `schema:"access-fence"`
+ AccessGate bool `schema:"access-gate"`
+ AccessLocked bool `schema:"access-locked"`
+ AccessOther bool `schema:"access-other"`
+ Address string `schema:"address"`
+ AddressGID string `schema:"address-gid"`
+ Comments string `schema:"comments"`
+ HasAdult bool `schema:"has-adult"`
+ HasBackyardPermission bool `schema:"backyard-permission"`
+ HasLarvae bool `schema:"has-larvae"`
+ HasPupae bool `schema:"has-pupae"`
+ IsReporterConfidential bool `schema:"reporter-confidential"`
+ IsReporter_owner bool `schema:"property-ownership"`
+ Location types.Location `schema:"location"`
+ Locator Locator `schema:"locator"`
+ OwnerEmail string `schema:"owner-email"`
+ OwnerName string `schema:"owner-name"`
+ OwnerPhone string `schema:"owner-phone"`
}
func (res *waterR) Create(ctx context.Context, r *http.Request, w waterForm) (*water, *nhttp.ErrorWithStatus) {
- latlng, err := parseLatLng(r)
- if err != nil {
- return nil, nhttp.NewError("Failed to parse lat lng for water report: %w", err)
- }
uploads, err := html.ExtractImageUploads(r)
+ log.Info().Int("len", len(uploads)).Msg("extracted water uploads")
if err != nil {
return nil, nhttp.NewError("Failed to extract image uploads: %w", err)
}
address := platform.Address{
- Country: w.AddressCountry,
- Locality: w.AddressLocality,
- Number: w.AddressNumber,
- PostalCode: w.AddressPostalCode,
- Raw: w.AddressRaw,
- Region: w.AddressRegion,
- Street: w.AddressStreet,
- Unit: "",
+ GID: w.AddressGID,
+ Raw: w.Address,
+ }
+ accuracy := float32(0.0)
+ if w.Location.Accuracy != nil {
+ accuracy = *w.Location.Accuracy
}
setter_report := models.PublicreportReportSetter{
AddressRaw: omit.From(address.Raw),
- AddressCountry: omit.From(address.Country),
- AddressNumber: omit.From(address.Number),
- AddressLocality: omit.From(address.Locality),
- AddressPostalCode: omit.From(address.PostalCode),
- AddressRegion: omit.From(address.Region),
- AddressStreet: omit.From(address.Street),
+ AddressCountry: omit.From(""),
+ AddressNumber: omit.From(""),
+ AddressLocality: omit.From(""),
+ AddressPostalCode: omit.From(""),
+ AddressRegion: omit.From(""),
+ AddressStreet: omit.From(""),
Created: omit.From(time.Now()),
//H3cell: omitnull.From(geospatial.Cell.String()),
- LatlngAccuracyType: omit.From(latlng.AccuracyType),
- LatlngAccuracyValue: omit.From(float32(latlng.AccuracyValue)),
+ LatlngAccuracyType: omit.From(enums.PublicreportAccuracytypeBrowser),
+ LatlngAccuracyValue: omit.From(accuracy),
//Location: add later
- MapZoom: omit.From(latlng.MapZoom),
+ Location: omitnull.FromPtr[string](nil),
+ MapZoom: omit.From(float32(0.0)),
//OrganizationID: omitnull.FromPtr(organization_id),
//PublicID: omit.From(public_id),
ReporterEmail: omit.From(""),
@@ -115,11 +111,21 @@ func (res *waterR) Create(ctx context.Context, r *http.Request, w waterForm) (*w
OwnerPhone: omit.From(w.OwnerPhone),
//ReportID omit.Val[int32]
}
- report, err := platform.ReportWaterCreate(ctx, setter_report, setter_water, latlng, address, uploads)
+ report, err := platform.ReportWaterCreate(ctx, setter_report, setter_water, w.Location, address, uploads)
if err != nil {
return nil, nhttp.NewError("Failed to save new report: %w", err)
}
+ uri, err := res.router.IDStrToURI("publicreport.ByIDGet", report.PublicID)
+ if err != nil {
+ return nil, nhttp.NewError("generate uri: %w", err)
+ }
+ district_uri, err := res.router.IDToURI("district.ByIDGet", int(report.OrganizationID))
+ if err != nil {
+ return nil, nhttp.NewError("generate district uri: %w", err)
+ }
return &water{
- ID: report.PublicID,
+ District: district_uri,
+ ID: report.PublicID,
+ URI: uri,
}, nil
}
diff --git a/scss/rmo/nuisance.scss b/scss/rmo/nuisance.scss
deleted file mode 100644
index e69de29b..00000000
diff --git a/scss/rmo/root.scss b/scss/rmo/root.scss
deleted file mode 100644
index b98631f1..00000000
--- a/scss/rmo/root.scss
+++ /dev/null
@@ -1,39 +0,0 @@
-.banner {
- display: block;
-}
-@include media-breakpoint-up(xs) {
- .banner {
- width: 100%;
- }
-}
-@include media-breakpoint-up(xl) {
- .banner {
- height: 100%;
- }
-}
-.service-card {
- transition: transform 0.3s;
- height: 100%;
-}
-.service-card:hover {
- transform: translateY(-5px);
- box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
-}
-.district-logo {
- max-height: 80px;
- width: auto;
-}
-.quick-report-mobile {
- background-color: #ff9800;
-}
-.quick-report-desktop {
- background-color: #ffefd5;
- border-left: 4px solid #ff9800;
-}
-
-.banner-container {
- position: relative;
- width: 100%;
- background-color: #f76436;
- overflow: hidden;
-}
diff --git a/scss/rmo/status.scss b/scss/rmo/status.scss
deleted file mode 100644
index da2c897d..00000000
--- a/scss/rmo/status.scss
+++ /dev/null
@@ -1,66 +0,0 @@
-.map-container {
- background-color: #e9ecef;
- border-radius: 10px;
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
- height: 500px;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-top: 20px;
-}
-#map {
- height: 500px;
- width: 100%;
- margin-bottom: 10px;
-}
-#map img {
- max-width: none;
- min-width: 0px;
- height: auto;
-}
-.search-box {
- box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
- border-radius: 8px;
-}
-@media (max-width: 768px) {
- .map-container {
- height: 300px;
- }
-}
-/* Base styles for circular checkboxes */
-.custom-circle-checkbox .form-check-input {
- border-radius: 50%;
- width: 20px;
- height: 20px;
- cursor: pointer;
- margin-top: 0.25rem;
- background-image: none; /* Remove Bootstrap's default checkmark */
- position: relative;
-}
-
-/* Style for when checked */
-.custom-circle-checkbox .form-check-input:checked {
- background-color: currentColor;
- border-color: currentColor;
-}
-
-/* Style for when unchecked - just an outline */
-.custom-circle-checkbox .form-check-input:not(:checked) {
- background-color: transparent;
-}
-
-/* Colors based on data attribute */
-.custom-circle-checkbox .form-check-input[data-color="danger"] {
- border-color: $red;
- color: $red;
-}
-
-.custom-circle-checkbox .form-check-input[data-color="success"] {
- border-color: $blue;
- color: $blue;
-}
-
-.custom-circle-checkbox .form-check-input[data-color="info"] {
- border-color: $green;
- color: $green;
-}
diff --git a/ts/components/AddressSuggestion.vue b/ts/components/AddressSuggestion.vue
index 8bd7b3e7..5cda764e 100644
--- a/ts/components/AddressSuggestion.vue
+++ b/ts/components/AddressSuggestion.vue
@@ -30,7 +30,7 @@
width: 100%;
max-height: 300px;
overflow-y: auto;
- z-index: 1000;
+ z-index: 3;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background: white;
}
diff --git a/ts/components/MapLocator.vue b/ts/components/MapLocator.vue
index 33899a32..b63d3a37 100644
--- a/ts/components/MapLocator.vue
+++ b/ts/components/MapLocator.vue
@@ -1,4 +1,4 @@
-
+
+
You can also click on the map to mark the location precisely