Merge branch 'master' into POI-Polylines
This commit is contained in:
@@ -14,7 +14,7 @@ before_script:
|
|||||||
- git clone git://github.com/overviewer/Minecraft-Overviewer-Addons.git ~/mcoa/
|
- git clone git://github.com/overviewer/Minecraft-Overviewer-Addons.git ~/mcoa/
|
||||||
- wget -N http://s3.amazonaws.com/MinecraftDownload/minecraft.jar -P ~/.minecraft/bin/
|
- wget -N http://s3.amazonaws.com/MinecraftDownload/minecraft.jar -P ~/.minecraft/bin/
|
||||||
script:
|
script:
|
||||||
- python overviewer.py ~/mcoa/exmaple ~/test-output --rendermodes=smooth-lighting
|
- python overviewer.py ~/mcoa/exmaple ~/test-output --rendermodes=smooth-lighting -p1
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
# matrix:
|
# matrix:
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ def main():
|
|||||||
parser.add_option('--center', '-e', help = 'Mark what will be the center of the image, two percentage values comma separated',\
|
parser.add_option('--center', '-e', help = 'Mark what will be the center of the image, two percentage values comma separated',\
|
||||||
metavar = '<center>', type = str, dest = 'center', default = None)
|
metavar = '<center>', type = str, dest = 'center', default = None)
|
||||||
|
|
||||||
|
parser.add_option('--autocrop', '-a', help = 'Calculates the center and crop vales automatically to show all the tiles in the minimun image size.Unless you want a very specific image this options is very recommendedable.',\
|
||||||
|
action = 'store_true', dest = 'autocrop', default = False)
|
||||||
|
|
||||||
parser.add_option('--output', '-o', help = 'Path for the resulting PNG. It will save it as PNG, no matter what extension do you use.',\
|
parser.add_option('--output', '-o', help = 'Path for the resulting PNG. It will save it as PNG, no matter what extension do you use.',\
|
||||||
metavar = '<output>', type = str, dest = 'output', default = "output.png")
|
metavar = '<output>', type = str, dest = 'output', default = "output.png")
|
||||||
|
|
||||||
@@ -43,6 +46,9 @@ def main():
|
|||||||
if not options.zoom_level:
|
if not options.zoom_level:
|
||||||
parser.error("Error! The option zoom-level is mandatory.")
|
parser.error("Error! The option zoom-level is mandatory.")
|
||||||
|
|
||||||
|
if options.autocrop and (options.center or options.crop):
|
||||||
|
parser.error("Error! You can't mix --autocrop with --center or --crop.")
|
||||||
|
|
||||||
# check for the output
|
# check for the output
|
||||||
folder, filename = split(options.output)
|
folder, filename = split(options.output)
|
||||||
if folder != '' and not exists(folder):
|
if folder != '' and not exists(folder):
|
||||||
@@ -54,32 +60,6 @@ def main():
|
|||||||
tile_size = (384,384)
|
tile_size = (384,384)
|
||||||
px_size = 4 # bytes
|
px_size = 4 # bytes
|
||||||
|
|
||||||
# the vector that joins the center tile with the new center tile in
|
|
||||||
# tile coords (tile coords is how many tile are on the left, x, and
|
|
||||||
# how many above, y. The top-left tile has coords (0,0)
|
|
||||||
if options.center:
|
|
||||||
center_x, center_y = options.center.split(",")
|
|
||||||
center_x = int(center_x)
|
|
||||||
center_y = int(center_y)
|
|
||||||
center_tile_x = int(2**n*(center_x/100.))
|
|
||||||
center_tile_y = int(2**n*(center_y/100.))
|
|
||||||
center_vector = (int(center_tile_x - length_in_tiles/2.), int(center_tile_y - length_in_tiles/2.))
|
|
||||||
else:
|
|
||||||
center_vector = (0,0)
|
|
||||||
|
|
||||||
tiles_to_crop = int(2**n*(options.crop/100.))
|
|
||||||
crop = (tiles_to_crop, tiles_to_crop)
|
|
||||||
|
|
||||||
final_img_size = (tile_size[0]*length_in_tiles,tile_size[1]*length_in_tiles)
|
|
||||||
final_cropped_img_size = (final_img_size[0] - 2*crop[0]*tile_size[0],final_img_size[1] - 2*crop[1]*tile_size[1])
|
|
||||||
|
|
||||||
mem = final_cropped_img_size[0]*final_cropped_img_size[1]*px_size # bytes!
|
|
||||||
print "The image size will be {0}x{1}".format(final_cropped_img_size[0],final_cropped_img_size[1])
|
|
||||||
print "A total of {0} MB of memory will be used.".format(mem/1024**2)
|
|
||||||
if mem/1024.**2. > options.memory_limit:
|
|
||||||
print "Warning! The expected RAM usage exceeds the spicifyed limit. Exiting."
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# create a list with all the images in the zoom level
|
# create a list with all the images in the zoom level
|
||||||
path = tileset
|
path = tileset
|
||||||
for i in range(options.zoom_level):
|
for i in range(options.zoom_level):
|
||||||
@@ -91,6 +71,64 @@ def main():
|
|||||||
"Error! No images found in this zoom leve. Is this really an overviewer tile set directory?"
|
"Error! No images found in this zoom leve. Is this really an overviewer tile set directory?"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
# autocrop will calculate the center and crop values automagically
|
||||||
|
if options.autocrop:
|
||||||
|
min_x = min_y = length_in_tiles
|
||||||
|
max_x = max_y = 0
|
||||||
|
counter = 0
|
||||||
|
total = len(all_images)
|
||||||
|
print "Checking tiles for autocrop calculations:"
|
||||||
|
# get the maximun and minimun tiles coordinates of the map
|
||||||
|
for path in all_images:
|
||||||
|
t = get_tuple_coords(options, path)
|
||||||
|
c = get_tile_coords_from_tuple(options, t)
|
||||||
|
min_x = min(min_x, c[0])
|
||||||
|
min_y = min(min_y, c[1])
|
||||||
|
max_x = max(max_x, c[0])
|
||||||
|
max_y = max(max_y, c[1])
|
||||||
|
counter += 1
|
||||||
|
if (counter % 100 == 0 or counter == total or counter == 1): print "Checked {0} of {1}".format(counter, total)
|
||||||
|
|
||||||
|
# the center of the map will be in the middle of the occupied zone
|
||||||
|
center = (int((min_x + max_x)/2.), int((min_y + max_y)/2.))
|
||||||
|
# see the next next comment to know what's center_vector
|
||||||
|
center_vector = (int(center[0] - (length_in_tiles/2. - 1)), int(center[1] - (length_in_tiles/2. - 1)))
|
||||||
|
# I'm not completely sure why, but the - 1 factor in ^ makes everything nicer.
|
||||||
|
|
||||||
|
# min_x - center_vector[0] will be the unused amount of tiles in
|
||||||
|
# the left and the right of the map (and this is true because we
|
||||||
|
# are in the actual center of the map)
|
||||||
|
crop = (min_x - center_vector[0], min_y - center_vector[1])
|
||||||
|
|
||||||
|
else:
|
||||||
|
# center_vector is the vector that joins the center tile with
|
||||||
|
# the new center tile in tile coords
|
||||||
|
#(tile coords are how many tile are on the left, x, and
|
||||||
|
# how many above, y. The top-left tile has coords (0,0)
|
||||||
|
if options.center:
|
||||||
|
center_x, center_y = options.center.split(",")
|
||||||
|
center_x = int(center_x)
|
||||||
|
center_y = int(center_y)
|
||||||
|
center_tile_x = int(2**n*(center_x/100.))
|
||||||
|
center_tile_y = int(2**n*(center_y/100.))
|
||||||
|
center_vector = (int(center_tile_x - length_in_tiles/2.), int(center_tile_y - length_in_tiles/2.))
|
||||||
|
else:
|
||||||
|
center_vector = (0,0)
|
||||||
|
|
||||||
|
# crop if needed
|
||||||
|
tiles_to_crop = int(2**n*(options.crop/100.))
|
||||||
|
crop = (tiles_to_crop, tiles_to_crop)
|
||||||
|
|
||||||
|
final_img_size = (tile_size[0]*length_in_tiles,tile_size[1]*length_in_tiles)
|
||||||
|
final_cropped_img_size = (final_img_size[0] - 2*crop[0]*tile_size[0],final_img_size[1] - 2*crop[1]*tile_size[1])
|
||||||
|
|
||||||
|
mem = final_cropped_img_size[0]*final_cropped_img_size[1]*px_size # bytes!
|
||||||
|
print "The image size will be {0}x{1}".format(final_cropped_img_size[0],final_cropped_img_size[1])
|
||||||
|
print "A total of {0} MB of memory will be used.".format(mem/1024**2)
|
||||||
|
if mem/1024.**2. > options.memory_limit:
|
||||||
|
print "Warning! The expected RAM usage exceeds the spicifyed limit. Exiting."
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
# Create a new huge image
|
# Create a new huge image
|
||||||
final_img = Image.new("RGBA", final_cropped_img_size, (26, 26, 26, 0))
|
final_img = Image.new("RGBA", final_cropped_img_size, (26, 26, 26, 0))
|
||||||
|
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ the form ``key = value``. Two items take a different form:, ``worlds`` and
|
|||||||
If you want to specify an observer manually, try something like:
|
If you want to specify an observer manually, try something like:
|
||||||
::
|
::
|
||||||
|
|
||||||
from observer import ProgressBarObserver()
|
from observer import ProgressBarObserver
|
||||||
observer = ProgressBarObserver()
|
observer = ProgressBarObserver()
|
||||||
|
|
||||||
There are currently three observers available: ``LoggingObserver``,
|
There are currently three observers available: ``LoggingObserver``,
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ import sys
|
|||||||
|
|
||||||
# quick version check
|
# quick version check
|
||||||
if not (sys.version_info[0] == 2 and sys.version_info[1] >= 6):
|
if not (sys.version_info[0] == 2 and sys.version_info[1] >= 6):
|
||||||
print "Sorry, the Overviewer requires at least Python 2.6 to run"
|
print("Sorry, the Overviewer requires at least Python 2.6 to run")
|
||||||
if sys.version_info[0] >= 3:
|
if sys.version_info[0] >= 3:
|
||||||
print "and will not run on Python 3.0 or later"
|
print("and will not run on Python 3.0 or later")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@@ -125,15 +125,15 @@ def main():
|
|||||||
# This section of main() runs in response to any one-time options we have,
|
# This section of main() runs in response to any one-time options we have,
|
||||||
# such as -V for version reporting
|
# such as -V for version reporting
|
||||||
if options.version:
|
if options.version:
|
||||||
print "Minecraft Overviewer %s" % util.findGitVersion(),
|
print("Minecraft Overviewer %s" % util.findGitVersion()),
|
||||||
print "(%s)" % util.findGitHash()[:7]
|
print("(%s)" % util.findGitHash()[:7])
|
||||||
try:
|
try:
|
||||||
import overviewer_core.overviewer_version as overviewer_version
|
import overviewer_core.overviewer_version as overviewer_version
|
||||||
print "built on %s" % overviewer_version.BUILD_DATE
|
print("built on %s" % overviewer_version.BUILD_DATE)
|
||||||
if options.verbose > 0:
|
if options.verbose > 0:
|
||||||
print "Build machine: %s %s" % (overviewer_version.BUILD_PLATFORM, overviewer_version.BUILD_OS)
|
print("Build machine: %s %s" % (overviewer_version.BUILD_PLATFORM, overviewer_version.BUILD_OS))
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print "(build info not found)"
|
print("(build info not found)")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
if options.check_terrain:
|
if options.check_terrain:
|
||||||
@@ -158,13 +158,13 @@ def main():
|
|||||||
# first provide an appropriate error for bare-console users
|
# first provide an appropriate error for bare-console users
|
||||||
# that don't provide any options
|
# that don't provide any options
|
||||||
if util.is_bare_console():
|
if util.is_bare_console():
|
||||||
print "\n"
|
print("\n")
|
||||||
print "The Overviewer is a console program. Please open a Windows command prompt"
|
print("The Overviewer is a console program. Please open a Windows command prompt")
|
||||||
print "first and run Overviewer from there. Further documentation is available at"
|
print("first and run Overviewer from there. Further documentation is available at")
|
||||||
print "http://docs.overviewer.org/\n"
|
print("http://docs.overviewer.org/\n")
|
||||||
print "\n"
|
print("\n")
|
||||||
print "For a quick-start guide on Windows, visit the following URL:\n"
|
print("For a quick-start guide on Windows, visit the following URL:\n")
|
||||||
print "http://docs.overviewer.org/en/latest/win_tut/windowsguide/\n"
|
print("http://docs.overviewer.org/en/latest/win_tut/windowsguide/\n")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# more helpful message for users who know what they're doing
|
# more helpful message for users who know what they're doing
|
||||||
@@ -178,13 +178,13 @@ def main():
|
|||||||
# in. It checks to see if --config was given that no worldname/destdir were
|
# in. It checks to see if --config was given that no worldname/destdir were
|
||||||
# given, and vice versa
|
# given, and vice versa
|
||||||
if options.config and args:
|
if options.config and args:
|
||||||
print
|
print()
|
||||||
print "If you specify --config, you need to specify the world to render as well as"
|
print("If you specify --config, you need to specify the world to render as well as")
|
||||||
print "the destination in the config file, not on the command line."
|
print("the destination in the config file, not on the command line.")
|
||||||
print "Put something like this in your config file:"
|
print("Put something like this in your config file:")
|
||||||
print "worlds['myworld'] = %r" % args[0]
|
print("worlds['myworld'] = %r" % args[0])
|
||||||
print "outputdir = %r" % (args[1] if len(args) > 1 else "/path/to/output")
|
print("outputdir = %r" % (args[1] if len(args) > 1 else "/path/to/output"))
|
||||||
print
|
print()
|
||||||
logging.error("Cannot specify both --config AND a world + output directory on the command line.")
|
logging.error("Cannot specify both --config AND a world + output directory on the command line.")
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
return 1
|
return 1
|
||||||
@@ -471,16 +471,16 @@ def list_worlds():
|
|||||||
print
|
print
|
||||||
worlds = world.get_worlds()
|
worlds = world.get_worlds()
|
||||||
if not worlds:
|
if not worlds:
|
||||||
print 'No world saves found in the usual place'
|
print('No world saves found in the usual place')
|
||||||
return
|
return
|
||||||
print "Detected saves:"
|
print("Detected saves:")
|
||||||
|
|
||||||
# get max length of world name
|
# get max length of world name
|
||||||
worldNameLen = max([len(str(x)) for x in worlds] + [len("World")])
|
worldNameLen = max([len(str(x)) for x in worlds] + [len("World")])
|
||||||
|
|
||||||
formatString = "%-" + str(worldNameLen) + "s | %-8s | %-8s | %-16s | %s "
|
formatString = "%-" + str(worldNameLen) + "s | %-8s | %-8s | %-16s | %s "
|
||||||
print formatString % ("World", "Size", "Playtime", "Modified", "Path")
|
print(formatString % ("World", "Size", "Playtime", "Modified", "Path"))
|
||||||
print formatString % ("-"*worldNameLen, "-"*8, "-"*8, '-'*16, '-'*4)
|
print(formatString % ("-"*worldNameLen, "-"*8, "-"*8, '-'*16, '-'*4))
|
||||||
for name, info in sorted(worlds.iteritems()):
|
for name, info in sorted(worlds.iteritems()):
|
||||||
if isinstance(name, basestring) and name.startswith("World") and len(name) == 6:
|
if isinstance(name, basestring) and name.startswith("World") and len(name) == 6:
|
||||||
try:
|
try:
|
||||||
@@ -496,18 +496,18 @@ def list_worlds():
|
|||||||
playstamp = '%d:%02d' % (playtime / 3600, playtime / 60 % 60)
|
playstamp = '%d:%02d' % (playtime / 3600, playtime / 60 % 60)
|
||||||
size = "%.2fMB" % (info['SizeOnDisk'] / 1024. / 1024.)
|
size = "%.2fMB" % (info['SizeOnDisk'] / 1024. / 1024.)
|
||||||
path = info['path']
|
path = info['path']
|
||||||
print formatString % (name, size, playstamp, timestamp, path)
|
print(formatString % (name, size, playstamp, timestamp, path))
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
multiprocessing.freeze_support()
|
multiprocessing.freeze_support()
|
||||||
try:
|
try:
|
||||||
ret = main()
|
ret = main()
|
||||||
util.nice_exit(ret)
|
util.nice_exit(ret)
|
||||||
except textures.TextureException, e:
|
except textures.TextureException as e:
|
||||||
# this isn't a "bug", so don't print scary traceback
|
# this isn't a "bug", so don't print scary traceback
|
||||||
logging.error(str(e))
|
logging.error(str(e))
|
||||||
util.nice_exit(1)
|
util.nice_exit(1)
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
logging.exception("""An error has occurred. This may be a bug. Please let us know!
|
logging.exception("""An error has occurred. This may be a bug. Please let us know!
|
||||||
See http://docs.overviewer.org/en/latest/index.html#help
|
See http://docs.overviewer.org/en/latest/index.html#help
|
||||||
|
|
||||||
|
|||||||
@@ -298,8 +298,8 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) {
|
|||||||
above_level_data = check_adjacent_blocks(state, x, y+1, z, state->block);
|
above_level_data = check_adjacent_blocks(state, x, y+1, z, state->block);
|
||||||
} /* else above_level_data = 0 */
|
} /* else above_level_data = 0 */
|
||||||
|
|
||||||
/* check connection with same level */
|
/* check connection with same level (other redstone and trapped chests */
|
||||||
same_level_data = check_adjacent_blocks(state, x, y, z, 55);
|
same_level_data = check_adjacent_blocks(state, x, y, z, 55) | check_adjacent_blocks(state, x, y, z, 146);
|
||||||
|
|
||||||
/* check the posibility of connection with y-1 level, check for air */
|
/* check the posibility of connection with y-1 level, check for air */
|
||||||
possibly_connected = check_adjacent_blocks(state, x, y, z, 0);
|
possibly_connected = check_adjacent_blocks(state, x, y, z, 0);
|
||||||
|
|||||||
@@ -158,8 +158,9 @@ get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
|
|||||||
blocklevel = get_data(state, BLOCKLIGHT, x, y, z);
|
blocklevel = get_data(state, BLOCKLIGHT, x, y, z);
|
||||||
|
|
||||||
/* special half-step handling, stairs handling */
|
/* special half-step handling, stairs handling */
|
||||||
|
/* Anvil also needs to be here, blockid 145 */
|
||||||
if (block == 44 || block == 53 || block == 67 || block == 108 || block == 109 || block == 114 ||
|
if (block == 44 || block == 53 || block == 67 || block == 108 || block == 109 || block == 114 ||
|
||||||
block == 128 || block == 134 || block == 135 || block == 136) {
|
block == 128 || block == 134 || block == 135 || block == 136 || block == 145 || block == 156) {
|
||||||
unsigned int upper_block;
|
unsigned int upper_block;
|
||||||
|
|
||||||
/* stairs and half-blocks take the skylevel from the upper block if it's transparent */
|
/* stairs and half-blocks take the skylevel from the upper block if it's transparent */
|
||||||
@@ -170,7 +171,7 @@ get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
|
|||||||
upper_block = get_data(state, BLOCKS, x, y + upper_counter, z);
|
upper_block = get_data(state, BLOCKS, x, y + upper_counter, z);
|
||||||
} while (upper_block == 44 || upper_block == 53 || upper_block == 67 || upper_block == 108 ||
|
} while (upper_block == 44 || upper_block == 53 || upper_block == 67 || upper_block == 108 ||
|
||||||
upper_block == 109 || upper_block == 114 || upper_block == 128 || upper_block == 134 ||
|
upper_block == 109 || upper_block == 114 || upper_block == 128 || upper_block == 134 ||
|
||||||
upper_block == 135 || upper_block == 136);
|
upper_block == 135 || upper_block == 136 || upper_block == 156 );
|
||||||
if (is_transparent(upper_block)) {
|
if (is_transparent(upper_block)) {
|
||||||
skylevel = get_data(state, SKYLIGHT, x, y + upper_counter, z);
|
skylevel = get_data(state, SKYLIGHT, x, y + upper_counter, z);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,7 @@ import logging
|
|||||||
import hashlib
|
import hashlib
|
||||||
import time
|
import time
|
||||||
import random
|
import random
|
||||||
|
import re
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
@@ -116,7 +117,7 @@ class World(object):
|
|||||||
# seem to be any set standard on what dimensions are in each world,
|
# seem to be any set standard on what dimensions are in each world,
|
||||||
# just scan the directory heirarchy to find a directory with .mca
|
# just scan the directory heirarchy to find a directory with .mca
|
||||||
# files.
|
# files.
|
||||||
for root, dirs, files in os.walk(self.worlddir):
|
for root, dirs, files in os.walk(self.worlddir, followlinks=True):
|
||||||
# any .mcr files in this directory?
|
# any .mcr files in this directory?
|
||||||
mcas = [x for x in files if x.endswith(".mca")]
|
mcas = [x for x in files if x.endswith(".mca")]
|
||||||
if mcas:
|
if mcas:
|
||||||
@@ -490,16 +491,16 @@ class RegionSet(object):
|
|||||||
|
|
||||||
Returns (regionx, regiony, filename)"""
|
Returns (regionx, regiony, filename)"""
|
||||||
|
|
||||||
logging.debug("regiondir is %s", self.regiondir)
|
logging.debug("regiondir is %s, has type %r", self.regiondir, self.type)
|
||||||
|
|
||||||
for path in glob(self.regiondir + "/r.*.*.mca"):
|
for f in os.listdir(self.regiondir):
|
||||||
dirpath, f = os.path.split(path)
|
if re.match(r"^r\.-?\d+\.-?\d+\.mca$", f):
|
||||||
p = f.split(".")
|
p = f.split(".")
|
||||||
x = int(p[1])
|
x = int(p[1])
|
||||||
y = int(p[2])
|
y = int(p[2])
|
||||||
if abs(x) > 500000 or abs(y) > 500000:
|
if abs(x) > 500000 or abs(y) > 500000:
|
||||||
logging.warning("Holy shit what is up with region file %s !?" % f)
|
logging.warning("Holy shit what is up with region file %s !?" % f)
|
||||||
yield (x, y, path)
|
yield (x, y, os.path.join(self.regiondir, f))
|
||||||
|
|
||||||
class RegionSetWrapper(object):
|
class RegionSetWrapper(object):
|
||||||
"""This is the base class for all "wrappers" of RegionSet objects. A
|
"""This is the base class for all "wrappers" of RegionSet objects. A
|
||||||
|
|||||||
Reference in New Issue
Block a user