ファイル名を整理
いろいろなサイズのNumPy配列のファイルを作っているので、わけがわからなくてなってきたので、ちゃんと規則を決めておく。
種類 | サイズ | NumPy |
---|---|---|
2次メッシュ | 1500x2250 | npydata-{0:04d}-{1:02d}.npy |
2次メッシュ (DEM構成点種別) | 1500x2250 | npysurf-{0:04d}-{1:02d}.npy |
2次メッシュ (5x5) | 7500x11250 | npy_5x5-{0:04d}-{1:02d}.npy |
3次メッシュ | 150x225 | npydata-{0:04d}-{1:02d}-{2:02d}.npy |
3次メッシュ (DEM構成点種別) | 150x225 | npysurf-{0:04d}-{1:02d}-{2:02d}.npy |
3次メッシュ (5x5) | 750x1125 | npy_5x5-{0:04d}-{1:02d}-{2:02d}.npy |
4次メッシュ | 30x45 | npydata-{0:04d}-{1:02d}-{2:02d}-{3:02d}.npy |
4次メッシュ (DEM構成点種別) | 30x45 | npysurf-{0:04d}-{1:02d}-{2:02d}-{3:02d}.npy |
4次メッシュ (5x5) | 150x225 | npy_5x5-{0:04d}-{1:02d}-{2:02d}-{3:02d}.npy |
ここまで決めたら、プログラムもまとめたい。
機能 | プログラム名 |
---|---|
メッシュデータをNumPyデータへ | xml2npy.py |
NumPyデータをプロットする | plotnpy.py |
NumPyデータを5x5倍する | npy5x5.py |
NumPyデータを5x5分割する | npydiv5.py |
NumPyデータをマイクラ内でロードする | loadnpy.py |
メッシュデータをNumPyデータへ (xml2npy.py)
# coding: utf-8 import xml.etree.ElementTree as ET import numpy as np import sys import os GEO_DIR = "FG-GML-{0:04d}-{1:02d}-DEM5A" GEO_XML_20161001 = "FG-GML-{0:04d}-{1:02d}-{2:02d}-DEM5A-20161001.xml" GEO_XML_20170202 = "FG-GML-{0:04d}-{1:02d}-{2:02d}-DEM5A-20170202.xml" NPY_DIR = "/Users/pycra/Desktop/NPY_DATA" NPY_2ND_FILE = "npydata-{0:04d}-{1:02d}.npy" NPY_3RD_FILE = "npydata-{0:04d}-{1:02d}-{2:02d}.npy" WATER_LEVEL = -1.0 SEA_LEVEL = -5.0 def xml2array(mesh1, mesh2, mesh3): dir = GEO_DIR.format(mesh1, mesh2) fname = GEO_XML_20161001.format(mesh1, mesh2, mesh3) if os.path.isfile(dir+"/"+fname) == False: fname = GEO_XML_20170202.format(mesh1, mesh2, mesh3) if os.path.isfile(dir+"/"+fname) == False: raise FileNotFoundError(dir+"/"+fname) tree = ET.parse(dir+"/"+fname) root = tree.getroot() tl = root.find('./{http://fgd.gsi.go.jp/spec/2008/FGD_GMLSchema}DEM/{http://fgd.gsi.go.jp/spec/2008/FGD_GMLSchema}coverage/{http://www.opengis.net/gml/3.2}rangeSet/{http://www.opengis.net/gml/3.2}DataBlock/{http://www.opengis.net/gml/3.2}tupleList') if tl is None: raise Exception("{http://www.opengis.net/gml/3.2}tupleList is not found") sp = root.find('./{http://fgd.gsi.go.jp/spec/2008/FGD_GMLSchema}DEM/{http://fgd.gsi.go.jp/spec/2008/FGD_GMLSchema}coverage/{http://www.opengis.net/gml/3.2}coverageFunction/{http://www.opengis.net/gml/3.2}GridFunction/{http://www.opengis.net/gml/3.2}startPoint') if sp is None: raise Exception("{http://www.opengis.net/gml/3.2}startPoint is not found") (spx, spy) = sp.text.split() lines = tl.text.split() array = np.zeros(33750) array.fill(WATER_LEVEL) i = int(spx) + int(spy) * 225 for l in lines: (t, h) = l.split(",") hval = float(h) if hval == -9999: array[i] = WATER_LEVEL else: array[i] = hval i += 1 return array.reshape((150, 225)) # ここからスタート if len(sys.argv) < 3: print("xml2npy.py mesh1 mesh2 [mesh3]") exit(-1) print("sys.argv=", sys.argv) mesh1 = int(sys.argv[1]) mesh2 = int(sys.argv[2]) mesh3 = -1 if len(sys.argv) > 3: mesh3 = int(sys.argv[3]) print("mesh1=", mesh1) print("mesh2=", mesh2) print("mesh3=", mesh3) if mesh3 == -1: yarray = None for y in range(10): xarray = None for x in range(10): try: m3 = y * 10 + x tarray = xml2array(mesh1, mesh2, m3) except Excetion as err: tarray = np.zeros((150, 225)) tarray.fill(SEA_LEVEL) finally: if xarray is None: xarray = tarray else: xarray = np.concatenate((xarray, tarray), axis=1) if yarray is None: yarray = xarray else: yarray = np.concatenate((xarray, yarray), axis=0) np.save(NPY_DIR+"/"+NPY_2ND_FILE.format(mesh1, mesh2), yarray) else: yarray = xml2array(mesh1, mesh2, mesh3) np.save(NPY_DIR+"/"+NPY_3RD_FILE.format(mesh1, mesh2, mesh3), yarray) print(yarray.shape)
NumPyデータをプロットする (plotnpy.py)
# coding: utf-8 import numpy as np import matplotlib.pyplot as plot import sys NPY_DIR = "/Users/pycra/Desktop/NPY_DATA" # ここからスタート if len(sys.argv) < 2: print("plotnpy.py npyfilename") exit(-1) array = np.load(NPY_DIR+"/"+sys.argv[1]) plot.imshow(array) plot.colorbar() plot.show()
NumPyデータを5x5倍する (npy5x5.py)
# coding: utf-8 import numpy as np from scipy.ndimage import filters import re import sys NPY_DIR = "/Users/pycra/Desktop/NPY_DATA" NPY_FILE = "npy_5x5{0}.npy" # ここからスタート if len(sys.argv) < 2: print("plotnpy.py npyfilename") exit(-1) m = re.search('npy(data|_5x5)((\-[0-9]+)+)\.npy', sys.argv[1]) if m is None: print("Bad npy filename.") exit(-1) if m.group(1) == '_5x5': print("This is 5x5 file.") exit(-1) array = np.load(NPY_DIR+"/"+sys.argv[1]) print(array.shape) print(array) array5 = np.repeat(array, 5, axis=0) print(array5.shape) print(array5) array5x5 = np.repeat(array5, 5, axis=1) print(array5x5.shape) print(array5x5) aa_array = filters.gaussian_filter(array5x5, 2) np.save(NPY_DIR+"/"+NPY_FILE.format(m.group(2)), aa_array)
NumPyデータを5x5分割する (npydiv5.py)
# coding: utf-8 import numpy as np import re import sys NPY_DIR = "/Users/pycra/Desktop/NPY_DATA" NPY_DIV5_FILE = "npydiv5-{0:04d}-{1:02d}-{2:02d}.npy" NPY_FILE = "npy{0}-{1:04d}-{2:02d}-{3:02d}-{4:02d}.npy" # ここからスタート if len(sys.argv) < 2: print("npydiv5.py npyfilename") exit(-1) m = re.search('npy(data|_5x5)\-([0-9]+)\-([0-9]+)(\-([0-9]+))?(\-([0-9]+))?\.npy', sys.argv[1]) if m is None: print("Bad filename") exit(-1) fmt = m.group(1) mesh1 = int(m.group(2)) mesh2 = int(m.group(3)) mesh3 = None mesh4 = None if m.group(5) is not None: mesh3 = int(m.group(5)) if m.group(7) is not None: mesh4 = int(m.group(7)) if mesh4 is not None: print("this file is 4th mesh.") exit(-1) array = np.load(NPY_DIR+"/"+sys.argv[1]) a = np.split(array, 5, axis=1) #print("a=", a) count = 0 for j in range(5): b = np.split(a[j], 5, axis=0) #print("b=", b) for i in range(5): if mesh3 is None: np.save(NPY_DIR+"/"+NPY_DIV5_FILE.format(mesh1, mesh2, count), b[i]) else: np.save(NPY_DIR+"/"+NPY_FILE.format(fmt, mesh1, mesh2, mesh3, count), b[i]) count+=1 print(b[i].shape)
NumPyデータをマイクラ内でロードする (loadnpy.py)
# coding: utf-8 import mcpi.minecraft as minecraft import mcpi.block as block import numpy as np import sys from time import sleep NPY_DIR = "/Users/pycra/Desktop/NPY_DATA" LOG_FMT = "Z step ({}/{})" mc = minecraft.Minecraft() mc.postToChat("Loadnpy.py Start!") if len(sys.argv) < 2: print("loadnpy.py npyfilename") exit(-1) array = np.load(NPY_DIR+"/"+sys.argv[1]) (zshape, xshape) = array.shape for z in range(zshape): for x in range(xshape): hval = array[z][x] mc.setBlocks(x, hval-1, z, x, hval-7, z, block.DIRT) mc.setBlock(x, hval, z, block.GRASS) sleep(0.01) mc.postToChat(LOG_FMT.format(z, zshape)) sleep(0.1) mc.postToChat("Loadnpy.py Finish!!!")
ここの修正で新たに勉強したこと
ファイルの有無をチェックする
os.path.isfile
ファイルやディレクトリの有無を調べる - Python Tips
import os GEO_DIR = "FG-GML-{0:04d}-{1:02d}-DEM5A" GEO_XML_20161001 = "FG-GML-{0:04d}-{1:02d}-{2:02d}-DEM5A-20161001.xml" GEO_XML_20170202 = "FG-GML-{0:04d}-{1:02d}-{2:02d}-DEM5A-20170202.xml" ・・・中略・・・ def xml2array(mesh1, mesh2, mesh3): dir = GEO_DIR.format(mesh1, mesh2) fname = GEO_XML_20161001.format(mesh1, mesh2, mesh3) if os.path.isfile(dir+"/"+fname) == False: fname = GEO_XML_20170202.format(mesh1, mesh2, mesh3) if os.path.isfile(dir+"/"+fname) == False: raise FileNotFoundError(dir+"/"+fname) ・・・以下、略・・・
正規表現
渡されたファイル名から、各次メッシュ番号を取得するのに正規表現を使った。
re.matchもあるけど、re.searchの方が優しい。
6.2. re — 正規表現操作 — Python 3.6.1 ドキュメント
import re import sys ・・・中略・・・ m = re.search('npy(data|_5x5)\-([0-9]+)\-([0-9]+)(\-([0-9]+))?(\-([0-9]+))?\.npy', sys.argv[1]) if m is None: print("Bad filename") exit(-1) fmt = m.group(1) mesh1 = int(m.group(2)) mesh2 = int(m.group(3)) mesh3 = None mesh4 = None if m.group(5) is not None: mesh3 = int(m.group(5)) if m.group(7) is not None: mesh4 = int(m.group(7)) if mesh4 is not None: print("this file is 4th mesh.") exit(-1) ・・・以下、略・・・