Merge branch 'master' into POI-Polylines
This commit is contained in:
@@ -14,9 +14,9 @@ before_script:
|
||||
- git clone git://github.com/overviewer/Minecraft-Overviewer-Addons.git ~/mcoa/
|
||||
- wget -N http://s3.amazonaws.com/MinecraftDownload/minecraft.jar -P ~/.minecraft/bin/
|
||||
script:
|
||||
- python overviewer.py ~/mcoa/exmaple ~/test-output --rendermodes=smooth-lighting
|
||||
- python overviewer.py ~/mcoa/exmaple ~/test-output --rendermodes=smooth-lighting -p1
|
||||
notifications:
|
||||
email: false
|
||||
# matrix:
|
||||
# allow_failures:
|
||||
# - python: "3.2"
|
||||
# - python: "3.2"
|
||||
|
||||
@@ -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',\
|
||||
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.',\
|
||||
metavar = '<output>', type = str, dest = 'output', default = "output.png")
|
||||
|
||||
@@ -43,6 +46,9 @@ def main():
|
||||
if not options.zoom_level:
|
||||
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
|
||||
folder, filename = split(options.output)
|
||||
if folder != '' and not exists(folder):
|
||||
@@ -54,32 +60,6 @@ def main():
|
||||
tile_size = (384,384)
|
||||
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
|
||||
path = tileset
|
||||
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?"
|
||||
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
|
||||
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:
|
||||
::
|
||||
|
||||
from observer import ProgressBarObserver()
|
||||
from observer import ProgressBarObserver
|
||||
observer = ProgressBarObserver()
|
||||
|
||||
There are currently three observers available: ``LoggingObserver``,
|
||||
|
||||
@@ -20,9 +20,9 @@ import sys
|
||||
|
||||
# quick version check
|
||||
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:
|
||||
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)
|
||||
|
||||
import os
|
||||
@@ -125,15 +125,15 @@ def main():
|
||||
# This section of main() runs in response to any one-time options we have,
|
||||
# such as -V for version reporting
|
||||
if options.version:
|
||||
print "Minecraft Overviewer %s" % util.findGitVersion(),
|
||||
print "(%s)" % util.findGitHash()[:7]
|
||||
print("Minecraft Overviewer %s" % util.findGitVersion()),
|
||||
print("(%s)" % util.findGitHash()[:7])
|
||||
try:
|
||||
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:
|
||||
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:
|
||||
print "(build info not found)"
|
||||
print("(build info not found)")
|
||||
return 0
|
||||
|
||||
if options.check_terrain:
|
||||
@@ -158,13 +158,13 @@ def main():
|
||||
# first provide an appropriate error for bare-console users
|
||||
# that don't provide any options
|
||||
if util.is_bare_console():
|
||||
print "\n"
|
||||
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 "http://docs.overviewer.org/\n"
|
||||
print "\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("\n")
|
||||
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("http://docs.overviewer.org/\n")
|
||||
print("\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")
|
||||
|
||||
else:
|
||||
# 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
|
||||
# given, and vice versa
|
||||
if options.config and args:
|
||||
print
|
||||
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 "Put something like this in your config file:"
|
||||
print "worlds['myworld'] = %r" % args[0]
|
||||
print "outputdir = %r" % (args[1] if len(args) > 1 else "/path/to/output")
|
||||
print
|
||||
print()
|
||||
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("Put something like this in your config file:")
|
||||
print("worlds['myworld'] = %r" % args[0])
|
||||
print("outputdir = %r" % (args[1] if len(args) > 1 else "/path/to/output"))
|
||||
print()
|
||||
logging.error("Cannot specify both --config AND a world + output directory on the command line.")
|
||||
parser.print_help()
|
||||
return 1
|
||||
@@ -471,16 +471,16 @@ def list_worlds():
|
||||
print
|
||||
worlds = world.get_worlds()
|
||||
if not worlds:
|
||||
print 'No world saves found in the usual place'
|
||||
print('No world saves found in the usual place')
|
||||
return
|
||||
print "Detected saves:"
|
||||
print("Detected saves:")
|
||||
|
||||
# get max length of world name
|
||||
worldNameLen = max([len(str(x)) for x in worlds] + [len("World")])
|
||||
|
||||
formatString = "%-" + str(worldNameLen) + "s | %-8s | %-8s | %-16s | %s "
|
||||
print formatString % ("World", "Size", "Playtime", "Modified", "Path")
|
||||
print formatString % ("-"*worldNameLen, "-"*8, "-"*8, '-'*16, '-'*4)
|
||||
print(formatString % ("World", "Size", "Playtime", "Modified", "Path"))
|
||||
print(formatString % ("-"*worldNameLen, "-"*8, "-"*8, '-'*16, '-'*4))
|
||||
for name, info in sorted(worlds.iteritems()):
|
||||
if isinstance(name, basestring) and name.startswith("World") and len(name) == 6:
|
||||
try:
|
||||
@@ -496,18 +496,18 @@ def list_worlds():
|
||||
playstamp = '%d:%02d' % (playtime / 3600, playtime / 60 % 60)
|
||||
size = "%.2fMB" % (info['SizeOnDisk'] / 1024. / 1024.)
|
||||
path = info['path']
|
||||
print formatString % (name, size, playstamp, timestamp, path)
|
||||
print(formatString % (name, size, playstamp, timestamp, path))
|
||||
|
||||
if __name__ == "__main__":
|
||||
multiprocessing.freeze_support()
|
||||
try:
|
||||
ret = main()
|
||||
util.nice_exit(ret)
|
||||
except textures.TextureException, e:
|
||||
except textures.TextureException as e:
|
||||
# this isn't a "bug", so don't print scary traceback
|
||||
logging.error(str(e))
|
||||
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!
|
||||
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);
|
||||
} /* else above_level_data = 0 */
|
||||
|
||||
/* check connection with same level */
|
||||
same_level_data = check_adjacent_blocks(state, x, y, z, 55);
|
||||
/* check connection with same level (other redstone and trapped chests */
|
||||
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 */
|
||||
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);
|
||||
|
||||
/* 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 ||
|
||||
block == 128 || block == 134 || block == 135 || block == 136) {
|
||||
block == 128 || block == 134 || block == 135 || block == 136 || block == 145 || block == 156) {
|
||||
unsigned int upper_block;
|
||||
|
||||
/* 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);
|
||||
} 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 == 135 || upper_block == 136);
|
||||
upper_block == 135 || upper_block == 136 || upper_block == 156 );
|
||||
if (is_transparent(upper_block)) {
|
||||
skylevel = get_data(state, SKYLIGHT, x, y + upper_counter, z);
|
||||
} else {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,7 @@ import logging
|
||||
import hashlib
|
||||
import time
|
||||
import random
|
||||
import re
|
||||
|
||||
import numpy
|
||||
|
||||
@@ -116,7 +117,7 @@ class World(object):
|
||||
# seem to be any set standard on what dimensions are in each world,
|
||||
# just scan the directory heirarchy to find a directory with .mca
|
||||
# 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?
|
||||
mcas = [x for x in files if x.endswith(".mca")]
|
||||
if mcas:
|
||||
@@ -490,16 +491,16 @@ class RegionSet(object):
|
||||
|
||||
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"):
|
||||
dirpath, f = os.path.split(path)
|
||||
p = f.split(".")
|
||||
x = int(p[1])
|
||||
y = int(p[2])
|
||||
if abs(x) > 500000 or abs(y) > 500000:
|
||||
logging.warning("Holy shit what is up with region file %s !?" % f)
|
||||
yield (x, y, path)
|
||||
for f in os.listdir(self.regiondir):
|
||||
if re.match(r"^r\.-?\d+\.-?\d+\.mca$", f):
|
||||
p = f.split(".")
|
||||
x = int(p[1])
|
||||
y = int(p[2])
|
||||
if abs(x) > 500000 or abs(y) > 500000:
|
||||
logging.warning("Holy shit what is up with region file %s !?" % f)
|
||||
yield (x, y, os.path.join(self.regiondir, f))
|
||||
|
||||
class RegionSetWrapper(object):
|
||||
"""This is the base class for all "wrappers" of RegionSet objects. A
|
||||
|
||||
Reference in New Issue
Block a user