Skip to content

Commit

Permalink
Merge pull request #55 from eukarya-inc/dev/py3dtiles-beta
Browse files Browse the repository at this point in the history
#54 supports new features and bump 0.0.13
  • Loading branch information
smellman authored Nov 24, 2023
2 parents c8b629b + 8328823 commit 4324407
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 80 deletions.
6 changes: 4 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"python.formatting.provider": "black",
"editor.formatOnSave": true
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.formatOnSave": true
}
}
2 changes: 1 addition & 1 deletion dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pluggy==1.0.0
plyfile==1.0.1
psutil==5.9.5
psycopg2-binary==2.9.7
py3dtiles==6.0.0
git+https://gitlab.com/Oslandia/py3dtiles.git@489289d2f7310fbcb8e95710e250d893999adf5d#egg=py3dtiles
Pygments==2.15.1
pyproj==3.6.1
pyproject_hooks==1.0.0
Expand Down
2 changes: 1 addition & 1 deletion doc/plateauutils.citygmlfinder.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ plateauutils.citygmlfinder パッケージ
======================================

plateauutils.citygmlfinder.from_reearth_cms モジュール
--------------------------------------------------
-------------------------------------------------------

.. automodule:: plateauutils.citygmlfinder.from_reearth_cms
:members:
Expand Down
23 changes: 17 additions & 6 deletions plateauutils/abc/numpy_tile_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,28 @@ def _parse_tile(self):
tile_list = self.__make_tile_list()
lons = [] # 経度
lats = [] # 緯度
maps = [] # 標高
dems = [] # 標高
classifications = [] # 属性値
# それぞれのタイルをパース
for tile in tile_list:
t = np.load(tile)
lons.append(t["lons"])
lats.append(t["lats"])
map = t["map"]
# 標高がnanの場合は0にする
map[np.isnan(map)] = 0
maps.append(map)
return np.concatenate(lons), np.concatenate(lats), np.concatenate(maps)
dems.append(t["dem"])
classifications.append(t["classification"])
# np.arrayに変換
np_lons, np_lats, np_dems, np_classifications = (
np.concatenate(lons),
np.concatenate(lats),
np.concatenate(dems),
np.concatenate(classifications),
)
# nanを除去
np_lons = np_lons[~np.isnan(np_dems)]
np_lats = np_lats[~np.isnan(np_dems)]
np_classifications = np_classifications[~np.isnan(np_dems)]
np_dems = np_dems[~np.isnan(np_dems)]
return np_lons, np_lats, np_dems, np_classifications

def __make_tile_list(self):
"""タイルのリストを作成するメソッド"""
Expand Down
2 changes: 1 addition & 1 deletion plateauutils/flood_converter/flood_to_3dtiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def convert(
"""
# xyzファイルを作成
xyz = FloodToXyz(path).parse()
tmp = tempfile.mktemp(suffix=".xyz")
tmp = tempfile.mktemp(suffix=".csv")
# 一時ファイルにxyzを書き込み
with open(tmp, "w") as f:
f.write(xyz)
Expand Down
118 changes: 57 additions & 61 deletions plateauutils/flood_converter/flood_to_png.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,49 +26,50 @@ def parse(self, output_dir: str = ""):
output_dir : str
pngの出力先
"""
# lontitude, latitude, altitudeを取得
lons, lats, maps = self._parse_tile()
# storeを作成
store = Store()
# storeのaddメソッドをベクトル化
vfunc = np.vectorize(store.add)
# storeにlontitude, latitude, altitudeを追加
vfunc(lons, lats, maps)
# pngを書き出す
writer = PngWriter(output_dir, 15)
writer.setStore(store)
writer.write()
# lontitude, latitude, classificationsを取得
lons, lats, _, classifications = self._parse_tile()
# ズームレベル8から15までのpngを作成
for zoom in range(8, 16):
# storeを作成
store = Store(zoom)
# storeのaddメソッドをベクトル化
vfunc = np.vectorize(store.add)
# storeにlontitude, latitude, classificationsを追加
vfunc(lons, lats, classifications)
# pngを書き出す
writer = PngWriter(output_dir, zoom)
writer.setStore(store)
writer.write()


class Store(object):
"""タイルの座標及び標高を保持するクラス"""

def __init__(self):
self.zoom = 15
def __init__(self, zoom):
self.zoom = zoom
self.storage = dict()

def add(self, x, y, z):
def add(self, x, y, classification):
"""タイルの座標及び標高を格納するメソッド"""
longitude, latitude, altitude = x, y, z
longitude, latitude = x, y
# 座標からタイルの座標とタイル内の座標を取得
x, y, pos_x, pos_y = self._coordinate_to_position(longitude, latitude)
# storageに格納
self._insert(x, y, pos_x, pos_y, altitude)
self._insert(x, y, pos_x, pos_y, classification)

def _insert(self, x, y, pos_x, pos_y, altitude):
def _insert(self, x, y, pos_x, pos_y, classification):
# keyがstorageに存在する場合はその値を取得
key = (x, y)
if key in self.storage.keys():
array = self.storage[key]
else:
# 存在しない場合は256*256の配列を作成
array = np.zeros((256, 256))
array.fill(-np.inf)
array = np.zeros((256, 256), dtype=np.int32)
self.storage[key] = array
# 標高を格納
current = array[pos_x][pos_y]
if current < altitude:
array[pos_x][pos_y] = altitude
if current < classification:
array[pos_x][pos_y] = classification
self.storage[key] = array

def _coordinate_to_position(self, longitude, latitude):
Expand Down Expand Up @@ -157,55 +158,50 @@ def _write(self, x, y, value):
sys.exit(-1)
# 標高をpngに変換
dt = np.dtype(
{"names": ["r", "g", "b"], "formats": [np.uint8, np.uint8, np.uint8]}
{
"names": ["r", "g", "b", "a"],
"formats": [np.uint8, np.uint8, np.uint8, np.uint8],
}
)
converted1 = np.array(
[tuple(self._dem_to_png(v)) for v in value.reshape(value.size)], dtype=dt
[tuple(self._classification_to_png(v)) for v in value.reshape(value.size)],
dtype=dt,
)
converted2 = converted1.reshape(value.shape)
filename = f"{self.directory}/{self.zoom}/{x}/{y}.png"
width = 256
img = Image.new("RGB", (width, width), (128, 0, 0))
img = Image.new("RGBA", (width, width), (128, 0, 0, 0))
draw = ImageDraw.Draw(img)
for i in range(0, width):
for j in range(0, width):
p = converted2[i][j]
draw.point([(i, j)], (int(p[0]), int(p[1]), int(p[2])))
draw.point([(i, j)], (int(p[0]), int(p[1]), int(p[2]), int(p[3])))
img.save(filename)

def _dem_to_png(self, dem):
# 標高をPNGのRGBに変換するメソッド
# 内容が入っていなかったら白色
if dem == -np.inf:
return (0xFF, 0xFF, 0xFF)
# 標高に応じて色を変更
if dem > 20:
# 185 26 248
return (0xB9, 0x1A, 0xF8)
if dem > 10:
# 169 8 91
return (0xA9, 0x08, 0x5B)
if dem > 5:
# 253 35 21
return (0xFD, 0x23, 0x15)
if dem > 4:
# 236 106 141
return (0xEC, 0x6A, 0x8D)
if dem > 3:
# 254 115 117
return (0xFE, 0x73, 0x75)
if dem > 2:
# 236 182 182
return (0xEC, 0xB6, 0xB6)
if dem > 1:
# 255 141 36
return (0xFF, 0x8D, 0x24)
if dem > 0.3:
# 255 225 53
return (0xFF, 0xE1, 0x35)
if dem > 0.01:
# 48 254 55
return (0x30, 0xFE, 0x37)
# 0.01以下は白色
def _classification_to_png(self, classification):
# 属性をPNGのRGBに変換するメソッド
# 内容が入っていなかったら透明色
if classification == 0:
return (0xFF, 0xFF, 0xFF, 0x00)
# 属性に応じて色を変更
if classification == 6:
# 220 122 220
return (0xDC, 0x7A, 0xDC, 0xFF)
if classification == 5:
# 242 133 201
return (0xF2, 0x85, 0xC9, 0xFF)
if classification == 4:
# 255 145 145
return (0xFF, 0x91, 0x91, 0xFF)
if classification == 3:
# 255 183 183
return (0xFF, 0xB7, 0xB7, 0xFF)
if classification == 2:
# 255 216 192
return (0xFF, 0xD8, 0xC0, 0xFF)
if classification == 1:
# 247 245 169
return (0xF7, 0xF5, 0xA9, 0xFF)
# 例外は透明色
# 255 255 255
return (0xFF, 0xFF, 0xFF)
return (0xFF, 0xFF, 0xFF, 0x00)
25 changes: 21 additions & 4 deletions plateauutils/flood_converter/flood_to_xyz.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import numpy as np
import pandas as pd
from plateauutils.abc.numpy_tile_parser import NumpyTileParser

Expand All @@ -16,7 +17,23 @@ def __init__(self, path: str = ""):

def parse(self):
"""洪水浸水域をxyzに変換するメソッド"""
lons, lats, maps = self._parse_tile()
# xyzファイルを作成, 並びはlatitude, longitude, altitude
df = pd.DataFrame({"lat": lats, "lon": lons, "map": maps})
return df.to_csv(index=False, header=False, sep=" ")
lons, lats, dems, classifications = self._parse_tile()
# IRGB値を作成
i_values = np.ones_like(dems, dtype=np.int32) * 1
r_values = np.ones_like(dems, dtype=np.int32) * 0
g_values = np.ones_like(dems, dtype=np.int32) * 191
b_values = np.ones_like(dems, dtype=np.int32) * 255
# xyzファイルを作成, 並びはlatitude, longitude, altitude, i, r, g, b, classification
df = pd.DataFrame(
{
"lat": lats,
"lon": lons,
"dem": dems,
"i": i_values,
"r": r_values,
"g": g_values,
"b": b_values,
"classification": classifications,
}
)
return df.to_csv(index=False, header=True, sep=" ")
Binary file modified plateauutils/flood_converter/tests/fixtures/15/28264/13160.npz
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ def test_convert(tmp_dir: str):
assert Path(tmp_dir, "tileset.json").exists()
assert Path(tmp_dir, "r.pnts").exists()
tileset_path = tmp_dir / "tileset.json"
assert 256 * 256 == number_of_points_in_tileset(tileset_path)
assert 62615 == number_of_points_in_tileset(tileset_path)
1 change: 1 addition & 0 deletions plateauutils/flood_converter/tests/test_flood_to_xyz.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ def test_convert(tmp_dir: str):
flood_to_png = FloodToPng(str(DATA_DIRECTORY))
flood_to_png.parse(output_dir=str(tmp_dir))
assert Path(tmp_dir, "15/28264/13160.png").exists()
assert Path(tmp_dir, "8/220/102.png").exists()
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ classifiers = [
"Development Status :: 2 - Pre-Alpha",
"Programming Language :: Python :: 3",
]
version = "0.0.12"
version = "0.0.13"
dependencies = [
"click",
"numpy",
"pandas",
"Pillow",
"py3dtiles",
"py3dtiles @ git+https://gitlab.com/Oslandia/py3dtiles.git@489289d2f7310fbcb8e95710e250d893999adf5d",
"pyproj",
"requests",
"reearthcmsapi",
Expand All @@ -34,6 +34,9 @@ keywords = ['plateau']
[tool.hatch.build]
exclude = ["tests/*"]

[tool.hatch.metadata]
allow-direct-references = true

[project.urls]
"Homepage" = "https://eukarya-inc.github.io/plateauutils/"
"Bug Reports" = "https://github.com/eukarya-inc/plateauutils/issues"
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ reearthcmsapi==0.0.3
numpy==1.22.4
pandas==2.1.0
Pillow==10.0.1
py3dtiles==6.0.0
git+https://gitlab.com/Oslandia/py3dtiles.git@489289d2f7310fbcb8e95710e250d893999adf5d#egg=py3dtiles
pyproj==3.6.1
requests==2.31.0
shapely==2.0.1
Expand Down

0 comments on commit 4324407

Please sign in to comment.