Great module!

So, I am starting to look at GeoJSON support in the OL module. I just committed a basic GeoJSON layer type into the code. I should now be able to just offer any views_geojson as an overlay (it might make sense for that to live in this module, actually).

But, OL has a BBOX strategy, but it seems that is fairly hard coded that the way that it sends its bounding box request is like: ?BBOX=x,x,x,x (cant recall exact coordinates). So, I just want to start thinking about how this should work. Is this something that this module can handle? Or should modules like Geofield write filters that can handle this sort of this?

Thoughts?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jeffschuler’s picture

Are we talking about a bounding box to filter all data that's passed to OL, or that OL is using for the current viewport? (Should I actually be distinguishing these?)

For the former, it seems like Views GeoJSON could offer a views argument for bounding box params, and filter the output features accordingly.

The latter would be more dynamic and has View GeoJSON and OL talking more. Do we ever want changes to the OL map (like dragging and zooming) to trigger re-request of new GeoJSON data?

zzolo’s picture

So, basically we want to be able to filter a Views GeoJSON feed with a bounding box. Ideally, there would be a global way to do this for the whole feed.

The issue with OL is that it expects to query parameter in a very specific way. ?BBOX=:west,:south,:east,:north But, this way is not the craziest thing (Google Maps uses it in places).

And this filter should be either automatically built into the GeoJSON feed, or as a Views filter than can be enabled. The question is: should Views GeoJSON module provide that filter, or should something like the OL module provide it?

If it is provided in the Views JSON module, then it would make sense to possibly make it configurable so that other mapping libraries that use other formats can use it as well.

ressa’s picture

Are we talking about a bounding box to filter all data that's passed to OL, or that OL is using for the current viewport?

My map will probably end up having more than 100.000 markers, which would make the loading time Very Slow. See also this discussion about the same issue: Solutions for dealing with large numbers of features on a map

So I would prefer it if Openlayers could grab the lat+long of the bounding box and use it to filter the view, so that only the markers in visible area of the map is returned and displayed. If I understand it correctly :-)

jeffschuler’s picture

Status: Active » Needs work
FileSize
6.93 KB

Spent a little time on this.

Still a lot to do, and a lot wrong with this (like that it's a filter instead of a contextual filter, :-p,) but it's a start.

jeffschuler’s picture

Inching forward a bit further. This one actually pulls the bbox coordinates from the arg string instead of using sample numbers. Works if your GeoJSON view uses lat & lon fields.

jeffschuler’s picture

Added Geofield support. Next will be to change this into a contextual filter.

jeffschuler’s picture

Status: Needs work » Needs review
FileSize
9.16 KB

OK. This is in a working state where I could use a few more eyes.

I've turned it from a Views filter to a contextual filter (argument.) You can add a contextual argument for bounding box, which accepts an arg in form "x,x,x,x" and edits the query accordingly. If the string starts with "?BBOX=" it'll strip that. Well, kind of, (see inline comments.)

I've also added a "default argument" plugin to allow pulling the query string from the URL (via GET params.) I'm not sure whether this is actually necessary. I'm not totally clear how the query string from OpenLayers will come through Views: whether Views will interpret it as an argument, (and we can just do some substring stripping,) or we need to special case this and pull it from GET like I'm doing.

Another issue is that, when using the default argument, if the string is not in the query, no results are returned...

Would love some feedback on whether this is a good route.

jeffschuler’s picture

Status: Needs review » Fixed
FileSize
8.65 KB

Committed this. Let's pick it apart and improve it.

nottaken’s picture

@zzolo I noticed this sandbox project doing the same thing - at least by the description. no code commits yet.

http://drupal.org/sandbox/katbailey/1445310

Status: Fixed » Closed (fixed)

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

jeffschuler’s picture

Just committed a small fix to return all results when arg is not in the query string, (when using the Provide default value: Bounding box from query string context filter option:

index a084610..fb8e384 100644
--- a/views/views_plugin_argument_default_bboxquery.inc
+++ b/views/views_plugin_argument_default_bboxquery.inc
@@ -34,6 +34,8 @@ class views_plugin_argument_default_bboxquery extends views_plugin_argument_defa
   function get_argument() {
     if (isset($_GET[$this->options['arg_id']])) {
       return $_GET[$this->options['arg_id']];
+    } else {
+      return TRUE; // Return all values if arg not present
     }
   }
 }
zzolo’s picture

Status: Closed (fixed) » Needs review
FileSize
4.15 KB

Hey @jeffschuler. Let me know if you want me to open a new ticket.

I had some problems getting things working correctly, but with the following patch, I was able to get things to work properly. I don't have a full grasp of the module, and I definitely don't know the Views API all that great.

jeffschuler’s picture

Thanks @zzolo, I've made most of those changes.

I changed the logic for "unwrapping" out-of-bounds bbox coords. It's working for me, but there's faulty logic that should be fixed to make things more efficient.

When the displayed map wraps over the 180° or -180° line, OpenLayers extends those numbers further out, making the next map, for example, from 180 to 540. If you zoom out more and keep dragging the map further in that direction, the numbers keep getting bigger.

My current logic is incorrect in assuming that points are displayed across one of these [180°/-180°] lines. I'm taking the negated modulus and turning the query into an OR, to get the points on either side of the line that are inside the map view. What I see OL doing, though, is only displaying points on a single full-width map (-180° to 180) part of the display at any given time. If there are two full-width maps in view, the points get shown on the one that takes up the majority of the viewport... Since my logic is asking for points on both sides of the dividing line, the ones on the side whose points aren't being shown are being loaded but not viewed.

jeffschuler’s picture

The patch...

jeffschuler’s picture

Status: Needs review » Fixed

Committed this to get us closer to good.
Let's make new tickets for new issues.

Status: Fixed » Closed (fixed)

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