Skip to content

Commit

Permalink
download relations
Browse files Browse the repository at this point in the history
  • Loading branch information
Shanghui Yang committed May 21, 2020
1 parent 962eec3 commit 65720ac
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 88 deletions.
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@
Download nodes or ways by specific ids from open street map

## Install
to use this tool, you need to install osmosis first.
please refer to https://wiki.openstreetmap.org/wiki/Osmosis/Installation for installing it.
for example,
```shell
# for MacOS
$ brew install osmosis
```

install source codes
```shell
$ go get github.com/shanghuiyang/osmdownloader
```
Expand All @@ -15,10 +24,11 @@ $ go build -o osmdownloader main.go

## Usage
```
osmdownloader -f xxx.osm [-n list | -w list]
osmdownloader -f xxx.osm [-n list | -w list | -r list]
-f the output file
-n the id list of nodes
-w the id list of ways
-r the id list of relations
```

## Example
Expand All @@ -27,5 +37,5 @@ $ osmdownloader -f test.osm -n 111,222,333
# or
$ osmdownloader -f test.osm -w 444,555,666
# or
$ osmdownloader -f test.osm -n 111,222,333 -w 444,555,666
$ osmdownloader -f test.osm -n 111,111,222 -w 333,444 -r 555,666
```
184 changes: 98 additions & 86 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,125 +7,138 @@ import (
"strings"
)

type element string

const (
api = "https://www.openstreetmap.org/api/0.6"

node element = "node"
way element = "way"
relation element = "relation"
)

func main() {

argCount := len(os.Args)
if argCount != 5 && argCount != 7 {
if argCount != 5 && argCount != 7 && argCount != 9 {
fmt.Println("error: invalid args")
fmt.Println(`usage: osmdownloader -f "test.osm" -n 111,222 -w 333,444`)
return
fmt.Println(`usage: osmdownloader -f "test.osm" -n 111,222 -w 333,444 -r 555,666`)
os.Exit(-1)
}
var file string
var nodeIDs string
var wayIDs string
var (
file string
nodeids string
wayids string
relationids string
)
for i, arg := range os.Args {
if arg == "-f" || arg == "-F" {
file = os.Args[i+1]
}
if arg == "-n" || arg == "-N" {
nodeIDs = os.Args[i+1]
nodeids = os.Args[i+1]
}
if arg == "-w" || arg == "-W" {
wayIDs = os.Args[i+1]
wayids = os.Args[i+1]
}
if arg == "-r" || arg == "-R" {
relationids = os.Args[i+1]
}
}

if file == "" {
fmt.Printf("need to specify a file for saving map data\n")
return
os.Exit(-1)
}
if nodeIDs == "" && wayIDs == "" {
fmt.Printf("need to specify the ids for node or way\n")
return
if nodeids == "" && wayids == "" && relationids == "" {
fmt.Printf("need to specify the element ids\n")
os.Exit(-1)
}

fmt.Printf("file: %v\n", file)
arrayNodeIDs := []string{}
arrayWayIDs := []string{}
if nodeIDs != "" {
fmt.Printf("nodes: %v\n", nodeIDs)
arrayNodeIDs = strings.Split(nodeIDs, ",")
var files []string
if nodeids != "" {
f := download(node, nodeids)
files = append(files, f...)
}
if wayIDs != "" {
fmt.Printf("ways: %v\n", wayIDs)
arrayWayIDs = strings.Split(wayIDs, ",")

if wayids != "" {
f := download(way, wayids)
files = append(files, f...)
}
fmt.Printf("--------\n")

files := map[string]string{}
var error int
for _, id := range arrayNodeIDs {
url := fmt.Sprintf("%v/node/%v", api, id)
fmt.Printf("node %v\t", id)
f := fmt.Sprintf("n%v.osm", id)
cmd := exec.Command("wget", url, "-O", f)
if err := cmd.Run(); err != nil {
fmt.Printf("not found\n")
error++
continue
}
if isEmptyFile(f) {
fmt.Printf("not found\n")
error++
continue
}
fmt.Printf("ok\n")
files[f] = id
if relationids != "" {
f := download(relation, relationids)
files = append(files, f...)
}

for _, id := range arrayWayIDs {
url := fmt.Sprintf("%v/way/%v/full", api, id)
fmt.Printf("way %v\t", id)
f := fmt.Sprintf("w%v.osm", id)
cmd := exec.Command("wget", url, "-O", f)
if err := cmd.Run(); err != nil {
fmt.Printf("not found\n")
error++
continue
}
if isEmptyFile(f) {
fmt.Printf("not found\n")
error++
continue
}
fmt.Printf("ok\n")
files[f] = id
fmt.Printf("---------------------------------------------\n")
if len(files) == 0 {
fmt.Printf("nothing was downloaded\n")
os.Exit(-1)
}

var args []string
for f := range files {
for _, f := range files {
args = append(args, "--read-xml")
args = append(args, f)
}
for i := 0; i < len(files)-1; i++ {
args = append(args, "--merge")
}

if len(files) > 0 {
args = append(args, "--write-xml")
args = append(args, file)
args = append(args, "--write-xml")
args = append(args, file)

fmt.Printf("generate %v\n", file)
cmd := exec.Command("osmosis", args...)
if err := cmd.Run(); err != nil {
fmt.Printf("failed to merge *.osm\n")
error++
}
fmt.Printf("generate %v\n", file)
cmd := exec.Command("osmosis", args...)
if err := cmd.Run(); err != nil {
fmt.Printf("failed to merge *.osm, err: %v\n", err)
clear(files)
os.Exit(-1)
}

error += clear("n", arrayNodeIDs)
error += clear("w", arrayWayIDs)
clear(files)
fmt.Printf("done in success\n")
os.Exit(0)
}

func download(e element, idlist string) []string {

if error == 0 {
fmt.Printf("done in success\n")
} else {
fmt.Printf("done with %v errors\n", error)
if idlist == "" {
return nil
}
return
var (
succes []string
failed []string
)
defer func() {
clear(failed)
}()

ids := strings.Split(idlist, ",")
for _, id := range ids {
url := fmt.Sprintf("%v/%v/%v", api, e, id)
if e == way || e == relation {
url += "/full"
}

fmt.Printf("%-15s%-15s", e, id)
f := fmt.Sprintf("%v%v.osm", e, id)
cmd := exec.Command("wget", url, "-O", f)
if err := cmd.Run(); err != nil {
fmt.Printf("%-15s\n", "[not found]")
failed = append(failed, f)
continue
}

if isEmptyFile(f) {
fmt.Printf("%-15s\n", "[not found]")
failed = append(failed, f)
continue
}
fmt.Printf("%-15s\n", "[ok]")
succes = append(succes, f)
}
return succes
}

func isEmptyFile(file string) bool {
Expand All @@ -136,16 +149,15 @@ func isEmptyFile(file string) bool {
return fi.Size() == 0
}

func clear(elementType string, ids []string) int {
error := 0
for _, id := range ids {
file := fmt.Sprintf("%v%v.osm", elementType, id)
if _, err := os.Stat(file); err == nil {
if e := os.Remove(file); e != nil {
fmt.Printf("failed to delete %v, err: %v\n", file, e)
error++
}
func clear(files []string) {
for _, file := range files {
if _, err := os.Stat(file); err != nil {
fmt.Printf("failed to remove %v, err: %v\n", files, err)
continue
}
if err := os.Remove(file); err != nil {
fmt.Printf("failed to remove %v, err: %v\n", file, err)
continue
}
}
return error
}

0 comments on commit 65720ac

Please sign in to comment.