This patch adds another Views filter plugin which extends (subclasses) the existing geofieldProximityGeocoder class, so that instead of inputting a postal address the visitor may leave the field blank to filter the View on locations within the entered distance from the visitor's CURRENT LOCATION.

See the screenshot, where the filter was used to filter a View Page (map) + View Attachment (the table underneath, reflecting the map).
in the map the green marker represents the visitor's current location, while the remaining markers are the locations after the filter was applied, with a radius (distance) of 1.5 km.

Geofield HTML5 based proximity filtering

For HTML5 location retrieval this patch relies on IP Geolocation Views and Maps.
The module uses Smart IP as a fallback, executing an IP address lookup, if the HTML5 (satellite and WiFi) based location retrieval fails.
That same module also produces the map in the screen shot and the configurable markers.

Apply the patch against the 7.x-2.x branch, using the attached .patch file as normal.
Then also drop the new file geofieldProximityGeocoderWithHTML5.txt in sites/all/geofield/views/proximity_plugins, changing its extension from .txt to .inc

Don't forget to execute /update.php before configuring your VIew.

Comments

RdeBoer’s picture

Issue summary:View changes

formatting

RdeBoer’s picture

Title:Patch adding plugin for proximity filtering based postal address with HTML5 as default» Geofield plugin to extend proximity filtering based on postal address with option to use HTML5 location
Status:Active» Patch (to be ported)

PS1: naturally, if in addition to a distance figure (the 1.5 km in the example above) the user DOES type a street address or partial street address (e.g. just "Melbourne"), then this new plugin falls back to the old geofieldProximityGeocoder behaviour.

PS2: the above setup requires the Geocoder module

PS3: You can use the "Refine location via street address" block from the "IP Geolocation Views and Maps" module to display the visitor's reverse geocoded HTML5 position. That is the street address where the system believes the visitor is located, based on the latitude/longitude coordinates the browser/device received via satellite and/or WiFi.

nicoz’s picture

I have done some testing and it seems to be working really well so far. Rik, I have PM'd you with a link so you can see your work out there in the wild.

Brandonian’s picture

Status:Patch (to be ported)» Needs review

Nice! At a glance, looks good, I'll take a look later to provide notes/commit.

RdeBoer’s picture

@Brandonian #3:

Some notes from me:
The plugin as it is has a conditional dependency on "IP Geolocation Views and Maps", via if (module_exists('ip_geoloc')) { ... .
This is a quick fix that works, but isn't great architecturally.

This could be improved by having Geofield expose a hook that allows other modules to pass in lat/lon of the default point of interest, be it the visitor's current location or an externally geocoded street address. That hook may also be used in existing or future sections of Geofield code. I for one would love to take advantage of it in a proximity CONTEXTUAL filter for Geofield, which could then be driven by Views Global Filter. This is functionality that already exists between Views Global Filter and the Location module.

Alternatively, using a hook or CTools plugin approach the proximity plugin system in Geofield could be made more extensible, so that the above geofieldProximityGeocoderWithHTML5.inc plugin could live in the IPGV&M module. This is pretty much what was requested here also: #1991828: Provide a hook_proximity_views_handlers such that other modules can implement a proximity_views_handler.

Rik

SocialNicheGuru’s picture

after applying this, I did as the filter config picture says.

I get this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'A' in 'where clause'

part of the views query:
AND (( A * ACOS( COS( RADIANS(45.3101717) ) * COS( RADIANS(field_data_field_geofield.field_geofield_lat) ) * COS( RADIANS(field_data_field_geofield.field_geofield_lon) - RADIANS(-89.0166135) ) + SIN( RADIANS(45.3101717) ) * SIN( RADIANS(field_data_field_geofield.field_geofield_lat) ) ) ) <= A) ))

RdeBoer’s picture

@SocualNicheGuru:
Have you run update.php?

nicoz’s picture

I have to say that we have been running this patch for the last few weeks without issue. @SocialNicheGuru when you get a chance, can you follow up to see if running update.php fixes your issue, so we can push this patch along?

aliciatheduff’s picture

This patch worked great for me as well, it threw an error until I ran update.php, so that might be @SocualNicheGuru issue.

GBain22’s picture

I have tried this recently and I keep getting "Visitor Location not available" - I can see this is called from the new .inc file - does this suggest something wrong with the geolocating?

nicoz’s picture

go to admin/config/system/ip_geoloc and make sure you select some user roles for which the HTML5 location may be sampled and reverse-geocoded to a street address

SocialNicheGuru’s picture

the above works. I re-installed and applied.

nicoz’s picture

Status:Needs review» Reviewed & tested by the community
funature’s picture

maybe it is better to put a "my location" button there, so that the user can easily locate to the current position anytime. just like the geolocation field widget.

mgifford’s picture

Agreed that a "My location" button would be a good prompt.

mgifford’s picture

Issue summary:View changes

mention branch to use

bneil’s picture

Re #4 RdeBoer-

Alternatively, using a hook or CTools plugin approach the proximity plugin system in Geofield could be made more extensible, so that the above geofieldProximityGeocoderWithHTML5.inc plugin could live in the IPGV&M module.

I think that's what is being requested in #2134777: Allow other modules to define their own proximity plugins which would then make it easy for this to live in IPGV&M.

camoa’s picture

I really need the "My location" Option, anyone has any idea or can point me where and how to modify the code to accomplish this?

Thanks!

JayShoe’s picture

Hello,

  • I would like to confirm that this patch works as described.
  • Feature Request to pre-populate the field with the visitor's city and state data as text.

Thanks RdeBoer this is going to help my site shine.

Jay

RdeBoer’s picture

Re #17:
That's sweet of you to say Jay!
Rik

JayShoe’s picture

Rik,

Is this going to get committed?

Jay

RdeBoer’s picture

Hi Jay,
I don't know. It's not up to me, as I'm not the maintainer of Geofield and do not have the permissions.
Brandonian may know.
Rik

jsibley’s picture

This seems like a really helpful enhancement.

Are we at all close to getting this committed?

Thanks.

jsibley’s picture

I have tried the patch, and it seems quite good but I have 2 questions:

- When the user inputs an address, the proximity field seems to provide the distance from the user, not from the address that was input

- When the user inputs an address, the map is centered on the user's location, not the location that was input

Perhaps these issues are related, and perhaps there is some user error involved?

Is there something I should be doing differently on my end?

camoa’s picture

I am getting a lot of this warning, Anyway to debug the reason for this or how to improve the location detection?

Thanks

rofsky’s picture

@jsibley have you found a solution? I also need to center the map on the input location.

jsibley’s picture

@rofsky, I haven't found a solution yet, but I might have a clue.

I don't know the internals of Drupal and of views well, but I think that the patch takes care of filters and sorting in views, but might not have patched where the actual field that gets displayed.

When I look at the SQL returned by the view and put in a location as an exposed filter, I see the values for the filter change, but the value of the field does not.

So, here is what I see for the field after I have put an address into the exposed filter:

( 3959 * ACOS( COS( RADIANS(40.813642200000004) ) * COS( RADIANS(field_collection_item_field_data_field_address_plus_phone__field_data_field_geoaddress.field_geoaddress_lat) ) * COS( RADIANS(field_collection_item_field_data_field_address_plus_phone__field_data_field_geoaddress.field_geoaddress_lon) - RADIANS(-74.21709899999999) ) + SIN( RADIANS(40.813642200000004) ) * SIN( RADIANS(field_collection_item_field_data_field_address_plus_phone__field_data_field_geoaddress.field_geoaddress_lat) ) ) ) AS field_collection_item_field_data_field_address_plus_phone__f

Here is what I see in the filter:

where ......(( 3959 * ACOS( COS( RADIANS(40.9792645) ) * COS( RADIANS(field_collection_item_field_data_field_address_plus_phone__field_data_field_geoaddress.field_geoaddress_lat) ) * COS( RADIANS(field_collection_item_field_data_field_address_plus_phone__field_data_field_geoaddress.field_geoaddress_lon) - RADIANS(-74.1165313) ) + SIN( RADIANS(40.9792645) ) * SIN( RADIANS(field_collection_item_field_data_field_address_plus_phone__field_data_field_geoaddress.field_geoaddress_lat) ) ) ) <= 10) ))

The sort uses a label from the field, so it will also be incorrect.

Unfortunately, I don't know where this would need to be changed in the code. Hope this helps, though.

Jonathan

RdeBoer’s picture

A proper, maintainable solution should be built upon a proper maintainable framework.

The patch referred to above in #15, #2134777: Allow other modules to define their own proximity plugins, sounds like a great start. It's small, easy to apply and not likely to have any side-effects. With that in place I'm happy to re-roll the above functionality with any bits relying on third-party modules, e.g. http://drupal.org/project/ip_geoloc, located there.

Rik

jsibley’s picture

Rik, are you saying that once the patch mentioned in #15 is committed, you would be willing to create a new patch with the HTML5 functionality? Would that potentially resolve the proximity field issue mentioned in #22 and #25, as well?

Also, in the meantime, do you know where the proximity calculation is defined?

Thanks!

RdeBoer’s picture

@jsibley,
Well a new patch would not automagically solve the issue. I'd have to investigate first where the bug originates, then rewrite the code and include the fix.

But the great thing about doing #15/[2134777] is that the patch would no longer have to consist of code entangled with Geofield. With #15/[2134777] in place we'd have an even more extensible, maintainable Geofield framework. Geofield is already architected very well -- this last part (or a solution similar to it) would be the icing on the cake for all of us.

Any new functionality of this kind could then added as a stand-alone mini-module or a class, and reside inside Geofield (as a separate file), IPGV&M or another module, wherever it is best suited. #2134777: Allow other modules to define their own proximity plugins already contains a lovely example of such a mini-module.

This keeps Geofield clean while making any extensions separately maintainable, so it does not burden the Geofield maintainers.

MrPeanut’s picture

Not contributing anything other than to say that this patch works incredibly well for what I'm doing. Hope to see it incorporated in one way or another!

RdeBoer’s picture

campbdy’s picture

I would love this functionality. Am not confident about applying any patches, so the sooner it gets implemented or a new module created the better. Great work folks. Will follow thread with interest.

RdeBoer’s picture

Just to say that I'm about to do some more work on this, proceeding along the lines of #28.

In the mean time, a few observations and tips in response to some of the comments above, after applying the patch (which today, still applies cleanly against the Geofield 7.x-2.x branch)

Re #22, 25 (jsibley) and #24 (rofsky) "When the user inputs an address, the proximity field seems to provide the distance from the user, not from the address that was input."
I did not find this to be true. The distance in shown in the FIELD is with respect to the location typed in the Exposed filter provided you select "Exposed Geofield Proximity Filter" as the "Source of Origin Point" for the FIELD.
For the FILTER Source of Origin Point" should be Geocoded Location with HTML5 default".

Re #22: "When the user inputs an address, the map is centered on the user's location, not the location that was input"
Yes, but you can make them one and the same by using the "Refine your location" block (enabled for the same page as the map) from module IP Geolocation Views and Maps (7.x-1.25) and entering "me" for the the Exposed filter location. The "Refine your location" block has a location input field to override the HTML5 location, which is then picked up by the Geofield exposed filter.
You can take it a step further by pressing the "Grouped filters" radio button and entering a number of distances for a drop-down, all with "me" as the location. The exposed filter then reduces to a simple drop-down with filter distances, e.g 1, 5, 10, 100 miles. There will be no text field to enter location, as the location is taken automatically from the "Refine your location" block, which produces either the HTML5 location or a typed partial address.

See this screenshot and comments https://drupal.org/node/2176513#comment-8545667. There are some suggestions in that thread for improving the UX that I'm looking at also.

You can even switch on AJAX so that there's no "Apply" button and the map refreshes automatically the moment a new filter distance is selected.

Anyway, with all that in place and some reworking of some of the texts for the blocks and filter labels it can be made quite nice, but I feel it can be better still. I'm doing some work on this now, but not sure how far I get in the time I have.

RdeBoer’s picture

Following on from the above. I've realised my ideas here: https://drupal.org/node/2176513#comment-8731579.

Requires this simple patch to Geofield: https://drupal.org/node/2134777#comment-8731227
I hope Brandonian or one of the other committers can apply it soon.

jsibley’s picture

This seems great, but I'm confused about which versions (dev, patched, downloaded version of a customized module) of geofield and ip geolocation now represent the "latest and greatest" (html5 default, refine location block, etc.)

With the various issues and patches adding functionality, I'm unclear what I should be using now.

Thanks!

RdeBoer’s picture

@jsibley, #34

Yes it has become confusing this thread, hasn't it?
Now that the dust has settled, go with:

o Geofield 7.x-2.x branch (https://drupal.org/node/1360636, 17 Nov 2013), with this patch applied: https://drupal.org/node/2134777#comment-8823463
o IPGV&M 7.x-1.x branch, e.g. 7.x-1.x-dev (https://drupal.org/node/1365582, 5 June 2014 or later).

jsibley’s picture

Are the above supposed to include the html5 default patch? I'm not seeing that option in my view, but maybe I'm not looking in the right place.

Thanks!

RdeBoer’s picture

@jsibley, #36:
It should be. Have you run /update.php ?
The HTML5 default shows up when you specify the Source of Origin on Geofield proximity fields, filters and sorts.
Rik

jsibley’s picture

It says I don't have any updates to run, so I think I'm up to date.

I think I'm also seeing the wrong "refine my location" block, as I only see a place to write an address, not the radio buttons.

RdeBoer’s picture

Yep, then you have the wrong version of IPGV&M 7.x-1.x-dev. In the latest version the block is called "Set my location".

jsibley’s picture

Thanks. I must have made a mistake at some point, as I thought I was running the correct dev version but was not.

Is there something I need to do to recode existing addressfield values? I have them in a field collection in a profile2 profile.

I see geoaddress longitude and latitude but am getting this with a new view:

None of the 11 result rows in view maptest (Page) had their ip_geoloc_latitude set. Therefore those rows could not be displayed as locations on the map. Are you using the correct field names?

I have tried running update.php again but it says there is nothing to update.

Thanks.

RdeBoer’s picture

@jsibley, #40
If they're in a field collection you could be in for a rough ride.
You may have to move them into Views PHP variables ((as in the Views PHP module) first and then map those.
See #2267015: unable to map on php field result (where the latitude is retrieved).

jsibley’s picture

When and where is ip_geoloc_latitude set and where is it required?

It appears that I can use these versions of geofield and ip_geolocation to create some maps. I'm not sure if it is the html5 option and/or the set my location that is creating the problem and am still running some tests.

Thanks.

jsibley’s picture

Also, in case it helps, this is from the error message I am getting:

field_field_geoaddress = Array ( [0] => Array ( [rendered] => Array ( [#markup] => Latitude: 55.378051000000
Longitude: -3.435973000000 [#access] => 1 ) [raw] => Array ( [geom] => POINT (-3.435973 55.378051) [geo_type] => point [lat] => 55.378051000000 [lon] => -3.435973000000 [left] => -3.435973000000 [top] => 55.378051000000 [right] => -3.435973000000 [bottom] => 55.378051000000 [geohash] => gcve1c6080bv ) ) )

and in watchdog:

Notice: Undefined index: lon in geofieldProximityManual->getSourceValue() (line 39 of /srv/bindings/0c0af6161f58491a8df36a8322c62f11/code/sites/all/modules/geofield/views/proximity_plugins/geofieldProximityManual.inc).

jsibley’s picture

So, the good news (I hope) is that while you were hopefully asleep I have made some significant progress.

ip_geoloc_latitude had been filled in automatically, somehow, in the text box below the name of latitude dropbox. It definitely isn't something that I had typed in.

It appears that, even though I have relationships in the views from user to profile to addressplusphone (the field collection allowing multiple addresses with corresponding phone numbers for each user), choosing field collection item: geoaddress for name of latitude field seems to provide a map.

However, selecting [type field name] and putting in field_geoaddress gives an error.

Also, I have a proximity field that shows when a user's icon is clicked on in the map. If use geocoded location (without html5), the distance always shows as 0. If I use geocoded location with html5 the distance appears to work.

Finally, if this isn't too much at one time, it seems that if I select the "here" radio button after "there" has already been selected, it doesn't switch to the current location with "apply".

Thanks!

jsibley’s picture

Oops. As you probably realized, I was using the IPGV&M set my location block rather than the geofield proximity filter exposed as a block.

RdeBoer’s picture

@jsibley #45:
"However, selecting [type field name] and putting in field_geoaddress gives an error." (IPGV&M)

Yes because Views creates its field names in mysterious ways. field_geoaddress is probably not the right name to use in the context of relationships.

" If use geocoded location (without html5), the distance always shows as 0."
It all depends which Source of Origin you use.

Finally.... it seems that if I select the "here" radio button after "there" has already been selected, it doesn't switch to the current location with "apply". (IPGV&M)
You need to have the auto-refresh on (a config option on the IPGV&M config page) or (re)load the same or another page. By the way, the button is called "Go", right? Or do you have an older version of IPGV&M ?

PS: this originally was a Geofield issue. Most of your post is about IPGV&M.... if you have more, maybe address it in the IPGV&M issue queue?

jsibley’s picture

I think I was confused about what was geofield functionality and what belonged to IPGV&M. Sorry about that.

So, the option to filter by proximity using html5 or a geocoded address comes from geofield, where one can select either "geocoded address" or "geocoded address with html5 default".

Then, one can use "exposed geocoded proximity filter" in Fields and/or Sort Criteria (and this is true whether using "with html5 default" or not), right?

And, this much is true whether showing a table or an IPGV&M map, right?

If using an IPGV&M map, when can then add, in addition to the exposed filter, the "IPGV&M set my location" block. I assume that this block doesn't do anything if just using a table, yes?

So, my map seems to be working now. I am using the map as a block, with the exposed filter as a block using the Views Block Filter Block module as well as the set my location block. It is still just a dev site or I would provide a link.

Where I think that I am still having an issue is on a different page of the website where a table view with an exposed filter seems to work properly when the proximity filter is set to "geocoded address". Distances seem to be correct and the sort seems to work. As soon as I switch the proximity filter to "geocoded address with html5 default" changing the "from" field in the proximity filter and hitting apply, even multiple times, seems to have no effect. All distances seem to be calculated from the current location, no matter what. The only change I make is from "geocoded address" to "geocoded address with html5 default" in the proximity filter. If I change back to "geocoded address", distances seem to work again. Any thoughts?

Thank you for all of your great work on both modules!

RdeBoer’s picture

@jsibley, #47
The two are very close. Geofield offers the option for other modules to plug in and IPGV&M does just that with the "Geolocated Location with HTML5 default" Source of Origin Point

"I assume that this "Set my location" block doesn't do anything if just using a table, yes?"
With Geofield enabled, it does work on any Views format, including tables, when used in conjunction with the Geofield Proximity Fields/Filters/Sorts provided by Geofield, as it sets the "Source of Origin Point" for the distance calculation to be either the satellite/WiFi-retrieved visitor location (i.e. HTML5) or a geocoded address the visitor types into the "Set my location" block.

Regarding your final question, have you read this README section from IPGV&M:

ADVANCED OPTIONS
================
If you use Geofield for coordinate storage, you have a number of great options
to create sophisticated maps. First you can use Geofield in combination
with Geocoder and AddressField (or any plain textfield) to have lat/lon
autogenerated from the street address typed on each piece of content.

Second, you get some great Views filters thrown in. When you select Geofield's
proximity filter you get a new option for the "Source of Origin Point", named
"Geocoded location with HTML5" default. When the visitor does not type in a
location into the exposed proximity filter, or types "me", the filter will use
the visitor's current location as the center of your map as well as the source
of origin for distance calculations. So your map will only show locations within
the specified radius.
You can display these distances in the marker balloons and/or a tabular
attachment too, by adding the Geofield proximity field in the Views UI. When
it comes to specifying the "Source of Origin Point" pick "Exposed Geofield
Proximity Filter" so that the distance quoted is with respect to the location
that the exposed filter is set to, be it a typed location or the visitor's HTML5
location.

To top it all off, add the "IPGV&M: Set my location" block, which supplies 3
ways for the user to specify the center of the map: by typed adddress, by region
taxonomy and by an explicit request to perform an HTML5 lookup. The latter
means that you can switch off the periodic prompting to share location, which
can become annoying, i.e. you can UNtick the box "Employ the Google Maps API to
reverse-geocode HTML5 visitor locations to street addresses".

PS: I haven't used VIews Block Exposed Filter Blocks, so don't know whether it throws a spanner in the works or not.

jsibley’s picture

Thanks, it's great to know that "set my location" can work with a table view.

As for my last question in #47, I'm not sure that the IPGV&M readme applies, as I was using a table view without "set my location".

So, even creating a simple view page (not blocks) with only the proximity as an exposed filter, it seems like the "apply" button when I change the address isn't doing anything when I use the html5 as default proximity filter.

FWIW, if I do add the IPGV&M "set my location" block to the table view, even if I use the block-based view, I do see the changes. It's just without any IPGV&M stuff that the distances don't get updated.

If there is some way you would like me to troubleshoot this, let me know and I'll do my best.

Thanks.

RdeBoer’s picture

Re #49:

Yes "Set my location" works for tables and maps. In fact that is a common setup: to have a Views Page display as a map and then add an Views Attachment display as a table showing details of the markers on the map.

"So, even creating a simple view page (not blocks) with only the proximity as an exposed filter, it seems like the "apply" button when I change the address isn't doing anything when I use the html5 as default proximity filter."

That would be a bug in IPGV&M. I've entered it for you here: #2287945: Geocoding of typed address doesn't happen in exposed Geofield Proximity Filter with HTML5 fallback.
You may want to "Follow" that issue for updates.

Rik

jsibley’s picture

Thanks, Rik.

Just to be clear, even though it is a view that doesn't use IPGV&M (just a regular views table) and doesn't use the IPGV&M "set my location" block, it is still an IPGV&M bug? Is the option to use "geocoded address with html5 default" coming from IPGV&M and not from geofield?

Jonathan

RdeBoer’s picture

@jsibley, #51

Yes Jonathan, that is 100% correct.
The plugin can be found here on your system: sites/all/modules/ip_geoloc/views/proximity_plugins/geofieldProximityGeocoderWithHTML

For others reading only this part of the thread. The above IPGV&M plugin (in ip_geoloc 7.x-1.x-dev or future official releases) will only work if and when this patch is applied to the Geofield module, Geofield 7.x-2.x branch (https://drupal.org/node/1360636, 17 Nov 2013): https://drupal.org/node/2134777#comment-8823463

Rik

SocialNicheGuru’s picture

I'm a little confused.
Is the patch and associated file at the top of this issue needed any longer?

RdeBoer’s picture

@SocialNicheGuru, #53

No that patch is not required. In fact the patch at the top of this issue should NOT be applied, if you follow the steps in #52, using the alternative Geofield patch mentioned in #52 patch and IPGV&M 7.x-1.x-dev
Rik

Brandonian’s picture

So, @RdeBoer, since #2134777: Allow other modules to define their own proximity plugins was committed, can we close this issue, or am I missing a patch?

RdeBoer’s picture

No that is it I believe, Brandon.
Thanks so much!
Rik

Brandonian’s picture

Status:Reviewed & tested by the community» Fixed

H'ok, marking as fixed.

Status:Fixed» Closed (fixed)

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