[DebianGIS-dev] [SCM] tilestache branch, upstream, updated. upstream/1.0.1-1-g3b73df9

David Paleino dapal at debian.org
Wed Nov 10 17:20:51 UTC 2010


The following commit has been merged in the upstream branch:
commit 3b73df9e7c8114438a407d6cf683fff92023ed5e
Author: David Paleino <dapal at debian.org>
Date:   Wed Nov 10 18:19:22 2010 +0100

    Imported Upstream version 1.1.3

diff --git a/README b/README
index 912c113..0b9c5b5 100644
--- a/README
+++ b/README
@@ -28,6 +28,10 @@ designers and cartographers.
     
     open('tile.png', 'w').write(bytes)
 
+---- Documentation ----
+
+http://tilestache.org/doc/
+
 ---- Features ----
 
 Rendering providers:
@@ -70,43 +74,6 @@ Yahoo! and others. It should be possible to make TileStache do whatever is
 necessary to support any external system, but we eschew complex, impenetrable
 standards in favor of pragmatic, fast utility with basic web clients.
 
----- Functions ----
-
-cgiHandler(environ, config='./tilestache.cfg', debug=False)
-    Read environment PATH_INFO, load up configuration, talk to stdout by CGI.
-
-handleRequest(layer, coord, extension)
-    Get a type string and image binary for a given request layer tile.
-    
-    Arguments:
-    - layer: instance of Core.Layer to render.
-    - coord: one ModestMaps.Core.Coordinate corresponding to a single tile.
-    - extension: filename extension to choose response type, e.g. "png" or "jpg".
-    
-    This is the main entry point, after site configuration has been loaded
-    and individual tiles need to be rendered.
-
-parseConfigfile(configpath)
-    Parse a configuration file and return a Configuration object.
-    
-    Configuration file is formatted as JSON with two sections, "cache" and "layers":
-    
-      {
-        "cache": { ... },
-        "layers": {
-          "layer-1": { ... },
-          "layer-2": { ... },
-          ...
-        }
-      }
-    
-    The full filesystem path to the file is significant, used
-    to resolve any relative paths found in the configuration.
-    
-    See the Caches module for more information on the "caches" section,
-    and the Core and Providers modules for more information on the
-    "layers" section.
-
 ---- Dependencies ----
 
 - ModestMaps: http://modestmaps.com, http://github.com/migurski/modestmaps-py
diff --git a/TileStache/Config.py b/TileStache/Config.py
index b57f164..6e156b1 100644
--- a/TileStache/Config.py
+++ b/TileStache/Config.py
@@ -61,6 +61,37 @@ import Geography
 
 class Configuration:
     """ A complete site configuration, with a collection of Layer objects.
+    
+        Attributes:
+        
+          cache:
+            Cache instance, e.g. TileStache.Caches.Disk etc.
+            See TileStache.Caches for details on what makes
+            a usable cache.
+        
+          layers:
+            Dictionary of layers keyed by name.
+            
+            When creating a custom layers dictionary, e.g. for dynamic
+            layer collections backed by some external configuration,
+            these dictionary methods must be provided for a complete
+            collection of layers:
+            
+              keys():
+                Return list of layer name strings.
+
+              items():
+                Return list of (name, layer) pairs.
+
+              __contains__(key):
+                Return boolean true if given key is an existing layer.
+                
+              __getitem__(key):
+                Return existing layer object for given key or raise KeyError.
+        
+          dirpath:
+            Local filesystem path for this configuration,
+            useful for expanding relative paths.
     """
     def __init__(self, cache, dirpath):
         self.cache = cache
@@ -192,8 +223,8 @@ def _parseConfigfileLayer(layer_dict, config, dirpath):
         provider_kwargs = {}
         
         if _class is Providers.Mapnik:
-            mapfile = provider_dict['mapfile']
-            provider_kwargs['mapfile'] = urljoin(dirpath, mapfile)
+            provider_kwargs['mapfile'] = provider_dict['mapfile']
+            provider_kwargs['fonts'] = provider_dict.get('fonts', None)
         
         elif _class is Providers.Proxy:
             if provider_dict.has_key('url'):
diff --git a/TileStache/Core.py b/TileStache/Core.py
index ad9f82a..3b4275b 100644
--- a/TileStache/Core.py
+++ b/TileStache/Core.py
@@ -113,12 +113,22 @@ class Metatile:
 class Layer:
     """ A Layer.
     
-        Properties:
-        - provider: render provider, see Providers module.
-        - config: Configuration instance, see Config module.
-        - projection: geographic projection, see Geography module.
-        - metatile: some information on drawing many tiles at once.
-        - stale_lock_timeout: number of seconds until a cache lock is forced.
+        Attributes:
+
+          provider:
+            Render provider, see Providers module.
+
+          config:
+            Configuration instance, see Config module.
+
+          projection:
+            Geographic projection, see Geography module.
+
+          metatile:
+            Some information for drawing many tiles at once.
+
+          stale_lock_timeout:
+            Number of seconds until a cache lock is forced.
     """
     def __init__(self, config, projection, metatile, stale_lock_timeout=15):
         self.provider = None
@@ -130,6 +140,9 @@ class Layer:
 
     def name(self):
         """ Figure out what I'm called, return a name if there is one.
+        
+            Layer names are stored in the Configuration object, so
+            config.layers must be inspected to find a matching name.
         """
         for (name, layer) in self.config.layers.items():
             if layer is self:
diff --git a/TileStache/Providers.py b/TileStache/Providers.py
index b1d0d23..3a6a663 100644
--- a/TileStache/Providers.py
+++ b/TileStache/Providers.py
@@ -69,7 +69,8 @@ For an example of a non-image provider, see TileStache.Goodies.Provider.PostGeoJ
 import os
 
 from StringIO import StringIO
-from urlparse import urlparse
+from posixpath import exists
+from urlparse import urlparse, urljoin
 from httplib import HTTPConnection
 from tempfile import mkstemp
 from urllib import urlopen
@@ -184,15 +185,22 @@ class Mapnik:
             XML mapfile keyword arg comes from TileStache config,
             and is an absolute path by the time it gets here.
         """
+        maphref = urljoin(layer.config.dirpath, mapfile)
+        scheme, h, path, q, p, f = urlparse(maphref)
+        
+        if scheme in ('file', ''):
+            self.mapfile = path
+        else:
+            self.mapfile = maphref
+        
         self.layer = layer
-        self.mapfile = str(mapfile)
         self.mapnik = None
         
         engine = mapnik.FontEngine.instance()
         
         if fonts:
             for font in glob(fonts.rstrip('/') + '/*.ttf'):
-                engine.register_font(font)
+                engine.register_font(str(font))
 
     def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom):
         """
@@ -200,12 +208,16 @@ class Mapnik:
         if self.mapnik is None:
             self.mapnik = mapnik.Map(0, 0)
             
-            handle, filename = mkstemp()
-            os.write(handle, urlopen(self.mapfile).read())
-            os.close(handle)
-
-            mapnik.load_map(self.mapnik, filename)
-            os.unlink(filename)
+            if exists(self.mapfile):
+                mapnik.load_map(self.mapnik, str(self.mapfile))
+            
+            else:
+                handle, filename = mkstemp()
+                os.write(handle, urlopen(self.mapfile).read())
+                os.close(handle)
+    
+                mapnik.load_map(self.mapnik, filename)
+                os.unlink(filename)
         
         self.mapnik.width = width
         self.mapnik.height = height
diff --git a/TileStache/__init__.py b/TileStache/__init__.py
index 441526c..a0e6b73 100644
--- a/TileStache/__init__.py
+++ b/TileStache/__init__.py
@@ -1,6 +1,12 @@
 """ A stylish alternative for caching your map tiles.
 
+TileStache is a Python-based server application that can serve up map tiles
+based on rendered geographic data. You might be familiar with TileCache
+(http://tilecache.org), the venerable open source WMS server from MetaCarta.
+TileStache is similar, but we hope simpler and better-suited to the needs of
+designers and cartographers.
 
+Documentation available at http://tilestache.org/doc/
 """
 
 import re
@@ -129,10 +135,14 @@ def splitPathInfo(pathinfo):
 
     return layer, coord, extension
 
-def requestHandler(config_path, path_info, query_string):
+def requestHandler(config, path_info, query_string):
     """ Generate a mime-type and response body for a given request.
     
-        Requires a path to a config file and PATH_INFO (e.g. "/example/0/0/0.png").
+        Requires a configuration and PATH_INFO (e.g. "/example/0/0/0.png").
+        
+        Config parameter can be a file path string for a JSON configuration file
+        or a configuration object with 'cache', 'layers', and 'dirpath' properties.
+        
         Query string is optional and not currently used. Calls getTile()
         to render actual tiles, and getPreview() to render preview.html.
     """
@@ -140,7 +150,14 @@ def requestHandler(config_path, path_info, query_string):
         if path_info is None:
             raise Core.KnownUnknown('Missing path_info in requestHandler().')
     
-        config = parseConfigfile(config_path)
+        if type(config) in (str, unicode):
+            # should be a path to a configuration file we can load
+            config = parseConfigfile(config)
+        else:
+            assert hasattr(config, 'cache'), 'Configuration object must have a cache.'
+            assert hasattr(config, 'layers'), 'Configuration object must have layers.'
+            assert hasattr(config, 'dirpath'), 'Configuration object must have a dirpath.'
+        
         layername, coord, extension = splitPathInfo(path_info)
         
         if layername not in config.layers:
@@ -167,10 +184,13 @@ def requestHandler(config_path, path_info, query_string):
 
     return mimetype, content
 
-def cgiHandler(environ, config_path='./tilestache.cfg', debug=False):
+def cgiHandler(environ, config='./tilestache.cfg', debug=False):
     """ Read environment PATH_INFO, load up configuration, talk to stdout by CGI.
     
         Calls requestHandler().
+        
+        Config parameter can be a file path string for a JSON configuration file
+        or a configuration object with 'cache', 'layers', and 'dirpath' properties.
     """
     if debug:
         import cgitb
@@ -179,7 +199,7 @@ def cgiHandler(environ, config_path='./tilestache.cfg', debug=False):
     path_info = environ.get('PATH_INFO', None)
     query_string = environ.get('QUERY_STRING', None)
     
-    mimetype, content = requestHandler(config_path, path_info, query_string)
+    mimetype, content = requestHandler(config, path_info, query_string)
 
     print >> stdout, 'Content-Length: %d' % len(content)
     print >> stdout, 'Content-Type: %s\n' % mimetype
diff --git a/doc/TileStache.Config.html b/doc/TileStache.Config.html
index 9e1280d..ea4a4b4 100644
--- a/doc/TileStache.Config.html
+++ b/doc/TileStache.Config.html
@@ -82,7 +82,38 @@ documentation&nbsp;for&nbsp;TileStache.Providers,&nbsp;TileStache.Core,&nbsp;and
 <font color="#000000" face="helvetica, arial"><a name="Configuration">class <strong>Configuration</strong></a></font></td></tr>
     
 <tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;complete&nbsp;site&nbsp;configuration,&nbsp;with&nbsp;a&nbsp;collection&nbsp;of&nbsp;Layer&nbsp;objects.<br>&nbsp;</tt></td></tr>
+<td colspan=2><tt>A&nbsp;complete&nbsp;site&nbsp;configuration,&nbsp;with&nbsp;a&nbsp;collection&nbsp;of&nbsp;Layer&nbsp;objects.<br>
+&nbsp;<br>
+Attributes:<br>
+&nbsp;<br>
+&nbsp;&nbsp;cache:<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Cache&nbsp;instance,&nbsp;e.g.&nbsp;TileStache.Caches.Disk&nbsp;etc.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;See&nbsp;TileStache.Caches&nbsp;for&nbsp;details&nbsp;on&nbsp;what&nbsp;makes<br>
+&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;usable&nbsp;cache.<br>
+&nbsp;<br>
+&nbsp;&nbsp;layers:<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;of&nbsp;layers&nbsp;keyed&nbsp;by&nbsp;name.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;When&nbsp;creating&nbsp;a&nbsp;custom&nbsp;layers&nbsp;dictionary,&nbsp;e.g.&nbsp;for&nbsp;dynamic<br>
+&nbsp;&nbsp;&nbsp;&nbsp;layer&nbsp;collections&nbsp;backed&nbsp;by&nbsp;some&nbsp;external&nbsp;configuration,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;these&nbsp;dictionary&nbsp;methods&nbsp;must&nbsp;be&nbsp;provided&nbsp;for&nbsp;a&nbsp;complete<br>
+&nbsp;&nbsp;&nbsp;&nbsp;collection&nbsp;of&nbsp;layers:<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keys():<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return&nbsp;list&nbsp;of&nbsp;layer&nbsp;name&nbsp;strings.<br>
+&nbsp;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;items():<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return&nbsp;list&nbsp;of&nbsp;(name,&nbsp;layer)&nbsp;pairs.<br>
+&nbsp;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__contains__(key):<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return&nbsp;boolean&nbsp;true&nbsp;if&nbsp;given&nbsp;key&nbsp;is&nbsp;an&nbsp;existing&nbsp;layer.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__getitem__(key):<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Return&nbsp;existing&nbsp;layer&nbsp;object&nbsp;for&nbsp;given&nbsp;key&nbsp;or&nbsp;raise&nbsp;KeyError.<br>
+&nbsp;<br>
+&nbsp;&nbsp;dirpath:<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Local&nbsp;filesystem&nbsp;path&nbsp;for&nbsp;this&nbsp;configuration,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;useful&nbsp;for&nbsp;expanding&nbsp;relative&nbsp;paths.<br>&nbsp;</tt></td></tr>
 <tr><td>&nbsp;</td>
 <td width="100%">Methods defined here:<br>
 <dl><dt><a name="Configuration-__init__"><strong>__init__</strong></a>(self, cache, dirpath)</dt></dl>
diff --git a/doc/TileStache.Core.html b/doc/TileStache.Core.html
index 4466995..3a5e964 100644
--- a/doc/TileStache.Core.html
+++ b/doc/TileStache.Core.html
@@ -152,12 +152,22 @@ Data descriptors inherited from <a href="exceptions.html#BaseException">exceptio
 <tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
 <td colspan=2><tt>A&nbsp;<a href="#Layer">Layer</a>.<br>
 &nbsp;<br>
-Properties:<br>
--&nbsp;provider:&nbsp;render&nbsp;provider,&nbsp;see&nbsp;Providers&nbsp;module.<br>
--&nbsp;config:&nbsp;Configuration&nbsp;instance,&nbsp;see&nbsp;Config&nbsp;module.<br>
--&nbsp;projection:&nbsp;geographic&nbsp;projection,&nbsp;see&nbsp;Geography&nbsp;module.<br>
--&nbsp;metatile:&nbsp;some&nbsp;information&nbsp;on&nbsp;drawing&nbsp;many&nbsp;tiles&nbsp;at&nbsp;once.<br>
--&nbsp;stale_lock_timeout:&nbsp;number&nbsp;of&nbsp;seconds&nbsp;until&nbsp;a&nbsp;cache&nbsp;lock&nbsp;is&nbsp;forced.<br>&nbsp;</tt></td></tr>
+Attributes:<br>
+&nbsp;<br>
+&nbsp;&nbsp;provider:<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Render&nbsp;provider,&nbsp;see&nbsp;Providers&nbsp;module.<br>
+&nbsp;<br>
+&nbsp;&nbsp;config:<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Configuration&nbsp;instance,&nbsp;see&nbsp;Config&nbsp;module.<br>
+&nbsp;<br>
+&nbsp;&nbsp;projection:<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Geographic&nbsp;projection,&nbsp;see&nbsp;Geography&nbsp;module.<br>
+&nbsp;<br>
+&nbsp;&nbsp;metatile:<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Some&nbsp;information&nbsp;for&nbsp;drawing&nbsp;many&nbsp;tiles&nbsp;at&nbsp;once.<br>
+&nbsp;<br>
+&nbsp;&nbsp;stale_lock_timeout:<br>
+&nbsp;&nbsp;&nbsp;&nbsp;Number&nbsp;of&nbsp;seconds&nbsp;until&nbsp;a&nbsp;cache&nbsp;lock&nbsp;is&nbsp;forced.<br>&nbsp;</tt></td></tr>
 <tr><td>&nbsp;</td>
 <td width="100%">Methods defined here:<br>
 <dl><dt><a name="Layer-__init__"><strong>__init__</strong></a>(self, config, projection, metatile, stale_lock_timeout<font color="#909090">=15</font>)</dt></dl>
@@ -174,7 +184,10 @@ Properties:<br>
 
 <dl><dt><a name="Layer-metaSubtiles"><strong>metaSubtiles</strong></a>(self, coord)</dt><dd><tt>List&nbsp;of&nbsp;all&nbsp;coords&nbsp;in&nbsp;a&nbsp;metatile&nbsp;and&nbsp;their&nbsp;x,&nbsp;y&nbsp;offsets&nbsp;in&nbsp;a&nbsp;parent&nbsp;image.</tt></dd></dl>
 
-<dl><dt><a name="Layer-name"><strong>name</strong></a>(self)</dt><dd><tt>Figure&nbsp;out&nbsp;what&nbsp;I'm&nbsp;called,&nbsp;return&nbsp;a&nbsp;name&nbsp;if&nbsp;there&nbsp;is&nbsp;one.</tt></dd></dl>
+<dl><dt><a name="Layer-name"><strong>name</strong></a>(self)</dt><dd><tt>Figure&nbsp;out&nbsp;what&nbsp;I'm&nbsp;called,&nbsp;return&nbsp;a&nbsp;name&nbsp;if&nbsp;there&nbsp;is&nbsp;one.<br>
+&nbsp;<br>
+<a href="#Layer">Layer</a>&nbsp;names&nbsp;are&nbsp;stored&nbsp;in&nbsp;the&nbsp;Configuration&nbsp;object,&nbsp;so<br>
+config.layers&nbsp;must&nbsp;be&nbsp;inspected&nbsp;to&nbsp;find&nbsp;a&nbsp;matching&nbsp;name.</tt></dd></dl>
 
 <dl><dt><a name="Layer-render"><strong>render</strong></a>(self, coord, format)</dt><dd><tt>Render&nbsp;a&nbsp;tile&nbsp;for&nbsp;a&nbsp;coordinate,&nbsp;return&nbsp;PIL&nbsp;Image-like&nbsp;object.<br>
 &nbsp;<br>
diff --git a/doc/TileStache.Goodies.Providers.html b/doc/TileStache.Goodies.Providers.html
index fc04964..2d15205 100644
--- a/doc/TileStache.Goodies.Providers.html
+++ b/doc/TileStache.Goodies.Providers.html
@@ -19,8 +19,8 @@
 <tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
 <td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="TileStache.Goodies.Providers.Composite.html">Composite</a><br>
 <a href="TileStache.Goodies.Providers.Grid.html">Grid</a><br>
-</td><td width="25%" valign=top><a href="TileStache.Goodies.Providers.MirrorOSM.html">MirrorOSM</a><br>
-<a href="TileStache.Goodies.Providers.PostGeoJSON.html">PostGeoJSON</a><br>
-</td><td width="25%" valign=top><a href="TileStache.Goodies.Providers.SolrGeoJSON.html">SolrGeoJSON</a><br>
+</td><td width="25%" valign=top><a href="TileStache.Goodies.Providers.PostGeoJSON.html">PostGeoJSON</a><br>
+<a href="TileStache.Goodies.Providers.SolrGeoJSON.html">SolrGeoJSON</a><br>
+</td><td width="25%" valign=top><a href="TileStache.Goodies.Providers.UrlTemplate.html">UrlTemplate</a><br>
 </td><td width="25%" valign=top></td></tr></table></td></tr></table>
 </body></html>
\ No newline at end of file
diff --git a/doc/TileStache.html b/doc/TileStache.html
index 19ee5d6..8d09897 100644
--- a/doc/TileStache.html
+++ b/doc/TileStache.html
@@ -9,7 +9,15 @@
 <font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>TileStache</strong></big></big></font></td
 ><td align=right valign=bottom
 ><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/migurski/public_html/TileStache/TileStache/__init__.py">/home/migurski/public_html/TileStache/TileStache/__init__.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;stylish&nbsp;alternative&nbsp;for&nbsp;caching&nbsp;your&nbsp;map&nbsp;tiles.</tt></p>
+    <p><tt>A&nbsp;stylish&nbsp;alternative&nbsp;for&nbsp;caching&nbsp;your&nbsp;map&nbsp;tiles.<br>
+&nbsp;<br>
+TileStache&nbsp;is&nbsp;a&nbsp;Python-based&nbsp;server&nbsp;application&nbsp;that&nbsp;can&nbsp;serve&nbsp;up&nbsp;map&nbsp;tiles<br>
+based&nbsp;on&nbsp;rendered&nbsp;geographic&nbsp;data.&nbsp;You&nbsp;might&nbsp;be&nbsp;familiar&nbsp;with&nbsp;TileCache<br>
+(<a href="http://tilecache.org">http://tilecache.org</a>),&nbsp;the&nbsp;venerable&nbsp;open&nbsp;source&nbsp;WMS&nbsp;server&nbsp;from&nbsp;MetaCarta.<br>
+TileStache&nbsp;is&nbsp;similar,&nbsp;but&nbsp;we&nbsp;hope&nbsp;simpler&nbsp;and&nbsp;better-suited&nbsp;to&nbsp;the&nbsp;needs&nbsp;of<br>
+designers&nbsp;and&nbsp;cartographers.<br>
+&nbsp;<br>
+Documentation&nbsp;available&nbsp;at&nbsp;<a href="http://tilestache.org/doc/">http://tilestache.org/doc/</a></tt></p>
 <p>
 <table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
 <tr bgcolor="#aa55cc">
@@ -30,9 +38,12 @@
 <font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
     
 <tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-cgiHandler"><strong>cgiHandler</strong></a>(environ, config_path<font color="#909090">='./tilestache.cfg'</font>, debug<font color="#909090">=False</font>)</dt><dd><tt>Read&nbsp;environment&nbsp;PATH_INFO,&nbsp;load&nbsp;up&nbsp;configuration,&nbsp;talk&nbsp;to&nbsp;stdout&nbsp;by&nbsp;CGI.<br>
+<td width="100%"><dl><dt><a name="-cgiHandler"><strong>cgiHandler</strong></a>(environ, config<font color="#909090">='./tilestache.cfg'</font>, debug<font color="#909090">=False</font>)</dt><dd><tt>Read&nbsp;environment&nbsp;PATH_INFO,&nbsp;load&nbsp;up&nbsp;configuration,&nbsp;talk&nbsp;to&nbsp;stdout&nbsp;by&nbsp;CGI.<br>
+&nbsp;<br>
+Calls&nbsp;<a href="#-requestHandler">requestHandler</a>().<br>
 &nbsp;<br>
-Calls&nbsp;<a href="#-requestHandler">requestHandler</a>().</tt></dd></dl>
+Config&nbsp;parameter&nbsp;can&nbsp;be&nbsp;a&nbsp;file&nbsp;path&nbsp;string&nbsp;for&nbsp;a&nbsp;JSON&nbsp;configuration&nbsp;file<br>
+or&nbsp;a&nbsp;configuration&nbsp;object&nbsp;with&nbsp;'cache',&nbsp;'layers',&nbsp;and&nbsp;'dirpath'&nbsp;properties.</tt></dd></dl>
  <dl><dt><a name="-getPreview"><strong>getPreview</strong></a>(layer)</dt><dd><tt>Get&nbsp;a&nbsp;type&nbsp;string&nbsp;and&nbsp;dynamic&nbsp;map&nbsp;viewer&nbsp;HTML&nbsp;for&nbsp;a&nbsp;given&nbsp;layer.</tt></dd></dl>
  <dl><dt><a name="-getTile"><strong>getTile</strong></a>(layer, coord, extension)</dt><dd><tt>Get&nbsp;a&nbsp;type&nbsp;string&nbsp;and&nbsp;tile&nbsp;binary&nbsp;for&nbsp;a&nbsp;given&nbsp;request&nbsp;layer&nbsp;tile.<br>
 &nbsp;<br>
@@ -77,9 +88,13 @@ resolve&nbsp;any&nbsp;relative&nbsp;paths&nbsp;found&nbsp;in&nbsp;the&nbsp;confi
 See&nbsp;the&nbsp;Caches&nbsp;module&nbsp;for&nbsp;more&nbsp;information&nbsp;on&nbsp;the&nbsp;"caches"&nbsp;section,<br>
 and&nbsp;the&nbsp;Core&nbsp;and&nbsp;Providers&nbsp;modules&nbsp;for&nbsp;more&nbsp;information&nbsp;on&nbsp;the<br>
 "layers"&nbsp;section.</tt></dd></dl>
- <dl><dt><a name="-requestHandler"><strong>requestHandler</strong></a>(config_path, path_info, query_string)</dt><dd><tt>Generate&nbsp;a&nbsp;mime-type&nbsp;and&nbsp;response&nbsp;body&nbsp;for&nbsp;a&nbsp;given&nbsp;request.<br>
+ <dl><dt><a name="-requestHandler"><strong>requestHandler</strong></a>(config, path_info, query_string)</dt><dd><tt>Generate&nbsp;a&nbsp;mime-type&nbsp;and&nbsp;response&nbsp;body&nbsp;for&nbsp;a&nbsp;given&nbsp;request.<br>
+&nbsp;<br>
+Requires&nbsp;a&nbsp;configuration&nbsp;and&nbsp;PATH_INFO&nbsp;(e.g.&nbsp;"/example/0/0/0.png").<br>
+&nbsp;<br>
+Config&nbsp;parameter&nbsp;can&nbsp;be&nbsp;a&nbsp;file&nbsp;path&nbsp;string&nbsp;for&nbsp;a&nbsp;JSON&nbsp;configuration&nbsp;file<br>
+or&nbsp;a&nbsp;configuration&nbsp;object&nbsp;with&nbsp;'cache',&nbsp;'layers',&nbsp;and&nbsp;'dirpath'&nbsp;properties.<br>
 &nbsp;<br>
-Requires&nbsp;a&nbsp;path&nbsp;to&nbsp;a&nbsp;config&nbsp;file&nbsp;and&nbsp;PATH_INFO&nbsp;(e.g.&nbsp;"/example/0/0/0.png").<br>
 Query&nbsp;string&nbsp;is&nbsp;optional&nbsp;and&nbsp;not&nbsp;currently&nbsp;used.&nbsp;Calls&nbsp;<a href="#-getTile">getTile</a>()<br>
 to&nbsp;render&nbsp;actual&nbsp;tiles,&nbsp;and&nbsp;<a href="#-getPreview">getPreview</a>()&nbsp;to&nbsp;render&nbsp;preview.html.</tt></dd></dl>
  <dl><dt><a name="-splitPathInfo"><strong>splitPathInfo</strong></a>(pathinfo)</dt><dd><tt>Converts&nbsp;a&nbsp;PATH_INFO&nbsp;string&nbsp;to&nbsp;layer&nbsp;name,&nbsp;coordinate,&nbsp;and&nbsp;extension&nbsp;parts.<br>
diff --git a/doc/index.html b/doc/index.html
new file mode 100644
index 0000000..ba80489
--- /dev/null
+++ b/doc/index.html
@@ -0,0 +1,1106 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <title>TileStache API</title>
+    <meta http-equiv="content-type" content="text/html; charset=utf-8">
+    <style type="text/css" title="text/css">
+    <!--
+
+    body
+    {
+        font-family: Arial, Helvetica, sans-serif;
+        font-size: 14px;
+        line-height: 18px;
+        color: black;
+    }
+    
+    h2 { font-size: 1.5em; }
+    h3 { font-size: 1.2em; }
+    h4 { font-size: 1em; }
+    
+    pre, p samp, dl samp, p code, dl code
+    {
+        font-family: Monaco, monospace;
+        font-size: 0.9em;
+    }
+
+    pre { font-size: 0.8em; }
+    
+    body { margin-left: 56px; margin-bottom: 4em; }
+    #intro { margin-left: -28px; }
+    h1, h2, h3, h4 { margin: 1em 56px 1em -28px; }
+    dd, li { margin-left: 14px; }
+    ul { padding-left: 0; list-style-type: none; }
+    #index { float: right; width: 20em; padding-bottom: 2em; }
+    
+    h2 { margin-top: 2em; border-top: 1px solid #ccc; padding-top: 1em;}
+
+    body, #index { background-color: white; }
+    pre .bg { color: #aaa; }
+
+    p, dd, pre { width: 50em; }
+
+    var, samp, code { white-space: nowrap; }
+    samp, pre { background-color: #eee; }
+    dt { display: inline; font-weight: bold; }
+    var { background-color: #fe7; }
+
+    samp, pre, var { padding: 0 2px; margin: 0 -2px; border-radius: 2px; }
+    pre { margin: -4px 10px; padding: 4px; border: 1px solid #ddd; border-radius: 3px; }
+
+    -->
+    </style>
+</head>
+<body>
+
+<h1>TileStache API</h1>
+
+<div id="intro">
+
+    <p>
+    TileStache is a Python-based server application that can serve up map tiles
+    based on rendered geographic data. You might be familiar with
+    <a href="http://tilecache.org">TileCache</a> the venerable open source WMS
+    server from MetaCarta. TileStache is similar, but we hope simpler and
+    better-suited to the needs of designers and cartographers.
+    </p>
+
+    <p>
+    <strong>This document covers TileStache version 1.1.3</strong>.
+    </p>
+
+    <p>
+    See also <a href="TileStache.html">detailed module and class reference</a>.
+    </p>
+
+</div>
+
+<ul id="index">
+  <li>
+    <a href="#requesting-tiles">Requesting Tiles</a>
+    <ul>
+      <li><a href="#over-http">Over HTTP</a></li>
+      <li>
+        <a href="#in-code">In Code</a>
+<!-- 
+        <ul>
+          <li><a href="#tilestache-gettile"><code>TileStache.getTile</code></a></li>
+          <li><a href="#tilestache-requesthandler"><code>TileStache.requestHandler</code></a></li>
+        </ul>
+ -->
+      </li>
+    </ul>
+  </li>
+  <li>
+    <a href="#serving-tiles">Serving Tiles</a>
+    <ul>
+      <li><a href="#cgi">CGI</a></li>
+      <li><a href="#mod-python">mod_python</a></li>
+    </ul>
+  </li>
+  <li>
+    <a href="#configuring-tilestache">Configuring TileStache</a>
+    <ul>
+      <li>
+        <a href="#caches">Caches</a>
+<!-- 
+        <ul>
+          <li><a href="#test-cache">Test</a></li>
+          <li><a href="#disk-cache">Disk</a></li>
+        </ul>
+ -->
+      </li>
+      <li><a href="#layers">Layers</a></li>
+      <li>
+        <a href="#providers">Providers</a>
+<!-- 
+        <ul>
+          <li><a href="#mapnik-provider">Mapnik</a></li>
+          <li><a href="#proxy-provider">Proxy</a></li>
+        </ul>
+ -->
+      </li>
+      <li><a href="#projections">Projections</a></li>
+      <li><a href="#metatiles">Metatiles</a></li>
+    </ul>
+  </li>
+  <li>
+    <a href="#extending-tilestache">Extending TileStache</a>
+    <ul>
+      <li>
+        <a href="#custom-providers">Providers</a>
+<!-- 
+        <ul>
+          <li><a href="#provider-rendertile"><code>provider.renderTile</code></a></li>
+          <li><a href="#provider-renderarea"><code>provider.renderArea</code></a></li>
+          <li><a href="#provider-gettypebyextension"><code>provider.getTypeByExtension</code></a></li>
+        </ul>
+ -->
+      </li>
+      <li><a href="#custom-caches">Caches</a></li>
+      <li><a href="#custom-configuration">Configuration</a></li>
+    </ul>
+  </li>
+</ul>
+
+<h2><a id="requesting-tiles" name="requesting-tiles">Requesting Tiles</a></h2>
+
+<h3><a id="over-http" name="over-http">Over HTTP</a></h3>
+
+<p>
+TileStache URLs are based on a simplified TMS scheme:
+</p>
+
+<pre>
+/{layer name}/{zoom}/{column}/{row}.{extension}
+</pre>
+
+<p>
+An example tile URL might look like this:
+</p>
+
+<pre>
+http://example.org/path/tile.cgi/streets/12/656/1582.png
+</pre>
+
+<p>
+Interactive, slippy-map previews of tiles are also available:
+</p>
+
+<pre>
+/{layer name}/preview.html
+</pre>
+
+<h3><a id="in-code" name="in-code">In Code</a></h3>
+
+<h4><a id="tilestache-gettile" name="tilestache-gettile"><code>TileStache.getTile</code></a></h4>
+
+<p>
+Get a type string and tile binary for a given request layer tile.
+</p>
+ 
+<p>
+Arguments to <code>getTile</code>:
+</p>
+
+<dl>
+    <dt>layer</dt>
+    <dd>
+    Instance of <code>Core.Layer</code> to render.
+    </dd>
+
+    <dt>coord</dt>
+    <dd>
+    One <code>ModestMaps.Core.Coordinate</code> corresponding to a single tile.
+    </dd>
+
+    <dt>extension</dt>
+    <dd>
+    Filename extension to choose response type, e.g. <samp>"png"</samp> or
+    <samp>"jpg"</samp>.
+    </dd>
+</dl>
+ 
+<p>
+Return value of <code>getTile</code> is a tuple containing a mime-type string
+such as <samp>"image/png"</samp> and a complete byte string representing the
+rendered tile.
+</p>
+
+<p>
+See
+<a href="TileStache.html#-getTile">TileStache.getTile</a>
+documentation for more information.
+</p>
+
+<h4><a id="tilestache-requesthandler" name="tilestache-requesthandler"><code>TileStache.requestHandler</code></a></h4>
+
+<p>
+Generate a mime-type and response body for a given request. This is the function
+to use when creating new HTTP interfaces to TileStache.
+</p>
+ 
+<p>
+Arguments to <code>requestHandler</code>:
+</p>
+
+<dl>
+    <dt>config</dt>
+    <dd>
+    Required file path string for a JSON configuration file or a configuration
+    object with <var>cache</var>, <var>layers</var>, and <var>dirpath</var>
+    properties, such as
+    <a href="TileStache.Config.html#Configuration"><code>TileStache.Config.Configuration</code></a>.
+    </dd>
+
+    <dt>path_info</dt>
+    <dd>
+    Required end portion of a request URL including the layer name and tile
+    coordinate, e.g. <samp>"/roads/12/656/1582.png"</samp>.
+    </dd>
+
+    <dt>query_string</dt>
+    <dd>
+    Optional, currently-unused placeholder for possible future query string
+    use. Or maybe an explicit deterrent from ever building such a thing.
+    <small>Hard to say.</small>
+    </dd>
+</dl>
+ 
+<p>
+Return value of <code>requestHandler</code> is a tuple containing a mime-type string
+such as <samp>"image/png"</samp> and a complete byte string representing the
+rendered tile.
+</p>
+
+<p>
+See
+<a href="TileStache.html#-requestHandler">TileStache.requestHandler</a>
+documentation for more information.
+</p>
+
+<h2><a id="serving-tiles" name="serving-tiles">Serving Tiles</a></h2>
+
+<p>
+We currently provide two scripts for serving tiles, one for a CGI-based
+webserver and another for Apache <code>mod_python</code>.
+</p>
+
+<h4><a id="cgi" name="cgi">CGI</a></h4>
+
+<p>
+Using TileStache through CGI supports basic tile serving, and is useful for
+simple testing and low-to-medium traffic websites. This is a complete, working
+CGI script that looks for configuration in a local file called
+<tt>tilestache.cfg</tt>:
+</p>
+
+<pre>
+#!/usr/bin/python
+import os, TileStache
+TileStache.cgiHandler(os.environ, 'tilestache.cfg', debug=True)
+</pre>
+
+<p>
+See
+<a href="TileStache.html#-cgiHandler"><code>TileStache.cgiHandler</code></a>
+documentation for more information.
+</p>
+
+<h4><a id="mod-python" name="mod-python">mod_python</a></h4>
+
+<p>
+Using TileStache through <code>mod_python</code> improves performance by
+caching imported modules, but must be configured via the Apache webserver
+config. This is a complete example configuration for a webserver publishing
+tiles configured by a file in <code>/etc</code>:
+</p>
+
+<pre>
+&lt;Directory /var/www/tiles&gt;
+  AddHandler mod_python .py
+  PythonHandler TileStache::modpythonHandler
+  PythonOption config /etc/tilestache.cfg
+&lt;/Directory&gt;
+</pre>
+
+<p>
+See
+<a href="TileStache.html#-modPythonHandler"><code>TileStache.modPythonHandler</code></a>
+documentation for more information.
+</p>
+
+<h2><a id="configuring-tilestache" name="configuring-tilestache">Configuring TileStache</a></h2>
+
+<p>
+TileStache configuration is stored in JSON files, and is composed of two main
+top-level sections: <samp>"cache"</samp> and <samp>"layers"</samp>. There are
+examples of both in this minimal sample configuration:
+</p>
+ 
+<pre>
+{
+  "cache": {"name": "Test"},
+  "layers": {
+    "ex": {
+        "provider": {"name": "mapnik", "mapfile": "style.xml"},
+        "projection": "spherical mercator"
+    } 
+  }
+}
+</pre>
+
+<h3><a id="caches" name="caches">Caches</a></h3>
+
+<p>
+A Cache is the part of TileStache that stores static files to speed up future
+requests. A few default caches are shown here, with additional cache classes
+defined in
+<a href="TileStache.Goodies.Caches.html"><code>TileStache.Goodies.Caches</code></a>
+</p>
+
+<h4><a id="test-cache" name="test-cache">Test</a></h4>
+
+<p>
+Simple cache that doesn’t actually cache anything.
+</p>
+ 
+<p>
+Activity is optionally logged, though.
+</p>
+ 
+<p>
+Example configuration:
+</p>
+
+<pre>
+<span class="bg">{</span>
+  "cache": {
+    "name": "Test",
+    "verbose": True
+  }<span class="bg">,
+  "layers": { … }
+}</span>
+</pre>
+ 
+<p>
+Test cache parameters:
+</p>
+
+<dl>
+    <dt>verbose</dt>
+    <dd>
+    Optional boolean flag to write cache activities to a logging function,
+    defaults to <samp>False</samp> if omitted.
+    </dd>
+</dl>
+
+<p>
+See
+<a href="TileStache.Caches.html#Test">TileStache.Caches.Test</a>
+documentation for more information.
+</p>
+
+<h4><a id="disk-cache" name="disk-cache">Disk</a></h4>
+
+<p>
+Caches files to disk.
+</p>
+ 
+<p>
+Example configuration:
+</p>
+ 
+<pre>
+<span class="bg">{</span>
+  "cache": {
+    "name": "Disk",
+    "path": "/tmp/stache",
+    "umask": "0000",
+    "dirs": "portable"
+  }<span class="bg">,
+  "layers": { … }
+}</span>
+</pre>
+ 
+<p>
+Disk cache parameters:
+</p>
+
+<dl>
+    <dt>path</dt>
+    <dd>
+    Required local directory path where files should be stored.
+    </dd>
+
+    <dt>umask</dt>
+    <dd>
+    Optional string representation of octal permission mask for stored files.
+    Defaults to <samp>"0022"</samp>.
+    </dd>
+
+    <dt>dirs</dt>
+    <dd>
+    Optional string saying whether to create cache directories that are safe or
+    portable. For an example tile <samp>12/656/1582.png</samp>,
+    <samp>"portable"</samp> creates matching directory trees while
+    <samp>"safe"</samp> guarantees directories with fewer files, e.g.
+    <samp>12/000/656/001/582.png</samp>. Defaults to <samp>"safe"</samp>.
+    </dd>
+</dl>
+
+<p>
+If your configuration file is loaded from a remote location, e.g.
+<samp>http://example.com/tilestache.cfg</samp>, the path <strong>must</strong>
+be an unambiguous filesystem path, e.g. <samp>"file:///tmp/cache"</samp>.
+</p>
+
+<p>
+See
+<a href="TileStache.Caches.html#Disk">TileStache.Caches.Disk</a>
+documentation for more information.
+</p>
+
+<h3><a id="layers" name="layers">Layers</a></h3>
+
+<p>
+A Layer represents a set of tiles in TileStache. It keeps references to
+providers, projections, a Configuration instance, and other details required
+for to the storage and rendering of a tile set.
+</p>
+
+<p>
+Example layer configuration:
+</p>
+ 
+<pre>
+<span class="bg">{
+  "cache": …,
+  "layers": 
+  {</span>
+    "example-name":
+    {
+      "provider": { … },
+      "metatile": { … },
+      "stale lock timeout": …,
+      "projection": …
+    }
+  <span class="bg">}
+}</span>
+</pre>
+ 
+<p>
+The public-facing URL of a single tile for this layer might look like this:
+</p>
+ 
+<pre>
+http://example.com/tilestache.cgi/example-name/0/0/0.png
+</pre>
+
+<p>
+Shared layer parameters:
+</p>
+
+<dl>
+    <dt>provider</dt>
+    <dd>
+    Refers to a Provider, explained in detail under Providers.
+    </dd>
+
+    <dt>metatile</dt>
+    <dd>
+    Optionally makes it possible for multiple individual tiles to be rendered
+    at one time, for greater speed and efficiency. This is commonly used for
+    bitmap providers such as Mapnik. See Metatiles for more information.
+    </dd>
+
+    <dt>projection</dt>
+    <dd>
+    Names a geographic projection, explained in Projections. If omitted,
+    defaults to <samp>"spherical mercator"</samp>.
+    </dd>
+
+    <dt>stale lock timeout</dt>
+    <dd>
+    An optional number of seconds to wait before forcing a lock that might be
+    stuck. This is defined on a per-layer basis, rather than for an entire
+    cache at one time, because you may have different expectations for the
+    rendering speeds of different layer configurations. Defaults to
+    <samp>15</samp>.
+    </dd>
+</dl>
+
+<h3><a id="providers" name="providers">Providers</a></h3>
+
+<p>
+A Provider is the part of TileStache that stores static files to speed up
+future requests. A few default providers are shown here, with additional
+provider classes defined in
+<a href="TileStache.Goodies.Providers.html"><code>TileStache.Goodies.Providers</code></a>
+</p>
+
+<h4><a id="mapnik-provider" name="mapnik-provider">Mapnik</a></h4>
+
+<p>
+Built-in Mapnik provider, renders map images from Mapnik XML files.
+</p>
+ 
+<p>
+Example Mapnik provider configuration:
+</p>
+
+<pre>
+<span class="bg">{
+  "cache": { … }.
+  "layers":
+  {
+    "roads":
+    {</span>
+      "provider":
+      {
+        "name": "mapnik", 
+        "mapfile": "style.xml"
+      }
+    <span class="bg">}
+  }
+}</span>
+</pre>
+ 
+<p>
+Mapnik provider parameters:
+</p>
+
+<dl>
+    <dt>mapfile</dt>
+    <dd>
+    Required local file path to Mapnik XML file.
+    </dd>
+</dl>
+
+<p>
+See
+<a href="TileStache.Providers.html#Mapnik">TileStache.Providers.Mapnik</a>
+for more information.
+</p>
+
+<h4><a id="proxy-provider" name="proxy-provider">Proxy</a></h4>
+
+<p>
+Proxy provider, to pass through and cache tiles from other places.
+</p>
+ 
+<p>
+Example Proxy provider configuration:
+</p>
+
+<pre>
+<span class="bg">{
+  "cache": { … }.
+  "layers":
+  {
+    "roads":
+    {</span>
+      "provider":
+      {
+        "name": "proxy", 
+        "url": "http://tile.openstreetmap.org/{Z}/{X}/{Y}.png"
+      }
+    <span class="bg">}
+  }
+}</span>
+</pre>
+ 
+<p>
+Proxy provider parameters:
+</p>
+
+<dl>
+    <dt>url</dt>
+    <dd>
+    Optional URL template for remote tiles, for example:
+    <samp>"http://tile.openstreetmap.org/{Z}/{X}/{Y}.png"</samp>
+    </dd>
+    <dt>provider</dt>
+    <dd>
+    Optional provider name string from Modest Maps built-ins. See
+    <code>ModestMaps.builtinProviders.keys()</code> for a list. Example:
+    <samp>"OPENSTREETMAP"</samp>.
+    </dd>
+</dl>
+
+<p>
+See
+<a href="TileStache.Providers.html#Proxy">TileStache.Providers.Proxy</a>
+for more information.
+</p>
+
+<h3><a id="projections" name="projections">Projections</a></h3>
+
+<p>
+A Projection defines the relationship between the rendered tiles and the
+underlying geographic data. Generally, just one popular projection is used for
+most web maps, <samp>"spherical mercator"</samp>.
+</p>
+
+<p>
+Provided projections:
+</p>
+
+<dl>
+    <dt>spherical mercator</dt>
+    <dd>
+    Projection for most commonly-used web map tile scheme, equivalent to
+    <code>EPSG:900913</code>. The simplified projection used here is described
+    in greater detail at
+    <a href="http://trac.openlayers.org/wiki/SphericalMercator">openlayers.org</a>.
+    </dd>
+    
+    <dt>WGS84</dt>
+    <dd>
+    Unprojected projection for the other commonly-used web map tile scheme,
+    equivalent to <code>EPSG:4326</code>.
+    </dd>
+</dl>
+
+<p>
+See
+<a href="TileStache.Geography.html">TileStache.Geography</a>
+for more information.
+</p>
+
+<h4><a id="metatiles" name="metatiles">Metatiles</a></h4>
+
+<p>
+Metatiles are larger areas to be rendered at one time, often used because it’s
+more efficient to render a large number of contiguous tiles at once than each
+one separately.
+</p>
+ 
+<p>
+Example metatile configuration:
+</p>
+
+<pre>
+<span class="bg">{
+  "cache": …,
+  "layers": 
+  {
+    "example-name":
+    {
+      "provider": { … },</span>
+      "metatile": 
+      {
+        "rows": 4,
+        "columns": 4,
+        "buffer": 64
+      }
+    <span class="bg">}
+  }
+}</span>
+</pre>
+
+<p>
+This example metatile is four rows tall and four columns wide with a buffer
+of 64 pixels, for a total bitmap size of 4 × 256 + 64 × 2 = <strong>1152</strong>.
+</p>
+
+<p>
+Metatile parameters:
+</p>
+
+<dl>
+    <dt>rows</dt>
+    <dd>
+    Height of the metatile measured in tiles.
+    </dd>
+
+    <dt>columns</dt>
+    <dd>
+    Width of the metatile measured in tiles.
+    </dd>
+
+    <dt>buffer</dt>
+    <dd>
+    Buffer area around the metatile, measured in pixels. This is useful for
+    providers with labels or icons, where it’s necessary to draw a bit extra
+    around the edges to ensure that text is not cut off.
+    </dd>
+</dl> 
+
+<h2><a id="extending-tilestache" name="extending-tilestache">Extending TileStache</a></h2>
+
+<p>
+TileStache relies on <a href="http://en.wikipedia.org/wiki/Duck_typing">duck typing</a>
+rather than inheritance for extensibility, so all guidelines for customization
+below explain what methods and properties must be defined on objects for them
+to be valid as providers, caches, and configurations.
+</p>
+
+<h3><a id="custom-providers" name="custom-providers">Providers</a></h3>
+
+<p>
+Example external provider configuration:
+</p>
+ 
+<pre>
+<span class="bg">{
+  "cache": …,
+  "layers": 
+  {
+    "example-name":
+    {</span>
+      "provider":
+      {
+        "class": "Module.Classname",
+        "kwargs": {"frob": "yes"}
+      }
+    <span class="bg">}
+  }
+}</span>
+</pre>
+
+<p>
+The <var>class</var> value is split up into module and classname, and
+dynamically included. If this doesn’t work for some reason, TileStache will
+fail loudly to let you know. The <var>kwargs</var> value is fed to the class
+constructor as a dictionary of keyword args. If your defined class doesn’t
+accept any of these keyword arguments, TileStache will throw an exception.
+</p>
+
+<p>
+A provider must offer at least one of two methods for rendering map areas:
+<code>renderTile</code> or <code>renderArea</code>. A provider must also accept
+an instance of <code>Layer</code> as the first argument to its constructor.
+</p>
+
+<p>
+Return value of both <code>renderTile</code> and <code>renderArea</code> is an
+object with a <code>save</code> method that can accept a file-like object and
+a format name, typically an instance of the <code>PIL.Image</code> object but
+allowing for creation of providers that save text, raw data or other non-image
+response.
+</p>
+
+<p>
+A minimal provider stub class:
+</p>
+
+<pre>
+class ProviderStub:
+
+  def __init__(self, layer):
+    # create a new provider for a layer
+    raise NotImplementedError
+    
+  def renderTile(self, width, height, srs, coord):
+    # return an object with a PIL-like save() method for a tile
+    raise NotImplementedError
+    
+  def renderArea(self, width, height, srs, xmin, ymin, xmax, ymax, zoom):
+    # return an object with a PIL-like save() method for an area
+    raise NotImplementedError
+</pre>
+
+<p>
+See
+<a href="TileStache.Providers.html">TileStache.Providers</a>
+for more information on custom providers and
+<a href="TileStache.Goodies.Providers.html">TileStache.Goodies.Providers</a>
+for examples of custom providers.
+</p>
+
+<h4><a id="provider-rendertile" name="provider-rendertile"><code>provider.renderTile</code></a></h4>
+
+<p>
+Draws a single tile at a time.
+</p>
+
+<p>
+Arguments to <code>renderTile</code>:
+</p>
+
+<dl>
+    <dt>width</dt>
+    <dd>
+    Pixel width of tile, typically <samp>256</samp>.
+    </dd>
+    
+    <dt>height</dt>
+    <dd>
+    Pixel height of tile, typically <samp>256</samp>.
+    </dd>
+    
+    <dt>srs</dt>
+    <dd>
+    Projection as Proj4 string.
+    <samp>"+proj=longlat +ellps=WGS84 +datum=WGS84"</samp> is an example, see
+    <a href="TileStache.Geography.html">TileStache.Geography</a>
+    for actual values.
+    </dd>
+    
+    <dt>coord</dt>
+    <dd>
+    Coordinate object representing a single tile.
+    </dd>
+</dl>
+
+<p>
+Return value of <code>renderTile</code> is a
+<a href="http://www.pythonware.com/library/pil/handbook/image.htm#Image.save"><code>PIL.Image</code></a>
+or other saveable object, used like this:
+</p>
+
+<pre>
+provider.renderTile(…).save(file, "XML")
+</pre>
+ 
+<h4><a id="provider-renderarea" name="provider-renderarea"><code>provider.renderArea</code></a></h4>
+
+<p>
+Draws a variably-sized area, and is used when drawing metatiles.
+</p>
+
+<p>
+Non-image providers and metatiles do not mix. If your provider returns JSON,
+plaintext, XML, or some other non-PIL format, implement only the
+<code>renderTile</code> method.
+</p>
+
+<p>
+Arguments to <code>renderArea</code>:
+</p>
+
+<dl>
+    <dt>width</dt>
+    <dd>
+    Pixel width of tile, typically <samp>256</samp>.
+    </dd>
+    
+    <dt>height</dt>
+    <dd>
+    Pixel height of tile, typically <samp>256</samp>.
+    </dd>
+    
+    <dt>srs</dt>
+    <dd>
+    Projection as Proj4 string.
+    <samp>"+proj=longlat +ellps=WGS84 +datum=WGS84"</samp> is an example, see
+    <a href="TileStache.Geography.html">TileStache.Geography</a>
+    for actual values.
+    </dd>
+    
+    <dt>xmin</dt>
+    <dd>
+    Minimum <var>x</var> boundary of rendered area in projected coordinates.
+    </dd>
+    
+    <dt>ymin</dt>
+    <dd>
+    Minimum <var>y</var> boundary of rendered area in projected coordinates.
+    </dd>
+    
+    <dt>xmax</dt>
+    <dd>
+    Maximum <var>x</var> boundary of rendered area in projected coordinates.
+    </dd>
+    
+    <dt>ymax</dt>
+    <dd>
+    Maximum <var>y</var> boundary of rendered area in projected coordinates.
+    </dd>
+    
+    <dt>zoom</dt>
+    <dd>
+    Zoom level of final map. Technically this can be derived from the other
+    arguments, but that’s a hassle so we’ll pass it in explicitly.
+    </dd>
+</dl>
+
+<p>
+Return value of <code>renderArea</code> is a
+<a href="http://www.pythonware.com/library/pil/handbook/image.htm#Image.save"><code>PIL.Image</code></a>
+or other saveable object, used like this:
+</p>
+
+<pre>
+provider.renderArea(…).save(file, "PNG")
+</pre>
+
+<h4><a id="provider-gettypebyextension" name="provider-gettypebyextension"><code>provider.getTypeByExtension</code></a></h4>
+
+<p>
+A provider may offer a method for custom response types,
+<code>getTypeByExtension</code>. This method returns a tuple with two strings:
+a mime-type and a format.
+</p>
+
+<p>
+Arguments to <code>getTypeByExtension</code>:
+</p>
+
+<dl>
+    <dt>extension</dt>
+    <dd>
+    Filename extension string, e.g. <samp>"png"</samp>, <samp>"json"</samp>, etc.
+    </dd>
+</dl>
+
+<h3><a id="custom-caches" name="custom-caches">Caches</a></h3>
+
+<p>
+Example external provider configuration:
+</p>
+ 
+<pre>
+<span class="bg">{</span>
+  "cache":
+  {
+    "class": "Module.Classname",
+    "kwargs": {"frob": "yes"}
+  },
+  <span class="bg">"layers": { … }
+}</span>
+</pre>
+
+<p>
+The <var>class</var> value is split up into module and classname, and
+dynamically included. If this doesn’t work for some reason, TileStache will
+fail loudly to let you know. The <var>kwargs</var> value is fed to the class
+constructor as a dictionary of keyword args. If your defined class doesn’t
+accept any of these keyword arguments, TileStache will throw an exception.
+</p>
+
+<p>
+A cache must provide all of these four methods: <code>lock</code>,
+<code>unlock</code>, <code>read</code>, and <code>save</code>.
+</p>
+
+<p>
+Each method requires three arguments:
+</p>
+
+<dl>
+    <dt>layer</dt>
+    <dd>
+    Instance of a layer.
+    </dd>
+
+    <dt>coord</dt>
+    <dd>
+    Single Coordinate that represents a tile.
+    </dd>
+
+    <dt>format</dt>
+    <dd>
+    String like <samp>"png"</samp> or <samp>"jpg"</samp> that is used as a
+    filename extension.
+    </dd>
+</dl>
+ 
+<p>
+The <code>save</code> method accepts an additional argument <i>before the others</i>:
+</p>
+ 
+<dl>
+    <dt>body</dt>
+    <dd>
+    Raw content to save to the cache.
+    </dd>
+</dl>
+
+<p>
+A minimal cache stub class:
+</p>
+
+<pre>
+class CacheStub:
+
+  def lock(self, layer, coord, format):
+    # lock a tile
+    raise NotImplementedError
+
+  def unlock(self, layer, coord, format):
+    # unlock a tile
+    raise NotImplementedError
+
+  def read(self, layer, coord, format):
+    # return raw tile content from cache
+    raise NotImplementedError
+  
+  def save(self, body, layer, coord, format):
+    # save raw tile content to cache
+    raise NotImplementedError
+</pre>
+
+<p>
+See
+<a href="TileStache.Caches.html">TileStache.Caches</a>
+for more information on custom caches and
+<a href="TileStache.Goodies.Caches.html">TileStache.Goodies.Caches</a>
+for examples of custom caches.
+</p>
+
+<h3><a id="custom-configuration" name="custom-configuration">Configuration</a></h3>
+
+<p>
+A complete configuration object includes <var>cache</var>,
+<var>layers</var>, and <var>dirpath</var> properties:
+</p>
+ 
+<dl>
+    <dt>cache</dt>
+    <dd>
+    Cache instance, e.g.
+    <code><a href="TileStache.Caches.html#Disk">TileStache.Caches.Disk</a></code>
+    etc. See
+    <a href="TileStache.Caches.html">TileStache.Caches</a>
+    for details on what makes a usable cache.
+    </dd>
+
+    <dt>layers</dt>
+    <dd>
+    Dictionary of layers keyed by name. 
+    </dd>
+
+    <dt>dirpath</dt>
+    <dd>
+    Local filesystem path for this configuration, useful for expanding relative
+    paths.
+    </dd>
+</dl>
+
+<p>
+When creating a custom <var>layers</var> dictionary, e.g. for dynamic layer
+collections backed by some external configuration, these
+<a href="http://docs.python.org/library/stdtypes.html#mapping-types-dict">dictionary methods</a>
+must be provided for a complete collection of layers:
+</p>
+ 
+<dl>
+    <dt>keys</dt>
+    <dd>
+    Return list of layer name strings.
+    </dd>
+
+    <dt>items</dt>
+    <dd>
+    Return list of (name, layer) pairs.
+    </dd>
+
+    <dt>__contains__</dt>
+    <dd>
+    Return boolean true if given key is an existing layer.
+    </dd>
+
+    <dt>__getitem__</dt>
+    <dd>
+    Return existing layer object for given key or raise <code>KeyError</code>.
+    </dd>
+</dl>
+
+<p>
+A minimal layers dictionary stub class:
+</p>
+
+<pre>
+class LayersStub:
+
+  def keys(self):
+    # return a list of key strings
+    raise NotImplementedError
+
+  def items(self):
+    # return a list of (key, layer) tuples
+    raise NotImplementedError
+
+  def __contains__(self, key):
+    # return True if the key is here
+    raise NotImplementedError
+  
+  def __getitem__(self, key):
+    # return the layer named by the key
+    raise NotImplementedError
+</pre>
+
+</body>
+</html>
diff --git a/setup.py b/setup.py
index 6b8f971..105e129 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@
 
 from distutils.core import setup
 
-version = '1.0.1'
+version = '1.1.3'
 
 setup(name='TileStache',
       version=version,
diff --git a/tilestache.cfg b/tilestache.cfg
index 8306714..60a5a6f 100644
--- a/tilestache.cfg
+++ b/tilestache.cfg
@@ -2,7 +2,7 @@
   "cache":
   {
     "name": "Test",
-    "path": "cache",
+    "path": "/tmp/stache",
     "umask": "0000"
   },
   "layers": 
@@ -26,17 +26,6 @@
     {
         "provider": {"class": "TileStache.Goodies.Providers.Grid.UTM",
                      "kwargs": {"display": "UTM", "spacing": 200, "tick": 10}}
-    },
-    "poi":
-    {
-        "stale lock timeout": 2,
-        "projection": "WGS84",
-        "provider": {"class": "TileStache.Goodies.Providers.PostGeoJSON.Provider",
-                     "kwargs": {
-                        "dsn": "dbname=geodata user=postgres",
-                        "query": "SELECT osm_id, name, way FROM bayarea_osm_point WHERE way && !bbox! AND name IS NOT NULL",
-                        "id_column": "osm_id", "geometry_column": "way"
-                     }}
     }
   }
 }

-- 
map tiles caching system



More information about the Pkg-grass-devel mailing list