パイクラおじさんの日記

MinecraftでPythonを勉強するおじさんの日記です。

ファイル名を整理

いろいろなサイズの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)
・・・以下、略・・・