private void parse(ParseContext context, GeoPoint point, String geohash) throws IOException {
    if (fieldType().ignoreMalformed == false) {
      if (point.lat() > 90.0 || point.lat() < -90.0) {
        throw new IllegalArgumentException(
            "illegal latitude value [" + point.lat() + "] for " + name());
      }
      if (point.lon() > 180.0 || point.lon() < -180) {
        throw new IllegalArgumentException(
            "illegal longitude value [" + point.lon() + "] for " + name());
      }
    }

    if (fieldType().coerce) {
      // by setting coerce to false we are assuming all geopoints are already in a valid coordinate
      // system
      // thus this extra step can be skipped
      // LUCENE WATCH: This will be folded back into Lucene's GeoPointField
      GeoUtils.normalizePoint(point, true, true);
    }

    if (fieldType().indexOptions() != IndexOptions.NONE || fieldType().stored()) {
      Field field =
          new Field(
              fieldType().names().indexName(),
              Double.toString(point.lat()) + ',' + Double.toString(point.lon()),
              fieldType());
      context.doc().add(field);
    }
    if (fieldType().isGeohashEnabled()) {
      if (geohash == null) {
        geohash = GeoHashUtils.encode(point.lat(), point.lon());
      }
      addGeohashField(context, geohash);
    }
    if (fieldType().isLatLonEnabled()) {
      latMapper.parse(context.createExternalValueContext(point.lat()));
      lonMapper.parse(context.createExternalValueContext(point.lon()));
    }
    if (fieldType().hasDocValues()) {
      CustomGeoPointDocValuesField field =
          (CustomGeoPointDocValuesField) context.doc().getByKey(fieldType().names().indexName());
      if (field == null) {
        field =
            new CustomGeoPointDocValuesField(
                fieldType().names().indexName(), point.lat(), point.lon());
        context.doc().addWithKey(fieldType().names().indexName(), field);
      } else {
        field.add(point.lat(), point.lon());
      }
    }
    multiFields.parse(this, context);
  }
 @Override
 public DoubleFieldMapper build(BuilderContext context) {
   fieldType.setOmitNorms(fieldType.omitNorms() && boost == 1.0f);
   DoubleFieldMapper fieldMapper =
       new DoubleFieldMapper(
           buildNames(context),
           fieldType.numericPrecisionStep(),
           boost,
           fieldType,
           docValues,
           nullValue,
           ignoreMalformed(context),
           coerce(context),
           postingsProvider,
           docValuesProvider,
           similarity,
           normsLoading,
           fieldDataSettings,
           context.indexSettings(),
           multiFieldsBuilder.build(this, context),
           copyTo);
   fieldMapper.includeInAll(includeInAll);
   return fieldMapper;
 }
  @Test
  public void testDoubles() throws Exception {
    List<Integer> docs = Arrays.asList(1, 5, 7);

    DoubleOpenHashSet hTerms = new DoubleOpenHashSet();
    List<Double> cTerms = new ArrayList<Double>(docs.size());
    for (int i = 0; i < docs.size(); i++) {
      double term = Double.valueOf(docs.get(i));
      hTerms.add(term);
      cTerms.add(term);
    }

    FieldDataTermsFilter hFilter = FieldDataTermsFilter.newDoubles(getFieldData(dblMapper), hTerms);

    int size = reader.maxDoc();
    FixedBitSet result = new FixedBitSet(size);

    result.clear(0, size);
    assertThat(result.cardinality(), equalTo(0));
    result.or(hFilter.getDocIdSet(reader.getContext(), reader.getLiveDocs()).iterator());
    assertThat(result.cardinality(), equalTo(docs.size()));
    for (int i = 0; i < reader.maxDoc(); i++) {
      assertThat(result.get(i), equalTo(docs.contains(i)));
    }

    // filter from mapper
    result.clear(0, size);
    assertThat(result.cardinality(), equalTo(0));
    result.or(
        dblMapper
            .termsFilter(ifdService, cTerms, null)
            .getDocIdSet(reader.getContext(), reader.getLiveDocs())
            .iterator());
    assertThat(result.cardinality(), equalTo(docs.size()));
    for (int i = 0; i < reader.maxDoc(); i++) {
      assertThat(result.get(i), equalTo(docs.contains(i)));
    }

    hFilter = FieldDataTermsFilter.newDoubles(getFieldData(lngMapper), hTerms);
    assertNull(hFilter.getDocIdSet(reader.getContext(), reader.getLiveDocs()));
  }
  @Before
  public void setup() throws Exception {
    super.setUp();

    // setup field mappers
    strMapper =
        new StringFieldMapper.Builder("str_value")
            .build(new Mapper.BuilderContext(null, new ContentPath(1)));

    lngMapper =
        new LongFieldMapper.Builder("lng_value")
            .build(new Mapper.BuilderContext(null, new ContentPath(1)));

    dblMapper =
        new DoubleFieldMapper.Builder("dbl_value")
            .build(new Mapper.BuilderContext(null, new ContentPath(1)));

    // create index and fielddata service
    ifdService = new IndexFieldDataService(new Index("test"), new DummyCircuitBreakerService());
    MapperService mapperService =
        MapperTestUtils.newMapperService(
            ifdService.index(), ImmutableSettings.Builder.EMPTY_SETTINGS);
    ifdService.setIndexService(new StubIndexService(mapperService));
    writer =
        new IndexWriter(
            new RAMDirectory(),
            new IndexWriterConfig(Lucene.VERSION, new StandardAnalyzer(Lucene.VERSION)));

    int numDocs = 10;
    for (int i = 0; i < numDocs; i++) {
      Document d = new Document();
      d.add(new StringField(strMapper.names().indexName(), "str" + i, Field.Store.NO));
      d.add(new LongField(lngMapper.names().indexName(), i, Field.Store.NO));
      d.add(new DoubleField(dblMapper.names().indexName(), Double.valueOf(i), Field.Store.NO));
      writer.addDocument(d);
    }

    reader = SlowCompositeReaderWrapper.wrap(DirectoryReader.open(writer, true));
  }
    @Override
    public GeoPointFieldMapper build(BuilderContext context) {
      ContentPath.Type origPathType = context.path().pathType();
      context.path().pathType(pathType);

      DoubleFieldMapper latMapper = null;
      DoubleFieldMapper lonMapper = null;
      GeoPointFieldType geoPointFieldType = (GeoPointFieldType) fieldType;

      context.path().add(name);
      if (enableLatLon) {
        NumberFieldMapper.Builder<?, ?> latMapperBuilder =
            doubleField(Names.LAT).includeInAll(false);
        NumberFieldMapper.Builder<?, ?> lonMapperBuilder =
            doubleField(Names.LON).includeInAll(false);
        if (precisionStep != null) {
          latMapperBuilder.precisionStep(precisionStep);
          lonMapperBuilder.precisionStep(precisionStep);
        }
        latMapper =
            (DoubleFieldMapper)
                latMapperBuilder
                    .includeInAll(false)
                    .store(fieldType.stored())
                    .docValues(false)
                    .build(context);
        lonMapper =
            (DoubleFieldMapper)
                lonMapperBuilder
                    .includeInAll(false)
                    .store(fieldType.stored())
                    .docValues(false)
                    .build(context);
        geoPointFieldType.setLatLonEnabled(latMapper.fieldType(), lonMapper.fieldType());
      }
      StringFieldMapper geohashMapper = null;
      if (enableGeoHash || enableGeohashPrefix) {
        // TODO: possible also implicitly enable geohash if geohash precision is set
        geohashMapper =
            stringField(Names.GEOHASH)
                .index(true)
                .tokenized(false)
                .includeInAll(false)
                .omitNorms(true)
                .indexOptions(IndexOptions.DOCS)
                .build(context);
        geoPointFieldType.setGeohashEnabled(
            geohashMapper.fieldType(), geoHashPrecision, enableGeohashPrefix);
      }
      context.path().remove();

      context.path().pathType(origPathType);

      // this is important: even if geo points feel like they need to be tokenized to distinguish
      // lat from lon, we actually want to
      // store them as a single token.
      fieldType.setTokenized(false);
      setupFieldType(context);
      fieldType.setHasDocValues(false);
      defaultFieldType.setHasDocValues(false);
      return new GeoPointFieldMapper(
          name,
          fieldType,
          defaultFieldType,
          context.indexSettings(),
          origPathType,
          latMapper,
          lonMapper,
          geohashMapper,
          multiFieldsBuilder.build(this, context));
    }