Add options to specify a custom major and minor interval in the scale(s).
This commit is contained in:
parent
5ce7ff4bce
commit
a6eed3a1ed
@ -152,6 +152,10 @@ TileGenerator::TileGenerator():
|
|||||||
m_scaleFactor(1),
|
m_scaleFactor(1),
|
||||||
m_sqliteCacheWorldRow(false),
|
m_sqliteCacheWorldRow(false),
|
||||||
m_chunkSize(0),
|
m_chunkSize(0),
|
||||||
|
m_sideScaleMajor(0),
|
||||||
|
m_sideScaleMinor(0),
|
||||||
|
m_heightScaleMajor(0),
|
||||||
|
m_heightScaleMinor(0),
|
||||||
m_image(0),
|
m_image(0),
|
||||||
m_xMin(INT_MAX/16-1),
|
m_xMin(INT_MAX/16-1),
|
||||||
m_xMax(INT_MIN/16+1),
|
m_xMax(INT_MIN/16+1),
|
||||||
@ -319,6 +323,18 @@ void TileGenerator::setDrawHeightScale(int scale)
|
|||||||
m_drawScale = (scale & DRAWHEIGHTSCALE_MASK) | (m_drawScale & DRAWSCALE_MASK & ((~scale & DRAWHEIGHTSCALE_MASK) >> 4));
|
m_drawScale = (scale & DRAWHEIGHTSCALE_MASK) | (m_drawScale & DRAWSCALE_MASK & ((~scale & DRAWHEIGHTSCALE_MASK) >> 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TileGenerator::setSideScaleInterval(int major, int minor)
|
||||||
|
{
|
||||||
|
m_sideScaleMajor = major;
|
||||||
|
m_sideScaleMinor = minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TileGenerator::setHeightScaleInterval(int major, int minor)
|
||||||
|
{
|
||||||
|
m_heightScaleMajor = major;
|
||||||
|
m_heightScaleMinor = minor;
|
||||||
|
}
|
||||||
|
|
||||||
void TileGenerator::setDrawAlpha(bool drawAlpha)
|
void TileGenerator::setDrawAlpha(bool drawAlpha)
|
||||||
{
|
{
|
||||||
m_drawAlpha = drawAlpha;
|
m_drawAlpha = drawAlpha;
|
||||||
@ -1649,40 +1665,82 @@ void TileGenerator::renderScale()
|
|||||||
{
|
{
|
||||||
int color = m_scaleColor.to_libgd();
|
int color = m_scaleColor.to_libgd();
|
||||||
if ((m_drawScale & DRAWSCALE_LEFT) && (m_drawScale & DRAWSCALE_TOP)) {
|
if ((m_drawScale & DRAWSCALE_LEFT) && (m_drawScale & DRAWSCALE_TOP)) {
|
||||||
gdImageString(m_image, gdFontGetMediumBold(), 24, 0, reinterpret_cast<unsigned char *>(const_cast<char *>("X")), color);
|
gdImageString(m_image, gdFontGetMediumBold(), borderLeft() - 26, 0, reinterpret_cast<unsigned char *>(const_cast<char *>("X")), color);
|
||||||
gdImageString(m_image, gdFontGetMediumBold(), 2, 24, reinterpret_cast<unsigned char *>(const_cast<char *>("Z")), color);
|
gdImageString(m_image, gdFontGetMediumBold(), 2, borderTop() - 26, reinterpret_cast<unsigned char *>(const_cast<char *>("Z")), color);
|
||||||
}
|
}
|
||||||
|
int major = m_sideScaleMajor ? m_sideScaleMajor : 4 * 16 * m_scaleFactor;
|
||||||
|
int minor = m_sideScaleMinor;
|
||||||
|
|
||||||
string scaleText;
|
string scaleText;
|
||||||
|
|
||||||
if ((m_drawScale & DRAWSCALE_TOP)) {
|
if ((m_drawScale & DRAWSCALE_TOP)) {
|
||||||
for (int i = (m_xMin / 4) * 4; i <= m_xMax; i += 4 * m_scaleFactor) {
|
int start;
|
||||||
stringstream buf1, buf2;
|
int extra_left = borderLeft() ? 0 : major;
|
||||||
buf1 << i * 16;
|
int extra_right = borderRight() ? 0 : major;
|
||||||
buf2 << "(" << i << ")";
|
if (m_xMin >= 0)
|
||||||
int xPos = worldX2ImageX(i * 16);
|
start = (m_xMin * 16 + m_mapXStartNodeOffset - 1 + major - 1 - extra_left) / major * major;
|
||||||
|
else
|
||||||
|
start = (m_xMin * 16 + m_mapXStartNodeOffset - 1 - extra_left) / major * major;
|
||||||
|
for (int i = start; i <= (m_xMax + 1) * 16 + m_mapXEndNodeOffset + extra_right; i += major) {
|
||||||
|
stringstream buf;
|
||||||
|
buf << i;
|
||||||
|
int xPos = worldX2ImageX(i);
|
||||||
|
|
||||||
scaleText = buf1.str();
|
scaleText = buf.str();
|
||||||
gdImageString(m_image, gdFontGetMediumBold(), xPos + 2, 0, reinterpret_cast<unsigned char *>(const_cast<char *>(scaleText.c_str())), color);
|
gdImageString(m_image, gdFontGetMediumBold(), xPos + 2, 0, reinterpret_cast<unsigned char *>(const_cast<char *>(scaleText.c_str())), color);
|
||||||
scaleText = buf2.str();
|
if ((major % 16) == 0) {
|
||||||
gdImageString(m_image, gdFontGetTiny(), xPos + 2, 16, reinterpret_cast<unsigned char *>(const_cast<char *>(scaleText.c_str())), color);
|
buf.str("");
|
||||||
|
buf << "(" << i / 16 << ")";
|
||||||
|
scaleText = buf.str();
|
||||||
|
gdImageString(m_image, gdFontGetTiny(), xPos + 2, 16, reinterpret_cast<unsigned char *>(const_cast<char *>(scaleText.c_str())), color);
|
||||||
|
}
|
||||||
gdImageLine(m_image, xPos, 0, xPos, borderTop() - 1, color);
|
gdImageLine(m_image, xPos, 0, xPos, borderTop() - 1, color);
|
||||||
}
|
}
|
||||||
|
if (minor) {
|
||||||
|
if (m_xMin >= 0)
|
||||||
|
start = (m_xMin * 16 + m_mapXStartNodeOffset + minor - 2) / minor * minor;
|
||||||
|
else
|
||||||
|
start = (m_xMin * 16 + m_mapXStartNodeOffset - 1) / minor * minor;
|
||||||
|
for (int i = start; i <= (m_xMax + 1) * 16 + m_mapXEndNodeOffset; i += minor) {
|
||||||
|
int xPos = worldX2ImageX(i);
|
||||||
|
gdImageLine(m_image, xPos, borderTop() - 5, xPos, borderTop() - 1, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_drawScale & DRAWSCALE_LEFT)) {
|
if ((m_drawScale & DRAWSCALE_LEFT)) {
|
||||||
for (int i = (m_zMax / 4) * 4; i >= m_zMin; i -= 4 * m_scaleFactor) {
|
int start;
|
||||||
stringstream buf1, buf2;
|
int extra_top = borderTop() ? 0 : major;
|
||||||
buf1 << i * 16;
|
int extra_bottom = borderBottom() ? 0 : major;
|
||||||
buf2 << "(" << i << ")";
|
if (m_zMax >= 0)
|
||||||
int yPos = worldZ2ImageY(i * 16);
|
start = ((m_zMax + 1) * 16 - m_mapYStartNodeOffset + extra_top) / major * major;
|
||||||
|
else
|
||||||
|
start = ((m_zMax + 1) * 16 - m_mapYStartNodeOffset - major + 1 + extra_top) / major * major;
|
||||||
|
for (int i = start; i >= m_zMin * 16 - m_mapYEndNodeOffset - 1 - extra_bottom; i -= major) {
|
||||||
|
stringstream buf;
|
||||||
|
buf << i;
|
||||||
|
int yPos = worldZ2ImageY(i);
|
||||||
|
|
||||||
scaleText = buf1.str();
|
scaleText = buf.str();
|
||||||
gdImageString(m_image, gdFontGetMediumBold(), 2, yPos, reinterpret_cast<unsigned char *>(const_cast<char *>(scaleText.c_str())), color);
|
gdImageString(m_image, gdFontGetMediumBold(), 2, yPos, reinterpret_cast<unsigned char *>(const_cast<char *>(scaleText.c_str())), color);
|
||||||
scaleText = buf2.str();
|
if ((major % 16) == 0) {
|
||||||
gdImageString(m_image, gdFontGetTiny(), 2, yPos-10, reinterpret_cast<unsigned char *>(const_cast<char *>(scaleText.c_str())), color);
|
buf.str("");
|
||||||
|
buf << "(" << i / 16 << ")";
|
||||||
|
scaleText = buf.str();
|
||||||
|
gdImageString(m_image, gdFontGetTiny(), 2, yPos-10, reinterpret_cast<unsigned char *>(const_cast<char *>(scaleText.c_str())), color);
|
||||||
|
}
|
||||||
gdImageLine(m_image, 0, yPos, borderLeft() - 1, yPos, color);
|
gdImageLine(m_image, 0, yPos, borderLeft() - 1, yPos, color);
|
||||||
}
|
}
|
||||||
|
if (minor) {
|
||||||
|
if (m_zMax >= 0)
|
||||||
|
start = ((m_zMax + 1) * 16 - m_mapYStartNodeOffset) / minor * minor;
|
||||||
|
else
|
||||||
|
start = ((m_zMax + 1) * 16 - m_mapYStartNodeOffset - minor + 1) / minor * minor;
|
||||||
|
for (int i = start; i >= m_zMin * 16 - m_mapYEndNodeOffset - 1; i -= minor) {
|
||||||
|
int yPos = worldZ2ImageY(i);
|
||||||
|
gdImageLine(m_image, borderLeft() - 5, yPos, borderLeft() - 1, yPos, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DRAWSCALE_RIGHT and DRAWSCALE_BOTTOM not implemented - getting the text positioned right seems not trivial (??)
|
// DRAWSCALE_RIGHT and DRAWSCALE_BOTTOM not implemented - getting the text positioned right seems not trivial (??)
|
||||||
@ -1700,11 +1758,18 @@ void TileGenerator::renderHeightScale()
|
|||||||
if (height_step < 1.0 / 16) {
|
if (height_step < 1.0 / 16) {
|
||||||
height_step = 1.0 / 16;
|
height_step = 1.0 / 16;
|
||||||
}
|
}
|
||||||
double number_step = 64;
|
double major;
|
||||||
while (number_step / height_step < 48)
|
int minor = m_heightScaleMinor;
|
||||||
number_step *= 2;
|
if (m_heightScaleMajor) {
|
||||||
while (number_step / height_step > 96)
|
major = m_heightScaleMajor;
|
||||||
number_step /= 2;
|
}
|
||||||
|
else {
|
||||||
|
major = 64;
|
||||||
|
while (major / height_step / 64 < 0.75)
|
||||||
|
major *= 2;
|
||||||
|
while (major / height_step / 64 > 1.5)
|
||||||
|
major /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
double height = height_min;
|
double height = height_min;
|
||||||
for (int x = 0; height < height_limit; x++, height += height_step) {
|
for (int x = 0; height < height_limit; x++, height += height_step) {
|
||||||
@ -1712,21 +1777,27 @@ void TileGenerator::renderHeightScale()
|
|||||||
gdImageLine(m_image, xBorderOffset + x, yBorderOffset + 8, xBorderOffset + x, yBorderOffset + borderBottom() - 20, color.to_libgd());
|
gdImageLine(m_image, xBorderOffset + x, yBorderOffset + 8, xBorderOffset + x, yBorderOffset + borderBottom() - 20, color.to_libgd());
|
||||||
|
|
||||||
int iheight = int(height + (height > 0 ? 0.5 : -0.5));
|
int iheight = int(height + (height > 0 ? 0.5 : -0.5));
|
||||||
int iheight64 = int(iheight / number_step + (height > 0 ? 0.5 : -0.5)) * number_step;
|
int iheightMaj = int(iheight / major + (height > 0 ? 0.5 : -0.5)) * major;
|
||||||
if (fabs(height - iheight64) <= height_step / 2 && (height - iheight64) > -height_step / 2) {
|
if (fabs(height - iheightMaj) <= height_step / 2 && (height - iheightMaj) > -height_step / 2) {
|
||||||
if (iheight64 / int(number_step) % 2 == 1 && fabs(height) > 9999 && number_step / height_step < 56) {
|
if (iheightMaj / int(major) % 2 == 1 && fabs(height) > 9999 && major / height_step < 56) {
|
||||||
// Maybe not enough room for the number. Draw a tick mark instead
|
// Maybe not enough room for the number. Draw a tick mark instead
|
||||||
gdImageLine(m_image, xBorderOffset + x, yBorderOffset + borderBottom() - 19, xBorderOffset + x, yBorderOffset + borderBottom() - 16, scaleColor);
|
gdImageLine(m_image, xBorderOffset + x, yBorderOffset + borderBottom() - 19, xBorderOffset + x, yBorderOffset + borderBottom() - 16, scaleColor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
stringstream buf;
|
stringstream buf;
|
||||||
buf << iheight64;
|
buf << iheightMaj;
|
||||||
string scaleText = buf.str();
|
string scaleText = buf.str();
|
||||||
gdImageString(m_image, gdFontGetMediumBold(), xBorderOffset + x + 2, yBorderOffset + borderBottom() - 16,
|
gdImageString(m_image, gdFontGetMediumBold(), xBorderOffset + x + 2, yBorderOffset + borderBottom() - 16,
|
||||||
reinterpret_cast<unsigned char *>(const_cast<char *>(scaleText.c_str())), scaleColor);
|
reinterpret_cast<unsigned char *>(const_cast<char *>(scaleText.c_str())), scaleColor);
|
||||||
gdImageLine(m_image, xBorderOffset + x, yBorderOffset + borderBottom() - 19, xBorderOffset + x, yBorderOffset + borderBottom() - 1, scaleColor);
|
gdImageLine(m_image, xBorderOffset + x, yBorderOffset + borderBottom() - 19, xBorderOffset + x, yBorderOffset + borderBottom() - 1, scaleColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (minor) {
|
||||||
|
int iheightMin = int(iheight / minor + (height > 0 ? 0.5 : -0.5)) * minor;
|
||||||
|
if (fabs(height - iheightMin) <= height_step / 2 && (height - iheightMin) > -height_step / 2) {
|
||||||
|
gdImageLine(m_image, xBorderOffset + x, yBorderOffset + borderBottom() - 19, xBorderOffset + x, yBorderOffset + borderBottom() - 16, scaleColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +123,8 @@ public:
|
|||||||
void setDrawPlayers(bool drawPlayers);
|
void setDrawPlayers(bool drawPlayers);
|
||||||
void setDrawScale(int scale);
|
void setDrawScale(int scale);
|
||||||
void setDrawHeightScale(int scale);
|
void setDrawHeightScale(int scale);
|
||||||
|
void setSideScaleInterval(int major, int minor);
|
||||||
|
void setHeightScaleInterval(int major, int minor);
|
||||||
void setDrawAlpha(bool drawAlpha);
|
void setDrawAlpha(bool drawAlpha);
|
||||||
void setDrawAir(bool drawAir);
|
void setDrawAir(bool drawAir);
|
||||||
void drawObject(const DrawObject &object) { m_drawObjects.push_back(object); }
|
void drawObject(const DrawObject &object) { m_drawObjects.push_back(object); }
|
||||||
@ -235,6 +237,10 @@ private:
|
|||||||
int m_scaleFactor;
|
int m_scaleFactor;
|
||||||
bool m_sqliteCacheWorldRow;
|
bool m_sqliteCacheWorldRow;
|
||||||
int m_chunkSize;
|
int m_chunkSize;
|
||||||
|
int m_sideScaleMajor;
|
||||||
|
int m_sideScaleMinor;
|
||||||
|
int m_heightScaleMajor;
|
||||||
|
int m_heightScaleMinor;
|
||||||
|
|
||||||
DB *m_db;
|
DB *m_db;
|
||||||
gdImagePtr m_image;
|
gdImagePtr m_image;
|
||||||
|
59
mapper.cpp
59
mapper.cpp
@ -38,6 +38,7 @@ using namespace std;
|
|||||||
#define OPT_HEIGHTMAPCOLORSFILE 0x8c
|
#define OPT_HEIGHTMAPCOLORSFILE 0x8c
|
||||||
#define OPT_DRAWHEIGHTSCALE 0x8d
|
#define OPT_DRAWHEIGHTSCALE 0x8d
|
||||||
#define OPT_SCALEFACTOR 0x8e
|
#define OPT_SCALEFACTOR 0x8e
|
||||||
|
#define OPT_SCALEINTERVAL 0x8f
|
||||||
|
|
||||||
// Will be replaced with the actual name and location of the executable (if found)
|
// Will be replaced with the actual name and location of the executable (if found)
|
||||||
string executableName = "minetestmapper";
|
string executableName = "minetestmapper";
|
||||||
@ -87,7 +88,9 @@ void usage()
|
|||||||
" --origincolor <color>\n"
|
" --origincolor <color>\n"
|
||||||
" --tilebordercolor <color>\n"
|
" --tilebordercolor <color>\n"
|
||||||
" --drawscale[=left,top]\n"
|
" --drawscale[=left,top]\n"
|
||||||
|
" --sidescale-interval <major>[[,:]<minor>]\n"
|
||||||
" --drawheightscale\n"
|
" --drawheightscale\n"
|
||||||
|
" --heightscale-interval <major>[[,:]<minor>]\n"
|
||||||
" --drawplayers\n"
|
" --drawplayers\n"
|
||||||
" --draworigin\n"
|
" --draworigin\n"
|
||||||
" --drawalpha[=cumulative|cumulative-darken|average|none]\n"
|
" --drawalpha[=cumulative|cumulative-darken|average|none]\n"
|
||||||
@ -555,7 +558,9 @@ int main(int argc, char *argv[])
|
|||||||
{"draworigin", no_argument, 0, 'R'},
|
{"draworigin", no_argument, 0, 'R'},
|
||||||
{"drawplayers", no_argument, 0, 'P'},
|
{"drawplayers", no_argument, 0, 'P'},
|
||||||
{"drawscale", optional_argument, 0, 'S'},
|
{"drawscale", optional_argument, 0, 'S'},
|
||||||
|
{"sidescale-interval", required_argument, 0, OPT_SCALEINTERVAL},
|
||||||
{"drawheightscale", no_argument, 0, OPT_DRAWHEIGHTSCALE},
|
{"drawheightscale", no_argument, 0, OPT_DRAWHEIGHTSCALE},
|
||||||
|
{"heightscale-interval", required_argument, 0, OPT_SCALEINTERVAL},
|
||||||
{"drawalpha", optional_argument, 0, 'e'},
|
{"drawalpha", optional_argument, 0, 'e'},
|
||||||
{"drawair", no_argument, 0, OPT_DRAWAIR},
|
{"drawair", no_argument, 0, OPT_DRAWAIR},
|
||||||
{"drawpoint", required_argument, 0, OPT_DRAW_OBJECT},
|
{"drawpoint", required_argument, 0, OPT_DRAW_OBJECT},
|
||||||
@ -733,6 +738,60 @@ int main(int argc, char *argv[])
|
|||||||
case OPT_DRAWHEIGHTSCALE :
|
case OPT_DRAWHEIGHTSCALE :
|
||||||
generator.setDrawHeightScale(DRAWHEIGHTSCALE_BOTTOM);
|
generator.setDrawHeightScale(DRAWHEIGHTSCALE_BOTTOM);
|
||||||
break;
|
break;
|
||||||
|
case OPT_SCALEINTERVAL: {
|
||||||
|
istringstream arg;
|
||||||
|
arg.str(optarg);
|
||||||
|
int major;
|
||||||
|
int minor;
|
||||||
|
char sep;
|
||||||
|
arg >> major;
|
||||||
|
if (major < 0 || !isdigit(*optarg) || arg.fail()) {
|
||||||
|
std::cerr << "Invalid parameter to '" << long_options[option_index].name
|
||||||
|
<< "': '" << optarg << "' (expected: <major>[,<minor>]" << std::endl;
|
||||||
|
usage();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
arg >> std::ws >> sep >> std::ws;
|
||||||
|
if (!arg.fail()) {
|
||||||
|
if ((sep != ',' && sep != ':') || !isdigit(arg.peek())) {
|
||||||
|
std::cerr << "Invalid parameter to '" << long_options[option_index].name
|
||||||
|
<< "': '" << optarg << "' (expected: <major>[,<minor>]" << std::endl;
|
||||||
|
usage();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
arg >> minor;
|
||||||
|
if (minor < 0) {
|
||||||
|
std::cerr << "Invalid parameter to '" << long_options[option_index].name
|
||||||
|
<< "': '" << optarg << "' (expected: <major>[,<minor>]" << std::endl;
|
||||||
|
usage();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
minor = 0;
|
||||||
|
}
|
||||||
|
if (minor && sep == ':') {
|
||||||
|
if (major % minor) {
|
||||||
|
std::cerr << long_options[option_index].name << ": Cannot divide major interval in "
|
||||||
|
<< minor << " subintervals (not divisible)" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
minor = major / minor;
|
||||||
|
}
|
||||||
|
if ((minor % major) == 0)
|
||||||
|
minor = 0;
|
||||||
|
if (long_options[option_index].name[0] == 's') {
|
||||||
|
generator.setSideScaleInterval(major, minor);
|
||||||
|
}
|
||||||
|
else if (long_options[option_index].name[0] == 'h') {
|
||||||
|
generator.setHeightScaleInterval(major, minor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << "Internal error: option " << long_options[option_index].name << " not handled" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
if (optarg && isdigit(optarg[0]) && optarg[1] == '\0') {
|
if (optarg && isdigit(optarg[0]) && optarg[1] == '\0') {
|
||||||
if (optarg[0] == '0')
|
if (optarg[0] == '0')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user