Line widths are determined at the rasterization step
Other than lines in a vector image (e.g. SVG), lines in vector data do not have an inherent width. They are lines in a mathematical, not in a graphical sense. I assume that this is also the case for
contours.shp, the output of the contour finding step with
Thus line width is determined by the rasterization step.
(Tiling, when done after the rasterization like here, cannot know about the original vector data and thus cannot control the line widths. It will influence them though by raster image scaling, leading to the aliasing you describe.)
Controlling line width
gdal_rasterize doesn't seem to feature any settings directly related to it except for
-at (burning "all pixels touched by lines or polygons [...], not just those on the line render path"), I assume that it always uses a line width of one pixel.
So we cannot control line width directly.
But even if we could, setting it to sub-pixel values wouldn't do us much good: One cannot color half a pixel. And even if
gdal_rasterize was clever and would do some antialiasing, mixing the original image color/value with the burn color/value, the raster image scaling in the following tiling step would still introduce the aliasing you describe.
I hope we can avoid that effect indirectly when taking away from the tiling step the need to up-scale at all by providing an image already in the correct pixel-per-cartographic-unit resolution to
gdal2tiles.py. (As you probably work in Mercator projection, the cartographic unit will be neither meters nor degrees, but this doesn't have to concern us.)
Off course, if we just take the result from
gdal_rasterize and scale it ourselves, we haven't won anything, as we'd introduce the aliasing ourselves. Rather, we have to burn the contours into a higher-resolution image right at the rasterization step.
gdal_rasterize, when given an existing file as output file, will just modify values (colors) of affected pixels and will not change the size/resolution of that pre-existing image. Thus I don't think the
-tr option suggested by fluidmotion or
-ts option would have any effect. (I haven't tried, though.)
Thus I suggest you either
Choosing the right resolution
The area covered by a tile of zoom level
N will be covered by 4 (
2 x 2) tiles of zoom level
N+1. So for each increment of the zoom-level you have to double the resolution for both, x and y direction.