# Elasticsearch Geo queries - Java API

**URL:** <https://discuss.elastic.co/t/elasticsearch-geo-queries-java-api/173501>\
**Category:** Elasticsearch\
**Created:** [March 22, 2019, 2:06pm UTC](https://discuss.elastic.co/t/elasticsearch-geo-queries-java-api/173501 "2019-03-22T14:06:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![AAHM](https://avatars.discourse-cdn.com/v4/letter/a/f475e1/32.png) [@AAHM](https://discuss.elastic.co/u/AAHM)\
**Post date:** [March 22, 2019, 2:06pm UTC](https://discuss.elastic.co/t/elasticsearch-geo-queries-java-api/173501/1 "2019-03-22T14:06:12Z")

</div>

Hi,  
We are migrating to ES and need to support different geo queries. We use a geo\_point field type in our mapping. I can see that ES supports geo\_bounding\_box & geo\_distance but I'm trying to figure out whether they can be used for our use cases below:

1.BBOX: where the box is defined using a central point & radius. As far as I understand, the geo\_distance will create a circular shape, how can we use a bbox of that circle?

```
//something like this - but we want a box shape not circle
QueryBuilders.geoDistanceQuery("location")
        .point(lat, lon)
        .distance(r, DistanceUnit.KILOMETERS);

```

2.LAT\_WITHIN: how can we check for documents with latitude that is within a distance (north & south) from a central latitude?

```
//something like this - but with only lat & radius
QueryBuilders.geoDistanceQuery(pointField)
        .point(lat) //only lat?
        .distance(r, DistanceUnit.KILOMETERS);

```

3.LON\_WITHIN: similarly to the above point but for longitude.

4.SAME POINT: find documents with the same lat & lon. So can we use here the geo point field in a term query or is it possible to use the lat/lon keys?  
using the first query below gives error "Geo fields do not support exact searching, use dedicated geo queries instead: [location]". The second query doesn't return results.

```
//point equal - this gives error
QueryBuilders.termQuery("location", "lat,lon");
//OR - this doesn't return
QueryBuilders.boolQuery()
.must(QueryBuilders.termQuery("location.lat", lat))
.must(QueryBuilders.termQuery("location.lon", lon));

```

Thanks

---

<div class="post-metadata">

**Author:** ![Ignacio\_Vera](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ignacio_vera/32/36674_2.png) [@Ignacio\_Vera](https://discuss.elastic.co/u/Ignacio_Vera)\
**Post date:** [March 22, 2019, 2:40pm UTC](https://discuss.elastic.co/t/elasticsearch-geo-queries-java-api/173501/2 "2019-03-22T14:40:30Z")

</div>

To support those use cases you will have to do some work on your side:

1. This is currently not possible, you need to compute the bounding box on the client and then build the query.

2. This is something similar as you can define the query as `geo_bounding_box`. First calculate the upper and lower bound for the latitude in the client and then generate the corresponding bounding box using -180 & 180 for the longitude.

3. Same as above.

4. geo points are encoded in the index with a small lost of precision (~1cm on the surface of the earth) and therefore equality is not possible. You can either filter by distance using a very small distance (~1cm) or you can index lat and Lon in another field and use that for equality.

---

<div class="post-metadata">

**Author:** ![AAHM](https://avatars.discourse-cdn.com/v4/letter/a/f475e1/32.png) [@AAHM](https://discuss.elastic.co/u/AAHM)\
**Post date:** [March 22, 2019, 4:43pm UTC](https://discuss.elastic.co/t/elasticsearch-geo-queries-java-api/173501/3 "2019-03-22T16:43:19Z")

</div>

Hi,

Thanks for your reply.  
Is there a util class in the lib or any external lib that would calculate this? I couldn't find any guide online.

---

<div class="post-metadata">

**Author:** ![Ignacio\_Vera](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ignacio_vera/32/36674_2.png) [@Ignacio\_Vera](https://discuss.elastic.co/u/Ignacio_Vera)\
**Post date:** [March 22, 2019, 4:46pm UTC](https://discuss.elastic.co/t/elasticsearch-geo-queries-java-api/173501/4 "2019-03-22T16:46:55Z")

</div>

This class in Lucene might contain most of the logic you need, in particular have a look into `fromPointDistance` and `axisLat` methods

> <https://github.com/apache/lucene-solr/blob/master/lucene/core/src/java/org/apache/lucene/geo/Rectangle.java>

---

<div class="post-metadata">

**Author:** ![AAHM](https://avatars.discourse-cdn.com/v4/letter/a/f475e1/32.png) [@AAHM](https://discuss.elastic.co/u/AAHM)\
**Post date:** [April 8, 2019, 1:34pm UTC](https://discuss.elastic.co/t/elasticsearch-geo-queries-java-api/173501/5 "2019-04-08T13:34:46Z")

</div>

Thanks Vera & sorry for the late reply.  
I think the fromPointDistance would solve my first problem by supplying the generated Rectangle points to a geo\_bounding\_box query

```
 Rectangle rectangle = Rectangle.fromPointDistance(
            lat, lon, DistanceUnit.convert(distance, DistanceUnit.KILOMETERS, DistanceUnit.METERS));
QueryBuilder queryBuilder = QueryBuilders.geoBoundingBoxQuery("location")
            .setCorners(rectangle.maxLat, rectangle.maxLon, rectangle.minLat, rectangle.minLon);

```

I tried the axisLat method with the following values

```
double cenLat = 14;
double distance = 225;
distance = DistanceUnit.convert(distance, DistanceUnit.KILOMETERS, DistanceUnit.METERS);
double maxLat = Rectangle.axisLat(cenLat, distance);
double minLat = ??;

// this prints 222390.1594687375
log.info("{}", GeoUtils.planeDistance(14,0,12,0));

```

I got maxLat value = 14.0089134. I know from an example that latitude 12 is between 220 - 230 km from latitude 14, but I don't get the expected result.  
I'm probably misusing the function. can you please help.

Thanks

---

<div class="post-metadata">

**Author:** ![Ignacio\_Vera](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ignacio_vera/32/36674_2.png) [@Ignacio\_Vera](https://discuss.elastic.co/u/Ignacio_Vera)\
**Post date:** [April 9, 2019, 7:17am UTC](https://discuss.elastic.co/t/elasticsearch-geo-queries-java-api/173501/6 "2019-04-09T07:17:19Z")

</div>

I think we are misunderstanding what Rectangle.axisLat does. It gives you the latitude of a circle's intersections with its bbox meridians which I think it is not what you want. This is the intersection of the box with the circle at minLon and maxLon.

I think in your case you can use again the method Rectangle.fromPointDistance with a dummy longitude (e.g. 0.0) and use the given minLat and maxLat.

---

<div class="post-metadata">

**Author:** ![AAHM](https://avatars.discourse-cdn.com/v4/letter/a/f475e1/32.png) [@AAHM](https://discuss.elastic.co/u/AAHM)\
**Post date:** [April 9, 2019, 8:10am UTC](https://discuss.elastic.co/t/elasticsearch-geo-queries-java-api/173501/7 "2019-04-09T08:10:38Z")

</div>

Thank you very much. This now gives expected values using the Rectangle.fromPointDistance.

Many thanks

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [May 7, 2019, 8:10am UTC](https://discuss.elastic.co/t/elasticsearch-geo-queries-java-api/173501/8 "2019-05-07T08:10:41Z")

</div>

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