示例#1
0
def determinePaperDimensions(paperSize):
    # Paper sizes in meter
    paperSizes = {
        'A5': {'width': 0.149, 'height': 0.210},
        'A4': {'width': 0.210, 'height': 0.297},
        'A3': {'width': 0.297, 'height': 0.420},
        'A2': {'width': 0.420, 'height': 0.594},
        'A1': {'width': 0.594, 'height': 0.841},
        'A0': {'width': 0.841, 'height': 1.189},
    }

    millimeters = re.match(r'^(\d+\.?\d*) mm [x×] (\d+\.?\d*) mm$', paperSize)
    meters = re.match(r'^(\d+\.?\d*) m [x×] (\d+\.?\d*) m$', paperSize)
    inches = re.match(r'^(\d+\.?\d*) in [x×] (\d+\.?\d*) in$', paperSize)
    if paperSize in paperSizes:
        return paperSizes[paperSize]['width'], paperSizes[paperSize]['height']
    elif millimeters:
        return float(millimeters.group(1)) / 1000, float(millimeters.group(2)) / 1000
    elif meters:
        return float(meters.group(1)), float(meters.group(2))
    elif inches:
        return float(inches.group(1)) * 0.0254, float(inches.group(2)) * 0.0254
    else:
        environment.exitError("The paper size should be one of the values %s or of the form `A mm x B mm`, `A m x B m` or `A in x B in`, but %s was given" % (list(paperSizes.keys()), paperSize))
        return
示例#2
0
def determinePageOverlap(overlap):
    pageOverlapMatch = re.match(r'^(\d+\.?\d*)%$', overlap)

    if not pageOverlapMatch:
        environment.exitError("The page overlap must be a percentage value, like '5%%' or '10.1%%'. %s was given" % (overlap,))
        return

    return float(overlap[:-1]) / 100.0
示例#3
0
def determineBoundingBox(bbox):
    bboxMatch = re.match(r'^(\d+\.?\d*):(\d+\.?\d*):(\d+\.?\d*):(\d+\.?\d*)$', bbox)

    if not bboxMatch:
        environment.exitError("The bounding box must be of the form A:B:C:D with (A, B) the bottom left corner and (C, D) the top right corner. %s was given" % (bbox,))
        return

    return float(bboxMatch.group(1)), float(bboxMatch.group(2)), float(bboxMatch.group(3)), float(bboxMatch.group(4)),
示例#4
0
def determineScale(scale):
    if not scale.strip().startswith('1:'):
        environment.exitError("The scale should be of the form 1:N but %s was given" % (scale,))
        return
    try:
        return float(scale[2:])
    except:
        environment.exitError("The scale should parsable as a floating point number but got %s" % (scale[2:],))
        return
示例#5
0
def determineOrientation(orientation):
    paperOrientations = {
        ORIENTATION_LANDSCAPE,
        ORIENTATION_PORTRAIT,
    }
    if orientation not in paperOrientations:
        environment.exitError("The paper orientation should be one of the values %s but %s was given" % (paperOrientations, orientation))
        return

    return orientation
示例#6
0
def boundingBoxes(bbox, pageOverlap, scale, paperDimensions):
    # The bounding box is in degrees
    # All other distances are in meters

    paperWidth, paperHeight = paperDimensions

    pageWidth = paperWidth * scale
    pageHeight = paperHeight * scale

    mercatorBoundingBox = latitudeLongitudeToWebMercator.forward(bbox)

    averageBboxX = bbox.minx + (bbox.maxx - bbox.minx) / 2
    averageBboxY = bbox.miny + (bbox.maxy - bbox.miny) / 2

    distanceX = haversine((bbox.minx, averageBboxY), (bbox.maxx, averageBboxY))
    distanceY = haversine((averageBboxX, bbox.miny), (averageBboxX, bbox.maxy))

    if distanceX < 1 or distanceY < 1:
        environment.exitError("The horizontal and vertical distance of the bounding box is less than 1 meter. Horizontal distance: %.2f, vertical distance: %.2f." % (distanceX, distanceY))
        return

    mercatorMeterPerRealMeterX = (mercatorBoundingBox.maxx - mercatorBoundingBox.minx) / distanceX
    mercatorMeterPerRealMeterY = (mercatorBoundingBox.maxy - mercatorBoundingBox.miny) / distanceY

    # If the bounding box fits on one page, then do not use padding
    epsilon = 1
    fitsOnOnePageHorizontal = distanceX <= pageWidth + epsilon
    fitsOnOnePageVertical = distanceY <= pageHeight + epsilon

    numPagesHorizontal = 1 if fitsOnOnePageHorizontal else 1 + int(math.ceil((distanceX - pageWidth) / ((1.0 - pageOverlap) * pageWidth)))
    numPagesVertical = 1 if fitsOnOnePageVertical else 1 + int(math.ceil((distanceY - pageHeight) / ((1.0 - pageOverlap) * pageHeight)))

    # Fit the generated pages perfectly 'around' the bounding box
    paddingX = ((numPagesHorizontal * pageWidth - (numPagesHorizontal - 1) * pageOverlap * pageWidth) - distanceX) / 2
    paddingY = ((numPagesVertical * pageHeight - (numPagesVertical - 1) * pageOverlap * pageHeight) - distanceY) / 2

    boundingBoxes = []
    for i in range(numPagesHorizontal):
        for j in range(numPagesVertical):
            topLeft = mercatorBoundingBox.minx + mercatorMeterPerRealMeterX * (- paddingX + i * pageWidth - i * pageOverlap * pageWidth), \
                      mercatorBoundingBox.maxy + mercatorMeterPerRealMeterY * (+ paddingY - j * pageHeight + j * pageOverlap * pageHeight)
            bottomRight = topLeft[0] + mercatorMeterPerRealMeterX * pageWidth, \
                          topLeft[1] - mercatorMeterPerRealMeterY * pageHeight

            tileBoundingBox = latitudeLongitudeToWebMercator.backward(mapnik.Box2d(
                topLeft[0],
                topLeft[1],
                bottomRight[0],
                bottomRight[1],
            ))
            boundingBoxes.append(tileBoundingBox)

    return boundingBoxes