Split unit designators (UNIT/APT/STE/etc) out of combined address strings into addr:unit instead of leaving them in addr:street
This commit is contained in:
+20
-2
@@ -52,14 +52,17 @@ def process_address_fields(gdf, exceptions):
|
|||||||
mapping['addr:housenumber'] = series.round().astype('Int64')
|
mapping['addr:housenumber'] = series.round().astype('Int64')
|
||||||
break
|
break
|
||||||
|
|
||||||
# Unit
|
# Unit (a dedicated column takes priority; otherwise fall back to a unit
|
||||||
|
# designator embedded in a combined street+unit address string below)
|
||||||
|
unit_from_column = [None] * len(processed)
|
||||||
for field in ['UNIT', 'UnitNumber', 'UNIT_NUM', 'APT']:
|
for field in ['UNIT', 'UnitNumber', 'UNIT_NUM', 'APT']:
|
||||||
if field in processed.columns:
|
if field in processed.columns:
|
||||||
series = processed[field].copy().replace(['nan', 'None', '', None], None)
|
series = processed[field].copy().replace(['nan', 'None', '', None], None)
|
||||||
mapping['addr:unit'] = series.where(series.notna(), None)
|
unit_from_column = list(series.where(series.notna(), None))
|
||||||
break
|
break
|
||||||
|
|
||||||
# Street name
|
# Street name
|
||||||
|
unit_from_address = [None] * len(processed)
|
||||||
if 'SADD' in processed.columns:
|
if 'SADD' in processed.columns:
|
||||||
# Sumter: full address string in SADD
|
# Sumter: full address string in SADD
|
||||||
mapping['addr:street'] = [
|
mapping['addr:street'] = [
|
||||||
@@ -67,6 +70,11 @@ def process_address_fields(gdf, exceptions):
|
|||||||
if pd.notna(v) else None
|
if pd.notna(v) else None
|
||||||
for v in processed['SADD']
|
for v in processed['SADD']
|
||||||
]
|
]
|
||||||
|
unit_from_address = [
|
||||||
|
qgis_functions.title(qgis_functions.getunitfromaddress(str(v), None, None) or '') or None
|
||||||
|
if pd.notna(v) else None
|
||||||
|
for v in processed['SADD']
|
||||||
|
]
|
||||||
elif 'FullAddres' in processed.columns:
|
elif 'FullAddres' in processed.columns:
|
||||||
# Lake: full address string in FullAddres
|
# Lake: full address string in FullAddres
|
||||||
mapping['addr:street'] = [
|
mapping['addr:street'] = [
|
||||||
@@ -74,6 +82,11 @@ def process_address_fields(gdf, exceptions):
|
|||||||
if pd.notna(v) else None
|
if pd.notna(v) else None
|
||||||
for v in processed['FullAddres']
|
for v in processed['FullAddres']
|
||||||
]
|
]
|
||||||
|
unit_from_address = [
|
||||||
|
qgis_functions.title(qgis_functions.getunitfromaddress(str(v), None, None) or '') or None
|
||||||
|
if pd.notna(v) else None
|
||||||
|
for v in processed['FullAddres']
|
||||||
|
]
|
||||||
elif 'BaseStreet' in processed.columns:
|
elif 'BaseStreet' in processed.columns:
|
||||||
# Lake alternative: assemble from components
|
# Lake alternative: assemble from components
|
||||||
street_names = []
|
street_names = []
|
||||||
@@ -85,6 +98,11 @@ def process_address_fields(gdf, exceptions):
|
|||||||
street_names.append(qgis_functions.title(' '.join(parts)) if parts else None)
|
street_names.append(qgis_functions.title(' '.join(parts)) if parts else None)
|
||||||
mapping['addr:street'] = street_names
|
mapping['addr:street'] = street_names
|
||||||
|
|
||||||
|
mapping['addr:unit'] = [
|
||||||
|
col if col is not None else addr
|
||||||
|
for col, addr in zip(unit_from_column, unit_from_address)
|
||||||
|
]
|
||||||
|
|
||||||
# Apply street name exceptions
|
# Apply street name exceptions
|
||||||
if 'addr:street' in mapping and exceptions:
|
if 'addr:street' in mapping and exceptions:
|
||||||
mapping['addr:street'] = [
|
mapping['addr:street'] = [
|
||||||
|
|||||||
+20
-1
@@ -21,13 +21,32 @@ def title(s):
|
|||||||
result = re.sub(pattern, replacement, result)
|
result = re.sub(pattern, replacement, result)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
# Secondary unit designators that may appear inline in a full address string,
|
||||||
|
# e.g. "123 ROLLING ACRES RD UNIT 208" - everything from the designator on is
|
||||||
|
# the unit, not part of the street name.
|
||||||
|
_UNIT_DESIGNATORS = {'UNIT', 'APT', 'APARTMENT', 'STE', 'SUITE', 'BLDG', 'BUILDING', 'LOT'}
|
||||||
|
|
||||||
|
def _splitunit(parts):
|
||||||
|
for i, part in enumerate(parts):
|
||||||
|
if part.upper().rstrip('.') in _UNIT_DESIGNATORS:
|
||||||
|
return parts[:i], (" ".join(parts[i + 1:]) or None)
|
||||||
|
return parts, None
|
||||||
|
|
||||||
# @qgsfunction(args='auto', group='Custom', referenced_columns=[])
|
# @qgsfunction(args='auto', group='Custom', referenced_columns=[])
|
||||||
def getstreetfromaddress(value1, feature, parent):
|
def getstreetfromaddress(value1, feature, parent):
|
||||||
parts = value1.split()
|
parts = value1.split()
|
||||||
parts.pop(0) # Ignore the first bit (i.e. "123" in "123 N MAIN ST")
|
parts.pop(0) # Ignore the first bit (i.e. "123" in "123 N MAIN ST")
|
||||||
|
street_parts, _ = _splitunit(parts)
|
||||||
#parts = map(formatstreetname, parts)
|
#parts = map(formatstreetname, parts)
|
||||||
#return " ".join(parts)
|
#return " ".join(parts)
|
||||||
return formatstreet(" ".join(parts), None, None)
|
return formatstreet(" ".join(street_parts), None, None)
|
||||||
|
|
||||||
|
# @qgsfunction(args='auto', group='Custom', referenced_columns=[])
|
||||||
|
def getunitfromaddress(value1, feature, parent):
|
||||||
|
parts = value1.split()
|
||||||
|
parts.pop(0) # Ignore the first bit (i.e. "123" in "123 N MAIN ST")
|
||||||
|
_, unit = _splitunit(parts)
|
||||||
|
return unit
|
||||||
|
|
||||||
# @qgsfunction(args='auto', group='Custom', referenced_columns=[])
|
# @qgsfunction(args='auto', group='Custom', referenced_columns=[])
|
||||||
def formatstreet(value1, feature, parent):
|
def formatstreet(value1, feature, parent):
|
||||||
|
|||||||
Reference in New Issue
Block a user