From cvs at intevation.de Thu Apr 1 11:58:32 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 1 Apr 2004 11:58:32 +0200 (CEST) Subject: joey: thuban/Extensions/wms capabilities.py,1.3,1.4 Message-ID: <20040401095832.7C3B713BE0@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv18514 Modified Files: capabilities.py Log Message: Misc corrections: . superflous asterisk . Documentation for __init__ . Syntax correction . fetchCapabilities: Initialise variable, use local one . loadCapabilities: Use local variable . Fix try...except to only cat IOError when handling files . Corrected __main__ code Index: capabilities.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/capabilities.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- capabilities.py 24 Mar 2004 20:07:34 -0000 1.3 +++ capabilities.py 1 Apr 2004 09:58:30 -0000 1.4 @@ -24,7 +24,7 @@ getErrorMsg() - fetchCapabilities(*resource) + fetchCapabilities(resource) saveCapabilities(filename) loadCapabilities(filename) printCapabilities() @@ -89,6 +89,8 @@ """ Initialises Capabilities with one optional parameter + param can be either a URL or a filename: + filename -- load capabilities from file url -- fetch capabilities from network """ @@ -101,8 +103,8 @@ self.fetchCapabilities(parm[0]) else: self.errorMsg \ - = _("Resource '%s' is neither local file nor URL") - % parm[0] + = _("Resource '%s' is neither local file nor URL") \ + % parm[0] def getErrorMsg(self): @@ -112,11 +114,12 @@ def fetchCapabilities(self, resource): """Fetches the WMS capabilities from an Internet resource""" + xml = None self.wmsVersion = "1.1" - self.capabilities = self.getCapabilities(resource, self.wmsVersion) + xml = self.getCapabilities(resource, self.wmsVersion) if not self.capabilities: self.wmsVersion = "1.0" - self.capabilities = self.getCapabilities(resource, self.wmsVersion) + xml = self.getCapabilities(resource, self.wmsVersion) def saveCapabilities(self, fname): @@ -129,7 +132,7 @@ out = open(fname, "w") out.write(self.capabilities) out.close() - except: + except IOError: self.errorMsg = _("Can't open file '%s' for writing") % fname @@ -138,9 +141,9 @@ try: input = open(fname, "r") - self.capabilities = input.read() + xml = input.read() input.close() - except: + except IOError: self.errorMsg = _("Can't open file '%s' for reading") % fname @@ -154,7 +157,7 @@ if __name__ == "__main__": capabilities \ = WMSCapabilities("http://frida.intevation.org/cgi-bin/frida_wms?") - if capa.getErrorMsg() is None: - capa.saveCapabilities("frida_capabilities.xml") + if capabilities.getErrorMsg() is None: + capabilities.saveCapabilities("frida_capabilities.xml") else: - print "Error: " + capa.getErrorMsg() + print "Error: " + capabilities.getErrorMsg() From cvs at intevation.de Thu Apr 1 12:06:15 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 1 Apr 2004 12:06:15 +0200 (CEST) Subject: joey: thuban/Extensions/wms capabilities.py,1.4,1.5 Message-ID: <20040401100615.C544A13BD9@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv18768 Modified Files: capabilities.py Log Message: Revert part of former changes, since the capabilities XML is used by more methods. Index: capabilities.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/capabilities.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- capabilities.py 1 Apr 2004 09:58:30 -0000 1.4 +++ capabilities.py 1 Apr 2004 10:06:13 -0000 1.5 @@ -114,12 +114,11 @@ def fetchCapabilities(self, resource): """Fetches the WMS capabilities from an Internet resource""" - xml = None self.wmsVersion = "1.1" - xml = self.getCapabilities(resource, self.wmsVersion) + self.capabilities = self.getCapabilities(resource, self.wmsVersion) if not self.capabilities: self.wmsVersion = "1.0" - xml = self.getCapabilities(resource, self.wmsVersion) + self.capabilities = self.getCapabilities(resource, self.wmsVersion) def saveCapabilities(self, fname): @@ -141,7 +140,7 @@ try: input = open(fname, "r") - xml = input.read() + self.capabilities = input.read() input.close() except IOError: self.errorMsg = _("Can't open file '%s' for reading") % fname From cvs at intevation.de Thu Apr 1 12:17:02 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 1 Apr 2004 12:17:02 +0200 (CEST) Subject: joey: thuban/Extensions/wms capabilities.py,1.5,1.6 Message-ID: <20040401101702.69F2413BE4@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv19005 Modified Files: capabilities.py Log Message: Make this class a specialisation of WMSCapabilitiesParser as well. Also execute grok() after loading or fetching capabilities, if that went well, so that subsequent calls can already access the data. Index: capabilities.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/capabilities.py,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- capabilities.py 1 Apr 2004 10:06:13 -0000 1.5 +++ capabilities.py 1 Apr 2004 10:17:00 -0000 1.6 @@ -19,6 +19,8 @@ """ Maintain WMS Capabilities +Inherits methods from WMSCapabilitiesParser + class WMSCapabilities: __init__ (resource xor filename xor nothing) @@ -67,8 +69,9 @@ from Thuban import _ from ogclib.WMSClient import WMSClient +from parser import WMSCapabilitiesParser -class WMSCapabilities(WMSClient): +class WMSCapabilities(WMSClient, WMSCapabilitiesParser): """ Thuban class to maintain capabilities. This class provides methods to fetch, save and load capabilities as well as methods to @@ -120,6 +123,9 @@ self.wmsVersion = "1.0" self.capabilities = self.getCapabilities(resource, self.wmsVersion) + if self.capabilities: + self.grok(self.capabilities) + def saveCapabilities(self, fname): """Save capabilities to local file""" @@ -142,6 +148,7 @@ input = open(fname, "r") self.capabilities = input.read() input.close() + self.grok(self.capabilities) except IOError: self.errorMsg = _("Can't open file '%s' for reading") % fname From cvs at intevation.de Thu Apr 1 16:39:41 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 1 Apr 2004 16:39:41 +0200 (CEST) Subject: joey: thuban/Extensions/wms capabilities.py,1.6,1.7 Message-ID: <20040401143941.BF93713BD5@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv23127 Modified Files: capabilities.py Log Message: Export the used version of the GetCapabilities request, so we can use it for subsequent calls, i.e. for GetMap requests. Index: capabilities.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/capabilities.py,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- capabilities.py 1 Apr 2004 10:17:00 -0000 1.6 +++ capabilities.py 1 Apr 2004 14:39:39 -0000 1.7 @@ -31,6 +31,8 @@ loadCapabilities(filename) printCapabilities() + getVersion() + Requirements: - PyOGCLib @@ -122,6 +124,8 @@ if not self.capabilities: self.wmsVersion = "1.0" self.capabilities = self.getCapabilities(resource, self.wmsVersion) + if not self.capabilities: + self.wmsVersion = None if self.capabilities: self.grok(self.capabilities) @@ -158,6 +162,14 @@ print self.capabilities + + def getVersion(self): + """ + Returns the WMS protocol version + + If no capabilities could be fetched, None is returned. + """ + return self.wmsVersion if __name__ == "__main__": From cvs at intevation.de Thu Apr 1 16:41:37 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 1 Apr 2004 16:41:37 +0200 (CEST) Subject: joey: thuban/Extensions/wms capabilities.py,1.7,1.8 Message-ID: <20040401144137.6A4DD13BD5@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv23178 Modified Files: capabilities.py Log Message: Added proper error handling when the GetCapabilities request failed, so that the surrounding program can act accordingly. Index: capabilities.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/capabilities.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- capabilities.py 1 Apr 2004 14:39:39 -0000 1.7 +++ capabilities.py 1 Apr 2004 14:41:35 -0000 1.8 @@ -117,7 +117,14 @@ def fetchCapabilities(self, resource): - """Fetches the WMS capabilities from an Internet resource""" + """ + Fetches the WMS capabilities from an Internet resource + + WMS Protocol version 1.1 is tried first, then 1.0. The + protocol version used can be queried by the getVersion() + method for later use. If both tries fail, errorMsg will be + set accordingly, which can be fetched with getErrorMsg(). + """ self.wmsVersion = "1.1" self.capabilities = self.getCapabilities(resource, self.wmsVersion) @@ -126,6 +133,10 @@ self.capabilities = self.getCapabilities(resource, self.wmsVersion) if not self.capabilities: self.wmsVersion = None + self.errorMsg \ + = _("Resource '%s' " + + "does support neither WMS version 1.1 nor 1.0") \ + % resource if self.capabilities: self.grok(self.capabilities) From joey at infodrom.org Thu Apr 1 17:03:27 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 1 Apr 2004 17:03:27 +0200 Subject: joey: thuban/Extensions/wms capabilities.py,1.7,1.8 In-Reply-To: <20040401144137.6A4DD13BD5@lists.intevation.de> References: <20040401144137.6A4DD13BD5@lists.intevation.de> Message-ID: <20040401150327.GS1655@finlandia.infodrom.north.de> Do you know if this poses a problem with gettext? cvs at intevation.de wrote: > @@ -126,6 +133,10 @@ > self.capabilities = self.getCapabilities(resource, self.wmsVersion) > if not self.capabilities: > self.wmsVersion = None > + self.errorMsg \ > + = _("Resource '%s' " > + + "does support neither WMS version 1.1 nor 1.0") \ > + % resource Regards, Joey -- It's practically impossible to look at a penguin and feel angry. From bh at intevation.de Thu Apr 1 17:15:44 2004 From: bh at intevation.de (Bernhard Herzog) Date: Thu, 01 Apr 2004 17:15:44 +0200 Subject: joey: thuban/Extensions/wms capabilities.py,1.7,1.8 In-Reply-To: <20040401150327.GS1655@finlandia.infodrom.north.de> (Martin Schulze's message of "Thu, 1 Apr 2004 17:03:27 +0200") References: <20040401144137.6A4DD13BD5@lists.intevation.de> <20040401150327.GS1655@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > Do you know if this poses a problem with gettext? > > cvs at intevation.de wrote: >> @@ -126,6 +133,10 @@ >> self.capabilities = self.getCapabilities(resource, self.wmsVersion) >> if not self.capabilities: >> self.wmsVersion = None >> + self.errorMsg \ >> + = _("Resource '%s' " >> + + "does support neither WMS version 1.1 nor 1.0") \ >> + % resource It's better written as self.errorMsg \ = _("Resource '%s' " "does support neither WMS version 1.1 nor 1.0") \ % resource I.e. without the +. Python automatically concatenates string literals, pretty much like C and xgettext supports it too. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From cvs at intevation.de Thu Apr 1 17:34:27 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 1 Apr 2004 17:34:27 +0200 (CEST) Subject: joey: thuban/Extensions/wms capabilities.py,1.8,1.9 Message-ID: <20040401153427.CBB4413AC2@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv24154 Modified Files: capabilities.py Log Message: No need to use the concatenation operator here, and this version will also be understood by gettext which is important for translations later. Index: capabilities.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/capabilities.py,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- capabilities.py 1 Apr 2004 14:41:35 -0000 1.8 +++ capabilities.py 1 Apr 2004 15:34:25 -0000 1.9 @@ -135,7 +135,7 @@ self.wmsVersion = None self.errorMsg \ = _("Resource '%s' " - + "does support neither WMS version 1.1 nor 1.0") \ + "does support neither WMS version 1.1 nor 1.0") \ % resource if self.capabilities: From joey at infodrom.org Thu Apr 1 17:32:16 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 1 Apr 2004 17:32:16 +0200 Subject: Status: My work on the WMS integration Message-ID: <20040401153216.GV1655@finlandia.infodrom.north.de> Hi, I was asked to send out a short status report about my work on the WMS integration into Thuban. I've finished the Capabilities XML backend (mainly parser.py, but also capabilities.py), so that the server response is read and parsed accordingly. The class WMSCapabilities provides methods to access the extracted Capability data, so that the surrounding program or class can work on the data. WMSCapabilities is a specialisation of WMSClient (from OGCLib, provides web access to the WMS server) and WMSCapabilitiesParser, which performs XML parsing and storing in local variables. My next step is to integrate the data into the existing wms code by Jan to see it in action, and then see how it needs to be integrated into the graphic Thuban structure. Regards, Joey -- It's practically impossible to look at a penguin and feel angry. From joey at infodrom.org Thu Apr 1 17:33:42 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 1 Apr 2004 17:33:42 +0200 Subject: joey: thuban/Extensions/wms capabilities.py,1.7,1.8 In-Reply-To: References: <20040401144137.6A4DD13BD5@lists.intevation.de> <20040401150327.GS1655@finlandia.infodrom.north.de> Message-ID: <20040401153342.GW1655@finlandia.infodrom.north.de> Bernhard Herzog wrote: > > cvs at intevation.de wrote: > >> @@ -126,6 +133,10 @@ > >> self.capabilities = self.getCapabilities(resource, self.wmsVersion) > >> if not self.capabilities: > >> self.wmsVersion = None > >> + self.errorMsg \ > >> + = _("Resource '%s' " > >> + + "does support neither WMS version 1.1 nor 1.0") \ > >> + % resource > > It's better written as > > self.errorMsg \ > = _("Resource '%s' " > "does support neither WMS version 1.1 nor 1.0") \ > % resource > > I.e. without the +. Python automatically concatenates string literals, > pretty much like C and xgettext supports it too. Ah, great! Didn't know that it's valid without the +, but I was tempted (not enough, though) to just try it. Will change it. Regards, Joey -- It's practically impossible to look at a penguin and feel angry. From JensMattke at aol.com Wed Apr 7 19:40:38 2004 From: JensMattke at aol.com (JensMattke@aol.com) Date: Wed, 7 Apr 2004 13:40:38 EDT Subject: Great amount of shapes with PostGIS Message-ID: <106.2e909ec4.2da59716@aol.com> Hi. I am designing a spatial database for my Diploma-Dissertation. I would like to work with Thuban on tables containing up to 95.000 shapes (I think this number is even increasing!). Unfortunately, this doesn't work on acceptable speed. It seems to me, Thuban reloads all the data from the database at every action. I will have the chance to devide my tables, but I don't think this will bring the number of shapes below 20.000. Are there any plans in the near future, to keep the data persistent for a session? Jens -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.intevation.de/pipermail/thuban-devel/attachments/20040407/64c34fb0/attachment.html From frank.koormann at intevation.de Thu Apr 8 11:42:40 2004 From: frank.koormann at intevation.de (Frank Koormann) Date: Thu, 8 Apr 2004 11:42:40 +0200 Subject: Great amount of shapes with PostGIS In-Reply-To: <106.2e909ec4.2da59716@aol.com> References: <106.2e909ec4.2da59716@aol.com> Message-ID: <20040408094240.GB16705@intevation.de> Hi Jens, * JensMattke at aol.com [040407 19:40]: > Hi. > > I am designing a spatial database for my Diploma-Dissertation. > I would like to work with Thuban on tables containing up to 95.000 shapes > (I think this number is even increasing!). Unfortunately, this doesn't > work on acceptable speed. > It seems to me, Thuban reloads all the data from the database at every > action. > > I will have the chance to devide my tables, but I don't think this will > bring the number of shapes below 20.000. > Are there any plans in the near future, to keep the data persistent for a > session? Thuban's PostGIS interface is the result of a thesis (with some revision by Bernhard Herzog), it has been implemented under the paradigm 'first make it work'. We are aware that there are numerous screws to tune the DB connection and rendering in general. But Intevation is currently not contracted to work on the optimization of this interface, hence progress in that direction runs on low priority. So near term improvements might be voluntary contributions. Although Bernhard is quite busy this month, if someone is interested we could sketch some improvements. Cheers, Frank -- Frank Koormann Professional Service around Free Software (http://intevation.net/) FreeGIS Project (http://freegis.org/) From cvs at intevation.de Sat Apr 10 15:20:55 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sat, 10 Apr 2004 15:20:55 +0200 (CEST) Subject: joey: thuban/Extensions/wms parser.py,1.3,1.4 Message-ID: <20040410132055.60CAE139A9@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv11603 Modified Files: parser.py Log Message: unlink the DOM object Index: parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/parser.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- parser.py 30 Mar 2004 18:05:53 -0000 1.3 +++ parser.py 10 Apr 2004 13:20:53 -0000 1.4 @@ -89,7 +89,8 @@ Information should only be retrieved with the respective get*() methods. """ - root = xml.dom.minidom.parseString(data).documentElement + xml_dom = xml.dom.minidom.parseString(data) + root = xml_dom.documentElement # Extract the title foo = getElementByName(getElementByName(root, 'Service'), 'Title') @@ -124,6 +125,8 @@ self.layers = [] self.peekLayers(getElementByName(getElementByName( root, 'Capability'), 'Layer'), -1) + + xml_dom.unlink() def peekLayers(self, top, parent): From joey at infodrom.org Sat Apr 10 19:24:07 2004 From: joey at infodrom.org (Martin Schulze) Date: Sat, 10 Apr 2004 19:24:07 +0200 Subject: Support for bitmap image formats Message-ID: <20040410172407.GD1655@finlandia.infodrom.north.de> Hi, is there a reason the render engine is limited to support only JPEG and BMP? The wxWidgets library seems to support more image formats, such as commonly used TIFF, PNG, GIF, or less commonly used PNM, PCX, XBM and XPM, just to name some. I've just tested whether the engine can handle PNG, TIFF and GIF, which worked fine. I know that's not a proof, but only a circumstantial evidence. Attached is a patch that would add these formats. Regards, Joey -- Life is too short to run proprietary software. -- Bdale Garbee -------------- next part -------------- Index: renderer.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/renderer.py,v retrieving revision 1.49 diff -u -r1.49 renderer.py --- Thuban/UI/renderer.py 11 Nov 2003 18:16:42 -0000 1.49 +++ Thuban/UI/renderer.py 10 Apr 2004 17:15:23 -0000 @@ -20,7 +20,8 @@ from wxPython.wx import wxPoint, wxRect, wxPen, wxBrush, wxFont, \ wxTRANSPARENT_PEN, wxTRANSPARENT_BRUSH, \ wxBLACK_PEN, wxBLACK, wxSOLID, wxCROSS_HATCH, wxSWISS, wxNORMAL, \ - wxBitmapFromImage, wxImageFromStream, wxBITMAP_TYPE_BMP, wxBITMAP_TYPE_JPEG + wxBitmapFromImage, wxImageFromStream, wxBITMAP_TYPE_BMP, \ + wxBITMAP_TYPE_JPEG, wxBITMAP_TYPE_PNG, wxBITMAP_TYPE_TIF, wxBITMAP_TYPE_GIF from wxproj import draw_polygon_shape, draw_polygon_init @@ -42,6 +43,9 @@ raster_format_map = { "BMP": wxBITMAP_TYPE_BMP, "JPEG": wxBITMAP_TYPE_JPEG, + "PNG": wxBITMAP_TYPE_PNG, + "TIFF": wxBITMAP_TYPE_TIF, + "GIF": wxBITMAP_TYPE_GIF, } class MapRenderer(BaseRenderer): From cvs at intevation.de Sat Apr 10 21:08:01 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sat, 10 Apr 2004 21:08:01 +0200 (CEST) Subject: joey: thuban/Extensions/wms wms.py,1.2,1.3 Message-ID: <20040410190801.80DA213B16@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv18556 Modified Files: wms.py Log Message: Incorporate WMSCapabilities from capabilities.py and parser.py. Implement priority list for supported graphics formats, take care of wbmp != bmp. PNG, TIFF and GIF are supported here, but not yet by main Thuban. Hence, support for them may be removed later. Special contribution to usability: get wxWidgets to change the cursor when we're waiting for data from the network so the user won't start to worry. This causes a redrawing error/warning, though. Index: wms.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/wms.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- wms.py 20 Feb 2004 20:09:25 -0000 1.2 +++ wms.py 10 Apr 2004 19:07:59 -0000 1.3 @@ -40,6 +40,7 @@ from Thuban import _ import Thuban.UI.baserenderer +from capabilities import WMSCapabilities def epsg_code_to_projection(epsg): """Find the projection for the given epsg code. @@ -62,7 +63,7 @@ return (_("Extension: %s") % self.title, [ object.TreeInfo() for object in self.objects ]) -class WMSLayer(BaseLayer, WMSClient): +class WMSLayer(BaseLayer): def __init__(self, title, url): """Initializes the WMSLayer. @@ -79,38 +80,50 @@ self.latlonbbox = None self.error_msg = None self.layer_name = None + self.capabilities = None - wms_response = self.getCapabilities(self.url, '1.0') - self._capa_dom = xml.dom.minidom.parseString(wms_response) + # Change the cursor to demonstrate that we're busy but working + wxBeginBusyCursor() + self.capabilities = WMSCapabilities(url) + wxEndBusyCursor() - root = self._capa_dom.documentElement - cap = root.getElementsByTagName('Capability')[0] - layer = cap.getElementsByTagName('Layer')[0] + # 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 - # get projected bounding box and latlon bounding box - for node in layer.childNodes: - if node.nodeName == 'BoundingBox': - minx = node.attributes.get('minx').nodeValue - miny = node.attributes.get('miny').nodeValue - maxx = node.attributes.get('maxx').nodeValue - maxy = node.attributes.get('maxy').nodeValue - self.bbox = (float(minx), float(miny), float(maxx), float(maxy)) - bbox = layer.getElementsByTagName('LatLonBoundingBox')[0] - self.layer_name = layer.getElementsByTagName('Name')[0].childNodes[0].data - minx = bbox.attributes.get('minx').nodeValue - miny = bbox.attributes.get('miny').nodeValue - maxx = bbox.attributes.get('maxx').nodeValue - maxy = bbox.attributes.get('maxy').nodeValue - self.latlonbbox = (float(minx), float(miny), float(maxx), float(maxy)) + # 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] - # get projection - srs = layer.getElementsByTagName('SRS')[0].childNodes[0].data - if len(srs.split(':')) == 1: - epsg_id = srs - else: - epsg_id = srs.split(':')[1] + # 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'])) - p = epsg_code_to_projection(epsg_id) + # 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: @@ -119,11 +132,17 @@ 'Please set an appropriate projection yourself.'\ % epsg_id) - # get title - title = layer.getElementsByTagName('Title')[0].childNodes[0].data - self.SetTitle(title.encode('latin1', 'replace')) + # 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')) - self._capa_dom.unlink() def LatLongBoundingBox(self): """Return the layer's bounding box in lat-lon. @@ -135,15 +154,77 @@ """ 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 = ['png', 'jpeg', 'jpg', 'tif', 'gif', '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 + wxBeginBusyCursor() + + wmsclient = WMSClient() + epsg_id = int(self.GetProjection().EPSGCode()) - wms_response = self.getMap(self.url, 'JPEG', width, height, - epsg_id, bbox_dict, - [self.layer_name], version = '1.0') - return wms_response + wms_response = wmsclient.getMap(self.url, self.wmsformat, width, height, + epsg_id, bbox_dict, + [self.layer_name], version = self.capabilities.getVersion()) + wxEndBusyCursor() + return wms_response, self.format def render_wms_layer(renderer, layer): @@ -156,8 +237,8 @@ xmax = (width - offx) / scale ymax = (offy - 0) / scale - img = layer.GetMapImg(width, height, (xmin, ymin, xmax, ymax)) - renderer.draw_raster_data(img, "JPEG") + img, format = layer.GetMapImg(width, height, (xmin, ymin, xmax, ymax)) + renderer.draw_raster_data(img, format) return () From cvs at intevation.de Sat Apr 10 21:12:43 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sat, 10 Apr 2004 21:12:43 +0200 (CEST) Subject: joey: thuban/Extensions/wms parser.py,1.4,1.5 Message-ID: <20040410191243.4760C13B16@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv18618 Modified Files: parser.py Log Message: Whoops, it's "foo".lower() and not lower(foo) without lower imported from strings or something. Index: parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/parser.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- parser.py 10 Apr 2004 13:20:53 -0000 1.4 +++ parser.py 10 Apr 2004 19:12:41 -0000 1.5 @@ -105,14 +105,14 @@ # Extract fees information foo = getElementByName(getElementByName(root, 'Service'), 'Fees') if foo and len(foo.childNodes[0].data) \ - and lower(foo.childNodes[0].data) != 'none': + and foo.childNodes[0].data.lower() != 'none': self.fees = foo.childNodes[0].data # Extract access information foo = getElementByName(getElementByName(root, 'Service'), 'AccessConstraints') if foo and len(foo.childNodes[0].data) \ - and lower(foo.childNodes[0].data) != 'none': + and foo.childNodes[0].data.lower() != 'none': self.access = foo.childNodes[0].data # Extract output format information From cvs at intevation.de Sat Apr 10 21:14:11 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sat, 10 Apr 2004 21:14:11 +0200 (CEST) Subject: joey: thuban ChangeLog,1.637,1.638 Message-ID: <20040410191411.3CF7913B16@lists.intevation.de> Author: joey Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv18642 Modified Files: ChangeLog Log Message: Documented my changes. Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.637 retrieving revision 1.638 diff -u -d -r1.637 -r1.638 --- ChangeLog 30 Mar 2004 19:08:55 -0000 1.637 +++ ChangeLog 10 Apr 2004 19:14:08 -0000 1.638 @@ -1,3 +1,42 @@ +2004-04-10 Martin Schulze + + * Extensions/wms/parser.py (WMSCapabilitiesParser.grok): Adjusted + string handling. It's "foo".lower() and not lower(foo) without + lower imported from strings or something. + + * Extensions/wms/wms.py (WMSLayer): Incorporated WMSCapabilities + from capabilities.py and parser.py. Implement priority list for + supported graphics formats, take care of wbmp != bmp. PNG, TIFF + and GIF are supported here, but not yet by main Thuban. Hence, + support for them may be removed later. Special contribution to + usability: get wxWidgets to change the cursor when we're waiting + for data from the network so the user won't start to worry. This + causes a redrawing error/warning, though. + + * Extensions/wms/parser.py (WMSCapabilitiesParser.grok): Unlink + the DOM object. + + +2004-04-01 Martin Schulze + + * Extensions/wms/capabilities.py: Adjusted documentation + (WMSCapabilities.__init__): Improved documentation, fixed syntax + (WMSCapabilities.saveCapabilities): Only catch IOError when + handling files + (WMSCapabilities.loadCapabilities): Only catch IOError when + handling files + __main__: corrected variable naming + (WMSCapabilities.fetchCapabilities,loadCapabilities): Make this + class a specialisation of WMSCapabilitiesParser as well. Also + execute grok() after loading or fetching capabilities, if that + went well, so that subsequent calls can already access the data. + (WMSCapabilities.getVersion): Export the used version of the + GetCapabilities request, so we can use it for subsequent calls, + i.e. for GetMap requests. + (WMSCapabilities.fetchCapabilities): Added proper error handling + when the GetCapabilities request failed, so that the surrounding + program can act accordingly. + 2004-03-30 Martin Schulze * Extensions/wms/parser.py (WMSCapabilitiesParser.getLayerSRS): From joey at infodrom.org Sun Apr 11 09:52:06 2004 From: joey at infodrom.org (Martin Schulze) Date: Sun, 11 Apr 2004 09:52:06 +0200 Subject: ValueError when resetting the BusyCursor Message-ID: <20040411075206.GG1655@finlandia.infodrom.north.de> Hi, I noticed that when I utilise wxBeginBusyCursor() and wxEndBusyCursor() in order to help the user understand that Thuban is doing something when talking to a remote WMS resource, Thuban/UI/view.py emits an error File: ".../Thuban/UI/view.py", line 206, in _do_redraw if self.render_iter.netxt(): ValueError: generator already executing Even though I do understand the error: the function _do_redraw is called within itself, which is not permitted, I don't understand why this error is happening here. This problem is caused by wxEndBusyCursor() in Extension/wms/wms.py line 226, i.e. in the GetMapImg() method when resetting the mouse cursor. However, removing it could end up in long delays until Thuban reacts again which has the potential to confuse the user, so that doesn't seem to be an option, but only a workaround against this exception. Another way to circumvent this problem would be to explicitly ignore ValueError in the render method: Index: Thuban/UI/view.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/view.py,v retrieving revision 1.62 diff -u -r1.62 view.py --- Thuban/UI/view.py 17 Feb 2004 13:14:49 -0000 1.62 +++ Thuban/UI/view.py 11 Apr 2004 07:45:58 -0000 @@ -223,6 +223,9 @@ if not self.dragging: self.redraw() finished = True + except ValueError: + finished = True + self.render_iter = None except StopIteration: finished = True self.render_iter = None What do you think? Regards, Joey -- Life is too short to run proprietary software. -- Bdale Garbee From joey at infodrom.org Sun Apr 11 11:38:26 2004 From: joey at infodrom.org (Martin Schulze) Date: Sun, 11 Apr 2004 11:38:26 +0200 Subject: ShowTable not raised? Message-ID: <20040411093825.GI1655@finlandia.infodrom.north.de> Hi, I noticed a FIXME comment in Thuban/UI/mainwindow.py that could easily be resolved with the following patch: Index: Thuban/UI/mainwindow.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/mainwindow.py,v retrieving revision 1.129 diff -u -r1.129 mainwindow.py --- Thuban/UI/mainwindow.py 11 Mar 2004 21:04:30 -0000 1.129 +++ Thuban/UI/mainwindow.py 11 Apr 2004 08:49:34 -0000 @@ -641,8 +641,7 @@ self.add_dialog(name, dialog) dialog.Show(True) else: - # FIXME: bring dialog to front here - pass + dialog.Raise() def MapProjection(self): Should I apply it? Regards, Joey -- Life is too short to run proprietary software. -- Bdale Garbee From cvs at intevation.de Sun Apr 11 18:19:37 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sun, 11 Apr 2004 18:19:37 +0200 (CEST) Subject: joey: thuban/Extensions/wms infodialog.py,NONE,1.1 Message-ID: <20040411161937.0AFE4139B8@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv32643 Added Files: infodialog.py Log Message: Added an information dialog that will display various information about the WMS current resource, so that additional information such as the title, the abstract, fees and access constraints can be displayed for the user if they are documented in the WMS XML. --- NEW FILE: infodialog.py --- # Copyright (c) 2004 by Intevation GmbH # Authors: # Martin Schulze # # 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 """ Information dialog to display various information about a WMS layer. class wmsInfoDialog(NonModalDialog): __init__ dialog_layout(text) calcText(layer) """ __version__ = "$Revision: 1.1 $" # $Source: /thubanrepository/thuban/Extensions/wms/infodialog.py,v $ # $Id: infodialog.py,v 1.1 2004/04/11 16:19:34 joey Exp $ from Thuban import _ from Thuban.UI.dialogs import ThubanFrame from wxPython.wx import wxBoxSizer, wxTextCtrl, wxVERTICAL, \ wxHORIZONTAL, wxTE_READONLY, wxTE_MULTILINE, wxTE_LINEWRAP, \ wxEXPAND, wxALL, wxButton, wxALIGN_CENTER_HORIZONTAL, wxID_OK, \ EVT_BUTTON class wmsInfoDialog(ThubanFrame): """ Representation for a simple information dialog This dialog will display the title of the WMS resource """ def __init__(self, parent, name, title, layer): """ Build the information dialog """ ThubanFrame.__init__(self, parent, name, title) self.dialog_layout(self.calcText(layer)) def dialog_layout(self, text): """ Set up the information dialog """ vbox = wxBoxSizer(wxVERTICAL) textBox = wxTextCtrl(self, -1, text, style=wxTE_READONLY|wxTE_MULTILINE|wxTE_LINEWRAP) w, h = (500, 300) textBox.SetSizeHints(w, h) textBox.SetSize((w, h)) vbox.Add(textBox, 1, wxEXPAND|wxALL, 10) buttons = wxBoxSizer(wxHORIZONTAL) buttons.Add(wxButton(self, wxID_OK, _("Close")), 0, wxALL, 4) vbox.Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10) EVT_BUTTON(self, wxID_OK, self.OnClose) self.SetAutoLayout(True) self.SetSizer(vbox) vbox.Fit(self) vbox.SetSizeHints(self) def calcText(self, layer): """ Generate the text to be displayed in the information window It will use several nodes returned by the GetCapabilities request, such as the title, the abstract, fees and access constraints, if they are documented. """ text = '' foo = layer.capabilities.getTitle() if foo != "": text += foo.encode('latin1') + "\n\n" foo = layer.capabilities.getAbstract() if foo != "": text += foo + "\n\n" foo = layer.capabilities.getFees() if foo != "": text += _("Fees:") + "\n\n" + foo + "\n\n" foo = layer.capabilities.getAccessConstraints() if foo != "": text += _("Acces Constraints:") + "\n\n" + foo + "\n\n" text += "URL: " + layer.url return text From joey at infodrom.org Sun Apr 11 19:36:14 2004 From: joey at infodrom.org (Martin Schulze) Date: Sun, 11 Apr 2004 19:36:14 +0200 Subject: ValueError when resetting the BusyCursor In-Reply-To: <20040411075206.GG1655@finlandia.infodrom.north.de> References: <20040411075206.GG1655@finlandia.infodrom.north.de> Message-ID: <20040411173614.GR1655@finlandia.infodrom.north.de> Martin Schulze wrote: > Hi, > > I noticed that when I utilise wxBeginBusyCursor() and > wxEndBusyCursor() in order to help the user understand that Thuban is > doing something when talking to a remote WMS resource, > Thuban/UI/view.py emits an error > > File: ".../Thuban/UI/view.py", line 206, in _do_redraw > if self.render_iter.netxt(): > ValueError: generator already executing For what it's worth, this also happens when I use Thuban{Begin,End}BusyCursor. I read a comment in Thuban/UI/common.py: In addition to calling wxBeginBusyCursor this function also calls wxSafeYield to make sure that the cursor change takes effect. wxGTK 2.4 at least doesn't do that automatically. This doesn't seem to be the case anymore with wxWidgets 2.4.2.4 (libwxgtk2.4-python, Debian unstable) Regards, Joey -- Life is too short to run proprietary software. -- Bdale Garbee From cvs at intevation.de Sun Apr 11 19:38:13 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sun, 11 Apr 2004 19:38:13 +0200 (CEST) Subject: joey: thuban/Extensions/wms wms.py,1.3,1.4 Message-ID: <20040411173813.0BA8D139B8@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv948 Modified Files: wms.py Log Message: Switch to using Thuban{Begin,End}BusyCursor instead of the pure wxWidgets variants. Index: wms.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/wms.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- wms.py 10 Apr 2004 19:07:59 -0000 1.3 +++ wms.py 11 Apr 2004 17:38:10 -0000 1.4 @@ -37,6 +37,7 @@ EPSG_DEPRECATED_PROJ_FILE from Thuban.UI.command import registry, Command import Thuban.UI.mainwindow +from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor from Thuban import _ import Thuban.UI.baserenderer @@ -83,9 +84,9 @@ self.capabilities = None # Change the cursor to demonstrate that we're busy but working - wxBeginBusyCursor() + ThubanBeginBusyCursor() self.capabilities = WMSCapabilities(url) - wxEndBusyCursor() + ThubanEndBusyCursor() # name of the top layer of the remote map foo = self.capabilities.getLayers() @@ -214,7 +215,7 @@ 'maxx': bbox[2], 'maxy': bbox[3] } # Change the cursor to demonstrate that we're busy but working - wxBeginBusyCursor() + ThubanBeginBusyCursor() wmsclient = WMSClient() @@ -223,7 +224,7 @@ wms_response = wmsclient.getMap(self.url, self.wmsformat, width, height, epsg_id, bbox_dict, [self.layer_name], version = self.capabilities.getVersion()) - wxEndBusyCursor() + ThubanEndBusyCursor() return wms_response, self.format From cvs at intevation.de Sun Apr 11 19:39:32 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sun, 11 Apr 2004 19:39:32 +0200 (CEST) Subject: joey: thuban/Extensions/wms wms.py,1.4,1.5 Message-ID: <20040411173932.B2FF2139B8@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv973 Modified Files: wms.py Log Message: The epsg_id variable is named top_srs now. Index: wms.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/wms.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- wms.py 11 Apr 2004 17:38:10 -0000 1.4 +++ wms.py 11 Apr 2004 17:39:30 -0000 1.5 @@ -131,7 +131,7 @@ self.error_msg = _('EPSG projection code %s not found!\n'\ 'Setting projection to "None".\n'\ 'Please set an appropriate projection yourself.'\ - % epsg_id) + % top_srs) # pre-determine the used format self.wmsformat, self.format = \ From cvs at intevation.de Sun Apr 11 20:15:35 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sun, 11 Apr 2004 20:15:35 +0200 (CEST) Subject: joey: thuban/Extensions/wms infodialog.py,1.1,1.2 Message-ID: <20040411181535.D22951397F@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv1372 Modified Files: infodialog.py Log Message: Adjusted the class documentation Index: infodialog.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/infodialog.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- infodialog.py 11 Apr 2004 16:19:34 -0000 1.1 +++ infodialog.py 11 Apr 2004 18:15:33 -0000 1.2 @@ -19,7 +19,7 @@ """ Information dialog to display various information about a WMS layer. -class wmsInfoDialog(NonModalDialog): +class wmsInfoDialog(ThubanFrame): __init__ dialog_layout(text) From cvs at intevation.de Sun Apr 11 20:36:12 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sun, 11 Apr 2004 20:36:12 +0200 (CEST) Subject: joey: thuban ChangeLog,1.638,1.639 Message-ID: <20040411183612.535AF1397F@lists.intevation.de> Author: joey Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv1578 Modified Files: ChangeLog Log Message: Documented changes Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.638 retrieving revision 1.639 diff -u -d -r1.638 -r1.639 --- ChangeLog 10 Apr 2004 19:14:08 -0000 1.638 +++ ChangeLog 11 Apr 2004 18:36:10 -0000 1.639 @@ -1,3 +1,18 @@ +2004-04-11 Martin Schulze + + * Extensions/wms/infodialog.py: Adjusted the class documentation + + * Extensions/wms/wms.py (WMSLayer.__init__, WMSLayer.GetMapImg): + Switch to using Thuban{Begin,End}BusyCursor instead of the pure + wxWidgets variants. + (WMSLayer.__init__): The epsg_id variable is named top_srs now. + + * Extensions/wms/infodialog.py: Added an information dialog that + will display various information about the WMS current resource, + so that additional information such as the title, the abstract, + fees and access constraints can be displayed for the user if they + are documented in the WMS XML. + 2004-04-10 Martin Schulze * Extensions/wms/parser.py (WMSCapabilitiesParser.grok): Adjusted @@ -15,7 +30,6 @@ * Extensions/wms/parser.py (WMSCapabilitiesParser.grok): Unlink the DOM object. - 2004-04-01 Martin Schulze From cvs at intevation.de Sun Apr 11 20:40:08 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sun, 11 Apr 2004 20:40:08 +0200 (CEST) Subject: joey: thuban ChangeLog,1.639,1.640 Message-ID: <20040411184008.3C1271397F@lists.intevation.de> Author: joey Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv1633 Modified Files: ChangeLog Log Message: Added back lost newline Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.639 retrieving revision 1.640 diff -u -d -r1.639 -r1.640 --- ChangeLog 11 Apr 2004 18:36:10 -0000 1.639 +++ ChangeLog 11 Apr 2004 18:40:06 -0000 1.640 @@ -4563,7 +4563,8 @@ Fix problem of hidden properties dialog under windows after double click on layer tree: The tree control always gets an Expanded / Collapsed event after - the ItemActivated on double click, which raises the main window again. We add a second ItemActivated event to the queue, which simply + the ItemActivated on double click, which raises the main window again. + We add a second ItemActivated event to the queue, which simply raises the already displayed window. * Thuban/UI/legend.py (LegendTree.__init__): Instance variable From bh at intevation.de Tue Apr 13 11:45:10 2004 From: bh at intevation.de (Bernhard Herzog) Date: Tue, 13 Apr 2004 11:45:10 +0200 Subject: ShowTable not raised? In-Reply-To: <20040411093825.GI1655@finlandia.infodrom.north.de> (Martin Schulze's message of "Sun, 11 Apr 2004 11:38:26 +0200") References: <20040411093825.GI1655@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > Index: Thuban/UI/mainwindow.py > =================================================================== > RCS file: /thubanrepository/thuban/Thuban/UI/mainwindow.py,v > retrieving revision 1.129 > diff -u -r1.129 mainwindow.py > --- Thuban/UI/mainwindow.py 11 Mar 2004 21:04:30 -0000 1.129 > +++ Thuban/UI/mainwindow.py 11 Apr 2004 08:49:34 -0000 > @@ -641,8 +641,7 @@ > self.add_dialog(name, dialog) > dialog.Show(True) > else: > - # FIXME: bring dialog to front here > - pass > + dialog.Raise() > > def MapProjection(self): > > Should I apply it? Yes. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From cvs at intevation.de Tue Apr 13 12:10:36 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 13 Apr 2004 12:10:36 +0200 (CEST) Subject: joey: thuban/Thuban/UI mainwindow.py,1.129,1.130 Message-ID: <20040413101036.BE69313B84@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Thuban/UI In directory doto:/tmp/cvs-serv29384 Modified Files: mainwindow.py Log Message: Raise the ShowTable() dialog/frame when the user attempts to display it while it has been opened before already and not closed again. Index: mainwindow.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/mainwindow.py,v retrieving revision 1.129 retrieving revision 1.130 diff -u -d -r1.129 -r1.130 --- mainwindow.py 11 Mar 2004 21:04:30 -0000 1.129 +++ mainwindow.py 13 Apr 2004 10:10:34 -0000 1.130 @@ -641,8 +641,7 @@ self.add_dialog(name, dialog) dialog.Show(True) else: - # FIXME: bring dialog to front here - pass + dialog.Raise() def MapProjection(self): From cvs at intevation.de Tue Apr 13 15:15:25 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 13 Apr 2004 15:15:25 +0200 (CEST) Subject: joey: thuban/Extensions/wms parser.py,1.5,1.6 Message-ID: <20040413131525.B9FF913AE9@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv32237 Modified Files: parser.py Log Message: Use a variable for denoting the sample filename Index: parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/parser.py,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- parser.py 10 Apr 2004 19:12:41 -0000 1.5 +++ parser.py 13 Apr 2004 13:15:22 -0000 1.6 @@ -482,13 +482,14 @@ import os + sample = "test/sample.xml" try: - f = open("test/sample.xml", "r") + f = open(sample, "r") except IOError: try: - f = open(os.path.dirname(__file__) + "/test/sample.xml", "r") + f = open(os.path.dirname(__file__) + "/" + sample, "r") except IOError: - print "Cannot open sample.xml for reading" + print "Cannot open %s for reading" % sample if f is not None: sample = f.read(); From joey at infodrom.org Tue Apr 13 15:22:38 2004 From: joey at infodrom.org (Martin Schulze) Date: Tue, 13 Apr 2004 15:22:38 +0200 Subject: Context menu cursor Message-ID: <20040413132238.GI1655@finlandia.infodrom.north.de> Hi, I noticed that when I'm in the layer selection and press the right mouse button to let the context menu pop up, the cursor is changed from the Thuban arrow into the X cross. Is this intentional? I wouldn't expect this, but rather the opposite, since an arrow seems to be more adequate for a menu. Regards, Joey -- GNU does not eliminate all the world's problems, only some of them. -- The GNU Manifesto From bh at intevation.de Tue Apr 13 15:29:26 2004 From: bh at intevation.de (Bernhard Herzog) Date: Tue, 13 Apr 2004 15:29:26 +0200 Subject: Context menu cursor In-Reply-To: <20040413132238.GI1655@finlandia.infodrom.north.de> (Martin Schulze's message of "Tue, 13 Apr 2004 15:22:38 +0200") References: <20040413132238.GI1655@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > I noticed that when I'm in the layer selection and press the right > mouse button to let the context menu pop up, the cursor is changed > from the Thuban arrow into the X cross. Doesn't happen here (I haven't updated CVS in a while, though, too busy with other projects). Could it have something to do with the busy cursors? Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From joey at infodrom.org Tue Apr 13 15:53:51 2004 From: joey at infodrom.org (Martin Schulze) Date: Tue, 13 Apr 2004 15:53:51 +0200 Subject: Context menu cursor In-Reply-To: References: <20040413132238.GI1655@finlandia.infodrom.north.de> Message-ID: <20040413135351.GK1655@finlandia.infodrom.north.de> Bernhard Herzog wrote: > > I noticed that when I'm in the layer selection and press the right > > mouse button to let the context menu pop up, the cursor is changed > > from the Thuban arrow into the X cross. > > Doesn't happen here (I haven't updated CVS in a while, though, too busy > with other projects). Could it have something to do with the busy > cursors? I noticed it before I started playing with cursors, and indeed when I disable the BusyCursor stuff in Thuban.UI.common the cursor is still changed to the standard X cross here. When it's not happening on your version, it may be another strange wx/GTK issue (like the colour dialog[1] you probably can't reproduce as well). Maybe one day I find time to track this problem as well... Regards, Joey [1] http://intevation.de/pipermail/thuban-devel/2004-March/000037.html -- GNU does not eliminate all the world's problems, only some of them. -- The GNU Manifesto From cvs at intevation.de Tue Apr 13 18:42:50 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 13 Apr 2004 18:42:50 +0200 (CEST) Subject: joey: thuban/Extensions/wms parser.py,1.6,1.7 Message-ID: <20040413164250.B45511398D@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv2948 Modified Files: parser.py Log Message: Added support for error messages during grok(). They will be aggregated in an array and may be displayed later. We may have to add a classification "Warning" and "Error" to this. That requires more experience, though, since not every error may be lethal. Index: parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/parser.py,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- parser.py 13 Apr 2004 13:15:22 -0000 1.6 +++ parser.py 13 Apr 2004 16:42:48 -0000 1.7 @@ -52,6 +52,8 @@ from domutils import getElementsByName, getElementByName +from Thuban import _ + class WMSCapabilitiesParser: """ Thuban class to parse capabilities supplied as large string. @@ -68,6 +70,7 @@ access = None formats = None srs_discrepancies = None + error = None def __init__(self): @@ -78,7 +81,7 @@ # Note that we must not initialise internal variables of the # class in a mutable way or it will be shared among all # instances. None is immutable, [] is not. - layers = [] + self.error = [] def grok(self, data): @@ -152,6 +155,10 @@ foo = getElementByName(top, 'Title') if foo and len(foo.childNodes[0].data): self.layers[index]['title'] = foo.childNodes[0].data + else: + # A is required for each layer, <name> is optional + # See OGC 01-068r3, 7.1.4.5.1 and 7.1.4.5.2 + self.error.append(_("No title found for layer #%d") % index) foo = getElementByName(top, 'Name') if foo and len(foo.childNodes[0].data): From cvs at intevation.de Tue Apr 13 18:50:16 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 13 Apr 2004 18:50:16 +0200 (CEST) Subject: joey: thuban/Extensions/wms/test sample.xml,1.2,1.3 Message-ID: <20040413165016.AFF911398D@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv3090/test Modified Files: sample.xml Log Message: Added AUTO:* SRS since they appear in the real world as well. Since we cannot handle them yet (OGCLib can't either), we will ignore them for the moment. Index: sample.xml =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/sample.xml,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- sample.xml 24 Mar 2004 17:07:08 -0000 1.2 +++ sample.xml 13 Apr 2004 16:50:14 -0000 1.3 @@ -140,7 +140,7 @@ <Layer queryable="1" opaque="0" cascaded="0"> <Name>sehenswuerdigkeiten</Name> <Title>Sehenswürdigkeiten - EPSG:31493 + EPSG:31493 AUTO:42003 AUTO:42005 From cvs at intevation.de Tue Apr 13 19:05:58 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 13 Apr 2004 19:05:58 +0200 (CEST) Subject: joey: thuban/Extensions/wms parser.py,1.7,1.8 Message-ID: <20040413170558.C3EB51398D@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv3336 Modified Files: parser.py Log Message: Added rudimentary support for non-EPSG SRS, i.e. ignore them for the moment by placing them into a variable which is currently unused. Also test whether the EPSG SRS is numerical as it should be and add an error message if it is not. Index: parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/parser.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- parser.py 13 Apr 2004 16:42:48 -0000 1.7 +++ parser.py 13 Apr 2004 17:05:56 -0000 1.8 @@ -170,9 +170,22 @@ if srs[0:5] == 'EPSG:': srs = srs[5:] try: - self.layers[index]['srs'].append(srs) - except KeyError: - self.layers[index]['srs'] = [srs] + int(srs) + try: + self.layers[index]['srs'].append(srs) + except KeyError: + self.layers[index]['srs'] = [srs] + except ValueError: + if srs[0:4].upper() == 'AUTO' \ + or srs[0:4].upper() == 'NONE': + try: + self.layers[index]['_srs_'].append(srs) + except KeyError: + self.layers[index]['_srs_'] = [srs] + else: + self.error.append(_("SRS '%s' is not numerical and not" + " AUTO/NONE in layer '%s'") \ + % (srs, self.layers[index]['title'])) foo = getElementByName(top, 'LatLonBoundingBox') if foo is not None: From jan at intevation.de Tue Apr 13 19:09:00 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Tue, 13 Apr 2004 19:09:00 +0200 Subject: WMS Extension not functional as from CVS Message-ID: <20040413170900.GA1846@intevation.de> Hi, I noticed that the WMS function is not function as from CVS right now. I get the following when selecting the predefined frida WMS: | Traceback (most recent call last): | File "/powerhome/jan/project/thuban/Thuban/UI/view.py", line 206, in | _do_redraw | if self.render_iter.next(): | ValueError: generator already executing | Traceback (most recent call last): | File "/powerhome/jan/project/thuban/Thuban/UI/view.py", line 206, in | _do_redraw | if self.render_iter.next(): | File "/powerhome/jan/project/thuban/Thuban/UI/view.py", line 255, in | _render_iterator | for cont in renderer.RenderMapIncrementally(): | File "/powerhome/jan/project/thuban/Thuban/UI/baserenderer.py", line | 213, in render_map_incrementally | for i in func(self, layer): | File "/powerhome/jan/project/thuban/Extensions/wms/wms.py", line 242, | in render_wms_layer | renderer.draw_raster_data(img, format) | File "/powerhome/jan/project/thuban/Thuban/UI/renderer.py", line 99, | in draw_raster_data | image = wxImageFromStream(stream, raster_format_map[format]) | KeyError: 'PNG' Furthermore, I wonder how to call the info dialog that I saw in the commit messages. Jan -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From cvs at intevation.de Tue Apr 13 19:16:22 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 13 Apr 2004 19:16:22 +0200 (CEST) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.16,1.17 Message-ID: <20040413171622.E431613B55@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv3680/test Modified Files: test_parser.py Log Message: Added a test for ignoring AUTO:* SRS Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- test_parser.py 30 Mar 2004 16:30:12 -0000 1.16 +++ test_parser.py 13 Apr 2004 17:16:20 -0000 1.17 @@ -166,6 +166,9 @@ self.compareLists(self.getLayerSRS('beschriftung'), ['31493', '31494', '31495']) + # SRS of a layer with AUTO SRS ignored + self.compareLists(self.getLayerSRS('sehenswuerdigkeiten'), ['31493']) + def test_LatLonBoundingBoxes(self): """ From cvs at intevation.de Tue Apr 13 19:17:42 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 13 Apr 2004 19:17:42 +0200 (CEST) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.17,1.18 Message-ID: <20040413171742.7DE1413B55@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv3737/test Modified Files: test_parser.py Log Message: Looks like I misinterpreted the specs. First of all, a element does not have to be specified. This could cause the program to fail if later a bbox will be requested which wasn't defined in the Capabilities XML. Secondly, since EPSG:3426 is the implicit spatial reference system for its values should be returned if the client requests a bounding box for SRS EPSG:3426, even if no was defined for EPSG:3426. Therefore added another test method to ensure the LatLonBoundingBox values will be returned if the request SRS is EPSG:3426. Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- test_parser.py 13 Apr 2004 17:16:20 -0000 1.17 +++ test_parser.py 13 Apr 2004 17:17:40 -0000 1.18 @@ -221,6 +221,27 @@ self.assertEquals(self.getLayerBBox('beschriftung', '31490'), None) + def test_LatLonBoundingBoxes_as_bboxes(self): + """ + Check if the LatLonBoundingBoxes are returned properly + """ + + # main LatLonBoundingBox + bbox = {'minx': "7.92881", 'miny': "52.2131", + 'maxx': "8.18349", 'maxy': "52.341"} + self.compareDicts(self.getLayerBBox('Osnabrueck', '4326'), bbox) + + # inherited LatLonBoundingBox + bbox = {'minx': "7.92881", 'miny': "52.2131", + 'maxx': "8.18349", 'maxy': "52.341"} + self.compareDicts(self.getLayerBBox('gewaesser', '4326'), bbox) + + # third layer non-inherited LatLonBoundingBox + bbox = {'minx': "7.93531", 'miny': "52.2328", + 'maxx': "8.17739", 'maxy': "52.3353"} + self.compareDicts(self.getLayerBBox('gewaesserpolyl', '4326'), bbox) + + def test_queryable(self): """ Check if layers are properly classified queryable or not From cvs at intevation.de Tue Apr 13 19:21:21 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 13 Apr 2004 19:21:21 +0200 (CEST) Subject: joey: thuban/Extensions/wms parser.py,1.8,1.9 Message-ID: <20040413172121.3221C13B55@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv3837 Modified Files: parser.py Log Message: Looks like I misinterpreted the specs. First of all, a element does not have to be specified. This could cause the program to fail if later a bbox will be requested which wasn't defined in the Capabilities XML. Secondly, since EPSG:3426 is the implicit spatial reference system for its values should be returned if the client requests a bounding box for SRS EPSG:3426, even if no was defined for EPSG:3426. Therefore whenever a native BoundingBox request cannot be fulfilled, check whether the requested SRS is EPSG:3426, in which case return the LatLonBoundingBox values. Index: parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/parser.py,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- parser.py 13 Apr 2004 17:05:56 -0000 1.8 +++ parser.py 13 Apr 2004 17:21:19 -0000 1.9 @@ -458,6 +458,10 @@ if srs in pivot['bbox']: return pivot['bbox'][srs] + # No matching BBox found, let's see if it was EPSG:4326 + if srs == '4326': + return self.getLayerLatLonBBox(name) + return None From cvs at intevation.de Tue Apr 13 19:31:03 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 13 Apr 2004 19:31:03 +0200 (CEST) Subject: joey: thuban/Extensions/wms wms.py,1.5,1.6 Message-ID: <20040413173103.C206D13B55@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv4084 Modified Files: wms.py Log Message: Reduce the list of supported graphic formats back to JPEG and BMP, PNG and others are too *cough* experimental... Sorry, Imeant to filter this out before I committed this part. Index: wms.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/wms.py,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- wms.py 11 Apr 2004 17:39:30 -0000 1.5 +++ wms.py 13 Apr 2004 17:31:01 -0000 1.6 @@ -201,7 +201,7 @@ image/wbmp or WBMP which refers to WAP bitmap format and is not supported by the included render engine. """ - prio = ['png', 'jpeg', 'jpg', 'tif', 'gif', 'bmp'] + prio = ['jpeg', 'bmp'] for p in prio: for f in formats: if f.lower().find(p) > -1: From joey at infodrom.org Tue Apr 13 19:35:47 2004 From: joey at infodrom.org (Martin Schulze) Date: Tue, 13 Apr 2004 19:35:47 +0200 Subject: WMS Extension not functional as from CVS In-Reply-To: <20040413170900.GA1846@intevation.de> References: <20040413170900.GA1846@intevation.de> Message-ID: <20040413173547.GR1655@finlandia.infodrom.north.de> Moin Jan! Jan-Oliver Wagner wrote: > I noticed that the WMS function is not function as from CVS right now. > I get the following when selecting the predefined frida WMS: > > | Traceback (most recent call last): > | File "/powerhome/jan/project/thuban/Thuban/UI/view.py", line 206, in > | _do_redraw [lots of declarations of love from Python] Oh, sorry. That's my fault. I didn't mean to include this in the patch when I committed it. I've reduced the list to JPEG and BMP now, with the longer list only in my local copy. > Furthermore, I wonder how to call the info dialog that I saw > in the commit messages. I can send you a patch that lets you call it, but it's too dirty for discussion, I guess. I planned to start discussing this for a real solution later (i.e. end of the week / next week). Regards, Joey -- GNU does not eliminate all the world's problems, only some of them. -- The GNU Manifesto From cvs at intevation.de Tue Apr 13 19:38:28 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 13 Apr 2004 19:38:28 +0200 (CEST) Subject: joey: thuban/Extensions/wms wms.py,1.6,1.7 Message-ID: <20040413173828.235E613B55@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv4285 Modified Files: wms.py Log Message: Reset an empty URL to None so that the subsequent program can depend on this, since the dialog will indeed return an empty URL, causing another declaration of love by Python. Index: wms.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/wms.py,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- wms.py 13 Apr 2004 17:31:01 -0000 1.6 +++ wms.py 13 Apr 2004 17:38:26 -0000 1.7 @@ -301,6 +301,8 @@ if dialog.ShowModal() == wxID_OK: url = dialog.url + if len(url) == 0: + url = None else: url = None dialog.Destroy() From cvs at intevation.de Tue Apr 13 21:28:08 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 13 Apr 2004 21:28:08 +0200 (CEST) Subject: joey: thuban/Extensions/wms parser.py,1.9,1.10 Message-ID: <20040413192808.12BAC13B44@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv6570 Modified Files: parser.py Log Message: Added support for oldstyle (WMS 1.0 apparently) image format specification. Index: parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/parser.py,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- parser.py 13 Apr 2004 17:21:19 -0000 1.9 +++ parser.py 13 Apr 2004 19:28:05 -0000 1.10 @@ -49,6 +49,7 @@ # $Id$ import xml.dom.minidom +from xml.dom import Node from domutils import getElementsByName, getElementByName @@ -118,11 +119,25 @@ and foo.childNodes[0].data.lower() != 'none': self.access = foo.childNodes[0].data - # Extract output format information - foo = getElementsByName( - getElementByName(getElementByName(getElementByName( - root, 'Capability'), 'Request'), 'GetMap'), 'Format') - self.formats = map((lambda i: i.childNodes[0].data), foo) + foo = getElementByName(getElementByName( + root, 'Capability'), 'Request') + + # Need to distinguish between Map and GetMap for v1.0 and v1.1 + bar = getElementByName(foo, 'GetMap') + if bar: + # WMS 1.1 + foo = getElementsByName(bar, 'Format') + self.formats = map((lambda i: i.childNodes[0].data), foo) + else: + # WMS 1.0 + foo = getElementByName(getElementByName( + foo, 'Map'), 'Format') + for node in foo.childNodes: + if node.nodeType == Node.ELEMENT_NODE: + try: + self.formats.append(node.nodeName) + except AttributeError: + self.formats = [node.nodeName] # Extract layer names self.layers = [] From cvs at intevation.de Tue Apr 13 21:28:49 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 13 Apr 2004 21:28:49 +0200 (CEST) Subject: joey: thuban ChangeLog,1.640,1.641 Message-ID: <20040413192849.9DE8A13B44@lists.intevation.de> Author: joey Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv6594 Modified Files: ChangeLog Log Message: Documenting the changes Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.640 retrieving revision 1.641 diff -u -d -r1.640 -r1.641 --- ChangeLog 11 Apr 2004 18:40:06 -0000 1.640 +++ ChangeLog 13 Apr 2004 19:28:47 -0000 1.641 @@ -1,3 +1,53 @@ +2004-04-13 Martin Schulze + + * Extensions/wms/parser.py (WMSCapabilitiesParser.grok): Added + support for oldstyle (WMS 1.0 apparently) image format + specification. + + * Extensions/wms/wms.py (WMSLayer.calcFormat): Reduce the list of + supported graphic formats back to JPEG and BMP, PNG and others are + too *cough* experimental... Sorry, I meant to filter this out + before I committed this part. This should make the WMS extension + run from CVS again. + (wms_dialog): Reset an empty URL to None so that the subsequent + program can depend on this, since the dialog will indeed return an + empty URL, causing another declaration of love by Python. + + * Extensions/wms/parser.py (WMSCapabilitiesParser.getLayerBBox): + Whenever a native BoundingBox request cannot be fulfilled, check + whether the requested SRS is EPSG:3426, in which case return the + LatLonBoundingBox values. + + * Extensions/wms/test/test_parser.py + (TestWMSCapabilitiesParser.test_LayerSRS): Added a test for + ignoring AUTO:* SRS. + (TestWMSCapabilitiesParser.test_LatLonBoundingBoxes_as_bboxes): + Added another test method to test whether the LatLonBoundingBox + values will be returned if BoundingBox values are requested with + SRS set to EPSG:3426. + + * Extensions/wms/parser.py (WMSCapabilitiesParser.peekLayers): + Added rudimentary support for non-EPSG SRS, i.e. ignore them for + the moment by placing them into a variable which is currently + unused. Also test whether the EPSG SRS is numerical as it should + be and add an error message if it is not. + + * Extensions/wms/test/sample.xml: Added AUTO:* SRS since they + appear in the real world as well. Since we cannot handle them yet + (OGCLib can't either), we will ignore them for the moment. + + * Extensions/wms/parser.py: Use a variable for denoting the sample + filename + (WMSCapabilitiesParser.peekLayers): Added support for error + messages during grok(). They will be aggregated in an array and + may be displayed later. We may have to add a classification + "Warning" and "Error" to this. That requires more experience, + though, since not every error may be lethal. + + * Thuban/UI/mainwindow.py (MainWindow.LayerShowTable): Raise the + ShowTable() dialog/frame when the user attempts to display it + while it has been opened before already and not closed again. + 2004-04-11 Martin Schulze * Extensions/wms/infodialog.py: Adjusted the class documentation From jan at intevation.de Wed Apr 14 09:53:06 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Wed, 14 Apr 2004 09:53:06 +0200 Subject: [Thuban-devel] Re: WMS Extension not functional as from CVS In-Reply-To: <20040413173547.GR1655@finlandia.infodrom.north.de> References: <20040413170900.GA1846@intevation.de> <20040413173547.GR1655@finlandia.infodrom.north.de> Message-ID: <20040414075306.GC2371@intevation.de> On Tue, Apr 13, 2004 at 07:35:47PM +0200, Martin Schulze wrote: > Jan-Oliver Wagner wrote: > > I noticed that the WMS function is not function as from CVS right now. > > I get the following when selecting the predefined frida WMS: > > > > | Traceback (most recent call last): > > | File "/powerhome/jan/project/thuban/Thuban/UI/view.py", line 206, in > > | _do_redraw > > [lots of declarations of love from Python] > > Oh, sorry. That's my fault. I didn't mean to include this in the > patch when I committed it. I've reduced the list to JPEG and BMP > now, with the longer list only in my local copy. works again :-) > > Furthermore, I wonder how to call the info dialog that I saw > > in the commit messages. > > I can send you a patch that lets you call it, but it's too dirty > for discussion, I guess. I planned to start discussing this for > a real solution later (i.e. end of the week / next week). end of this week/beginning of next is fine with me. Jan -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From cvs at intevation.de Thu Apr 15 09:13:33 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 15 Apr 2004 09:13:33 +0200 (CEST) Subject: joey: thuban/Extensions/wms layer.py,NONE,1.1 Message-ID: <20040415071333.E761913B85@lists.intevation.de> 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 # Martin Schulze # # 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 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 From cvs at intevation.de Thu Apr 15 09:14:28 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 15 Apr 2004 09:14:28 +0200 (CEST) Subject: joey: thuban/Extensions/wms wms.py,1.7,1.8 Message-ID: <20040415071428.0988113B89@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv27359 Modified Files: wms.py Log Message: Moved the WMS layer into layer.py in order to establish a clean structure. Index: wms.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/wms.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- wms.py 13 Apr 2004 17:38:26 -0000 1.7 +++ wms.py 15 Apr 2004 07:14:25 -0000 1.8 @@ -13,11 +13,6 @@ layer into Thuban via an extension. Some things are not wired, so be prepared for Exceptions everywhere. - -You will need PyOGCLib 0.1.0, see - http://pyogclib.sourceforge.net/ -Set the PYTHONPATH to the PyOGCLib directory before -starting Thuban. """ __version__ = "$Revision$" @@ -28,204 +23,20 @@ from wxPython.wx import * -from ogclib.WMSClient import WMSClient - -from Thuban.Model.layer import BaseLayer from Thuban.Model.proj import Projection from Thuban.Model.extension import Extension -from Thuban.Model.resource import get_system_proj_file, EPSG_PROJ_FILE, \ - EPSG_DEPRECATED_PROJ_FILE from Thuban.UI.command import registry, Command import Thuban.UI.mainwindow -from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor from Thuban import _ import Thuban.UI.baserenderer -from capabilities import WMSCapabilities - -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) +from layer import WMSLayer - 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 WMSExtension(Extension): def TreeInfo(self): return (_("Extension: %s") % self.title, [ object.TreeInfo() for object in self.objects ]) - -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 def render_wms_layer(renderer, layer): From cvs at intevation.de Thu Apr 15 09:40:34 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 15 Apr 2004 09:40:34 +0200 (CEST) Subject: joey: thuban/Extensions/wms layer.py,1.1,1.2 Message-ID: <20040415074034.B6BE1139AB@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv27882 Modified Files: layer.py Log Message: Added more documentation Index: layer.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/layer.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- layer.py 15 Apr 2004 07:13:31 -0000 1.1 +++ layer.py 15 Apr 2004 07:40:32 -0000 1.2 @@ -23,6 +23,13 @@ class WMSLayer: __init__() + LatLongBoundingBox() + BoundingBox() + + getFormat(format) + calcFormat(formats) + + GetMapImg(width, height, bbox) Requirements: - PyOGCLib @@ -66,6 +73,12 @@ class WMSLayer(BaseLayer): + """ + WMS Layer + + This layer incorporates all methods from the Thuban BaseLayer and + adds specific methods for operating with a WMS server. + """ def __init__(self, title, url): """Initializes the WMSLayer. @@ -147,12 +160,15 @@ def LatLongBoundingBox(self): - """Return the layer's bounding box in lat-lon. + """ + 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 the layer's bounding box in the intrinsic coordinate system """ return self.bbox @@ -163,7 +179,11 @@ format -- format as returned by the WMS server - If no mapping was found, None is returned + If no mapping was found, None is returned. + + This routine uses a simple heuristic in order to find the + broken down image format to be used with the internal render + engine. An exception rule is implemented in order to not accept image/wbmp or WBMP which refers to WAP bitmap format and is @@ -212,6 +232,16 @@ def GetMapImg(self, width, height, bbox): + """ + Retrieve a new map from the WMS server and return it + + width -- width in pixel of the desired image + height -- height in pixel of the desired image + bbox -- array of min(x,y) max(x,y) in the given SRS + + SRS and used image format will be retrieved from within the + layer itself. + """ bbox_dict = { 'minx': bbox[0], 'miny': bbox[1], 'maxx': bbox[2], 'maxy': bbox[3] } From cvs at intevation.de Thu Apr 15 10:52:49 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 15 Apr 2004 10:52:49 +0200 (CEST) Subject: joey: thuban/Extensions/wms layer.py,1.2,1.3 Message-ID: <20040415085249.C594B139AA@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv29132 Modified Files: layer.py Log Message: Added more convenience methods for a clear data exchange Index: layer.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/layer.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- layer.py 15 Apr 2004 07:40:32 -0000 1.2 +++ layer.py 15 Apr 2004 08:52:47 -0000 1.3 @@ -29,6 +29,13 @@ getFormat(format) calcFormat(formats) + getFormats() + getLayers() + getLayerTitle() + + getWMSFormat() + setWMSFormat(format) + GetMapImg(width, height, bbox) Requirements: @@ -230,6 +237,62 @@ return f, self.getFormat(f) return None, None + + def getFormats(self): + """ + Return the list of supported image formats by the WMS server + + These formats may be used in the WMS GetMap request. Data is + retrieved from the included WMSCapabilities object. + + The called method from WMSCapabilities will default to + 'image/jpeg' if no format is recognised in XML Capabilities, + assuming that JPEG will always be supported on the server side + with this encoding. + """ + return self.capabilities.getFormats() + + + def getLayers(self): + """ + Return the list of layer names supported by the WMS server + + Data is retrieved from the included WMSCapabilities object. + + Only named layers will be returned, since a layer may have a + title but doesn't have to have a name associated to it as + well. If no layers were found, an empty list is returned. + """ + return self.capabilities.getLayers() + + + def getLayerTitle(self, layer): + """ + Return the title of the named layer + + Data is retrieved from the included WMSCapabilities object. + + If no such title or no such layer exists, an empty string is + returned. + """ + return self.capabilities.getLayerTitle(layer) + + + def getWMSFormat(self): + """ + Return the image format that is used for WMS GetMap requests + """ + return self.wmsformat + + + def setWMSFormat(self, format): + """ + Set the image format that is used for WMS GetMap requests + + format -- format, one of getFormats() + """ + self.wmsformat = format + def GetMapImg(self, width, height, bbox): """ From cvs at intevation.de Thu Apr 15 18:06:26 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 15 Apr 2004 18:06:26 +0200 (CEST) Subject: joey: thuban/Extensions/wms layer.py,1.3,1.4 Message-ID: <20040415160626.7464B139AE@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv3794 Modified Files: layer.py Log Message: Move away from using only one layer to using a list of layers (unsorted at the moment, though). Added two convenience methods for retrieving and setting the list of visible layers (get/setVisibleLayers) Index: layer.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/layer.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- layer.py 15 Apr 2004 08:52:47 -0000 1.3 +++ layer.py 15 Apr 2004 16:06:24 -0000 1.4 @@ -101,7 +101,7 @@ self.bbox = None self.latlonbbox = None self.error_msg = None - self.layer_name = None + self.wms_layers = [] self.capabilities = None # Change the cursor to demonstrate that we're busy but working @@ -116,7 +116,7 @@ '%s') % url return top_layer = foo[0] - self.layer_name = top_layer + self.wms_layers = [top_layer] # first projection of the top layer foo = self.capabilities.getLayerSRS(top_layer) @@ -294,6 +294,22 @@ self.wmsformat = format + def getVisibleLayers(self): + """ + Return the list of names for all visible layers + + """ + return self.wms_layers + + + def setVisibleLayers(self, layers): + """ + Set the list of names for all visible layers + + """ + self.wms_layers = layers + + def GetMapImg(self, width, height, bbox): """ Retrieve a new map from the WMS server and return it @@ -317,6 +333,6 @@ wms_response = wmsclient.getMap(self.url, self.wmsformat, width, height, epsg_id, bbox_dict, - [self.layer_name], version = self.capabilities.getVersion()) + self.wms_layers, version = self.capabilities.getVersion()) ThubanEndBusyCursor() return wms_response, self.format From cvs at intevation.de Thu Apr 15 18:14:53 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 15 Apr 2004 18:14:53 +0200 (CEST) Subject: joey: thuban/Extensions/wms properties.py,NONE,1.1 Message-ID: <20040415161453.76F40139AE@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv3889 Added Files: properties.py Log Message: First start for a properties dialog. I'm not too happy with it at the moment but it's functional for a first selection of layers. It also has some wxWidgets/GTK problems but beautification can be done later as well. --- NEW FILE: properties.py --- # Copyright (c) 2004 by Intevation GmbH # Authors: # Martin Schulze # # 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 """ Edit Layer Properties class wmsProperties(NonModalNonParentDialog): __init__ dialog_layout(text) OnOK(event) OnCancel(event) Problems: 1. The wxTextCtrl should fit to the right side of the horizontal box/sizer. It doesn't. I only found the sizer.Add() method to be able to take proportions but no way to tell the object to fill all remaining space. 2. The framed box "Layers" needs to be scrollable if there are more than 12 items, since the dialog would probably not fit on people's screen anymore. Todo: This can be solved (in C it was possible at least), probably with wxScrolledWindow 3. The button hbox is not aligned to the right side which should be. For some reason wxALIGN_RIGHT does not have any effect. Maybe I just misunderstood the documentation? """ __version__ = "$Revision: 1.1 $" # $Source: /thubanrepository/thuban/Extensions/wms/properties.py,v $ # $Id: properties.py,v 1.1 2004/04/15 16:14:51 joey Exp $ from Thuban import _ from Thuban.UI.dialogs import NonModalNonParentDialog from wxPython.wx import * # wxBoxSizer, wxVERTICAL, wxHORIZONTAL, \ # wxButton, wxID_OK, wxID_CANCEL, wxALL, wxALIGN_CENTER_HORIZONTAL, \ # EVT_BUTTON, wxEXPAND, wxStaticBoxSizer, wxStaticBox, wxALIGN_RIGHT, \ # wxALIGN_BOTTOM ID_WMS_TITLE = 5001 ID_WMS_LAYER = 5002 ID_WMS_FORMATS = 5003 MAX_LAYERNAME_LENGTH = 45 MAX_VISIBLE_LAYERS = 12 class wmsProperties(NonModalNonParentDialog): """ Representation for the WMS properties dialog """ def __init__(self, parent, name, layer): """ Build the properties dialog """ title = _("Edit WMS Properties") NonModalNonParentDialog.__init__(self, parent, name, title) self.layer = layer # Hooks for the widgets to get user data self.entry = None self.layers = {} self.formats = None self.dialog_layout(layer) def dialog_layout(self, layer): """ Set up the information dialog """ # main box for the entire dialog mainbox = wxBoxSizer(wxHORIZONTAL) # vertical box to contain the three parts # (title, layers, formats+buttons) vbox = wxBoxSizer(wxVERTICAL) mainbox.Add(vbox, 0, wxALL|wxEXPAND, 4) # edit the title hbox = wxBoxSizer(wxHORIZONTAL) vbox.Add(hbox, 0, wxALL, 0) label = wxStaticText(self, ID_WMS_TITLE, _("Title:")) hbox.Add(label, 1, wxALL|wxEXPAND, 4) self.entry = wxTextCtrl(self, ID_WMS_TITLE, layer.Title()) hbox.Add(self.entry, 7, wxALL|wxEXPAND|wxALIGN_RIGHT, 0) layerbox = wxStaticBox(self, ID_WMS_LAYER, _("Layers")) lbox = wxStaticBoxSizer(layerbox, wxVERTICAL) vbox.Add(lbox, 0, wxALL, 0) visible = layer.getVisibleLayers() for l in layer.getLayers(): checker = wxCheckBox(self, ID_WMS_LAYER, layer.getLayerTitle(l)[0:MAX_LAYERNAME_LENGTH].encode('latin1')) self.layers[l] = checker if l in visible: checker.SetValue(True) lbox.Add(checker, 0, wxALL|wxEXPAND, 0) # tiled box: hbox = wxBoxSizer(wxHORIZONTAL) vbox.Add(hbox, 0, wxALL|wxEXPAND, 0) # left part: image format selection formatbox = wxBoxSizer(wxHORIZONTAL) hbox.Add(formatbox, 1, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 0) label = wxStaticText(self, ID_WMS_FORMATS, _("Format:")) formatbox.Add(label, 0, wxALL|wxALIGN_CENTER_VERTICAL, 4) self.formats = wxChoice(self, ID_WMS_FORMATS) formatbox.Add(self.formats, 1, wxALL|wxEXPAND|wxALIGN_CENTER_VERTICAL, 4) # fill the select box match = 0 count = 0 format = layer.getWMSFormat() for f in layer.getFormats(): self.formats.Append(f) if f == format: match = count count += 1 self.formats.Fit() self.formats.SetSelection(match) # Build the button hbox, to be added into row buttons = wxBoxSizer(wxHORIZONTAL) hbox.Add(buttons, 1, wxALL|wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT, 0) buttons.Add(wxButton(self, wxID_OK, _("OK")), 0, wxALL, 4) buttons.Add(wxButton(self, wxID_CANCEL, _("Cancel")), 0, wxALL, 4) EVT_BUTTON(self, wxID_OK, self.OnOK) EVT_BUTTON(self, wxID_CANCEL, self.OnCancel) self.SetAutoLayout(True) self.SetSizer(mainbox) mainbox.Fit(self) mainbox.SetSizeHints(self) def OnOK(self, event): """ Handle the 'OK button pressed' event i.e. transfer user input into the layer """ # Set the title self.layer.SetTitle(self.entry.GetValue()) # Set the image format for WMS GetMap requests selection = self.formats.GetSelection() if selection > -1: self.layer.setWMSFormat(self.formats.GetString(self.formats.GetSelection())) # Set the list of visible layers visible = [] for l in self.layers.keys(): if self.layers[l].IsChecked(): visible.append(l) self.layer.setVisibleLayers(visible) self.Close() def OnCancel(self, event): """ Handle the 'Cancel button pressed' event """ self.Close() def OpenWMSProperties(parent, layer): """ Open or raise the WMS properties dialog """ name = "layer_properties_" + layer.url dialog = parent.get_open_dialog(name) if dialog is None: dialog = wmsProperties(parent, name, layer) parent.add_dialog(name, dialog) dialog.Show(True) else: dialog.Raise() From cvs at intevation.de Thu Apr 15 19:28:06 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 15 Apr 2004 19:28:06 +0200 (CEST) Subject: joey: thuban/Extensions/wms layer.py,1.4,1.5 Message-ID: <20040415172806.8CC11139AE@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv4738 Modified Files: layer.py Log Message: Need to recalculate the format for the internal render engine as well. Index: layer.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/layer.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- layer.py 15 Apr 2004 16:06:24 -0000 1.4 +++ layer.py 15 Apr 2004 17:28:04 -0000 1.5 @@ -292,6 +292,7 @@ format -- format, one of getFormats() """ self.wmsformat = format + self.format = self.getFormat(format) def getVisibleLayers(self): From joey at infodrom.org Thu Apr 15 20:00:39 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 15 Apr 2004 20:00:39 +0200 Subject: Status: WMS Client Functionality Message-ID: <20040415180039.GE1655@finlandia.infodrom.north.de> Hi, this is just another quick status update on my work with regards to the WMS client capability of Thuban. I have a local version of the WMS client subsystem which bails out for less WMS resources compared with before, due to adjusted and more failure tolerant Capabilities XML parsing. I have created an information dialog that displays some general information about the used layer for which the dialog was opened. It will display the title, the abstract, fees, access constraints if the are present as well as the URL of the resource. I have also created a first version of a properties dialog so the user gets a possibility to configure the WMS layer. With this it is possible to change the used image format and the layer or list of layers that are retrieved and displayed. I'll add more details in another mail. For completeness the user can edit the title in this dialog as well (and in Layer -> Rename). These dialogs are not yet reachable through the CVS version, though. Their integration are subject of another mail and discussion. Regards, Joey -- It's time to close the windows. From joey at infodrom.org Thu Apr 15 20:08:42 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 15 Apr 2004 20:08:42 +0200 Subject: Status: Layer organisation Message-ID: <20040415180842.GF1655@finlandia.infodrom.north.de> Hi, since it is now possible to select which layer the WMS server should render for Thuban, it starts to make sense to mix WMS resources with local resources or with other WMS resources. For example, it could be easier and faster for hide some layers and re-display them later. However, this does require transparent layers which can be stacked. In trying this, it seems that I have opened a can of worms: 1. Transparency is not supported by JPEG, but only by PNG (through an alpha channel), GIF and probably BMP. 2. The internal render engine from Thuban does only support BMP and JPEG at the moment. At least on GNU/Linux it is no problem to support PNG, TIFF and GIF as well. See [1]. 3. The frida server only supports JPEG, PNG, GIF and WBMP. WBMP is Wap Bitmap, something you may find useful on your mobile phone but not on a standalone computer. 4. At least the frida server supports transparent PNG and transparent GIF images. See [2] as an example. 5. Even after I added support for PNG and GIF (see [1]) the results were not promising since the transparent background was rendered in a bright pink tone (#FF00FF), a nice colour but not exactly suited for transparency. As a result of 1 and 2 the CVS version of Thuban does not support transparent image layers. Bummer. As a result of 1, 2 and 3 it is not possible with the CVS version of Thuban to use more than one layer of frida. As a result of 5 it is currently not posible to use multiple image or WMS layers with Thuban. I had hoped that transparent images would be supported since that would have delivered such a nice presentation tomorrow (I need to give a talk about WMS to members of the environmental computer science). Todo: 1. I guess that we should see if we can support more graphics formats. That's easily doable, but there may be a good reason for limiting support to BMP and JPEG. 2. If 1. we should see why transparency is currently not supported by Thuban and see if we can fix this. Links: 1. http://intevation.de/pipermail/thuban-devel/2004-April/000094.html 2. http://frida.intevation.org/cgi-bin/frida_wms?LAYERS=Osnabrueck&STYLES=&SERVICE=WMS&SRS=EPSG%3A31493&FORMAT=image%2Fpng&REQUEST=GetMap&HEIGHT=600&WIDTH=800&VERSION=1.1&BBOX=3426792.643114%2C5786721.353642%2C3444358.076702%2C5801282.173590&TRANSPARENT=TRUE Regards, Joey -- It's time to close the windows. From cvs at intevation.de Thu Apr 15 20:23:28 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 15 Apr 2004 20:23:28 +0200 (CEST) Subject: joey: thuban ChangeLog,1.641,1.642 Message-ID: <20040415182328.A3823139AE@lists.intevation.de> Author: joey Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv5270 Modified Files: ChangeLog Log Message: Document my changes Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.641 retrieving revision 1.642 diff -u -d -r1.641 -r1.642 --- ChangeLog 13 Apr 2004 19:28:47 -0000 1.641 +++ ChangeLog 15 Apr 2004 18:23:26 -0000 1.642 @@ -1,3 +1,36 @@ +2004-04-15 Martin Schulze + + * Extensions/wms/layer.py (WMSLayer.setWMSFormat): Need to + recalculate the format for the internal render engine as well. + + * Extensions/wms/properties.py (wmsProperties): First start for a + properties dialog. It's functional for a first selection of + layers, but still has some weired wxWidgets/GTK problems but + beautification can be done later. + + * Extensions/wms/layer.py: Added more documentation + (WMSLayer.getFormats): New: Return list of supported image formats + by the WMS server + (WMSLayer.getLayers): New: Return the list of layer names + supported by the WMS server + (WMSLayer.getLayerTitle): New: Return the title of the named layer + (WMSLayer.getWMSFormat): New: Return the image format that is used + for WMS GetMap requests + (WMSLayer.setWMSFormat): New: Set the image format that is used + for WMS GetMap requests + (WMSLayer.__init__): Move away from using only one layer to using + a list of layers (unsorted at the moment, though). + (WMSLayer.getVisibleLayers): New: Return the list of names for all + visible layers + (WMSLayer.setVisibleLayers): New: Set the list of names for all + visible layers + + * Extensions/wms/wms.py: Moved the WMS layer into layer.py in + order to establish a clean structure. + + * Extensions/wms/layer.py: Moved the WMS layer into a file on its + own in order to establish a clean structure. + 2004-04-13 Martin Schulze * Extensions/wms/parser.py (WMSCapabilitiesParser.grok): Added From joey at infodrom.org Thu Apr 15 20:20:50 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 15 Apr 2004 20:20:50 +0200 Subject: RfD: Support for layer specific resources Message-ID: <20040415182050.GH1655@finlandia.infodrom.north.de> Hi! In the past, Thuban supported mostly local layers. As a result, several dialogs were not classified layer-specific and hence controlled through a general control within Thuban. This poses a problem since the general control of Thuban which also creates menus and legends thinks that all layers are "normal" layers. As a result, if you try to open the properties dialog for a WMS layer, Python will declare its love for you. It will do the very same if you try to display the Table ("Show Table" on the context menu) for the current layer. I guess that we should start to discuss how we could move layer-specfic dialogs into the control of the dialog and add global hooks where the layer can registrate features (dialog boxes and the like) in the menu, legend (context menu), icon box, and main menu. For this particular problem the source is in Thuban/UI/legend.py for the Properties dialog and Thuban/UI/mainwindow.py for the Show Table dialog If you read the backtrace Python prepares for you when you try to open these dialogs, you'll see that this is buried deep in Thuban. As a temporary local workaround in order to support the new information and properties dialogs I have hooked them into the system and modified the above mentioned files. However, in my oppinion this is way too dirty and too much of a klugde to propose it as a general solution. I may be willing to distribute the patches in private but don't want to see them committed. So... Comments? Regards, Joey -- It's time to close the windows. From bernhard at intevation.de Thu Apr 15 21:26:06 2004 From: bernhard at intevation.de (Bernhard Reiter) Date: Thu, 15 Apr 2004 21:26:06 +0200 Subject: RfD: Support for layer specific resources In-Reply-To: <20040415182050.GH1655@finlandia.infodrom.north.de> References: <20040415182050.GH1655@finlandia.infodrom.north.de> Message-ID: <20040415192606.GW22347@intevation.de> On Thu, Apr 15, 2004 at 08:20:50PM +0200, Martin Schulze wrote: > In the past, Thuban supported mostly local layers. As a result, > several dialogs were not classified layer-specific and hence > controlled through a general control within Thuban. This poses a > problem since the general control of Thuban which also creates menus > and legends thinks that all layers are "normal" layers. Another problem that comes with "remote" layers is buffering. We saw that with the postgis tables already, but I also expect this to be a problem with your layers, too. We do not only need layers specific information, but also general and layer specific buffering methods. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://www.intevation.de/pipermail/thuban-devel/attachments/20040415/0b74c9b0/attachment.bin From joey at infodrom.org Fri Apr 16 07:38:27 2004 From: joey at infodrom.org (Martin Schulze) Date: Fri, 16 Apr 2004 07:38:27 +0200 Subject: RfD: Support for layer specific resources In-Reply-To: <20040415192606.GW22347@intevation.de> References: <20040415182050.GH1655@finlandia.infodrom.north.de> <20040415192606.GW22347@intevation.de> Message-ID: <20040416053827.GM1655@finlandia.infodrom.north.de> Bernhard Reiter wrote: > On Thu, Apr 15, 2004 at 08:20:50PM +0200, Martin Schulze wrote: > > In the past, Thuban supported mostly local layers. As a result, > > several dialogs were not classified layer-specific and hence > > controlled through a general control within Thuban. This poses a > > problem since the general control of Thuban which also creates menus > > and legends thinks that all layers are "normal" layers. > > Another problem that comes with "remote" layers is buffering. Yes. I've already thought about caching since on a slow line it takes a while to retrieve the remote image. > We saw that with the postgis tables already, > but I also expect this to be a problem with your layers, too. True. I thought about hooking an image cache into the WMSLayer.GetMapImg(). I've also thought about buffering the current image locally so it doesn't have to be retrieved when the image needs to be rendered again (for hide/unhide for example). > We do not only need layers specific information, > but also general and layer specific buffering methods. What kinds of data need to be buffered with postgis tables? I'd expect this to be tons of rows from SQL queries. Is that true? Anything else that should be buffered/cached in Thuban? Regards, Joey -- Long noun chains don't automatically imply security. -- Bruce Schneier From cvs at intevation.de Fri Apr 16 09:57:16 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Fri, 16 Apr 2004 09:57:16 +0200 (CEST) Subject: jan: thuban/Thuban/UI exceptiondialog.py,1.1,1.2 Message-ID: <20040416075716.3B3B81398D@lists.intevation.de> Author: jan Update of /thubanrepository/thuban/Thuban/UI In directory doto:/tmp/cvs-serv20263 Modified Files: exceptiondialog.py Log Message: (ExceptionDialog.dialog_layout): Improved button string to stronger clearify that Thuban will be closed when hitting the button. Index: exceptiondialog.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/exceptiondialog.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- exceptiondialog.py 3 Sep 2003 06:58:47 -0000 1.1 +++ exceptiondialog.py 16 Apr 2004 07:57:13 -0000 1.2 @@ -41,7 +41,7 @@ box = wxBoxSizer(wxHORIZONTAL) box.Add(wxButton(self, wxID_OK, _("Proceed")), 0, wxALL, 4) - box.Add(wxButton(self, wxID_CANCEL, _("Exit")), 0, wxALL, 4) + box.Add(wxButton(self, wxID_CANCEL, _("Exit Thuban now")), 0, wxALL, 4) top_box.Add(box, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 10) EVT_BUTTON(self, wxID_OK, self.OnOK) From cvs at intevation.de Fri Apr 16 10:21:15 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Fri, 16 Apr 2004 10:21:15 +0200 (CEST) Subject: jan: thuban/Thuban/UI mainwindow.py,1.130,1.131 Message-ID: <20040416082115.EEEC513B53@lists.intevation.de> Author: jan Update of /thubanrepository/thuban/Thuban/UI In directory doto:/tmp/cvs-serv20624 Modified Files: mainwindow.py Log Message: (MainWindow.LayerShowTable): Added docstring. Now for layers without a ShapeStore a corresponding message is given to the user, that this layer has no table to show. Index: mainwindow.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/mainwindow.py,v retrieving revision 1.130 retrieving revision 1.131 diff -u -d -r1.130 -r1.131 --- mainwindow.py 13 Apr 2004 10:10:34 -0000 1.130 +++ mainwindow.py 16 Apr 2004 08:21:12 -0000 1.131 @@ -629,8 +629,19 @@ return layer is not None and hasattr(layer, "ShapeStore") def LayerShowTable(self): + """ + Present a TableView Window for the current layer. + In case the window is already open, bring it to the front. + In case, there is no active layer, do nothing. + In case, the layer has not ShapeStore, raise a corresponding message dialog + and do nothing else. + """ layer = self.current_layer() if layer is not None: + if not hasattr(layer, "ShapeStore"): + self.RunMessageBox(_("Show Table"), + _("The layer '%s' has no table." % layer.Title())) + return table = layer.ShapeStore().Table() name = "table_view" + str(id(table)) dialog = self.get_open_dialog(name) From cvs at intevation.de Fri Apr 16 10:21:49 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Fri, 16 Apr 2004 10:21:49 +0200 (CEST) Subject: jan: thuban ChangeLog,1.642,1.643 Message-ID: <20040416082149.D131313B79@lists.intevation.de> Author: jan Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv20658 Modified Files: ChangeLog Log Message: fixed a bug and improved a string Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.642 retrieving revision 1.643 diff -u -d -r1.642 -r1.643 --- ChangeLog 15 Apr 2004 18:23:26 -0000 1.642 +++ ChangeLog 16 Apr 2004 08:21:47 -0000 1.643 @@ -1,3 +1,13 @@ +2004-04-16 Jan-Oliver Wagner + + * Thuban/UI/exceptiondialog.py (ExceptionDialog.dialog_layout): Improved + button string to stronger clearify that Thuban will be closed when hitting + the button. + + * Thuban/UI/mainwindow.py (MainWindow.LayerShowTable): Added docstring. + Now for layers without a ShapeStore a corresponding message is given + to the user, that this layer has no table to show. + 2004-04-15 Martin Schulze * Extensions/wms/layer.py (WMSLayer.setWMSFormat): Need to From bh at intevation.de Fri Apr 16 10:49:51 2004 From: bh at intevation.de (Bernhard Herzog) Date: Fri, 16 Apr 2004 10:49:51 +0200 Subject: jan: thuban/Thuban/UI mainwindow.py,1.130,1.131 In-Reply-To: <20040416082115.EEEC513B53@lists.intevation.de> (cvs@intevation.de's message of "Fri, 16 Apr 2004 10:21:15 +0200 (CEST)") References: <20040416082115.EEEC513B53@lists.intevation.de> Message-ID: cvs at intevation.de writes: > def LayerShowTable(self): > + """ > + Present a TableView Window for the current layer. > + In case the window is already open, bring it to the front. > + In case, there is no active layer, do nothing. > + In case, the layer has not ShapeStore, raise a corresponding message dialog > + and do nothing else. > + """ > layer = self.current_layer() > if layer is not None: > + if not hasattr(layer, "ShapeStore"): > + self.RunMessageBox(_("Show Table"), > + _("The layer '%s' has no table." % layer.Title())) > + return I don't think we should raise a dialog box here. We don't show one either when there's no selection. We should make sure that the commands that call this method are grayed out. The one in the main window does this with the has_selected_shape_layer method. The context menu should do something similar if it doesn't do that yet. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From joey at infodrom.org Fri Apr 16 11:57:58 2004 From: joey at infodrom.org (Martin Schulze) Date: Fri, 16 Apr 2004 11:57:58 +0200 Subject: jan: thuban/Thuban/UI mainwindow.py,1.130,1.131 In-Reply-To: References: <20040416082115.EEEC513B53@lists.intevation.de> Message-ID: <20040416095758.GD1655@finlandia.infodrom.north.de> Bernhard Herzog wrote: > I don't think we should raise a dialog box here. We don't show one > either when there's no selection. We should make sure that the commands > that call this method are grayed out. The one in the main window does > this with the has_selected_shape_layer method. The context menu should > do something similar if it doesn't do that yet. I would like layers be able to hook more dialogs/windows/control into the menu or context menu instead of only disabling existing entries. At least for the main menu, this is possible in general, but doesn't seem to be possible on a per-layer basis. Regards, Joey -- Long noun chains don't automatically imply security. -- Bruce Schneier From bernhard at intevation.de Fri Apr 16 12:27:18 2004 From: bernhard at intevation.de (Bernhard Reiter) Date: Fri, 16 Apr 2004 12:27:18 +0200 Subject: RfD: Support for layer specific resources In-Reply-To: <20040416053827.GM1655@finlandia.infodrom.north.de> References: <20040415182050.GH1655@finlandia.infodrom.north.de> <20040415192606.GW22347@intevation.de> <20040416053827.GM1655@finlandia.infodrom.north.de> Message-ID: <20040416102718.GF15457@intevation.de> On Fri, Apr 16, 2004 at 07:38:27AM +0200, Martin Schulze wrote: > Bernhard Reiter wrote: > > On Thu, Apr 15, 2004 at 08:20:50PM +0200, Martin Schulze wrote: > > > In the past, Thuban supported mostly local layers. As a result, > > > several dialogs were not classified layer-specific and hence > > > controlled through a general control within Thuban. This poses a > > > problem since the general control of Thuban which also creates menus > > > and legends thinks that all layers are "normal" layers. > > > > Another problem that comes with "remote" layers is buffering. > > Yes. I've already thought about caching since on a slow line it > takes a while to retrieve the remote image. > > > We saw that with the postgis tables already, > > but I also expect this to be a problem with your layers, too. > > True. > > I thought about hooking an image cache into the WMSLayer.GetMapImg(). > > I've also thought about buffering the current image locally so > it doesn't have to be retrieved when the image needs to be rendered > again (for hide/unhide for example). That is the major point I guess. Most redraws will not warrant a new remote fetch. Remote fetches are expensive in general, especially if the line is slow or the server underload. The possibility to keep stuff on the client is very important. It must be configuration in cases the client is a smaller machine. > > We do not only need layers specific information, > > but also general and layer specific buffering methods. > > What kinds of data need to be buffered with postgis tables? The problem is the same as above. I just do not know on which level of Thuban the caching is best. > I'd expect this to be tons of rows from SQL queries. Is that true? It depends, could be. We could buffer it later in the processing pipeline. But buffering SQL result would be a good start. > Anything else that should be buffered/cached in Thuban? Probably a lot. :) -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://www.intevation.de/pipermail/thuban-devel/attachments/20040416/918a5912/attachment.bin From frank.koormann at intevation.de Fri Apr 16 13:04:55 2004 From: frank.koormann at intevation.de (Frank Koormann) Date: Fri, 16 Apr 2004 13:04:55 +0200 Subject: RfD: Support for layer specific resources In-Reply-To: <20040416102718.GF15457@intevation.de> References: <20040415182050.GH1655@finlandia.infodrom.north.de> <20040415192606.GW22347@intevation.de> <20040416053827.GM1655@finlandia.infodrom.north.de> <20040416102718.GF15457@intevation.de> Message-ID: <20040416110455.GC24414@intevation.de> * Bernhard Reiter [040416 12:27]: > On Fri, Apr 16, 2004 at 07:38:27AM +0200, Martin Schulze wrote: > > I thought about hooking an image cache into the WMSLayer.GetMapImg(). > > > > I've also thought about buffering the current image locally so > > it doesn't have to be retrieved when the image needs to be rendered > > again (for hide/unhide for example). > > That is the major point I guess. > Most redraws will not warrant a new remote fetch. > Remote fetches are expensive in general, > especially if the line is slow or the server underload. > The possibility to keep stuff on the client is very important. > It must be configuration in cases the client is a smaller machine. > > > > We do not only need layers specific information, > > > but also general and layer specific buffering methods. > > > > What kinds of data need to be buffered with postgis tables? > > The problem is the same as above. > I just do not know on which level of Thuban the caching is best. > > > I'd expect this to be tons of rows from SQL queries. Is that true? > > It depends, could be. > We could buffer it later in the processing pipeline. > But buffering SQL result would be a good start. > > > Anything else that should be buffered/cached in Thuban? > > Probably a lot. :) Based on the assumption that rendering is the most expensive process step (at least for local layers) I had in mind to cache each rendered layer image separately. Would speed up Thuban significantly as long as the map extend is constant, but I haven't thought much about memory requirements so far ... On the other hand analysis on database layers requires also the query results, so caching these would also be helpful. Frank -- Frank Koormann Professional Service around Free Software (http://intevation.net/) FreeGIS Project (http://freegis.org/) -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://www.intevation.de/pipermail/thuban-devel/attachments/20040416/bb380bc9/attachment.bin From joey at infodrom.org Fri Apr 16 13:04:46 2004 From: joey at infodrom.org (Martin Schulze) Date: Fri, 16 Apr 2004 13:04:46 +0200 Subject: RfD: Support for layer specific resources In-Reply-To: <20040416102718.GF15457@intevation.de> References: <20040415182050.GH1655@finlandia.infodrom.north.de> <20040415192606.GW22347@intevation.de> <20040416053827.GM1655@finlandia.infodrom.north.de> <20040416102718.GF15457@intevation.de> Message-ID: <20040416110446.GG1655@finlandia.infodrom.north.de> Bernhard Reiter wrote: > > Anything else that should be buffered/cached in Thuban? > > Probably a lot. :) Ehem... ok... I'd like to retract that question. :) Regards, Joey -- Long noun chains don't automatically imply security. -- Bruce Schneier From joey at infodrom.org Fri Apr 16 13:22:26 2004 From: joey at infodrom.org (Martin Schulze) Date: Fri, 16 Apr 2004 13:22:26 +0200 Subject: RfD: Support for layer specific resources In-Reply-To: <20040416110455.GC24414@intevation.de> References: <20040415182050.GH1655@finlandia.infodrom.north.de> <20040415192606.GW22347@intevation.de> <20040416053827.GM1655@finlandia.infodrom.north.de> <20040416102718.GF15457@intevation.de> <20040416110455.GC24414@intevation.de> Message-ID: <20040416112226.GI1655@finlandia.infodrom.north.de> Frank Koormann wrote: > Based on the assumption that rendering is the most expensive process step > (at least for local layers) I had in mind to cache each rendered layer > image separately. Would speed up Thuban significantly as long as the map > extend is constant, but I haven't thought much about memory requirements > so far ... Storing the images in $config.thubandir + "/cache/" would help a lot as well. No need to store loads of images only in the RAM. Regards, Joey -- Long noun chains don't automatically imply security. -- Bruce Schneier From bh at intevation.de Fri Apr 16 17:02:28 2004 From: bh at intevation.de (Bernhard Herzog) Date: Fri, 16 Apr 2004 17:02:28 +0200 Subject: RfD: Support for layer specific resources In-Reply-To: <20040415182050.GH1655@finlandia.infodrom.north.de> (Martin Schulze's message of "Thu, 15 Apr 2004 20:20:50 +0200") References: <20040415182050.GH1655@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > In the past, Thuban supported mostly local layers. As a result, > several dialogs were not classified layer-specific and hence > controlled through a general control within Thuban. This poses a > problem since the general control of Thuban which also creates menus > and legends thinks that all layers are "normal" layers. Well, the issue is that there are different types of layers, not whether they're local or remote. Thuban already comes with two different layer types, both of which are local. Raster layers, just like wms layers, don't have tables, for instance. The way Thuban currently deals with different layer types in e.g. the properties dialog could be improved, though. > I guess that we should start to discuss how we could move > layer-specfic dialogs into the control of the dialog and add global > hooks where the layer can registrate features (dialog boxes and the > like) in the menu, legend (context menu), icon box, and main menu. > > For this particular problem the source is in > > Thuban/UI/legend.py for the Properties dialog > and > Thuban/UI/mainwindow.py for the Show Table dialog Actually, all the relevant code is in mainwindow.py. The code in legend.py simply calls the appropriate mainwindow method. The main problem with the Show Table command is that it's not grayed out in the context menu for non-shape layers. It is grayed out in the main menu, so it should be easy to do it in the context menu too. Jan is already looking into that. For the properties dialog, a registry like that for the renderer would be an easy way to define new layer type specific properties dialogs. The existing properties dialog should perhaps be split in two, one for the shape layers and one for raster layers, instead of having one which simply doesn't have some of the widgets of the other. It might be a good idea ot have a common base class for the property dialogs which has the widgets for the common base class BaseLayer. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From bh at intevation.de Fri Apr 16 17:26:42 2004 From: bh at intevation.de (Bernhard Herzog) Date: Fri, 16 Apr 2004 17:26:42 +0200 Subject: Status: Layer organisation References: <20040415180842.GF1655@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > 1. I guess that we should see if we can support more graphics > formats. That's easily doable, but there may be a good reason for > limiting support to BMP and JPEG. There's no particular reason for the limitation, IIRC. We simply didn't need something else yet. Which formats Thuban can support depends on what the underlying the wxWidgets library supports, so I don't think we should can guarantte much about the availability of support for formats that are optional in wx. I'm not sure which are optional, ATM. > 2. If 1. we should see why transparency is currently not supported by > Thuban The reason is simple: It's not easy to do with a wxDC. It would be possible and probably not even difficult to do a gif-like transparency (effecively one bit alpha channel, every pixel is either drawn or not). Full blown translucency (where the underlying pixels shine through) can't be done unless all rendering is done with some other library and only a complete raster image with the entire map is drawn by the DC, or we switch to OpenGL. For the one-bit transparency, we'd need to extend the draw_raster_data method so that it either accepts an additional one-bit image with a clip-mask and/or accepts image format with equivalent transparency information. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From jan at intevation.de Fri Apr 16 17:32:21 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Fri, 16 Apr 2004 17:32:21 +0200 Subject: [Thuban-devel] Re: Status: Layer organisation In-Reply-To: References: <20040415180842.GF1655@finlandia.infodrom.north.de> Message-ID: <20040416153221.GB6085@intevation.de> On Fri, Apr 16, 2004 at 05:26:42PM +0200, Bernhard Herzog wrote: > For the one-bit transparency, we'd need to extend the draw_raster_data > method so that it either accepts an additional one-bit image with a > clip-mask and/or accepts image format with equivalent transparency > information. I'd opt to this way instead of OpenGL for now. Even this simple (yes/no) transparency feature would bring massive improvement, because we could have tiled raster images and stack e.g. WMS layers. Eventually we might have to add an alternative rendering based on OpenGL, but I don't see massice advantages correlated to the work that needs to be done for that. Jan -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From jan at intevation.de Sat Apr 17 22:15:34 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Sat, 17 Apr 2004 22:15:34 +0200 Subject: popup menu In-Reply-To: References: <20040416082115.EEEC513B53@lists.intevation.de> Message-ID: <20040417201534.GB9749@intevation.de> On Fri, Apr 16, 2004 at 10:49:51AM +0200, Bernhard Herzog wrote: > I don't think we should raise a dialog box here. We don't show one > either when there's no selection. We should make sure that the commands > that call this method are grayed out. The one in the main window does > this with the has_selected_shape_layer method. The context menu should > do something similar if it doesn't do that yet. I've greyed out the menu item now. There is a simple solution to do this directly. I plan to commit that to the thuban-1-0-branch. For HEAD, I think it is better to use a Menu like defined for the main menu. This has the consequence that I added the Top/Bottom/ToggleVisibility Layer function to the mainwindow.py module though not actively used there. The functionality of e.g. raising/lowering layer is now redundant since it is part of mainwindow as well as part of of legend (there still used through the toolbar). So, eventually we should decide whether such functions should be part of the legend or of the mainwindow. However, though not the final solution my changes will clean up stuff a little bit. Will polish my patch and then commit. What I also recognized is that the toolbar in legend could have been build the same way the toolbar of the mainwindow is. But that was a bit more complicated than the menu, so I stopped this for the moment. First we have to decide whether the actual functions should be in legend or mainwindow. Jan -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From frank.koormann at intevation.de Sun Apr 18 15:36:51 2004 From: frank.koormann at intevation.de (Frank Koormann) Date: Sun, 18 Apr 2004 15:36:51 +0200 Subject: popup menu In-Reply-To: <20040417201534.GB9749@intevation.de> References: <20040416082115.EEEC513B53@lists.intevation.de> <20040417201534.GB9749@intevation.de> Message-ID: <20040418133651.GA16184@intevation.de> * Jan-Oliver Wagner [040417 22:15]: > For HEAD, I think it is better to use a Menu like > defined for the main menu. > This has the consequence that I added the Top/Bottom/ToggleVisibility Layer > function to the mainwindow.py module though not actively used there. > The functionality of e.g. raising/lowering layer is now > redundant since it is part of mainwindow as well as part > of of legend (there still used through the toolbar). > So, eventually we should decide whether such functions should > be part of the legend or of the mainwindow. > > However, though not the final solution my changes will clean > up stuff a little bit. Will polish my patch and then commit. > > What I also recognized is that the toolbar in legend could have > been build the same way the toolbar of the mainwindow is. > But that was a bit more complicated than the menu, so I stopped > this for the moment. First we have to decide whether the actual > functions should be in legend or mainwindow. Maybe the best would be to separate the functions currently deeply sunken in Thuban/UI/mainwindow.py from there and document them. The entire concept is not that clear on the first sight, this seems to me being one of the reasons why the legend implements it in a different way. I can think already of further popup menus (e.g. on the map). Hence for better transparency based on the separated helpers the menu item should be defined where used. Regards, Frank -- Frank Koormann Professional Service around Free Software (http://intevation.net/) FreeGIS Project (http://freegis.org/) -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://www.intevation.de/pipermail/thuban-devel/attachments/20040418/4397d742/attachment.bin From joey at infodrom.org Sun Apr 18 17:23:11 2004 From: joey at infodrom.org (Martin Schulze) Date: Sun, 18 Apr 2004 17:23:11 +0200 Subject: popup menu In-Reply-To: <20040418133651.GA16184@intevation.de> References: <20040416082115.EEEC513B53@lists.intevation.de> <20040417201534.GB9749@intevation.de> <20040418133651.GA16184@intevation.de> Message-ID: <20040418152310.GT1655@finlandia.infodrom.north.de> Frank Koormann wrote: > Maybe the best would be to separate the functions currently deeply > sunken in Thuban/UI/mainwindow.py from there and document them. The entire > concept is not that clear on the first sight, this seems to me being one of > the reasons why the legend implements it in a different way. > > I can think already of further popup menus (e.g. on the map). Hence for > better transparency based on the separated helpers the menu item > should be defined where used. FWIW: Agreed. This will give us the chance for fine grained control over such features users can use based on the currently visible object. Regards, Joey -- Have you ever noticed that "General Public Licence" contains the word "Pub"? From cvs at intevation.de Sun Apr 18 22:37:03 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sun, 18 Apr 2004 22:37:03 +0200 (CEST) Subject: jan: thuban/Thuban/UI mainwindow.py,1.131,1.132 Message-ID: <20040418203703.64CCA139C8@lists.intevation.de> Author: jan Update of /thubanrepository/thuban/Thuban/UI In directory doto:/tmp/cvs-serv30022 Modified Files: mainwindow.py Log Message: New method commands: layer_to_top, layer_to_bottom, layer_visibility (MainWindow.LayerToTop): New. Put current layer to the top. (MainWindow.LayerToBottom): New. Put current layer to bottom. (MainWindow.HideLayer, MainWindow.ShowLayer, _has_visible_map): Replace 1,0 by True, False. (MainWindow.ToggleLayerVisibility): New. Toggle visibility of current layer. (MainWindow.LayerShowTable): Removed raising of dialog. (_has_selected_layer_visible): New. Support function. Index: mainwindow.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/mainwindow.py,v retrieving revision 1.131 retrieving revision 1.132 diff -u -d -r1.131 -r1.132 --- mainwindow.py 16 Apr 2004 08:21:12 -0000 1.131 +++ mainwindow.py 18 Apr 2004 20:37:01 -0000 1.132 @@ -572,6 +572,11 @@ return self.canvas.Map().CanRemoveLayer(layer) return False + def LayerToTop(self): + layer = self.current_layer() + if layer is not None: + self.canvas.Map().MoveLayerToTop(layer) + def RaiseLayer(self): layer = self.current_layer() if layer is not None: @@ -582,6 +587,11 @@ if layer is not None: self.canvas.Map().LowerLayer(layer) + def LayerToBottom(self): + layer = self.current_layer() + if layer is not None: + self.canvas.Map().MoveLayerToBottom(layer) + def current_layer(self): """Return the currently selected layer. @@ -604,12 +614,16 @@ def HideLayer(self): layer = self.current_layer() if layer is not None: - layer.SetVisible(0) + layer.SetVisible(False) def ShowLayer(self): layer = self.current_layer() if layer is not None: - layer.SetVisible(1) + layer.SetVisible(True) + + def ToggleLayerVisibility(self): + layer = self.current_layer() + layer.SetVisible(not layer.Visible()) def DuplicateLayer(self): """Ceate a new layer above the selected layer with the same shapestore @@ -633,14 +647,11 @@ Present a TableView Window for the current layer. In case the window is already open, bring it to the front. In case, there is no active layer, do nothing. - In case, the layer has not ShapeStore, raise a corresponding message dialog - and do nothing else. + In case, the layer has no ShapeStore, do nothing. """ layer = self.current_layer() if layer is not None: if not hasattr(layer, "ShapeStore"): - self.RunMessageBox(_("Show Table"), - _("The layer '%s' has no table." % layer.Title())) return table = layer.ShapeStore().Table() name = "table_view" + str(id(table)) @@ -997,6 +1008,14 @@ """Return true if a layer is selected in the context""" return context.mainwindow.has_selected_layer() +def _has_selected_layer_visible(context): + """Return true if a layer is selected in the context which is + visible.""" + if context.mainwindow.has_selected_layer(): + layer = context.mainwindow.current_layer() + if layer.Visible(): return True + return False + def _has_selected_shape_layer(context): """Return true if a shape layer is selected in the context""" return context.mainwindow.has_selected_shape_layer() @@ -1020,8 +1039,8 @@ if map is not None: for layer in map.Layers(): if layer.Visible(): - return 1 - return 0 + return True + return False def _has_legend_shown(context): """Return true if the legend window is shown""" @@ -1144,6 +1163,18 @@ _method_command("layer_jointable", _("&Join Table..."), "LayerJoinTable", sensitive = _has_selected_shape_layer, helptext = _("Join and attach a table to the selected layer")) + +# further layer methods: +_method_command("layer_to_top", _("&Top"), "LayerToTop", + helptext = _("Put selected layer to the top"), + sensitive = _has_selected_layer) +_method_command("layer_to_bottom", _("&Bottom"), "LayerToBottom", + helptext = _("Put selected layer to the bottom"), + sensitive = _has_selected_layer) +_method_command("layer_visibility", _("&Visible"), "ToggleLayerVisibility", + checked = _has_selected_layer_visible, + helptext = _("Toggle visibility of selected layer"), + sensitive = _has_selected_layer) def _can_unjoin(context): """Return whether the Layer/Unjoin command can be executed. From cvs at intevation.de Sun Apr 18 22:37:47 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sun, 18 Apr 2004 22:37:47 +0200 (CEST) Subject: jan: thuban/Thuban/UI legend.py,1.36,1.37 Message-ID: <20040418203747.54D54139C8@lists.intevation.de> Author: jan Update of /thubanrepository/thuban/Thuban/UI In directory doto:/tmp/cvs-serv30047 Modified Files: legend.py Log Message: ID_POP_xxx: removed. (LegendPanel.__init__): Removed EVT_MENU bindings. (LegendTree._OnRightClick): Replace direct creation of menu via wx Classes by applying the menu definition as of Menu class of menu.py. Index: legend.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/legend.py,v retrieving revision 1.36 retrieving revision 1.37 diff -u -d -r1.36 -r1.37 --- legend.py 31 Oct 2003 10:13:32 -0000 1.36 +++ legend.py 18 Apr 2004 20:37:45 -0000 1.37 @@ -31,6 +31,8 @@ from Thuban.UI.dock import DockPanel from Thuban.UI.scalebar import ScaleBar +from Thuban.UI.menu import Menu + from Thuban.Lib.connector import ConnectorError ID_LEGEND_TOP = 4001 @@ -42,16 +44,6 @@ ID_LEGEND_SHOWLAYER = 4007 ID_LEGEND_HIDELAYER = 4008 -ID_POPUP_TOP = 4501 -ID_POPUP_UP = 4502 -ID_POPUP_DOWN = 4503 -ID_POPUP_BOTTOM = 4504 -ID_POPUP_PROPS = 4506 -ID_POPUP_VISIBLE = 4507 -ID_POPUP_PROJ = 4509 -ID_POPUP_REMOVE = 4510 -ID_POPUP_SHOWTABLE = 4511 - BMP_SIZE_W = 15 BMP_SIZE_H = 15 @@ -63,7 +55,6 @@ HIDE_BMP = "hide_layer" PROPS_BMP = "layer_properties" - class LegendPanel(DockPanel): def __init__(self, parent, map, mainWindow): @@ -118,16 +109,6 @@ EVT_TOOL(self, ID_LEGEND_SHOWLAYER, self._OnShowLayer) EVT_TOOL(self, ID_LEGEND_HIDELAYER, self._OnHideLayer) - EVT_MENU(self, ID_POPUP_PROPS, self._OnProperties) - EVT_MENU(self, ID_POPUP_TOP, self._OnMoveTop) - EVT_MENU(self, ID_POPUP_UP, self._OnMoveUp) - EVT_MENU(self, ID_POPUP_DOWN, self._OnMoveDown) - EVT_MENU(self, ID_POPUP_BOTTOM, self._OnMoveBottom) - EVT_MENU(self, ID_POPUP_VISIBLE, self._OnToggleVisibility) - EVT_MENU(self, ID_POPUP_PROJ, self._OnProjection) - EVT_MENU(self, ID_POPUP_REMOVE, self._OnRemoveLayer) - EVT_MENU(self, ID_POPUP_SHOWTABLE, self._OnShowTable) - self.tree = LegendTree(self, ID_LEGEND_TREE, map, mainWindow) panelBox.Add(self.tree, 1, wxGROW, 0) @@ -280,31 +261,25 @@ item = event.GetItem() self.SelectItem(item) - # Create the menu - menu = wxMenu("", 0) - - # The "Visible" item is a special ... - menuitem = wxMenuItem(menu, ID_POPUP_VISIBLE, _("Visible"), - "", wxITEM_CHECK) - menu.AppendItem(menuitem) - layer, group = self.GetSelectedHierarchy() - menuitem.Check(layer.Visible()) - - menu.AppendSeparator() - menu.Append(ID_POPUP_PROPS, _("&Properties...")) - menu.Append(ID_POPUP_PROJ, _("Pro&jection...")) - menu.Append(ID_POPUP_REMOVE, _("&Remove Layer")) - menu.Append(ID_POPUP_SHOWTABLE, _("Show Ta&ble")) - menu.AppendSeparator() - menu.Append(ID_POPUP_TOP, _("Top Layer")) - menu.Append(ID_POPUP_UP, _("Raise Layer")) - menu.Append(ID_POPUP_DOWN, _("Lower Layer")) - menu.Append(ID_POPUP_BOTTOM, _("Bottom Layer")) + # Define the menu + popup_menu = Menu("PopUp", "", + [ "layer_visibility", + None, + "layer_properties", + "layer_projection", + "layer_remove", + "layer_show_table", + None, + "layer_to_top", + "layer_raise", + "layer_lower", + "layer_to_bottom" + ]) # Display the menu pos = event.GetPoint() shift = self.ClientToScreen((0,0)) - self.PopupMenu(menu, pos) + self.PopupMenu(self.mainWindow.build_menu(popup_menu), pos) def find_layer(self, layer): """Return the tree item for the layer""" From cvs at intevation.de Sun Apr 18 22:40:32 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Sun, 18 Apr 2004 22:40:32 +0200 (CEST) Subject: jan: thuban ChangeLog,1.643,1.644 Message-ID: <20040418204032.6F7B1139C8@lists.intevation.de> Author: jan Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv30075 Modified Files: ChangeLog Log Message: Changing popup menu of legend from direct building to using the Menu construction as used for the mainwindow. Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.643 retrieving revision 1.644 diff -u -d -r1.643 -r1.644 --- ChangeLog 16 Apr 2004 08:21:47 -0000 1.643 +++ ChangeLog 18 Apr 2004 20:40:30 -0000 1.644 @@ -1,3 +1,25 @@ +2004-04-18 Jan-Oliver Wagner + + Changing popup menu of legend from direct building + to using the Menu construction as used for the mainwindow. + + * Thuban/UI/mainwindow.py: New method commands: layer_to_top, + layer_to_bottom, layer_visibility + (MainWindow.LayerToTop): New. Put current layer to the top. + (MainWindow.LayerToBottom): New. Put current layer to bottom. + (MainWindow.HideLayer, MainWindow.ShowLayer, _has_visible_map): + Replace 1,0 by True, False. + (MainWindow.ToggleLayerVisibility): New. Toggle visibility of + current layer. + (MainWindow.LayerShowTable): Removed raising of dialog. + (_has_selected_layer_visible): New. Support function. + + * Thuban/UI/legend.py: ID_POP_xxx: removed. + (LegendPanel.__init__): Removed EVT_MENU bindings. + (LegendTree._OnRightClick): Replace direct creation of + menu via wx Classes by applying the menu definition + as of Menu class of menu.py. + 2004-04-16 Jan-Oliver Wagner * Thuban/UI/exceptiondialog.py (ExceptionDialog.dialog_layout): Improved From jan at intevation.de Sun Apr 18 22:45:29 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Sun, 18 Apr 2004 22:45:29 +0200 Subject: [Thuban-devel] Re: popup menu In-Reply-To: <20040418133651.GA16184@intevation.de> References: <20040416082115.EEEC513B53@lists.intevation.de> <20040417201534.GB9749@intevation.de> <20040418133651.GA16184@intevation.de> Message-ID: <20040418204529.GA20281@intevation.de> On Sun, Apr 18, 2004 at 03:36:51PM +0200, Frank Koormann wrote: > Maybe the best would be to separate the functions currently deeply > sunken in Thuban/UI/mainwindow.py from there and document them. The entire > concept is not that clear on the first sight, this seems to me being one of > the reasons why the legend implements it in a different way. so, you would be in favour of putting e.g. the layer sequence commands into the LegendTree class? -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From jan at intevation.de Sun Apr 18 22:48:41 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Sun, 18 Apr 2004 22:48:41 +0200 Subject: [Thuban-devel] popup menu In-Reply-To: <20040417201534.GB9749@intevation.de> References: <20040416082115.EEEC513B53@lists.intevation.de> <20040417201534.GB9749@intevation.de> Message-ID: <20040418204841.GB20281@intevation.de> On Sat, Apr 17, 2004 at 10:15:34PM +0200, Jan-Oliver Wagner wrote: > For HEAD, I think it is better to use a Menu like > defined for the main menu. > This has the consequence that I added the Top/Bottom/ToggleVisibility Layer > function to the mainwindow.py module though not actively used there. > The functionality of e.g. raising/lowering layer is now > redundant since it is part of mainwindow as well as part > of of legend (there still used through the toolbar). > So, eventually we should decide whether such functions should > be part of the legend or of the mainwindow. > > However, though not the final solution my changes will clean > up stuff a little bit. Will polish my patch and then commit. I've commited this now. I did not remove the functions from LegendTree which are not called anymore since we might decide to move this functionality from the mainwindow to the LegendTree. This finally fixes also the bug that now the popup menu item "Show Table" is greyed out when the layer has no table to show. Jan -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From cvs at intevation.de Mon Apr 19 09:27:57 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Mon, 19 Apr 2004 09:27:57 +0200 (CEST) Subject: jan: thuban/Thuban/UI legend.py,1.36,1.36.2.1 Message-ID: <20040419072757.92884139AE@lists.intevation.de> Author: jan Update of /thubanrepository/thuban/Thuban/UI In directory doto:/tmp/cvs-serv4683 Modified Files: Tag: thuban-1-0-branch legend.py Log Message: (LegendTree._OnRightClick): Grey out popup menu item Show Table if the corresponding layer has no table. Index: legend.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/legend.py,v retrieving revision 1.36 retrieving revision 1.36.2.1 diff -u -d -r1.36 -r1.36.2.1 --- legend.py 31 Oct 2003 10:13:32 -0000 1.36 +++ legend.py 19 Apr 2004 07:27:55 -0000 1.36.2.1 @@ -295,6 +295,12 @@ menu.Append(ID_POPUP_PROJ, _("Pro&jection...")) menu.Append(ID_POPUP_REMOVE, _("&Remove Layer")) menu.Append(ID_POPUP_SHOWTABLE, _("Show Ta&ble")) + + # grey out this Show Table item if the Layer has no table to show + menuitem = menu.FindItemById(ID_POPUP_SHOWTABLE) + if not layer.HasShapes(): + menuitem.Enable(False) + menu.AppendSeparator() menu.Append(ID_POPUP_TOP, _("Top Layer")) menu.Append(ID_POPUP_UP, _("Raise Layer")) From cvs at intevation.de Mon Apr 19 09:28:19 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Mon, 19 Apr 2004 09:28:19 +0200 (CEST) Subject: jan: thuban ChangeLog,1.624.2.2,1.624.2.3 Message-ID: <20040419072819.D7E51139AF@lists.intevation.de> Author: jan Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv4712 Modified Files: Tag: thuban-1-0-branch ChangeLog Log Message: Fixed a bug Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.624.2.2 retrieving revision 1.624.2.3 diff -u -d -r1.624.2.2 -r1.624.2.3 --- ChangeLog 11 Mar 2004 15:54:47 -0000 1.624.2.2 +++ ChangeLog 19 Apr 2004 07:28:17 -0000 1.624.2.3 @@ -1,3 +1,8 @@ +2004-04-19 Jan-Oliver Wagner + + * Thuban/UI/legend.py (LegendTree._OnRightClick): Grey out popup + menu item Show Table if the corresponding layer has no table. + 2004-03-11 Silke Reimer Update debian directory: From jan at intevation.de Mon Apr 19 13:30:29 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Mon, 19 Apr 2004 13:30:29 +0200 Subject: [Thuban-devel] Re: RfD: Support for layer specific resources In-Reply-To: References: <20040415182050.GH1655@finlandia.infodrom.north.de> Message-ID: <20040419113029.GA10000@intevation.de> On Fri, Apr 16, 2004 at 05:02:28PM +0200, Bernhard Herzog wrote: > The main problem with the Show Table command is that it's not grayed out > in the context menu for non-shape layers. It is grayed out in the main > menu, so it should be easy to do it in the context menu too. Jan is > already looking into that. and fixed that in HEAD and thuban-1-0-branch now :-) > For the properties dialog, a registry like that for the renderer would > be an easy way to define new layer type specific properties dialogs. > > The existing properties dialog should perhaps be split in two, one for > the shape layers and one for raster layers, instead of having one which > simply doesn't have some of the widgets of the other. It might be a > good idea ot have a common base class for the property dialogs which has > the widgets for the common base class BaseLayer. these two actions look quite sensible to me. Joey: Do you think you could develop patches for this (first the dialog separation, then based on that, the registry for properties dialogs like for renderer)? Jan -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From frank.koormann at intevation.de Tue Apr 20 16:50:04 2004 From: frank.koormann at intevation.de (Frank Koormann) Date: Tue, 20 Apr 2004 16:50:04 +0200 Subject: [Thuban-devel] Re: popup menu In-Reply-To: <20040418204529.GA20281@intevation.de> References: <20040416082115.EEEC513B53@lists.intevation.de> <20040417201534.GB9749@intevation.de> <20040418133651.GA16184@intevation.de> <20040418204529.GA20281@intevation.de> Message-ID: <20040420145004.GC20163@intevation.de> * Jan-Oliver Wagner [040418 22:45]: > On Sun, Apr 18, 2004 at 03:36:51PM +0200, Frank Koormann wrote: > > Maybe the best would be to separate the functions currently deeply > > sunken in Thuban/UI/mainwindow.py from there and document them. The entire > > concept is not that clear on the first sight, this seems to me being one of > > the reasons why the legend implements it in a different way. > > so, you would be in favour of putting e.g. the layer sequence > commands into the LegendTree class? This is a question regarding the general source structure of Thuban. Currently a lot of methods are placed in the mainwindow.py - and all of this is quite unbalanced: E.g. on one hand the sequence to deepcopy a layer is placed in mainwindow. The functionality to join two tables is implemented in a separate file (strange enough still under Thuban/UI). So, yes, I support to discuss a better separation. This could mean that all layer related stuff goes into the legend - since this is the central element for layer management. But I am still not decided if generating the main window's layer menu dynamically from all features a legend module provides goes too far or not. Regards, Frank -- Frank Koormann Professional Service around Free Software (http://intevation.net/) FreeGIS Project (http://freegis.org/) -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: not available Url : http://www.intevation.de/pipermail/thuban-devel/attachments/20040420/f91704a4/attachment.bin From bh at intevation.de Tue Apr 20 17:27:36 2004 From: bh at intevation.de (Bernhard Herzog) Date: Tue, 20 Apr 2004 17:27:36 +0200 Subject: [Thuban-devel] Re: popup menu References: <20040416082115.EEEC513B53@lists.intevation.de> <20040417201534.GB9749@intevation.de> <20040418133651.GA16184@intevation.de> <20040418204529.GA20281@intevation.de> <20040420145004.GC20163@intevation.de> Message-ID: Frank Koormann writes: > Currently a lot of methods are placed in the mainwindow.py - and > all of this is quite unbalanced: E.g. on one hand the sequence to > deepcopy a layer is placed in mainwindow. I guess you're talking about DuplicateLayer. That method should be split into two. The actual duplication should be done in a method of the layer, of course, and the mainwindow method should simply call that method on the currently selected layer. > So, yes, I support to discuss a better separation. This could mean that > all layer related stuff goes into the legend It shouldn't be in the legend. The legend window for instance can be switched off. It might be better to introduce a new class for the interaction logic. We could revive the interactor class for that. The interactor manages the selection (the Selection instance currently owned by viewport) for that, and has methods for all commands that work on the currently selected layer. Those methods would mostly just delegate the actual work to the appropriate method of the currently selected layer or the map (or whatever). The mainwindow and the legend would be just views on the interactor. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From jan at intevation.de Wed Apr 21 20:16:34 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Wed, 21 Apr 2004 20:16:34 +0200 Subject: RfD: Support for layer specific resources In-Reply-To: <20040419113029.GA10000@intevation.de> References: <20040415182050.GH1655@finlandia.infodrom.north.de> <20040419113029.GA10000@intevation.de> Message-ID: <20040421181634.GC12627@intevation.de> On Mon, Apr 19, 2004 at 01:30:29PM +0200, Jan-Oliver Wagner wrote: > On Fri, Apr 16, 2004 at 05:02:28PM +0200, Bernhard Herzog wrote: > > For the properties dialog, a registry like that for the renderer would > > be an easy way to define new layer type specific properties dialogs. > > > > The existing properties dialog should perhaps be split in two, one for > > the shape layers and one for raster layers, instead of having one which > > simply doesn't have some of the widgets of the other. It might be a > > good idea ot have a common base class for the property dialogs which has > > the widgets for the common base class BaseLayer. > > these two actions look quite sensible to me. > > Joey: Do you think you could develop patches for this (first the dialog > separation, then based on that, the registry for properties dialogs like > for renderer)? Joey? Jan -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From joey at infodrom.org Thu Apr 22 07:29:41 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 22 Apr 2004 07:29:41 +0200 Subject: RfD: Support for layer specific resources In-Reply-To: <20040421181634.GC12627@intevation.de> References: <20040415182050.GH1655@finlandia.infodrom.north.de> <20040419113029.GA10000@intevation.de> <20040421181634.GC12627@intevation.de> Message-ID: <20040422052941.GD1655@finlandia.infodrom.north.de> Jan-Oliver Wagner wrote: > On Mon, Apr 19, 2004 at 01:30:29PM +0200, Jan-Oliver Wagner wrote: > > On Fri, Apr 16, 2004 at 05:02:28PM +0200, Bernhard Herzog wrote: > > > For the properties dialog, a registry like that for the renderer would > > > be an easy way to define new layer type specific properties dialogs. > > > > > > The existing properties dialog should perhaps be split in two, one for > > > the shape layers and one for raster layers, instead of having one which > > > simply doesn't have some of the widgets of the other. It might be a > > > good idea ot have a common base class for the property dialogs which has > > > the widgets for the common base class BaseLayer. > > > > these two actions look quite sensible to me. > > > > Joey: Do you think you could develop patches for this (first the dialog > > separation, then based on that, the registry for properties dialogs like > > for renderer)? > > Joey? I guess that I could. Regards, Joey -- Linux - the choice of a GNU generation. From cvs at intevation.de Thu Apr 22 17:45:03 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 22 Apr 2004 17:45:03 +0200 (CEST) Subject: jan: thuban/Thuban/UI classgen.py,1.32,1.33 Message-ID: <20040422154503.B29B613B81@lists.intevation.de> Author: jan Update of /thubanrepository/thuban/Thuban/UI In directory doto:/tmp/cvs-serv10557 Modified Files: classgen.py Log Message: (GenUniquePanel.__init__): Fixed two strings to be i18n now. Index: classgen.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/classgen.py,v retrieving revision 1.32 retrieving revision 1.33 diff -u -d -r1.32 -r1.33 --- classgen.py 11 Mar 2004 20:50:43 -0000 1.32 +++ classgen.py 22 Apr 2004 15:45:01 -0000 1.33 @@ -644,7 +644,7 @@ psizer = wxBoxSizer(wxVERTICAL) self.list_avail = wxListCtrl(self, -1, style=wxLC_REPORT | wxLC_SINGLE_SEL) - self.list_avail.InsertColumn(0, "Available") + self.list_avail.InsertColumn(0, _("Available")) self.list_avail_data = [] psizer.Add(self.list_avail, 1, wxGROW, 0) @@ -684,7 +684,7 @@ psizer = wxBoxSizer(wxVERTICAL) self.list_use = wxListCtrl(self, -1, style=wxLC_REPORT | wxLC_SINGLE_SEL) - self.list_use.InsertColumn(0, "Use") + self.list_use.InsertColumn(0, _("Use")) self.list_use_data = [] psizer.Add(self.list_use, 1, wxGROW, 0) From cvs at intevation.de Thu Apr 22 17:45:51 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 22 Apr 2004 17:45:51 +0200 (CEST) Subject: jan: thuban ChangeLog,1.644,1.645 Message-ID: <20040422154551.66B6F13B81@lists.intevation.de> Author: jan Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv10580 Modified Files: ChangeLog Log Message: i18n bug fix Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.644 retrieving revision 1.645 diff -u -d -r1.644 -r1.645 --- ChangeLog 18 Apr 2004 20:40:30 -0000 1.644 +++ ChangeLog 22 Apr 2004 15:45:49 -0000 1.645 @@ -1,3 +1,8 @@ +2004-04-22 Jan-Oliver Wagner + + * Thuban/UI/classgen.py (GenUniquePanel.__init__): Fixed two + strings to be i18n now. + 2004-04-18 Jan-Oliver Wagner Changing popup menu of legend from direct building From cvs at intevation.de Thu Apr 22 17:48:04 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 22 Apr 2004 17:48:04 +0200 (CEST) Subject: jan: thuban/Thuban/UI classgen.py,1.30,1.30.2.1 Message-ID: <20040422154804.56EF513B81@lists.intevation.de> Author: jan Update of /thubanrepository/thuban/Thuban/UI In directory doto:/tmp/cvs-serv10606 Modified Files: Tag: thuban-1-0-branch classgen.py Log Message: (GenUniquePanel.__init__): Fixed two strings to be i18n now. Index: classgen.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/classgen.py,v retrieving revision 1.30 retrieving revision 1.30.2.1 diff -u -d -r1.30 -r1.30.2.1 --- classgen.py 8 Aug 2003 13:01:30 -0000 1.30 +++ classgen.py 22 Apr 2004 15:48:02 -0000 1.30.2.1 @@ -644,7 +644,7 @@ psizer = wxBoxSizer(wxVERTICAL) self.list_avail = wxListCtrl(self, -1, style=wxLC_REPORT | wxLC_SINGLE_SEL) - self.list_avail.InsertColumn(0, "Available") + self.list_avail.InsertColumn(0, _("Available")) self.list_avail_data = [] psizer.Add(self.list_avail, 1, wxGROW, 0) @@ -684,7 +684,7 @@ psizer = wxBoxSizer(wxVERTICAL) self.list_use = wxListCtrl(self, -1, style=wxLC_REPORT | wxLC_SINGLE_SEL) - self.list_use.InsertColumn(0, "Use") + self.list_use.InsertColumn(0, _("Use")) self.list_use_data = [] psizer.Add(self.list_use, 1, wxGROW, 0) From cvs at intevation.de Thu Apr 22 17:48:49 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 22 Apr 2004 17:48:49 +0200 (CEST) Subject: jan: thuban ChangeLog,1.624.2.3,1.624.2.4 Message-ID: <20040422154849.5A1E713B81@lists.intevation.de> Author: jan Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv10629 Modified Files: Tag: thuban-1-0-branch ChangeLog Log Message: i18n bug fix Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.624.2.3 retrieving revision 1.624.2.4 diff -u -d -r1.624.2.3 -r1.624.2.4 --- ChangeLog 19 Apr 2004 07:28:17 -0000 1.624.2.3 +++ ChangeLog 22 Apr 2004 15:48:46 -0000 1.624.2.4 @@ -1,3 +1,8 @@ +2004-04-22 Jan-Oliver Wagner + + * Thuban/UI/classgen.py (GenUniquePanel.__init__): Fixed two + strings to be i18n now. + 2004-04-19 Jan-Oliver Wagner * Thuban/UI/legend.py (LegendTree._OnRightClick): Grey out popup From cvs at intevation.de Thu Apr 22 17:52:15 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 22 Apr 2004 17:52:15 +0200 (CEST) Subject: bh: thuban/Thuban/UI classgen.py,1.30.2.1,1.30.2.2 Message-ID: <20040422155215.B8D2C13B81@lists.intevation.de> Author: bh Update of /thubanrepository/thuban/Thuban/UI In directory doto:/tmp/cvs-serv10693/Thuban/UI Modified Files: Tag: thuban-1-0-branch classgen.py Log Message: * Thuban/UI/classgen.py (GenQuantilesPanel.GetList): The row numbers given to ReadValue are ordinals. Backport from HEAD Index: classgen.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/classgen.py,v retrieving revision 1.30.2.1 retrieving revision 1.30.2.2 diff -u -d -r1.30.2.1 -r1.30.2.2 --- classgen.py 22 Apr 2004 15:48:02 -0000 1.30.2.1 +++ classgen.py 22 Apr 2004 15:52:13 -0000 1.30.2.2 @@ -1,4 +1,4 @@ -# Copyright (c) 2003 by Intevation GmbH +# Copyright (c) 2003, 2004 by Intevation GmbH # Authors: # Jonathan Coles # @@ -878,7 +878,8 @@ # has been written to get all the values # for i in range(table.NumRows()): - _list.append(table.ReadValue(i, self.fieldName)) + _list.append(table.ReadValue(i, self.fieldName, + row_is_ordinal = True) finally: ThubanEndBusyCursor() From cvs at intevation.de Thu Apr 22 17:52:16 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 22 Apr 2004 17:52:16 +0200 (CEST) Subject: bh: thuban ChangeLog,1.624.2.4,1.624.2.5 Message-ID: <20040422155216.3A26813BCD@lists.intevation.de> Author: bh Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv10693 Modified Files: Tag: thuban-1-0-branch ChangeLog Log Message: * Thuban/UI/classgen.py (GenQuantilesPanel.GetList): The row numbers given to ReadValue are ordinals. Backport from HEAD Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.624.2.4 retrieving revision 1.624.2.5 diff -u -d -r1.624.2.4 -r1.624.2.5 --- ChangeLog 22 Apr 2004 15:48:46 -0000 1.624.2.4 +++ ChangeLog 22 Apr 2004 15:52:13 -0000 1.624.2.5 @@ -1,3 +1,8 @@ +2004-04-22 Bernhard Herzog + + * Thuban/UI/classgen.py (GenQuantilesPanel.GetList): The row + numbers given to ReadValue are ordinals. Backport from HEAD + 2004-04-22 Jan-Oliver Wagner * Thuban/UI/classgen.py (GenUniquePanel.__init__): Fixed two From cvs at intevation.de Thu Apr 22 19:10:37 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 22 Apr 2004 19:10:37 +0200 (CEST) Subject: frank: thuban/Extensions/bboxdump - New directory Message-ID: <20040422171037.B16F113AAE@lists.intevation.de> Author: frank Update of /thubanrepository/thuban/Extensions/bboxdump In directory doto:/tmp/cvs-serv11576/Extensions/bboxdump Log Message: Directory /thubanrepository/thuban/Extensions/bboxdump added to the repository From cvs at intevation.de Thu Apr 22 19:11:56 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 22 Apr 2004 19:11:56 +0200 (CEST) Subject: frank: thuban/Extensions/bboxdump __init__.py, NONE, 1.1 bboxdump.py, NONE, 1.1 Message-ID: <20040422171156.47FCF13AAE@lists.intevation.de> Author: frank Update of /thubanrepository/thuban/Extensions/bboxdump In directory doto:/tmp/cvs-serv11616/Extensions/bboxdump Added Files: __init__.py bboxdump.py Log Message: New Extension to dump bounding boxes of all shapes of the selected layer. An optional column can be specified to group the objects, in this case the bounding box is a union of the separate boxes. Dump can be displayed in a ScrolledMessageDialog or written to file. The Extension is simply a combination of available and well tested Thuban functionality. * Extensions/bboxdump/__init__.py: New: Init to make this directory a package. * Extensions/bboxdump/bboxdump.py: New: Dump bounding boxes of all shapes of the selected layer. --- NEW FILE: __init__.py --- # Copyright (c) 2003 by Intevation GmbH # Authors: # Jan-Oliver Wagner # # This program is free software under the GPL (>=v2) # Read the file COPYING coming with Thuban for details. --- NEW FILE: bboxdump.py --- # Copyright (C) 2003 by Intevation GmbH # Authors: # Frank Koormann # # This program is free software under the GPL (>=v2) # Read the file COPYING coming with Thuban for details. """ Extend thuban with a bounding box dump. Dumps the bounding boxes of all shapes of the selected layer. An optional column can be specified to group the objects, in this case the bounding box is a union of the separate boxes. """ __version__ = '$Revision: 1.1 $' import os, sys # only import GUI when not called as command line tool from wxPython.wx import * from wxPython.lib.dialogs import wxScrolledMessageDialog from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor from Thuban.UI.command import registry, Command from Thuban.UI.mainwindow import main_menu, _has_selected_shape_layer from Thuban import _ import shapelib import dbflib ID_FILENAME = 4001 ID_ATTRIBUTES = 4002 ID_SELFN = 4003 class BBoxDumpDialog(wxDialog): """Bounding Box Dump Dialog Specify a filename for the dump and optionally a layer's column field to group objects. """ def __init__(self, parent, title, layer = None): wxDialog.__init__(self, parent, -1, title, style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER) if layer is None: return wxID_CANCEL # Store the layer self.layer = layer # Filename selection elements self.filename = wxTextCtrl(self, ID_FILENAME, "") self.button_selectfile = wxButton(self, ID_SELFN, _('Select...')) EVT_BUTTON(self, ID_SELFN, self.OnSelectFilename) # Column choice elements self.choice_column = wxChoice(self, ID_ATTRIBUTES) self.choice_column.Append(_('Select...'), None) for col in self.layer.ShapeStore().Table().Columns(): self.choice_column.Append(col.name, col) self.choice_column.SetSelection(0) # Dialog button elements self.button_dump = wxButton(self, wxID_OK, _("OK")) EVT_BUTTON(self, wxID_OK, self.OnDump) self.button_dump.SetDefault() # TODO: Disable the OK button until a filename is entered ... # self.button_dump.Enable(False) self.button_cancel = wxButton(self, wxID_CANCEL, _("Cancel")) # Dialog Layout: three horizontal box sizers. topbox = wxBoxSizer(wxVERTICAL) hbox = wxBoxSizer(wxHORIZONTAL) topbox.Add(hbox, 0, wxALL|wxEXPAND) hbox.Add(wxStaticText(self, -1, _("File:")), 0, wxALL|wxALIGN_CENTER_VERTICAL, 4) hbox.Add(self.filename, 1, wxALL|wxEXPAND, 4) hbox.Add(self.button_selectfile, 0, wxALL, 4) hbox = wxBoxSizer(wxHORIZONTAL) topbox.Add(hbox, 0, wxALL|wxEXPAND) hbox.Add(wxStaticText(self, -1, _("Group by:")), 0, wxALL|wxALIGN_CENTER_VERTICAL, 4) hbox.Add(self.choice_column, 1, wxALL|wxEXPAND, 4) hbox = wxBoxSizer(wxHORIZONTAL) topbox.Add(hbox, 0, wxALL|wxEXPAND) hbox.Add(self.button_dump, 0, wxALL|wxALIGN_CENTER, 10) hbox.Add(self.button_cancel, 0, wxALL|wxALIGN_CENTER, 10) # Finalize ... self.SetAutoLayout(True) self.SetSizer(topbox) topbox.Fit(self) topbox.SetSizeHints(self) # Store for later use self.parent = parent def OnDump(self, event): """Bounding Box Dump Dialog event handler OK button. Prepare the inputs from the dialog and call processing. """ i = self.choice_column.GetSelection() column = self.choice_column.GetClientData(i) self.Close() ThubanBeginBusyCursor() try: bboxmessage = bboxdump(self.layer, column, self.filename.GetValue()) finally: ThubanEndBusyCursor() if bboxmessage: dlg = wxScrolledMessageDialog( self.parent, bboxmessage, _("Bounding Box Dump %s") % self.layer.Title() ) dlg.ShowModal() def OnSelectFilename(self, event): """Bounding Box Dump Dialog event handler File Selection. Opens a file dialog to specify a file to dump into. """ dlg = wxFileDialog(self, _("Dump Bounding Boxes To"), os.path.dirname(self.filename.GetValue()), os.path.basename(self.filename.GetValue()), _("CSV Files (*.csv)|*.csv|") + _("All Files (*.*)|*.*"), wxSAVE|wxOVERWRITE_PROMPT) if dlg.ShowModal() == wxID_OK: self.filename.SetValue(dlg.GetPath()) dlg.Destroy() else: dlg.Destroy() def bboxdump(layer, column, filename): """Bounding Box Dump Processing layer - Layer of shapes to be dumped column - optional column to group shapes (else None) filename - optional filename to dump into (else empty string, i.e. dump to stdio) """ # Preparation shapelist = {} bboxmessage = "" # Collect shape ids to be dumped if column is None: # A simple dump of shapes bbox is required for i in xrange(layer.NumShapes()): shapelist[i] = (i,) else: # group them by column ... for i in xrange(layer.NumShapes()): row = layer.ShapeStore().Table().ReadRowAsDict(i) att = row[column.name] if not shapelist.has_key(att): shapelist[att] = [] shapelist[att].append(i) # Dump them, sorted keys = shapelist.keys() keys.sort() for key in keys: bbox = layer.ShapesBoundingBox(shapelist[key]) bboxmessage = bboxmessage + "%.3f,%.3f,%.3f,%.3f,%s\n" % ( bbox[0],bbox[1],bbox[2],bbox[3],key) # finally if filename != '': bboxfile = file(filename,'w+') bboxfile.write(bboxmessage) bboxfile.close() return None else: return bboxmessage def LayerBBoxDump(context): """Menu Handler BBoxDump """ layer = context.mainwindow.canvas.SelectedLayer() if layer is not None: dlg = BBoxDumpDialog(context.mainwindow, _("Bounding Box Dump"), layer = layer) dlg.ShowModal() # gns2shp executed as an extension to Thuban # register the new command registry.Add(Command('bboxdump', _('BBox Dump'), LayerBBoxDump, helptext = _('Dump Bounding Boxes of Layer Objects'), sensitive = _has_selected_shape_layer)) # find the extensions menu (create it anew if not found) extensions_menu = main_menu.find_menu('extensions') if extensions_menu is None: extensions_menu = main_menu.InsertMenu('extensions', _('E&xtensions')) # finally add the new entry to the extensions menu extensions_menu.InsertItem('bboxdump') From cvs at intevation.de Thu Apr 22 19:11:56 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 22 Apr 2004 19:11:56 +0200 (CEST) Subject: frank: thuban ChangeLog,1.645,1.646 Message-ID: <20040422171156.96B9B13AE9@lists.intevation.de> Author: frank Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv11616 Modified Files: ChangeLog Log Message: New Extension to dump bounding boxes of all shapes of the selected layer. An optional column can be specified to group the objects, in this case the bounding box is a union of the separate boxes. Dump can be displayed in a ScrolledMessageDialog or written to file. The Extension is simply a combination of available and well tested Thuban functionality. * Extensions/bboxdump/__init__.py: New: Init to make this directory a package. * Extensions/bboxdump/bboxdump.py: New: Dump bounding boxes of all shapes of the selected layer. Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.645 retrieving revision 1.646 diff -u -d -r1.645 -r1.646 --- ChangeLog 22 Apr 2004 15:45:49 -0000 1.645 +++ ChangeLog 22 Apr 2004 17:11:54 -0000 1.646 @@ -1,3 +1,18 @@ +2004-04-22 Frank Koormann + + New Extension to dump bounding boxes of all shapes of the selected + layer. An optional column can be specified to group the objects, + in this case the bounding box is a union of the separate boxes. + Dump can be displayed in a ScrolledMessageDialog or written to file. + The Extension is simply a combination of available and well tested + Thuban functionality. + + * Extensions/bboxdump/__init__.py: New: Init to make this + directory a package. + + * Extensions/bboxdump/bboxdump.py: New: Dump bounding boxes of + all shapes of the selected layer. + 2004-04-22 Jan-Oliver Wagner * Thuban/UI/classgen.py (GenUniquePanel.__init__): Fixed two From bh at intevation.de Thu Apr 22 19:27:10 2004 From: bh at intevation.de (Bernhard Herzog) Date: Thu, 22 Apr 2004 19:27:10 +0200 Subject: frank: thuban/Extensions/bboxdump __init__.py, NONE, 1.1 bboxdump.py, NONE, 1.1 In-Reply-To: <20040422171156.47FCF13AAE@lists.intevation.de> (cvs@intevation.de's message of "Thu, 22 Apr 2004 19:11:56 +0200 (CEST)") References: <20040422171156.47FCF13AAE@lists.intevation.de> Message-ID: cvs at intevation.de writes: > for i in xrange(layer.NumShapes()): > row = layer.ShapeStore().Table().ReadRowAsDict(i) This only works for shapefiles since there the shape ids form a contiguous sequence from 0 to # of shapes - 1. It won't work for postgis layers, for instance. It's better to iterate over all shapes with the ShapeStore's AllShapes() method and the get the correct shape id from the shape's ShapeID() method. Alternatively you could add row_is_ordinal = True to the ReadRowAsDict call. But that will cause problems later: > keys = shapelist.keys() > keys.sort() > for key in keys: > bbox = layer.ShapesBoundingBox(shapelist[key]) This will also fail for postgis layers unless shapelist contains the real shape ids. > # find the extensions menu (create it anew if not found) > extensions_menu = main_menu.find_menu('extensions') > if extensions_menu is None: > extensions_menu = main_menu.InsertMenu('extensions', _('E&xtensions')) We should add a function to Thuban.UI.mainwindow that returns the extensions menu after creating it if it doesn't exist yet. This code has been duplicated in at least 5 extensions. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From joey at infodrom.org Fri Apr 23 08:05:29 2004 From: joey at infodrom.org (Martin Schulze) Date: Fri, 23 Apr 2004 08:05:29 +0200 Subject: frank: thuban/Extensions/bboxdump __init__.py, NONE, 1.1 bboxdump.py, NONE, 1.1 In-Reply-To: <20040422171156.47FCF13AAE@lists.intevation.de> References: <20040422171156.47FCF13AAE@lists.intevation.de> Message-ID: <20040423060529.GI1655@finlandia.infodrom.north.de> Just a small cut'n'paste left-over. cvs at intevation.de wrote: > # gns2shp executed as an extension to Thuban ^^^^^^^ > # finally add the new entry to the extensions menu > extensions_menu.InsertItem('bboxdump') ^^^^^^^^ Regards, Joey -- GNU does not eliminate all the world's problems, only some of them. -- The GNU Manifesto From JensMattke at aol.com Fri Apr 30 16:12:18 2004 From: JensMattke at aol.com (JensMattke@aol.com) Date: Fri, 30 Apr 2004 10:12:18 EDT Subject: Improved PostGIS-Interface Message-ID: <11c.2e86a1c8.2dc3b8c2@aol.com> Hi. Some time ago, I complained about the speed of the postGIS-Inteface. I also suggested to keep the data persistent for a session - this suggestion was postpone to a later date. Unsatisfied with that, I thougth about a possibility to, at least, increase the speed of querying spatial data. I found thuban was using the 'astext()'-function of postGIS to read the shapes. Next, I compared this possibility with reading the shapes with binary cursor from the database. (This was in Java and JDBC, because I'm much more familiar with it) It happend to be more than 30 times faster. So I decided to rewrite the postgisdb.py and wellknowntext.py files using a binary cursor. Unfortunately, it seems to me as if psycopg is unable to read 'normal data' (integer, double, text...) as a binary cursor. Trying that, always killed the python-interpreter. So there are now two queries for one old query. One for the shapeid-data like 'gid' and stuff, and one for the shapes. I have to confess, it did only increase speed by the factor three to four. Thuban needed 226 secs for 91.000 shapes with the old version and 69 secs with my versions. (Yes, I always cleared the query-buffer of postgreSQL) Though this still isn't fast enough for my purpose, I thought perhaps you would like to see it. Happy May Day! (Klingt das nicht komisch?) Jens -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.intevation.de/pipermail/thuban-devel/attachments/20040430/bb059d31/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: wellknownbinary.ZIP Type: application/zip Size: 9487 bytes Desc: not available Url : http://www.intevation.de/pipermail/thuban-devel/attachments/20040430/bb059d31/wellknownbinary.ZIP