imposm3/cache/query/query.go

208 lines
4.4 KiB
Go
Raw Normal View History

2013-08-01 17:31:47 +04:00
package query
2013-05-17 12:29:23 +04:00
import (
2013-08-02 12:08:01 +04:00
"encoding/json"
2013-05-17 12:29:23 +04:00
"flag"
2013-08-01 17:31:47 +04:00
"fmt"
2013-05-17 12:29:23 +04:00
"log"
2013-08-01 15:35:00 +04:00
"os"
2013-08-02 12:08:01 +04:00
"strconv"
"strings"
2013-08-01 17:31:47 +04:00
2014-08-04 17:19:35 +04:00
"github.com/omniscale/imposm3/cache"
"github.com/omniscale/imposm3/element"
2013-05-17 12:29:23 +04:00
)
2013-08-01 17:31:47 +04:00
var flags = flag.NewFlagSet("query-cache", flag.ExitOnError)
2013-05-17 12:29:23 +04:00
var (
nodeIds = flags.String("node", "", "node")
wayIds = flags.String("way", "", "way")
relIds = flags.String("rel", "", "relation")
2013-08-01 17:31:47 +04:00
full = flags.Bool("full", false, "recurse into relations/ways")
deps = flags.Bool("deps", false, "show dependent ways/relations")
2018-04-17 22:06:55 +03:00
cachedir = flags.String("cachedir", "/tmp/imposm", "cache directory")
2013-05-17 12:29:23 +04:00
)
2013-08-02 12:08:01 +04:00
type nodes map[string]*node
type ways map[string]*way
type relations map[string]*relation
type node struct {
element.Node
Ways ways `json:"ways,omitempty"`
}
type way struct {
element.Way
Nodes nodes `json:"nodes,omitempty"`
Relations relations `json:"relations,omitempty"`
}
type relation struct {
element.Relation
Ways ways `json:"ways,omitempty"`
}
type result struct {
Nodes nodes `json:"nodes,omitempty"`
Ways ways `json:"ways,omitempty"`
Relations relations `json:"relations,omitempty"`
}
func collectRelations(osmCache *cache.OSMCache, ids []int64, recurse bool) relations {
rels := make(relations)
2013-05-17 12:29:23 +04:00
for _, id := range ids {
2013-08-02 12:08:01 +04:00
sid := strconv.FormatInt(id, 10)
2013-05-17 12:29:23 +04:00
rel, err := osmCache.Relations.GetRelation(id)
if err == cache.NotFound {
2013-08-02 12:08:01 +04:00
rels[sid] = nil
2013-05-17 12:29:23 +04:00
} else if err != nil {
log.Fatal(err)
} else {
2013-08-02 12:08:01 +04:00
rels[sid] = &relation{*rel, nil}
2013-05-17 12:29:23 +04:00
if recurse {
2013-08-02 12:08:01 +04:00
memberWayIds := []int64{}
2013-05-17 12:29:23 +04:00
for _, m := range rel.Members {
2013-08-02 12:08:01 +04:00
if m.Type == element.WAY {
memberWayIds = append(memberWayIds, m.Id)
}
2013-05-17 12:29:23 +04:00
}
2013-08-02 12:08:01 +04:00
rels[sid].Ways = collectWays(osmCache, nil, memberWayIds, true, false)
2013-05-17 12:29:23 +04:00
}
}
}
2013-08-02 12:08:01 +04:00
return rels
2013-05-17 12:29:23 +04:00
}
2013-08-02 12:08:01 +04:00
func collectWays(osmCache *cache.OSMCache, diffCache *cache.DiffCache, ids []int64, recurse, deps bool) ways {
ws := make(ways)
2013-05-17 12:29:23 +04:00
for _, id := range ids {
2013-08-02 12:08:01 +04:00
sid := strconv.FormatInt(id, 10)
w, err := osmCache.Ways.GetWay(id)
2013-05-17 12:29:23 +04:00
if err == cache.NotFound {
2013-08-02 12:08:01 +04:00
ws[sid] = nil
2013-05-17 12:29:23 +04:00
} else if err != nil {
log.Fatal(err)
} else {
2013-08-02 12:08:01 +04:00
ws[sid] = &way{*w, nil, nil}
2013-05-17 12:29:23 +04:00
if recurse {
2013-08-02 12:08:01 +04:00
ws[sid].Nodes = collectNodes(osmCache, nil, w.Refs, false)
}
2013-08-02 12:08:01 +04:00
if deps {
rels := diffCache.Ways.Get(id)
if len(rels) != 0 {
ws[sid].Relations = collectRelations(osmCache, rels, false)
}
2013-05-17 12:29:23 +04:00
}
}
}
2013-08-02 12:08:01 +04:00
return ws
2013-05-17 12:29:23 +04:00
}
2013-08-02 12:08:01 +04:00
func collectNodes(osmCache *cache.OSMCache, diffCache *cache.DiffCache, ids []int64, deps bool) nodes {
ns := make(nodes)
2013-05-17 12:29:23 +04:00
for _, id := range ids {
2013-08-02 12:08:01 +04:00
sid := strconv.FormatInt(id, 10)
n, err := osmCache.Nodes.GetNode(id)
2013-05-17 12:29:23 +04:00
if err != cache.NotFound && err != nil {
log.Fatal(err)
}
2013-08-02 12:08:01 +04:00
if n == nil {
n, err = osmCache.Coords.GetCoord(id)
2013-05-17 12:29:23 +04:00
if err == cache.NotFound {
2013-08-02 12:08:01 +04:00
ns[sid] = nil
2013-05-17 12:29:23 +04:00
} else if err != nil {
log.Fatal(err)
}
}
2013-08-02 12:08:01 +04:00
if n != nil {
ns[sid] = &node{*n, nil}
if deps {
ways := diffCache.Coords.Get(id)
if len(ways) != 0 {
ns[sid].Ways = collectWays(osmCache, diffCache, ways, false, true)
}
}
2013-05-17 12:29:23 +04:00
}
}
2013-08-02 12:08:01 +04:00
return ns
2013-05-17 12:29:23 +04:00
}
2013-08-01 17:31:47 +04:00
func Usage() {
fmt.Fprintf(os.Stderr, "Usage of %s %s:\n\n", os.Args[0], os.Args[1])
flags.PrintDefaults()
fmt.Fprintln(os.Stderr, "\nQuery cache for nodes/ways/relations.")
os.Exit(1)
}
2013-08-02 12:08:01 +04:00
func printJson(obj interface{}) {
bytes, err := json.MarshalIndent(obj, "", " ")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(bytes))
}
func splitIds(ids string) []int64 {
result := []int64{}
for _, s := range strings.Split(ids, ",") {
id, err := strconv.ParseInt(s, 10, 64)
if err != nil {
log.Fatal(err)
}
result = append(result, id)
}
return result
}
2013-08-01 17:31:47 +04:00
func Query(args []string) {
flags.Usage = Usage
if len(args) == 0 {
Usage()
}
err := flags.Parse(args)
if err != nil {
log.Fatal(err)
}
2013-05-17 12:29:23 +04:00
log.SetFlags(0)
2013-08-01 15:35:00 +04:00
log.SetOutput(os.Stdout)
2013-05-17 12:29:23 +04:00
osmCache := cache.NewOSMCache(*cachedir)
2013-08-01 17:31:47 +04:00
err = osmCache.Open()
2013-05-17 12:29:23 +04:00
if err != nil {
log.Fatal(err)
}
diffCache := cache.NewDiffCache(*cachedir)
err = diffCache.Open()
if err != nil {
log.Fatal(err)
}
if *full && *deps {
log.Fatal("cannot use -full and -deps option together")
}
2013-05-17 12:29:23 +04:00
2013-08-02 12:08:01 +04:00
result := result{}
if *relIds != "" {
ids := splitIds(*relIds)
result.Relations = collectRelations(osmCache, ids, *full)
2013-05-17 12:29:23 +04:00
}
if *wayIds != "" {
ids := splitIds(*wayIds)
result.Ways = collectWays(osmCache, diffCache, ids, *full, *deps)
2013-05-17 12:29:23 +04:00
}
if *nodeIds != "" {
ids := splitIds(*nodeIds)
result.Nodes = collectNodes(osmCache, diffCache, ids, *deps)
2013-05-17 12:29:23 +04:00
}
2013-08-02 12:08:01 +04:00
printJson(result)
2013-05-17 12:29:23 +04:00
}