From cvs at intevation.de Thu Mar 18 09:15:56 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 18 Mar 2004 09:15:56 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_ogclib.py,1.2,1.3 Message-ID: <20040318081556.9C20313A0F@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv23211 Modified Files: test_ogclib.py Log Message: The format specification is a mime-type, not a graphic format, hence image/jpeg wou ld be the proper format and not JPEG. We'll also have to take care of the encoding of / as %2F. Index: test_ogclib.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_ogclib.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- test_ogclib.py 16 Mar 2004 17:28:26 -0000 1.2 +++ test_ogclib.py 18 Mar 2004 08:15:54 -0000 1.3 @@ -6,12 +6,12 @@ # Read the file COPYING coming with Thuban for details. """ -Test for the PyOGCLib from Sean C. Gillies +Test for the PyOGCLib from Sean C. Gillies http://www.sourceforge.net/projects/pyogclib Requires the ogclib installed regularily on the system or checked out -next to the thuban checkout +next to the Thuban checkout. """ __version__ = "$Revision$" @@ -72,7 +72,7 @@ bar_opts = split (bar_tuple[1], "&") if len(foo_opts) != len(bar_opts): - self.fail ("different number of arguments"); + self.fail ("Different number of arguments"); for part in foo_opts: if part not in bar_opts: @@ -117,7 +117,8 @@ frida = "http://frida.intevation.org/cgi-bin/frida_wms?" - format = 'JPEG' + format = 'image/jpeg' + format_enc = 'image%2Fjpeg' width = 400 height = 350 epsg = 4326 @@ -127,7 +128,7 @@ version = '1.1' result_base = frida + "WMTVER=1.0&REQUEST=map" + \ - "&FORMAT="+format + \ + "&FORMAT="+format_enc + \ "&SRS=EPSG%s%d" % ("%3A", epsg) + \ "&BBOX=%f%s%f%s%f%s%f" % (bbox['minx'], "%2C", bbox['miny'], "%2C", bbox['maxx'], "%2C", bbox['maxy']) + \ @@ -141,7 +142,7 @@ # Repeat and continue with version 1.1, as denoted in OGC 01-068r3 version = '1.1' result_base = frida + "VERSION=1.1&SERVICE=WMS&REQUEST=GetMap" + \ - "&FORMAT="+format + \ + "&FORMAT="+format_enc + \ "&SRS=EPSG%s%d" % ("%3A", epsg) + \ "&BBOX=%f%s%f%s%f%s%f" % (bbox['minx'], "%2C", bbox['miny'], "%2C", bbox['maxx'], "%2C", bbox['maxy']) + \ @@ -198,8 +199,6 @@ bbox, layers, version=version, styles = styles) self.compare_URLs (result, url) - - # print url if __name__ == "__main__": From jan at intevation.de Thu Mar 18 10:25:39 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Thu, 18 Mar 2004 10:25:39 +0100 Subject: joey: thuban/Extensions/wms/test test_ogclib.py,1.2,1.3 In-Reply-To: <20040318081556.9C20313A0F@lists.intevation.de> References: <20040318081556.9C20313A0F@lists.intevation.de> Message-ID: <20040318092539.GA19220@intevation.de> Hi Joey, On Thu, Mar 18, 2004 at 09:15:56AM +0100, cvs at intevation.de wrote: > + format = 'image/jpeg' > + format_enc = 'image%2Fjpeg' maybe you try urllib for quoting/encoding the URL strings. It is a standard Python 2.2. module. Jan -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From joey at infodrom.org Thu Mar 18 10:32:27 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 18 Mar 2004 10:32:27 +0100 Subject: joey: thuban/Extensions/wms/test test_ogclib.py,1.2,1.3 In-Reply-To: <20040318092539.GA19220@intevation.de> References: <20040318081556.9C20313A0F@lists.intevation.de> <20040318092539.GA19220@intevation.de> Message-ID: <20040318093227.GV9104@finlandia.infodrom.north.de> Moin Jan! Jan-Oliver Wagner wrote: > On Thu, Mar 18, 2004 at 09:15:56AM +0100, cvs at intevation.de wrote: > > + format = 'image/jpeg' > > + format_enc = 'image%2Fjpeg' > > maybe you try urllib for quoting/encoding the URL strings. > It is a standard Python 2.2. module. I thought about this quite a while before, quite a while, but then I would just duplicate the ogclib which would not make much sense when trying to test + verify it works properly. Hence, I decided to manually encode the data for the tests so that the result from ogclib and urllib can be verified against proper data. Regards, Joey -- The MS-DOS filesystem is nice for removable media. -- H. Peter Anvin From joey at infodrom.org Thu Mar 18 11:59:45 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 18 Mar 2004 11:59:45 +0100 Subject: Test programs assumptions Message-ID: <20040318105945.GZ9104@finlandia.infodrom.north.de> How are test programs outside the main test/ directory supposed to be executed? At the moment most test programs are located in the test/ directory and are executed in that directory. I've been told that eventually tests should be located in a test directory of the module/class/source directory they test. Hence, in the future test programs will be located in about all directories. I wonder how they will be called and especially which assumptions with regards to the current working directory and the path environment can be made. Regards, Joey -- The MS-DOS filesystem is nice for removable media. -- H. Peter Anvin From bh at intevation.de Thu Mar 18 12:41:26 2004 From: bh at intevation.de (Bernhard Herzog) Date: Thu, 18 Mar 2004 12:41:26 +0100 Subject: Test programs assumptions In-Reply-To: <20040318105945.GZ9104@finlandia.infodrom.north.de> (Martin Schulze's message of "Thu, 18 Mar 2004 11:59:45 +0100") References: <20040318105945.GZ9104@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > How are test programs outside the main test/ directory supposed to be > executed? > > At the moment most test programs are located in the test/ directory > and are executed in that directory. I've been told that eventually > tests should be located in a test directory of the module/class/source > directory they test. Someday maybe. At first this will only be the case for the code under Extensions/. There is already one example of that: Extensions/svgexport/test/. You can add additional directories with tests in test/runtests.py (look for "svgexport"). > I wonder how they will be called and especially which assumptions with > regards to the current working directory It's best if the code makes no assumptions about the current directory. The code in test/ unfortunately relies on the current direcory being that test/ directory. That ought to be fixed, but I didn't have time for that yet. Furthermore not code anywhere in Thuban, including tests should change the current directory. > and the path environment can be made. The code can assume that third-party non-optional libraries on which Thuban depends are present and can be imported in the normal way. Optional libraries should be optional for the test cases too, but tests that cannot be run because of missing optional libraries should be skipped by raising the SkipTest exception defined in test/support.py so that it is obvious that some tests were not run and for what reason. See test/postgissupport.py for this might be used. If you raise SkipTest you need to use support.run_tests instead of unittest.main so that it is handled as intended (with the normal unittest it would be flagged as an error). Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From joey at infodrom.org Thu Mar 18 13:06:13 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 18 Mar 2004 13:06:13 +0100 Subject: Test programs assumptions In-Reply-To: References: <20040318105945.GZ9104@finlandia.infodrom.north.de> Message-ID: <20040318120613.GB9104@finlandia.infodrom.north.de> Moin! Hmm, I guess I need more information. Bernhard Herzog wrote: > > How are test programs outside the main test/ directory supposed to be > > executed? > > Someday maybe. At first this will only be the case for the code under > Extensions/. There is already one example of that: > Extensions/svgexport/test/. You can add additional directories with > tests in test/runtests.py (look for "svgexport"). Does this imply that other tests outside the test/ directory (i.e. ../Extension/**/test/test*.py) will be executed from within the test/ directory if they get included in the normal test suite? > > I wonder how they will be called and especially which assumptions with > > regards to the current working directory > > It's best if the code makes no assumptions about the current directory. > The code in test/ unfortunately relies on the current direcory being > that test/ directory. That ought to be fixed, but I didn't have time > for that yet. As soon as you want to import other modules, load files, run external programs you have to make assumptions on the paths, which is why I ask, so I know how the tools are supposed to work. > Furthermore not code anywhere in Thuban, including tests should change > the current directory. Ack. Hmm, I'll rephrase my original question: [ ] **/test/test_*.py except for the test programs in the test/ directory are supposed to run from the Thuban main directory (which is not test/ but rather test/../) [ ] **/test/test_*.py except for the test programs in the test/ directory are supposed to run from the Thuban test/ directory [ ] **/test/test_*.py are only supposed to run from the directory they are placed in > The code can assume that third-party non-optional libraries on which > Thuban depends are present and can be imported in the normal way. > Optional libraries should be optional for the test cases too, but tests > that cannot be run because of missing optional libraries should be > skipped by raising the SkipTest exception defined in test/support.py so > that it is obvious that some tests were not run and for what reason. I see, will adjust test_ogclib accordingly since it just exists if the PyOGCLib isn't found. > See test/postgissupport.py for this might be used. If you raise > SkipTest you need to use support.run_tests instead of unittest.main so > that it is handled as intended (with the normal unittest it would be > flagged as an error). Which leads me back to my initial question, which directory to assume besides the one the test is stored in, since support.py is either test.support, support or ../../../test/support. Regards, Joey -- The MS-DOS filesystem is nice for removable media. -- H. Peter Anvin From bh at intevation.de Thu Mar 18 15:44:50 2004 From: bh at intevation.de (Bernhard Herzog) Date: Thu, 18 Mar 2004 15:44:50 +0100 Subject: Test programs assumptions References: <20040318105945.GZ9104@finlandia.infodrom.north.de> <20040318120613.GB9104@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > Does this imply that other tests outside the test/ directory > (i.e. ../Extension/**/test/test*.py) will be executed from within the > test/ directory if they get included in the normal test suite? If you run them with test/runtests.py (and expect the tests in test/ to work): yes. > As soon as you want to import other modules, load files, run external > programs you have to make assumptions on the paths, which is why I > ask, so I know how the tools are supposed to work. Well, __file__ will give you the name of the current module, so you can use that to figure out where files are if you know the location relative to the module's file. E.g. a file "foo" in the same directory is usually os.path.join(os.path.dirname(__file__), "foo") > Hmm, I'll rephrase my original question: I can't simply make a cross in any one of these as the sitution a more complex than that. > [ ] **/test/test_*.py except for the test programs in the test/ > directory are supposed to run from the Thuban main directory > (which is not test/ but rather test/../) It's OK if they can be run from that directory as long as they don't rely on it. > [ ] **/test/test_*.py except for the test programs in the test/ > directory are supposed to run from the Thuban test/ directory It should be possible to run them this way. They should not rely on it though. It's OK if they can be run from other directories too. > [ ] **/test/test_*.py are only supposed to run from the directory > they are placed in That's the way it currently is for some of the tests, which is more or less by accident. I wouldn't say that they are supposed to be run from there. It's the only way it currently works if you want to be able to run all the tests but that really is a bug that ought to be fixed. >> See test/postgissupport.py for this might be used. If you raise >> SkipTest you need to use support.run_tests instead of unittest.main so >> that it is handled as intended (with the normal unittest it would be >> flagged as an error). > > Which leads me back to my initial question, which directory to assume > besides the one the test is stored in, since support.py is either > test.support, support or ../../../test/support. Good question. I must admit that I'm not sure exactly how we need to extend the test suite and its support code to handle tests outside of test/. For the svgexport tests I only did the minimum to make them run as part of the whole test suite when run via test/runtests.py. The easiest way for you to continue is probably this: create your own support module in Extensions/wms/test and put the some code there that is run only once to add some directories to sys.path, like the Thuban main directory and test so that you can import Thuban and the test support modules. You can't call it support.py though because then it would shadow the support module from test/. Longer term it would probably be a good idea to put the test support code into a separate package alongside Thuban/ or maybe even in Thuban/. Then you'd only have to make sure that you can import Thuban itself to also get the test support code. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From cvs at intevation.de Thu Mar 18 18:13:30 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 18 Mar 2004 18:13:30 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_ogclib.py,1.3,1.4 Message-ID: <20040318171330.CC7BD13A08@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv30634 Modified Files: test_ogclib.py Log Message: Added legacy code to add the main Thuban directory to the path in order to be able to import random modules. Adjusted the PyOGCLib detection to reuse the information gathered. Also added a note about the PYTHONPATH environment variable. This should ensure that the test program can now be run from outside the test directory as well. Index: test_ogclib.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_ogclib.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- test_ogclib.py 18 Mar 2004 08:15:54 -0000 1.3 +++ test_ogclib.py 18 Mar 2004 17:13:28 -0000 1.4 @@ -10,8 +10,8 @@ http://www.sourceforge.net/projects/pyogclib -Requires the ogclib installed regularily on the system or checked out -next to the Thuban checkout. +Requires the ogclib installed regularily on the system, accessible via +PYTHONPATH or checked out alongside the Thuban checkout. """ __version__ = "$Revision$" @@ -22,6 +22,16 @@ import unittest from string import split +from sys import path + +# Add the main Thuban directory so the path so that all modules are +# accessible as expected +# +if os.path.dirname (__file__) == "" or os.path.dirname (__file__) == ".": + thubandir = os.path.abspath ("../../../") +else: + thubandir = os.path.abspath (os.path.dirname(__file__) + "/../../..") +path.insert (0, thubandir) # ---------------------------------------------------------------------- # FIXME: Temporary code until PyOGCLib is a standard requirement @@ -29,7 +39,9 @@ from sys import path # Assume the PyOGCLib to be checked out next to the thuban main directory -pyogclib = "../../../../PyOGCLib" +# setting PYTHONPATH accordingly is fine as well +# +pyogclib = os.path.abspath (thubandir + "/../PyOGCLib") if os.path.isdir (pyogclib) and os.path.isdir (pyogclib + "/ogclib"): path.insert (0, pyogclib) # ---------------------------------------------------------------------- From joey at infodrom.org Thu Mar 18 18:08:41 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 18 Mar 2004 18:08:41 +0100 Subject: Test programs assumptions In-Reply-To: References: <20040318105945.GZ9104@finlandia.infodrom.north.de> <20040318120613.GB9104@finlandia.infodrom.north.de> Message-ID: <20040318170841.GH9104@finlandia.infodrom.north.de> Moin! Bernhard Herzog wrote: > > Does this imply that other tests outside the test/ directory > > (i.e. ../Extension/**/test/test*.py) will be executed from within the > > test/ directory if they get included in the normal test suite? > > If you run them with test/runtests.py (and expect the tests in test/ to > work): yes. Thought that was the long-term plan. :) > > As soon as you want to import other modules, load files, run external > > programs you have to make assumptions on the paths, which is why I > > ask, so I know how the tools are supposed to work. > > Well, __file__ will give you the name of the current module, so you can > use that to figure out where files are if you know the location relative > to the module's file. E.g. a file "foo" in the same directory is > usually os.path.join(os.path.dirname(__file__), "foo") That's a good idea, will implement it this way. Thanks a lot! > That's the way it currently is for some of the tests, which is more or > less by accident. I wouldn't say that they are supposed to be run from > there. It's the only way it currently works if you want to be able to > run all the tests but that really is a bug that ought to be fixed. I wish not to introduce more such "accidents", hence my questions. > >> See test/postgissupport.py for this might be used. If you raise > >> SkipTest you need to use support.run_tests instead of unittest.main so > >> that it is handled as intended (with the normal unittest it would be > >> flagged as an error). Hmm, I seem to be unable to import test.support in order to import SkipTest and stuff. There's no __init__.py in the test directory but even creating it doesn't seem to help. Looks like I'm a bit lost now. I'd be glad if you could give me a hand with incorporating this into Extensions/wms/test/test_ogclib.py. > > Which leads me back to my initial question, which directory to assume > > besides the one the test is stored in, since support.py is either > > test.support, support or ../../../test/support. > > Good question. I must admit that I'm not sure exactly how we need to > extend the test suite and its support code to handle tests outside of > test/. For the svgexport tests I only did the minimum to make them run > as part of the whole test suite when run via test/runtests.py. Well, in the long-term I'd suggest to include all the various test suites into the main one if the goal is to place the test suites next to the code it tests. You'll have to decide one day, not necessarily today, though. > The easiest way for you to continue is probably this: > > create your own support module in Extensions/wms/test and put the some done > code there that is run only once to add some directories to sys.path, done > like the Thuban main directory and test so that you can import Thuban added > and the test support modules. You can't call it support.py though failed, see above, I'm a bit clueless with that problem. > because then it would shadow the support module from test/. Ack. Regards, Joey -- The MS-DOS filesystem is nice for removable media. -- H. Peter Anvin From cvs at intevation.de Thu Mar 18 18:18:56 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 18 Mar 2004 18:18:56 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py, NONE, 1.1 sample.xml, NONE, 1.1 Message-ID: <20040318171856.F250C13A0F@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv30729 Added Files: test_parser.py sample.xml Log Message: Added another test for checking whether the WMS XML parser (to be implemented) returns the information we expect. This requires a sample WMS WML file (sample.xml) which has been extracted from the frida server and "improved" manually. --- NEW FILE: test_parser.py --- # -*- encoding: iso-8859-1 -*- # # 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 """ Test for WMSCapabilitiesParser from ../parser.py """ __version__ = "$Revision: 1.1 $" # $Source: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v $ # $Id: test_parser.py,v 1.1 2004/03/18 17:18:53 joey Exp $ import os import unittest from sys import path # Add the main Thuban directory so the path so that all modules are # accessible as expected # if os.path.dirname (__file__) == "" or os.path.dirname (__file__) == ".": path.insert (0, os.path.abspath ("../../../")) else: path.insert (0, os.path.abspath (os.path.dirname(__file__) + "/../../..")) from Extensions.wms.parser import WMSCapabilitiesParser class TestWMSCapabilitiesParser (unittest.TestCase, WMSCapabilitiesParser): """ Defines a test environment for the class WMSCapabilities. """ def compareLists (self, foo, bar): """ Compare two lists - check same number of elements - check whether all elements in the first list are part of the second """ # Check for same number of elements if len(foo) != len(bar): self.fail ("Different number of elements"); # Loop through all elements for existance for elm in foo: if elm not in bar: self.fail ("%s not in second list" % elm); def compareDicts (self, foo, bar): """ Compare two dictionaries (hashes) - check same number of keys - check whether all keys from the first list are part of the second """ # Check for same number of elements if len(foo) != len(bar): self.fail ("Different number of keys"); # Loop through all elements for existance for key in foo.keys(): if key not in bar: self.fail ("%s not in second dictionary" % key); if foo[key] != bar[key]: self.fail ("%s has different value in second dictionary" % key); def load_frida(self): """ Load the locally stored frida capabilities. http://frida.intevation.org/cgi-bin/frida_wms? """ try: try: f = open ("sample.xml", "r") except: f = open (os.path.dirname (__file__) + "/sample.xml", "r") except: print "Cannot open sample.xml for reading" else: xml = f.read (); f.close() self.grok (xml) def test_general (self): """ Test general attributes extracted from Capabilities XML """ if not self.capabilities: self.load_frida() self.assertEquals (self.getTitle(),'Frida - Freie Vektor-Geodaten Osnabrück') self.assertEquals (self.getAbstract(),'') self.assertEquals (self.getFees(),'') self.assertEquals (self.getAccessConstraints(),'') formats = ['image/gif', 'image/png', 'image/jpeg', 'image/wbmp'] self.compareLists (self.getFormats(),formats) layers = ['Osnabrueck', 'gruenflaechen', 'gewaesser', 'gewaesserpolyl','gewaesserlinien', 'strassen_all', 'strassenhinten', 'strassen', 'beschriftung', 'hauptbeschriftung', 'sehenswuerdigkeiten'] self.compareLists (self.getLayers(),layers) self.compareLists (self.getSRS(),[31493]) def test_LayerTitle (self): """ Check if layer titles are recognised properly """ if not self.capabilities: self.load_frida() # main layer self.assertEquals (self.getLayerTitle('Osnabrueck'),'Frida - Freie Vektor-Geodaten Osnabrück') # first nested layer self.assertEquals (self.getLayerTitle('gruenflaechen'),'Grünflächen') # first nested layer self.assertEquals (self.getLayerTitle('gewaesser'),'Gewässer') # second nested layer self.assertEquals (self.getLayerTitle('gewaesserpolyl'),'Gewässerflächen') def test_LayerSRS (self): """ Check if the SRS are returned properly """ if not self.capabilities: self.load_frida() # SRS of main layer self.compareLists (self.getLayerSRS('Osnabrueck'),[31493]) # Single SRS of layer without inheritance self.compareLists (self.getLayerSRS('gruenflaechen'),[31493]) # Multiple SRS (new/1.1.1) of layer without inheritance self.compareLists (self.getLayerSRS('gewaesserpolyl'),[31493, 31494]) # Multiple SRS (old/1.0.0) of layer without inheritance self.compareLists (self.getLayerSRS('gewaesserlinien'),[31493, 31494]) # Multiple SRS of layer with inheritance self.compareLists (self.getLayerSRS('strassenhinten'),[31493, 31494]) # Multiple SRS (old/1.0.0) with inheritance self.compareLists (self.getLayerSRS('strassen'),[31493, 31494, 31495]) # Multiple SRS (new/1.1.1) with inheritance self.compareLists (self.getLayerSRS('beschriftung'),[31493, 31494, 31495]) def test_LatLonBoundingBoxes (self): """ Check if the LatLonBoundingBoxes are returned properly """ if not self.capabilities: self.load_frida() # main LatLonBoundingBox bbox = {'minx': "7.92881", 'miny': "52.2131", 'maxx': "8.18349", 'maxy': "52.341"} self.compareDicts (self.getLayerLatLonBBox('Osnabrueck'),bbox) # inherited LatLonBoundingBox bbox = {'minx': "7.92881", 'miny': "52.2131", 'maxx': "8.18349", 'maxy': "52.341"} self.compareDicts (self.getLayerLatLonBBox('gewaesser'),bbox) # third layer non-inherited LatLonBoundingBox bbox = {'minx': "7.93531", 'miny': "52.2328", 'maxx': "8.17739", 'maxy': "52.3353"} self.compareDicts (self.getLayerLatLonBBox('gewaesserpolyl'),bbox) def test_BBoxSRS (self): """ Check if the BoundingBoxSRS' are returned properly """ if not self.capabilities: self.load_frida() # Single SRS:BBox self.compareLists (self.getLayerBBoxSRS('gruenflaechen'),[31493]) # Single inherited SRS:BBox self.compareLists (self.getLayerBBoxSRS('gewaesser'),[31493]) # Multiple SRS:BBox self.compareLists (self.getLayerBBoxSRS('gewaesserpolyl'),[31493, 31494]) def test_BoundingBoxes (self): """ Check if the BoundingBoxes are returned properly """ if not self.capabilities: self.load_frida() # main BoundingBox bbox = {'minx': "3.427e+06", 'miny': "5.787e+06", 'maxx': "3.4442e+06", 'maxy': "5.801e+06"} self.compareDicts (self.getLayerBBox('Osnabrueck', 31493),bbox) # inherited BoundingBox self.compareDicts (self.getLayerBBox('gewaesser', 31493),bbox) # overwritten BoundingBox bbox = {'minx': "3.427e+06", 'miny': "5.78901e+06", 'maxx': "3.44173e+06", 'maxy': "5.79952e+06"} self.compareDicts (self.getLayerBBox('gewaesserlinien', 31493),bbox) # multiple BoundingBoxes bbox = {'minx': "3.42743e+06", 'miny': "5.78919e+06", 'maxx': "3.44381e+06", 'maxy': "5.80038e+06"} self.compareDicts (self.getLayerBBox('gewaesserpolyl', 31493),bbox) bbox = {'minx': "3.42742e+06", 'miny': "5.78918e+06", 'maxx': "3.44380e+06", 'maxy': "5.80037e+06"} self.compareDicts (self.getLayerBBox('gewaesserpolyl', 31494),bbox) def test_queryable (self): """ Check if layers are properly classified queryable or not """ if not self.capabilities: self.load_frida() # implicit setting in main layer self.assertEquals (self.isQueryable('Osnabrueck'),0) # explicit setting in second layer self.assertEquals (self.isQueryable('gruenflaechen'),0) # inherited setting in second layer self.assertEquals (self.isQueryable('gewaesser'),0) # explicit setting in second layer self.assertEquals (self.isQueryable('sehenswuerdigkeiten'),1) # explicit setting in third layer self.assertEquals (self.isQueryable('strassen'),1) if __name__ == "__main__": unittest.main() --- NEW FILE: sample.xml --- ]> GetMap Frida - Freie Vektor-Geodaten Osnabrück application/vnd.ogc.wms_xml image/gif image/png image/jpeg image/wbmp text/plain text/html application/vnd.ogc.gml application/vnd.ogc.se_xml application/vnd.ogc.se_inimage application/vnd.ogc.se_blank Osnabrueck Frida - Freie Vektor-Geodaten Osnabrück 31493 gruenflaechen Grünflächen EPSG:31493 gewaesser Gewässer gewaesserpolyl Gewässerflächen EPSG:31493 EPSG:31494 gewaesserlinien Gewässerlinien EPSG:31493 EPSG:31492 strassen_all Strassen sowie Beschriftung und Hintergrund strassenhinten Strassenhintergrund EPSG:31494 strassen Strassen EPSG:31494 EPSG:31495 beschriftung Beschriftung EPSG:31494 EPSG:31495 hauptbeschriftung Hauptbeschriftung EPSG:31493 sehenswuerdigkeiten Sehenswürdigkeiten EPSG:31493 From cvs at intevation.de Thu Mar 18 18:58:27 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 18 Mar 2004 18:58:27 +0100 (CET) Subject: joey: thuban ChangeLog,1.632,1.633 Message-ID: <20040318175827.E249113A08@lists.intevation.de> Author: joey Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv31164 Modified Files: ChangeLog Log Message: Reflect my changes from today Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.632 retrieving revision 1.633 diff -u -d -r1.632 -r1.633 --- ChangeLog 17 Mar 2004 10:44:53 -0000 1.632 +++ ChangeLog 18 Mar 2004 17:58:25 -0000 1.633 @@ -1,3 +1,22 @@ +2004-03-18 Martin Schulze + + * Extensions/wms/test/test_parser.py: Added another test for + checking whether the WMS XML parser (to be implemented) returns + the information we expect. This requires a sample WMS WML file + (sample.xml) which has been extracted from the frida server and + "improved" manually. + + * Extensions/wms/test/test_ogclib.py: Added legacy code to add the + main Thuban directory to the path in order to be able to import + random modules. Adjusted the PyOGCLib detection to reuse the + information gathered. Also added a note about the PYTHONPATH + environment variable. + + * Extensions/wms/test/test_ogclib.py: The format specification is + a mime-type, not a graphic format, hence image/jpeg wou ld be the + proper format and not JPEG. We'll also have to take care of the + encoding of / as %2F. + 2004-03-16 Martin Schulze * Extensions/wms/test/test_ogclib.py: Added a (hopefully) From bh at intevation.de Thu Mar 18 20:12:28 2004 From: bh at intevation.de (Bernhard Herzog) Date: Thu, 18 Mar 2004 20:12:28 +0100 Subject: Test programs assumptions In-Reply-To: <20040318170841.GH9104@finlandia.infodrom.north.de> (Martin Schulze's message of "Thu, 18 Mar 2004 18:08:41 +0100") References: <20040318105945.GZ9104@finlandia.infodrom.north.de> <20040318120613.GB9104@finlandia.infodrom.north.de> <20040318170841.GH9104@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > Hmm, I seem to be unable to import test.support in order to import > SkipTest and stuff. There's no __init__.py in the test directory but > even creating it doesn't seem to help. Looks like I'm a bit lost > now. Have you added the test directory itself to sys.path, so that you can import support directly? Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From joey at infodrom.org Thu Mar 18 20:32:18 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 18 Mar 2004 20:32:18 +0100 Subject: Test programs assumptions In-Reply-To: References: <20040318105945.GZ9104@finlandia.infodrom.north.de> <20040318120613.GB9104@finlandia.infodrom.north.de> <20040318170841.GH9104@finlandia.infodrom.north.de> Message-ID: <20040318193218.GO9104@finlandia.infodrom.north.de> Bernhard Herzog wrote: > > Hmm, I seem to be unable to import test.support in order to import > > SkipTest and stuff. There's no __init__.py in the test directory but > > even creating it doesn't seem to help. Looks like I'm a bit lost > > now. > > Have you added the test directory itself to sys.path, so that you can > import support directly? No, since I considered this ugly. However, adding the test directory as well it seems to work. Does this patch look like how the test should be run? Regards, Joey Index: test_ogclib.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_ogclib.py,v retrieving revision 1.4 diff -u -r1.4 test_ogclib.py --- test_ogclib.py 18 Mar 2004 17:13:28 -0000 1.4 +++ test_ogclib.py 18 Mar 2004 19:30:57 -0000 @@ -31,8 +31,11 @@ thubandir = os.path.abspath ("../../../") else: thubandir = os.path.abspath (os.path.dirname(__file__) + "/../../..") +path.insert (0, thubandir + "/test") path.insert (0, thubandir) +import support + # ---------------------------------------------------------------------- # FIXME: Temporary code until PyOGCLib is a standard requirement @@ -49,8 +52,7 @@ try: from ogclib.WMSClient import WMSClient except: - print "No PyOGCLib found, hence no tests available." - os._exit(-1) + raise support.SkipTest("No PyOGCLib found, hence no tests available.") class TestOGCLib (unittest.TestCase, WMSClient): @@ -214,7 +216,7 @@ if __name__ == "__main__": - unittest.main() + support.run_tests() """ -- The MS-DOS filesystem is nice for removable media. -- H. Peter Anvin From joey at infodrom.org Thu Mar 18 20:40:58 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 18 Mar 2004 20:40:58 +0100 Subject: Test cases always run with separate instance? Message-ID: <20040318194057.GP9104@finlandia.infodrom.north.de> Hi! I wonder if a class containing several test functions needs to be created and destroyed for each test, so that no object data can survive from one test to another. I've read the documentation of unittest[1] but it didn't help me understand how I can prevent this. It talks about aggregating tests into test suites, though, but still mentions that each test will get its own object. Maybe it's not possible to have one class and a bunch of test methods which are *not* run separately, each in an instance of its own. Regards, Joey 1. http://pyunit.sourceforge.net/pyunit.html -- The MS-DOS filesystem is nice for removable media. -- H. Peter Anvin From mlennert at club.worldonline.be Thu Mar 18 22:34:59 2004 From: mlennert at club.worldonline.be (Moritz Lennert) Date: Thu, 18 Mar 2004 22:34:59 +0100 (CET) Subject: create [Thuban-devel] subject header Message-ID: <32985.213.219.155.7.1079645699.squirrel@213.219.155.7> Hello, Would it be possible to create a "[Thuban-devel]" subject header for the mailing list ? Just to make it easier to visualize... Moritz From joey at infodrom.org Fri Mar 19 07:22:37 2004 From: joey at infodrom.org (Martin Schulze) Date: Fri, 19 Mar 2004 07:22:37 +0100 Subject: create [Thuban-devel] subject header In-Reply-To: <32985.213.219.155.7.1079645699.squirrel@213.219.155.7> References: <32985.213.219.155.7.1079645699.squirrel@213.219.155.7> Message-ID: <20040319062236.GR9104@finlandia.infodrom.north.de> Moritz Lennert wrote: > Would it be possible to create a "[Thuban-devel]" subject header for the > mailing list ? Just to make it easier to visualize... FWIW: I'd like to stay without that header since it disimproves the subject readability and threads look quite err... strange with it. If your mail goes through a GNU/Linux or Unix account you can easily flag your incoming mail to comply your personal wishes by using procmail (|procmail -f- in .forward) and the following receipe: :0 fhw * ^ List-Id:.*thuban-devel\.intevation\.de | sed 's/^Subject: /Subject: [Thuban-devel]/' Regards, Joey -- Unix is user friendly ... It's just picky about its friends. From bh at intevation.de Fri Mar 19 14:59:46 2004 From: bh at intevation.de (Bernhard Herzog) Date: Fri, 19 Mar 2004 14:59:46 +0100 Subject: Test programs assumptions References: <20040318105945.GZ9104@finlandia.infodrom.north.de> <20040318120613.GB9104@finlandia.infodrom.north.de> <20040318170841.GH9104@finlandia.infodrom.north.de> <20040318193218.GO9104@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > Index: test_ogclib.py > =================================================================== > RCS file: /thubanrepository/thuban/Extensions/wms/test/test_ogclib.py,v > retrieving revision 1.4 > diff -u -r1.4 test_ogclib.py > --- test_ogclib.py 18 Mar 2004 17:13:28 -0000 1.4 > +++ test_ogclib.py 18 Mar 2004 19:30:57 -0000 > @@ -31,8 +31,11 @@ > thubandir = os.path.abspath ("../../../") > else: > thubandir = os.path.abspath (os.path.dirname(__file__) + "/../../..") > +path.insert (0, thubandir + "/test") > path.insert (0, thubandir) This path munging code should really be in a separate module so that you don't have to repeat in all the test modules. Lokking at it a bit closer, you probably should only add the test directory, import support and call support.initthuban() which will do all the rest. initthuban is what all the test modules in test/ use. Oh, and I'd prefer no spaces before the open parenthese for function calls or in function and class definitions. > @@ -49,8 +52,7 @@ > try: > from ogclib.WMSClient import WMSClient > except: It's better to only catch ImportErrors here. Catch all excepts often hide unexpected errors. > - print "No PyOGCLib found, hence no tests available." > - os._exit(-1) > + raise support.SkipTest("No PyOGCLib found, hence no tests available.") This will raise SkipTest when the module is imported, which is too early. It only works from within setUp or a test method. In the postgissupport module this situation is handled by first catching import errors for psycopg: try: import psycopg except ImportError: psycopg = None and then a function called by all postgis tests in the setUp method or in the test method: _cannot_run_postgis_tests = None def skip_if_no_postgis(): global _cannot_run_postgis_tests if _cannot_run_postgis_tests is None: _cannot_run_postgis_tests = reason_for_not_running_tests() if _cannot_run_postgis_tests: raise support.SkipTest(_cannot_run_postgis_tests) reason_for_not_running_tests checks whether psycopg is None but also does a few more tests since psycopg isn't the only requirement for the postgis tests. Something simpler might suffice for your needs. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From bh at intevation.de Fri Mar 19 15:13:27 2004 From: bh at intevation.de (Bernhard Herzog) Date: Fri, 19 Mar 2004 15:13:27 +0100 Subject: Test cases always run with separate instance? References: <20040318194057.GP9104@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > Hi! > > I wonder if a class containing several test functions needs to be > created and destroyed for each test, so that no object data can > survive from one test to another. The class will be instantiated once for each of the test methods. This happens pretty early on IIRC and the instances live until the end of the test suite run. Each of the instance will only call one of the test methods. If you build you data structures in setUp and destroy them in tearDown each of the instances will get their own copy of the data structures unless you do something explicitly to share them. The docs try to express this too, I think when they write (below code for a class with two test methods and self.widget created in setUp and destroyed in tearDown): Here we have not provided a runTest() method, but have instead provided two different test methods. Class instances will now each run one of the test*() methods, with self.widget created and destroyed separately for each instance. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From joey at infodrom.org Fri Mar 19 16:30:37 2004 From: joey at infodrom.org (Martin Schulze) Date: Fri, 19 Mar 2004 16:30:37 +0100 Subject: Test programs assumptions In-Reply-To: References: <20040318105945.GZ9104@finlandia.infodrom.north.de> <20040318120613.GB9104@finlandia.infodrom.north.de> <20040318170841.GH9104@finlandia.infodrom.north.de> <20040318193218.GO9104@finlandia.infodrom.north.de> Message-ID: <20040319153036.GB9104@finlandia.infodrom.north.de> Moin! Bernhard Herzog wrote: > Martin Schulze writes: > > > Index: test_ogclib.py > > =================================================================== > > RCS file: /thubanrepository/thuban/Extensions/wms/test/test_ogclib.py,v > > retrieving revision 1.4 > > diff -u -r1.4 test_ogclib.py > > --- test_ogclib.py 18 Mar 2004 17:13:28 -0000 1.4 > > +++ test_ogclib.py 18 Mar 2004 19:30:57 -0000 > > @@ -31,8 +31,11 @@ > > thubandir = os.path.abspath ("../../../") > > else: > > thubandir = os.path.abspath (os.path.dirname(__file__) + "/../../..") > > +path.insert (0, thubandir + "/test") > > path.insert (0, thubandir) > > This path munging code should really be in a separate module so that you > don't have to repeat in all the test modules. Aye. > Lokking at it a bit closer, you probably should only add the test > directory, import support and call support.initthuban() which will do > all the rest. initthuban is what all the test modules in test/ use. I wonder how useful this is if you don't need the rest of Thuban but only certain modules. I believe that this would add quite some bloat to the tests, which isn't required and has a chance of slowing down things more than we want. However, if you insist on this, I'll implement it the way you want it. > Oh, and I'd prefer no spaces before the open parenthese for function > calls or in function and class definitions. I'll remove them. > > @@ -49,8 +52,7 @@ > > try: > > from ogclib.WMSClient import WMSClient > > except: > > It's better to only catch ImportErrors here. Catch all excepts often > hide unexpected errors. true. > > - print "No PyOGCLib found, hence no tests available." > > - os._exit(-1) > > + raise support.SkipTest("No PyOGCLib found, hence no tests available.") > > This will raise SkipTest when the module is imported, which is too > early. It only works from within setUp or a test method. > > > In the postgissupport module this situation is handled by first catching > import errors for psycopg: > > try: > import psycopg > except ImportError: > psycopg = None > > > and then a function called by all postgis tests in the setUp method or > in the test method: > > _cannot_run_postgis_tests = None > def skip_if_no_postgis(): > global _cannot_run_postgis_tests > if _cannot_run_postgis_tests is None: > _cannot_run_postgis_tests = reason_for_not_running_tests() > if _cannot_run_postgis_tests: > raise support.SkipTest(_cannot_run_postgis_tests) > > reason_for_not_running_tests checks whether psycopg is None but also > does a few more tests since psycopg isn't the only requirement for the > postgis tests. Something simpler might suffice for your needs. I understand. However, in this particular case this won't work because the main (and only) test class is a specialisation of the class from the module we're importing and whose import we're trying to catch with SkipTest. ogclib contains class WMSClient [..] from ogclib import WMSClient class TestWMSClient (unittest.TestCase, WMSClient) def... def skip_if_no_ogclib() [..] This won't work since if the class TestWMSClient cannot be created since WMSClient is not available. Any idea how to solve this dilemma? Regards, Joey -- Unix is user friendly ... It's just picky about its friends. From bh at intevation.de Fri Mar 19 16:51:46 2004 From: bh at intevation.de (Bernhard Herzog) Date: Fri, 19 Mar 2004 16:51:46 +0100 Subject: Test programs assumptions In-Reply-To: <20040319153036.GB9104@finlandia.infodrom.north.de> (Martin Schulze's message of "Fri, 19 Mar 2004 16:30:37 +0100") References: <20040318105945.GZ9104@finlandia.infodrom.north.de> <20040318120613.GB9104@finlandia.infodrom.north.de> <20040318170841.GH9104@finlandia.infodrom.north.de> <20040318193218.GO9104@finlandia.infodrom.north.de> <20040319153036.GB9104@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > ogclib contains class WMSClient > > [..] > from ogclib import WMSClient > > class TestWMSClient (unittest.TestCase, WMSClient) > def... > def > skip_if_no_ogclib() > [..] > > This won't work since if the class TestWMSClient cannot be created > since WMSClient is not available. > > Any idea how to solve this dilemma? Is it really necessary that TestWMSClient is a subclass of WMSClient? You could do something like this instead: _ogc_import_error = "" try: from ogclib.WMSClient import WMSClient except ImportError, e: _ogc_import_error = str(e) def skip_if_no_ogclib(): if _ogc_import_error: raise support.SkipTest(_ogc_import_error) class TestWMSClient(unittest.TestCase): def setUp(self): skip_if_no_ogclib() def test_foo(self): client = WMSClient() ... WMSClient is a mix-in class and therfore is usually used by deriving a class from it, so it might be a bit cleaner to derive a special client class, like it's done in the tests in PyOGCLib itself. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From joey at infodrom.org Fri Mar 19 17:53:09 2004 From: joey at infodrom.org (Martin Schulze) Date: Fri, 19 Mar 2004 17:53:09 +0100 Subject: Test programs assumptions In-Reply-To: References: <20040318105945.GZ9104@finlandia.infodrom.north.de> <20040318120613.GB9104@finlandia.infodrom.north.de> <20040318170841.GH9104@finlandia.infodrom.north.de> <20040318193218.GO9104@finlandia.infodrom.north.de> <20040319153036.GB9104@finlandia.infodrom.north.de> Message-ID: <20040319165309.GC9104@finlandia.infodrom.north.de> Bernhard Herzog wrote: > Is it really necessary that TestWMSClient is a subclass of WMSClient? Hmm. That's the way it was used before. But no, it doesn't have to be used this way, especially since we only use two methods from it (maybe three in the end). I'll change the use like you suggested. Regards, Joey -- Unix is user friendly ... It's just picky about its friends. From cvs at intevation.de Fri Mar 19 17:57:33 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Fri, 19 Mar 2004 17:57:33 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_ogclib.py,1.4,1.5 Message-ID: <20040319165733.81AD413A0D@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv25518 Modified Files: test_ogclib.py Log Message: Several improvements: . Moved path detection and adding into a module of its own, adjustpath, which exports thubandir as main Thuban directory. . Reorganised the module in order to support the SkipTest feature for Thuban test cases. - Adjusted the error handling for importing the ogclib from the PyOGCLib package. - The test class is no longer a specialisation of WMSClient, but contains an instance of this particular class and uses its methods instead. - The special setUp() method will check whether importing PyOGCLib worked by calling the external function skip_if_no_ogclib() and also create the WMSClient instance. - Call support.run_tests() instead of unittest.main(). Index: test_ogclib.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_ogclib.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- test_ogclib.py 18 Mar 2004 17:13:28 -0000 1.4 +++ test_ogclib.py 19 Mar 2004 16:57:31 -0000 1.5 @@ -24,14 +24,10 @@ from string import split from sys import path -# Add the main Thuban directory so the path so that all modules are -# accessible as expected -# -if os.path.dirname (__file__) == "" or os.path.dirname (__file__) == ".": - thubandir = os.path.abspath ("../../../") -else: - thubandir = os.path.abspath (os.path.dirname(__file__) + "/../../..") -path.insert (0, thubandir) +from adjustpath import thubandir +path.insert (0, thubandir + "/test") + +import support # ---------------------------------------------------------------------- # FIXME: Temporary code until PyOGCLib is a standard requirement @@ -46,19 +42,25 @@ path.insert (0, pyogclib) # ---------------------------------------------------------------------- +_pyogclib_import_error = None try: from ogclib.WMSClient import WMSClient -except: - print "No PyOGCLib found, hence no tests available." - os._exit(-1) +except ImportError, extra: + _pyogclib_import_error = str(extra) -class TestOGCLib (unittest.TestCase, WMSClient): +class TestOGCLib (unittest.TestCase): """ Defines a test environment for the PyOGCLib, i.e. check whether URL strings are built properly. """ + wmsclient = None + + def setUp (self): + skip_if_no_ogclib() + self.wmsclient = WMSClient() + def compare_URLs (self, foo, bar): """ Check if two URLs are equal, i.e.: @@ -115,11 +117,11 @@ frida = "http://frida.intevation.org/cgi-bin/frida_wms?" - url = self.getCapabilitiesURL(frida, "1.0") + url = self.wmsclient.getCapabilitiesURL(frida, "1.0") result = frida + "WMTVER=1.0&REQUEST=capabilities" self.compare_URLs (url, result) - url = self.getCapabilitiesURL(frida, "1.1") + url = self.wmsclient.getCapabilitiesURL(frida, "1.1") result = frida + "VERSION=1.1&SERVICE=WMS&REQUEST=GetCapabilities" self.compare_URLs (url, result) @@ -148,7 +150,7 @@ result = result_base + \ "&LAYERS=" + "%2C".join(layers) + \ "&STYLES=" + "%2C".join(styles) - url = self.getMapURL(frida, format, width, height, epsg, + url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version) # Repeat and continue with version 1.1, as denoted in OGC 01-068r3 @@ -162,18 +164,18 @@ result = result_base + \ "&LAYERS=" + "%2C".join(layers) + \ "&STYLES=" + "%2C".join(styles) - url = self.getMapURL(frida, format, width, height, epsg, + url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version) self.compare_URLs (result, url) result += "&TRANSPARENT=TRUE" - url = self.getMapURL(frida, format, width, height, epsg, + url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version, transparent=1 ) self.compare_URLs (result, url) result += "&BGCOLOR=0xFF00FF" - url = self.getMapURL(frida, format, width, height, epsg, + url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version, transparent=1, bgcolor='0xFF00FF') self.compare_URLs (result, url) @@ -182,7 +184,7 @@ result = result_base + \ "&LAYERS=" + "%2C".join(layers) + \ "&STYLES=" + "%2C".join(styles) - url = self.getMapURL(frida, format, width, height, epsg, + url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version) self.compare_URLs (result, url) @@ -190,7 +192,7 @@ result = result_base + \ "&LAYERS=" + "%2C".join(layers) + \ "&STYLES=" + "%2C".join(styles) - url = self.getMapURL(frida, format, width, height, epsg, + url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version) self.compare_URLs (result, url) @@ -198,7 +200,7 @@ result = result_base + \ "&LAYERS=" + "%2C".join(layers) + \ "&STYLES=" + "%2C".join(styles) - url = self.getMapURL(frida, format, width, height, epsg, + url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version, styles = styles) self.compare_URLs (result, url) @@ -207,14 +209,20 @@ result = result_base + \ "&LAYERS=" + "%2C".join(layers) + \ "&STYLES=" + "%2C".join(styles) - url = self.getMapURL(frida, format, width, height, epsg, + url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version, styles = styles) self.compare_URLs (result, url) +def skip_if_no_ogclib(): + if _pyogclib_import_error is not None: + raise support.SkipTest(_pyogclib_import_error) +# raise support.SkipTest("No PyOGCLib found, hence no tests available.") + + if __name__ == "__main__": - unittest.main() + support.run_tests() """ From cvs at intevation.de Fri Mar 19 18:00:19 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Fri, 19 Mar 2004 18:00:19 +0100 (CET) Subject: joey: thuban/Extensions/wms/test adjustpath.py,NONE,1.1 Message-ID: <20040319170019.4FFD113A09@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv25580 Added Files: adjustpath.py Log Message: Moved path detection and adding into a module of its own. --- NEW FILE: adjustpath.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 """ Add the main Thuban directory to the path, so that Thuban modules can be added without problems. Exported variables: thubandir -- absolute path to the main Thuban directory """ __version__ = "$Revision: 1.1 $" # $Source: /thubanrepository/thuban/Extensions/wms/test/adjustpath.py,v $ # $Id: adjustpath.py,v 1.1 2004/03/19 17:00:17 joey Exp $ import os from sys import path if os.path.dirname(__file__) == "" or os.path.dirname(__file__) == ".": thubandir = os.path.abspath("../../..") else: thubandir = os.path.abspath(os.path.dirname(__file__) + "/../../..") path.insert(0, thubandir) From cvs at intevation.de Fri Mar 19 18:02:13 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Fri, 19 Mar 2004 18:02:13 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_ogclib.py,1.5,1.6 Message-ID: <20040319170213.3A6FF13A09@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv25617 Modified Files: test_ogclib.py Log Message: Removed a space before an opening parenthesis Index: test_ogclib.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_ogclib.py,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- test_ogclib.py 19 Mar 2004 16:57:31 -0000 1.5 +++ test_ogclib.py 19 Mar 2004 17:02:11 -0000 1.6 @@ -25,7 +25,7 @@ from sys import path from adjustpath import thubandir -path.insert (0, thubandir + "/test") +path.insert(0, thubandir + "/test") import support @@ -37,9 +37,9 @@ # Assume the PyOGCLib to be checked out next to the thuban main directory # setting PYTHONPATH accordingly is fine as well # -pyogclib = os.path.abspath (thubandir + "/../PyOGCLib") -if os.path.isdir (pyogclib) and os.path.isdir (pyogclib + "/ogclib"): - path.insert (0, pyogclib) +pyogclib = os.path.abspath(thubandir + "/../PyOGCLib") +if os.path.isdir(pyogclib) and os.path.isdir(pyogclib + "/ogclib"): + path.insert(0, pyogclib) # ---------------------------------------------------------------------- _pyogclib_import_error = None @@ -49,7 +49,7 @@ _pyogclib_import_error = str(extra) -class TestOGCLib (unittest.TestCase): +class TestOGCLib(unittest.TestCase): """ Defines a test environment for the PyOGCLib, i.e. check whether URL strings are built properly. @@ -57,11 +57,11 @@ wmsclient = None - def setUp (self): + def setUp(self): skip_if_no_ogclib() self.wmsclient = WMSClient() - def compare_URLs (self, foo, bar): + def compare_URLs(self, foo, bar): """ Check if two URLs are equal, i.e.: - check for same base URL @@ -69,64 +69,64 @@ - check whether all arguments from one URL also exist in the second """ - foo_tuple = split (foo, "?") - bar_tuple = split (bar, "?") + foo_tuple = split(foo, "?") + bar_tuple = split(bar, "?") # Check for same base URL if foo_tuple[0] != bar_tuple[0]: - self.fail ("%s != %s" % (foo_tuple[0], bar_tuple[0])) + self.fail("%s != %s" %(foo_tuple[0], bar_tuple[0])) # Check for same number of HTTP GET arguments if len(foo_tuple) != len(bar_tuple): - self.fail ("One URL has no arguments"); + self.fail("One URL has no arguments"); # Loop through all HTTP GET arguments for existance if len(foo_tuple) > 1 and len(bar_tuple) > 1: - foo_opts = split (foo_tuple[1], "&") - bar_opts = split (bar_tuple[1], "&") + foo_opts = split(foo_tuple[1], "&") + bar_opts = split(bar_tuple[1], "&") if len(foo_opts) != len(bar_opts): - self.fail ("Different number of arguments"); + self.fail("Different number of arguments"); for part in foo_opts: if part not in bar_opts: - self.fail ("%s not in second argument list" % part); + self.fail("%s not in second argument list" % part); - def test_compareURLs (self): + def test_compareURLs(self): """Perform some tests for own compare routine""" result = "http://frida.intevation.org/cgi-bin" - self.compare_URLs ("http://frida.intevation.org/cgi-bin", result) + self.compare_URLs("http://frida.intevation.org/cgi-bin", result) result = "http://frida.intevation.org/cgi-bin?foo=eins" - self.compare_URLs ("http://frida.intevation.org/cgi-bin?foo=eins", result) + self.compare_URLs("http://frida.intevation.org/cgi-bin?foo=eins", result) result = "http://frida.intevation.org/cgi-bin?foo=eins&bar=zwei" - self.compare_URLs ("http://frida.intevation.org/cgi-bin?foo=eins&bar=zwei", result) + self.compare_URLs("http://frida.intevation.org/cgi-bin?foo=eins&bar=zwei", result) result = "http://frida.intevation.org/cgi-bin?foo=eins&bar=zwei" - self.compare_URLs ("http://frida.intevation.org/cgi-bin?bar=zwei&foo=eins", result) + self.compare_URLs("http://frida.intevation.org/cgi-bin?bar=zwei&foo=eins", result) result = "http://frida.intevation.org/cgi-bin?foo=eins&bar=zwei&baz=jan&quux=tux" - self.compare_URLs ("http://frida.intevation.org/cgi-bin?baz=jan&bar=zwei&quux=tux&foo=eins", result) + self.compare_URLs("http://frida.intevation.org/cgi-bin?baz=jan&bar=zwei&quux=tux&foo=eins", result) - def test_CapabilityURL (self): + def test_CapabilityURL(self): """Test the getCapabilitiesURL() method""" frida = "http://frida.intevation.org/cgi-bin/frida_wms?" url = self.wmsclient.getCapabilitiesURL(frida, "1.0") result = frida + "WMTVER=1.0&REQUEST=capabilities" - self.compare_URLs (url, result) + self.compare_URLs(url, result) url = self.wmsclient.getCapabilitiesURL(frida, "1.1") result = frida + "VERSION=1.1&SERVICE=WMS&REQUEST=GetCapabilities" - self.compare_URLs (url, result) + self.compare_URLs(url, result) - def test_GetMapURL (self): + def test_GetMapURL(self): """Test the getMapURL() method""" frida = "http://frida.intevation.org/cgi-bin/frida_wms?" @@ -143,8 +143,8 @@ result_base = frida + "WMTVER=1.0&REQUEST=map" + \ "&FORMAT="+format_enc + \ - "&SRS=EPSG%s%d" % ("%3A", epsg) + \ - "&BBOX=%f%s%f%s%f%s%f" % (bbox['minx'], "%2C", bbox['miny'], "%2C", + "&SRS=EPSG%s%d" %("%3A", epsg) + \ + "&BBOX=%f%s%f%s%f%s%f" %(bbox['minx'], "%2C", bbox['miny'], "%2C", bbox['maxx'], "%2C", bbox['maxy']) + \ "&WIDTH=%s" % width + "&HEIGHT=%s" % height result = result_base + \ @@ -157,8 +157,8 @@ version = '1.1' result_base = frida + "VERSION=1.1&SERVICE=WMS&REQUEST=GetMap" + \ "&FORMAT="+format_enc + \ - "&SRS=EPSG%s%d" % ("%3A", epsg) + \ - "&BBOX=%f%s%f%s%f%s%f" % (bbox['minx'], "%2C", bbox['miny'], "%2C", + "&SRS=EPSG%s%d" %("%3A", epsg) + \ + "&BBOX=%f%s%f%s%f%s%f" %(bbox['minx'], "%2C", bbox['miny'], "%2C", bbox['maxx'], "%2C", bbox['maxy']) + \ "&WIDTH=%s" % width + "&HEIGHT=%s" % height result = result_base + \ @@ -166,19 +166,19 @@ "&STYLES=" + "%2C".join(styles) url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version) - self.compare_URLs (result, url) + self.compare_URLs(result, url) result += "&TRANSPARENT=TRUE" url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version, transparent=1 ) - self.compare_URLs (result, url) + self.compare_URLs(result, url) result += "&BGCOLOR=0xFF00FF" url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version, transparent=1, bgcolor='0xFF00FF') - self.compare_URLs (result, url) + self.compare_URLs(result, url) layers = [ 'foo' ] result = result_base + \ @@ -186,15 +186,15 @@ "&STYLES=" + "%2C".join(styles) url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version) - self.compare_URLs (result, url) + self.compare_URLs(result, url) - layers.append ('bar') + layers.append('bar') result = result_base + \ "&LAYERS=" + "%2C".join(layers) + \ "&STYLES=" + "%2C".join(styles) url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version) - self.compare_URLs (result, url) + self.compare_URLs(result, url) styles = [ 'something' ] result = result_base + \ @@ -203,16 +203,16 @@ url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version, styles = styles) - self.compare_URLs (result, url) + self.compare_URLs(result, url) - styles.append ('else') + styles.append('else') result = result_base + \ "&LAYERS=" + "%2C".join(layers) + \ "&STYLES=" + "%2C".join(styles) url = self.wmsclient.getMapURL(frida, format, width, height, epsg, bbox, layers, version=version, styles = styles) - self.compare_URLs (result, url) + self.compare_URLs(result, url) def skip_if_no_ogclib(): From cvs at intevation.de Fri Mar 19 20:43:42 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Fri, 19 Mar 2004 20:43:42 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.1,1.2 Message-ID: <20040319194342.94282139C9@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv27240 Modified Files: test_parser.py Log Message: Moved path detection and adding into a module of its own, adjustpath, which exports thubandir as main Thuban directory. Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- test_parser.py 18 Mar 2004 17:18:53 -0000 1.1 +++ test_parser.py 19 Mar 2004 19:43:40 -0000 1.2 @@ -30,16 +30,7 @@ import os import unittest -from sys import path - -# Add the main Thuban directory so the path so that all modules are -# accessible as expected -# -if os.path.dirname (__file__) == "" or os.path.dirname (__file__) == ".": - path.insert (0, os.path.abspath ("../../../")) -else: - path.insert (0, os.path.abspath (os.path.dirname(__file__) + "/../../..")) - +from adjustpath import thubandir from Extensions.wms.parser import WMSCapabilitiesParser @@ -247,6 +238,7 @@ bbox = {'minx': "3.42742e+06", 'miny': "5.78918e+06", 'maxx': "3.44380e+06", 'maxy': "5.80037e+06"} self.compareDicts (self.getLayerBBox('gewaesserpolyl', 31494),bbox) + def test_queryable (self): """ From cvs at intevation.de Fri Mar 19 20:47:20 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Fri, 19 Mar 2004 20:47:20 +0100 (CET) Subject: joey: thuban ChangeLog,1.633,1.634 Message-ID: <20040319194720.4AB0A139C9@lists.intevation.de> Author: joey Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv27263 Modified Files: ChangeLog Log Message: Added today's released work to the ChangeLog Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.633 retrieving revision 1.634 diff -u -d -r1.633 -r1.634 --- ChangeLog 18 Mar 2004 17:58:25 -0000 1.633 +++ ChangeLog 19 Mar 2004 19:47:17 -0000 1.634 @@ -1,3 +1,18 @@ +2004-03-19 Martin Schulze + + * Extensions/wms/test/test_parser.py (TestWMSCapabilitiesParser): + Moved path detection and adding into a module of its own, + adjustpath, which exports thubandir as main Thuban directory. + + * Extensions/wms/test/test_ogclib.py (TestWMSLib): Moved path + detection and adding into a module of its own, adjustpath, which + exports thubandir as main Thuban directory. Reorganised the + module in order to support the SkipTest feature for Thuban test + cases. + + * Extensions/wms/test/adjustpath.py: Moved path detection and + adding into a module of its own. + 2004-03-18 Martin Schulze * Extensions/wms/test/test_parser.py: Added another test for From cvs at intevation.de Fri Mar 19 20:53:09 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Fri, 19 Mar 2004 20:53:09 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.2,1.3 Message-ID: <20040319195309.7C7AB139C9@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv27344 Modified Files: test_parser.py Log Message: Nah, don't need the thubandir here, stupid me Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- test_parser.py 19 Mar 2004 19:43:40 -0000 1.2 +++ test_parser.py 19 Mar 2004 19:53:07 -0000 1.3 @@ -30,7 +30,7 @@ import os import unittest -from adjustpath import thubandir +import adjustpath from Extensions.wms.parser import WMSCapabilitiesParser From joey at infodrom.org Sun Mar 21 19:44:01 2004 From: joey at infodrom.org (Martin Schulze) Date: Sun, 21 Mar 2004 19:44:01 +0100 Subject: SRS handling questions Message-ID: <20040321184401.GE9104@finlandia.infodrom.north.de> Hi, I wonder how I should interpret the WMS specification with regards to SRS handling. The specification [OGC 01-068r3, ?7.1.4.5.5, page 26] says about inheritance of SRS: - Every layer shall have at least one SRS element that is either stated explicitly or inherited from a parent layer. - Layers may optionally add to the global SRS list, or to the list inherited from a parent layer. Since the specs don't lose a word how these two cases are distinguished, I'd consider them clashing. Does anybody feel I should not implement the first rule and skip the latter? Also, since the XML response has both foo and elements, I wonder if it wouldn't be wiser to extract information about availibl SRS from the element, except for the root layer. I'd say yes, but I'd better ask if somebody sees a problem with this. Regards, Joey -- No question is too silly to ask, but, of course, some are too silly to answer. -- Perl book From jan at intevation.de Mon Mar 22 10:10:38 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Mon, 22 Mar 2004 10:10:38 +0100 Subject: SRS handling questions In-Reply-To: <20040321184401.GE9104@finlandia.infodrom.north.de> References: <20040321184401.GE9104@finlandia.infodrom.north.de> Message-ID: <20040322091038.GA23627@intevation.de> On Sun, Mar 21, 2004 at 07:44:01PM +0100, Martin Schulze wrote: > I wonder how I should interpret the WMS specification with regards to > SRS handling. > > The specification [OGC 01-068r3, ?7.1.4.5.5, page 26] says about > inheritance of SRS: > > - Every layer shall have at least one SRS element that is either > stated explicitly or inherited from a parent layer. > > - Layers may optionally add to the global SRS list, or to the list > inherited from a parent layer. > > Since the specs don't lose a word how these two cases are > distinguished, I'd consider them clashing. I do understand the first rule and the syntax should be clear. To understand the second rule I would like to see an example to understand how this rule is to be expressed in the syntax. > Does anybody feel I should not implement the first rule and skip the > latter? Are you talking about the 2 rules or the 2 cases of the second rule? > Also, since the XML response has both foo and > elements, I wonder if it wouldn't be > wiser to extract information about availibl SRS from the > element, except for the root layer. > I'd say yes, but I'd better ask if somebody sees a problem with this. Are you talking about XML responses that came from the frida demo wms? If yes, please note that it is an older UMN MapServer and not necessarily 100% compliant with WMS specification. If there are both, they should be the same, right? So, at least there should be a test whether this is the case and raise a warning if not. Jan -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From joey at infodrom.org Mon Mar 22 10:24:57 2004 From: joey at infodrom.org (Martin Schulze) Date: Mon, 22 Mar 2004 10:24:57 +0100 Subject: SRS handling questions In-Reply-To: <20040322091038.GA23627@intevation.de> References: <20040321184401.GE9104@finlandia.infodrom.north.de> <20040322091038.GA23627@intevation.de> Message-ID: <20040322092457.GK9104@finlandia.infodrom.north.de> Moin! Jan-Oliver Wagner wrote: > > I wonder how I should interpret the WMS specification with regards to > > SRS handling. > > > > The specification [OGC 01-068r3, ?7.1.4.5.5, page 26] says about > > inheritance of SRS: > > > > - Every layer shall have at least one SRS element that is either > > stated explicitly or inherited from a parent layer. > > > > - Layers may optionally add to the global SRS list, or to the list > > inherited from a parent layer. > > > > Since the specs don't lose a word how these two cases are > > distinguished, I'd consider them clashing. > > I do understand the first rule and the syntax should be clear. > To understand the second rule I would like to see an example to > understand how this rule is to be expressed in the syntax. *smile* If I had an example and a different syntax, I wouldn't have to ask. > > Does anybody feel I should not implement the first rule and skip the > > latter? > > Are you talking about the 2 rules or the 2 cases of the second rule? Since I don't know when which of these rules may apply since I don't know how to distinguish between -replace and -addtoinherit I'm talking about the two rules. I guess the two cases of the second rules could be aggregated to 'add SRS to inherited list'. However, it's not very clear in the document as well. > > Also, since the XML response has both foo and > > elements, I wonder if it wouldn't be > > wiser to extract information about availibl SRS from the > > element, except for the root layer. > > I'd say yes, but I'd better ask if somebody sees a problem with this. > > Are you talking about XML responses that came from the frida demo wms? > If yes, please note that it is an older UMN MapServer and not > necessarily 100% compliant with WMS specification. I already noticed. According to the specs the root layer SRS is wrong. However, applying the programming paradigma below it doesn't matter to our implementation. However, that wasn't the reason, even though I'm currently using frida as an example. I'm merely talking about a good programming paradigma versus a strong specification implementation: "be strict in your output but lax in what you accept". > If there are both, they should be the same, right? Yes. They should. However, if they aren't, and the list of SRS is larger, it's likely to cause problems since there won't be a bounding box associated to an SRS. Hence, I tend to ignore the tags except for the root layer, and generate the list of SRS for child layers from their bounding box elements. Except if you disagree. > So, at least there should be a test whether this is the case and > raise a warning if not. This could be achieved. Regards, Joey -- Computers are not intelligent. They only think they are. From Silke.Reimer at intevation.de Mon Mar 22 10:46:48 2004 From: Silke.Reimer at intevation.de (Silke Reimer) Date: Mon, 22 Mar 2004 10:46:48 +0100 Subject: SRS handling questions In-Reply-To: <20040322092457.GK9104@finlandia.infodrom.north.de> References: <20040321184401.GE9104@finlandia.infodrom.north.de> <20040322091038.GA23627@intevation.de> <20040322092457.GK9104@finlandia.infodrom.north.de> Message-ID: <20040322094648.GA21327@intevation.de> On Mon, Mar 22, 2004 at 10:24:57AM +0100, Martin Schulze wrote: > Moin! > > Jan-Oliver Wagner wrote: > > > I wonder how I should interpret the WMS specification with regards to > > > SRS handling. > > > > > > The specification [OGC 01-068r3, ?7.1.4.5.5, page 26] says about > > > inheritance of SRS: > > > > > > - Every layer shall have at least one SRS element that is either > > > stated explicitly or inherited from a parent layer. > > > > > > - Layers may optionally add to the global SRS list, or to the list > > > inherited from a parent layer. > > > > > > Since the specs don't lose a word how these two cases are > > > distinguished, I'd consider them clashing. > > > > I do understand the first rule and the syntax should be clear. > > To understand the second rule I would like to see an example to > > understand how this rule is to be expressed in the syntax. > > *smile* If I had an example and a different syntax, I wouldn't have > to ask. Perhaps you could have a look on the deegree-exapmles [1] how the lat-lon people interpretate the spec. They are rather involved in the development of the OGC-specifications. > > > > Does anybody feel I should not implement the first rule and skip the > > > latter? > > > > Are you talking about the 2 rules or the 2 cases of the second rule? > > Since I don't know when which of these rules may apply since I don't > know how to distinguish between -replace and -addtoinherit > I'm talking about the two rules. > > I guess the two cases of the second rules could be aggregated to > 'add SRS to inherited list'. However, it's not very clear in the > document as well. > > > > Also, since the XML response has both foo and > > > elements, I wonder if it wouldn't be > > > wiser to extract information about availibl SRS from the > > > element, except for the root layer. > > > I'd say yes, but I'd better ask if somebody sees a problem with this. > > > > Are you talking about XML responses that came from the frida demo wms? > > If yes, please note that it is an older UMN MapServer and not > > necessarily 100% compliant with WMS specification. > > I already noticed. According to the specs the root layer SRS is wrong. > However, applying the programming paradigma below it doesn't matter > to our implementation. Please have in mind that the UMN MapServer is implementing WMS version 1.1.0 while you are referring to WMS version 1.1.1. I don't no whether there is a difference in the handling of SRS between these two versions but it is at least possible. Many greetings, Silke [1] http://deegree.sourceforge.net/ -- Silke Reimer Intevation GmbH http://intevation.de/ FreeGIS 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/20040322/a4c953a6/attachment.bin From joey at infodrom.org Mon Mar 22 11:00:37 2004 From: joey at infodrom.org (Martin Schulze) Date: Mon, 22 Mar 2004 11:00:37 +0100 Subject: SRS handling questions In-Reply-To: <20040322094648.GA21327@intevation.de> References: <20040321184401.GE9104@finlandia.infodrom.north.de> <20040322091038.GA23627@intevation.de> <20040322092457.GK9104@finlandia.infodrom.north.de> <20040322094648.GA21327@intevation.de> Message-ID: <20040322100037.GP9104@finlandia.infodrom.north.de> Silke Reimer wrote: > Perhaps you could have a look on the deegree-exapmles [1] how the > lat-lon people interpretate the spec. They are rather involved in > the development of the OGC-specifications. [..] > [1] http://deegree.sourceforge.net/ Will do. Thanks. > > I already noticed. According to the specs the root layer SRS is wrong. > > However, applying the programming paradigma below it doesn't matter > > to our implementation. > > Please have in mind that the UMN MapServer is implementing WMS > version 1.1.0 while you are referring to WMS version 1.1.1. I don't > no whether there is a difference in the handling of SRS between > these two versions but it is at least possible. I don't think this difference is responsible here. Bu as I said, our implementation should cope with both without a problem. Regards, Joey -- Computers are not intelligent. They only think they are. From jan at intevation.de Mon Mar 22 21:07:30 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Mon, 22 Mar 2004 21:07:30 +0100 Subject: SRS handling questions In-Reply-To: <20040322092457.GK9104@finlandia.infodrom.north.de> References: <20040321184401.GE9104@finlandia.infodrom.north.de> <20040322091038.GA23627@intevation.de> <20040322092457.GK9104@finlandia.infodrom.north.de> Message-ID: <20040322200730.GA14483@intevation.de> On Mon, Mar 22, 2004 at 10:24:57AM +0100, Martin Schulze wrote: > Yes. They should. However, if they aren't, and the list of SRS is > larger, it's likely to cause problems since there won't be a bounding > box associated to an SRS. Hence, I tend to ignore the tags > except for the root layer, and generate the list of SRS for child > layers from their bounding box elements. Except if you disagree. agreed, but you should carefully document in the code what you are doing and why and what the differences/uncertainties according to the speciication are. Best Jan -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From joey at infodrom.org Tue Mar 23 10:46:13 2004 From: joey at infodrom.org (Martin Schulze) Date: Tue, 23 Mar 2004 10:46:13 +0100 Subject: SRS handling questions In-Reply-To: <20040322200730.GA14483@intevation.de> References: <20040321184401.GE9104@finlandia.infodrom.north.de> <20040322091038.GA23627@intevation.de> <20040322092457.GK9104@finlandia.infodrom.north.de> <20040322200730.GA14483@intevation.de> Message-ID: <20040323094613.GC1655@finlandia.infodrom.north.de> Jan-Oliver Wagner wrote: > On Mon, Mar 22, 2004 at 10:24:57AM +0100, Martin Schulze wrote: > > Yes. They should. However, if they aren't, and the list of SRS is > > larger, it's likely to cause problems since there won't be a bounding > > box associated to an SRS. Hence, I tend to ignore the tags > > except for the root layer, and generate the list of SRS for child > > layers from their bounding box elements. Except if you disagree. > > agreed, but you should carefully document in the code what > you are doing and why and what the differences/uncertainties > according to the speciication are. Already done. Hope, nobody will complain about too much information in comments. Need to do the comparison and warning between and the calculation, though. I assume you'd like to see the warning displayed in an optional window? Regards, Joey -- GNU GPL: "The source will be with you... always." From thuban-bugs at intevation.de Tue Mar 23 16:26:10 2004 From: thuban-bugs at intevation.de (Request Tracker) Date: Tue, 23 Mar 2004 16:26:10 +0100 (CET) Subject: [bug #2360] (thuban) offer random color Message-ID: <20040323152610.190BF139C9@lists.intevation.de> this bug's URL: http://intevation.de/rt/webrt?serial_num=2360 ------------------------------------------------------------------------- Subject: offer random color Thuban version: CVS 2004-3-23 It would be nice to have the choice of a random color "ramp", in order to identify unique categories which are not in a quantitative relationship to other categories. Doing it by hand can be a bit tedious... -------------------------------------------- Managed by Request Tracker From thuban-bugs at intevation.de Tue Mar 23 16:26:36 2004 From: thuban-bugs at intevation.de (Request Tracker) Date: Tue, 23 Mar 2004 16:26:36 +0100 (CET) Subject: [bug #2361] (thuban) Classifiers should handle NULL fields in tables Message-ID: <20040323152636.ABB3213B53@lists.intevation.de> this bug's URL: http://intevation.de/rt/webrt?serial_num=2361 ------------------------------------------------------------------------- Subject: Classifiers should handle NULL fields in tables The classifiers make the assumption that all rows in the column they generate the classification for have non-NULL values. The should be extended to handle that case. The Table methods that return values will return None for NULL values. One case: GenQuantilesPanel.GetList in Thuban/UI/classgen.py -------------------------------------------- Managed by Request Tracker From jan at intevation.de Tue Mar 23 20:59:44 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Tue, 23 Mar 2004 20:59:44 +0100 Subject: create [Thuban-devel] subject header In-Reply-To: <20040319062236.GR9104@finlandia.infodrom.north.de> References: <32985.213.219.155.7.1079645699.squirrel@213.219.155.7> <20040319062236.GR9104@finlandia.infodrom.north.de> Message-ID: <20040323195944.GB32319@intevation.de> Alternatively to procmail, all modern MUAs offer filter rules where you can perform an equivalent operation. The idea not to add the prefix by MailMan is that it should be a users decision to either add the prefix or automatically sort it to thematic folders. On Fri, Mar 19, 2004 at 07:22:37AM +0100, Martin Schulze wrote: > Moritz Lennert wrote: > > Would it be possible to create a "[Thuban-devel]" subject header for the > > mailing list ? Just to make it easier to visualize... > > FWIW: I'd like to stay without that header since it disimproves the > subject readability and threads look quite err... strange with it. > > If your mail goes through a GNU/Linux or Unix account you can easily > flag your incoming mail to comply your personal wishes by using > procmail (|procmail -f- in .forward) and the following receipe: > > :0 fhw > * ^ List-Id:.*thuban-devel\.intevation\.de > | sed 's/^Subject: /Subject: [Thuban-devel]/' -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From joey at infodrom.org Wed Mar 24 11:54:09 2004 From: joey at infodrom.org (Martin Schulze) Date: Wed, 24 Mar 2004 11:54:09 +0100 Subject: ColourDialog doesn't use pre-set data for display Message-ID: <20040324105409.GJ1655@finlandia.infodrom.north.de> Hi! I noticed an oddity in wxWidgets/Python/GTK. It doesn't appear to other widget set bindings though. I've been able to track it down with help of Robert Roebling and Robin Dunn from the wxWidgets project. This mail is just to inform you about the nature and fix for the problem. I discovered this problem with Thuban and located it in Thuban.UI.classifier, but the real bug is somewhere inside the GTK/Python binding to wxWidgets. After creating the ColourDialog, pre-setting the colour the way Thuban does it, doesn't seem to take the effects I expected. Instead, the dialog always displays black as selected colour, regardless of a pre-setting (old value). In the example below I set the colour to red (#FF0000) after the dialog is created but before it is drawn on the screen. However, on my system it still displays black as selection instead of red. This bug has been confirmed by Robin Dunn , who is responsible for the Python bindings of wxWidgets. However, he discovered that this problem can be bypassed by using a different constructor and supplying the color data at the __init__ stage. Commented out in the attached example is an adjusted version with a workaround by Robin. He is working on a fix for the underlying problem. I've assigned Debian Bug#239782 to this problem. Regards, Joey -- Still can't talk about what I can't talk about. Sorry. -- Bruce Schneier -------------- next part -------------- A non-text attachment was scrubbed... Name: wxcolor.py Type: text/x-python Size: 3118 bytes Desc: not available Url : http://www.intevation.de/pipermail/thuban-devel/attachments/20040324/2d14fc9b/wxcolor.py From cvs at intevation.de Wed Mar 24 12:47:33 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 12:47:33 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_domutils.py,NONE,1.1 Message-ID: <20040324114733.3ECC513A0C@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv8128 Added Files: test_domutils.py Log Message: Test for the domutils module --- NEW FILE: test_domutils.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 """ Test for the domutils module """ __version__ = "$Revision: 1.1 $" # $Source: /thubanrepository/thuban/Extensions/wms/test/test_domutils.py,v $ # $Id: test_domutils.py,v 1.1 2004/03/24 11:47:31 joey Exp $ import unittest import xml.dom.minidom import adjustpath from Extensions.wms.domutils import getElementByName, getElementsByName class TestDOMutils(unittest.TestCase): """ Defines a test environment for the class WMSCapabilities. """ root = None def setUp(self): """ Set up the XML test string, parse it into a DOM element and hook it to the internal root variable. """ data = "\n".join(['', '', '', ' ', ' Osnabrueck', ' ', ' gewaesser', ' ', ' gewaesserpolyl', ' ', ' ', ' ', ' gruenflaechen', ' ', ' ', '']) self.root = xml.dom.minidom.parseString(data).documentElement def compareLists(self, foo, bar): """ Compare two lists - check same number of elements - check whether all elements in the first list are part of the second """ # Check for same number of elements if len(foo) != len(bar): self.fail("Different number of elements"); # Loop through all elements for existance for elm in foo: if elm not in bar: self.fail("%s not in second list" % elm); def compareNodeLists (self, result, nodelist): """ Compares the Name children versus the given result list. """ names = [] for pivot in nodelist: for i in range (pivot.childNodes.length): if pivot.childNodes[i].nodeName == 'Name': names.append(pivot.childNodes[i].childNodes[0].data) self.compareLists(result, names) def compareNode (self, result, node): """ Compares the Name child versus the given result. """ for i in range (node.childNodes.length): if node.childNodes[i].nodeName == 'Name': self.assertEquals(result, node.childNodes[i].childNodes[0].data) break else: self.fail("No Name child found."); def test_compareLists (self): """ Test the internal compareLists function. """ # Zero element self.compareLists([], []) # Single element self.compareLists(['alpha'], ['alpha']) # Multiple elements self.compareLists(['alpha', 'beta', 'gamma'], ['alpha', 'beta', 'gamma']) # Multiple elements, different order self.compareLists(['alpha', 'beta', 'gamma'], ['gamma', 'alpha', 'beta']) def test_getElementsByName (self): """ Test for the getElementsByName function. """ # Test for level 1 result = ['Osnabrueck'] self.compareNodeLists(result, getElementsByName(self.root, 'Layer')) # Test for level 2 result = ['gruenflaechen', 'gewaesser'] self.compareNodeLists(result, getElementsByName(getElementsByName(self.root, 'Layer')[0], 'Layer')) # Test for level 3 result = ['gewaesserpolyl'] self.compareNodeLists(result, getElementsByName (getElementsByName (getElementsByName (self.root, 'Layer')[0], 'Layer')[0], 'Layer')) def test_getElementByName (self): """ Test for the getElementByName function. """ # Test for level 1 self.compareNode('Osnabrueck', getElementByName(self.root, 'Layer')) # Test for level 2 self.compareNode('gewaesser', getElementByName(getElementByName(self.root, 'Layer'), 'Layer')) # Test for level 3 self.compareNode('gewaesserpolyl', getElementByName (getElementByName (getElementByName (self.root, 'Layer'), 'Layer'), 'Layer')) if __name__ == "__main__": unittest.main() From cvs at intevation.de Wed Mar 24 12:48:53 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 12:48:53 +0100 (CET) Subject: joey: thuban/Extensions/wms domutils.py,NONE,1.1 Message-ID: <20040324114853.11AB013A0C@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv8161 Added Files: domutils.py Log Message: Convenience routines for handling of Document Object Model (DOM) nodes. --- NEW FILE: domutils.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 """ Convenience routines for handling of Document Object Model (DOM) nodes. For more information on DOM see . """ def listChildNodes (node): """ Prints a list of all child DOM nodes for the given node. This function is normally only used for inspection of a DOM tree during development. """ print "Node %s has %d children" % (node.nodeName, node.childNodes.length) for i in range (node.childNodes.length): print " %d: %s" % (i, node.childNodes[i].nodeName) def listAttributes (node): """ Prints a list of all DOM attributes for the given node. This function is normally only used for inspection of a DOM tree during development. """ print "Node %s has %d attributes" % (node.nodeName, node.attributes.length) for key in node.attributes.keys(): print " %s=%s" % (key, node.attributes.get(key).nodeValue) # Can't use node.getElementsByTagName(name) since it traverses the XML # data recursively and we need hierarchy information as well in order # to get inheritance of attributes implemented properly. # def getElementsByName (node, name): """ Returns a list of child DOM nodes whose nodeName matches given string. """ res = [] for i in range (node.childNodes.length): if node.childNodes[i].nodeName == name: res.append(node.childNodes[i]) return res def getElementByName (node, name): """ Returns the first child DOM node whose nodeName matches given string. """ try: return getElementsByName (node, name)[0] except IndexError: return None From cvs at intevation.de Wed Mar 24 17:34:16 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 17:34:16 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.3,1.4 Message-ID: <20040324163416.0171C13954@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv11953 Modified Files: test_parser.py Log Message: Need to encode non-ascii strings since Python works with unicode strings internally, otherwise comparisons will fail. Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- test_parser.py 19 Mar 2004 19:53:07 -0000 1.3 +++ test_parser.py 24 Mar 2004 16:34:13 -0000 1.4 @@ -103,7 +103,7 @@ if not self.capabilities: self.load_frida() - self.assertEquals (self.getTitle(),'Frida - Freie Vektor-Geodaten Osnabrück') + self.assertEquals (self.getTitle().encode('latin-1'),'Frida - Freie Vektor-Geodaten Osnabrück') self.assertEquals (self.getAbstract(),'') self.assertEquals (self.getFees(),'') self.assertEquals (self.getAccessConstraints(),'') @@ -114,7 +114,7 @@ 'strassenhinten', 'strassen', 'beschriftung', 'hauptbeschriftung', 'sehenswuerdigkeiten'] self.compareLists (self.getLayers(),layers) - self.compareLists (self.getSRS(),[31493]) + self.compareLists (self.getSRS(),['31493']) def test_LayerTitle (self): @@ -126,16 +126,16 @@ self.load_frida() # main layer - self.assertEquals (self.getLayerTitle('Osnabrueck'),'Frida - Freie Vektor-Geodaten Osnabrück') + self.assertEquals (self.getLayerTitle('Osnabrueck').encode('latin-1'),'Frida - Freie Vektor-Geodaten Osnabrück') # first nested layer - self.assertEquals (self.getLayerTitle('gruenflaechen'),'Grünflächen') + self.assertEquals (self.getLayerTitle('gruenflaechen').encode('latin-1'),'Grünflächen') # first nested layer - self.assertEquals (self.getLayerTitle('gewaesser'),'Gewässer') + self.assertEquals (self.getLayerTitle('gewaesser').encode('latin-1'),'Gewässer') # second nested layer - self.assertEquals (self.getLayerTitle('gewaesserpolyl'),'Gewässerflächen') + self.assertEquals (self.getLayerTitle('gewaesserpolyl').encode('latin-1'),'Gewässerflächen') def test_LayerSRS (self): From cvs at intevation.de Wed Mar 24 17:38:24 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 17:38:24 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.4,1.5 Message-ID: <20040324163824.EC86E13954@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv12006 Modified Files: test_parser.py Log Message: We don't need getLayerBBoxSRS() anymore since the SRS is calculated from the BoundingBoxes anyway in order to provide correct information, hence this routine is obsoleted by getLayerSRS(). Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- test_parser.py 24 Mar 2004 16:34:13 -0000 1.4 +++ test_parser.py 24 Mar 2004 16:38:21 -0000 1.5 @@ -192,24 +192,6 @@ self.compareDicts (self.getLayerLatLonBBox('gewaesserpolyl'),bbox) - def test_BBoxSRS (self): - """ - Check if the BoundingBoxSRS' are returned properly - """ - - if not self.capabilities: - self.load_frida() - - # Single SRS:BBox - self.compareLists (self.getLayerBBoxSRS('gruenflaechen'),[31493]) - - # Single inherited SRS:BBox - self.compareLists (self.getLayerBBoxSRS('gewaesser'),[31493]) - - # Multiple SRS:BBox - self.compareLists (self.getLayerBBoxSRS('gewaesserpolyl'),[31493, 31494]) - - def test_BoundingBoxes (self): """ Check if the BoundingBoxes are returned properly From cvs at intevation.de Wed Mar 24 17:42:48 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 17:42:48 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.5,1.6 Message-ID: <20040324164248.2E53A13954@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv12056 Modified Files: test_parser.py Log Message: SRS are stored in strings and Python has strong typechecking, so a number is either a cardinal number or a string, but the string has to be enclosed in quotes, different to how Perl works, my fault. Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- test_parser.py 24 Mar 2004 16:38:21 -0000 1.5 +++ test_parser.py 24 Mar 2004 16:42:45 -0000 1.6 @@ -147,25 +147,22 @@ self.load_frida() # SRS of main layer - self.compareLists (self.getLayerSRS('Osnabrueck'),[31493]) + self.compareLists (self.getLayerSRS('Osnabrueck'),['31493']) # Single SRS of layer without inheritance - self.compareLists (self.getLayerSRS('gruenflaechen'),[31493]) - - # Multiple SRS (new/1.1.1) of layer without inheritance - self.compareLists (self.getLayerSRS('gewaesserpolyl'),[31493, 31494]) + self.compareLists (self.getLayerSRS('gruenflaechen'),['31493']) - # Multiple SRS (old/1.0.0) of layer without inheritance - self.compareLists (self.getLayerSRS('gewaesserlinien'),[31493, 31494]) + # Multiple SRS of layer without inheritance, but overwriting + self.compareLists (self.getLayerSRS('gewaesserpolyl'),['31493', '31494']) - # Multiple SRS of layer with inheritance - self.compareLists (self.getLayerSRS('strassenhinten'),[31493, 31494]) + # Multiple SRS of layer with inheritance, one new locally + self.compareLists (self.getLayerSRS('gewaesserlinien'),['31493', '31492']) - # Multiple SRS (old/1.0.0) with inheritance - self.compareLists (self.getLayerSRS('strassen'),[31493, 31494, 31495]) + # Multiple SRS with inheritance, two new locally + self.compareLists (self.getLayerSRS('strassen'),['31493', '31494', '31495']) - # Multiple SRS (new/1.1.1) with inheritance - self.compareLists (self.getLayerSRS('beschriftung'),[31493, 31494, 31495]) + # Single SRS with inheritance but overwriting + self.compareLists (self.getLayerSRS('beschriftung'),['31493']) def test_LatLonBoundingBoxes (self): @@ -203,23 +200,23 @@ # main BoundingBox bbox = {'minx': "3.427e+06", 'miny': "5.787e+06", 'maxx': "3.4442e+06", 'maxy': "5.801e+06"} - self.compareDicts (self.getLayerBBox('Osnabrueck', 31493),bbox) + self.compareDicts (self.getLayerBBox('Osnabrueck', '31493'),bbox) # inherited BoundingBox - self.compareDicts (self.getLayerBBox('gewaesser', 31493),bbox) + self.compareDicts (self.getLayerBBox('gewaesser', '31493'),bbox) # overwritten BoundingBox bbox = {'minx': "3.427e+06", 'miny': "5.78901e+06", 'maxx': "3.44173e+06", 'maxy': "5.79952e+06"} - self.compareDicts (self.getLayerBBox('gewaesserlinien', 31493),bbox) + self.compareDicts (self.getLayerBBox('gewaesserlinien', '31492'),bbox) # multiple BoundingBoxes bbox = {'minx': "3.42743e+06", 'miny': "5.78919e+06", 'maxx': "3.44381e+06", 'maxy': "5.80038e+06"} - self.compareDicts (self.getLayerBBox('gewaesserpolyl', 31493),bbox) + self.compareDicts (self.getLayerBBox('gewaesserpolyl', '31493'),bbox) bbox = {'minx': "3.42742e+06", 'miny': "5.78918e+06", 'maxx': "3.44380e+06", 'maxy': "5.80037e+06"} - self.compareDicts (self.getLayerBBox('gewaesserpolyl', 31494),bbox) + self.compareDicts (self.getLayerBBox('gewaesserpolyl', '31494'),bbox) def test_queryable (self): From bh at intevation.de Wed Mar 24 17:48:58 2004 From: bh at intevation.de (Bernhard Herzog) Date: Wed, 24 Mar 2004 17:48:58 +0100 Subject: joey: thuban/Extensions/wms/test test_parser.py,1.3,1.4 In-Reply-To: <20040324163416.0171C13954@lists.intevation.de> (cvs@intevation.de's message of "Wed, 24 Mar 2004 17:34:16 +0100 (CET)") References: <20040324163416.0171C13954@lists.intevation.de> Message-ID: cvs at intevation.de writes: > Author: joey > > Update of /thubanrepository/thuban/Extensions/wms/test > In directory doto:/tmp/cvs-serv11953 > > Modified Files: > test_parser.py > Log Message: > Need to encode non-ascii strings since Python works with unicode > strings internally, otherwise comparisons will fail. [...] > - self.assertEquals (self.getTitle(),'Frida - Freie Vektor-Geodaten Osnabr?ck') > + self.assertEquals (self.getTitle().encode('latin-1'),'Frida - Freie Vektor-Geodaten Osnabr?ck') Alternatively you could use unicode literals instead. BTW, you still have spaces before the opening parenthesis. Keeping the lines shorter than 79 characters and putting spaces after the commas would also be more in line with the coding conventions. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From cvs at intevation.de Wed Mar 24 17:59:04 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 17:59:04 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.6,1.7 Message-ID: <20040324165904.A802813954@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv12236 Modified Files: test_parser.py Log Message: Move loading the sample file into the setUp method. Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- test_parser.py 24 Mar 2004 16:42:45 -0000 1.6 +++ test_parser.py 24 Mar 2004 16:59:02 -0000 1.7 @@ -76,7 +76,7 @@ self.fail ("%s has different value in second dictionary" % key); - def load_frida(self): + def setUp(self): """ Load the locally stored frida capabilities. http://frida.intevation.org/cgi-bin/frida_wms? @@ -100,9 +100,6 @@ Test general attributes extracted from Capabilities XML """ - if not self.capabilities: - self.load_frida() - self.assertEquals (self.getTitle().encode('latin-1'),'Frida - Freie Vektor-Geodaten Osnabrück') self.assertEquals (self.getAbstract(),'') self.assertEquals (self.getFees(),'') @@ -122,9 +119,6 @@ Check if layer titles are recognised properly """ - if not self.capabilities: - self.load_frida() - # main layer self.assertEquals (self.getLayerTitle('Osnabrueck').encode('latin-1'),'Frida - Freie Vektor-Geodaten Osnabrück') @@ -143,9 +137,6 @@ Check if the SRS are returned properly """ - if not self.capabilities: - self.load_frida() - # SRS of main layer self.compareLists (self.getLayerSRS('Osnabrueck'),['31493']) @@ -170,9 +161,6 @@ Check if the LatLonBoundingBoxes are returned properly """ - if not self.capabilities: - self.load_frida() - # main LatLonBoundingBox bbox = {'minx': "7.92881", 'miny': "52.2131", 'maxx': "8.18349", 'maxy': "52.341"} @@ -194,9 +182,6 @@ Check if the BoundingBoxes are returned properly """ - if not self.capabilities: - self.load_frida() - # main BoundingBox bbox = {'minx': "3.427e+06", 'miny': "5.787e+06", 'maxx': "3.4442e+06", 'maxy': "5.801e+06"} @@ -224,9 +209,6 @@ Check if layers are properly classified queryable or not """ - if not self.capabilities: - self.load_frida() - # implicit setting in main layer self.assertEquals (self.isQueryable('Osnabrueck'),0) @@ -241,7 +223,6 @@ # explicit setting in third layer self.assertEquals (self.isQueryable('strassen'),1) - if __name__ == "__main__": From cvs at intevation.de Wed Mar 24 18:00:40 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 18:00:40 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.7,1.8 Message-ID: <20040324170040.0FAAD13954@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv12281 Modified Files: test_parser.py Log Message: Added a test for finding the integrity problem in the sample response. Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- test_parser.py 24 Mar 2004 16:59:02 -0000 1.7 +++ test_parser.py 24 Mar 2004 17:00:37 -0000 1.8 @@ -95,6 +95,15 @@ self.grok (xml) + def test_grok (self): + """ + Test whether grok() discovers discrepances in the SRS + elements, calculated and specified. + """ + + self.compareLists(['name:beschriftung'], self.srs_discrepances, ) + + def test_general (self): """ Test general attributes extracted from Capabilities XML From cvs at intevation.de Wed Mar 24 18:07:10 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 18:07:10 +0100 (CET) Subject: joey: thuban/Extensions/wms/test sample.xml,1.1,1.2 Message-ID: <20040324170710.8B7E613954@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv12391 Modified Files: sample.xml Log Message: Adjusted the sample file so that elements match the elements, except for the layer 'beschriftung' Index: sample.xml =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/sample.xml,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- sample.xml 18 Mar 2004 17:18:53 -0000 1.1 +++ sample.xml 24 Mar 2004 17:07:08 -0000 1.2 @@ -92,7 +92,7 @@ Gewässerlinien EPSG:31493 EPSG:31492 - @@ -102,7 +102,7 @@ strassenhinten Strassenhintergrund - EPSG:31494 + EPSG:31493 @@ -112,7 +112,9 @@ Strassen EPSG:31494 EPSG:31495 - + From cvs at intevation.de Wed Mar 24 18:10:44 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 18:10:44 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.8,1.9 Message-ID: <20040324171044.0FBC013954@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv12437 Modified Files: test_parser.py Log Message: Remove spaces before opening parathesis Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- test_parser.py 24 Mar 2004 17:00:37 -0000 1.8 +++ test_parser.py 24 Mar 2004 17:10:41 -0000 1.9 @@ -35,12 +35,12 @@ from Extensions.wms.parser import WMSCapabilitiesParser -class TestWMSCapabilitiesParser (unittest.TestCase, WMSCapabilitiesParser): +class TestWMSCapabilitiesParser(unittest.TestCase, WMSCapabilitiesParser): """ Defines a test environment for the class WMSCapabilities. """ - def compareLists (self, foo, bar): + def compareLists(self, foo, bar): """ Compare two lists - check same number of elements @@ -49,15 +49,15 @@ # Check for same number of elements if len(foo) != len(bar): - self.fail ("Different number of elements"); + self.fail("Different number of elements"); # Loop through all elements for existance for elm in foo: if elm not in bar: - self.fail ("%s not in second list" % elm); + self.fail("%s not in second list" % elm); - def compareDicts (self, foo, bar): + def compareDicts(self, foo, bar): """ Compare two dictionaries (hashes) - check same number of keys @@ -66,14 +66,14 @@ # Check for same number of elements if len(foo) != len(bar): - self.fail ("Different number of keys"); + self.fail("Different number of keys"); # Loop through all elements for existance for key in foo.keys(): if key not in bar: - self.fail ("%s not in second dictionary" % key); + self.fail("%s not in second dictionary" % key); if foo[key] != bar[key]: - self.fail ("%s has different value in second dictionary" % key); + self.fail("%s has different value in second dictionary" % key); def setUp(self): @@ -84,18 +84,18 @@ try: try: - f = open ("sample.xml", "r") + f = open("sample.xml", "r") except: - f = open (os.path.dirname (__file__) + "/sample.xml", "r") + f = open(os.path.dirname(__file__) + "/sample.xml", "r") except: print "Cannot open sample.xml for reading" else: - xml = f.read (); + xml = f.read(); f.close() - self.grok (xml) + self.grok(xml) - def test_grok (self): + def test_grok(self): """ Test whether grok() discovers discrepances in the SRS elements, calculated and specified. @@ -104,68 +104,68 @@ self.compareLists(['name:beschriftung'], self.srs_discrepances, ) - def test_general (self): + def test_general(self): """ Test general attributes extracted from Capabilities XML """ - self.assertEquals (self.getTitle().encode('latin-1'),'Frida - Freie Vektor-Geodaten Osnabrück') - self.assertEquals (self.getAbstract(),'') - self.assertEquals (self.getFees(),'') - self.assertEquals (self.getAccessConstraints(),'') + self.assertEquals(self.getTitle().encode('latin-1'),'Frida - Freie Vektor-Geodaten Osnabrück') + self.assertEquals(self.getAbstract(),'') + self.assertEquals(self.getFees(),'') + self.assertEquals(self.getAccessConstraints(),'') formats = ['image/gif', 'image/png', 'image/jpeg', 'image/wbmp'] - self.compareLists (self.getFormats(),formats) + self.compareLists(self.getFormats(),formats) layers = ['Osnabrueck', 'gruenflaechen', 'gewaesser', 'gewaesserpolyl','gewaesserlinien', 'strassen_all', 'strassenhinten', 'strassen', 'beschriftung', 'hauptbeschriftung', 'sehenswuerdigkeiten'] - self.compareLists (self.getLayers(),layers) - self.compareLists (self.getSRS(),['31493']) + self.compareLists(self.getLayers(),layers) + self.compareLists(self.getSRS(),['31493']) - def test_LayerTitle (self): + def test_LayerTitle(self): """ Check if layer titles are recognised properly """ # main layer - self.assertEquals (self.getLayerTitle('Osnabrueck').encode('latin-1'),'Frida - Freie Vektor-Geodaten Osnabrück') + self.assertEquals(self.getLayerTitle('Osnabrueck').encode('latin-1'),'Frida - Freie Vektor-Geodaten Osnabrück') # first nested layer - self.assertEquals (self.getLayerTitle('gruenflaechen').encode('latin-1'),'Grünflächen') + self.assertEquals(self.getLayerTitle('gruenflaechen').encode('latin-1'),'Grünflächen') # first nested layer - self.assertEquals (self.getLayerTitle('gewaesser').encode('latin-1'),'Gewässer') + self.assertEquals(self.getLayerTitle('gewaesser').encode('latin-1'),'Gewässer') # second nested layer - self.assertEquals (self.getLayerTitle('gewaesserpolyl').encode('latin-1'),'Gewässerflächen') + self.assertEquals(self.getLayerTitle('gewaesserpolyl').encode('latin-1'),'Gewässerflächen') - def test_LayerSRS (self): + def test_LayerSRS(self): """ Check if the SRS are returned properly """ # SRS of main layer - self.compareLists (self.getLayerSRS('Osnabrueck'),['31493']) + self.compareLists(self.getLayerSRS('Osnabrueck'),['31493']) # Single SRS of layer without inheritance - self.compareLists (self.getLayerSRS('gruenflaechen'),['31493']) + self.compareLists(self.getLayerSRS('gruenflaechen'),['31493']) # Multiple SRS of layer without inheritance, but overwriting - self.compareLists (self.getLayerSRS('gewaesserpolyl'),['31493', '31494']) + self.compareLists(self.getLayerSRS('gewaesserpolyl'),['31493', '31494']) # Multiple SRS of layer with inheritance, one new locally - self.compareLists (self.getLayerSRS('gewaesserlinien'),['31493', '31492']) + self.compareLists(self.getLayerSRS('gewaesserlinien'),['31493', '31492']) # Multiple SRS with inheritance, two new locally - self.compareLists (self.getLayerSRS('strassen'),['31493', '31494', '31495']) + self.compareLists(self.getLayerSRS('strassen'),['31493', '31494', '31495']) # Single SRS with inheritance but overwriting - self.compareLists (self.getLayerSRS('beschriftung'),['31493']) + self.compareLists(self.getLayerSRS('beschriftung'),['31493']) - def test_LatLonBoundingBoxes (self): + def test_LatLonBoundingBoxes(self): """ Check if the LatLonBoundingBoxes are returned properly """ @@ -173,20 +173,20 @@ # main LatLonBoundingBox bbox = {'minx': "7.92881", 'miny': "52.2131", 'maxx': "8.18349", 'maxy': "52.341"} - self.compareDicts (self.getLayerLatLonBBox('Osnabrueck'),bbox) + self.compareDicts(self.getLayerLatLonBBox('Osnabrueck'),bbox) # inherited LatLonBoundingBox bbox = {'minx': "7.92881", 'miny': "52.2131", 'maxx': "8.18349", 'maxy': "52.341"} - self.compareDicts (self.getLayerLatLonBBox('gewaesser'),bbox) + self.compareDicts(self.getLayerLatLonBBox('gewaesser'),bbox) # third layer non-inherited LatLonBoundingBox bbox = {'minx': "7.93531", 'miny': "52.2328", 'maxx': "8.17739", 'maxy': "52.3353"} - self.compareDicts (self.getLayerLatLonBBox('gewaesserpolyl'),bbox) + self.compareDicts(self.getLayerLatLonBBox('gewaesserpolyl'),bbox) - def test_BoundingBoxes (self): + def test_BoundingBoxes(self): """ Check if the BoundingBoxes are returned properly """ @@ -194,44 +194,44 @@ # main BoundingBox bbox = {'minx': "3.427e+06", 'miny': "5.787e+06", 'maxx': "3.4442e+06", 'maxy': "5.801e+06"} - self.compareDicts (self.getLayerBBox('Osnabrueck', '31493'),bbox) + self.compareDicts(self.getLayerBBox('Osnabrueck', '31493'),bbox) # inherited BoundingBox - self.compareDicts (self.getLayerBBox('gewaesser', '31493'),bbox) + self.compareDicts(self.getLayerBBox('gewaesser', '31493'),bbox) # overwritten BoundingBox bbox = {'minx': "3.427e+06", 'miny': "5.78901e+06", 'maxx': "3.44173e+06", 'maxy': "5.79952e+06"} - self.compareDicts (self.getLayerBBox('gewaesserlinien', '31492'),bbox) + self.compareDicts(self.getLayerBBox('gewaesserlinien', '31492'),bbox) # multiple BoundingBoxes bbox = {'minx': "3.42743e+06", 'miny': "5.78919e+06", 'maxx': "3.44381e+06", 'maxy': "5.80038e+06"} - self.compareDicts (self.getLayerBBox('gewaesserpolyl', '31493'),bbox) + self.compareDicts(self.getLayerBBox('gewaesserpolyl', '31493'),bbox) bbox = {'minx': "3.42742e+06", 'miny': "5.78918e+06", 'maxx': "3.44380e+06", 'maxy': "5.80037e+06"} - self.compareDicts (self.getLayerBBox('gewaesserpolyl', '31494'),bbox) + self.compareDicts(self.getLayerBBox('gewaesserpolyl', '31494'),bbox) - def test_queryable (self): + def test_queryable(self): """ Check if layers are properly classified queryable or not """ # implicit setting in main layer - self.assertEquals (self.isQueryable('Osnabrueck'),0) + self.assertEquals(self.isQueryable('Osnabrueck'),0) # explicit setting in second layer - self.assertEquals (self.isQueryable('gruenflaechen'),0) + self.assertEquals(self.isQueryable('gruenflaechen'),0) # inherited setting in second layer - self.assertEquals (self.isQueryable('gewaesser'),0) + self.assertEquals(self.isQueryable('gewaesser'),0) # explicit setting in second layer - self.assertEquals (self.isQueryable('sehenswuerdigkeiten'),1) + self.assertEquals(self.isQueryable('sehenswuerdigkeiten'),1) # explicit setting in third layer - self.assertEquals (self.isQueryable('strassen'),1) + self.assertEquals(self.isQueryable('strassen'),1) if __name__ == "__main__": From joey at infodrom.org Wed Mar 24 18:15:10 2004 From: joey at infodrom.org (Martin Schulze) Date: Wed, 24 Mar 2004 18:15:10 +0100 Subject: joey: thuban/Extensions/wms/test test_parser.py,1.3,1.4 In-Reply-To: References: <20040324163416.0171C13954@lists.intevation.de> Message-ID: <20040324171510.GP1655@finlandia.infodrom.north.de> Bernhard Herzog wrote: > > Modified Files: > > test_parser.py > > Log Message: > > Need to encode non-ascii strings since Python works with unicode > > strings internally, otherwise comparisons will fail. > [...] > > - self.assertEquals (self.getTitle(),'Frida - Freie Vektor-Geodaten Osnabr?ck') > > + self.assertEquals (self.getTitle().encode('latin-1'),'Frida - Freie Vektor-Geodaten Osnabr?ck') > > Alternatively you could use unicode literals instead. That would remove readability for me which is why I opposed against it. > BTW, you still have spaces before the opening parenthesis. Keeping the I know. One issue after another. I believe in clean patches, and hence, don't want to commit one large patch with everything in it but smaller ones. > lines shorter than 79 characters and putting spaces after the commas > would also be more in line with the coding conventions. I thought I did? Hmm, not always, strange. I'll add that to my list, also linebreaks. Regards, Joey -- Still can't talk about what I can't talk about. Sorry. -- Bruce Schneier From cvs at intevation.de Wed Mar 24 18:56:39 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 18:56:39 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.9,1.10 Message-ID: <20040324175639.D6EDF13954@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv12818 Modified Files: test_parser.py Log Message: Too fast, use a method instead of directly accessing internal data Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- test_parser.py 24 Mar 2004 17:10:41 -0000 1.9 +++ test_parser.py 24 Mar 2004 17:56:37 -0000 1.10 @@ -101,7 +101,7 @@ elements, calculated and specified. """ - self.compareLists(['name:beschriftung'], self.srs_discrepances, ) + self.compareLists(['name:beschriftung'], self.get_srs_discrepances()) def test_general(self): From joey at infodrom.org Wed Mar 24 18:48:33 2004 From: joey at infodrom.org (Martin Schulze) Date: Wed, 24 Mar 2004 18:48:33 +0100 Subject: Linebreaks and Indention Message-ID: <20040324174833.GR1655@finlandia.infodrom.north.de> I noticed that python-mode *and* Python behave "a little bit" strange to linebreaks. If I try to break a longer line inside python-mode foo_bar_baz = bar auto-indention creates: foo_bar_baz = \ bar which only saves two characters width, which is rediculous. Do you want the second line indented by 4 characters or zero characters? I.e. foo_bar_baz = \ bar or foo_bar_baz = \ bar The latter is created by python-mode/auto-indent if one splits the line without inserting a backslash at once. Surprisingly Python will accept both. Another question is how you prefer to break long lines with function/method calls like foo_bar_baz(baz_bar Emacs python-mode/auto-indent automatically indents properly if split after an opening paranthesis: foo_bar_baz( baz_bar but not if split before the parentheis: foo_bar_baz (baz_bar Surprisingly Python will accept both. But which one do you prefer? Regards, Joey -- Still can't talk about what I can't talk about. Sorry. -- Bruce Schneier Please always Cc to me when replying to me on the lists. From bh at intevation.de Wed Mar 24 19:13:31 2004 From: bh at intevation.de (Bernhard Herzog) Date: Wed, 24 Mar 2004 19:13:31 +0100 Subject: Linebreaks and Indention In-Reply-To: <20040324174833.GR1655@finlandia.infodrom.north.de> (Martin Schulze's message of "Wed, 24 Mar 2004 18:48:33 +0100") References: <20040324174833.GR1655@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > I noticed that python-mode *and* Python behave "a little bit" strange > to linebreaks. > > If I try to break a longer line inside python-mode > > foo_bar_baz = bar > > auto-indention creates: > > foo_bar_baz = \ > bar > > which only saves two characters width, which is rediculous. If I have to split at a "=" (which I try to avoid) I usually do that before the =: foo_bar_baz \ = bar python-mode doesn't behave all that nicely in that case either but I usually adjust the indentation of the second line manually. The behavior of python-mode in this case has annoyed me a bit in the past but not enough that I've tried to do something about it. > Do you want the second line indented by 4 characters or zero > characters? I.e. > > foo_bar_baz = \ > bar > > or > > foo_bar_baz = \ > bar > > The latter is created by python-mode/auto-indent if one splits the > line without inserting a backslash at once. But reindenting the second line will move it again. > Surprisingly Python will accept both. For Python the amount of indentation in the second line doesn't matter at all as long as the backslash is the last character before the newline. > Another question is how you prefer to break long lines with > function/method calls like > > foo_bar_baz(baz_bar > > Emacs python-mode/auto-indent automatically indents properly if > split after an opening paranthesis: > > foo_bar_baz( > baz_bar > > but not if split before the parentheis: > > foo_bar_baz > (baz_bar > > Surprisingly Python will accept both. But which one do you prefer? The second one has a different meaning, so it's not acceptable :) I usually do foo_bar_baz(some - long - expression, second argument) That is, insert line breaks between the arguments. If the argument expressions are long I'd rather insert the line breaks in the argument expressions than directly before or after the parenthesis. Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From dcalvelo at minag.gob.pe Wed Mar 24 19:25:07 2004 From: dcalvelo at minag.gob.pe (Daniel Calvelo Aros) Date: Wed, 24 Mar 2004 13:25:07 -0500 Subject: Linebreaks and Indention In-Reply-To: <20040324174833.GR1655@finlandia.infodrom.north.de> References: <20040324174833.GR1655@finlandia.infodrom.north.de> Message-ID: <20040324181258.M42667@minag.gob.pe> On Wed, 24 Mar 2004 18:48:33 +0100, Martin Schulze wrote > I noticed that python-mode *and* Python behave "a little bit" strange > to linebreaks. > > If I try to break a longer line inside python-mode > > foo_bar_baz = bar > > auto-indention creates: > > foo_bar_baz = \ > bar > > which only saves two characters width, which is rediculous. > > Do you want the second line indented by 4 characters or zero > characters? I.e. > > foo_bar_baz = \ > bar > > or > > foo_bar_baz = \ > bar > > The latter is created by python-mode/auto-indent if one splits the > line without inserting a backslash at once. Surprisingly Python > will accept both. > > Another question is how you prefer to break long lines with > function/method calls like > > foo_bar_baz(baz_bar > > Emacs python-mode/auto-indent automatically indents properly if > split after an opening paranthesis: > > foo_bar_baz( > baz_bar > > but not if split before the parentheis: > > foo_bar_baz > (baz_bar > > Surprisingly Python will accept both. But which one do you prefer? In almost all cases, I try to indent by four spaces. Only exceptions are complicated expressions involving nested function calls, where I try to indent each functions arguments according to the expression structure, like: outer_call( tricky_function( arg_foo, arg_baz = bar, arg_bar ), further_function( with, its, own = args ) ) But that could as well be outer_call( tricky_function( arg_foo, arg_baz = bar, arg_bar ), further_function( with, its, own = args ) ) And we are back to the always-four-space-indent rule. Another interesting indentation layout is in generators, when they won't fit in a line. I'd rather have: [ very_long_expression for var in seq if condition ] than [ very_long_expression for var in seq if condition ] if that's what autoindent generates. BTW, opening brackets always at the end of the line. Old habit from the days where python wouldn't accept multi-line expressions sans backslash except with an unclosed bracket. Just my taste of it. Are you trying to build consensus? Stuff like this should be in the guidelines. Daniel. > Regards, > > Joey > > -- > Still can't talk about what I can't talk about. Sorry. -- Bruce Schneier > > Please always Cc to me when replying to me on the lists. > > _______________________________________________ > Thuban-devel mailing list > Thuban-devel at intevation.de > https://intevation.de/mailman/listinfo/thuban-devel -- Daniel Calvelo Aros -- Direcci?n General de Informaci?n Agraria -- Ministerio de Agricultura del Per? -- (51-1)424-9001 From cvs at intevation.de Wed Mar 24 20:13:56 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 20:13:56 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.10,1.11 Message-ID: <20040324191356.9E4F213AC2@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv13475 Modified Files: test_parser.py Log Message: Untypo Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- test_parser.py 24 Mar 2004 17:56:37 -0000 1.10 +++ test_parser.py 24 Mar 2004 19:13:54 -0000 1.11 @@ -97,11 +97,11 @@ def test_grok(self): """ - Test whether grok() discovers discrepances in the SRS + Test whether grok() discovers discrepancies in the SRS elements, calculated and specified. """ - self.compareLists(['name:beschriftung'], self.get_srs_discrepances()) + self.compareLists(['name:beschriftung'], self.get_srs_discrepancies()) def test_general(self): From joey at infodrom.org Wed Mar 24 20:17:55 2004 From: joey at infodrom.org (Martin Schulze) Date: Wed, 24 Mar 2004 20:17:55 +0100 Subject: Linebreaks and Indention In-Reply-To: References: <20040324174833.GR1655@finlandia.infodrom.north.de> Message-ID: <20040324191755.GS1655@finlandia.infodrom.north.de> Bernhard Herzog wrote: > If I have to split at a "=" (which I try to avoid) I usually do that > before the =: > > foo_bar_baz \ > = bar Will use this variant. > python-mode doesn't behave all that nicely in that case either but I > usually adjust the indentation of the second line manually. The > behavior of python-mode in this case has annoyed me a bit in the past > but not enough that I've tried to do something about it. But that would have been soo cool... :) > > Do you want the second line indented by 4 characters or zero > > characters? I.e. > > > > foo_bar_baz = \ > > bar > > > > or > > > > foo_bar_baz = \ > > bar > > > > The latter is created by python-mode/auto-indent if one splits the > > line without inserting a backslash at once. > > But reindenting the second line will move it again. Unfortunately. > > Surprisingly Python will accept both. > > For Python the amount of indentation in the second line doesn't matter > at all as long as the backslash is the last character before the > newline. Ah, I see. > > Another question is how you prefer to break long lines with > > function/method calls like > > > > foo_bar_baz(baz_bar > > > > Emacs python-mode/auto-indent automatically indents properly if > > split after an opening paranthesis: > > > > foo_bar_baz( > > baz_bar > > > > but not if split before the parentheis: > > > > foo_bar_baz > > (baz_bar > > > > Surprisingly Python will accept both. But which one do you prefer? > > The second one has a different meaning, so it's not acceptable :) Oops... > I usually do > > foo_bar_baz(some - long - expression, > second argument) > > That is, insert line breaks between the arguments. If the argument > expressions are long I'd rather insert the line breaks in the argument > expressions than directly before or after the parenthesis. Hmm, that doesn't quite fit. How would you like to have the following construct splitted? foo = getElementsByName( getElementByName(getElementByName(getElementByName( root, 'Capability'), 'Request'), 'GetMap'), 'Format') It could be done with a *long* root.foo.bar[0].baz[1].gnarz... chain as well. I don't want to assign four local variables just to keep all constructs short. Regards, Joey -- Still can't talk about what I can't talk about. Sorry. -- Bruce Schneier From joey at infodrom.org Wed Mar 24 20:22:50 2004 From: joey at infodrom.org (Martin Schulze) Date: Wed, 24 Mar 2004 20:22:50 +0100 Subject: Linebreaks and Indention In-Reply-To: <20040324181258.M42667@minag.gob.pe> References: <20040324174833.GR1655@finlandia.infodrom.north.de> <20040324181258.M42667@minag.gob.pe> Message-ID: <20040324192250.GU1655@finlandia.infodrom.north.de> Daniel Calvelo Aros wrote: > In almost all cases, I try to indent by four spaces. I used this as default for indention as well. > Only exceptions are complicated expressions involving nested function calls, > where I try to indent each functions arguments according to the expression > structure, like: > > outer_call( > tricky_function( > arg_foo, > arg_baz = bar, > arg_bar > ), > further_function( > with, > its, > own = args > ) > ) > > But that could as well be > > outer_call( > tricky_function( > arg_foo, > arg_baz = bar, > arg_bar > ), > further_function( > with, > its, > own = args > ) > ) Interesting idea. > BTW, opening brackets always at the end of the line. Old habit from the days > where python wouldn't accept multi-line expressions sans backslash except with > an unclosed bracket. Ah, I see. I'm new to Python. Hit one Perl-trap already the other day... > Just my taste of it. Are you trying to build consensus? Stuff like this should > be in the guidelines. I didn't discover it there. Consensus, well, not really. I'd like to know how the main developer, i.e. Bernhard, would like things to look like, especially when I'm unsure how to indent it properly. Regards, Joey -- Still can't talk about what I can't talk about. Sorry. -- Bruce Schneier From cvs at intevation.de Wed Mar 24 20:31:56 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 20:31:56 +0100 (CET) Subject: joey: thuban/Extensions/wms parser.py,NONE,1.1 Message-ID: <20040324193156.29A7313AC2@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv13727 Added Files: parser.py Log Message: Finally added the XML parser for the GetCapabilities response. --- NEW FILE: parser.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 """ Inspect WMS Capabilities for later processing. Information should only be retrieved with the proper get*() methods. class WMSCapabilitiesParser: __init__() grok(string) getTitle() getAbstract() getFees() getAccessConstraints() getFormats() getLayers() getSRS() getLayerTitle(layer) getLayerSRS(layer) getLayerLatLonBBox(layer) getLayerBBox(layer, srs) isQueryable(layer) get_srs_discrepancies() """ __version__ = "$Revision: 1.1 $" # $Source: /thubanrepository/thuban/Extensions/wms/parser.py,v $ # $Id: parser.py,v 1.1 2004/03/24 19:31:54 joey Exp $ import xml.dom.minidom from domutils import getElementsByName, getElementByName class WMSCapabilitiesParser: """ Thuban class to parse capabilities supplied as large string. This class provides methods to parse and retrieve particular information from the WMS capabilities XML. Information should only be extracted by the respective get*() methods. """ layers = None title = None abstract = None fees = None access = None formats = None srs_discrepancies = None def __init__(self): """ Initialises an instance in this class. """ # 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 = [] def grok(self, data): """ Parses the XML response to a WMS GetCapabilities request. Internal datastructure of the class will be filled. Information should only be retrieved with the respective get*() methods. """ root = xml.dom.minidom.parseString(data).documentElement # Extract the title foo = getElementByName(getElementByName(root, 'Service'), 'Title') if foo: self.title = foo.childNodes[0].data # Extract the abstract foo = getElementByName(getElementByName(root, 'Service'), 'Abstract') if foo and len(foo.childNodes[0].data): self.abstract = foo.childNodes[0].data # Extract fees information foo = getElementByName(getElementByName(root, 'Service'), 'Fees') if foo and len(foo.childNodes[0].data) \ and lower(foo.childNodes[0].data) != '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': 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) # Extract layer names self.layers = [] self.peekLayers(getElementByName(getElementByName( root, 'Capability'), 'Layer'), -1) def peekLayers(self, top, parent): """ Inspect the provided DOM fragment referenced as top. This method will inspect all included layers and traverse the tree recursively in order to fill the internal datastructure. Note that SRS other than EPSG:* are not yet supported, especially there is no support for AUTO and NONE. """ index = len (self.layers) self.layers.append({}) self.layers[index]['parent'] = parent for foo in top.attributes.keys(): if foo == 'queryable': self.layers[index]['queryable'] \ = int(top.attributes.get(foo).nodeValue) foo = getElementByName(top, 'Title') if foo and len(foo.childNodes[0].data): self.layers[index]['title'] = foo.childNodes[0].data foo = getElementByName(top, 'Name') if foo and len(foo.childNodes[0].data): self.layers[index]['name'] = foo.childNodes[0].data # These values are only used for an integrity check for foo in getElementsByName(top, 'SRS'): for srs in foo.childNodes[0].data.split(" "): if srs[0:5] == 'EPSG:': srs = srs[5:] try: self.layers[index]['srs'].append(srs) except KeyError: self.layers[index]['srs'] = [srs] foo = getElementByName(top, 'LatLonBoundingBox') if foo is not None: self.layers[index]['llbbox'] = {} for corner in ['minx', 'miny', 'maxx', 'maxy']: self.layers[index]['llbbox'][corner] \ = foo.attributes.get(corner).nodeValue boxes = getElementsByName(top, 'BoundingBox') if boxes != []: self.layers[index]['bbox'] = {} for foo in boxes: srs = foo.attributes.get('SRS').nodeValue if srs[0:5] == 'EPSG:': srs = srs[5:] self.layers[index]['bbox'][srs] = {} for corner in ['minx', 'miny', 'maxx', 'maxy']: self.layers[index]['bbox'][srs][corner] \ = foo.attributes.get(corner).nodeValue # Check for integrity self.checkLayerSRS(index) # Traverse subsidiary layers sublayer = getElementsByName(top, 'Layer') for l in sublayer: self.peekLayers(l, index) def checkLayerSRS(self, index): """ Checks the integrity of the underlying XML data. This is done by comparing the elements with the calculated list from the BoundingBox elements. index -- position in the layers array to check """ pivot = index calculated = [] while pivot != -1: if 'bbox' in self.layers[pivot]: for srs in self.layers[pivot]['bbox'].keys(): if srs not in calculated: calculated.append(srs) pivot = self.layers[pivot]['parent'] pivot = index specified = [] while pivot != -1: if 'srs' in self.layers[pivot]: for srs in self.layers[pivot]['srs']: if srs not in specified: specified.append(srs) pivot = self.layers[pivot]['parent'] equal = True # Check for same number of elements if len(calculated) != len(specified): equal = False # Loop through all elements for existance for elm in calculated: if elm not in specified: equal = False if not equal: if self.srs_discrepancies is None: self.srs_discrepancies = [] if 'name' in self.layers[index]: id = "name:%s" % self.layers[index]['name'] else: id = "title:%s" % self.layers[index]['title'] self.srs_discrepancies.append(id) def getTitle(self): """ Returns the main title of the WMS object. If no title is provided in the capabilities, an empty string is returned. """ if self.title is None: return '' else: return self.title def getAbstract(self): """ Returns the abstract of the WMS object. If no abstract is provided in the capabilities, an empty string is returned. """ if self.abstract is None: return '' else: return self.abstract def getFees(self): """ Returns the fees information of the WMS object. If no information is provided in the capabilities or if it is set to 'none', an empty string is returned. """ if self.fees is None: return '' else: return self.fees def getAccessConstraints(self): """ Returns information about access constraints for the WMS object. If no information is provided in the capabilities or if it is set to 'none', an empty string is returned. """ if self.access is None: return '' else: return self.access def getFormats(self): """ Returns a list of supported output formats. These are used in the GetMap request. This method will default to 'image/jpeg' if no format is recognised in XML Capabilities, assuming that JPEG will always be supported on the server side. """ if self.formats is None: return ['image/jpeg'] else: return self.formats def getLayers(self): """ Returns a list of layer names. 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. """ result = [] for layer in self.layers: if 'name' in layer: result.append(layer['name']) return result def getSRS(self): """ Returns the root list of spatial reference systems (SRS). This list is taken from the root layer. Those SRS are common to all subsidiary layers. If no SRS are common to all layers, an empty list is returned. If no layers were detected, an empty list is returned as well. """ if len(self.layers) == 0: return [] # index 0 denotes the root layer by design if 'srs' in self.layers[0].keys(): return self.layers[0]['srs'] def getLayerTitle(self, name): """ Returns the title of the named layer. If no such title or no such layer exists, an empty string is returned. """ for layer in self.layers: if 'name' in layer: if layer['name'] == name: if 'title' in layer: return layer['title'] return '' def getLayerSRS(self, name): """ Returns a list of spacial reference systems (SRS). The SRS are specified by the European Petroleum Survey Group (EPSG). There should be at least one SRS per layer, though. The prefix 'EPSG:' will be stripped. If none exists, an empty list is returned. The specification [OGC 01-068r3] says about inheritance of SRS: - Every layer is available in one or more SRS (or in an undefined SRS) - Geographic information whose SRS is undefined (e.g. digitised historical maps) shall use 'NONE' (case-sensitive). This implementation does not support this. - Every layer shall have at least one SRS element that is either stated explicitly or inherited from a parent layer. - The root layer element shall include a sequence of zero or more SRS elements listing all SRS which are common for to all subsidiary layers. - Layers may optionally add to the global SRS list, or to the list inherited from a parent layer. This implementation returns the list of SRS for the given layer, calculated by looking at BoundingBoxes defined in the named layer and all layers higher in the hierarchy up to the root layer which weren't overwritten. """ for i in range(len(self.layers)): if 'name' in self.layers[i]: if self.layers[i]['name'] == name: pivot = i break else: return [] result = [] while pivot != -1: if 'bbox' in self.layers[pivot]: for srs in self.layers[pivot]['bbox'].keys(): if srs not in result: result.append(srs) pivot = self.layers[pivot]['parent'] return result def getLayerLatLonBBox(self, name): """ Returns a dictionary of the LatLonBoundingBox. ... for the named layer if it exists. The SRS is always EPSG:4326 per convention. There should be at least one, though, inherited from the root layer at least. If none exists, the value None is returned. """ for layer in self.layers: if 'name' in layer: if layer['name'] == name: if 'llbbox' in layer: return layer['llbbox'] else: # No LatLonBoundingBox found in current layer, # so traverse the hierarchy upwards and check # again until there is one. pivot = layer while pivot['parent'] != -1: pivot = self.layers[pivot['parent']] if 'llbbox' in pivot: return pivot['llbbox'] return None def getLayerBBox(self, name, srs): """ Returns a dictionary of the BoundingBox. If no such BoundingBox exists, None is returned. The specification [OGC 01-068r3] says about BoundingBoxes: - Layers may have zero or more BoundingBox elements what are either stated explicitly or inherited from a parent layer. - A layer may have multiple BoundingBox elements, but each one shall state a different SRS. - A layer inherits any BoundingBoxes defined by its parents. - A BoundingBox inherited from the parent layer for a particular SRS is replaced by any declaration for the same SRS in the current layer. - A BoundingBox in the child layer for a new SRS which is not already declared by the parent, is added to the list of BoundingBoxes for the child layer. - A single layer shall not contain more than one BoundingBox element for the same SRS. """ for layer in self.layers: if 'name' in layer: if layer['name'] == name: if 'bbox' in layer: if srs in layer['bbox']: return layer['bbox'][srs] # No BoundingBox for the given SRS found in # current layer, so traverse the hierarchy upwards # and check again until there is one. pivot = layer while pivot['parent'] != -1: pivot = self.layers[pivot['parent']] if 'bbox' in pivot: if srs in pivot['bbox']: return pivot['bbox'][srs] return None def isQueryable(self, name): """ Returns the value of the queryable attribute of a layer. This attribute denotes whether this layer can be queried through the GetFeatureInfo request. The default value is 0. The specification [OGC 01-068r3] this attribute can be inherited. """ for layer in self.layers: if 'name' in layer: if layer['name'] == name: try: return layer['queryable'] except KeyError: # No attribute in this layer, so traverse the # hierarchy upwards pivot = layer while pivot['parent'] != -1: pivot = self.layers[pivot['parent']] if 'queryable' in pivot: return pivot['queryable'] return 0 def get_srs_discrepancies(self): """ Returns a list of layer identifications where the denoted SRS values differ from the calculated ones through BoundingBox elements. """ return self.srs_discrepancies if __name__ == "__main__": print "This module cannot be executed standalone." import os try: f = open("test/sample.xml", "r") except IOError: try: f = open(os.path.dirname(__file__) + "/test/sample.xml", "r") except IOError: print "Cannot open sample.xml for reading" if f is not None: sample = f.read(); f.close() ina = WMSCapabilitiesParser() ina.grok(sample) From cvs at intevation.de Wed Mar 24 20:35:23 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 20:35:23 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.11,1.12 Message-ID: <20040324193523.852A013AC2@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv13859/test Modified Files: test_parser.py Log Message: Added a space after a comma in arguments Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- test_parser.py 24 Mar 2004 19:13:54 -0000 1.11 +++ test_parser.py 24 Mar 2004 19:35:21 -0000 1.12 @@ -109,18 +109,19 @@ Test general attributes extracted from Capabilities XML """ - self.assertEquals(self.getTitle().encode('latin-1'),'Frida - Freie Vektor-Geodaten Osnabrück') - self.assertEquals(self.getAbstract(),'') - self.assertEquals(self.getFees(),'') - self.assertEquals(self.getAccessConstraints(),'') + self.assertEquals(self.getTitle().encode('latin-1'), + 'Frida - Freie Vektor-Geodaten Osnabrück') + self.assertEquals(self.getAbstract(), '') + self.assertEquals(self.getFees(), '') + self.assertEquals(self.getAccessConstraints(), '') formats = ['image/gif', 'image/png', 'image/jpeg', 'image/wbmp'] - self.compareLists(self.getFormats(),formats) + self.compareLists(self.getFormats(), formats) layers = ['Osnabrueck', 'gruenflaechen', 'gewaesser', 'gewaesserpolyl','gewaesserlinien', 'strassen_all', 'strassenhinten', 'strassen', 'beschriftung', 'hauptbeschriftung', 'sehenswuerdigkeiten'] - self.compareLists(self.getLayers(),layers) - self.compareLists(self.getSRS(),['31493']) + self.compareLists(self.getLayers(), layers) + self.compareLists(self.getSRS(), ['31493']) def test_LayerTitle(self): @@ -129,16 +130,20 @@ """ # main layer - self.assertEquals(self.getLayerTitle('Osnabrueck').encode('latin-1'),'Frida - Freie Vektor-Geodaten Osnabrück') + self.assertEquals(self.getLayerTitle('Osnabrueck').encode('latin-1'), + 'Frida - Freie Vektor-Geodaten Osnabrück') # first nested layer - self.assertEquals(self.getLayerTitle('gruenflaechen').encode('latin-1'),'Grünflächen') + self.assertEquals(self.getLayerTitle('gruenflaechen').encode('latin-1'), + 'Grünflächen') # first nested layer - self.assertEquals(self.getLayerTitle('gewaesser').encode('latin-1'),'Gewässer') + self.assertEquals(self.getLayerTitle('gewaesser').encode('latin-1'), + 'Gewässer') # second nested layer - self.assertEquals(self.getLayerTitle('gewaesserpolyl').encode('latin-1'),'Gewässerflächen') + self.assertEquals(self.getLayerTitle('gewaesserpolyl').encode('latin-1'), + 'Gewässerflächen') def test_LayerSRS(self): @@ -147,22 +152,22 @@ """ # SRS of main layer - self.compareLists(self.getLayerSRS('Osnabrueck'),['31493']) + self.compareLists(self.getLayerSRS('Osnabrueck'), ['31493']) # Single SRS of layer without inheritance - self.compareLists(self.getLayerSRS('gruenflaechen'),['31493']) + self.compareLists(self.getLayerSRS('gruenflaechen'), ['31493']) # Multiple SRS of layer without inheritance, but overwriting - self.compareLists(self.getLayerSRS('gewaesserpolyl'),['31493', '31494']) + self.compareLists(self.getLayerSRS('gewaesserpolyl'), ['31493', '31494']) # Multiple SRS of layer with inheritance, one new locally - self.compareLists(self.getLayerSRS('gewaesserlinien'),['31493', '31492']) + self.compareLists(self.getLayerSRS('gewaesserlinien'), ['31493', '31492']) # Multiple SRS with inheritance, two new locally - self.compareLists(self.getLayerSRS('strassen'),['31493', '31494', '31495']) + self.compareLists(self.getLayerSRS('strassen'), ['31493', '31494', '31495']) # Single SRS with inheritance but overwriting - self.compareLists(self.getLayerSRS('beschriftung'),['31493']) + self.compareLists(self.getLayerSRS('beschriftung'), ['31493']) def test_LatLonBoundingBoxes(self): @@ -173,17 +178,17 @@ # main LatLonBoundingBox bbox = {'minx': "7.92881", 'miny': "52.2131", 'maxx': "8.18349", 'maxy': "52.341"} - self.compareDicts(self.getLayerLatLonBBox('Osnabrueck'),bbox) + self.compareDicts(self.getLayerLatLonBBox('Osnabrueck'), bbox) # inherited LatLonBoundingBox bbox = {'minx': "7.92881", 'miny': "52.2131", 'maxx': "8.18349", 'maxy': "52.341"} - self.compareDicts(self.getLayerLatLonBBox('gewaesser'),bbox) + self.compareDicts(self.getLayerLatLonBBox('gewaesser'), bbox) # third layer non-inherited LatLonBoundingBox bbox = {'minx': "7.93531", 'miny': "52.2328", 'maxx': "8.17739", 'maxy': "52.3353"} - self.compareDicts(self.getLayerLatLonBBox('gewaesserpolyl'),bbox) + self.compareDicts(self.getLayerLatLonBBox('gewaesserpolyl'), bbox) def test_BoundingBoxes(self): @@ -194,23 +199,23 @@ # main BoundingBox bbox = {'minx': "3.427e+06", 'miny': "5.787e+06", 'maxx': "3.4442e+06", 'maxy': "5.801e+06"} - self.compareDicts(self.getLayerBBox('Osnabrueck', '31493'),bbox) + self.compareDicts(self.getLayerBBox('Osnabrueck', '31493'), bbox) # inherited BoundingBox - self.compareDicts(self.getLayerBBox('gewaesser', '31493'),bbox) + self.compareDicts(self.getLayerBBox('gewaesser', '31493'), bbox) # overwritten BoundingBox bbox = {'minx': "3.427e+06", 'miny': "5.78901e+06", 'maxx': "3.44173e+06", 'maxy': "5.79952e+06"} - self.compareDicts(self.getLayerBBox('gewaesserlinien', '31492'),bbox) + self.compareDicts(self.getLayerBBox('gewaesserlinien', '31492'), bbox) # multiple BoundingBoxes bbox = {'minx': "3.42743e+06", 'miny': "5.78919e+06", 'maxx': "3.44381e+06", 'maxy': "5.80038e+06"} - self.compareDicts(self.getLayerBBox('gewaesserpolyl', '31493'),bbox) + self.compareDicts(self.getLayerBBox('gewaesserpolyl', '31493'), bbox) bbox = {'minx': "3.42742e+06", 'miny': "5.78918e+06", 'maxx': "3.44380e+06", 'maxy': "5.80037e+06"} - self.compareDicts(self.getLayerBBox('gewaesserpolyl', '31494'),bbox) + self.compareDicts(self.getLayerBBox('gewaesserpolyl', '31494'), bbox) def test_queryable(self): @@ -219,19 +224,19 @@ """ # implicit setting in main layer - self.assertEquals(self.isQueryable('Osnabrueck'),0) + self.assertEquals(self.isQueryable('Osnabrueck'), 0) # explicit setting in second layer - self.assertEquals(self.isQueryable('gruenflaechen'),0) + self.assertEquals(self.isQueryable('gruenflaechen'), 0) # inherited setting in second layer - self.assertEquals(self.isQueryable('gewaesser'),0) + self.assertEquals(self.isQueryable('gewaesser'), 0) # explicit setting in second layer - self.assertEquals(self.isQueryable('sehenswuerdigkeiten'),1) + self.assertEquals(self.isQueryable('sehenswuerdigkeiten'), 1) # explicit setting in third layer - self.assertEquals(self.isQueryable('strassen'),1) + self.assertEquals(self.isQueryable('strassen'), 1) if __name__ == "__main__": From cvs at intevation.de Wed Mar 24 20:39:09 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 20:39:09 +0100 (CET) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.12,1.13 Message-ID: <20040324193909.1AA5C13AC2@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv14153 Modified Files: test_parser.py Log Message: Break lines in time Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- test_parser.py 24 Mar 2004 19:35:21 -0000 1.12 +++ test_parser.py 24 Mar 2004 19:39:06 -0000 1.13 @@ -134,7 +134,8 @@ 'Frida - Freie Vektor-Geodaten Osnabrück') # first nested layer - self.assertEquals(self.getLayerTitle('gruenflaechen').encode('latin-1'), + self.assertEquals(self.getLayerTitle( + 'gruenflaechen').encode('latin-1'), 'Grünflächen') # first nested layer @@ -142,7 +143,8 @@ 'Gewässer') # second nested layer - self.assertEquals(self.getLayerTitle('gewaesserpolyl').encode('latin-1'), + self.assertEquals(self.getLayerTitle( + 'gewaesserpolyl').encode('latin-1'), 'Gewässerflächen') @@ -158,13 +160,16 @@ self.compareLists(self.getLayerSRS('gruenflaechen'), ['31493']) # Multiple SRS of layer without inheritance, but overwriting - self.compareLists(self.getLayerSRS('gewaesserpolyl'), ['31493', '31494']) + self.compareLists(self.getLayerSRS('gewaesserpolyl'), + ['31493', '31494']) # Multiple SRS of layer with inheritance, one new locally - self.compareLists(self.getLayerSRS('gewaesserlinien'), ['31493', '31492']) + self.compareLists(self.getLayerSRS('gewaesserlinien'), + ['31493', '31492']) # Multiple SRS with inheritance, two new locally - self.compareLists(self.getLayerSRS('strassen'), ['31493', '31494', '31495']) + self.compareLists(self.getLayerSRS('strassen'), + ['31493', '31494', '31495']) # Single SRS with inheritance but overwriting self.compareLists(self.getLayerSRS('beschriftung'), ['31493']) From cvs at intevation.de Wed Mar 24 21:05:35 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 21:05:35 +0100 (CET) Subject: joey: thuban/Extensions/wms capabilities.py,1.1,1.2 Message-ID: <20040324200535.DCEB613AC2@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv15106 Modified Files: capabilities.py Log Message: Renamed the class to contain 'WMS', also added a linebreak where required Index: capabilities.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/capabilities.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- capabilities.py 16 Mar 2004 19:14:56 -0000 1.1 +++ capabilities.py 24 Mar 2004 20:05:33 -0000 1.2 @@ -68,7 +68,7 @@ from ogclib.WMSClient import WMSClient -class Capabilities (WMSClient): +class WMSCapabilities (WMSClient): """ Thuban class to maintain capabilities. This class provides methods to fetch, save and load capabilities as well as methods to @@ -100,7 +100,9 @@ if parm[0].find ("http://",0) == 0: self.fetchCapabilities (parm[0]) else: - self.errorMsg = _("Resource '%s' is neither local file nor URL") % parm[0] + self.errorMsg \ + = _("Resource '%s' is neither local file nor URL") + % parm[0] def getErrorMsg (self): @@ -150,7 +152,8 @@ if __name__ == "__main__": - capa = Capabilities("http://frida.intevation.org/cgi-bin/frida_wms?") + capabilities \ + = WMSCapabilities("http://frida.intevation.org/cgi-bin/frida_wms?") if capa.getErrorMsg() is None: capa.saveCapabilities("frida_capabilities.xml") else: From cvs at intevation.de Wed Mar 24 21:07:36 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Wed, 24 Mar 2004 21:07:36 +0100 (CET) Subject: joey: thuban/Extensions/wms capabilities.py,1.2,1.3 Message-ID: <20040324200736.7601D13AC2@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv15141 Modified Files: capabilities.py Log Message: Removed a space before an opening parenthesis, added a few spaces after a comma in argument lists Index: capabilities.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/capabilities.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- capabilities.py 24 Mar 2004 20:05:33 -0000 1.2 +++ capabilities.py 24 Mar 2004 20:07:34 -0000 1.3 @@ -24,10 +24,10 @@ getErrorMsg() - fetchCapabilities (*resource) - saveCapabilities (filename) - loadCapabilities (filename) - printCapabilities () + fetchCapabilities(*resource) + saveCapabilities(filename) + loadCapabilities(filename) + printCapabilities() Requirements: - PyOGCLib @@ -54,13 +54,13 @@ # Assume the PyOGCLib to be checked out next to the thuban main directory pyogclib = "../../../PyOGCLib" -if os.path.isdir (pyogclib) and os.path.isdir (pyogclib + "/ogclib"): - path.insert (0, pyogclib) +if os.path.isdir(pyogclib) and os.path.isdir(pyogclib + "/ogclib"): + path.insert(0, pyogclib) # We use gettext, so we need to import it and hence need to adjust the # path again if __name__ == "__main__": - path.insert (0, "../../") + path.insert(0, "../../") # ---------------------------------------------------------------------- @@ -68,7 +68,7 @@ from ogclib.WMSClient import WMSClient -class WMSCapabilities (WMSClient): +class WMSCapabilities(WMSClient): """ Thuban class to maintain capabilities. This class provides methods to fetch, save and load capabilities as well as methods to @@ -85,7 +85,7 @@ errorMsg = None wmsVersion = None - def __init__ (self, *parm): + def __init__(self, *parm): """ Initialises Capabilities with one optional parameter @@ -94,22 +94,22 @@ """ if parm and parm[0]: - if os.path.isfile (parm[0]): - self.loadCapabilities (parm[0]) + if os.path.isfile(parm[0]): + self.loadCapabilities(parm[0]) else: - if parm[0].find ("http://",0) == 0: - self.fetchCapabilities (parm[0]) + if parm[0].find("http://", 0) == 0: + self.fetchCapabilities(parm[0]) else: self.errorMsg \ = _("Resource '%s' is neither local file nor URL") % parm[0] - def getErrorMsg (self): + def getErrorMsg(self): return self.errorMsg - def fetchCapabilities (self, resource): + def fetchCapabilities(self, resource): """Fetches the WMS capabilities from an Internet resource""" self.wmsVersion = "1.1" @@ -119,32 +119,32 @@ self.capabilities = self.getCapabilities(resource, self.wmsVersion) - def saveCapabilities (self, fname): + def saveCapabilities(self, fname): """Save capabilities to local file""" if self.capabilities is None: self.errorMsg = _("No capabilities available") else: try: - out = open (fname, "w") - out.write (self.capabilities) + out = open(fname, "w") + out.write(self.capabilities) out.close() except: self.errorMsg = _("Can't open file '%s' for writing") % fname - def loadCapabilities (self, fname): + def loadCapabilities(self, fname): """Load capabilities from a local file""" try: - input = open (fname, "r") - self.capabilities = input.read () + input = open(fname, "r") + self.capabilities = input.read() input.close() except: self.errorMsg = _("Can't open file '%s' for reading") % fname - def printCapabilities (self): + def printCapabilities(self): """Prints capabilities to stdout""" print self.capabilities From thuban-bugs at intevation.de Thu Mar 25 00:04:51 2004 From: thuban-bugs at intevation.de (Request Tracker) Date: Thu, 25 Mar 2004 00:04:51 +0100 (CET) Subject: [bug #2363] (thuban) Info on thubanstart.py Message-ID: <20040324230451.6900D13AC2@lists.intevation.de> this bug's URL: http://intevation.de/rt/webrt?serial_num=2363 ------------------------------------------------------------------------- Subject: Info on thubanstart.py At startup time thuban searches for a user specific file thubanstart.py and prints the message "Thuban start module not available" if it not found onto stdout. Instead, the message should be printed to stdout, but a information be added to the about dialog like: /home/user/.thuban/thubanstart.py not found or /home/user/.thuban/thubanstart.py has been succesfully applied or /home/user/.thuban/thubanstart.py found, but parse errors occured I don't whether the distinction between successful and unsuccessful can or should be made though. -------------------------------------------- Managed by Request Tracker From jan at intevation.de Thu Mar 25 00:14:13 2004 From: jan at intevation.de (Jan-Oliver Wagner) Date: Thu, 25 Mar 2004 00:14:13 +0100 Subject: SRS handling questions In-Reply-To: <20040323094613.GC1655@finlandia.infodrom.north.de> References: <20040321184401.GE9104@finlandia.infodrom.north.de> <20040322091038.GA23627@intevation.de> <20040322092457.GK9104@finlandia.infodrom.north.de> <20040322200730.GA14483@intevation.de> <20040323094613.GC1655@finlandia.infodrom.north.de> Message-ID: <20040324231413.GE26274@intevation.de> On Tue, Mar 23, 2004 at 10:46:13AM +0100, Martin Schulze wrote: > Jan-Oliver Wagner wrote: > > On Mon, Mar 22, 2004 at 10:24:57AM +0100, Martin Schulze wrote: > > > Yes. They should. However, if they aren't, and the list of SRS is > > > larger, it's likely to cause problems since there won't be a bounding > > > box associated to an SRS. Hence, I tend to ignore the tags > > > except for the root layer, and generate the list of SRS for child > > > layers from their bounding box elements. Except if you disagree. > > > > agreed, but you should carefully document in the code what > > you are doing and why and what the differences/uncertainties > > according to the speciication are. > > Already done. Hope, nobody will complain about too much information > in comments. Need to do the comparison and warning between > and the calculation, though. > > I assume you'd like to see the warning displayed in an optional > window? not sure what you mean with that? Jan -- Jan-Oliver Wagner http://intevation.de/~jan/ Intevation GmbH http://intevation.de/ FreeGIS http://freegis.org/ From cvs at intevation.de Thu Mar 25 06:31:40 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Thu, 25 Mar 2004 06:31:40 +0100 (CET) Subject: joey: thuban ChangeLog,1.634,1.635 Message-ID: <20040325053140.DE6CE139AE@lists.intevation.de> Author: joey Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv23728 Modified Files: ChangeLog Log Message: Missing update for the ChangeLog Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.634 retrieving revision 1.635 diff -u -d -r1.634 -r1.635 --- ChangeLog 19 Mar 2004 19:47:17 -0000 1.634 +++ ChangeLog 25 Mar 2004 05:31:38 -0000 1.635 @@ -1,4 +1,31 @@ -2004-03-19 Martin Schulze +2004-03-24 Martin Schulze + + * Extensions/wms/capabilities.py: Renamed the class to contain + 'WMS', also added a linebreak where required + + * Extensions/wms/parser.py: Finally added the XML parser for the + GetCapabilities response. + + * Extensions/wms/test/sample.xml: Adjusted the sample file so that + elements match the elements, except for the + layer 'beschriftung'. + + * Extensions/wms/test/test_parser.py: Encode non-ascii strings + since Python uses unicode strings internally, otherwise + comparisons will fail. Removed tests for getLayerBBoxSRS() since + the SRS will be calculated anyway and this method is obsoleted by + getLayerSRS(). Denote SRS as strings and not as cardinal numbers. + Move loading the sample file into the setUp method. Added a test + for finding the integrity problem in the sample response. + Improved formatting. + + * Extensions/wms/domutils.py: Added convenience routines for + handling of Document Object Model (DOM) nodes. + + * Extensions/wms/test/test_domutils.py: Added a test for the + domutils module + +2004-03-19 Martin Schulze * Extensions/wms/test/test_parser.py (TestWMSCapabilitiesParser): Moved path detection and adding into a module of its own, From Silke.Reimer at intevation.de Thu Mar 25 09:10:48 2004 From: Silke.Reimer at intevation.de (Silke Reimer) Date: Thu, 25 Mar 2004 09:10:48 +0100 Subject: SRS handling questions In-Reply-To: <20040322092457.GK9104@finlandia.infodrom.north.de> References: <20040321184401.GE9104@finlandia.infodrom.north.de> <20040322091038.GA23627@intevation.de> <20040322092457.GK9104@finlandia.infodrom.north.de> Message-ID: <20040325081048.GA21119@intevation.de> On Mon, Mar 22, 2004 at 10:24:57AM +0100, Martin Schulze wrote: > > Yes. They should. However, if they aren't, and the list of SRS is > larger, it's likely to cause problems since there won't be a bounding > box associated to an SRS. Hence, I tend to ignore the tags > except for the root layer, and generate the list of SRS for child > layers from their bounding box elements. Except if you disagree. Sorry to reopen the discussion again, but I had the idea that the perhaps the SRS attribute in the BoundingBox element is not meant to define the existence of a new SRS but does only assign the BoundingBox to a special SRS. Perhaps a SRS should even not be appear in an BoundingBox element if it is not part of the SRS element. If there is no BoundingBox for in SRS the BoundingBox would just be the LatLonBoundingBox projected to the SRS. Does the spec write something about this relation? At least this would make sense in my opinion. As a follow-up the list of SRSs should not be derived from the bounding box elements of a layer, but only from the SRS element. What do you think? Silke -- Silke Reimer Intevation GmbH http://intevation.de/ FreeGIS 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/20040325/a714710a/attachment.bin From joey at infodrom.org Thu Mar 25 09:41:49 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 25 Mar 2004 09:41:49 +0100 Subject: SRS handling questions In-Reply-To: <20040325081048.GA21119@intevation.de> References: <20040321184401.GE9104@finlandia.infodrom.north.de> <20040322091038.GA23627@intevation.de> <20040322092457.GK9104@finlandia.infodrom.north.de> <20040325081048.GA21119@intevation.de> Message-ID: <20040325084148.GE1655@finlandia.infodrom.north.de> Moin! Silke Reimer wrote: > > Yes. They should. However, if they aren't, and the list of SRS is > > larger, it's likely to cause problems since there won't be a bounding > > box associated to an SRS. Hence, I tend to ignore the tags > > except for the root layer, and generate the list of SRS for child > > layers from their bounding box elements. Except if you disagree. > > Sorry to reopen the discussion again, but I had the idea that the > perhaps the SRS attribute in the BoundingBox element is not meant to > define the existence of a new SRS but does only assign the > BoundingBox to a special SRS. Perhaps a SRS should even not be true. > appear in an BoundingBox element if it is not part of the SRS *shrug* I don't remember the specs drawing any connection between the element and the elements. > element. If there is no BoundingBox for in SRS the BoundingBox would > just be the LatLonBoundingBox projected to the SRS. There's nothing like this mentioned in the specs, as far as I can see. > Does the spec write something about this relation? At least this > would make sense in my opinion. As a follow-up the list of SRSs > should not be derived from the bounding box elements of a layer, but > only from the SRS element. As far as I have understood the use of Bounding Boxes and SRS, each layer is available in multiple SRS. The map server will render the requested layer clipping using the specified projection. From the clients point of view, the layer is available in a number of SRSs, EPSG:4326 being the one used for the LatLonBoundingBox clipping, and others (or the same) for the other BoundingBox clippings. I'll quote the specs a bit: 6.5.5 [..] OGC Web Services are not required to support all possible SRSes, but shall advertise in their Capabilities XML those projections which they do offer and shall accept requests for all advertised projections. If a request contains an SRS not offered by a particular server, the server shall throw a Service Exception (code="InvalidSRS"). 7.1.4.5.7 [..] Each BoundingBox states the bounding rectangle of the map data in a particular spatial reference system; the attribute SRS indicates which SRS applies. [..] A Layer may have multiple Boundingbox elements, but each one shall state a different SRS. A Layer inherits any Bounding Box values defined by its parents. [..] A single Layer element shall not contain more than one BoundingBox for the same SRS. [..] A server which has the ability to transform data to different SRSes may choose not to provide an explicit BoundingBox for every possible SRS available for each Layer. The server should provide BoundingBox information for a tleast the native SRS of the Layer. My interpretation is that a layer is available for the SRS it announces in the elements (and llbbox) with the respective minimum enclosing rectangle as specified. When you request a map to be rendered by the map server, you'll have to supply the SRS you want to receive it rendered in. Using an SRS which wasn't announced, will most probably result in an exception instead of an image. Hence, I believe that the SRS denoted in the elements build the authoritative list of SRSes the map can be rendered in. Regards, Joey -- We all know Linux is great... it does infinite loops in 5 seconds. -- Linus Torvalds From Silke.Reimer at intevation.de Thu Mar 25 11:29:16 2004 From: Silke.Reimer at intevation.de (Silke Reimer) Date: Thu, 25 Mar 2004 11:29:16 +0100 Subject: SRS handling questions In-Reply-To: <20040325084148.GE1655@finlandia.infodrom.north.de> References: <20040321184401.GE9104@finlandia.infodrom.north.de> <20040322091038.GA23627@intevation.de> <20040322092457.GK9104@finlandia.infodrom.north.de> <20040325081048.GA21119@intevation.de> <20040325084148.GE1655@finlandia.infodrom.north.de> Message-ID: <20040325102916.GE21119@intevation.de> On Thu, Mar 25, 2004 at 09:41:49AM +0100, Martin Schulze wrote: > Moin! > > Silke Reimer wrote: > > > Yes. They should. However, if they aren't, and the list of SRS is > > > larger, it's likely to cause problems since there won't be a bounding > > > box associated to an SRS. Hence, I tend to ignore the tags > > > except for the root layer, and generate the list of SRS for child > > > layers from their bounding box elements. Except if you disagree. > > > > Sorry to reopen the discussion again, but I had the idea that the > > perhaps the SRS attribute in the BoundingBox element is not meant to > > define the existence of a new SRS but does only assign the > > BoundingBox to a special SRS. Perhaps a SRS should even not be > > true. > > > appear in an BoundingBox element if it is not part of the SRS > > *shrug* I don't remember the specs drawing any connection between the > element and the elements. > > > element. If there is no BoundingBox for in SRS the BoundingBox would > > just be the LatLonBoundingBox projected to the SRS. > > There's nothing like this mentioned in the specs, as far as I can see. > > > Does the spec write something about this relation? At least this > > would make sense in my opinion. As a follow-up the list of SRSs > > should not be derived from the bounding box elements of a layer, but > > only from the SRS element. > > As far as I have understood the use of Bounding Boxes and SRS, each > layer is available in multiple SRS. The map server will render the > requested layer clipping using the specified projection. From the > clients point of view, the layer is available in a number of SRSs, > EPSG:4326 being the one used for the LatLonBoundingBox clipping, and > others (or the same) for the other BoundingBox clippings. > > I'll quote the specs a bit: > > 6.5.5 > > [..] OGC Web Services are not required to support all possible > SRSes, but shall advertise in their Capabilities XML those > projections which they do offer and shall accept requests for all > advertised projections. > > If a request contains an SRS not offered by a particular server, > the server shall throw a Service Exception (code="InvalidSRS"). > > > 7.1.4.5.7 > > [..] Each BoundingBox states the bounding rectangle of the map data > in a particular spatial reference system; the attribute SRS > indicates which SRS applies. > > [..] A Layer may have multiple Boundingbox elements, but each one > shall state a different SRS. > > A Layer inherits any Bounding Box values defined by its parents. > > [..] A single Layer element shall not contain more than one > BoundingBox for the same SRS. > > The server should provide BoundingBox information for a tleast the > native SRS of the Layer. > > My interpretation is that a layer is available for the SRS it > announces in the elements (and llbbox) with the > respective minimum enclosing rectangle as specified. In my opinion the announcement of SRS is done in the SRS-element not in the BoundingBox-element (see above). > > When you request a map to be rendered by the map server, you'll have > to supply the SRS you want to receive it rendered in. Using an SRS > which wasn't announced, will most probably result in an exception > instead of an image. agreed. > > Hence, I believe that the SRS denoted in the elements > build the authoritative list of SRSes the map can be rendered in. I don't understand how you come to this conclusion You quote: [..] A server which has the ability to transform data to different SRSes may choose not to provide an explicit BoundingBox for every possible SRS available for each Layer. The server should provide BoundingBox information for a tleast the native SRS of the Layer. Hence you can announce SRSes without giving a BoundingBox for a specific SRS. I interpretate this as: The announcement is done in the SRS element while you *can* provide a BoundingBox. I agree with you that the spec doesn't prevent you to provide a BoundingBox for a SRS which is not in the SRS-element but my interpretation of the spec is that this should not be the case. Silke -- Silke Reimer Intevation GmbH http://intevation.de/ FreeGIS 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/20040325/9fc1dcd4/attachment.bin From bh at intevation.de Thu Mar 25 16:33:11 2004 From: bh at intevation.de (Bernhard Herzog) Date: Thu, 25 Mar 2004 16:33:11 +0100 Subject: Linebreaks and Indention References: <20040324174833.GR1655@finlandia.infodrom.north.de> <20040324191755.GS1655@finlandia.infodrom.north.de> Message-ID: Martin Schulze writes: > How would you like to have the following construct splitted? > > foo = getElementsByName( > getElementByName(getElementByName(getElementByName( > root, 'Capability'), 'Request'), 'GetMap'), 'Format') Well, that's a bit of a pathological case in general. In this particular case I'd probably write a function or method to combine those nested getElementByName calls, e.g. def getNestedElementsByName(element, *names): for name in names: element = getElementByName(element, name): return element And then you can do foo = getNestedElementsByName(root, 'Capability', 'Request', 'GetMap', 'Format') Or you could extend getElementByName to accept more than one name. > It could be done with a *long* root.foo.bar[0].baz[1].gnarz... chain as well. > > I don't want to assign four local variables just to keep all > constructs short. Well, sometimes it's easier to read if you introduce a new variable, sometimes not. I don't want to create rules that handle all of the possible situations. Not least because I wouldn't always abide by them :) Bernhard -- Intevation GmbH http://intevation.de/ Skencil http://sketch.sourceforge.net/ Thuban http://thuban.intevation.org/ From joey at infodrom.org Thu Mar 25 19:45:05 2004 From: joey at infodrom.org (Martin Schulze) Date: Thu, 25 Mar 2004 19:45:05 +0100 Subject: SRS handling questions In-Reply-To: <20040325102916.GE21119@intevation.de> References: <20040321184401.GE9104@finlandia.infodrom.north.de> <20040322091038.GA23627@intevation.de> <20040322092457.GK9104@finlandia.infodrom.north.de> <20040325081048.GA21119@intevation.de> <20040325084148.GE1655@finlandia.infodrom.north.de> <20040325102916.GE21119@intevation.de> Message-ID: <20040325184505.GS1655@finlandia.infodrom.north.de> Silke Reimer wrote: > > My interpretation is that a layer is available for the SRS it > > announces in the elements (and llbbox) with the > > respective minimum enclosing rectangle as specified. > > In my opinion the announcement of SRS is done in the SRS-element not > in the BoundingBox-element (see above). > You quote: > > [..] A server which has the ability to transform data to different > SRSes may choose not to provide an explicit BoundingBox for every > possible SRS available for each Layer. > > The server should provide BoundingBox information for a tleast the > native SRS of the Layer. > > Hence you can announce SRSes without giving a BoundingBox for a > specific SRS. I interpretate this as: The announcement is done in > the SRS element while you *can* provide a BoundingBox. *blush* You are correct. I don't know how I managed to overlook this during reading an typing. Doesn't this pose a problem with non-existent knowledge in the client about the known rectangle in that particular projection? The server can cope with it without a problem. > I agree with you that the spec doesn't prevent you to provide a > BoundingBox for a SRS which is not in the SRS-element but my > interpretation of the spec is that this should not be the case. Ok. I'll adjust the code. -- We all know Linux is great... it does infinite loops in 5 seconds. -- Linus Torvalds From Silke.Reimer at intevation.de Fri Mar 26 12:07:39 2004 From: Silke.Reimer at intevation.de (Silke Reimer) Date: Fri, 26 Mar 2004 12:07:39 +0100 Subject: SRS handling questions In-Reply-To: <20040325184505.GS1655@finlandia.infodrom.north.de> References: <20040321184401.GE9104@finlandia.infodrom.north.de> <20040322091038.GA23627@intevation.de> <20040322092457.GK9104@finlandia.infodrom.north.de> <20040325081048.GA21119@intevation.de> <20040325084148.GE1655@finlandia.infodrom.north.de> <20040325102916.GE21119@intevation.de> <20040325184505.GS1655@finlandia.infodrom.north.de> Message-ID: <20040326110739.GD1242@intevation.de> On Thu, Mar 25, 2004 at 07:45:05PM +0100, Martin Schulze wrote: > Silke Reimer wrote: > > > My interpretation is that a layer is available for the SRS it > > > announces in the elements (and llbbox) with the > > > respective minimum enclosing rectangle as specified. > > > > In my opinion the announcement of SRS is done in the SRS-element not > > in the BoundingBox-element (see above). > > > You quote: > > > > [..] A server which has the ability to transform data to different > > SRSes may choose not to provide an explicit BoundingBox for every > > possible SRS available for each Layer. > > > > The server should provide BoundingBox information for a tleast the > > native SRS of the Layer. > > > > Hence you can announce SRSes without giving a BoundingBox for a > > specific SRS. I interpretate this as: The announcement is done in > > the SRS element while you *can* provide a BoundingBox. > > *blush* You are correct. I don't know how I managed to overlook this > during reading an typing. > > Doesn't this pose a problem with non-existent knowledge in the client > about the known rectangle in that particular projection? The server > can cope with it without a problem. Hm, this depends on the ability of the client to reproject by himself. Obviously there must be at least on definition of a BoundingBox or LatLonBoundingBox. In addition I remember that one of those BoundingBoxes (I think it was LatLonBoundingBox but this has be checked in the spec) must contain the union of all rectangles which is covered by the projections. Thus there is a definition of an overall BoundingBox. I am not sure what happens if no BoundingBox is provided. I would assume that the specific projection than covers the union of all BoundingBoxes thus the rectangle defined by the LatLonBoundingBox. And then: If the client requests a wrong BoundingBox the worse is that he gets an empty image. This is not optimal but doesn't crash the client. I think the greatest problem is the "zoom to full extent" functionality of the client. Silke -- Silke Reimer Intevation GmbH http://intevation.de/ FreeGIS 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/20040326/16b08934/attachment.bin From cvs at intevation.de Fri Mar 26 19:04:26 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Fri, 26 Mar 2004 19:04:26 +0100 (CET) Subject: bernhard: thuban README,1.7,1.8 Message-ID: <20040326180426.E620A139A7@lists.intevation.de> Author: bernhard Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv10933 Modified Files: README Log Message: Nicer formatting of text. Improved descriptions. Reflected wxWidgets name change. Index: README =================================================================== RCS file: /thubanrepository/thuban/README,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- README 30 Oct 2003 18:17:01 -0000 1.7 +++ README 26 Mar 2004 18:04:23 -0000 1.8 @@ -5,9 +5,10 @@ $Date$ $Revision$ -Thuban is an interactive viewer for geographic data. It is written in -Python using the wxWindows toolkit for portability. It runs on Unix-like -systems and on Windows. +Thuban is an interactive viewer for geographic data. +Python and the wxWidgets framework ensure great portability. +Thuban is Free Software and runs on GNU/Linux, Windows +and several other operating systems. About the Name @@ -23,7 +24,7 @@ Thuban requires the following software to be installed: Python 2.2.1 http://www.python.org - wxWindows 2.4.0.4 http://www.wxwindows.org + wxWidgets 2.4.0.4 http://www.wxwidgets.org (formerly known as wxWindows) wxPython 2.4.0.4 http://www.wxpython.org proj 4.4.5 http://www.remotesensing.org/proj/ SQLite 2.8.3 http://www.hwaci.com/sw/sqlite/ @@ -31,9 +32,8 @@ The versions given are the lowest versions that are known to work. for proj, sqlite and pysqlite somewhat older versions probably work as well. -Note that the wxPython version must be the same as the wxWindows version -(Some wxPython binary packages already contain the right wxWindows -version) +Note that the wxPython version must be the same as the wxWidgets version +(Some wxPython binary packages already contain the right wxWidgets version) Optional software: @@ -79,9 +79,8 @@ License ------- -Thuban is licensed under the terms of the GNU General Public License -(GPL). +Thuban is licensed under the terms of the GNU General Public License (GPL). However, some of the extension modules in the extension subdirectory are -licensed under other free licenses. See the respective README files for -more details. +licensed under other Free Software licenses. +See the respective README files for details. From cvs at intevation.de Fri Mar 26 19:15:37 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Fri, 26 Mar 2004 19:15:37 +0100 (CET) Subject: bernhard: thuban ChangeLog,1.635,1.636 Message-ID: <20040326181537.4D41C139A7@lists.intevation.de> Author: bernhard Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv12908 Modified Files: ChangeLog Log Message: * Thuban/UI/about.py: Extended copyright to 2004 and added information about the thuban-devel mailinglist. * ChangeLog: Added changes. Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.635 retrieving revision 1.636 diff -u -d -r1.635 -r1.636 --- ChangeLog 25 Mar 2004 05:31:38 -0000 1.635 +++ ChangeLog 26 Mar 2004 18:15:34 -0000 1.636 @@ -1,3 +1,10 @@ +2004-03-26 Bernhard Reiter + * README: Nicer formatting of text. Improved descriptions. + Reflected wxWidgets name change. + + * Thuban/UI/about.py: Extended copyright to 2004 and added + information about the thuban-devel mailinglist. + 2004-03-24 Martin Schulze * Extensions/wms/capabilities.py: Renamed the class to contain From cvs at intevation.de Fri Mar 26 19:15:37 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Fri, 26 Mar 2004 19:15:37 +0100 (CET) Subject: bernhard: thuban/Thuban/UI about.py,1.11,1.12 Message-ID: <20040326181537.41F5B1398D@lists.intevation.de> Author: bernhard Update of /thubanrepository/thuban/Thuban/UI In directory doto:/tmp/cvs-serv12908/Thuban/UI Modified Files: about.py Log Message: * Thuban/UI/about.py: Extended copyright to 2004 and added information about the thuban-devel mailinglist. * ChangeLog: Added changes. Index: about.py =================================================================== RCS file: /thubanrepository/thuban/Thuban/UI/about.py,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- about.py 3 Feb 2004 19:12:03 -0000 1.11 +++ about.py 26 Mar 2004 18:15:35 -0000 1.12 @@ -1,6 +1,7 @@ -# Copyright (c) 2001, 2002, 2003 by Intevation GmbH +# Copyright (c) 2001, 2002, 2003, 2004 by Intevation GmbH # Authors: # Jonathan Coles +# Bernhard Reiter # # This program is free software under the GPL (>=v2) # Read the file COPYING coming with Thuban for details. @@ -89,14 +90,16 @@ text += \ _("Questions and comments can be sent to the following addresses:\n" - "\tThuban developers:\n\t\t\n" - "\tThuban mailing list:\n\t\t") + "\tGeneral list (public):\n\t\t\n" + "\tDevelopers list (public):\n\t\t\n" + "\tThuban team at Intevation:\n\t\t\n" + ) self.text = text text_title = wxStaticText(self, -1, _("Thuban is a program for exploring geographic data.\n\n") + - "Copyright 2001-2003 Intevation GmbH.\n" + + "Copyright 2001-2004 Intevation GmbH.\n" + _("Thuban is licensed under the GNU GPL"), style=wxST_NO_AUTORESIZE|wxALIGN_CENTRE) From bernhard at intevation.de Fri Mar 26 19:27:13 2004 From: bernhard at intevation.de (Bernhard Reiter) Date: Fri, 26 Mar 2004 19:27:13 +0100 Subject: Contributors and Extension modules Message-ID: <20040326182713.GE14619@intevation.de> Naturally we should document thoroughly, who did what on Thuban. We probably miss an AUTORS file in the short and in the long version. For Extension modules: What about adding a mechanism that adds section in the about dialog for each loaded or known extension module also stating the author and the title? Markus should be added to contributors now, btw? Bernhard -------------- 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/20040326/f7a66e87/attachment.bin From joey at infodrom.org Mon Mar 29 09:37:06 2004 From: joey at infodrom.org (Martin Schulze) Date: Mon, 29 Mar 2004 09:37:06 +0200 Subject: Contributors and Extension modules In-Reply-To: <20040326182713.GE14619@intevation.de> References: <20040326182713.GE14619@intevation.de> Message-ID: <20040329073706.GZ1655@finlandia.infodrom.north.de> Bernhard Reiter wrote: > For Extension modules: > What about adding a mechanism that > adds section in the about dialog > for each loaded or known extension module > also stating the author and the title? Good idea, I guess. However, since the extension should become a regular module in the long-term (at least I was told so) and at least then won't be maintained by a 'separate' author, I'd rather not emphasise on modules too much. Otherwise, the information should be extracted from the extension data, I'd presume. Regards, Joey -- The good thing about standards is that there are so many to choose from. -- Andrew S. Tanenbaum From cvs at intevation.de Tue Mar 30 18:25:05 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 30 Mar 2004 18:25:05 +0200 (CEST) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.13,1.14 Message-ID: <20040330162505.2B9C713B98@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv17384 Modified Files: test_parser.py Log Message: Adjust the tests to reflect the corrected interpretation of the standard: i.e. a layer does not have to define a BoundingBox for all SRSes it supports. Hence the specification is authoritative, not the list of BoundingBoxes. Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- test_parser.py 24 Mar 2004 19:39:06 -0000 1.13 +++ test_parser.py 30 Mar 2004 16:25:02 -0000 1.14 @@ -172,7 +172,8 @@ ['31493', '31494', '31495']) # Single SRS with inheritance but overwriting - self.compareLists(self.getLayerSRS('beschriftung'), ['31493']) + self.compareLists(self.getLayerSRS('beschriftung'), + ['31493', '31494', '31495']) def test_LatLonBoundingBoxes(self): From cvs at intevation.de Tue Mar 30 18:28:58 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 30 Mar 2004 18:28:58 +0200 (CEST) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.14,1.15 Message-ID: <20040330162858.39FDC13B98@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv17444 Modified Files: test_parser.py Log Message: Added a new test to ensure None is returned for a non-existing SRS. Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- test_parser.py 30 Mar 2004 16:25:02 -0000 1.14 +++ test_parser.py 30 Mar 2004 16:28:56 -0000 1.15 @@ -223,6 +223,9 @@ 'maxx': "3.44380e+06", 'maxy': "5.80037e+06"} self.compareDicts(self.getLayerBBox('gewaesserpolyl', '31494'), bbox) + # Non-existing BoundingBox + self.assertEquals(self.getLayerBBox('beschriftung', '31490'), None) + def test_queryable(self): """ From cvs at intevation.de Tue Mar 30 18:30:15 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 30 Mar 2004 18:30:15 +0200 (CEST) Subject: joey: thuban/Extensions/wms/test test_parser.py,1.15,1.16 Message-ID: <20040330163015.0134913B98@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms/test In directory doto:/tmp/cvs-serv17464 Modified Files: test_parser.py Log Message: Removed test_grok method since it is not applicable anymore. Listing more SRSes in elements is valid according to the specs. Index: test_parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/test/test_parser.py,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- test_parser.py 30 Mar 2004 16:28:56 -0000 1.15 +++ test_parser.py 30 Mar 2004 16:30:12 -0000 1.16 @@ -95,15 +95,6 @@ self.grok(xml) - def test_grok(self): - """ - Test whether grok() discovers discrepancies in the SRS - elements, calculated and specified. - """ - - self.compareLists(['name:beschriftung'], self.get_srs_discrepancies()) - - def test_general(self): """ Test general attributes extracted from Capabilities XML From cvs at intevation.de Tue Mar 30 19:25:22 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 30 Mar 2004 19:25:22 +0200 (CEST) Subject: joey: thuban/Extensions/wms parser.py,1.1,1.2 Message-ID: <20040330172522.2152913BA6@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv18247 Modified Files: parser.py Log Message: Adjusted the getLayerSRS method to return the list of SRSes extracted from elements instead of elements. Added a bit of documentation as well. Index: parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/parser.py,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- parser.py 24 Mar 2004 19:31:54 -0000 1.1 +++ parser.py 30 Mar 2004 17:25:20 -0000 1.2 @@ -385,6 +385,11 @@ - Layers may optionally add to the global SRS list, or to the list inherited from a parent layer. + - A server which has the ability to transform data to + different SRSes may choose not to provide an explicit + BoundingBox for every possible SRS available for each Layer. + Thus the list of elements are authoritative. + This implementation returns the list of SRS for the given layer, calculated by looking at BoundingBoxes defined in the named layer and all layers higher in the hierarchy up to the @@ -400,8 +405,8 @@ result = [] while pivot != -1: - if 'bbox' in self.layers[pivot]: - for srs in self.layers[pivot]['bbox'].keys(): + if 'srs' in self.layers[pivot]: + for srs in self.layers[pivot]['srs']: if srs not in result: result.append(srs) pivot = self.layers[pivot]['parent'] From cvs at intevation.de Tue Mar 30 20:05:56 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 30 Mar 2004 20:05:56 +0200 (CEST) Subject: joey: thuban/Extensions/wms parser.py,1.2,1.3 Message-ID: <20040330180556.16FC913BA4@lists.intevation.de> Author: joey Update of /thubanrepository/thuban/Extensions/wms In directory doto:/tmp/cvs-serv18693 Modified Files: parser.py Log Message: Removed integrity test since it was only implemented due to a misunderstanding. Index: parser.py =================================================================== RCS file: /thubanrepository/thuban/Extensions/wms/parser.py,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- parser.py 30 Mar 2004 17:25:20 -0000 1.2 +++ parser.py 30 Mar 2004 18:05:53 -0000 1.3 @@ -183,61 +183,10 @@ self.layers[index]['bbox'][srs][corner] \ = foo.attributes.get(corner).nodeValue - # Check for integrity - self.checkLayerSRS(index) - # Traverse subsidiary layers sublayer = getElementsByName(top, 'Layer') for l in sublayer: self.peekLayers(l, index) - - - def checkLayerSRS(self, index): - """ - Checks the integrity of the underlying XML data. - - This is done by comparing the elements with the - calculated list from the BoundingBox elements. - - index -- position in the layers array to check - """ - - pivot = index - calculated = [] - while pivot != -1: - if 'bbox' in self.layers[pivot]: - for srs in self.layers[pivot]['bbox'].keys(): - if srs not in calculated: - calculated.append(srs) - pivot = self.layers[pivot]['parent'] - - pivot = index - specified = [] - while pivot != -1: - if 'srs' in self.layers[pivot]: - for srs in self.layers[pivot]['srs']: - if srs not in specified: - specified.append(srs) - pivot = self.layers[pivot]['parent'] - - equal = True - # Check for same number of elements - if len(calculated) != len(specified): - equal = False - - # Loop through all elements for existance - for elm in calculated: - if elm not in specified: - equal = False - - if not equal: - if self.srs_discrepancies is None: - self.srs_discrepancies = [] - if 'name' in self.layers[index]: - id = "name:%s" % self.layers[index]['name'] - else: - id = "title:%s" % self.layers[index]['title'] - self.srs_discrepancies.append(id) def getTitle(self): From cvs at intevation.de Tue Mar 30 21:08:58 2004 From: cvs at intevation.de (cvs@intevation.de) Date: Tue, 30 Mar 2004 21:08:58 +0200 (CEST) Subject: joey: thuban ChangeLog,1.636,1.637 Message-ID: <20040330190858.2A6E013BC2@lists.intevation.de> Author: joey Update of /thubanrepository/thuban In directory doto:/tmp/cvs-serv19578 Modified Files: ChangeLog Log Message: Updates Index: ChangeLog =================================================================== RCS file: /thubanrepository/thuban/ChangeLog,v retrieving revision 1.636 retrieving revision 1.637 diff -u -d -r1.636 -r1.637 --- ChangeLog 26 Mar 2004 18:15:34 -0000 1.636 +++ ChangeLog 30 Mar 2004 19:08:55 -0000 1.637 @@ -1,4 +1,26 @@ +2004-03-30 Martin Schulze + + * Extensions/wms/parser.py (WMSCapabilitiesParser.getLayerSRS): + Adjusted the getLayerSRS method to return the list of SRSes + extracted from elements instead of elements. + Added a bit of documentation as well. + (WMSCapabilitiesParser.checkLayerSRS): Removed integrity test + since it was only implemented due to a misunderstanding. + + * Extensions/wms/test/test_parser.py + (TestWMSCapabilitiesParser.test_LayerSRS): Adjust the tests to + reflect the corrected interpretation of the standard: i.e. a layer + does not have to define a BoundingBox for all SRSes it supports. + Hence the specification is authoritative, not the list + of BoundingBoxes. + (TestWMSCapabilitiesParser.test_BoundingBoxes): Added a new test + to ensure None is returned for a non-existing SRS. + (TestWMSCapabilitiesParser.test_grok): Removed test_grok method + since it is not applicable anymore. Listing more SRSes in + elements is valid according to the specs. + 2004-03-26 Bernhard Reiter + * README: Nicer formatting of text. Improved descriptions. Reflected wxWidgets name change.