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._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))
|
||||||
|
|
|
||||||
|
|
@ -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')
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
Ładowanie…
Reference in New Issue