public void testInvalidDistanceUnit() {
   GeoDistanceRangeQueryBuilder builder =
       new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, new GeoPoint());
   IllegalArgumentException e =
       expectThrows(IllegalArgumentException.class, () -> builder.unit(null));
   assertEquals("distance unit must not be null", e.getMessage());
 }
 public void testInvalidTo() {
   GeoDistanceRangeQueryBuilder builder =
       new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, new GeoPoint());
   IllegalArgumentException e =
       expectThrows(IllegalArgumentException.class, () -> builder.to((String) null));
   assertEquals("[to] must not be null", e.getMessage());
   e = expectThrows(IllegalArgumentException.class, () -> builder.to((Number) null));
   assertEquals("[to] must not be null", e.getMessage());
 }
 public void testFromJson() throws IOException {
   String json =
       "{\n"
           + "  \"geo_distance_range\" : {\n"
           + "    \"pin.location\" : [ -70.0, 40.0 ],\n"
           + "    \"from\" : \"200km\",\n"
           + "    \"to\" : \"400km\",\n"
           + "    \"include_lower\" : true,\n"
           + "    \"include_upper\" : true,\n"
           + "    \"unit\" : \"m\",\n"
           + "    \"distance_type\" : \"sloppy_arc\",\n"
           + "    \"validation_method\" : \"STRICT\",\n"
           + "    \"ignore_unmapped\" : false,\n"
           + "    \"boost\" : 1.0\n"
           + "  }\n"
           + "}";
   GeoDistanceRangeQueryBuilder parsed = (GeoDistanceRangeQueryBuilder) parseQuery(json);
   checkGeneratedJson(json, parsed);
   assertEquals(json, -70.0, parsed.point().lon(), 0.0001);
 }
  public void testIgnoreUnmapped() throws IOException {
    final GeoDistanceRangeQueryBuilder queryBuilder =
        new GeoDistanceRangeQueryBuilder("unmapped", new GeoPoint(0.0, 0.0)).from("20m");
    queryBuilder.ignoreUnmapped(true);
    Query query = queryBuilder.toQuery(createShardContext());
    assertThat(query, notNullValue());
    assertThat(query, instanceOf(MatchNoDocsQuery.class));

    final GeoDistanceRangeQueryBuilder failingQueryBuilder =
        new GeoDistanceRangeQueryBuilder("unmapped", new GeoPoint(0.0, 0.0)).from("20m");
    failingQueryBuilder.ignoreUnmapped(false);
    QueryShardException e =
        expectThrows(
            QueryShardException.class, () -> failingQueryBuilder.toQuery(createShardContext()));
    assertThat(e.getMessage(), containsString("failed to find geo_point field [unmapped]"));
  }
  @Override
  protected GeoDistanceRangeQueryBuilder doCreateTestQueryBuilder() {
    GeoDistanceRangeQueryBuilder builder;
    GeoPoint randomPoint = RandomGeoGenerator.randomPointIn(random(), -180.0, -89.9, 180.0, 89.9);
    if (randomBoolean()) {
      builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, randomPoint.geohash());
    } else {
      if (randomBoolean()) {
        builder = new GeoDistanceRangeQueryBuilder(GEO_POINT_FIELD_NAME, randomPoint);
      } else {
        builder =
            new GeoDistanceRangeQueryBuilder(
                GEO_POINT_FIELD_NAME, randomPoint.lat(), randomPoint.lon());
      }
    }
    GeoPoint point = builder.point();
    final double maxRadius = GeoUtils.maxRadialDistanceMeters(point.lat(), point.lon());
    final int fromValueMeters = randomInt((int) (maxRadius * 0.5));
    final int toValueMeters = randomIntBetween(fromValueMeters + 1, (int) maxRadius);
    DistanceUnit fromToUnits = randomFrom(DistanceUnit.values());
    final String fromToUnitsStr = fromToUnits.toString();
    final double fromValue =
        DistanceUnit.convert(fromValueMeters, DistanceUnit.DEFAULT, fromToUnits);
    final double toValue = DistanceUnit.convert(toValueMeters, DistanceUnit.DEFAULT, fromToUnits);

    if (randomBoolean()) {
      int branch = randomInt(2);
      fromToUnits = DistanceUnit.DEFAULT;
      switch (branch) {
        case 0:
          builder.from(fromValueMeters);
          break;
        case 1:
          builder.to(toValueMeters);
          break;
        case 2:
          builder.from(fromValueMeters);
          builder.to(toValueMeters);
          break;
      }
    } else {
      int branch = randomInt(2);
      switch (branch) {
        case 0:
          builder.from(fromValue + fromToUnitsStr);
          break;
        case 1:
          builder.to(toValue + fromToUnitsStr);
          break;
        case 2:
          builder.from(fromValue + fromToUnitsStr);
          builder.to(toValue + fromToUnitsStr);
          break;
      }
    }
    if (randomBoolean()) {
      builder.includeLower(randomBoolean());
    }
    if (randomBoolean()) {
      builder.includeUpper(randomBoolean());
    }
    if (randomBoolean()) {
      builder.geoDistance(randomFrom(GeoDistance.values()));
    }
    builder.unit(fromToUnits);
    if (randomBoolean()) {
      builder.setValidationMethod(randomFrom(GeoValidationMethod.values()));
    }

    if (randomBoolean()) {
      builder.ignoreUnmapped(randomBoolean());
    }
    return builder;
  }
 private void assertGeoPointQuery(GeoDistanceRangeQueryBuilder queryBuilder, Query query)
     throws IOException {
   assertThat(query, instanceOf(XGeoPointDistanceRangeQuery.class));
   XGeoPointDistanceRangeQuery geoQuery = (XGeoPointDistanceRangeQuery) query;
   assertThat(geoQuery.getField(), equalTo(queryBuilder.fieldName()));
   if (queryBuilder.point() != null) {
     GeoPoint expectedPoint = new GeoPoint(queryBuilder.point());
     GeoUtils.normalizePoint(expectedPoint);
     assertThat(geoQuery.getCenterLat(), equalTo(expectedPoint.lat()));
     assertThat(geoQuery.getCenterLon(), equalTo(expectedPoint.lon()));
   }
   if (queryBuilder.from() != null && queryBuilder.from() instanceof Number) {
     double fromValue = ((Number) queryBuilder.from()).doubleValue();
     if (queryBuilder.unit() != null) {
       fromValue = queryBuilder.unit().toMeters(fromValue);
     }
     assertThat(geoQuery.getMinRadiusMeters(), closeTo(fromValue, 1E-5));
   }
   if (queryBuilder.to() != null && queryBuilder.to() instanceof Number) {
     double toValue = ((Number) queryBuilder.to()).doubleValue();
     if (queryBuilder.unit() != null) {
       toValue = queryBuilder.unit().toMeters(toValue);
     }
     assertThat(geoQuery.getMaxRadiusMeters(), closeTo(toValue, 1E-5));
   }
 }
 private void assertLegacyQuery(GeoDistanceRangeQueryBuilder queryBuilder, Query query)
     throws IOException {
   assertThat(query, instanceOf(GeoDistanceRangeQuery.class));
   GeoDistanceRangeQuery geoQuery = (GeoDistanceRangeQuery) query;
   assertThat(geoQuery.fieldName(), equalTo(queryBuilder.fieldName()));
   if (queryBuilder.point() != null) {
     GeoPoint expectedPoint = new GeoPoint(queryBuilder.point());
     if (GeoValidationMethod.isCoerce(queryBuilder.getValidationMethod())) {
       GeoUtils.normalizePoint(expectedPoint, true, true);
     }
     assertThat(geoQuery.lat(), equalTo(expectedPoint.lat()));
     assertThat(geoQuery.lon(), equalTo(expectedPoint.lon()));
   }
   assertThat(geoQuery.geoDistance(), equalTo(queryBuilder.geoDistance()));
   if (queryBuilder.from() != null && queryBuilder.from() instanceof Number) {
     double fromValue = ((Number) queryBuilder.from()).doubleValue();
     if (queryBuilder.unit() != null) {
       fromValue = queryBuilder.unit().toMeters(fromValue);
     }
     if (queryBuilder.geoDistance() != null) {
       fromValue = queryBuilder.geoDistance().normalize(fromValue, DistanceUnit.DEFAULT);
     }
     double fromSlop = Math.abs(fromValue) / 1000;
     if (queryBuilder.includeLower() == false) {
       fromSlop =
           NumericUtils.sortableLongToDouble(
                   (NumericUtils.doubleToSortableLong(Math.abs(fromValue)) + 1L))
               / 1000.0;
     }
     assertThat(geoQuery.minInclusiveDistance(), closeTo(fromValue, fromSlop));
   }
   if (queryBuilder.to() != null && queryBuilder.to() instanceof Number) {
     double toValue = ((Number) queryBuilder.to()).doubleValue();
     if (queryBuilder.unit() != null) {
       toValue = queryBuilder.unit().toMeters(toValue);
     }
     if (queryBuilder.geoDistance() != null) {
       toValue = queryBuilder.geoDistance().normalize(toValue, DistanceUnit.DEFAULT);
     }
     double toSlop = Math.abs(toValue) / 1000;
     if (queryBuilder.includeUpper() == false) {
       toSlop =
           NumericUtils.sortableLongToDouble(
                   (NumericUtils.doubleToSortableLong(Math.abs(toValue)) - 1L))
               / 1000.0;
     }
     assertThat(geoQuery.maxInclusiveDistance(), closeTo(toValue, toSlop));
   }
 }