Updated doc and simpler object for StreetIndex objects

This patch makes the ctor args minimal for the StreetIndex indexer
objects, and also drops the ref to the DB after the object has been
created. Also cleans up the rendering process a bit (WIP, still).
stable
David Decotigny 2010-09-02 21:20:39 +02:00
rodzic f612534ec6
commit 230e2ccda2
4 zmienionych plików z 97 dodań i 50 usunięć

Wyświetl plik

@ -111,6 +111,9 @@ class RenderingConfiguration:
self.paper_width_mm = None
self.paper_height_mm = None
# Setup by Rendering routines from osmid and bounding_box fields:
self.polygon_wkt = None # str (WKT of interest)
class Stylesheet:
"""
A Stylesheet object defines how the map features will be rendered. It
@ -267,8 +270,9 @@ class OCitySMap:
os.rmdir(tmpdir)
def get_geographic_info(self, osmids):
"""Returns the envelope and area, in 4002 projection, of all the
provided OSM IDs."""
"""Return a list of tuples (one tuple for each specified ID in
osmids) where each tuple contains (osmid, WKT_envelope,
WKT_buildarea)"""
# Ensure all OSM IDs are integers, bust cast them back to strings
# afterwards.
@ -348,40 +352,52 @@ class OCitySMap:
l.info('Rendering with renderer %s in language: %s (rtl: %s).' %
(renderer_name, self._i18n.language_code(), config.rtl))
try:
osmid_geo_info = self.get_geographic_info([config.osmid])[0]
except IndexError:
raise AssertionError, 'OSM ID not found in the database!'
# Determine bounding box and WKT of interest
if config.osmid:
try:
osmid_geo_info = self.get_geographic_info([config.osmid])[0]
except IndexError:
raise AssertionError, 'OSM ID not found in the database!'
# Define the bbox if not already defined
if not config.bounding_box:
config.bounding_box \
= coords.BoundingBox.parse_wkt(osmid_geo_info[1])
# Update the polygon WKT of interest
config.polygon_wkt = osmid_geo_info[2]
else:
# No OSM ID provided => use specified bbox
config.polygon_wkt = config.bounding_box.as_wkt()
# Make sure we have a bounding box
config.bounding_box = (config.bounding_box or
coords.BoundingBox.parse_wkt(osmid_geo_info[1]))
assert config.bounding_box is not None
assert config.polygon_wkt is not None
# Prepare the index
street_index = index.indexer.StreetIndex(self._db,
config.polygon_wkt,
self._i18n)
# Create a temporary directory for all our shape files
tmpdir = tempfile.mkdtemp(prefix='ocitysmap')
l.debug('Rendering in temporary directory %s' % tmpdir)
# Prepare the main renderer
renderer_cls = renderers.get_renderer_class_by_name(renderer_name)
renderer = renderer_cls(config, tmpdir)
renderer.create_map_canvas()
if config.osmid:
polygon = osmid_geo_info[2]
if polygon:
shade_wkt = self._get_shade_wkt(
renderer.canvas.get_actual_bounding_box(),
polygon)
renderer.render_shade(shade_wkt)
else:
polygon = None
shade_wkt = self._get_shade_wkt(
renderer.canvas.get_actual_bounding_box(),
config.polygon_wkt)
renderer.add_shade(shade_wkt)
renderer.canvas.render()
street_index = index.indexer.StreetIndex(self._db, config.osmid,
renderer.canvas.get_actual_bounding_box(),
self._i18n, renderer.grid, polygon)
street_index_renderer = index.StreetIndexRenderer(self._i18n,
street_index.categories)
street_index_renderer = index.StreetIndexRenderer(
self._i18n,
street_index.categories)
try:
for output_format in output_formats:

Wyświetl plik

@ -58,7 +58,7 @@ if __name__ == '__main__':
host='localhost',
database='maposmatic')
street_index = StreetIndex(db, None, None, i18n, None, bbox.as_wkt())
street_index = StreetIndex(db, bbox.as_wkt(), i18n)
print street_index.categories
# Render the items

Wyświetl plik

@ -44,18 +44,24 @@ l = logging.getLogger('ocitysmap')
class StreetIndex:
def __init__(self, db, osmid, bounding_box, i18n, grid, polygon_wkt):
self._db = db
self._osmid = osmid
self._bounding_box = bounding_box
def __init__(self, db, polygon_wkt, i18n):
"""
Prepare the index of the streets inside the given WKT. This
constructor will perform all the SQL queries.
Args:
db (psycopg2 DB): The GIS database
polygon_wkt (str): The WKT of the surrounding polygon of interest
i18n (i18n.i18n): Internationalization configuration
Note: All the arguments have to be provided !
"""
self._i18n = i18n
self._grid = grid
self._polygon_wkt = polygon_wkt
# Build the contents of the index
self._categories = \
(self._build_street_index_nogrid()
+ self._build_amenities_index_nogrid())
(self._list_streets(db, polygon_wkt)
+ self._list_amenities(db, polygon_wkt))
if not self._categories:
raise IndexEmptyError("Nothing to index")
@ -66,8 +72,8 @@ class StreetIndex:
def apply_grid(self, grid):
"""
Fix the label location_str field by mapping the streets to the
given grid.
Update the location_str field of the streets and amenities by
mapping them onto the given grid.
Args:
grid (ocitysmap2.Grid): the Grid object from which we
@ -120,12 +126,21 @@ class StreetIndex:
fd.close()
def _get_selected_amenities(self):
# Amenities to retrieve from DB, a list of string tuples:
# 1. Category, displayed headers in the final index
# 2. db_amenity, description string stored in the DB
# 3. Label, text to display in the index for this amenity
"""
Return the kinds of amenities to retrieve from DB as a list of
string tuples:
1. Category, displayed headers in the final index
2. db_amenity, description string stored in the DB
3. Label, text to display in the index for this amenity
Note: This has to be a function because gettext() has to be
called, which takes i18n into account... It cannot be
statically defined as a class attribute for example.
"""
selected_amenities = [
(_(u"Places of worship"), "place_of_worship", _(u"Place of worship")),
(_(u"Places of worship"), "place_of_worship",
_(u"Place of worship")),
(_(u"Education"), "kindergarten", _(u"Kindergarten")),
(_(u"Education"), "school", _(u"School")),
(_(u"Education"), "college", _(u"College")),
@ -194,16 +209,20 @@ class StreetIndex:
return result
def _build_street_index_nogrid(self):
"""Get the list of streets in the administrative area if city
is defined or in the bounding box otherwise. Don't try to map
these streets onto the grid of squares.
def _list_streets(self, db, polygon_wkt):
"""Get the list of streets inside the given polygon. Don't
try to map them onto the grid of squares (there location_str
field remains undefined).
Args:
db (psycopg2 DB): The GIS database
polygon_wkt (str): The WKT of the surrounding polygon of interest
Returns a list of commons.IndexCategory objects, with their IndexItems
having no specific grid square location
"""
cursor = self._db.cursor()
cursor = db.cursor()
l.info("Getting streets (no grid)...")
# POstGIS >= 1.5.0 for this to work:
@ -223,7 +242,7 @@ from
group by name ---, street_kind -- (optional)
order by name) as foo;
""" % dict(wkb_limits = ("st_transform(GeomFromText('%s', 4002), 900913)"
% (self._polygon_wkt or self._bounding_box.as_wkt())))
% (polygon_wkt,)))
l.debug("Street query (nogrid): %s" % query)
@ -234,8 +253,21 @@ from
return self._convert_street_index(sl)
def _build_amenities_index_nogrid(self):
cursor = self._db.cursor()
def _list_amenities(self, db, polygon_wkt):
"""Get the list of amenities inside the given polygon. Don't
try to map them onto the grid of squares (there location_str
field remains undefined).
Args:
db (psycopg2 DB): The GIS database
polygon_wkt (str): The WKT of the surrounding polygon of interest
Returns a list of commons.IndexCategory objects, with their IndexItems
having no specific grid square location
"""
cursor = db.cursor()
result = []
for catname, db_amenity, label in self._get_selected_amenities():
@ -269,7 +301,7 @@ from (
order by amenity_name""" \
% {'amenity': _sql_escape_unicode(db_amenity),
'wkb_limits': ("st_transform(GeomFromText('%s', 4002), 900913)"
% (self._polygon_wkt or self._bounding_box.as_wkt()))}
% (polygon_wkt,))}
l.debug("Amenity query for for %s/%s (nogrid): %s" \
@ -326,8 +358,7 @@ if __name__ == "__main__":
# Paris bbox
# limits_wkt = """POLYGON((2.22405964791711 48.8155243047565,2.22405964791711 48.9021584078545,2.46979772401737 48.9021584078545,2.46979772401737 48.8155243047565,2.22405964791711 48.8155243047565))"""
street_index = StreetIndex(db, None, None, i18n, None,
limits_wkt)
street_index = StreetIndex(db, limits_wkt, i18n)
print "=> Got %d categories, total %d items" \
% (len(street_index.categories),

Wyświetl plik

@ -211,7 +211,7 @@ class Renderer:
ctx.restore()
def render_shade(self, shade_wkt):
def add_shade(self, shade_wkt):
# Add the grey shade
shade_shape = shapes.PolyShapeFile(
self.canvas.get_actual_bounding_box(),