Skip to content

Commit

Permalink
Show and allow filtering of way_area
Browse files Browse the repository at this point in the history
  • Loading branch information
codesoap committed Sep 27, 2020
1 parent 410b92a commit a03defc
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 17 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ name: Velo-Sport
operator: Velo-Sport Ihr Radsporthaus GmbH
shop: bicycle

$ # Find a natural forest of at least 1km² in Bremen:
$ osmf polygon 53.076 8.807 3300 natural=wood 'way_area>1e+6' | awk '/^$/ /[^ ]*: ./'
distance_meters: 3242
osm_id: -1717327
osm_link: https://www.openstreetmap.org/relation/1717327
natural: wood
way_area: 1663160.000000

$ # Searching for multiple values of the same tag is also possible:
$ osmf point 53.076 8.807 15000 sport=climbing sport=swimming | awk '/^$/ /[^ ]*: ./'
distance_meters: 3169
Expand Down Expand Up @@ -77,9 +85,9 @@ sport: running

# Usage
```
osmf line <lat> <long> <radius_meter> [<tag>=<value>]...
osmf point <lat> <long> <radius_meter> [<tag>=<value>]...
osmf polygon <lat> <long> <radius_meter> [<tag>=<value>]...
osmf line <lat> <long> <radius_meter> [way_area<<value>] [way_area><value>] [<tag>=<value>]...
osmf polygon <lat> <long> <radius_meter> [way_area<<value>] [way_area><value>] [<tag>=<value>]...
General tags:
- access
Expand Down
66 changes: 51 additions & 15 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (
)

const usage = `Usage:
osmf line <lat> <long> <radius_meter> [<tag>=<value>]...
osmf point <lat> <long> <radius_meter> [<tag>=<value>]...
osmf polygon <lat> <long> <radius_meter> [<tag>=<value>]...
osmf line <lat> <long> <radius_meter> [way_area<<value>] [way_area><value>] [<tag>=<value>]...
osmf polygon <lat> <long> <radius_meter> [way_area<<value>] [way_area><value>] [<tag>=<value>]...
`

var pool *sql.DB
Expand Down Expand Up @@ -43,10 +43,10 @@ func main() {
dieOnErr("Could not parse long: %s\n", err)
radius, err := strconv.ParseFloat(os.Args[4], 64)
dieOnErr("Could not parse radius: %s\n", err)
tags, err := getTags()
dieOnErr("Could not parse tags: %s\n", err)
tags, minWayArea, maxWayArea, err := getFilters()
dieOnErr("Could not parse filters: %s\n", err)

rows, err := queryDB(lat, long, radius, tags)
rows, err := queryDB(lat, long, radius, tags, minWayArea, maxWayArea)
dieOnErr("Failed to query database: %s\n", err)
dieOnErr("Failed to print results: %s\n", printResults(rows))
}
Expand All @@ -58,25 +58,43 @@ func dieOnErr(msg string, err error) {
}
}

func getTags() (map[string][]string, error) {
tags := make(map[string][]string)
for _, tag := range os.Args[5:] {
split := strings.SplitN(tag, "=", 2)
if len(split) != 2 {
return tags, fmt.Errorf("tag without value: %s", tag)
func getFilters() (tags map[string][]string, minWayArea, maxWayArea *float64, err error) {
tags = make(map[string][]string)
for _, arg := range os.Args[5:] {
if strings.HasPrefix(arg, "way_area>") {
var minWayAreaTmp float64
minWayAreaTmp, err = strconv.ParseFloat(arg[9:], 64)
if err != nil {
return
}
minWayArea = &minWayAreaTmp
} else if strings.HasPrefix(arg, "way_area<") {
var maxWayAreaTmp float64
maxWayAreaTmp, err = strconv.ParseFloat(arg[9:], 64)
if err != nil {
return
}
maxWayArea = &maxWayAreaTmp
} else {
split := strings.SplitN(arg, "=", 2)
if len(split) != 2 {
err = fmt.Errorf("tag without value: %s", arg)
return
}
tags[split[0]] = append(tags[split[0]], split[1])
}
tags[split[0]] = append(tags[split[0]], split[1])
}
return tags, nil
return
}

func queryDB(lat, long, radius float64, tags map[string][]string) (*sql.Rows, error) {
func queryDB(lat, long, radius float64, tags map[string][]string, minWayArea, maxWayArea *float64) (*sql.Rows, error) {
refPoint := fmt.Sprintf("ST_SetSRID(ST_Point(%f, %f), 4326)::geography", long, lat)
distance := fmt.Sprintf("ST_Distance(ST_Transform(way, 4326)::geography, %s) AS distance", refPoint)
query := fmt.Sprintf("SELECT %s, * FROM planet_osm_%s\n", distance, os.Args[1])
poly := getBoundaryPolygon(lat, long, radius)
query += fmt.Sprintf("WHERE way && ST_Transform(ST_GeomFromText('%s', 4326), 3857)", poly)
query += getTagsFilter(tags)
query += getWayAreaFilter(minWayArea, maxWayArea)
query += "\nORDER BY distance"
return pool.Query(query)
}
Expand Down Expand Up @@ -115,6 +133,16 @@ func getTagsFilter(tags map[string][]string) (filter string) {
return
}

func getWayAreaFilter(minWayArea, maxWayArea *float64) (filter string) {
if minWayArea != nil {
filter += fmt.Sprintf("\nAND way_area > %f", *minWayArea)
}
if maxWayArea != nil {
filter += fmt.Sprintf("\nAND way_area < %f", *maxWayArea)
}
return
}

func printResults(rows *sql.Rows) error {
colNames, err := rows.Columns()
if err != nil {
Expand Down Expand Up @@ -143,8 +171,16 @@ func printResult(colNames []string, colPtrs []interface{}, rows *sql.Rows) error
return fmt.Errorf("failed to read row: %s\n", err.Error())
}
for i, colName := range colNames {
if colName == "z_order" || colName == "way_area" || colName == "way" {
if colName == "z_order" || colName == "way" {
// Those columns are not for displaying.
} else if colName == "way_area" {
val := colPtrs[i].(*interface{})
valFloat, ok := (*val).(float64)
if ok {
fmt.Printf("%s: %f\n", colName, valFloat)
} else {
fmt.Printf("%s:\n", colName, valFloat)
}
} else if colName == "distance" {
val := colPtrs[i].(*interface{})
fmt.Printf("distance_meters: %.0f\n", (*val).(float64))
Expand Down

0 comments on commit a03defc

Please sign in to comment.