JAVA版_shatter world limits_minescript_QGIS_GDAL
20250903 ★★★★★★★★★今までまでのまとめ★★★★★★★★★
参考までに
---<pythonで dir変更は>------------------------------------------
>>>import os
>>>print(os.getcwd())
---------------------------------------------------
ディレクトリの変更した
---------------------------------------------------------
>>>os.chdir('C:/Users/Yasushi/SynologyDrive/Minecraft')
-------------------------------------------------------
□
minecraft 1.19.3 に downversion
forge 1.19.3 installer download and install
shatteredworldlimits-0.2.0-512-forge-1.19.3.jar
minescript-mc1.19.3-forge-mod-3.2.jar
を探してきて入れた.
C:\Users\byf04\AppData\Roaming\.minecraft\modsに配置
これだと大丈夫(かも)
C:\Users\Yasushi\AppData\Roaming\.minecraft\minescript\config.txt を書きに書き換える
そうないと[Exited with error code 9009]
# Lines starting with "#" are ignored.
#python="%userprofile%\AppData\Local\Microsoft\WindowsApps\python3.exe"
python="C:\Python39\python.exe"
で
helloworld.pyなる下記のファィルを作り,C:\Users\Yasushi\AppData\Roaming\.minecraft\minescriptにおく
import minescript
minescript.echo("Hello world!")
で OK
Shattered World Lmits で 高度の制限を 1024 にして
minescript が動くようにした
QGIS(https://qgis.org/)からゲットした LTS 版をインストールしていたのだが
OSGeo4w をゲット
.....GDALをpythonから使う必要があるのだが(使わない方法もありそうだが),この導入が難しく,ここに入っている
QGIS は GDAL とか使いやすそうだったのでやってみた
https://trac.osgeo.org/osgeo4w/wiki/OSGeo4W_jp
...死んでる
https://qgis.org/
ここにある
osgeo4w-setup.exe QGIS, GDAL 入れて
install
quickDEM4JP なるプラグインをinstallした(LTS版にinstallしたものが再現されていた)
新規に入れるなら,QGISのプラグインマネージャから
これを使って
基盤情報地図から download した DEM ファィルを tiff にする
C:\Users\Yasushi\SynologyDrive\Minecraft において作業を進めてる
GDALを使った python
script を作り
tiff ファイルは精度5mなので(補完して)精度1mにする
Pythonを使用して数値標高モデル(DEM)からMinecraftの地形を作成する
にあるコード(再掲)ではNG
------------------------------------------------
from osgeo import gdal
# 入力ファイルを開く
tiff = gdal.Open("kakuda.tiff", gdal.GA_ReadOnly)
# 変換パラメーターを設定
dst_size_x = 1
dst_size_y = 1
# 立方体補間(Cubic Convolution)
で解像度を変更する
warp_options =
gdal.WarpOptions(xRes=dst_size_x, yRes=dst_size_y,
resampleAlg=gdal.GRIORA_Cubic)
# ラスターの変換を実行
dst = gdal.Warp("kakuda_1m.tiff", tiff,
options=warp_options)
# ファイルをクローズ
src = None
dst = None
------------------------------------------------
CoPilot に教えてもらってFB
-------PrepKakudaCorrected(ByPyQGIS).py で保存
EPSGコードが新潟県でハードコードされているので注意---------------
from
osgeo import gdal, osr
# 入力ファイルを開く
src_ds = gdal.Open("kakuda.tiff", gdal.GA_ReadOnly)
# UTM ゾーンの設定(例:新潟なら UTM Zone
54N)
srs =
osr.SpatialReference()
srs.ImportFromEPSG(32654) # EPSG:32654 = WGS84 / UTM zone 54N
# Warp オプションを設定(1m 解像度)
warp_options = gdal.WarpOptions(
dstSRS=srs.ExportToWkt(),
xRes=1,
yRes=1,
resampleAlg=gdal.GRIORA_Cubic
)
#
Warp 実行
dst_ds =
gdal.Warp("kakuda_1m_utm.tiff", src_ds, options=warp_options)
dst_ds = None
--------------------------------------------
この script
を実行するには.....
内包された GDAL のカレントディレクトリは
---<pythonで>------------------------------------------
>>>import os
>>>print(os.getcwd())
---------------------------------------------------
で,必要により
ディレクトリの変更した
---------------------------------------------------------
>>>os.chdir('C:/Users/Yasushi/SynologyDrive/Minecraft')
-------------------------------------------------------
で,実行するには
① >>> に全部貼り付けてenter
② QGISのpython console で
エディタの表示をすると右のペインにコードエディタが現れるので,ここでpyファイルを読み込む.で,実行
(外のpythonでも pip install gdal や pip install osr が出来れば,外の python でもできるのだろう)
Pythonを使用して数値標高モデル(DEM)からMinecraftの地形を作成する
次に xyz 変換 これも quitq 参考
(C:/Users/Yasushi/SynologyDrive/Minecraft/2_chgAxisByPython(ByPyQGIS).py)
適宜indent 要る
------------------------------------------------------------------
# ライブラリのインポート
import rasterio
import numpy as np
import pandas as pd
# 変換したラスターファイルを開く
with rasterio.open("553616_dem_1m.tiff") as src:
# 幅と高さを取得
width, height = src.width,
src.height
# 中心点のオフセットを計算
# 偶数の場合は0.5、奇数の場合は0
offset_x = 0.5 if width % 2 == 0
else 0
offset_y = -0.5 if height % 2 == 0 else 0
#
トランスフォーメーション行列から中心座標を計算
transform = src.transform
center_x = transform.c + width /
2.0 * transform.a + offset_x
center_y = transform.f + height /
2.0 * transform.e + offset_y
#
数値標高データを取得
data = src.read(1)
# 各ピクセルの中心座標を取得
y_indices, x_indices =
np.indices(data.shape)
x_coords = x_indices * transform.a + transform.c + transform.a / 2.0
y_coords = y_indices * transform.e
+ transform.f + transform.e / 2.0
#
ピクセル座標と標高値を一次元化
x_coords = x_coords.ravel()
y_coords = y_coords.ravel()
data = data.ravel()
#
マイクラの基準にする中心の座標を引く
x_coords = x_coords - center_x
y_coords = y_coords - center_y
#
y軸(北南)を反転。マイクラ座標に合わせるため
y_coords = y_coords * -1
# 小数点以下を排除
x_coords =
np.trunc(x_coords).astype(int)
y_coords =
np.trunc(y_coords).astype(int)
data = np.trunc(data).astype(int)
#
マイクラのブロック座標からregion(.mca)のファイル名を取得
region_x = (x_coords //
512).astype(int)
region_z = (y_coords // 512).astype(int)
# 文字列に変換
region_x_str = np.char.mod("%d",
region_x)
region_z_str = np.char.mod("%d", region_z)
#
ベクトル化した文字列フォーマット操作を適用
region = np.vectorize("r.{}.{}.mca".format)(region_x, region_z)
#
データフレームを作成
df = pd.DataFrame({
"x": x_coords,
"z": y_coords,
"y": data,
"region": region
})
------------------------------------------------------------------
今後の予定は
xyzにして,それをもとにして setblock していく
CoPilot に聞いて
df.to_csv("output_dem.xyz", sep=" ", index=False,
header=False)
を加えて csv を作る
[csv] 何だから separatoe がblank では変だろうということで,separator に[,]を使う
サイズが大きくなりすぎるが,どうしよう...とりあえず
5m 解像度で作ってみたが,1m 解像度で
標高の欠損値 [-9999]を書き出さないようにする.regions もいらない
としたらどだろ
まず5m解像度で実験しよう
できたdf を標高でソートしてから,標高毎(0m 台,100m台,200m 台...にxyz に書き出す.
欠損値を省いてソートするだけなら df を作った後に
--------------------------------------------------
# 欠損値(-9999)を除外
valid_mask = data != -9999
df = df[valid_mask]
# 標高(y)で降順ソート(高い順)
df = df.sort_values(by="y", ascending=False)
df.to_csv("kakuda_5m_utm.xyz",
sep=",", index=False, header=False)
---------------------------------------------------------------
minescript でつかう script を作っていく
置き場所は
C:\Users\Yasushi\AppData\Roaming\.minecraft\minescript
ではなくて....
コマンド群をつくって実行するのが良いみたい
ここでは
C:\Users\Yasushi\AppData\Roaming\.minecraft\saves\KAKUDA\datapacks
に
├── pack.mcmeta
└── data/
└── your_namespace/
└── functions/
└── teleport_and_setblock.mcfunction
なるフォルダ構成を作る
名前空間はこうしよう
data/
└── kakuda_build/
└── functions/
├── teleport_and_setblock.mcfunction
├── layer_400.mcfunction
└── layer_401.mcfunction
pack.mcmeta には json が入る
{
"pack": {
"pack_format": 26,
"description":
"Kakuda terrain builder"
}
}
今使っている 1.19.3 は [12] だというので
{
"pack": {
"pack_format": 12,
"description":
"Kakuda terrain builder"
}
}
となりそう.これを pack.mcmeta
として保存する
ここまで準備したうえで
------_mk_kakuda_function.py
取りあえずのファイル名------------------------------------------------------------------------
------この py ファイルの置き場所は-C:\Users\Yasushi\SynologyDrive\Minecraft
にしてある---------------------------------
import pandas as pd
# xyz
ファイルを読み込む
df = pd.read_csv("kakuda_5m_utm.xyz", names=["x", "z", "y"])
# y > 400 のフィルタ
df = df[df["y"] > 400]
# コマンドリスト
commands = []
for _, row in df.iterrows():
x, z, y = row["x"],
row["z"], row["y"]
tp_cmd = f'tp @p {x} {y+1} {z} 180 90'
setblock_cmd = f'setblock {x} {y} {z} minecraft:dirt'
commands.append(tp_cmd)
commands.append(setblock_cmd)
# ファイルに保存(例:commands.mcfunction)
with
open("teleport_and_setblock.mcfunction", "w") as f:
f.write("\n".join(commands))
"""
- tp @p x y z <yaw> <pitch> の形式で、
- yaw=180 → 南向き
- pitch=90 → 真下を見る
"""
------------------------------------------------------------------------------------
外の python でもできそうだが,pyQGIS でやろう
▲20250904 PM ここまで
できたファイルを上で準備した function を
C:\Users\Yasushi\AppData\Roaming\.minecraft\saves\KAKUDA\datapacks\kakuda_build\data\kakuda_build\functions
に置く感じ?
pack.mcmetaというファイルも忘れないで 文字コードはUTF-8 で
置き場所は
C:\Users\Yasushi\AppData\Roaming\.minecraft\saves\KAKUDA\datapacks\kakuda_build
{
"pack": {
"pack_format": 12,
"description": "Kakuda terrain
builder"
}
}
で /reload が吉.そのあと
ゲーム内で /function your_namespace:teleport_and_setblock を実行
ここでは
/function kakuda_build:teleport_and_setblock
になるかな?