Can update the street index label according to the grid's location.

With this patch, the street index should now have its labels A1-B2
correct for the location of streets. The street indexer has a new
method apply_grid() that calls item.update_location_str(grid) so that
all the items have their location_str field correct. The items are
updated in-place: beware if multiple threads are manipulating a
StreetIndex object...
stable
David Decotigny 2010-08-31 22:39:46 +02:00
rodzic bdcc6b01f0
commit f612534ec6
5 zmienionych plików z 102 dodań i 17 usunięć

Wyświetl plik

@ -53,6 +53,7 @@ class Grid:
""" """
self._bbox = bounding_box self._bbox = bounding_box
self.rtl = rtl
self._height_m, self._width_m = bounding_box.spheric_sizes() self._height_m, self._width_m = bounding_box.spheric_sizes()
l.info('Laying out grid on %.1fx%.1fm area...' % l.info('Laying out grid on %.1fx%.1fm area...' %
@ -67,28 +68,27 @@ class Grid:
Grid.GRID_COUNT_TRESHOLD): Grid.GRID_COUNT_TRESHOLD):
break break
self._horiz_angle = (abs(self._bbox.get_top_left()[1] - self._horiz_angle_span = abs(self._bbox.get_top_left()[1] -
self._bbox.get_bottom_right()[1]) / self._bbox.get_bottom_right()[1])
self.horiz_count) self._vert_angle_span = abs(self._bbox.get_top_left()[0] -
self._vert_angle = (abs(self._bbox.get_top_left()[0] - self._bbox.get_bottom_right()[0])
self._bbox.get_bottom_right()[0]) /
self.vert_count)
self._horizontal_lines = [self._bbox.get_top_left()[0] - self._horiz_unit_angle = (self._horiz_angle_span / self.horiz_count)
(x+1) * self._vert_angle for x in xrange( self._vert_unit_angle = (self._vert_angle_span / self.vert_count)
int(math.floor(self.vert_count)))]
self._vertical_lines = [self._bbox.get_top_left()[1] + self._horizontal_lines = [ ( self._bbox.get_top_left()[0] -
(x+1) * self._horiz_angle for x in xrange( (x+1) * self._vert_unit_angle)
int(math.floor(self.horiz_count)))] for x in xrange(int(math.floor(self.vert_count)))]
self._vertical_lines = [ (self._bbox.get_top_left()[1] +
(x+1) * self._horiz_unit_angle)
for x in xrange(int(math.floor(self.horiz_count)))]
self.horizontal_labels = map(self._gen_horizontal_square_label, self.horizontal_labels = map(self._gen_horizontal_square_label,
xrange(int(math.ceil(self.horiz_count)))) xrange(int(math.ceil(self.horiz_count))))
if rtl:
self.horizontal_labels.reverse()
self.vertical_labels = map(self._gen_vertical_square_label, self.vertical_labels = map(self._gen_vertical_square_label,
xrange(int(math.ceil(self.vert_count)))) xrange(int(math.ceil(self.vert_count))))
l.info('Using %dx%dm grid (%dx%d squares).' % l.info('Using %sx%sm grid (%sx%s squares).' %
(self.grid_size_m, self.grid_size_m, (self.grid_size_m, self.grid_size_m,
self.horiz_count, self.vert_count)) self.horiz_count, self.vert_count))
@ -120,6 +120,9 @@ class Grid:
28 -> AB 28 -> AB
... ...
""" """
if self.rtl:
x = len(self._vertical_lines) - x
label = '' label = ''
while x != -1: while x != -1:
label = chr(ord('A') + x % 26) + label label = chr(ord('A') + x % 26) + label
@ -131,6 +134,22 @@ class Grid:
number. Since we put numbers verticaly, this is simply x+1.""" number. Since we put numbers verticaly, this is simply x+1."""
return str(x + 1) return str(x + 1)
def get_location_str(self, lattitude, longitude):
"""
Translate the given lattitude/longitude (EPSG:4326) into a
string of the form "CA42"
"""
hdelta = min(abs(longitude - self._bbox.get_top_left()[1]),
self._horiz_angle_span)
hlabel = self.horizontal_labels[int(hdelta / self._horiz_unit_angle)]
vdelta = min(abs(lattitude - self._bbox.get_top_left()[0]),
self._vert_angle_span)
vlabel = self.vertical_labels[int(vdelta / self._vert_unit_angle)]
return "%s%s" % (hlabel, vlabel)
if __name__ == "__main__": if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
grid = Grid(coords.BoundingBox(44.4883, -1.0901, 44.4778, -1.0637)) grid = Grid(coords.BoundingBox(44.4883, -1.0901, 44.4778, -1.0637))

Wyświetl plik

@ -35,6 +35,7 @@ if __name__ == '__main__':
from ocitysmap2 import i18n, coords from ocitysmap2 import i18n, coords
from ocitysmap2.index import commons from ocitysmap2.index import commons
from ocitysmap2.grid import Grid
import render import render
@ -72,6 +73,10 @@ if __name__ == '__main__':
surface = cairo.PDFSurface('/tmp/myindex.pdf', width, height) surface = cairo.PDFSurface('/tmp/myindex.pdf', width, height)
# Map index to grid
grid = Grid(bbox, rtl = False)
street_index.apply_grid(grid)
index = render.StreetIndexRenderer(i18nMock(False), index = render.StreetIndexRenderer(i18nMock(False),
street_index.categories) street_index.categories)
@ -107,6 +112,14 @@ if __name__ == '__main__':
_render('width', 'right') _render('width', 'right')
surface.show_page() surface.show_page()
##
## Now demo with RTL = True
##
# Map index to grid
grid = Grid(bbox, rtl = True)
street_index.apply_grid(grid)
index = render.StreetIndexRenderer(i18nMock(True), index = render.StreetIndexRenderer(i18nMock(True),
street_index.categories) street_index.categories)
_render('height', 'top') _render('height', 'top')

Wyświetl plik

@ -90,6 +90,7 @@ class IndexCategory:
def get_all_item_squares(self): def get_all_item_squares(self):
return [x.squares for x in self.items] return [x.squares for x in self.items]
class IndexItem: class IndexItem:
""" """
An IndexItem represents one item in the index (a street or a POI). It An IndexItem represents one item in the index (a street or a POI). It
@ -161,6 +162,41 @@ class IndexItem:
line_end - line_start - fheight/2) line_end - line_start - fheight/2)
ctx.restore() ctx.restore()
def update_location_str(self, grid):
"""
Update the location_str field from the given Grid object.
Args:
grid (ocitysmap2.Grid): the Grid object from which we
compute the location strings
Returns:
Nothing, but the location_str field will have been altered
"""
if self.endpoint1 is not None:
ep1_label = grid.get_location_str( * self.endpoint1.get_latlong())
else:
ep1_label = None
if self.endpoint2 is not None:
ep2_label = grid.get_location_str( * self.endpoint2.get_latlong())
else:
ep2_label = None
if ep1_label is None:
ep1_label = ep2_label
if ep2_label is None:
ep2_label = ep1_label
if ep1_label == ep2_label:
if ep1_label is None:
self.location_str = "???"
self.location_str = ep1_label
elif grid.rtl:
self.location_str = "%s-%s" % (max(ep1_label, ep2_label),
min(ep1_label, ep2_label))
else:
self.location_str = "%s-%s" % (min(ep1_label, ep2_label),
max(ep1_label, ep2_label))
if __name__ == "__main__": if __name__ == "__main__":
import cairo import cairo

Wyświetl plik

@ -64,6 +64,23 @@ class StreetIndex:
def categories(self): def categories(self):
return self._categories return self._categories
def apply_grid(self, grid):
"""
Fix the label location_str field by mapping the streets to the
given grid.
Args:
grid (ocitysmap2.Grid): the Grid object from which we
compute the location strings
Returns:
Nothing, but self._categories will have been modified !
"""
for category in self._categories:
for item in category.items:
item.update_location_str(grid)
def write_to_csv(self, title, output_filename): def write_to_csv(self, title, output_filename):
# TODO: implement writing the index to CSV # TODO: implement writing the index to CSV
try: try:

Wyświetl plik

@ -96,7 +96,7 @@ class StreetIndexRenderingArea:
class StreetIndexRenderer: class StreetIndexRenderer:
""" """
The StreetIndex class encapsulate all the logic related to the querying and The StreetIndex class encapsulates all the logic related to the querying and
rendering of the street index. rendering of the street index.
""" """