Example #1
0
def makeSVSExchangeFormatFile(exportParams):
    """Generates a SVS export. If multiple time values are specified, the result will contain a WMS URL for each.
    """
    layerInfo = exportParams.layerInfoList[exportParams.animationLayerNumber - 1]

    # Make a set of parameters that excludes the dimension over which animation is to occur.
    baseParams = layerInfo.params.copy()
    if (exportParams.animationDimension != None) and (exportParams.animationDimension in baseParams):
        del baseParams[exportParams.animationDimension]

    baseUrl = wmc_util.parseEndpointString(layerInfo.endpoint, baseParams)

    # Create the export XML file.
    domImpl = xml.dom.minidom.getDOMImplementation()
    doc = domImpl.createDocument(None, "MovieExport", None)
    rootEl = doc.documentElement
    movieEl = doc.createElement("Movie")
    movieEl.setAttribute("framesPerSecond", exportParams.frameRate)
    rootEl.appendChild(movieEl)

    # Add a "wmsURL" for each dimension value.
    if exportParams.animationDimension == None:
        requestUrl = baseUrl
        xml_util.appendElement(doc, movieEl, "wmsURL", baseUrl)
    else:
        for val in exportParams.dimensionValues:
            requestUrl = baseUrl + "&" + urllib.urlencode({exportParams.animationDimension: val})
            log.debug("URL: %s" % (requestUrl));
            xml_util.appendElement(doc, movieEl, "wmsURL", requestUrl)

    # Include the outline URL.
    outlineLayerNumber = exportParams.getOutlineLayerNumber()
    if outlineLayerNumber != None:
        outlineInfo = exportParams.layerInfoList[outlineLayerNumber - 1]
        outlineUrl = wmc_util.parseEndpointString(outlineInfo.endpoint, outlineInfo.params)
        xml_util.appendElement(doc, movieEl, "outlineURL", outlineUrl)

    # Include the legend URL if included in the layer data.
    if layerInfo.legendURL != None:
        log.debug("legendURL %s" % (layerInfo.legendURL))
        xml_util.appendElement(doc, movieEl, "legendURL", layerInfo.legendURL);

    # Include the capabilities URL if included in the layer data.
    if layerInfo.capabilitiesURL != None:
        log.debug("capabilitiesURL %s" % (layerInfo.capabilitiesURL))
        xml_util.appendElement(doc, movieEl, "capabilitiesURL", layerInfo.capabilitiesURL)

    outFile = tempfile.NamedTemporaryFile(prefix=exportParams.fileNamePrefix, suffix=".xml", delete=False,
                                          dir=exportParams.exportDir)
    log.debug("File: %s" % (outFile.name))
    doc.writexml(outFile, addindent="  ", newl="\n", encoding="utf-8")
    outFile.close()

    return ExportResult(True, fileName = os.path.basename(outFile.name))
Example #2
0
def makeWmsDetailsFile(exportParams):
    """Generates a WMS export containing the URLs for the map, capabilities and legend for the current map.
    """

    # Create the export XML file.
    domImpl = xml.dom.minidom.getDOMImplementation()
    doc = domImpl.createDocument(None, "WmsDetails", None)
    rootEl = doc.documentElement

    # Construct a WMS GetMap URL for each layer.
    layerNumber = 1
    for layerInfo in exportParams.layerInfoList:
        wmsURL = wmc_util.parseEndpointString(layerInfo.endpoint, layerInfo.params)
        wmsUrlEl = doc.createElement("wmsURL")
        wmsUrlEl.setAttribute("layer", layerNumber.__str__())
        wmsUrlTextEl = doc.createTextNode(wmsURL)
        wmsUrlEl.appendChild(wmsUrlTextEl)
        rootEl.appendChild(wmsUrlEl)
        layerNumber += 1

    # Include the legend URL if included in the layer data.
    layerInfo = exportParams.layerInfoList[exportParams.animationLayerNumber - 1]
    if layerInfo.legendURL != None:
        log.debug("legendURL %s" % (layerInfo.legendURL))
        xml_util.appendElement(doc, rootEl, "legendURL", layerInfo.legendURL);

    outFile = tempfile.NamedTemporaryFile(prefix=exportParams.fileNamePrefix, suffix=".xml", delete=False,
                                          dir=exportParams.exportDir)
    log.debug("File: %s" % (outFile.name))
    doc.writexml(outFile, addindent="  ", newl="\n", encoding="utf-8")
    outFile.close()

    return ExportResult(True, fileName = os.path.basename(outFile.name))
Example #3
0
def makeKmlFile(exportParams):
    """Generates a KML export. If multiple dimension values are specified, the result will contain an overlay for each.
    """
    layerInfo = exportParams.layerInfoList[exportParams.animationLayerNumber - 1]

    # Make a set of parameters that excludes the dimension over which animation is to occur.
    baseParams = layerInfo.params.copy()

    # Determine if animation over multiple values is to occur.
    do_animation = ((exportParams.animationDimension != None) and
        (exportParams.dimensionValues != None) and (len(exportParams.dimensionValues) > 1))

    if do_animation and (exportParams.animationDimension in baseParams):
        del baseParams[exportParams.animationDimension]

    # Get the bounding box values [W, S, E, N].
    bounds = exportParams.commonLayerParams['BBOX'].split(',')

    baseUrl = wmc_util.parseEndpointString(layerInfo.endpoint, baseParams)

    # Create the export XML file.
    domImpl = xml.dom.minidom.getDOMImplementation()
    doc = domImpl.createDocument("http://earth.google.com/kml/2.2", "kml", None)
    rootEl = doc.documentElement

    folderEl = doc.createElement("Folder")
    rootEl.appendChild(folderEl)
    xml_util.appendElement(doc, folderEl, "name", layerInfo.layerName)
    xml_util.appendElement(doc, folderEl, "open", "1")

    # Add a "wmsURL" for each dimension value.
    layerIndex = 0
    if do_animation:
        itr = iter(exportParams.dimensionValues)
        val = itr.next()
        for nextVal in itr:
            makeKmlGroundOverlayFile(doc, folderEl, layerInfo.layerName, baseUrl, exportParams.animationDimension,
                                     val, val, nextVal, bounds, layerIndex)
            val = nextVal
            layerIndex += 1
        makeKmlGroundOverlayFile(doc, folderEl, layerInfo.layerName, baseUrl, exportParams.animationDimension,
                                 val, val, None, bounds, layerIndex)
    else:
        makeKmlGroundOverlayFile(doc, folderEl, layerInfo.layerName, baseUrl, None, None, None, None, bounds, layerIndex)

    outFile = tempfile.NamedTemporaryFile(prefix=exportParams.fileNamePrefix, suffix=".kml", delete=False, dir=exportParams.exportDir)
    log.debug("File: %s" % (outFile.name))
    doc.writexml(outFile, addindent="  ", newl="\n", encoding="utf-8")
    outFile.close()

    return ExportResult(True, fileName = os.path.basename(outFile.name))
Example #4
0
def makeVideo(exportParams):
    """Generates a video export.
    Creates an image for each frame then combines this into a video according to the format specified.
    """
    # Check that the number of steps is within range.
    maxNumberSteps = int(exportParams.configuration['maxnumbersteps'])
    log.debug("Number steps %d  max %d" % (exportParams.numberSteps, maxNumberSteps))
    if exportParams.numberSteps > maxNumberSteps:
        return ExportResult(False,
                            errorMessage = ('The number of steps for a video cannot exceed %d' % maxNumberSteps))

    layerInfo = exportParams.layerInfoList[exportParams.animationLayerNumber - 1]

    animationLayerParams = layerInfo.params
    if (exportParams.animationDimension != None) and (exportParams.animationDimension in animationLayerParams):
        del animationLayerParams[exportParams.animationDimension]

    imageDir = tempfile.mkdtemp(prefix="viewdataVideoExport", suffix="", dir=exportParams.exportDir)

    # Create an image for each dimension value.
    imageIndex = 0
    if exportParams.animationDimension == None:
        createImage(exportParams.params, exportParams.figureOptions, exportParams.commonLayerParams,
                    exportParams.layerInfoList, imageDir, imageIndex, None)
    else:
        # Initialise a list of cached images to be used for layers that don't change between steps.
        imageCache = [None] * len(exportParams.layerInfoList)
        for val in exportParams.dimensionValues:
            # Clear the cached image for the layer that is being animated.
            imageCache[exportParams.animationLayerNumber - 1] = None
            # Set the current value of the animated dimension.
            animationLayerParams[exportParams.animationDimension] = val
            # Update the legend URL with the animated dimension value.
            animationLayerLegendUrl = layerInfo.legendURL
            layerInfo.legendURL = wmc_util.parseEndpointString(animationLayerLegendUrl, {exportParams.animationDimension: val})

            # Create the image file for this value.
            createImage(exportParams.params, exportParams.figureOptions, exportParams.commonLayerParams,
                        exportParams.layerInfoList, imageDir, imageIndex, imageCache)
            imageIndex = imageIndex + 1

    # Create the video from the individual images.
    try:
        outFilePath = createVideo(exportParams.formatName, exportParams.frameRate, imageDir, exportParams.exportDir,
                                  exportParams.fileNamePrefix)
    except Exception, err:
        log.error("Exception creating video: %s" % err)
        outFilePath = None
Example #5
0
def buildImage(layerInfoList, imageCache):
    """Fetches and merges the figure images.
    @param layerInfoList: list of LayerInfo defining layers to include in the figure
    @param imageCache: cache of images that have been generated for layers (used for animations
           where dimensions only vary in the layer over which animation occurs)
    """
    images = []
    st = time.time()
    
    log.debug("Starting buildImage")
    
    size = None
    layerIndex = 0
    for layerInfo in layerInfoList:
        if imageCache == None or imageCache[layerIndex] == None:
            requestURL = wmc_util.parseEndpointString(layerInfo.endpoint, layerInfo.params)

            req = urllib2.Request(requestURL)
            req.add_header('Cookie', request.headers.get('Cookie', ''))

            filehandle = wmc_util.openURL(req)           
            imageString = StringIO(filehandle.read())
            img = Image.open(imageString)
            layerInfo.cachedImage = img
            if imageCache != None:
                imageCache[layerIndex] = img
        else:
            img = imageCache[layerIndex]

        images.append(img)
        size = img.size
        log.debug("img.size = %s, img.mode = %s" % (img.size, img.mode,))
        layerIndex = layerIndex + 1
    
    background = Image.new('RGBA', size, (255,255,255,255))

    log.debug("creating final image...")
    
    images.reverse()
    images.insert(0, background)
    finalImg = merge(*images)
    
    log.debug("finished buildImage in %s" % (time.time() - st,))
    
    return finalImg
Example #6
0
    def _getWCSObj(self, endpoint):
        oldProxy = proxyFix(endpoint)
        try:

            log.debug("wcs endpoint = %s" % (endpoint,))

            getCapabilitiesEndpoint = parseEndpointString(endpoint, {"Service": "WCS", "Request": "GetCapabilities"})

            log.debug("wcs endpoint = %s" % (getCapabilitiesEndpoint,))
            # requires OWSLib with cookie support
            wcs = WebCoverageService(
                getCapabilitiesEndpoint, version="1.0.0", cookies=request.headers.get("Cookie", "")
            )

            layers = [x[0] for x in wcs.items()]
        finally:
            resetProxy(oldProxy)

        return wcs, layers
    def getLayers(self, endpoint, parentId, idMap, keywordData, forceRefresh):
        """Returns a list of 'endpoint_hierarchy_builder.Node's for the layers of an endpoint in a WMC document.
        Also, adds nodes to a map from node ID to node.
        """
        log.debug("getLayers called for %s", endpoint['wmsurl'])
        log.debug("  keywordData: %s" % keywordData)
        wmsUrl = self.makeProxiedUrl(endpoint['wmsurl'])
        wmcDoc = self.wmsCapabilityCache.getWmsCapabilities(wmsUrl, True)

        dom = xml.dom.minidom.parseString(wmcDoc)
        # Get the namespace URI for the document root element.
        ns = dom.documentElement.namespaceURI

        # Get the version the WMS server responded with.
        wmsVersion = dom.documentElement.getAttribute('version')

        nodes = []
        capability = xml_util.getSingleChildByNameNS(dom.documentElement, ns, 'Capability')
        if capability == None:
            return None

        getCapabilitiesUrlEl = xml_util.getSingleChildByPathNS(capability,
                                                               [(ns, 'Request'), (ns, 'GetCapabilities'), (ns, 'DCPType'),
                                                                (ns, 'HTTP'), (ns, 'Get'), (ns, 'OnlineResource')])
        getCapabilitiesUrl = getCapabilitiesUrlEl.getAttributeNS(XLINK_URI, 'href')
        if not getCapabilitiesUrl:
            getCapabilitiesUrl = xml_util.getAttributeByLocalName(getCapabilitiesUrlEl, 'href')
        log.debug("GetCapabilities URL: %s", getCapabilitiesUrl)
        getCapabilitiesUrl = parseEndpointString(getCapabilitiesUrl, {'REQUEST':'GetCapabilities', 'SERVICE':'WMS'})

        getFeatureInfoOnlineResourceEl = xml_util.getSingleChildByPathNS(capability,
                                                                         [(ns, 'Request'), (ns, 'GetFeatureInfo'),
                                                                          (ns, 'DCPType'), (ns, 'HTTP'),
                                                                          (ns, 'Get'), (ns, 'OnlineResource')])
        if getFeatureInfoOnlineResourceEl:
            getFeatureInfoUrl = getFeatureInfoOnlineResourceEl.getAttributeNS(XLINK_URI, 'href')
            if not getFeatureInfoUrl:
                getFeatureInfoUrl = xml_util.getAttributeByLocalName(getFeatureInfoOnlineResourceEl, 'href')
            log.debug("GetFeatureInfo URL: %s", getFeatureInfoUrl)
            getFeatureInfoUrl = getFeatureInfoUrl.rstrip('?&')
        else:
            getFeatureInfoUrl = None

        getMapOnlineResourceEl = xml_util.getSingleChildByPathNS(capability,
                                                               [(ns, 'Request'), (ns, 'GetMap'), (ns, 'DCPType'), (ns, 'HTTP'),
                                                                (ns, 'Get'), (ns, 'OnlineResource')])
        getMapUrl = getMapOnlineResourceEl.getAttributeNS(XLINK_URI, 'href')
        if not getMapUrl:
            getMapUrl = xml_util.getAttributeByLocalName(getMapOnlineResourceEl, 'href')
        log.debug("GetMap URL: %s", getMapUrl)
        getMapUrl = getMapUrl.rstrip('?&')
        getMapUrl = self.makeProxiedUrl(getMapUrl)

        commonData = {
            'getCapabilitiesUrl': getCapabilitiesUrl,
            'getFeatureInfoUrl': getFeatureInfoUrl,
            'getMapUrl': getMapUrl,
            'wmsVersion': wmsVersion
            }
        if 'wcsurl' in endpoint:
            commonData['getCoverageUrl'] = endpoint['wcsurl']
        for layer in xml_util.getChildrenByNameNS(capability, ns, 'Layer'):
            self.handleLayer(ns, layer, nodes, endpoint, parentId, commonData, keywordData, idMap)

        # Break internal references to facilitate garbage collection.
        dom.unlink()

        return nodes