cms
cms copied to clipboard
Support distance calculation and limits in address queries
Description
Proof-of-concept for distance queries for addresses, as suggested in https://github.com/craftcms/cms/discussions/17227
The PR adds a AddressQuery::distanceTo() method to calculate the distance of an address to a given place, limit the query by minimum and/or maximum distance, and order results by distance.
Usage:
{# Calculate the distance to the given coordinates, and order the results by distance. #}
{% set addresses = craft.addresses()
.distanceTo({
latitude: 50.93515,
longitude: 6.936852,
})
.orderBy('distance ASC')
.all()
%}
{# Calculate the distance to the given coordinates, and only
# returns results with a distance between 10 and 50 kilometers.
#}
{% set addresses = craft.addresses()
.distanceTo({
latitude: 50.93515,
longitude: 6.936852,
min: 10000,
max: 50000,
})
.all()
%}
Definitely more of a proof of concept, there are a couple of things left to do:
- [ ] The code is only tested with MySQL (requires 8+), will probably need some adjustments for PostgreSQL.
- [ ] Align more closely with Craft coding standards
- [ ] Add better validation and error handling for invalid inputs to the
distanceTo()function - [ ] The
distanceproperty will be a float representing the distance in meters, andminandmaxexpect a distance in meters as well. Might want to support both metric and imperial units? - [ ] A filter to turn the
distanceproperty into a localized string (similar to themoneyordatefilters) would be helpful. - [ ] Is it really necessary to add all conditions to both the
queryandsubQuery? I don't completely understand this, but in my testing, adding the conditions only to the main query resulted in incorrect results, especially with pagination.
Related issues
https://github.com/craftcms/cms/discussions/17227