import codecs
import json
import osm2geojson
import geopandas
import xml.etree.ElementTreeas xee
from lxmlimport etree
import time
import requests
import geopandasas gpd
from shapely.geometryimport Point, LineString
import os
import pandasas pd
from tqdmimport tqdm
def osm_geojson(file_path,geofile):
? ? with codecs.open(file_path,'r',encoding='utf-8')as data:
? ? ? ? xml= data.read()
geojson= osm2geojson.xml2geojson(xml,filter_used_refs=False)
with open(geofile,'w')as fpath:
? ? ? ? json.dump(geojson,fpath)
data2 = geopandas.read_file(geojson)
print("123131")
def osmProcess(file_path):
? ? # 讀取文件
? ? domTree= xee.parse(file_path)
# 獲得所有節(jié)點的內(nèi)容
? ? root= domTree.getroot()
# 獲得所選區(qū)域的經(jīng)緯度范圍
? ? # bound = root.findall("bounds")
# maxLat = float(bound[0].get("maxlat"))
# maxLon = float(bound[0].get("maxlon"))
# minLat = float(bound[0].get("minlat"))
# minLon = float(bound[0].get("minlon"))
? ? # # 輸出所選區(qū)域的經(jīng)緯度范圍
? ? # print('Bounds:' + '\n' + 'minLat: ' + str(minLat) + '\n' + 'maxLat: ' + str(maxLat) + '\n' +
#? ? ? 'minLon: ' + str(minLon) + '\n' + 'maxLon: ' + str(maxLon) + '\n' + 'Nodes: ')
#
? ? # # 存儲不在所選區(qū)域內(nèi)的node ID
# IDlist = []
? ? # 逐個檢查node
? ? IDlist={}
nodes= root.findall("node")
for nodein nodes:
? ? ? ? # 當前節(jié)點的經(jīng)緯度和ID
? ? ? ? Lat= float(node.get("lat"))
Lon= float(node.get("lon"))
ID= node.get("id")
IDlist.update({str(ID):{"ID":ID,"Lat":Lat,"Lon":Lon,"geo":Point(Lat,Lon)}})
# 輸出node信息
? ? ? ? # print('nodeID:' + ID + ', Lat:' + str(Lat) + ', Lon:' + str(Lon) + ', Bound: ', end='')
? ? ? ? # 判斷
? ? ? ? # if Lat < minLat or Lat > maxLat or Lon < minLon or Lon > maxLon:
#? ? root.remove(node)
#? ? IDlist.append(ID)
? ? ? ? #? ? # 輸出bound比對情況,若Lat和Lon均不符合則只輸出Lat
#? ? if Lat < minLat:
#? ? ? ? print('Lat < min')
#? ? elif Lat > maxLat:
#? ? ? ? print('Lat > max')
#? ? elif Lon < minLon:
#? ? ? ? print('Lon < min')
#? ? elif Lon > maxLon:
#? ? ? ? print('Lon > max')
# else:
#? ? print('Satisfied')
? ? ? ? root.remove(node)
# IDlist.append(ID)
? ? ? ? # 輸出bound比對情況,若Lat和Lon均不符合則只輸出Lat
# if Lat < minLat:
#? ? print('Lat < min')
# elif Lat > maxLat:
#? ? print('Lat > max')
# elif Lon < minLon:
#? ? print('Lon < min')
# elif Lon > maxLon:
#? ? print('Lon > max')
? ? # 刪除不在所選區(qū)域內(nèi)的node在后續(xù)道路的參照行
? ? ways = root.findall("way")
# for ID in IDlist:
#? ? for way in ways:
#? ? ? ? refnodes = way.findall("nd")
#? ? ? ? for node in refnodes:
#? ? ? ? ? ? if node.get("ref") == ID:
#? ? ? ? ? ? ? ? way.remove(node)
? ? # 輸出文件
? ? domTree.write("out.osm",encoding="utf8")
def readosm(osm_path):
? ? raw_osm_json=""
? ? with open(osm_path,'r',encoding='utf-8')as a:
? ? ? ? raw_osm_json= a.read()
# raw_osm_json = eval(raw)
# raw_osm_json = eval(raw)
# print(raw_osm_json)
? ? # 抽取點圖層并保存
? ? points_contents= []
for elementin tqdm(raw_osm_json['elements'],desc='[{}]抽取點數(shù)據(jù)'.format("上海市")):
? ? ? ? if element['type']== 'node':
? ? ? ? ? ? points_contents.append((str(element['id']), element['lon'], element['lat']))
points= pd.DataFrame(points_contents,
columns=['id','lng','lat'])
points['geometry']= points.apply(lambda row: Point([row['lng'], row['lat']]),axis=1)
points= gpd.GeoDataFrame(points,crs='EPSG:4326')
# 構(gòu)造{id -> 點數(shù)據(jù)}字典
? ? id2points= {key: valuefor key, valuein zip(points['id'],
points['geometry'])}
# 保存線圖層
? ? ways_contents= []
for elementin tqdm(raw_osm_json['elements'],desc='[{}]抽取線數(shù)據(jù)'.format("上海市")):
? ? ? ? if element['type']== 'way':
? ? ? ? ? ? if element['nodes'].__len__()>= 2:
? ? ? ? ? ? ? ? ways_contents.append((str(element['id']),LineString([id2points[str(_)]
for _in element['nodes']])))
ways = gpd.GeoDataFrame(pd.DataFrame(ways_contents,columns=['id','geometry']),
crs='EPSG:4326')
print("4333333333")
def fast_iter(context,*args,**kwargs):
? ? """
? ? 讀取xml數(shù)據(jù),并釋放空間? ? context: etree.iterparse生成的迭代器"""
? ? # 打開文件
? ? with open('data/result.txt','a')as f:
? ? ? ? """
? ? ? ? event:事件? ? ? ? elem:元素"""
? ? # 處理xml數(shù)據(jù)
? ? for event, elemin context:
? ? ? ? list= []
for ein elem:
? ? ? ? # 獲取標簽屬性值,獲取標簽值
? ? ? ? ? ? s1= e.get("name")+ ":" + e.text
# print(e.get("name") + ":" + e.text)
? ? ? ? ? ? list= list+ [s1]
# 替換list的【】,變?yōu)橐粋€ ,分隔的字符串
? ? ? ? res= str(list).replace("[","").replace("]","").replace("'","")
f.write(res)# 寫入
? ? ? ? f.write('\n')
# 重置元素,清空元素內(nèi)部數(shù)據(jù)
? ? ? ? elem.clear()
# 選取當前節(jié)點的所有先輩(父、祖父等)節(jié)點,以及當前節(jié)點本身
? ? for ftagin elem.xpath('doc'):
? ? # 如果當前節(jié)點還有前一個兄弟,則刪除父節(jié)點的第一個子節(jié)點。getprevious():返回當前節(jié)點的前一個兄弟或None。
? ? ? ? while ftag.getprevious()is not None:
? ? ? ? # 刪除父節(jié)點的第一個子節(jié)點,getparent():返回當前節(jié)點的父元素或根元素或None。
? ? ? ? ? ? del ftag.getparent()[0]
# 釋放內(nèi)存
? ? ? ? ? ? del context
def process_element(elem):
? ? """
? ? 處理element
:params elem: Element
"""
? ? # 儲存基因列表
? ? gene_list= []
for iin elem.xpath('add'):
? ? ? ? # 獲取基因名字
? ? ? ? gene= i.text
# 添加到列表
? ? ? ? gene_list.append(gene)
print('gene', gene_list)
if __name__== '__main__':
? ? osm_path= r"F:/data/sh.osm"
? ? # geo_path = r'F:/data/sh.geojson'
# osm_geojson(osm_path,geo_path)
# osmProcess(osm_path)
? ? print('start', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
start= time.time()
# 需要處理的文件路徑
? ? infile= osm_path
# 通過迭代讀取xml,帶命名空間的要加上命名空間
? ? # context = etree.iterparse(infile, events=('end',), encoding='UTF-8', tag='{http://uniprot.org/uniprot}doc')
? ? context= etree.iterparse(infile,events=('end',),encoding='UTF-8',tag='doc')
# 快速讀取xml數(shù)據(jù)
? ? fast_iter(context,process_element)
print('stop', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
print('time', time.time()- start)
#http://www.itdecent.cn/p/a2c65dc8c87b