kopia lustrzana https://github.com/hholzgra/ocitysmap
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
rodzic
bdcc6b01f0
commit
f612534ec6
|
|
@ -53,6 +53,7 @@ class Grid:
|
|||
"""
|
||||
|
||||
self._bbox = bounding_box
|
||||
self.rtl = rtl
|
||||
self._height_m, self._width_m = bounding_box.spheric_sizes()
|
||||
|
||||
l.info('Laying out grid on %.1fx%.1fm area...' %
|
||||
|
|
@ -67,28 +68,27 @@ class Grid:
|
|||
Grid.GRID_COUNT_TRESHOLD):
|
||||
break
|
||||
|
||||
self._horiz_angle = (abs(self._bbox.get_top_left()[1] -
|
||||
self._bbox.get_bottom_right()[1]) /
|
||||
self.horiz_count)
|
||||
self._vert_angle = (abs(self._bbox.get_top_left()[0] -
|
||||
self._bbox.get_bottom_right()[0]) /
|
||||
self.vert_count)
|
||||
self._horiz_angle_span = abs(self._bbox.get_top_left()[1] -
|
||||
self._bbox.get_bottom_right()[1])
|
||||
self._vert_angle_span = abs(self._bbox.get_top_left()[0] -
|
||||
self._bbox.get_bottom_right()[0])
|
||||
|
||||
self._horizontal_lines = [self._bbox.get_top_left()[0] -
|
||||
(x+1) * self._vert_angle for x in xrange(
|
||||
int(math.floor(self.vert_count)))]
|
||||
self._vertical_lines = [self._bbox.get_top_left()[1] +
|
||||
(x+1) * self._horiz_angle for x in xrange(
|
||||
int(math.floor(self.horiz_count)))]
|
||||
self._horiz_unit_angle = (self._horiz_angle_span / self.horiz_count)
|
||||
self._vert_unit_angle = (self._vert_angle_span / self.vert_count)
|
||||
|
||||
self._horizontal_lines = [ ( self._bbox.get_top_left()[0] -
|
||||
(x+1) * self._vert_unit_angle)
|
||||
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,
|
||||
xrange(int(math.ceil(self.horiz_count))))
|
||||
if rtl:
|
||||
self.horizontal_labels.reverse()
|
||||
self.vertical_labels = map(self._gen_vertical_square_label,
|
||||
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.horiz_count, self.vert_count))
|
||||
|
||||
|
|
@ -120,6 +120,9 @@ class Grid:
|
|||
28 -> AB
|
||||
...
|
||||
"""
|
||||
if self.rtl:
|
||||
x = len(self._vertical_lines) - x
|
||||
|
||||
label = ''
|
||||
while x != -1:
|
||||
label = chr(ord('A') + x % 26) + label
|
||||
|
|
@ -131,6 +134,22 @@ class Grid:
|
|||
number. Since we put numbers verticaly, this is simply 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__":
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
grid = Grid(coords.BoundingBox(44.4883, -1.0901, 44.4778, -1.0637))
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ if __name__ == '__main__':
|
|||
|
||||
from ocitysmap2 import i18n, coords
|
||||
from ocitysmap2.index import commons
|
||||
from ocitysmap2.grid import Grid
|
||||
|
||||
import render
|
||||
|
||||
|
|
@ -72,6 +73,10 @@ if __name__ == '__main__':
|
|||
|
||||
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),
|
||||
street_index.categories)
|
||||
|
||||
|
|
@ -107,6 +112,14 @@ if __name__ == '__main__':
|
|||
_render('width', 'right')
|
||||
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),
|
||||
street_index.categories)
|
||||
_render('height', 'top')
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ class IndexCategory:
|
|||
def get_all_item_squares(self):
|
||||
return [x.squares for x in self.items]
|
||||
|
||||
|
||||
class IndexItem:
|
||||
"""
|
||||
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)
|
||||
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__":
|
||||
import cairo
|
||||
|
|
|
|||
|
|
@ -64,6 +64,23 @@ class StreetIndex:
|
|||
def categories(self):
|
||||
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):
|
||||
# TODO: implement writing the index to CSV
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ class StreetIndexRenderingArea:
|
|||
|
||||
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.
|
||||
"""
|
||||
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue