Finding a geo point inside a geoshape rectangle

All the documentation seems to point to either having geo points and then having a bounding box to select these geo points.
Is the reverse feature possible in Elastic Search?
The only closest I could find in this form is
Geo Center and Rectangle Box
Where is the contains keyword in elastic?

I have a mapping which says its a geo shape

"geoLocationBox": {
	"type": "geo_shape"
}

I am inserting the data

	"name": "wanted record",
	"geoLocationBox": {
		"type": "envelope",
		"coordinates": [
			[
				18.2503,
				-66.6593
			],
			[
				18.1119,
				-66.8364
			]
			
		]

How to get this record given a geopoint which is within this box?

"geoLocationPoint": {
	"lat": 18.1779,
	"lon": -66.7644
}

Hi @antonpious

I am struggling a bit to follow.

Is this the use case?

Given a point return all polygons that the given point is contained within?

Is that what you are asking?

Do you have an index with various geo_shape(s) and you want to provide a point and return all the shapes that contain the point

Yes. your understanding is correct.

The polygon is a rectangle. So each record would have a rectangle stating the top left and bottom right co-ordinate.

Now the query would get only a geo point.
The goal is to find all records where this point is contained within these rectangles.

I guess you don't have this feature... I might as well convert this field into an object with min max of latitude and longitude and then check the point is within these values as described in this thread

So odd I thought we did.. I have been experimenting... will keep trying...

Yes certainly I think do a range query... but I thought a geo_shape query would work but no luck so far!

I think the issue here is the understanding on how to define an Envelope. From the documentation the coordinates needs to be provided in the format [[minLon, maxLat], [maxLon, minLat]].

Therefore your envelope example has the following coordinates:

minLon=18.2503
maxLon=18.1119
minLat=-66.6593
maxLat=-66.8364

Note that the minLat > maxLAt, therefore this is an envelope that crosses the dateline, so an inside point would be for example:

GET my_index/_search
{
  "query": {
    "geo_shape": {
      "geoLocationBox": {
        "shape": {
          "type": "Point",
          "coordinates": [180.0, -66.7644]
        }
      }
    }
  }
}

Hope this helps.

Hi @Ignacio_Vera

Can you tell me why this does not work... I tried with relationships contains, within and intersects

DELETE discuss-shape

PUT discuss-shape/
{
  "mappings": {
    "properties": {
      "name" : {"type": "keyword"},
      "geoLocationBox": {"type": "geo_shape"}
    }
  }
}

POST discuss-shape/_doc
{
  "name": "10x10 Box",
  "geoLocationBox": {
    "type": "envelope",
    "coordinates": [
      [
        10.0,
        10.0
      ],
      [
        -10.0,
        -10.0
      ]
    ]
  }
}

POST discuss-shape/_doc
{
  "name": "5x5 Box",
  "geoLocationBox": {
    "type": "envelope",
    "coordinates": [
      [
        5.0,
        5.0
      ],
      [
        -5.0,
        -5.0
      ]
    ]
  }
}


POST discuss-shape/_doc
{
  "name": "5x5 Offset Box",
  "geoLocationBox": {
    "type": "envelope",
    "coordinates": [
      [
        10.0,
        10.0
      ],
      [
        5.0,
        5.0
      ]
    ]
  }
}

POST discuss-shape/_search
{
  "query": {
    "geo_shape": {
      "geoLocationBox": {
        "relation": "contains",
        "shape": {
          "coordinates": [ 0.0, 0.0 ],
          "type": "point"
        }
      }
    }
  }
}

#results

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 0,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  }
}

I even put these on the maps so I could see it would seem / I would expect the query above with the 0.0, 0.0 point should return the 2 centered boxes but it does not .... I can not get it too work...

1.0, 1.0 does not work either etc

POST discuss-shape/_search
{
  "query": {
    "geo_shape": {
      "geoLocationBox": {
        "relation": "contains",
        "shape": {
          "coordinates": [ 1.0, 1.0 ],
          "type": "point"
        }
      }
    }
  }
}

# Results
{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 0,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  }
}

Remember the format: [[minLon, maxLat], [maxLon, minLat]]

So your envelope:

{
    "type": "envelope",
    "coordinates": [
      [
        10.0,
        10.0
      ],
      [
        -10.0,
        -10.0
      ]
    ]
  }

contains minLon > maxLon, therefore crosses the dateline (it is not the shape you have drawn). Try swapping the longitudes:

{
    "type": "envelope",
    "coordinates": [
      [
        -10.0,
        10.0
      ],
      [
        10.0,
        -10.0
      ]
    ]
  }
1 Like

Ohhhhhh I see... YAY!!!!!

@Ignacio_Vera It is weird the malformed envelopes still show up on the map... and still ingest ... seems like some validation is in order :wink:

But now it Works when I define the envelopes correct!!!

@antonpious You should be able to do this..

DELETE discuss-shape

PUT discuss-shape/
{
  "mappings": {
    "properties": {
      "name" : {"type": "keyword"},
      "geoLocationBox": {"type": "geo_shape"}
    }
  }
}

POST discuss-shape/_doc
{
  "name": "10x10 Box Other",
  "geoLocationBox": {
    "type": "envelope",
    "coordinates": [
      [
        -10.0,
        10.0
      ],
      [
        10.0,
        -10.0
      ]
    ]
  }
}

POST discuss-shape/_doc
{
  "name": "5x5 Box",
  "geoLocationBox": {
    "type": "envelope",
    "coordinates": [
      [
        -5.0,
        5.0
      ],
      [
        5.0,
        -5.0
      ]
    ]
  }
}

POST discuss-shape/_doc
{
  "name": "5x5 Offset Box",
  "geoLocationBox": {
    "type": "envelope",
    "coordinates": [
      [
        5.0,
        10.0
      ],
      [
        10.0,
        5.0
      ]
    ]
  }
}

POST discuss-shape/_search
{
  "query": {
    "geo_shape": {
      "geoLocationBox": {
        "relation": "intersects",
        "shape": {
          "coordinates": [ 0.0, 0.0 ],
          "type": "point"
        }
      }
    }
  }
}

# Correct Results!!!

{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0,
    "hits": [
      {
        "_index": "discuss-shape",
        "_id": "8HoK-YMBWq97sHQ4avvA",
        "_score": 0,
        "_source": {
          "name": "10x10 Box Other",
          "geoLocationBox": {
            "type": "envelope",
            "coordinates": [
              [
                -10,
                10
              ],
              [
                10,
                -10
              ]
            ]
          }
        }
      },
      {
        "_index": "discuss-shape",
        "_id": "anoM-YMBWq97sHQ4dv38",
        "_score": 0,
        "_source": {
          "name": "5x5 Box",
          "geoLocationBox": {
            "type": "envelope",
            "coordinates": [
              [
                -5,
                5
              ],
              [
                5,
                -5
              ]
            ]
          }
        }
      }
    ]
  }
}

I KNEW we did this!!! :slight_smile:

I open: Envelopes crossing the dateline are not handled properly in vector tiles API · Issue #91060 · elastic/elasticsearch · GitHub

I think there is a bug on how we handle those kind of envelopes in vector tiles.

Thanks @stephenb it works.
The issue seems to be the order of the rectangle
|latitude_min|latitude_max|longitude_min|longitude_max|

|18.1119|18.2503|-66.8364|-66.6593|

To [[minLon, maxLat], [maxLon, minLat]]
This would give Left Top, Right Bottom

[
	-66.8364,
	18.2503
],
[
	-66.6593,
	18.1119
]

This was
[[maxLon, maxLat], [minLon, minLat]] before which would give Right Top, Left Bottom

Thanks for the syntax correction too @Ignacio_Vera

1 Like

Just for everyone Envelope Definition Here

Envelope

Elasticsearch supports an envelope type, which consists of coordinates for upper left and lower right points of the shape to represent a bounding rectangle in the format [[minLon, maxLat], [maxLon, minLat]]:

@stephenb is it possible to add this sample in this page Geo Shape Query so that people know Elasticsearch have this feature.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.