Ejemplo n.º 1
0
    def disambiguate_titles(self, source):
        entities = Entity.objects.filter(source=source)
        inferred_names = {}
        for entity in entities:
            inferred_name = entity.metadata['osm']['tags'].get('name') or entity.metadata['osm']['tags'].get('operator')
            if not inferred_name:
                continue
            if not inferred_name in inferred_names:
                inferred_names[inferred_name] = set()
            inferred_names[inferred_name].add(entity)

        for inferred_name, entities in inferred_names.items():
            if len(entities) > 1:
                for entity in entities:
                    if entity.metadata['osm']['tags'].get('addr:street'):
                        entity.title = u"%s, %s" % (inferred_name, entity.metadata['osm']['tags'].get('addr:street'))
                        continue

                    try:
                        name = reverse_geocode(entity.location[0], entity.location[1])[0]['name']
                        if name:
                            entity.title = u"%s, %s" % (inferred_name, name)
                            entity.save()
                    except:
                        self.output.write("Couldn't geocode for %s\n" % inferred_name)
Ejemplo n.º 2
0
    def endElement(self, name):
        if name in ('node','way') and self.valid:
            try:
                types = self.find_types(self.tags)
            except ValueError:
                self.ignore_count += 1
                return

            # Ignore ways that lay partly outside our bounding box
            if name == 'way' and not all(id in self.node_locations for id in self.nodes):
                return

            # We already have these from OxPoints, so leave them alone.
            if self.tags.get('amenity') == 'library' and self.tags.get('operator') == 'University of Oxford':
                return

            # Ignore disused and under-construction entities
            if self.tags.get('life_cycle', 'in_use') != 'in_use' or self.tags.get('disused') in ('1', 'yes', 'true'):
                return

            try:
                entity = Entity.objects.get(source=self.source, _identifiers__scheme='osm', _identifiers__value=self.id)
                created = True
            except Entity.DoesNotExist:
                entity = Entity(source=self.source)
                created = False

            if not 'osm' in entity.metadata or entity.metadata['osm'].get('attrs', {}).get('timestamp', '') < self.attrs['timestamp']:

                if created:
                    self.create_count += 1
                else:
                    self.modify_count += 1

                if name == 'node':
                    entity.location = Point(self.node_location, srid=4326)
                    entity.geometry = entity.location
                elif name == 'way':
                    cls = LinearRing if self.nodes[0] == self.nodes[-1] else LineString
                    entity.geometry = cls([self.node_locations[n] for n in self.nodes], srid=4326)
                    min_, max_ = (float('inf'), float('inf')), (float('-inf'), float('-inf'))
                    for lon, lat in [self.node_locations[n] for n in self.nodes]:
                        min_ = min(min_[0], lon), min(min_[1], lat) 
                        max_ = max(max_[0], lon), max(max_[1], lat)
                    entity.location = Point( (min_[0]+max_[0])/2 , (min_[1]+max_[1])/2 , srid=4326)
                else:
                    raise AssertionError("There should be no other types of entity we're to deal with.")

                try:
                    name = self.tags.get('name') or self.tags['operator']
                except (KeyError, AssertionError):
                    try:
                        name = reverse_geocode(*entity.location)[0]['name']
                        if not name:
                            raise IndexError
                        name = u"↝ %s" % name
                    except IndexError:
                        name = u"↝ %f, %f" % (self.node_location[1], self.node_location[0])

                entity.title = name
                entity.metadata['osm'] = {
                    'attrs': dict(self.attrs),
                    'tags': self.tags
                }
                entity.primary_type = self.entity_types[types[0]]

                if 'addr:postcode' in self.tags:
                    entity.post_code = self.tags['addr:postcode'].replace(' ', '')
                else:
                    entity.post_code = ""

                entity.save(identifiers={'osm': self.id})

                entity.all_types = [self.entity_types[et] for et in types]
                entity.update_all_types_completion()

            else:
                self.unchanged_count += 1