def checkStartEnd(args, mult, tile): "Checks to see if start and end values are valid for a region." (rows, cols) = getDatasetDims(args.region) (minTileRows, minTileCols) = args.start (maxTileRows, maxTileCols) = args.end (tileRows, tileCols) = tile numRowTiles = int((rows*mult+tileRows-1)/tileRows) numColTiles = int((cols*mult+tileCols-1)/tileCols) # maxTileRows and maxTileCols default to 0 meaning do everything if (maxTileRows == 0 or maxTileRows > numRowTiles): if (maxTileRows > numRowTiles): tilelogger.warning("maxTileRows greater than numRowTiles, setting to %d" % numRowTiles) maxTileRows = numRowTiles if (minTileRows > maxTileRows): tilelogger.warning("minTileRows less than maxTileRows, setting to %d" % maxTileRows) minTileRows = maxTileRows if (maxTileCols == 0 or maxTileCols > numColTiles): if (maxTileCols > numColTiles): tilelogger.warning("maxTileCols greater than numColTiles, setting to %d" % numColTiles) maxTileCols = numColTiles if (minTileCols > maxTileCols): tilelogger.warning("minTileCols less than maxTileCols, setting to %d" % maxTileCols) minTileCols = maxTileCols return (minTileRows, minTileCols, maxTileRows, maxTileCols)
def checkTile(args, mult): "Checks to see if a tile dimension is too big for a region." oldtilex, oldtiley = args.tile rows, cols = getDatasetDims(args.region) maxRows = int(rows * mult) maxCols = int(cols * mult) tilex = min(oldtilex, maxRows) tiley = min(oldtiley, maxCols) if (tilex != oldtilex or tiley != oldtiley): tilelogger.warning("Tile size of %d, %d for region %s is too large -- changed to %d, %d" % (oldtilex, oldtiley, args.region, tilex, tiley)) args.tile = (tilex, tiley) return (tilex, tiley)
def processTile(args, tileRowIndex, tileColIndex): "Actually process a tile." tileShape = args.tile mult = args.mult curtime = time() (lcds, elevds) = getDataset(args.region) (rows, cols) = getDatasetDims(args.region) (elevmin, elevmax) = getDatasetElevs(args.region) if (args.doTrim): trimElev = elevmin else: trimElev = 0 maxRows = int(rows*mult) maxCols = int(cols*mult) baseOffset, baseSize = getTileOffsetSize(tileRowIndex, tileColIndex, tileShape, maxRows, maxCols) idtOffset, idtSize = getTileOffsetSize(tileRowIndex, tileColIndex, tileShape, maxRows, maxCols, idtPad=tileShape[0]+tileShape[1]) tilelogger.info("Generating tile (%d, %d) with dimensions (%d, %d) and offset (%d, %d)..." % (tileRowIndex, tileColIndex, baseSize[0], baseSize[1], baseOffset[0], baseOffset[1])) baseShape = (baseSize[1], baseSize[0]) baseArray = getLatLongArray(lcds, baseOffset, baseSize, mult) #idtShape = (idtSize[1], idtSize[0]) #idtArray = getLatLongArray(lcds, idtOffset, idtSize, mult) # these points are scaled coordinates idtUL = getLatLong(lcds, int(idtOffset[0]/mult), int(idtOffset[1]/mult)) idtLR = getLatLong(lcds, int((idtOffset[0]+idtSize[0])/mult), int((idtOffset[1]+idtSize[1])/mult)) # nodata for landcover is equal to 11 lcImageArray = getImageArray(lcds, (idtUL, idtLR), baseArray, nodata=11, majority=True) lcImageArray.resize(baseShape) # elevation array elevImageArray = getImageArray(elevds, (idtUL, idtLR), baseArray, args.vscale, trim=trimElev) elevImageArray.resize(baseShape) # TODO: go through the arrays for some special transmogrification # first idea: bathymetry depthOffset, depthSize = getTileOffsetSize(tileRowIndex, tileColIndex, tileShape, maxRows, maxCols, idtPad=args.maxdepth) depthShape = (depthSize[1], depthSize[0]) depthArray = getLatLongArray(lcds, depthOffset, depthSize, mult) depthUL = getLatLong(lcds, int(depthOffset[0]/mult), int(depthOffset[1]/mult)) depthLR = getLatLong(lcds, int((depthOffset[0]+depthSize[0])/mult), int((depthOffset[1]+depthSize[1])/mult)) bigImageArray = getImageArray(lcds, (depthUL, depthLR), depthArray, majority=True) bigImageArray.resize(depthShape) bathyImageArray = getBathymetry(args, lcImageArray, bigImageArray, baseOffset, depthOffset) # second idea: crust crustImageArray = getCrust(bathyImageArray, baseArray) crustImageArray.resize(baseShape) # now we do what we do in processImage localmax = 0 spawnx = 10 spawnz = 10 for tilex, tilez in product(xrange(baseSize[0]), xrange(baseSize[1])): lcval = int(lcImageArray[tilez,tilex]) elevval = int(elevImageArray[tilez,tilex]) bathyval = int(bathyImageArray[tilez,tilex]) crustval = int(crustImageArray[tilez,tilex]) real_x = baseOffset[0] + tilex real_z = baseOffset[1] + tilez if (elevval < 0): print "OMG elevval %d is less than zero" % (elevval) if (elevval > maxelev): tilelogger.warning('Elevation %d exceeds maximum elevation (%d)' % (elevval, maxelev)) elevval = maxelev if (elevval > localmax): localmax = elevval spawnx = real_x spawnz = real_z processTerrain([(lcval, real_x, real_z, elevval, bathyval, crustval)]) tilelogger.info('... done with (%d, %d) in %f seconds!' % (tileRowIndex, tileColIndex, (time()-curtime))) return (spawnx, spawnz, localmax)
def main(argv): "The main portion of the script." default_scale = 6 default_vscale = 6 default_sealevel = 32 default_maxdepth = 16 default_slope = 1 default_tile = [256, 256] default_start = [0, 0] default_end = [0, 0] default_processes = cpu_count() parser = ArgumentParser(description='Generate images for BuildWorld.js from USGS datasets.') parser.add_argument('--region', nargs='?', type=checkDataset, help='a region to be processed (leave blank for list of regions)') parser.add_argument('--processes', nargs=1, default=default_processes, type=int, help="number of processes to spawn (default %d)" % default_processes) parser.add_argument('--scale', nargs=1, default=default_scale, type=int, help="horizontal scale factor (default %d)" % default_scale) parser.add_argument('--vscale', nargs=1, default=default_vscale, type=int, help="vertical scale factor (default %d)" % default_vscale) parser.add_argument('--sealevel', nargs=1, default=default_sealevel, type=mcarray.checkSealevel, help="maximum depth (default %d)" % default_sealevel) parser.add_argument('--maxdepth', nargs=1, default=default_maxdepth, type=bathy.checkMaxDepth, help="maximum depth (default %d)" % default_maxdepth) parser.add_argument('--slope', nargs=1, default=default_slope, type=bathy.checkSlope, help="underwater slope factor (default %d)" % default_slope) parser.add_argument('--tile', nargs=2, default=default_tile, type=int, help="tile size in tuple form (default %s)" % (default_tile,)) parser.add_argument('--start', nargs=2, default=default_start, type=int, help="start tile in tuple form (default %s)" % (default_start,)) parser.add_argument('--end', nargs=2, default=default_end, type=int, help="end tile in tuple form (default %s)" % (default_end,)) parser.add_argument('--disable-stats', action='store_false', dest='doStats', default=True, help="disables stats generation when not necessary") parser.add_argument('--disable-ore', action='store_false', dest='doOre', default=True, help="disables ore generation when not necessary") parser.add_argument('--trim', action='store_true', dest='doTrim', default=False, help="trim all space between minimum elevation and sea level") args = parser.parse_args() # list regions if requested if (args.region == None): listDatasets(dsDict) return 0 # set up all the values rows, cols = getDatasetDims(args.region) processes = checkProcesses(args) (scale, mult) = checkScale(args) vscale = checkVScale(args) tileShape = checkTile(args, mult) (tileRows, tileCols) = tileShape (minTileRows, minTileCols, maxTileRows, maxTileCols) = checkStartEnd(args, mult, tileShape) args.nodata = getDatasetNodata(args.region) print "Processing region %s of size (%d, %d) with %d processes..." % (args.region, rows, cols, processes) # createArrays should: # create the shared memory arrays like initWorld minX = 0 minZ = 0 maxX = int(rows*mult) maxZ = int(cols*mult) mcarray.createArrays(minX, minZ, maxX, maxZ, args.sealevel, args.processes) # build crust tree for whole map crust.makeCrustIDT(args) # process those tiles peaks = processTiles(args, minTileRows, maxTileRows, minTileCols, maxTileCols, processes) print "... tiles completed: total array of %d tiles was %d x %d" % ((maxTileRows-minTileRows)*(maxTileCols-minTileCols), int(rows*mult), int(cols*mult)) # per-tile peaks here # ... consider doing something nice on all the peaks? peak = sorted(peaks, key=lambda point: point[2], reverse=True)[0] # where's that ore? if (args.doOre): ore.placeOre() # place the safehouse at the peak (adjust it) building.building(peak[0], peak[1], peak[2]-1, 7, 9, 8, 1) print "Consider setting spawn point to %d, %d, %d" % (peak[0], peak[2]+1, peak[1]) # save arrays arraydir = os.path.join("Arrays", args.region) mcarray.saveArrays(arraydir, processes) # print statistics if (args.doStats): terrain.printStatistics() tree.printStatistics() if (args.doOre): ore.printStatistics()
def makeCrustIDT(args): rows, cols = getDatasetDims(args.region) lcds, elevds = getDataset(args.region) global crustIDT crustCoordsList = [] crustValuesList = [] crustlogger.info("making Crust IDT") # trying ten percent since one seemed too lame worldLatLong = getLatLongArray(lcds, (0, 0), (rows, cols), 1) crustCoordsList = [worldLatLong[randint(0,rows-1)*cols+randint(0,cols-1)] for elem in xrange(int(rows*cols*0.01))] crustValuesList = [uniform(1,5) for elem in crustCoordsList] crustIDT = Invdisttree(array(crustCoordsList), array(crustValuesList))