Ejemplo n.º 1
0
bool validateParamsFull(const string& inputpath, const string& outputpath, const string& imgpath, const MapParams& mp, int threads, const string& chunklist, const string& regionlist, bool expand, const string& htmlpath)
{
	// -c and -x are not allowed for full renders
	if (!chunklist.empty() || !regionlist.empty() || expand)
	{
		cerr << "-c, -r, -x not allowed for full renders" << endl;
		return false;
	}

	// B and T must be within range (upper limits aren't really necessary and can be adjusted if
	//  someone really wants gigantic tile images for some reason)
	if (!mp.valid())
	{
		cerr << "-B must be in range 2-16; -T must be in range 1-16" << endl;
		return false;
	}

	// baseZoom must be within range, or -1 (omitted)
	if (!mp.validZoom() && mp.baseZoom != -1)
	{
		cerr << "-Z must be in range 0-30, or may be omitted to set automatically" << endl;
		return false;
	}

	// MINY/MAXY must describe a valid range
	if (!mp.validYRange())
	{
		cerr << "-y and -Y, if used, must be in range 0-255, and -y must be <= -Y" << endl;
		return false;
	}

	// must have a sensible number of threads (upper limit is arbitrary, but you'd need a truly
	//  insanely large map to see any benefit to having that many...)
	if (threads < 1 || threads > 64)
	{
		cerr << "-h must be in range 1-64" << endl;
		return false;
	}

	// the various paths must be non-empty
	if (inputpath.empty() || outputpath.empty())
	{
		cerr << "must provide both input (-i) and output (-o) paths" << endl;
		return false;
	}
	if (imgpath.empty())
	{
		cerr << "must provide non-empty image path, or omit -g to use \".\"" << endl;
		return false;
	}
	if (htmlpath.empty())
	{
		cerr << "must provide non-empty HTML path, or omit -m to use \".\"" << endl;
		return false;
	}

	return true;
}
Ejemplo n.º 2
0
bool validateParamsTest(const string& inputpath, const string& outputpath, const string& imgpath, const MapParams& mp, int threads, const string& chunklist, const string& regionlist, bool expand, const string& htmlpath, int testworldsize)
{
	// -i, -o, -c, -r, -x, -m are not allowed
	if (!inputpath.empty() || !outputpath.empty() || !chunklist.empty() || !regionlist.empty() || expand || htmlpath != ".")
	{
		cerr << "-i, -o, -c, -r, -x, -m not allowed for test worlds" << endl;
		return false;
	}

	// B and T must be within range (upper limits aren't really necessary and can be adjusted if
	//  someone really wants gigantic tile images for some reason)
	if (!mp.valid())
	{
		cerr << "-B must be in range 2-16; -T must be in range 1-16" << endl;
		return false;
	}

	// baseZoom must be within range, or -1 (omitted)
	if (!mp.validZoom() && mp.baseZoom != -1)
	{
		cerr << "-Z must be in range 0-30, or may be omitted to set automatically" << endl;
		return false;
	}
	
	// MINY/MAXY must describe a valid range
	if (!mp.validYRange())
	{
		cerr << "-y and -Y, if used, must be in range 0-255, and -y must be <= -Y" << endl;
		return false;
	}

	// must have a sensible number of threads (upper limit is arbitrary, but you'd need a truly
	//  insanely large map to see any benefit to having that many...)
	if (threads < 1 || threads > 64)
	{
		cerr << "-h must be in range 1-64" << endl;
		return false;
	}

	// image path must be non-empty
	if (imgpath.empty())
	{
		cerr << "must provide non-empty image path, or omit -g to use \".\"" << endl;
		return false;
	}

	// test world size must be positive
	if (testworldsize < 0)
	{
		cerr << "testworld size must be positive" << endl;
		return false;
	}

	return true;
}
Ejemplo n.º 3
0
// see if there's enough available memory for some number of tile images
// (...by just attempting to allocate it!)
//!!!!!!! better way to do this?   maybe allow user to specify max memory for
//         ThreadOutputCache instead?
bool memoryAvailable(int tiles, const MapParams& mp)
{
	int64_t imgsize = mp.tileSize() * mp.tileSize();  // in pixels
	try
	{
		RGBAPixel *tempbuf = new RGBAPixel[imgsize * tiles];
		delete[] tempbuf;
	}
	catch (bad_alloc& ba)
	{
		return false;
	}
	return true;
}
Ejemplo n.º 4
0
// warning: slow
void testTileBBoxes(const MapParams& mp)
{
	// check tile bounding boxes for a few tiles
	for (int64_t tx = -5; tx <= 5; tx++)
		for (int64_t ty = -5; ty <= 5; ty++)
		{
			// get computed BBox
			TileIdx ti(tx,ty);
			BBox bbox = ti.getBBox(mp);

			// this is what the box is supposed to be
			int64_t xmin = 64*mp.B*mp.T*tx - 2*mp.B;
			int64_t ymax = 64*mp.B*mp.T*ty + 17*mp.B;
			int64_t xmax = xmin + mp.tileSize();
			int64_t ymin = ymax - mp.tileSize();

			// test pixels
			for (int64_t x = xmin - 15; x <= xmax + 15; x++)
				for (int64_t y = ymin - 15; y <= ymax + 15; y++)
				{
					bool result = bbox.includes(Pixel(x,y));
					bool expected = x >= xmin && x < xmax && y >= ymin && y < ymax;
					if (result != expected)
					{
						cout << "failed tile bounding box test!  " << tx << " " << ty << endl;
						cout << "[" << bbox.topLeft.x << "," << bbox.topLeft.y << "] to [" << bbox.bottomRight.x << "," << bbox.bottomRight.y << "]" << endl;
						cout << "[" << xmin << "," << ymin << "] to [" << xmax << "," << ymax << "]" << endl;
						cout << x << "," << y << endl;
						return;
					}
				}
		}
}
Ejemplo n.º 5
0
// also sets MapParams to values from existing map
bool validateParamsIncremental(const string& inputpath, const string& outputpath, const string& imgpath, MapParams& mp, int threads, const string& chunklist, const string& regionlist, bool expand, const string& htmlpath)
{
	// -B, -T, -Z are not allowed
	if (mp.B != -1 || mp.T != -1 || mp.baseZoom != -1)
	{
		cerr << "-B, -T, -Z not allowed for incremental updates" << endl;
		return false;
	}

	// the various paths must be non-empty
	if (inputpath.empty() || outputpath.empty())
	{
		cerr << "must provide both input (-i) and output (-o) paths" << endl;
		return false;
	}
	if (imgpath.empty())
	{
		cerr << "must provide non-empty image path, or omit -g to use \".\"" << endl;
		return false;
	}
	if (htmlpath.empty())
	{
		cerr << "must provide non-empty HTML path, or omit -m to use \".\"" << endl;
		return false;
	}

	// can't have both chunklist and regionlist
	if (!chunklist.empty() && !regionlist.empty())
	{
		cerr << "only one of -c, -r may be used" << endl;
		return false;
	}

	// if world is in region format, must use regionlist
	if (detectRegionFormat(inputpath) && regionlist.empty())
	{
		cerr << "world is in region format; must use -r, not -c" << endl;
		return false;
	}

	// pigmap.params must be present in output path; read it now
	if (!mp.readFile(outputpath))
	{
		cerr << "can't find pigmap.params in output path" << endl;
		return false;
	}

	// must have a sensible number of threads (upper limit is arbitrary, but you'd need a truly
	//  insanely large map to see any benefit to having that many...)
	if (threads < 1 || threads > 64)
	{
		cerr << "-h must be in range 1-64" << endl;
		return false;
	}

	return true;
}
Ejemplo n.º 6
0
bool expandMap(const string& outputpath)
{
	// read old params
	MapParams mp;
	if (!mp.readFile(outputpath))
	{
		cerr << "pigmap.params missing or corrupt" << endl;
		return false;
	}
	int32_t tileSize = mp.tileSize();

	// to expand a map, the following must be done:
	//  1. the top-left quadrant of the current zoom level 1 needs to be moved to zoom level 2, where
	//     it will become the bottom-right quadrant of the top-left quadrant of the new zoom level 1,
	//     so the top-level file "0.png" and subdirectory "0" must become "0/3.png" and "0/3",
	//     respectively; and similarly for the other three quadrants
	//  2. new zoom level 1 tiles must be created: "0.png" is 3/4 empty, but has a shrunk version of
	//     the old "0.png" (which is the new "0/3.png") in its bottom-right, etc.
	//  3. a new "base.png" must be created from the new zoom level 1 tiles

	// move everything at zoom 1 or higher one level deeper
	// ...first the subdirectories
	renameFile(outputpath + "/0", outputpath + "/old0");
	renameFile(outputpath + "/1", outputpath + "/old1");
	renameFile(outputpath + "/2", outputpath + "/old2");
	renameFile(outputpath + "/3", outputpath + "/old3");
	makePath(outputpath + "/0");
	makePath(outputpath + "/1");
	makePath(outputpath + "/2");
	makePath(outputpath + "/3");
	renameFile(outputpath + "/old0", outputpath + "/0/3");
	renameFile(outputpath + "/old1", outputpath + "/1/2");
	renameFile(outputpath + "/old2", outputpath + "/2/1");
	renameFile(outputpath + "/old3", outputpath + "/3/0");
	// ...now the zoom 1 files
	const char* formatExtensions[] = {".png", ".jpeg"};
	ImageSettings::Format formats[] = {ImageSettings::Format_PNG, ImageSettings::Format_JPEG};
	for (int i = 0; i < 2; ++i) {
		if (ImageSettings::format == formats[i] || ImageSettings::format == ImageSettings::Format_Both)
		{
			const char* format = formatExtensions[i];
			renameFile(outputpath + "/0" + format, outputpath + "/0/3" + format);
			renameFile(outputpath + "/1" + format, outputpath + "/1/2" + format);
			renameFile(outputpath + "/2" + format, outputpath + "/2/1" + format);
			renameFile(outputpath + "/3" + format, outputpath + "/3/0" + format);
		}
	}

	// build the new zoom 1 tiles
	RGBAImage old0img;
	bool used0 = old0img.readPNG(outputpath + "/0/3.png");
	RGBAImage new0img;
	new0img.create(tileSize, tileSize);
	if (used0)
	{
		reduceHalf(new0img, ImageRect(tileSize/2, tileSize/2, tileSize/2, tileSize/2), old0img);
		new0img.writeImage(outputpath + "/0");
	}
	RGBAImage old1img;
	bool used1 = old1img.readPNG(outputpath + "/1/2.png");
	RGBAImage new1img;
	new1img.create(tileSize, tileSize);
	if (used1)
	{
		reduceHalf(new1img, ImageRect(0, tileSize/2, tileSize/2, tileSize/2), old1img);
		new1img.writeImage(outputpath + "/1");
	}
	RGBAImage old2img;
	bool used2 = old2img.readPNG(outputpath + "/2/1.png");
	RGBAImage new2img;
	new2img.create(tileSize, tileSize);
	if (used2)
	{
		reduceHalf(new2img, ImageRect(tileSize/2, 0, tileSize/2, tileSize/2), old2img);
		new2img.writeImage(outputpath + "/2");
	}
	RGBAImage old3img;
	bool used3 = old3img.readPNG(outputpath + "/3/0.png");
	RGBAImage new3img;
	new3img.create(tileSize, tileSize);
	if (used3)
	{
		reduceHalf(new3img, ImageRect(0, 0, tileSize/2, tileSize/2), old3img);
		new3img.writeImage(outputpath + "/3");
	}

	// build the new base tile
	RGBAImage newbase;
	newbase.create(tileSize, tileSize);
	if (used0)
		reduceHalf(newbase, ImageRect(0, 0, tileSize/2, tileSize/2), new0img);
	if (used1)
		reduceHalf(newbase, ImageRect(tileSize/2, 0, tileSize/2, tileSize/2), new1img);
	if (used2)
		reduceHalf(newbase, ImageRect(0, tileSize/2, tileSize/2, tileSize/2), new2img);
	if (used3)
		reduceHalf(newbase, ImageRect(tileSize/2, tileSize/2, tileSize/2, tileSize/2), new3img);
	newbase.writeImage(outputpath + "/base");

	// write new params (with incremented baseZoom)
	mp.baseZoom++;
	mp.writeFile(outputpath);

	// touch all tiles, to prevent browser cache mishaps (since many new tiles will have the same
	//  filename as some old tile, but possibly with an earlier timestamp)
	if (system((string("find ") + outputpath + " -exec touch {} +").c_str()) < 0)
        cerr << "Error changing mtimes. Ignoring..." << endl;

	return true;
}