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))
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))
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))
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
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
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