+ def _get_assignments_postcode(self, base: TokenAssignment,
+ query_len: int) -> Iterator[TokenAssignment]:
+ """ Yield possible assignments of Postcode searches with an
+ address component.
+ """
+ assert base.postcode is not None
+
+ if (base.postcode.start == 0 and self.direction != -1)\
+ or (base.postcode.end == query_len and self.direction != 1):
+ log().comment('postcode search')
+ # <address>,<postcode> should give preference to address search
+ if base.postcode.start == 0:
+ penalty = self.penalty
+ self.direction = -1 # name searches are only possbile backwards
+ else:
+ penalty = self.penalty + 0.1
+ self.direction = 1 # name searches are only possbile forwards
+ yield dataclasses.replace(base, penalty=penalty)
+
+
+ def _get_assignments_address_forward(self, base: TokenAssignment,
+ query: qmod.QueryStruct) -> Iterator[TokenAssignment]:
+ """ Yield possible assignments of address searches with
+ left-to-right reading.
+ """
+ first = base.address[0]
+
+ log().comment('first word = name')
+ yield dataclasses.replace(base, penalty=self.penalty,
+ name=first, address=base.address[1:])
+
+ if (not base.housenumber or first.end >= base.housenumber.start)\
+ and (not base.qualifier or first.start >= base.qualifier.end):
+ base_penalty = self.penalty
+ if (base.housenumber and base.housenumber.start > first.start) \
+ or len(query.source) > 1:
+ base_penalty += 0.25
+ for i in range(first.start + 1, first.end):
+ name, addr = first.split(i)
+ penalty = base_penalty + PENALTY_TOKENCHANGE[query.nodes[i].btype]
+ log().comment(f'split first word = name ({i - first.start})')
+ yield dataclasses.replace(base, name=name, penalty=penalty,
+ address=[addr] + base.address[1:])
+
+
+ def _get_assignments_address_backward(self, base: TokenAssignment,
+ query: qmod.QueryStruct) -> Iterator[TokenAssignment]:
+ """ Yield possible assignments of address searches with
+ right-to-left reading.
+ """
+ last = base.address[-1]
+
+ if self.direction == -1 or len(base.address) > 1:
+ log().comment('last word = name')
+ yield dataclasses.replace(base, penalty=self.penalty,
+ name=last, address=base.address[:-1])
+
+ if (not base.housenumber or last.start <= base.housenumber.end)\
+ and (not base.qualifier or last.end <= base.qualifier.start):
+ base_penalty = self.penalty
+ if base.housenumber and base.housenumber.start < last.start:
+ base_penalty += 0.4
+ if len(query.source) > 1:
+ base_penalty += 0.25
+ for i in range(last.start + 1, last.end):
+ addr, name = last.split(i)
+ penalty = base_penalty + PENALTY_TOKENCHANGE[query.nodes[i].btype]
+ log().comment(f'split last word = name ({i - last.start})')
+ yield dataclasses.replace(base, name=name, penalty=penalty,
+ address=base.address[:-1] + [addr])
+
+