用于处理OSM数据的Java命令行应用程序,包括许多插件式的组件。比如读写数据库和文件的组件、继承和修改数据源的组件、对数据排序管理的组件等,避免了实现常用功能而重复性编写代码。
目前主要功能有:
https://wiki.openstreetmap.org/wiki/Osmosis/Examples
https://wiki.openstreetmap.org/wiki/Zh-hans:Osmosis
sudo apt-get update
sudo apt-get install osmosis
从 PBF 提取中提取火车站数据导出xml格式数据
osmosis --read-pbf china.osm.pbf --node-key-value keyValueList="railway.station" --write-xml station.osm.xml
package main
import (
"encoding/json"
"fmt"
xj "github.com/basgys/goxml2json"
"io/ioutil"
"log"
"os"
"strconv"
"strings"
"test_project/global"
"test_project/initialize"
)
type Station struct {
Id int `json:"id" gorm:"primary_key;auto_increment"`
Name string `json:"name"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
}
func (s *Station) TableName() string {
return "station"
}
func (s *Station) Insert(stations []Station) (err error) {
table := global.GVA_DB
err = table.Create(&stations).Error
return
}
// RegisterTables 注册数据库表专用
// Author SliverHorn
func RegisterTables() {
err := global.GVA_DB.AutoMigrate(
&Station{},
)
if err != nil {
fmt.Println("register table failed", err)
os.Exit(0)
}
fmt.Println("register table success", err)
}
func main() {
global.GVA_DB = initialize.GormSqlite()
RegisterTables()
bytes, err := ioutil.ReadFile("station.osm.xml")
if err != nil {
fmt.Println(err)
}
xml := strings.NewReader(string(bytes))
xmlData, err := xj.Convert(xml)
if err != nil {
panic("That's embarrassing...")
}
//xml转JSON
var scenarioInfo map[string]interface{}
err = json.Unmarshal(xmlData.Bytes(), &scenarioInfo)
if err != nil {
log.Println(err)
}
//获取所有的node
nodes := scenarioInfo["osm"].(map[string]interface{})["node"].([]interface{})
//所有车站信息
stations := make([]Station, 0)
for _, node := range nodes {
nodeInfo := node.(map[string]interface{})
lat := nodeInfo["-lat"].(string)
latitude, err := strconv.ParseFloat(lat, 64)
if err != nil {
log.Println(err)
}
lon := nodeInfo["-lon"].(string)
longitude, err := strconv.ParseFloat(lon, 64)
if err != nil {
log.Println(err)
}
tags := nodeInfo["tag"]
flag := true
stationName := ""
switch tags.(type) {
case map[string]interface{}:
tagInfo := tags.(map[string]interface{})
if key, ok := tagInfo["-k"]; ok {
if key == "name" {
fmt.Printf("车站名称:%v 纬度:%v 经度:%v \n", tagInfo["-v"], latitude, longitude)
}
}
case []interface{}:
for _, tag := range tags.([]interface{}) {
tagInfo := tag.(map[string]interface{})
if key, ok := tagInfo["-k"]; ok {
if key == "name" {
stationName = tagInfo["-v"].(string)
fmt.Printf("车站名称:%v 纬度:%v 经度:%v \n", tagInfo["-v"], latitude, longitude)
}
if key == "subway" {
flag = true
}
}
}
default:
fmt.Println("未找到类型")
}
//创建车站数据
if flag {
if len(stations) > 5000 {
station := Station{}
err := station.Insert(stations)
if err != nil {
log.Panic(err)
}
stations = make([]Station, 0)
}
station := Station{Latitude: latitude, Longitude: longitude, Name: stationName}
stations = append(stations, station)
}
}
fmt.Println(len(stations))
}