maposmatic-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Maposmatic-dev] [PATCH 11/22] multi-page: prepare data for index genera


From: Thomas Petazzoni
Subject: [Maposmatic-dev] [PATCH 11/22] multi-page: prepare data for index generation
Date: Fri, 30 Mar 2012 13:00:28 +0200

Using StreetIndex, we build an index for each page of the map, and
then with various sorting and grouping tricks, we merge those indexes,
categories by categories. This will allow to generate the index with
data that is properly sorted.

Signed-off-by: Thomas Petazzoni <address@hidden>
---
 ocitysmap2/layoutlib/multi_page_renderer.py |   86 +++++++++++++++++++++++++++
 1 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/ocitysmap2/layoutlib/multi_page_renderer.py 
b/ocitysmap2/layoutlib/multi_page_renderer.py
index 52254bf..c214f60 100644
--- a/ocitysmap2/layoutlib/multi_page_renderer.py
+++ b/ocitysmap2/layoutlib/multi_page_renderer.py
@@ -30,17 +30,23 @@ import sys
 import cairo
 import mapnik
 import coords
+import locale
+
+from itertools import groupby
 
 from abstract_renderer import Renderer
 
 from ocitysmap2.maplib.map_canvas import MapCanvas
 from ocitysmap2.maplib.grid import Grid
+from indexlib.indexer import StreetIndex
 
 import ocitysmap2
 import commons
 import shapely.wkt
 from ocitysmap2 import maplib
 
+from indexlib.commons import IndexCategory
+
 LOG = logging.getLogger('ocitysmap')
 PAGE_STR = " - Page %(page_number)d"
 
@@ -178,6 +184,7 @@ class MultiPageRenderer(Renderer):
 
         # Create the map canvas for each page
         self.pages = []
+        indexes = []
         print "List of all bboxes"
         for i, (bb, bb_inner) in enumerate(bboxes):
 
@@ -209,8 +216,87 @@ class MultiPageRenderer(Renderer):
 
             map_canvas.render()
 
+            index = StreetIndex(self.db,
+                                bb_inner.as_wkt(),
+                                self.rc.i18n)
+
+            index.apply_grid(map_grid)
+
+            print index
+
+            indexes.append(index)
             self.pages.append((map_canvas, map_grid))
 
+        self.index_data = self._merge_page_indexes(indexes)
+
+    def _merge_page_indexes(self, indexes):
+        # First, we split street categories and "other" categories,
+        # because we sort them and we don't want to have the "other"
+        # categories intermixed with the street categories. This
+        # sorting is required for the groupby Python operator to work
+        # properly.
+        all_categories_streets = []
+        all_categories_others  = []
+        for page_number, idx in enumerate(indexes):
+            for cat in idx.categories:
+                # Mark each IndexItem with its page number
+                for item in cat.items:
+                    item.page_number = page_number
+                # Split in two lists depending on the category type
+                # (street or other)
+                if cat.is_street:
+                    all_categories_streets.append(cat)
+                else:
+                    all_categories_others.append(cat)
+
+        all_categories_streets_merged = \
+            self._merge_index_same_categories(all_categories_streets, 
is_street=True)
+        all_categories_others_merged = \
+            self._merge_index_same_categories(all_categories_others, 
is_street=False)
+
+        all_categories_merged = \
+            all_categories_streets_merged + all_categories_others_merged
+
+        return all_categories_merged
+
+    def _merge_index_same_categories(self, categories, is_street=True):
+        # Sort by categories. Now we may have several consecutive
+        # categories with the same name (i.e category for letter 'A'
+        # from page 1, category for letter 'A' from page 3).
+        categories.sort(key=lambda s:s.name)
+
+        categories_merged = []
+        for category_name,grouped_categories in groupby(categories,
+                                                        key=lambda s:s.name):
+
+            # Group the different IndexItem from categories having the
+            # same name. The groupby() function guarantees us that
+            # categories with the same name are grouped together in
+            # grouped_categories[].
+
+            grouped_items = []
+            for cat in grouped_categories:
+                grouped_items.extend(cat.items)
+
+            # Re-sort alphabetically all the IndexItem according to
+            # the street name.
+
+            prev_locale = locale.getlocale(locale.LC_COLLATE)
+            locale.setlocale(locale.LC_COLLATE, self.rc.i18n.language_code())
+            try:
+                grouped_items_sorted = \
+                    sorted(grouped_items,
+                           lambda x,y: locale.strcoll(x.label, y.label))
+            finally:
+                locale.setlocale(locale.LC_COLLATE, prev_locale)
+
+            # Rebuild a IndexCategory object with the list of merged
+            # and sorted IndexItem
+            categories_merged.append(
+                IndexCategory(category_name, grouped_items_sorted, is_street))
+
+        return categories_merged
+
     def _project_envelope(self, bbox):
         """Project the given bounding box into the rendering projection."""
         envelope = mapnik.Box2d(bbox.get_top_left()[1],
-- 
1.7.4.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]