Add centroid information when geocoding
I would use the boundary rect, but I'm getting a 500-level error from stadia maps
This commit is contained in:
parent
8feabbc489
commit
2bb4a134b2
10 changed files with 272 additions and 56 deletions
|
|
@ -258,6 +258,24 @@ var Organizations = Table[
|
|||
Generated: true,
|
||||
AutoIncr: false,
|
||||
},
|
||||
ServiceAreaCentroidX: column{
|
||||
Name: "service_area_centroid_x",
|
||||
DBType: "double precision",
|
||||
Default: "GENERATED",
|
||||
Comment: "",
|
||||
Nullable: true,
|
||||
Generated: true,
|
||||
AutoIncr: false,
|
||||
},
|
||||
ServiceAreaCentroidY: column{
|
||||
Name: "service_area_centroid_y",
|
||||
DBType: "double precision",
|
||||
Default: "GENERATED",
|
||||
Comment: "",
|
||||
Nullable: true,
|
||||
Generated: true,
|
||||
AutoIncr: false,
|
||||
},
|
||||
},
|
||||
Indexes: organizationIndexes{
|
||||
OrganizationPkey: index{
|
||||
|
|
@ -372,11 +390,13 @@ type organizationColumns struct {
|
|||
ServiceAreaXmax column
|
||||
ServiceAreaYmax column
|
||||
ServiceAreaCentroidGeojson column
|
||||
ServiceAreaCentroidX column
|
||||
ServiceAreaCentroidY column
|
||||
}
|
||||
|
||||
func (c organizationColumns) AsSlice() []column {
|
||||
return []column{
|
||||
c.ID, c.Name, c.ArcgisID, c.ArcgisName, c.FieldseekerURL, c.ImportDistrictGid, c.Website, c.LogoUUID, c.Slug, c.GeneralManagerName, c.MailingAddressCity, c.MailingAddressPostalCode, c.MailingAddressStreet, c.OfficeAddressCity, c.OfficeAddressPostalCode, c.OfficeAddressStreet, c.ServiceAreaGeometry, c.ServiceAreaSquareMeters, c.ServiceAreaCentroid, c.ServiceAreaExtent, c.OfficeFax, c.OfficePhone, c.ServiceAreaXmin, c.ServiceAreaYmin, c.ServiceAreaXmax, c.ServiceAreaYmax, c.ServiceAreaCentroidGeojson,
|
||||
c.ID, c.Name, c.ArcgisID, c.ArcgisName, c.FieldseekerURL, c.ImportDistrictGid, c.Website, c.LogoUUID, c.Slug, c.GeneralManagerName, c.MailingAddressCity, c.MailingAddressPostalCode, c.MailingAddressStreet, c.OfficeAddressCity, c.OfficeAddressPostalCode, c.OfficeAddressStreet, c.ServiceAreaGeometry, c.ServiceAreaSquareMeters, c.ServiceAreaCentroid, c.ServiceAreaExtent, c.OfficeFax, c.OfficePhone, c.ServiceAreaXmin, c.ServiceAreaYmin, c.ServiceAreaXmax, c.ServiceAreaYmax, c.ServiceAreaCentroidGeojson, c.ServiceAreaCentroidX, c.ServiceAreaCentroidY,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2929,6 +2929,8 @@ func (f *Factory) FromExistingOrganization(m *models.Organization) *Organization
|
|||
o.ServiceAreaXmax = func() null.Val[float64] { return m.ServiceAreaXmax }
|
||||
o.ServiceAreaYmax = func() null.Val[float64] { return m.ServiceAreaYmax }
|
||||
o.ServiceAreaCentroidGeojson = func() null.Val[string] { return m.ServiceAreaCentroidGeojson }
|
||||
o.ServiceAreaCentroidX = func() null.Val[float64] { return m.ServiceAreaCentroidX }
|
||||
o.ServiceAreaCentroidY = func() null.Val[float64] { return m.ServiceAreaCentroidY }
|
||||
|
||||
ctx := context.Background()
|
||||
if len(m.R.EmailContacts) > 0 {
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ type OrganizationTemplate struct {
|
|||
ServiceAreaXmax func() null.Val[float64]
|
||||
ServiceAreaYmax func() null.Val[float64]
|
||||
ServiceAreaCentroidGeojson func() null.Val[string]
|
||||
ServiceAreaCentroidX func() null.Val[float64]
|
||||
ServiceAreaCentroidY func() null.Val[float64]
|
||||
|
||||
r organizationR
|
||||
f *Factory
|
||||
|
|
@ -971,6 +973,12 @@ func (o OrganizationTemplate) Build() *models.Organization {
|
|||
if o.ServiceAreaCentroidGeojson != nil {
|
||||
m.ServiceAreaCentroidGeojson = o.ServiceAreaCentroidGeojson()
|
||||
}
|
||||
if o.ServiceAreaCentroidX != nil {
|
||||
m.ServiceAreaCentroidX = o.ServiceAreaCentroidX()
|
||||
}
|
||||
if o.ServiceAreaCentroidY != nil {
|
||||
m.ServiceAreaCentroidY = o.ServiceAreaCentroidY()
|
||||
}
|
||||
|
||||
o.setModelRels(m)
|
||||
|
||||
|
|
@ -1902,6 +1910,8 @@ func (m organizationMods) RandomizeAllColumns(f *faker.Faker) OrganizationMod {
|
|||
OrganizationMods.RandomServiceAreaXmax(f),
|
||||
OrganizationMods.RandomServiceAreaYmax(f),
|
||||
OrganizationMods.RandomServiceAreaCentroidGeojson(f),
|
||||
OrganizationMods.RandomServiceAreaCentroidX(f),
|
||||
OrganizationMods.RandomServiceAreaCentroidY(f),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3292,6 +3302,112 @@ func (m organizationMods) RandomServiceAreaCentroidGeojsonNotNull(f *faker.Faker
|
|||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m organizationMods) ServiceAreaCentroidX(val null.Val[float64]) OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.ServiceAreaCentroidX = func() null.Val[float64] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m organizationMods) ServiceAreaCentroidXFunc(f func() null.Val[float64]) OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.ServiceAreaCentroidX = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m organizationMods) UnsetServiceAreaCentroidX() OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.ServiceAreaCentroidX = 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 organizationMods) RandomServiceAreaCentroidX(f *faker.Faker) OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.ServiceAreaCentroidX = func() null.Val[float64] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
val := random_float64(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 organizationMods) RandomServiceAreaCentroidXNotNull(f *faker.Faker) OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.ServiceAreaCentroidX = func() null.Val[float64] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
val := random_float64(f)
|
||||
return null.From(val)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Set the model columns to this value
|
||||
func (m organizationMods) ServiceAreaCentroidY(val null.Val[float64]) OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.ServiceAreaCentroidY = func() null.Val[float64] { return val }
|
||||
})
|
||||
}
|
||||
|
||||
// Set the Column from the function
|
||||
func (m organizationMods) ServiceAreaCentroidYFunc(f func() null.Val[float64]) OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.ServiceAreaCentroidY = f
|
||||
})
|
||||
}
|
||||
|
||||
// Clear any values for the column
|
||||
func (m organizationMods) UnsetServiceAreaCentroidY() OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.ServiceAreaCentroidY = 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 organizationMods) RandomServiceAreaCentroidY(f *faker.Faker) OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.ServiceAreaCentroidY = func() null.Val[float64] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
val := random_float64(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 organizationMods) RandomServiceAreaCentroidYNotNull(f *faker.Faker) OrganizationMod {
|
||||
return OrganizationModFunc(func(_ context.Context, o *OrganizationTemplate) {
|
||||
o.ServiceAreaCentroidY = func() null.Val[float64] {
|
||||
if f == nil {
|
||||
f = &defaultFaker
|
||||
}
|
||||
|
||||
val := random_float64(f)
|
||||
return null.From(val)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (m organizationMods) WithParentsCascading() OrganizationMod {
|
||||
return OrganizationModFunc(func(ctx context.Context, o *OrganizationTemplate) {
|
||||
if isDone, _ := organizationWithParentsCascadingCtx.Value(ctx); isDone {
|
||||
|
|
|
|||
3
db/migrations/00067_org_centroid_coords.sql
Normal file
3
db/migrations/00067_org_centroid_coords.sql
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
-- +goose Up
|
||||
ALTER TABLE organization ADD COLUMN service_area_centroid_x DOUBLE PRECISION GENERATED ALWAYS AS (ST_X(ST_Centroid(service_area_geometry))) STORED;
|
||||
ALTER TABLE organization ADD COLUMN service_area_centroid_y DOUBLE PRECISION GENERATED ALWAYS AS (ST_Y(ST_Centroid(service_area_geometry))) STORED;
|
||||
|
|
@ -56,6 +56,8 @@ type Organization struct {
|
|||
ServiceAreaXmax null.Val[float64] `db:"service_area_xmax,generated" `
|
||||
ServiceAreaYmax null.Val[float64] `db:"service_area_ymax,generated" `
|
||||
ServiceAreaCentroidGeojson null.Val[string] `db:"service_area_centroid_geojson,generated" `
|
||||
ServiceAreaCentroidX null.Val[float64] `db:"service_area_centroid_x,generated" `
|
||||
ServiceAreaCentroidY null.Val[float64] `db:"service_area_centroid_y,generated" `
|
||||
|
||||
R organizationR `db:"-" `
|
||||
|
||||
|
|
@ -118,7 +120,7 @@ type organizationR struct {
|
|||
func buildOrganizationColumns(alias string) organizationColumns {
|
||||
return organizationColumns{
|
||||
ColumnsExpr: expr.NewColumnsExpr(
|
||||
"id", "name", "arcgis_id", "arcgis_name", "fieldseeker_url", "import_district_gid", "website", "logo_uuid", "slug", "general_manager_name", "mailing_address_city", "mailing_address_postal_code", "mailing_address_street", "office_address_city", "office_address_postal_code", "office_address_street", "service_area_geometry", "service_area_square_meters", "service_area_centroid", "service_area_extent", "office_fax", "office_phone", "service_area_xmin", "service_area_ymin", "service_area_xmax", "service_area_ymax", "service_area_centroid_geojson",
|
||||
"id", "name", "arcgis_id", "arcgis_name", "fieldseeker_url", "import_district_gid", "website", "logo_uuid", "slug", "general_manager_name", "mailing_address_city", "mailing_address_postal_code", "mailing_address_street", "office_address_city", "office_address_postal_code", "office_address_street", "service_area_geometry", "service_area_square_meters", "service_area_centroid", "service_area_extent", "office_fax", "office_phone", "service_area_xmin", "service_area_ymin", "service_area_xmax", "service_area_ymax", "service_area_centroid_geojson", "service_area_centroid_x", "service_area_centroid_y",
|
||||
).WithParent("organization"),
|
||||
tableAlias: alias,
|
||||
ID: psql.Quote(alias, "id"),
|
||||
|
|
@ -148,6 +150,8 @@ func buildOrganizationColumns(alias string) organizationColumns {
|
|||
ServiceAreaXmax: psql.Quote(alias, "service_area_xmax"),
|
||||
ServiceAreaYmax: psql.Quote(alias, "service_area_ymax"),
|
||||
ServiceAreaCentroidGeojson: psql.Quote(alias, "service_area_centroid_geojson"),
|
||||
ServiceAreaCentroidX: psql.Quote(alias, "service_area_centroid_x"),
|
||||
ServiceAreaCentroidY: psql.Quote(alias, "service_area_centroid_y"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -181,6 +185,8 @@ type organizationColumns struct {
|
|||
ServiceAreaXmax psql.Expression
|
||||
ServiceAreaYmax psql.Expression
|
||||
ServiceAreaCentroidGeojson psql.Expression
|
||||
ServiceAreaCentroidX psql.Expression
|
||||
ServiceAreaCentroidY psql.Expression
|
||||
}
|
||||
|
||||
func (c organizationColumns) Alias() string {
|
||||
|
|
@ -4449,6 +4455,8 @@ type organizationWhere[Q psql.Filterable] struct {
|
|||
ServiceAreaXmax psql.WhereNullMod[Q, float64]
|
||||
ServiceAreaYmax psql.WhereNullMod[Q, float64]
|
||||
ServiceAreaCentroidGeojson psql.WhereNullMod[Q, string]
|
||||
ServiceAreaCentroidX psql.WhereNullMod[Q, float64]
|
||||
ServiceAreaCentroidY psql.WhereNullMod[Q, float64]
|
||||
}
|
||||
|
||||
func (organizationWhere[Q]) AliasedAs(alias string) organizationWhere[Q] {
|
||||
|
|
@ -4484,6 +4492,8 @@ func buildOrganizationWhere[Q psql.Filterable](cols organizationColumns) organiz
|
|||
ServiceAreaXmax: psql.WhereNull[Q, float64](cols.ServiceAreaXmax),
|
||||
ServiceAreaYmax: psql.WhereNull[Q, float64](cols.ServiceAreaYmax),
|
||||
ServiceAreaCentroidGeojson: psql.WhereNull[Q, string](cols.ServiceAreaCentroidGeojson),
|
||||
ServiceAreaCentroidX: psql.WhereNull[Q, float64](cols.ServiceAreaCentroidX),
|
||||
ServiceAreaCentroidY: psql.WhereNull[Q, float64](cols.ServiceAreaCentroidY),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -379,6 +379,7 @@ func errorMissingHeader(ctx context.Context, txn bob.Tx, c *models.FileuploadCSV
|
|||
return addError(ctx, txn, c, 0, 0, msg)
|
||||
}
|
||||
func maybeAddServiceArea(req *stadia.StructuredGeocodeRequest, org *models.Organization) {
|
||||
/*
|
||||
if org.ServiceAreaXmax.IsNull() ||
|
||||
org.ServiceAreaYmax.IsNull() ||
|
||||
org.ServiceAreaXmin.IsNull() ||
|
||||
|
|
@ -393,6 +394,14 @@ func maybeAddServiceArea(req *stadia.StructuredGeocodeRequest, org *models.Organ
|
|||
req.BoundaryRectMaxLat = &ymax
|
||||
req.BoundaryRectMinLon = &xmin
|
||||
req.BoundaryRectMinLat = &ymin
|
||||
*/
|
||||
if org.ServiceAreaCentroidX.IsNull() || org.ServiceAreaCentroidY.IsNull() {
|
||||
return
|
||||
}
|
||||
centroid_x := org.ServiceAreaCentroidX.MustGet()
|
||||
centroid_y := org.ServiceAreaCentroidY.MustGet()
|
||||
req.FocusPointLat = ¢roid_y
|
||||
req.FocusPointLng = ¢roid_x
|
||||
}
|
||||
func parseHeaders(row []string) ([]headerPoolEnum, []string) {
|
||||
result_enums := make([]headerPoolEnum, 0)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ func main() {
|
|||
boundaryRectMinLat := flag.Float64("boundary-rect-min-lat", 0, "The min lat of the boundary")
|
||||
boundaryRectMaxLon := flag.Float64("boundary-rect-max-lng", 0, "The max lon of the boundary")
|
||||
boundaryRectMinLon := flag.Float64("boundary-rect-min-lng", 0, "The min lon of the boundary")
|
||||
city := flag.String("city", "", "City address to geocode")
|
||||
postalCode := flag.String("postal-code", "", "Postal code")
|
||||
focusLat := flag.Float64("focus-lat", 0, "The latitude of the focus point")
|
||||
focusLng := flag.Float64("focus-lng", 0, "The longitude of the focus point")
|
||||
|
|
@ -35,23 +36,23 @@ func main() {
|
|||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
if focusLat != nil && focusLng == nil {
|
||||
if *focusLat != 0 && *focusLng == 0 {
|
||||
log.Println("Error: you must specify both focus-lat and focus-lng together, not just focus-lat")
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
if focusLat == nil && focusLng != nil {
|
||||
if *focusLat == 0 && *focusLng != 0 {
|
||||
log.Println("Error: you must specify both focus-lat and focus-lng together, not just focus-lng")
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
if (boundaryRectMaxLat != nil ||
|
||||
boundaryRectMinLat != nil ||
|
||||
boundaryRectMaxLon != nil ||
|
||||
boundaryRectMinLon != nil) && (boundaryRectMaxLat == nil ||
|
||||
boundaryRectMinLat == nil ||
|
||||
boundaryRectMaxLon == nil ||
|
||||
boundaryRectMinLon == nil) {
|
||||
if (*boundaryRectMaxLat != 0 ||
|
||||
*boundaryRectMinLat != 0 ||
|
||||
*boundaryRectMaxLon != 0 ||
|
||||
*boundaryRectMinLon != 0) && (*boundaryRectMaxLat == 0 ||
|
||||
*boundaryRectMinLat == 0 ||
|
||||
*boundaryRectMaxLon == 0 ||
|
||||
*boundaryRectMinLon == 0) {
|
||||
log.Println("If you specify one of boundary-rect you need to specify them all")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
|
@ -68,16 +69,19 @@ func main() {
|
|||
Address: address,
|
||||
PostalCode: postalCode,
|
||||
}
|
||||
if focusLat != nil && focusLng != nil {
|
||||
if *focusLat != 0 && *focusLng != 0 {
|
||||
req.FocusPointLat = focusLat
|
||||
req.FocusPointLng = focusLng
|
||||
}
|
||||
if boundaryRectMaxLat != nil {
|
||||
if *boundaryRectMaxLat != 0 {
|
||||
req.BoundaryRectMaxLat = boundaryRectMaxLat
|
||||
req.BoundaryRectMinLat = boundaryRectMinLat
|
||||
req.BoundaryRectMaxLon = boundaryRectMaxLon
|
||||
req.BoundaryRectMinLon = boundaryRectMinLon
|
||||
}
|
||||
if *city != "" {
|
||||
req.Locality = city
|
||||
}
|
||||
resp, err := client.StructuredGeocode(ctx, req)
|
||||
if err != nil {
|
||||
log.Printf("err: %v\n", err)
|
||||
|
|
@ -86,7 +90,7 @@ func main() {
|
|||
log.Printf("type: %s, features: %d\n", resp.Type, len(resp.Features))
|
||||
for i, feature := range resp.Features {
|
||||
log.Printf("feature %d: type %s\n", i, feature.Type)
|
||||
log.Printf("\tgeometry %s\n", feature.Geometry.Type)
|
||||
log.Printf("\tgeometry %s (%f %f)\n", feature.Geometry.Type, feature.Geometry.Coordinates[0], feature.Geometry.Coordinates[1])
|
||||
log.Printf("\tproperties %s\n", feature.Properties.Layer)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
80
stadia/error.go
Normal file
80
stadia/error.go
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
package stadia
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"resty.dev/v3"
|
||||
)
|
||||
|
||||
// Unfortunately, Stadia Maps is inconsistent in how it handles errors.
|
||||
// We therefore have to have a function that handles all the different JSON
|
||||
// error variations.
|
||||
func parseError(resp *resty.Response) error {
|
||||
content, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading all body: %w", err)
|
||||
}
|
||||
var server_error serverError
|
||||
err = json.Unmarshal(content, &server_error)
|
||||
if err == nil {
|
||||
return newAPIError(resp.StatusCode(), server_error.Error.Reason)
|
||||
}
|
||||
|
||||
// At this point we've exhausted all of our options, so just pass the JSON through
|
||||
return newAPIError(resp.StatusCode(), string(content))
|
||||
}
|
||||
|
||||
type apiError struct {
|
||||
Message string
|
||||
Status int
|
||||
}
|
||||
|
||||
func newAPIError(status int, msg string) apiError {
|
||||
return apiError{
|
||||
Message: msg,
|
||||
Status: status,
|
||||
}
|
||||
}
|
||||
func (e apiError) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
ErrorMessage string `json:"error"`
|
||||
Errors []string `json:"errors"`
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
return e.ErrorMessage
|
||||
}
|
||||
|
||||
/*
|
||||
Got this when I managed to bork the server
|
||||
|
||||
{
|
||||
"error": {
|
||||
"reason": "Internal Server Error"
|
||||
},
|
||||
"status": 500
|
||||
}
|
||||
*/
|
||||
type errorWithReason struct {
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
type serverError struct {
|
||||
Error errorWithReason `json:"error"`
|
||||
Status int `json:"status"`
|
||||
}
|
||||
|
||||
/*
|
||||
if len(result.Geocode.Errors) > 0 {
|
||||
joined := strings.Join(result.Geocode.Errors, ", ")
|
||||
return nil, fmt.Errorf("structured geocoding failure: %d '%s'", resp.StatusCode(), joined)
|
||||
} else if result.Geocode.Error != "" {
|
||||
return nil, fmt.Errorf("structured geocoding failure: %d '%s'", resp.StatusCode(), result.Geocode.Error)
|
||||
} else {
|
||||
return nil, fmt.Errorf("structured geocoding failure: %d", resp.StatusCode())
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,18 +1,9 @@
|
|||
package stadia
|
||||
|
||||
type Error struct {
|
||||
ErrorMessage string `json:"error"`
|
||||
Errors []string `json:"errors"`
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
return e.ErrorMessage
|
||||
}
|
||||
|
||||
// GeocodeResponse represents the top-level response from the geocoding API
|
||||
type GeocodeResponse struct {
|
||||
BBox []float64 `json:"bbox"` // [W, S, E, N]
|
||||
ErrorMessage string `json:"error"`
|
||||
ErrorMessage string `json:"error,omitempty"`
|
||||
Features []GeocodeFeature `json:"features"`
|
||||
Geocode GeocodeMeta `json:"geocoding"`
|
||||
Type string `json:"type"` // Should be "FeatureCollection"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package stadia
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
|
@ -58,7 +57,6 @@ func (s *StadiaMaps) StructuredGeocode(ctx context.Context, req StructuredGeocod
|
|||
resp, err := s.client.R().
|
||||
SetQueryParamsFromValues(query).
|
||||
SetContext(ctx).
|
||||
SetError(&result).
|
||||
SetResult(&result).
|
||||
SetPathParam("urlBase", s.urlBase).
|
||||
SetQueryParam("api_key", s.APIKey).
|
||||
|
|
@ -68,24 +66,7 @@ func (s *StadiaMaps) StructuredGeocode(ctx context.Context, req StructuredGeocod
|
|||
}
|
||||
|
||||
if !resp.IsSuccess() {
|
||||
/*
|
||||
if api_error.Error() != "" {
|
||||
return nil, &api_error
|
||||
}
|
||||
content, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read all failure: %w", err)
|
||||
}
|
||||
*/
|
||||
fmt.Printf("geocoding error: %s\n", result.Geocode.Error)
|
||||
if len(result.Geocode.Errors) > 0 {
|
||||
joined := strings.Join(result.Geocode.Errors, ", ")
|
||||
return nil, fmt.Errorf("structured geocoding failure: %d '%s'", resp.StatusCode(), joined)
|
||||
} else if result.Geocode.Error != "" {
|
||||
return nil, fmt.Errorf("structured geocoding failure: %d '%s'", resp.StatusCode(), result.Geocode.Error)
|
||||
} else {
|
||||
return nil, fmt.Errorf("structured geocoding failure: %d", resp.StatusCode())
|
||||
}
|
||||
return nil, parseError(resp)
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue