joey: thuban/Extensions/wms layer.py,NONE,1.1

cvs@intevation.de cvs at intevation.de
Thu Apr 15 09:13:33 CEST 2004


Author: joey

Update of /thubanrepository/thuban/Extensions/wms
In directory doto:/tmp/cvs-serv27328

Added Files:
	layer.py 
Log Message:
Moved the WMS layer into a file on its own in order to establish a
clean structure.

--- NEW FILE: layer.py ---
# Copyright (c) 2003, 2004 by Intevation GmbH
# Authors:
# Jan-Oliver Wagner <jan at intevation.de>
# Martin Schulze <joey at infodrom.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

"""
Graphic Layer via OGC WMS.

class WMSLayer:
    __init__()


Requirements:
    - PyOGCLib <http://www.sourceforge.net/projects/pyogclib>

Requires the ogclib installed regularily on the system or checked out
next to the Thuban checkout.  Or set the PYTHONPATH to the PyOGCLib
directory before starting Thuban.

"""

__version__ = "$Revision: 1.1 $"
# $Source: /thubanrepository/thuban/Extensions/wms/layer.py,v $
# $Id: layer.py,v 1.1 2004/04/15 07:13:31 joey Exp $


from Thuban.Model.layer import BaseLayer
from Thuban.Model.resource import get_system_proj_file, EPSG_PROJ_FILE, \
     EPSG_DEPRECATED_PROJ_FILE
from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor

from capabilities import WMSCapabilities

from ogclib.WMSClient import WMSClient


def epsg_code_to_projection(epsg):
    """Find the projection for the given epsg code.

    epsg -- EPSG code as string
    """
    proj_file, warnings = get_system_proj_file(EPSG_PROJ_FILE)

    for proj in proj_file.GetProjections():
        if proj.EPSGCode() == epsg:
            return proj
    proj_file, warnings = get_system_proj_file(EPSG_DEPRECATED_PROJ_FILE)
    for proj in proj_file.GetProjections():
        if proj.EPSGCode() == epsg:
            return proj
    return None


class WMSLayer(BaseLayer):

    def __init__(self, title, url):
        """Initializes the WMSLayer.

        title -- Title of this layer.
        url -- URL of the WMS-Server wich must contain '?'

        If an error occured, self.error_msg is a string describing
        the problem(s). Else, self.error_msg is None.
        """
        BaseLayer.__init__(self, title, visible = True, projection = None)
        self.url = url
        self.bbox = None
        self.latlonbbox = None
        self.error_msg = None
        self.layer_name = None
        self.capabilities = None

        # Change the cursor to demonstrate that we're busy but working
        ThubanBeginBusyCursor()
        self.capabilities = WMSCapabilities(url)
        ThubanEndBusyCursor()

        # name of the top layer of the remote map
        foo = self.capabilities.getLayers()
        if len(foo) == 0:
            self.error_msg = _('No layers found in remote resource:\n'\
                               '%s') % url
            return
        top_layer = foo[0]
        self.layer_name = top_layer

        # first projection of the top layer
        foo = self.capabilities.getLayerSRS(top_layer)
        if len(foo) == 0:
            self.error_msg = _('No LatLonBoundingBox found for top layer %s')\
                             % top_layer
            return
        top_srs = foo[0]

        # BoundingBox of the top layer
        bbox = self.capabilities.getLayerBBox(top_layer, top_srs)
        if len(bbox) == 0:
            self.error_msg = _('No BoundingBox found for layer %s and EPSG:')\
                             % (top_layer, top_srs)
            return
        self.bbox = (float(bbox['minx']),
                     float(bbox['miny']),
                     float(bbox['maxx']),
                     float(bbox['maxy']))

        # LatLonBox of the top layer
        bbox = self.capabilities.getLayerLatLonBBox(top_layer)
        self.latlonbbox = (float(bbox['minx']),
                           float(bbox['miny']),
                           float(bbox['maxx']),
                           float(bbox['maxy']))

        # get projection
        p = epsg_code_to_projection(top_srs)
        self.SetProjection(p)

        if p is None:
            self.error_msg = _('EPSG projection code %s not found!\n'\
                               'Setting projection to "None".\n'\
                               'Please set an appropriate projection yourself.'\
                               % top_srs)

        # pre-determine the used format
        self.wmsformat, self.format = \
            self.calcFormat(self.capabilities.getFormats())
        if self.wmsformat is None:
            self.error_msg = \
                _('No supported image format found in remote resource')
            return

        # get and set the title
        self.SetTitle(self.capabilities.getTitle().encode('latin1', 'replace'))


    def LatLongBoundingBox(self):
        """Return the layer's bounding box in lat-lon.
        """
        return self.latlonbbox

    def BoundingBox(self):
        """Return the layer's bounding box in the intrinsic coordinate system.
        """
        return self.bbox


    def getFormat(self, format):
        """
        Return the image format for the render engine

        format -- format as returned by the WMS server

        If no mapping was found, None is returned

        An exception rule is implemented in order to not accept
        image/wbmp or WBMP which refers to WAP bitmap format and is
        not supported by the included render engine.
        """
        fmap = {'png' : "PNG",
                'jpeg': "JPEG",
                'jpg' : "JPEG",
                'tif' : "TIFF",
                'gif' : "GIF",
                'wbmp': None,
                'bmp' : "BMP"}

        for f in fmap.keys():
            if format.lower().find(f) > -1:
                    return fmap[f]
        return None

        
    def calcFormat(self, formats):
        """
        Calculate the preferred image format

        formats -- list of formates as returned by the WMS server

        The following priority is used:
        - PNG
        - JPEG
        - TIFF
        - GIF
        - BMP

        If no matching format was found, None, None will be returned.

        An exception rule is implemented in order to not accept
        image/wbmp or WBMP which refers to WAP bitmap format and is
        not supported by the included render engine.
        """
        prio = ['jpeg', 'bmp']
        for p in prio:
            for f in formats:
                if f.lower().find(p) > -1:
                    if f.lower().find('wbmp') == -1:
                        return f, self.getFormat(f)
        return None, None
        

    def GetMapImg(self, width, height, bbox):
        bbox_dict = { 'minx': bbox[0], 'miny': bbox[1],
                      'maxx': bbox[2], 'maxy': bbox[3] }

        # Change the cursor to demonstrate that we're busy but working
        ThubanBeginBusyCursor()

        wmsclient = WMSClient()

        epsg_id = int(self.GetProjection().EPSGCode())

        wms_response = wmsclient.getMap(self.url, self.wmsformat, width, height,
                                   epsg_id, bbox_dict,
                                   [self.layer_name], version = self.capabilities.getVersion())
        ThubanEndBusyCursor()
        return wms_response, self.format





More information about the Thuban-devel mailing list

This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)