天天看点

osm 路网路网数据-解析-node-road 并入库 pg+postgis

import osm2gmns as og
import pandas as pd
import geopandas as gpd
import psycopg2

from sqlalchemy import create_engine
from shapely.geometry import Point, LineString
import matplotlib.pyplot as plt

import numpy as np
import nvector as nv

import datetime as dt

def nan2NULL(in_str):
    if in_str == 'nan':
        return "NULL"
    else:
        return in_str

# 第一步 读取 osm 路网文件
# 读取 osm 文件
# getNetFromOSMFile: network_type参数可选'auto', 'bike', 'walk','railway', 'aeroway'及任意组合
net = og.getNetFromOSMFile(osm_filename='beijing_4ring_map.osm', network_type=('auto',), POIs=False, combine=True)
# 第二步  解析 osm 路网文件 --> csv
# 保存输出
# GMNS格式 输出node.csv,link.csv和segment.csv组成,如选择POI也会有poi.csv文件输出
og.outputNetToCSV(net, output_folder='output')

# 第三步  简化交叉路口的节点 将同一个交叉路口的点合并成一个点
# 简化交叉路口
# 由于真实路网中存在复杂交叉口情况,同一个交叉口存在多个网络节点,
# consolidateComplexIntersections提供了简化交叉口功能,将属于同一交叉口的节点统一为一个节点
# check the main_node_id column in node.csv
# net = og.getNetFromCSV(folder='output')# 读取CSV 文件
og.consolidateComplexIntersections(net)# 简化交叉路口,将同一个交叉路口的点合并成一个点
# GMNS格式 输出 简化后路网的node.csv和link.csv文件
og.outputNetToCSV(net, output_folder='consolidated')

# 第四步  将短的Links 合并处理
# 合并非常短的Links
og.combineShortLinks(net)
# GMNS格式 输出 简化后路网的node.csv和link.csv文件
og.outputNetToCSV(net, output_folder='combined')

# 第五步  将处理好的路段文件入库
# node_gdf = gpd.read_file(r'.\combined\node.csv', encoding='utf-8')
# engine = create_engine('postgresql://postgres:jiangshan@localhost:5432/roadnetwork')
# node_gdf.to_postgis(name="beisihuan", con=engine, if_exists='replace')

node_pdf = pd.read_csv(r'.\combined\node.csv', encoding='utf-8')
road_pdf = pd.read_csv(r'.\combined\link.csv', encoding='gb2312')

# postgis
pgisCon = psycopg2.connect(database="roadnetwork", user="postgres", password="jiangshan", host="localhost", port="5432")
pgisCursor = pgisCon.cursor()

# create table
pgisCursor.execute("CREATE TABLE IF NOT EXISTS node_table (node_id BIGINT not null primary key,\
                    osm_node_id TEXT,name TEXT,osm_highway TEXT,ctrl_type BOOLEAN,\
                    x_coord DOUBLE PRECISION, y_coord DOUBLE PRECISION,\
                    notes TEXT, tstamp TIMESTAMP, geom GEOMETRY)")

pgisCursor.execute("CREATE TABLE IF NOT EXISTS road_table (road_id BIGINT not null primary key,\
                    osm_way_id TEXT,name TEXT,from_node_id BIGINT,to_node_id BIGINT,length DOUBLE PRECISION,\
                    road_type_name TEXT,road_type INTEGER, biway BOOLEAN, \
                    start_point GEOMETRY, end_point GEOMETRY, uses TEXT, tstamp TIMESTAMP, geom GEOMETRY, osm_geom GEOMETRY)")

pgisCursor.execute("CREATE TABLE IF NOT EXISTS trajectory_table (trj_id BIGINT,\
                    speed FLOAT,x_coord DOUBLE PRECISION, y_coord DOUBLE PRECISION, tstamp TIMESTAMP, geom GEOMETRY)")
pgisCon.commit()
now_time_str = dt.datetime.now().strftime('%F %T')

# # insert data to trajectory_table
# pgisCursor.execute("INSERT INTO trajectory_table (trj_id, speed, x_coord, y_coord, tstamp) VALUES (0, 35.5, 120.3425456, 38.3568425, '{}')".format(now_time_str))
# # update the geometry as a point
# pgisCursor.execute("UPDATE trajectory_table SET geom = st_point(x_coord, y_coord) WHERE trj_id = 0")
# pgisCon.commit()

# node
for i in range(len(node_pdf)):
    node = node_pdf.values[i]
    if str(node[2]) != 'nan':
        osm_node_id = str(int(node[2]))
    else:
        osm_node_id = "NULL"
    node_id, osm_node_id, name, osm_highway, ctrl_type = nan2NULL(str(node[1])), nan2NULL(osm_node_id), nan2NULL(str(node[3])), nan2NULL(str(node[0])), nan2NULL(str(node[5]))
    x_coord, y_coord, notes, tstamp = nan2NULL(format(node[9], '.7f')), nan2NULL(format(node[10], '.7f')), nan2NULL(str(node[13])), nan2NULL(str(now_time_str))
    value_str = "({0}, '{1}', '{2}', '{3}', '{4}', {5}, {6}, '{7}', '{8}')".format(node_id, osm_node_id, name, osm_highway, ctrl_type, x_coord, y_coord, notes, tstamp)
    pgisCursor.execute("INSERT INTO node_table (node_id, osm_node_id, name, osm_highway, ctrl_type, x_coord, y_coord, notes, tstamp) VALUES " + value_str)
    # update the geometry as a point
    pgisCursor.execute("UPDATE node_table SET geom = st_point(x_coord, y_coord) WHERE node_id = " + node_id)
    pgisCon.commit()

# road
for i in range(len(road_pdf)):
    road = road_pdf.values[i]
    road_id, osm_way_id, name = nan2NULL(str(road[1])), nan2NULL(str(road[2])), nan2NULL(str(road[0]))
    from_node_id, to_node_id, length, road_type_name = nan2NULL(str(road[3])), nan2NULL(str(road[4])), nan2NULL(format(road[6], '.3f')), nan2NULL(str(road[10]))
    road_type, biway, uses = nan2NULL(str(road[11])), nan2NULL(str(road[14])), nan2NULL(str(road[13]))
    tstamp = now_time_str
    osm_geom_str = nan2NULL(str(road[12]))
    value_str = "({0}, '{1}', '{2}', {3}, {4}, {5}, '{6}', {7}, '{8}', '{9}', '{10}')".format(road_id, osm_way_id, name, from_node_id, to_node_id, length,
                                                                                  road_type_name,road_type, biway, uses, tstamp)
    # insert data to table
    pgisCursor.execute("INSERT INTO road_table (road_id, osm_way_id, name, from_node_id, to_node_id, length,\
                         road_type_name,road_type, biway, uses, tstamp) VALUES " + value_str)
    # update the geometry as a point
    pgisCursor.execute("UPDATE road_table SET start_point = st_point(nt.x_coord, nt.y_coord) FROM node_table AS nt WHERE nt.node_id = " + from_node_id)
    pgisCursor.execute("UPDATE road_table SET end_point = st_point(nt.x_coord, nt.y_coord) FROM node_table AS nt WHERE nt.node_id = " + to_node_id)
    pgisCursor.execute("UPDATE road_table SET geom = st_makeline(start_point, end_point) WHERE road_id = " + road_id)
    pgisCursor.execute("UPDATE road_table SET osm_geom = st_geometryfromtext('{}')".format(osm_geom_str)+" WHERE road_id = " + road_id)

    pgisCon.commit()

pgisCursor.close()
pgisCon.close()
      

  

个人学习记录