Patient
→
location
documented
Address normalization. One Patient produces at most one location row (most recent home address). The location_id is then set as person.location_id FK.
Conversion profile
omop-patient-location
A FHIR instance converts to location iff it validates against this profile.
| Path | Card | Type | Binding / Fixed | Comment |
|---|---|---|---|---|
| Patient.address | 1..*MS | At least one address is required. If multiple are present, pick the most recent home address. | ||
| Patient.address.line | MS | First entry → location.address_1; second → address_2; remaining concatenated. | ||
| Patient.address.city | MS | |||
| Patient.address.state | MS | Truncated to 2 chars (US state code) for location.state. | ||
| Patient.address.postalCode | MS | Up to 9 chars (ZIP+4) for location.zip. | ||
| Patient.address.country | MS |
ViewDefinition (Stage 1 flattener)
omop-patient-location
10 columns · resource Patient
| column name | FHIRPath | type |
|---|---|---|
| id | Patient.id | id |
| address_1 | Patient.address.line[0] | string |
| address_2 | Patient.address.line[1] | string |
| city | Patient.address.city | string |
| state | Patient.address.state | string |
| zip | Patient.address.postalCode | string |
| county | Patient.address.district | string |
| country_text | Patient.address.country | string |
| latitude | Patient.address.extension.where(url='http://hl7.org/fhir/StructureDefinition/geolocation').extension.where(url='latitude').valueDecimal | decimal |
| longitude | Patient.address.extension.where(url='http://hl7.org/fhir/StructureDefinition/geolocation').extension.where(url='longitude').valueDecimal | decimal |
Condition: Patient.address is present with usable fields
Fields (12)
-
location_id← — integer · generatedPKrequiredAuto-generated primary key3 sources ▾
-
Search-or-create with dedup by (address_1, city, state, zip); shared location_id across persons at same address
- omoponfhir(java) refs/refs/omoponfhir-omopv5-r4-mapping/src/main/java/edu/gatech/chai/omoponfhir/omopv5/r4/mapping/OmopPatient.java — searchAndUpdate pattern with dedup
- ETL-German-FHIR-Core(java) refs/refs/ETL-German-FHIR-Core/src/main/java/org/miracum/etl/fhirtoomop/mapper/PatientMapper.java:293-334 — Deferred via post_process_map; dedup in PostProcessTask
-
Per-patient row, no dedup — one location row per person regardless of address uniqueness
- FhirToCdm(csharp) refs/refs/FhirToCdm/FhirToCdmMappings.cs:20-170 — CreatePersonAndLocations() per-patient row
-
Default location_id = 1 — address not actually mapped
-
-
address_1←Patient.address.line[0]varchar(50) · stringTruncate at 50 chars -
address_2←Patient.address.line[1]varchar(50) · stringNull if line has only one entry. Concatenate beyond 2 lines. -
city←Patient.address.cityvarchar(50) · string -
state←Patient.address.statevarchar(2) · stringTruncate to 2 chars (US state code) -
zip←Patient.address.postalCodevarchar(9) · stringUp to 9 chars (ZIP+4) -
county←Patient.address.districtvarchar(20) · string -
country_source_value←Patient.address.countryvarchar(80) · string -
country_concept_id← constant integer · lookupFK→CONCEPT=0transform:Map country to OMOP Geography conceptMap country to OMOP Geography concept. Default 0. -
location_source_value← — varchar(50) · computedtransform:concat(line, city, state, zip, country)line, city, state, zip, country joined2 sources ▾
-
Concatenated "zip;city;country" stored as dataOne in deferred post_process_map row
- ETL-German-FHIR-Core(java) refs/refs/ETL-German-FHIR-Core/src/main/java/org/miracum/etl/fhirtoomop/mapper/PatientMapper.java:293-334 — dataOne = zip;city;country, dataTwo = lines;state
-
Full address fields mapped directly without explicit source_value field
-
-
latitude←Patient.address.extension.where(url='http://hl7.org/fhir/StructureDefinition/geolocation').extension.where(url='latitude').valueDecimalfloat · decimalRange -90..90 -
longitude←Patient.address.extension.where(url='http://hl7.org/fhir/StructureDefinition/geolocation').extension.where(url='longitude').valueDecimalfloat · decimalRange -180..180
Edge Cases
Multiple line[] entries (>2)
OMOP only has address_1 and address_2. Concatenate beyond into address_2 or drop.
State longer than 2 chars (e.g. California)
Lookup abbreviation or truncate to first 2 letters.
Non-US ZIP (alphanumeric)
Store as-is up to 9 chars.
address.text only (no structured fields)
Store in location_source_value; leave structured fields null.
Geocoding extension absent
latitude/longitude null.
Multiple home addresses
Pick most recent. OMOP only stores one; address history lost.
Same address shared by multiple persons
Deduplicate (shared location_id) or duplicate (one row per person). Both valid.
Reference Implementations
- omoponfhir(java) refs/refs/omoponfhir-omopv5-r4-mapping/src/main/java/edu/gatech/chai/omoponfhir/omopv5/r4/mapping/OmopPatient.java — searchAndUpdate pattern with dedup
- FhirToCdm(csharp) refs/refs/FhirToCdm/FhirToCdmMappings.cs — CreatePersonAndLocations() -- per-patient row, no dedup
- ETL-German-FHIR-Core(java) refs/refs/ETL-German-FHIR-Core/src/main/java/org/miracum/etl/fhirtoomop/mapper/PatientMapper.java — Deferred via post_process_map lines 293-334