Filter points inside a polygon

Created on 25 November 2021, over 2 years ago
Updated 29 December 2023, 6 months ago

I have two content types:
A -> It has a geofield of type polygon
B -> It has a geofield of type point

I would like to build a view to show all B nodes that are inside a polygon defined from a A node, on a map.

💬 Support request
Status

Needs work

Version

2.1

Component

Code

Created by

🇪🇸Spain Alfonso_MA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇳🇱Netherlands JoshaHubbers

    I am also trying to accomplish this. Did you solve it?

  • Status changed to Needs review 6 months ago
  • 🇮🇹Italy itamair

    Hi @here ... well, this could sound a familiar geospatial task,
    but it is something that the Drupal Leaflet module is not able to accomplish with its actual settings, and I feel it not going to be able to accomplish in any future enhanced settings of (too many specific scenarios can derivate).

    BUT still I think you / we could accomplish this, leveraging its already present features ...

    If it was me I will be probably start minding about the following recipients for this task:
    - a Leaflet additional plugin such this one: https://github.com/hayeswise/Leaflet.PointInPolygon (or whatever could implement some Point in Polygon logics);
    - if needed will properly differentiate the Leaflet Features between the filtering ones (polygons) and the filtered ones (points), may be even adding a specific property with the "hook_leaflet_views_feature_alter" ...
    - make my additional and specific operations (to hide polygons and render only points inside polygons) after the Leaflet map and it Features are fully generated, simply reacting to the 'leafletMapInit' event (for reference please look to gist injected to this comment of mine: https://www.drupal.org/project/leaflet/issues/3345312#comment-14947388 💬 How to add a fixed polygon layer on map Fixed )

  • Status changed to Active 6 months ago
  • 🇳🇱Netherlands JoshaHubbers

    I solved it by creating a custom views-filter.
    1. create a view that loads all the points.
    2. in the module file I load the drawn area from the node:

    my_module_custom_views_pre_view(&$view, &$display_id, &$args){
      if($view->id() == 'test'){
        if($view->current_display == 'block_1'){
          $node = \Drupal::routeMatch()->getParameter('node');
          if ($node instanceof \Drupal\node\NodeInterface) {
            $focus_area = $node->field_adres->value;
            $args[0] = $focus_area;
            $view->setArguments($args);
          }
        }
      }
    }

    3. in the custom filter I add a join to the table, and the custom expression to select the points within the polygon:

         /** @var \Drupal\views\Plugin\views\query\Sql $query */
        $query = $this->query;
        $definition = [
          'table' => 'node__field_adres',
          'field' => 'entity_id',
          'left_table' => 'node_field_data',
          'left_field' => 'nid',
        ];
        $join = \Drupal::service('plugin.manager.views.join')->createInstance('standard', $definition);
        $query->addRelationship('adres_filter', $join, 'node__field_data');
        $expression = sprintf("st_Contains(st_GeomFromText('%s'), st_GeomFromText(\"adres_filter\".\"field_adres_value\"))", $this->view->args[0]);
        $query->addWhereExpression($this->options['group'], $expression);

    Note: this is quick and dirty. Some basics like service injection must be fixed.

  • Status changed to Needs work 6 months ago
  • 🇮🇹Italy itamair

    @JoshaHubbers very cool and logical approach. Thanks for sharing!
    Indeed I thought that a server side solution might be better than my suggestions ... and so it looks.
    It would be great if you could make all this a reusable plugins, with some configurations, etc.
    so that we could embed in the Leaflet module ...

Production build 0.69.0 2024