Skip to content

Instantly share code, notes, and snippets.

@tohka
Last active May 13, 2020 04:49
Show Gist options
  • Save tohka/f9432b97360c362f67a6f70abe987daa to your computer and use it in GitHub Desktop.
Save tohka/f9432b97360c362f67a6f70abe987daa to your computer and use it in GitHub Desktop.
基盤地図情報の PackDLMap.zip を全ファイル展開し、種別ごとにマージするやつ
{
"common_fields" : [
["gml_id", "String"],
["fid", "String"],
["lfSpanFr", "Date"],
["lfSpanTo", "Date"],
["devDate", "Date"],
["orgGILvl", "String"],
["orgMDId", "String"],
["vis", "String"]
],
"AdmArea" : {
"geom_type" : "Polygon",
"fields" : [
["type", "String"],
["name", "String"],
["admCode", "String"]
]
},
"AdmBdry" : {
"geom_type" : "LineString",
"fields" : [
["type", "String"]
]
},
"AdmPt" : {
"geom_type" : "Point",
"fields" : [
["type", "String"],
["name", "String"],
["admCode", "String"]
]
},
"BldA" : {
"geom_type" : "Polygon",
"fields" : [
["type", "String"],
["name", "String"]
]
},
"BldL" : {
"geom_type" : "LineString",
"fields" : [
["type", "String"],
["name", "String"]
]
},
"Cntr" : {
"geom_type" : "LineString",
"fields" : [
["type", "String"],
["alti", "Real"]
]
},
"CommBdry" : {
"geom_type" : "LineString",
"fields" : [
["type", "String"]
]
},
"CommPt" : {
"geom_type" : "Point",
"fields" : [
["type", "String"],
["name", "String"],
["admCode", "String"]
]
},
"Cstline" : {
"geom_type" : "LineString",
"fields" : [
["type", "String"],
["name", "String"]
]
},
"ElevPt" : {
"geom_type" : "Point",
"fields" : [
["type", "String"],
["alti", "Real"]
]
},
"GCP" : {
"geom_type" : "Point",
"fields" : [
["advNo", "String"],
["orgName", "String"],
["type", "String"],
["gcpClass", "String"],
["gcpCode", "String"],
["name", "String"],
["B", "Real"],
["L", "Real"],
["alti", "Real"],
["altiAcc", "Integer"]
]
},
"RailCL" : {
"geom_type" : "LineString",
"fields" : [
["type", "String"],
["name", "String"]
]
},
"RdCompt" : {
"geom_type" : "LineString",
"fields" : [
["type", "String"],
["name", "String"],
["admOffice", "String"]
]
},
"RdEdg" : {
"geom_type" : "LineString",
"fields" : [
["type", "String"],
["name", "String"],
["admOffice", "String"]
]
},
"WA" : {
"geom_type" : "Polygon",
"fields" : [
["type", "String"],
["name", "String"]
]
},
"WL" : {
"geom_type" : "LineString",
"fields" : [
["type", "String"],
["name", "String"]
]
},
"WStrA" : {
"geom_type" : "Polygon",
"fields" : [
["type", "String"],
["name", "String"]
]
},
"WStrL" : {
"geom_type" : "LineString",
"fields" : [
["type", "String"],
["name", "String"]
]
}
}
import glob
import json
import zipfile
import ogr
import osr
GEOM_TYPE = {
'Point' : ogr.wkbPoint,
'LineString' : ogr.wkbLineString,
'Polygon' : ogr.wkbPolygon
}
FIELD_TYPE = {
'Integer' : ogr.OFTInteger,
'Integer64' : ogr.OFTInteger64,
'Real' : ogr.OFTReal,
'String' : ogr.OFTString,
'Date' : ogr.OFTDate,
'Time' : ogr.OFTTime,
'DateTime' : ogr.OFTDateTime
}
def main():
with open('layer_spec.json', 'r') as f:
layer_spec = json.load(f)
out_filename = 'merged.gpkg'
out_driver = ogr.GetDriverByName('GPKG')
out_srs = osr.SpatialReference()
out_srs.ImportFromEPSG(6668)
driver = ogr.GetDriverByName('GML')
extract_zips()
# XML ファイルのリストを作り、 layername ごとに整理する
filelist = {}
for filename in glob.glob('FG-GML-*.xml'):
meshcode, layername, pubdate, num = filename[7:-4].split('-')
if layername not in filelist:
filelist[layername] = []
filelist[layername].append((layername, meshcode, filename))
# 出力用のファイルを作成する
out_ds = out_driver.CreateDataSource(out_filename)
# layername ごとにデータのマージ処理を行う
for layername in sorted(list(filelist.keys())):
if layername not in layer_spec:
print("Warning: undefined layer spec: %s" % layername)
continue
# 新しいレイヤを作成する
out_layer = out_ds.CreateLayer(layername, out_srs,
GEOM_TYPE[layer_spec[layername]['geom_type']],
options=["FID=ID"])
# 新しいレイヤの属性の設定
for i in range(len(layer_spec['common_fields'])):
f_name, f_type = layer_spec['common_fields'][i]
defn = ogr.FieldDefn(f_name, FIELD_TYPE[f_type])
out_layer.CreateField(defn)
for i in range(len(layer_spec[layername]['fields'])):
f_name, f_type = layer_spec[layername]['fields'][i]
defn = ogr.FieldDefn(f_name, FIELD_TYPE[f_type])
out_layer.CreateField(defn)
out_layer.CreateField(ogr.FieldDefn('filename', ogr.OFTString))
out_layer.CreateField(ogr.FieldDefn('meshcode', ogr.OFTString))
out_layer_defn = out_layer.GetLayerDefn()
# XML ファイルごとにデータをマージする
for f in sorted(filelist[layername], key=lambda v: v[1]):
_, meshcode, filename = f
print("data appending... %s" % filename)
ds = driver.Open(filename, 0)
layer = ds.GetLayer()
for feature in layer:
out_feature = ogr.Feature(out_layer_defn)
out_feature.SetGeometry(feature.GetGeometryRef().Clone())
for i in range(out_layer_defn.GetFieldCount()):
defn = out_layer_defn.GetFieldDefn(i)
field_name = defn.GetName()
if field_name == 'filename':
field_value = filename
elif field_name == 'meshcode':
field_value = meshcode
else:
field_value = feature.GetField(field_name)
out_feature.SetField(defn.GetNameRef(), field_value)
out_layer.CreateFeature(out_feature)
out_feature = None
out_layer.SyncToDisk()
def extract_zips():
for f in glob.glob('PackDLMap*.zip'):
with zipfile.ZipFile(f) as z:
for info in z.infolist():
if info.filename[-4:] == '.zip':
z.extract(info)
for f in glob.glob('FG-GML-*.zip'):
with zipfile.ZipFile(f) as z:
for info in z.infolist():
z.extract(info)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment