Exemplo n.º 1
0
def element_to_lines(element: Element, osm_helper: OsmHelper):
    if element.tag == 'relation' and tag_dict(element).get(
            'type') == 'multipolygon':
        return osm_helper.multipolygon_to_polygons(element)
    elif element.tag == 'way':
        return [osm_helper.way_coordinates(element)]
    return []
Exemplo n.º 2
0
    def draw(self, elements: Element, osm_helper: OsmHelper, camera: Camera,
             image_draw: ImageDraw):
        layers = defaultdict(lambda: defaultdict(list))
        for element in elements:
            tags = tag_dict(element)
            try:
                layer = int(tags['layer'])
            except (KeyError, ValueError):
                layer = 1 if tags.get('bridge') == 'yes'\
                    else -1 if tags.get('tunnel') == 'yes'\
                    else 0
            road_type: MappedFeature = self.types[element]
            layers[layer][road_type] += transform_shapes(
                element_to_lines(element, osm_helper), camera)

        def draw_roads(color, width, roads):
            if color is not None:
                for road in roads:
                    image_draw.line(road,
                                    fill=color,
                                    width=width,
                                    joint='curve')

        for layer in range(-5, 7):
            # draw bridge outline
            if layer > 0:
                for road_type in sorted(layers[layer]):
                    width = road_type.style.width * (camera.px_per_meter()**
                                                     road_type.style.exp)
                    draw_roads(road_type.style.outline_bridge,
                               int(width) + 2, layers[layer][road_type])

            # draw surface outline
            if layer == 0:
                for road_type in sorted(layers[layer]):
                    width = road_type.style.width * (camera.px_per_meter()**
                                                     road_type.style.exp)
                    draw_roads(road_type.style.outline,
                               int(width) + 2, layers[layer][road_type])

            # draw tunnel line
            if layer < 0:
                for road_type in sorted(layers[layer]):
                    width = road_type.style.width * (camera.px_per_meter()**
                                                     road_type.style.exp)
                    draw_roads(road_type.style.fill + '8', int(width),
                               layers[layer][road_type])

            # draw line
            if layer >= 0:
                for road_type in sorted(layers[layer]):
                    width = road_type.style.width * (camera.px_per_meter()**
                                                     road_type.style.exp)
                    draw_roads(road_type.style.fill, int(width),
                               layers[layer][road_type])
Exemplo n.º 3
0
    def _select(self, element, name=None):
        self.highlight, self.selection = None, None
        self.dirty = True
        if element is None:
            return
        if not name:
            name = osm_helper.tag_dict(element).get('name')

        if element.tag == 'node':
            self.highlight = (float(element.attrib['lat']),
                              float(element.attrib['lon']))
            self.camera.center_at(*self.highlight)
            self.selection = name
        else:
            points = []
            tp = element.tag
            if element.tag == 'way':
                points = self.osm_helper.way_coordinates(element)
            elif element.tag == 'relation':
                tags = osm_helper.tag_dict(element)
                tp = '{}:{}'.format(element.tag, tags.get('type'))
                if tags.get('type') == 'multipolygon':
                    points = [
                        point for polygon in
                        self.osm_helper.multipolygon_to_polygons(element)
                        for point in polygon
                    ]
            if len(points) == 0:
                log('Don\'t know how to select element {} of type {}'.format(
                    name, tp),
                    level=1)
            else:
                rect = Rectangle(
                    min(points, key=itemgetter(0))[0],
                    min(points, key=itemgetter(1))[1],
                    max(points, key=itemgetter(0))[0],
                    max(points, key=itemgetter(1))[1])
                self.highlight = rect
                self.camera.center_at((rect.min_lat + rect.max_lat) / 2,
                                      (rect.min_lon + rect.max_lon) / 2)
                self.selection = name
        log('Selected {} at {}'.format(self.highlight, self.selection))
Exemplo n.º 4
0
 def wants_element(self, element: Element, osm_helper: OsmHelper):
     tags = tag_dict(element)
     if tags.get('area') == 'yes' and \
             not tags.get('railway') == 'turntable':
         return False
     for tag, types in _road_types.items():
         try:
             self.types[element] = types[tags[tag]]
             return True
         except KeyError:
             pass
     return False
Exemplo n.º 5
0
def element_to_polygons(element: Element, osm_helper: OsmHelper):
    if element.tag == 'relation' and tag_dict(element).get(
            'type') == 'multipolygon':
        return [
            polygon[:-1]
            for polygon in osm_helper.multipolygon_to_wsps(element)
        ]
    elif element.tag == 'way':
        way = osm_helper.way_coordinates(element)
        if len(way) >= 4 and way[0] == way[-1]:
            return [way[:-1]]
    return []
Exemplo n.º 6
0
def element_to_points(element: Element, osm_helper: OsmHelper):
    if element.tag == 'relation' and tag_dict(element).get(
            'type') == 'multipolygon':
        return [
            point for polygon in osm_helper.multipolygon_to_polygons(element)
            for point in polygon
        ]
    elif element.tag == 'way':
        way = osm_helper.way_coordinates(element)
        if len(way) >= 2 and way[0] == way[-1]:
            return way[:-1]
        return way
    elif element.tag == 'node':
        return [(float(element.attrib['lat']), float(element.attrib['lon']))]
    return []
Exemplo n.º 7
0
 def wants_element(self, element: Element, osm_helper: OsmHelper):
     tags = tag_dict(element)
     for key, features in self.styles.items():
         try:
             feature: MappedFeature = features[tags[key]]
             if feature.style.wants_element(element, tags, osm_helper):
                 self.map[element] = feature
                 self.data[element] = feature.style.convert(
                     element, tags,
                     osm_helper), element_to_bbox(element, osm_helper)
                 return self.data[element][0] is not None
             return False
         except KeyError:
             pass
     return False
Exemplo n.º 8
0
 def task_search_address(self, street: str, number: str):
     street, number = street.lower(), number.lower()
     self._status(
         status='Searching for address: {}, {}'.format(street, number))
     self._select(None)
     for element in self.element_tree.getroot():
         tags = osm_helper.tag_dict(element)
         addr_street, addr_number = tags.get('addr:street', ''), tags.get(
             'addr:housenumber', '')
         address = ' '.join(filter(lambda x: x, [addr_street, addr_number]))
         if street in addr_street.lower() and number in addr_number.lower(
         ).split('/'):
             log('Found {}'.format(address))
             self._select(element, address)
             return
     log('Search unsuccessful')
Exemplo n.º 9
0
 def task_search_name(self, target: str):
     target = target.lower()
     self._status(status='Searching for name: {}'.format(target))
     self._select(None)
     best, best_len = None, 1000
     for element in self.element_tree.getroot():
         tags = osm_helper.tag_dict(element)
         names = filter(lambda i: 'name' in i[0], tags.items())
         for key, name in names:
             if target in name.lower():
                 match = len(name)
                 if element.tag == 'node':
                     match += 0.5
                 if element.tag == 'relation':
                     match -= 0.5
                 if match < best_len:
                     best, best_len = element, match
     if best is None:
         log('Search unsuccessful')
     self._select(best)
Exemplo n.º 10
0
        return False
    return True


print('testing osm_helper.multipolygon_to_wsps')
test_count = 0
correct_tests = 0
failure = None

element_tree = ET.parse('testdata/map.osm')
root = element_tree.getroot()
helper = osm_helper.OsmHelper(element_tree)

for element in root:
    if element.tag == 'relation':
        td = osm_helper.tag_dict(element)
        if td['type'] == 'multipolygon' and 'test' in td:
            fail = None
            result = helper.multipolygon_to_wsps(element)
            im1 = PIL.Image.new('RGB', (500, 800))
            draw = PIL.ImageDraw.Draw(im1)
            draw.rectangle((0, 0, 499, 799), fill='white', outline='black')

            xs = [p[0] for polygon in result for p in polygon]
            ys = [p[1] for polygon in result for p in polygon]
            scale_x = 300 / (max(xs) - min(xs))
            delta_x = -min(xs) * scale_x + 100
            scale_y = 300 / (max(ys) - min(ys))
            delta_y = -min(ys) * scale_y + 250

            for polygon in result:
Exemplo n.º 11
0
    if len(dict1) != len(dict2):
        return False
    return True

print('testing osm_helper.tag_dict')
test_count = 0
correct_tests = 0
failure = None

element_tree = ET.parse('testdata/map.osm')
root = element_tree.getroot()

with open('testdata/tag_dict.out', 'r', encoding="utf8") as f:
    for element in root:
        fail = None
        result = osm_helper.tag_dict(element)
        
        expected = {}
        expected_count = int(f.readline())
        for i in range(expected_count):
            key = f.readline().rstrip()
            value = f.readline().rstrip()
            expected[key] = value
        
        if not isinstance(result, dict):
            fail = 'expected dictionary, got {}'.format(type(result))
        elif not dicts_equal(result, expected):
            fail = 'expected \n{},\n got \n{}\n'.format(expected, result)
        else:
            correct_tests += 1
        test_count += 1