From e6f5af01ed2487b9d9d036698d3fb20968b1f2e3 Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Wed, 22 Jan 2020 16:55:19 -0500 Subject: [PATCH] convert degrees to kilometers for near calculation --- .../ca/uhn/fhir/jpa/dao/SearchBuilder.java | 68 +++++++------------ .../ca/uhn/fhir/jpa/util/CoordCalculator.java | 25 +++++-- .../FhirResourceDaoDstu3SearchNoFtTest.java | 26 +++---- .../r4/FhirResourceDaoR4SearchNoFtTest.java | 33 ++++----- .../fhir/jpa/util/CoordCalculatorTest.java | 30 +++++--- .../extractor/BaseSearchParamExtractor.java | 6 +- 6 files changed, 97 insertions(+), 91 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java index fa3dbbca590..2989ef796f1 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java @@ -20,15 +20,7 @@ package ca.uhn.fhir.jpa.dao; * #L% */ -import ca.uhn.fhir.context.BaseRuntimeChildDefinition; -import ca.uhn.fhir.context.BaseRuntimeDeclaredChildDefinition; -import ca.uhn.fhir.context.BaseRuntimeElementDefinition; -import ca.uhn.fhir.context.ConfigurationException; -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.context.RuntimeChildChoiceDefinition; -import ca.uhn.fhir.context.RuntimeChildResourceDefinition; -import ca.uhn.fhir.context.RuntimeResourceDefinition; -import ca.uhn.fhir.context.RuntimeSearchParam; +import ca.uhn.fhir.context.*; import ca.uhn.fhir.interceptor.api.HookParams; import ca.uhn.fhir.interceptor.api.IInterceptorBroadcaster; import ca.uhn.fhir.interceptor.api.Pointcut; @@ -51,18 +43,8 @@ import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.jpa.searchparam.util.SourceParam; import ca.uhn.fhir.jpa.term.VersionIndependentConcept; import ca.uhn.fhir.jpa.term.api.ITermReadSvc; -import ca.uhn.fhir.jpa.util.BaseIterator; -import ca.uhn.fhir.jpa.util.CurrentThreadCaptureQueriesListener; -import ca.uhn.fhir.jpa.util.JpaInterceptorBroadcaster; -import ca.uhn.fhir.jpa.util.ScrollableResultsIterator; -import ca.uhn.fhir.jpa.util.SqlQueryList; -import ca.uhn.fhir.model.api.IPrimitiveDatatype; -import ca.uhn.fhir.model.api.IQueryParameterAnd; -import ca.uhn.fhir.model.api.IQueryParameterOr; -import ca.uhn.fhir.model.api.IQueryParameterType; -import ca.uhn.fhir.model.api.IResource; -import ca.uhn.fhir.model.api.Include; -import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; +import ca.uhn.fhir.jpa.util.*; +import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.base.composite.BaseCodingDt; import ca.uhn.fhir.model.base.composite.BaseIdentifierDt; import ca.uhn.fhir.model.base.composite.BaseQuantityDt; @@ -71,11 +53,7 @@ import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum; import ca.uhn.fhir.parser.DataFormatException; -import ca.uhn.fhir.rest.api.Constants; -import ca.uhn.fhir.rest.api.QualifiedParamList; -import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; -import ca.uhn.fhir.rest.api.SortOrderEnum; -import ca.uhn.fhir.rest.api.SortSpec; +import ca.uhn.fhir.rest.api.*; import ca.uhn.fhir.rest.api.server.IPreResourceAccessDetails; import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.param.*; @@ -99,6 +77,7 @@ import org.hibernate.ScrollableResults; import org.hibernate.query.Query; import org.hibernate.query.criteria.internal.CriteriaBuilderImpl; import org.hibernate.query.criteria.internal.predicate.BooleanStaticAssertionPredicate; +import org.hibernate.search.spatial.impl.Point; import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; @@ -121,11 +100,7 @@ import java.util.Map.Entry; import java.util.stream.Collectors; import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; -import static org.apache.commons.lang3.StringUtils.defaultIfBlank; -import static org.apache.commons.lang3.StringUtils.defaultString; -import static org.apache.commons.lang3.StringUtils.isBlank; -import static org.apache.commons.lang3.StringUtils.isNotBlank; -import static org.apache.commons.lang3.StringUtils.trim; +import static org.apache.commons.lang3.StringUtils.*; /** * The SearchBuilder is responsible for actually forming the SQL query that handles @@ -2075,7 +2050,7 @@ public class SearchBuilder implements ISearchBuilder { From theFrom) { String latitudeValue; String longitudeValue; - Double distance = 0.0; + Double distanceKm = 0.0; if (theParam instanceof TokenParam) { // DSTU3 TokenParam param = (TokenParam) theParam; @@ -2091,7 +2066,7 @@ public class SearchBuilder implements ISearchBuilder { } QuantityParam distanceParam = myParams.getNearDistanceParam(); if (distanceParam != null) { - distance = distanceParam.getValue().doubleValue(); + distanceKm = distanceParam.getValue().doubleValue(); } } else if (theParam instanceof SpecialParam) { // R4 SpecialParam param = (SpecialParam) theParam; @@ -2108,7 +2083,7 @@ public class SearchBuilder implements ISearchBuilder { if (parts.length >= 3) { String distanceString = parts[2]; if (!isBlank(distanceString)) { - distance = Double.valueOf(distanceString); + distanceKm = Double.valueOf(distanceString); } } } else { @@ -2117,22 +2092,27 @@ public class SearchBuilder implements ISearchBuilder { Predicate latitudePredicate; Predicate longitudePredicate; - if (distance == 0.0) { + if (distanceKm == 0.0) { latitudePredicate = theBuilder.equal(theFrom.get("myLatitude"), latitudeValue); longitudePredicate = theBuilder.equal(theFrom.get("myLongitude"), longitudeValue); - } else if (distance < 0.0) { - throw new IllegalArgumentException("Invalid " + Location.SP_NEAR_DISTANCE + " parameter '" + distance + "' must be >= 0.0"); + } else if (distanceKm < 0.0) { + throw new IllegalArgumentException("Invalid " + Location.SP_NEAR_DISTANCE + " parameter '" + distanceKm + "' must be >= 0.0"); } else { - // FIXME KHS scale distance based on lat/long - Double latitude = Double.valueOf(latitudeValue); + Double latitudeDegrees = Double.valueOf(latitudeValue); + Double longitudeDegrees = Double.valueOf(longitudeValue); + + Point northPoint = CoordCalculator.findTarget(latitudeDegrees, longitudeDegrees, 0.0, distanceKm); + Point eastPoint = CoordCalculator.findTarget(latitudeDegrees, longitudeDegrees, 90.0, distanceKm); + Point southPoint = CoordCalculator.findTarget(latitudeDegrees, longitudeDegrees, 180.0, distanceKm); + Point westPoint = CoordCalculator.findTarget(latitudeDegrees, longitudeDegrees, 270.0, distanceKm); + latitudePredicate = theBuilder.and( - theBuilder.greaterThanOrEqualTo(theFrom.get("myLatitude"), latitude - distance), - theBuilder.lessThanOrEqualTo(theFrom.get("myLatitude"), latitude + distance) + theBuilder.greaterThanOrEqualTo(theFrom.get("myLatitude"), southPoint.getLatitude()), + theBuilder.lessThanOrEqualTo(theFrom.get("myLatitude"), northPoint.getLatitude()) ); - Double longitude = Double.valueOf(longitudeValue); longitudePredicate = theBuilder.and( - theBuilder.greaterThanOrEqualTo(theFrom.get("myLongitude"), longitude - distance), - theBuilder.lessThanOrEqualTo(theFrom.get("myLongitude"), longitude + distance) + theBuilder.greaterThanOrEqualTo(theFrom.get("myLongitude"), westPoint.getLongitude()), + theBuilder.lessThanOrEqualTo(theFrom.get("myLongitude"), eastPoint.getLongitude()) ); } Predicate singleCode = theBuilder.and(latitudePredicate, longitudePredicate); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/CoordCalculator.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/CoordCalculator.java index 52fd8f4b307..200b0c2f249 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/CoordCalculator.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/util/CoordCalculator.java @@ -1,13 +1,24 @@ package ca.uhn.fhir.jpa.util; -import org.springframework.data.geo.Point; + +import org.hibernate.search.spatial.impl.Point; public class CoordCalculator { - public static Point findTarget(double theLatitude, double theLongitude, double theBearing, double theDistance) { - double x; - double y; - x = theLatitude; - y = theLatitude; - return new Point(x, y); + public static final double RADIUS_EARTH_KM = 6378.1; + + public static Point findTarget(double theLatitudeDegrees, double theLongitudeDegrees, double theBearingDegrees, double theDistanceKm) { + + double latitudeRadians = Math.toRadians(theLatitudeDegrees); + double longitudeRadians = Math.toRadians(theLongitudeDegrees); + double bearingRadians = Math.toRadians(theBearingDegrees); + double distanceRadians = theDistanceKm / RADIUS_EARTH_KM; + + double targetLatitude = Math.asin( Math.sin(latitudeRadians) * Math.cos(distanceRadians) + + Math.cos(latitudeRadians) * Math.sin(distanceRadians) * Math.cos(bearingRadians)); + + double targetLongitude = longitudeRadians + Math.atan2(Math.sin(bearingRadians) * Math.sin(distanceRadians) * Math.cos(latitudeRadians), + Math.cos(distanceRadians)-Math.sin(latitudeRadians) * Math.sin(targetLatitude)); + + return Point.fromDegrees(Math.toDegrees(targetLatitude), Math.toDegrees(targetLongitude)); } } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchNoFtTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchNoFtTest.java index a692154f99b..eb6a2a50ee2 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchNoFtTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchNoFtTest.java @@ -7,6 +7,7 @@ import ca.uhn.fhir.jpa.searchparam.SearchParamConstants; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum; import ca.uhn.fhir.jpa.searchparam.registry.SearchParamRegistryImpl; +import ca.uhn.fhir.jpa.util.CoordCalculatorTest; import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.TemporalPrecisionEnum; @@ -3476,8 +3477,8 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { @Test public void testNearSearchDistanceNoDistance() { Location loc = new Location(); - double latitude = 1000.0; - double longitude = 2000.0; + double latitude = CoordCalculatorTest.LATITUDE_CHIN; + double longitude = CoordCalculatorTest.LONGITUDE_CHIN; Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude); loc.setPosition(position); String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue(); @@ -3494,8 +3495,8 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { @Test public void testNearSearchDistanceZero() { Location loc = new Location(); - double latitude = 1000.0; - double longitude = 2000.0; + double latitude = CoordCalculatorTest.LATITUDE_CHIN; + double longitude = CoordCalculatorTest.LONGITUDE_CHIN; Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude); loc.setPosition(position); String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue(); @@ -3514,30 +3515,31 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { @Test public void testNearSearchApproximate() { Location loc = new Location(); - double latitude = 1000.0; - double longitude = 2000.0; + double latitude = CoordCalculatorTest.LATITUDE_UHN; + double longitude = CoordCalculatorTest.LONGITUDE_UHN; Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude); loc.setPosition(position); String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue(); { // In the box - double offset = 50.0; + double bigEnoughDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN * 2; SearchParameterMap map = myMatchUrlService.translateMatchUrl( "Location?" + - Location.SP_NEAR + "=" + (latitude + offset) + ":" + (longitude - offset) + + Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + ":" + CoordCalculatorTest.LONGITUDE_CHIN + "&" + - Location.SP_NEAR_DISTANCE + "=" + (offset * 2) + "|http://unitsofmeasure.org|km", myFhirCtx.getResourceDefinition("Location")); + Location.SP_NEAR_DISTANCE + "=" + bigEnoughDistance + "|http://unitsofmeasure.org|km", myFhirCtx.getResourceDefinition("Location")); List ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map)); assertThat(ids, contains(locId)); } { // Outside the box - double offset = 50.0; + double tooSmallDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN / 2; + SearchParameterMap map = myMatchUrlService.translateMatchUrl( "Location?" + - Location.SP_NEAR + "=" + (latitude + offset) + ":" + (longitude - offset) + + Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + ":" + CoordCalculatorTest.LONGITUDE_CHIN + "&" + - Location.SP_NEAR_DISTANCE + "=" + (offset / 2) + "|http://unitsofmeasure.org|km", myFhirCtx.getResourceDefinition("Location")); + Location.SP_NEAR_DISTANCE + "=" + tooSmallDistance + "|http://unitsofmeasure.org|km", myFhirCtx.getResourceDefinition("Location")); List ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map)); assertThat(ids.size(), is(0)); diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java index b2688375f1c..dc7df9d4a20 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java @@ -15,6 +15,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum; +import ca.uhn.fhir.jpa.util.CoordCalculatorTest; import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.TemporalPrecisionEnum; @@ -4146,8 +4147,8 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { @Test public void testNearSearchDistanceNoDistance() { Location loc = new Location(); - double latitude = 1000.0; - double longitude = 2000.0; + double latitude = CoordCalculatorTest.LATITUDE_CHIN; + double longitude = CoordCalculatorTest.LATITUDE_CHIN; Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude); loc.setPosition(position); String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue(); @@ -4164,8 +4165,8 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { @Test public void testNearSearchDistanceZero() { Location loc = new Location(); - double latitude = 1000.0; - double longitude = 2000.0; + double latitude = CoordCalculatorTest.LATITUDE_CHIN; + double longitude = CoordCalculatorTest.LATITUDE_CHIN; Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude); loc.setPosition(position); String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue(); @@ -4192,36 +4193,36 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test { @Test public void testNearSearchApproximate() { Location loc = new Location(); - double latitude = 1000.0; - double longitude = 2000.0; + double latitude = CoordCalculatorTest.LATITUDE_UHN; + double longitude = CoordCalculatorTest.LONGITUDE_UHN; Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude); loc.setPosition(position); String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue(); { // In the box - double offset = 50.0; + double bigEnoughDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN * 2; SearchParameterMap map = myMatchUrlService.translateMatchUrl( "Location?" + - Location.SP_NEAR + "=" + (latitude + offset) + "|" + - (longitude - offset) + "|" + - (offset * 2) + "|km", - myFhirCtx.getResourceDefinition("Location")); + Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + "|" + + CoordCalculatorTest.LONGITUDE_CHIN + "|" + + bigEnoughDistance, myFhirCtx.getResourceDefinition("Location")); List ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map)); assertThat(ids, contains(locId)); } { // Outside the box - double offset = 50.0; + double tooSmallDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN / 2; + SearchParameterMap map = myMatchUrlService.translateMatchUrl( "Location?" + - Location.SP_NEAR + "=" + (latitude + offset) + "|" + - (longitude - offset) + "|" + - (offset / 2) + "|km", - myFhirCtx.getResourceDefinition("Location")); + Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + "|" + + CoordCalculatorTest.LONGITUDE_CHIN + "|" + + tooSmallDistance, myFhirCtx.getResourceDefinition("Location")); List ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map)); assertThat(ids.size(), is(0)); } + } private String toStringMultiline(List theResults) { diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/util/CoordCalculatorTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/util/CoordCalculatorTest.java index 8fe9c86eb09..a2ef5694898 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/util/CoordCalculatorTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/util/CoordCalculatorTest.java @@ -1,20 +1,28 @@ package ca.uhn.fhir.jpa.util; +import org.hibernate.search.spatial.impl.Point; import org.junit.Test; -import org.springframework.data.geo.Point; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; public class CoordCalculatorTest { - @Test - public void testCoordCalculator() { - double latitude = 52.20472; - double longitude = 0.14056; - double bearing = 1.57; - double distance = 15.0; + private final Logger ourLog = LoggerFactory.getLogger(CoordCalculatorTest.class); + // CHIN and UHN coordinates from Google Maps + // Distance and bearing from https://www.movable-type.co.uk/scripts/latlong.html + public static final double LATITUDE_CHIN = 43.65513; + public static final double LONGITUDE_CHIN = -79.4170007; + public static final double LATITUDE_UHN = 43.656765; + public static final double LONGITUDE_UHN = -79.3987645; + public static final double DISTANCE_KM_CHIN_TO_UHN = 1.478; + public static final double BEARING_CHIN_TO_UHN = 82 + (55.0 / 60) + (46.0 / 3600); - Point result = CoordCalculator.findTarget(latitude, longitude, bearing, distance); - assertEquals(52.20444, result.getX(), 0.00001); - assertEquals(0.36056, result.getX(), 0.00001); + @Test + public void testCHINToUHN() { + Point result = CoordCalculator.findTarget(LATITUDE_CHIN, LONGITUDE_CHIN, BEARING_CHIN_TO_UHN, DISTANCE_KM_CHIN_TO_UHN); + + assertEquals(LATITUDE_UHN, result.getLatitude(), 0.0001); + assertEquals(LONGITUDE_UHN, result.getLatitude(), 0.0001); } } diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java index 6c0ecb4c10c..dde87076aaf 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java @@ -315,7 +315,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor IExtractor extractor = (params, searchParam, value, path) -> { if ("Location.position".equals(path)) { - addCoords_Position(resourceTypeName, params, searchParam, value); + addCoords_Position(resourceTypeName, params, searchParam, value); } }; @@ -741,6 +741,10 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor org.hl7.fhir.r4.model.Location.LocationPositionComponent value = (org.hl7.fhir.r4.model.Location.LocationPositionComponent) theValue; latitude = value.getLatitude(); longitude = value.getLongitude(); + } else if (theValue instanceof org.hl7.fhir.r5.model.Location.LocationPositionComponent) { + org.hl7.fhir.r5.model.Location.LocationPositionComponent value = (org.hl7.fhir.r5.model.Location.LocationPositionComponent) theValue; + latitude = value.getLatitude(); + longitude = value.getLongitude(); } // We only accept coordinates when both are present if (latitude != null && longitude != null) {