As a follow up of the requests raised from this original issue: Re-implement the Views proximity filter/field for Drupal 8,
the attached patch implements a new solid, scalable and extensible Geofield Proximity System, composed by the following plugins handlers:

  • View Proximity Filter (\Drupal\geofield\Plugin\views\filter\GeofieldProximityFilter);
  • View Proximity Field (\Drupal\geofield\Plugin\views\field\GeofieldProximityField);
  • View Proximity Sort (\Drupal\geofield\Plugin\views\sort\GeofieldProximitySort);

These Views Proximity Handlers mainly extend the correspondent Numeric Views handlers, and are able to calculate the distance between every view results’ geofield and a geo origin, whose definition is driven by a dependent scalable Geofield Proximity Sources plugins sub-system.

As a whole, this Geofield Proximity View Handlers System is fully Drupal 8 plugins system compliant, so that is should be considered extensible/scalable with new specialized plugins by everybody.

The patch here attached allows the following main initial functionalities:

View Proximity Filter
The user is able to:

  • add a geofield proximity filter (or more than one);
  • define a criteria of selection based on a specific operator, a Distance or a Distance Interval (min and max value), and different distance Units (km, meters, yards, miles, etc);
  • choose the Origin definition among the Proximity Sources options. At the moment the following have been defined:
  • Manual Origin (Default): manual input of Latitude and Longitude;
  • Geofield Fixed Origin (for Demo purposes)
  • make the geofield proximity filter exposed, exposing both the Distance and the Origin specific input;
  • add (or hide) the specific description defined for the Proximity Source in the exposed form;
  • enjoy exposed geofield proximity filter functionalities also with Ajax, if enabled;

View Proximity Field
The user is able to:

  • add a geofield proximity fileld (or more than one), able to calculate and render a Distance (with specific Units) for every results’ geofield and a specific Origin definition, among one of the followings:
  • Manual Origin (Default): manual input of Latitude and Longitude;
  • Origin from Proximity Filter: dynamic and automatic input of the Origin coordinates from an existing Proximity Filter Origin (this will dinamically change accordingly to the Proximity Filter Origin, also when it is exposed);
  • define the specific format of the Proximity field, as a normal Numeric field;
  • enjoy the dynamic change of the geofield proximity field with Ajax, if enabled;
  • make it click - sortable in the Table format;

View Proximity Sort
The user is able to:

  • add a Geofield Proximity Sort, that adds a Sort Order based on Proximity Distance (with specific Units) calculated for every results’ geofield from a specific Origin definition, among one of the followings:
  • Manual Origin (Default): manual input of Latitude and Longitude;
  • Origin from Proximity Filter: dynamic / automatic input of the Origin coordinates from an existing Proximity Filter Origin (this will dinamically change accordingly to the Proximity Filter Origin, also when it is exposed);
  • define the specific order (Desc or Asc) for the Proximity sort;

Comments

itamair created an issue. See original summary.

itamair’s picture

Issue summary: View changes
itamair’s picture

Issue summary: View changes
itamair’s picture

Issue summary: View changes
itamair’s picture

Here is the announced patch, for your (users & contributors) review.
Let's keep here for a while, to acquire eventual suggestions, further features requests and bugs reports.
Also some new Proximity Sources plugins might be implemented and added.
Once properly reviewed will be committed into dev and into the new Geofield module release.

itamair’s picture

Issue summary: View changes
itamair’s picture

Issue summary: View changes
itamair’s picture

Actually, in this task implementation (expressed by the attached patch) there is a unique known bug that I couldn't solve/fix.
When a Geofield Proximity Handler (Filter, Field, or Sort) is chosen in the pop window, and the user tries to change a specific Proximity Source option different from the default one (Manual Origin) the Ajax reaction seems to be triggered (with the throbber rotating) but the Submit Form is triggered instead, causing (without any log) the Pop Window to close and the Proximity Handler being added with default / empty options ...
It would be great is somebody, very skilled, or properly inspired would be able to find a proper fix to this ... ;-)

rlmumford’s picture

Status: Needs review » Needs work

I'm having alot of trouble getting this filter working, for a start the origin doesn't work when it is exposed.

itamair’s picture

@rlmumford what do you mean exactly? May you better describe your use case, so that it can be reproduced?
What does it means this "for a start the origin doesn't work when it is exposed"?
Do you have any application error, or the filter just doesn't apply correctly?
Bear in mind that if the Origin (lat, lon) is not a correct one, or the distance is NULL or zero it will simply throw an exception and a written log ... and the filter won't apply in the view results.
Please some more detail on this ...

itamair’s picture

StatusFileSize
new85.33 KB

Here is a new updated patch, with better Exposed Form Elements validation.
Please apply and test this upon the last 8.x-1.x-dev.

itamair’s picture

Status: Needs work » Needs review
adamps’s picture

Many thanks @itamair. I tested the patch and it seems good in general. I recommend it for commit to dev as it doesn't break anything, and that will make it easier for everyone to test it. (I didn't review the code - I don't really know enough about the module to do that.)

Here's what didn't work as I expected:

  1. The pager doesn't work for me when I have a proximity filter and sort based on exposed manual origin. When I navigate to another page the query parameters for the proximity filter get corrupted.
  2. In the proximity filter settings page, the form requires a value for "Distance" and "Origin Coordinates". However they should be optional for an exposed filter.
  3. On the view itself, if you leave the proximity filter distance field blank, there is an error "The Distance value is not valid.". I would expect blank to be allowed unless the filter is required, in which case the error should say that the field is required.
  4. I couldn't find any way to set an origin point by geocoding the manual input which was possible in D7 and an important case. I guess that's still to do - is it worth raising a separate issue for it?
  5. The query parameters for the proximity filter are rather long with lots of brackets. However maybe that's unavoidable.
  6. In the settings for "Proximity Definition Mode", the value "Origin from Proximity Filter." should not have a period/full-stop at the end.
  7. I do see the problem you describe in #8. However after hitting the bug if I edit the field it works fine, so it's usable.
itamair’s picture

Thanks to you @AdamPS for the extended and very helpful review.
I will now try to fix all the raised matters and then commit into dev only when we reach a robust patch (not before).
Some of them are more structural ... and might take more time.

Just a question about this (you wrote):

2. In the proximity filter settings page, the form requires a value for "Distance" and "Origin Coordinates". However they should be optional for an exposed filter.

Why this? Actually invalid values (like NULL, or 0 for the distance value) would break the proximity filter query ...
and output error (exceptions) and bad/inconsistence results.
Why an exposed filter form shouldn't have constraints on them?. What results should we expect with a NULL or 0 value for the distance???
As usual., the whole view should be the results of all the exposed form elements, as chained as AND conditions, isn't ?

adamps’s picture

Thanks @itamair. I believe what I am suggesting is the same as the way that the core filters work, for example see /admin/people. There are multiple exposed filters and none of them has a default value. The user can leave them all blank or set one, or set many.

Actually invalid values (like NULL, or 0 for the distance value) would break the proximity filter query ...

I agree that it is important to ensure that any value given is valid. My point is that an empty value should be considered valid in the filter settings page for an exposed filter.

What results should we expect with a NULL or 0 value for the distance???

Except in the case where a filter is marked as 'required' in the view settings, then the user is allowed to leave a filter blank, and the filter will be ignored.

At the moment the site admin is forced to specify an origin, but normally there is no natural default so it will be an arbitrary origin. The user is then forced to delete this arbitrary value and either replace it or leave it blank.

droprocker’s picture

First of all: Thanks so much for making this work!

I've done a little testing and my results are quite the same as the one from AdamPS in #13. Especially 2. and 3. are important issues. I do expect, as a user, that exposed filters are optional. As AdamPS described in #15, I also think this is the way as it should work. If the filter is not filled, it is simply ignored. Like it is default behaviour of exposed filters.

For the moment I have one additonal issue:
1. Allow also "comma" as decimal separator, since this is used in some countries.

I also tested it with rest endpoints and it works as expected. Nice! One comment on that:
Is it possible to override the default query parameters? Since they are quite long and hard to read, it would be nice if I could define my own alias.

Example:
Set "field_geofield_proximity[source_configuration][origin][lat]" to "lat"

One more thing. I applied the patch to the latest beta version (beta5), because I couldn't change to the dev version of geofield module because the geofield map module requires a beta version of this module. Is this right or just my incompetence? ;-)

itamair’s picture

Good ok ... I will tune on your last clarifications, and requirements.

At the moment I will focus on (these) more urgent tasks, and also the Pager breaks.

The following will be faced afterwords, with possibly integrating patches (because more demanding):

1 -

- The query parameters for the proximity filter are rather long with lots of brackets / Is it possible to override the default query parameters? Since they are quite long and hard to read, it would be nice if I could define my own alias.

Those represents the Nested (TREE) structure of the Proximity Value & Origin Options form. They match the structure of this kind of proximity exposed filter options tree. Change and customize it? well ... Would need a further effort (of investigation) and implementation ... that I actually I cannot allocate further.

2

Allow also "comma" as decimal separator, since this is used in some countries.

The Manual Origin (Default) Source Plugin is using the GeofieldLatLon (geofield_latlon) native element, whose component are validated upon the is_numeric php function. So a comma format is not passed ...
An intermediate check/validate, to transform the comma format into a dot format should be added in this case eventually in the more General Geofield Lat Lon Widget Validate ... Let's see if it will be worth to be done.

Cheers. Stay tuned ...

itamair’s picture

StatusFileSize
new88.18 KB

Hi folks ... I brought on the work, basing it on the last reviews from @AdamPS and @der_wilko ...
And here is the result in a new patch attached, that applies into dev and that overrides the provious.
I would say that all has been accomplished, but the following considerations should be kept in mind:

- The pager doesn't work due to this Drupal 8 core issue: Views pager links incorrectly handle exposed filters that allow multiple numeric values.
This related patch should fix it: https://www.drupal.org/project/drupal/issues/2897694#comment-12597510
(it works for me into the proximity filter. Please that works with the sort too ...)

- Yes. The query parameters for the proximity filter are rather long with lots of brackets, and this is unavoidable, because is the way for the Drupal exposed form way of working ... (you can verify that the previous point issue deals with the same kind of long and nested query parameters);

- All the constraints and previous validations both on the value, min, max and origin (lat, lon) have been removed. The exposed filter on them should be simply bypassed (and only watchdog logs will be written to trace impossibility of proximity origin and values processing);

- The Lat and the Lon fields comply to the usual Geofield module LatLon element, whose db schema and usual format is based on the . separator. Similarly the comma cannot be admitted for the proximity views handlers functionalities (too long work would be needed to extend the module o this, and should be done on the whole Geofield, eventually);

- A new "Client Location Origin" GeofieldProximitySource plugin has been added, that should autofill the Origin with the Client / User HTML Geolocation position. Try it and review its functionalities, please ...

- yes, there isn't any way to set an origin point by geocoding the manual input (which was possible in D7).
I agree this might be an important case. But this is not coming easily as a gift, by itself. It would need at least a Geocoder, and the easiest Geocoder implementation would be the google js one ... But this would in Geofield a new unnatural dependency / management from a Google Maps API key, that is not both the case and that might overlap with Geofield Map (that is dependent form Geofield).
The best solution on this (IMO) would be to create integration / dependency from the D8 Geocoder module and a specific Service / endpoint (and configuration) through which manage a Geofield Geocoding proximity source plugin. May be this plugin might be better added into the Geocoder module instead. Indeed a new specific Issue should be opened to discus and implement all this ...

Please review all this. Thanks ...

itamair’s picture

A better refactoring of the 'Geofield Client Location Origin' plugin ...
Please use this last patch instead.

adamps’s picture

Thanks again @itamair. The new version mostly looks good and "Client Location Origin" is a great idea. I have pasted the list from my previous comment at the bottom with answers to each point and I raised two new issues.

New comments

  1. I'm still not sure about the validation. In the view configuration if I leave the manual origin blank I now get an exception and red error message. As in #15 I believe filters in Drupal 8 work like this:
    • Both view configuration and exposed form should have validation. Don't allow the form to be submitted if the value is not valid and don't throw an exception.
    • View configuration: if the filter is exposed, then blank is a valid value else blank is not valid.
    • Exposed form: blank is a valid value, and it means do not filter.
  2. In the view configuration after selecting "Client Location Origin" should hide "Origin Coordinates" and "Hide the Origin Input elements from the Exposed Form".
  3. Don't request the browser location on the view configuration, but instead request it to the user of the view.
  4. When the view configuration pop-up is opened, "Show (anyway) the Origin coordinates as summary in the Exposed Form" your code to hide it should run (it doesn't run unless the other value changes).
  5. The Summary Description "Allow the Manual input of Distance and Origin (as couple of Latitude and Longitude in decimal degrees.)". would work well to show in the view configuration. However as written it's not really suited to show to the user of the view.
  6. I'm not sure that "Geofield Fixed Origin" is useful on an a site. When configuring a view it can be confusing as it's similar to "Manual Origin". Maybe remove this, or move it do a separate sub-module as example code?

Original review

  1. CORE BUG: The pager doesn't work on proximity filter #2897694: Views pager links incorrectly handle complex exposed filters.
  2. STILL BROKEN In the proximity filter settings page, the form requires a value for "Distance" and "Origin Coordinates". However they should be optional for an exposed filter.
  3. FIXED: On the view itself, if you leave the proximity filter distance field blank, there is an error "The Distance value is not valid.". I would expect blank to be allowed unless the filter is required, in which case the error should say that the field is required.
  4. SEPARATE ISSUE I couldn't find any way to set an origin point by geocoding the manual input which was possible in D7 and an important case #3014737: Geofield Geocoding proximity source plugin
  5. CAN'T BE FIXED The query parameters for the proximity filter are rather long with lots of brackets.
  6. FIXED In the settings for "Proximity Definition Mode", the value "Origin from Proximity Filter." should not have a period/full-stop at the end.
  7. SEPARATE ISSUE I do see the problem you describe in #8. However after hitting the bug if I edit the field it works fine, so it's usable. #3014744: Ajax problem adding proximity handlers
itamair’s picture

thanks @AdamPS ... working on this and related fixes. Will come back with update asap

itamair’s picture

Status: Needs review » Needs work
itamair’s picture

Hi folks ... this is becoming really demanding, but it's worth to don't give up.
I hope we reached a first final commit state now.
Here is a further updating patch (that overrides the previous and apply to actual dev) where I really refined the proximity handlers, and better tuned the new/last "Client Location Origin" to behave as @AdamPS highlighted should better do. Actually, due to its nature, because it is relying on the HTML5 Geolocation API and might work only acting on a front end form, I had to force and limit it as a Proximity Filter Source handler available ONLY if exposed.
Other similar cases, such as User/Client Source location on an unexposed filter, and Field and Sort Proximity calculation would & might be implemented with more complex types Geocoding solutions (probably server side), quite similarly to the Manual Address input that has been already mentioned (and postponed) above.

Please review and let me know if this patch initial and valuable functionalities are ok, and might be finally committed into dev,
as a first geofield proximity functionality baseline system. (would be a great starting result itself).

itamair’s picture

Status: Needs work » Needs review
adamps’s picture

Status: Needs review » Reviewed & tested by the community

Excellent work @itamair, many thanks for your hard work to help the Drupal community. I tested thoroughly and did not find any bugs.

Reminder for anyone using this feature these issues are still open:

  • itamair committed 8fc900b on 8.x-1.x
    Issue #3012750 by itamair: (New) Drupal 8 Geofield Proximity View (Field...
itamair’s picture

itamair’s picture

itamair’s picture

itamair’s picture

Thanks @AdamPS for your reviewing ... I loved this way of working and contributing on this.
Committed into dev and also in a brand new 8.x-1.0-beta6 release ...

itamair’s picture

Status: Reviewed & tested by the community » Fixed
adamps’s picture

Thank you @itamair I enjoyed it too. I will be away from Drupal.org for Dec/Jan, but sometime after that if you are keen to work on the geocoder proximity plugin issue then we can do it the same way.

itamair’s picture

sure

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

rafaticarte’s picture

Hi,

I have a content type with a geofield. I want to have a block that It shows nearby nodes from current node.

How can I use Contextual filter to obtain current geofield fron URL?

Is It posible?

Thanks in advance.

itamair’s picture

Syntapse’s picture

Does post need updating to include contextual filter functionality: https://www.drupal.org/project/geofield/issues/3149688

I raised an issue with the documentation here: https://www.drupal.org/project/geofield/issues/3211147

ressa’s picture

Amazing feature, thanks for creating it @itamair! I wanted to add a proximity search ("Show shops close to you") and wasn't sure if I needed another module ... but when I looked under "Filter criteria" in my View, there it was:

"Geofield Proximity"

This is a killer feature, which in my opinion deserves a prominent place on the https://www.drupal.org/project/geofield project description. Both to alert users scanning the module description that the feature exists, but also to allow it to get found via search engines.

Maybe add a new section, right below "Formatters (Data Output)"?

Proximity Views filter (Field, Filter and Sort)

Supports proximity filter in Views, to limit data by proximity, calculate and sort by distance, and much more. Supports client Location through the browser HTML5 Geolocation API. For more, see the documentation.

I created a guide for Geofield under https://www.drupal.org/docs/extending-drupal/contributed-modules/contrib... and used the the features listed on #3012750: (New) Drupal 8 Geofield Proximity View (Field, Filter and Sort) Handlers System to create a new Proximity search page in the documentation, to be able to link to that.