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 b5f0b180829..fadecd6a8be 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 @@ -2111,22 +2111,37 @@ public class SearchBuilder implements ISearchBuilder { } latitudeValue = parts[0]; longitudeValue = parts[1]; + if (isBlank(latitudeValue) || isBlank(longitudeValue)) { + throw new IllegalArgumentException("Invalid position format '" + value + "'. Both latitude and longitude must be provided."); + } } else { throw new IllegalArgumentException("Invalid position type: " + theParam.getClass()); } - Predicate latitude = null; - if (!isBlank(latitudeValue)) { - latitude = theBuilder.equal(theFrom.get("myLatitude"), latitudeValue); + QuantityParam distanceParam = myParams.getNearDistanceParam(); + Predicate latitudePredicate; + Predicate longitudePredicate; + if (distanceParam == null) { + latitudePredicate = theBuilder.equal(theFrom.get("myLatitude"), latitudeValue); + longitudePredicate = theBuilder.equal(theFrom.get("myLongitude"), longitudeValue); + } else { + // FIXME KHS suppress hash + Double distance = distanceParam.getValue().doubleValue(); + if (distance < 0.0) { + throw new IllegalArgumentException("Invalid " + Location.SP_NEAR_DISTANCE + " parameter '" + distance + "' must be >= 0.0"); + } + Double latitude = Double.valueOf(latitudeValue); + latitudePredicate = theBuilder.and( + theBuilder.greaterThanOrEqualTo(theFrom.get("myLatitude"), latitude - distance), + theBuilder.lessThanOrEqualTo(theFrom.get("myLatitude"), latitude + distance) + ); + Double longitude = Double.valueOf(longitudeValue); + longitudePredicate = theBuilder.and( + theBuilder.greaterThanOrEqualTo(theFrom.get("myLongitude"), longitude - distance), + theBuilder.lessThanOrEqualTo(theFrom.get("myLongitude"), longitude + distance) + ); } - - Predicate longitude = null; - if (!isBlank(longitudeValue)) { - longitude = theBuilder.equal(theFrom.get("myLongitude"), longitudeValue); - } - - Predicate singleCode = theBuilder.and(latitude, longitude); - + Predicate singleCode = theBuilder.and(latitudePredicate, longitudePredicate); return combineParamIndexPredicateWithParamNamePredicate(theResourceName, theParamName, theFrom, singleCode); } 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 1020c0c79e1..9cc64412461 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 @@ -3505,12 +3505,6 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { "&" + Location.SP_NEAR_DISTANCE + "=" + (offset * 2) + "|http://unitsofmeasure.org|km", myFhirCtx.getResourceDefinition("Location")); - // FIXME KHS -// new SearchParameterMap(); -// map.add(Location.SP_NEAR, new TokenParam()); -// QuantityParam distance = new QuantityParam(ParamPrefixEnum.LESSTHAN_OR_EQUALS, ); -// map.add(Location.SP_NEAR_DISTANCE, distance); - List ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map)); assertThat(ids, contains(locId)); }