4.6 KiB
4.6 KiB
Salem Oregon Address Import
See https://wiki.openstreetmap.org/wiki/Salem_Oregon_Address_Import
Data Source
- Salem GIS department's FTP server
- No copyright, public domain
Field Mapping
-
ADD_NUM -> addr:housenumber
-
FULL_ST_NA -> addr:street via getformattedstreetname(FULL_ST_NA)
-
SUB_VAL -> addr:unit
-
CITY -> addr:city via title(CITY)
-
ZIP -> addr:postcode
-
manually add addr:state "OR"
Processing
- Use the below script in QGIS to do virtual field calculations.
- Export the layer to geojson with WGS84 projection.
- Save as
processed.geojson
- Use VIM or similar to find-replace "ADD_NUM" to "addr:housenumber" etc.
Import steps
- Load processed.geojson into JOSM
- Zoom in to the area you wish to work on and Download OSM data to a New Layer
- In the geojson layer, select one neighborhood or city block worth of addresses
- Click Edit > Merge Selection
- Switch to Data Layer 1 and run the JOSM Validator
- Fix all duplicate housenumber warnings and nearby street not found warnings
- Click Upload, verify there are no further warnings or errors in the changeset
- Make sure there are no erroneous Relations or other unwanted objects about to be uploaded.
- Upload with this changeset comment:
comment=Addresses near Salem Oregon #salemimport
import=yes
website=https://wiki.openstreetmap.org/wiki/Salem_Oregon_Address_Import
source=City of Salem GIS
source:url=https://data.cityofsalem.net/datasets/salem::primary-address/explore
- Review imported data in Achavi or Osmcha to ensure it looks proper.
QGIS Processing script
from qgis.core import *
from qgis.gui import *
import re
@qgsfunction(args='auto', group='Custom', referenced_columns=[])
def getformattedstreetname(value1, feature, parent):
parts = value1.split()
parts = map(formatstreetname, parts)
return " ".join(parts)
@qgsfunction(args='auto', group='Custom', referenced_columns=[])
def getformattedstreetnamefromaddress(value1, feature, parent):
parts = value1.split()
parts.pop(0) # Ignore the first bit (i.e. "123" in "123 N MAIN ST")
parts = map(formatstreetname, parts)
return " ".join(parts)
def formatstreetname(name):
# Specific suffixes like "123th" we have lower
if re.search("[0-9]+TH", name):
return name.capitalize()
if re.search("[0-9]+ND", name):
return name.capitalize()
if re.search("[0-9]+ST", name):
return name.capitalize()
if re.search("[0-9]+RD", name):
return name.capitalize()
# Weird names like 123D we keep upper
if re.search("[0-9]+[A-Z]+", name):
return name
# Prefixes we want to keep uppercase
if name == "US":
return "US"
if name == "SR":
return "SR"
if name == "CR":
return "CR"
if name == "C":
return "C"
# Directions
if name == "N":
return "North"
if name == "NE":
return "Northeast"
if name == "E":
return "East"
if name == "SE":
return "Southeast"
if name == "S":
return "South"
if name == "SW":
return "Southwest"
if name == "W":
return "West"
if name == "NW":
return "Northwest"
# Suffixes
if name == "AV":
return "Avenue"
if name == "AVE":
return "Avenue"
if name == "BLVD":
return "Boulevard"
if name == "BND":
return "Bend"
if name == "CIR":
return "Circle"
if name == "CT":
return "Court"
if name == "DR":
return "Drive"
if name == "FLDS":
return "Fields"
if name == "GRV":
return "Grove"
if name == "HOLW":
return "Hollow"
if name == "HW":
return "Highway"
if name == "HWY":
return "Highway"
if name == "LN":
return "Lane"
if name == "LP":
return "Loop"
if name == "LOOP":
return "Loop"
if name == "PATH":
return "Path"
if name == "PL":
return "Place"
if name == "RD":
return "Road"
if name == "RUN":
return "Run"
if name == "ST":
return "Street"
if name == "TER":
return "Terrace"
if name == "TL":
return "Trail"
if name == "TRL":
return "Trail"
if name == "VW":
return "View"
if name == "WAY":
return "Way"
if name == "XING":
return "Crossing"
# Irish names
if name == "MCCRAY":
return "McCray"
if name == "MCKOWN":
return "McKown"
return name.capitalize()