kopia lustrzana https://github.com/hholzgra/ocitysmap
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
rodzic
f612534ec6
commit
230e2ccda2
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue