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)
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