How to obtain statistics of a loaded map?
Opened this issue · 3 comments
Is there any way to request dimensions of a map?
I have a map and I wish to export it into mts, but I don't know the position of existing blocks. Is there a way to compute a min/max on each dimension?
I did something like the following script, but it seems incorrect.
vessel = libminetest.map.MapVessel(map)
minpos = None
maxpos = None
for block in vessel.get_all_mapblock_ids():
print(block)
pos = libminetest.utils.posFromInt(block, 4096)
if minpos is None:
minpos = pos
if maxpos is None:
maxpos = pos
minpos = libminetest.utils.Pos(min(pos.x,minpos.x),min(pos.y,minpos.y),min(pos.z,minpos.z))
maxpos = libminetest.utils.Pos(max(pos.x,maxpos.x),max(pos.y,maxpos.y),max(pos.z,maxpos.z))
#print(vessel.load(block))
print(minpos)
print(maxpos)
vessel.close()
i am trying your code by incorporating it as another test in the tests/test.py
i agree that something is wrong. for example, i have a mapgen mod that tells me how many chunks (5x5x5 blocks) it has generated and for a start the number of mapblocks in the mapblock load test is always more than twice as many as it should be. also when I go into a world and wander around more to generate more blocks your code still comes up with the same min and max positions, although different maps have different max and min positions but they don't change as i explore either. also there are a lot of 4095 values which seems suspicious considering I am only wandering around the map for a few seconds.
First, I'd recommend using libminetest.utils.getIntegerAsBlock
instead of the generic position calculator function, which doesn't really work with block positions. getIntegerAsBlock was written by celeron55 and pulled out of minetest's actual documentation related to world format. I used it instead and now I have correct coordinates.
Then, I believe the most accurate way to get a map's dimension here is to actually the number of blocks by using the length of the table returned by vessel.get_all_mapblock_ids()
.
Finally, your way of creating a minimal/maximal position actually keeps the smallest/biggest coordinate in every dimension, so the mapblock position it indicate may not exist yet, but other mapblocks exist with very low/high positions on one or two coordinates and those are kept. Maybe you knew it already but I had to clarify.
But, here, I fixed your code and added the block count thing :)
def map_dimensions(map):
vessel = libminetest.map.MapVessel(map)
minpos = None
maxpos = None
for block in vessel.get_all_mapblock_ids():
print(block)
pos = libminetest.utils.getIntegerAsBlock(block)
if minpos is None:
minpos = pos
if maxpos is None:
maxpos = pos
minpos = libminetest.utils.Pos(min(pos.x,minpos.x),min(pos.y,minpos.y),min(pos.z,minpos.z))
maxpos = libminetest.utils.Pos(max(pos.x,maxpos.x),max(pos.y,maxpos.y),max(pos.z,maxpos.z))
#print(vessel.load(block))
print(minpos)
print(maxpos)
dimens = len(vessel.get_all_mapblock_ids())
print("There are {0} blocks currently generated and stored".format(dimens))
vessel.close()