= Geocoder Component
:doctitle: Geocoder
:shortname: geocoder
:artifactid: camel-geocoder
:description: Find geocodes (latitude and longitude) for a given address or the other way round.
:since: 2.12
:supportlevel: Stable
:component-header: Only producer is supported
//Manually maintained attributes
:camel-spring-boot-name: geocoder

*Since Camel {since}*

*{component-header}*

The Geocoder component is used for looking up geocodes (latitude and
longitude) for a given address, or reverse lookup.

The component uses either a hosted https://github.com/openstreetmap/Nominatim[Nominatim server] or
the https://code.google.com/p/geocoder-java/[Java  API for Google Geocoder] library.

Maven users will need to add the following dependency to their `pom.xml`
for this component:

[source,xml]
------------------------------------------------------------
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-geocoder</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>
------------------------------------------------------------

== URI format

--------------------------------------------
geocoder:address:name[?options]
geocoder:latlng:latitude,longitude[?options]
--------------------------------------------

// component-configure options: START

// component-configure options: END

// component options: START
include::partial$component-configure-options.adoc[]
include::partial$component-endpoint-options.adoc[]
// component options: END

// endpoint options: START

// endpoint options: END


== Exchange data format

== Message Headers

[width="100%",cols="50%,50%",options="header",]
|=======================================================================
|Header |Description

|`CamelGeoCoderStatus` |Mandatory. Status code from the geocoder library. If status is
`GeocoderStatus.OK` then additional headers is enriched

|`CamelGeoCoderAddress` |The formatted address

|`CamelGeoCoderLat` |The latitude of the location.

|`CamelGeoCoderLng` |The longitude of the location.

|`CamelGeoCoderLatlng` |The latitude and longitude of the location. Separated by comma.

|`CamelGeoCoderCity` |The city long name.

|`CamelGeoCoderRegionCode` |The region code.

|`CamelGeoCoderRegionName` |The region name.

|`CamelGeoCoderCountryLong` |The country long name.

|`CamelGeoCoderCountryShort` |The country short name.

|`CamelGeoCoderPostalCode` |The postal code.
|=======================================================================

Notice not all headers may be provided depending on available data and
mode in use (address vs latlng).

=== Body using a Nominatim Server

Camel will deliver the body as a JSONv2 type.

=== Body using a Google Server

Camel will deliver the body as a
`com.google.code.geocoder.model.GeocodeResponse` type. +
And if the address is `"current"` then the response is a String type
with a JSON representation of the current location.

If the option `headersOnly` is set to `true` then the message body is
left as-is, and only headers will be added to the
Exchange.

== Samples

In the example below we get the latitude and longitude for Paris, France

[source,java]
-----------------------------------------
from("direct:start")
    .to("geocoder:address:Paris, France?type=NOMINATIM&serverUrl=https://nominatim.openstreetmap.org")
-----------------------------------------

If you provide a header with the `CamelGeoCoderAddress` then that
overrides the endpoint configuration, so to get the location of
Copenhagen, Denmark we can send a message with a headers as shown:

[source,java]
------------------------------------------------------------------------------------------------------
template.sendBodyAndHeader("direct:start", "Hello", GeoCoderConstants.ADDRESS, "Copenhagen, Denmark");
------------------------------------------------------------------------------------------------------

To get the address for a latitude and longitude we can do:

[source,java]
---------------------------------------------------------------------------------------------------------------------------------------------------
from("direct:start")
    .to("geocoder:latlng:40.714224,-73.961452")
    .log("Location ${header.CamelGeocoderAddress} is at lat/lng: ${header.CamelGeocoderLatlng} and in country ${header.CamelGeoCoderCountryShort}")
---------------------------------------------------------------------------------------------------------------------------------------------------

Which will log

--------------------------------------------------------------------------------------------------------------
Location 285 Bedford Avenue, Brooklyn, NY 11211, USA is at lat/lng: 40.71412890,-73.96140740 and in country US
--------------------------------------------------------------------------------------------------------------

To get the current location using the Google GeoCoder,
you can use "current" as the address as shown:

[source,java]
-----------------------------------
from("direct:start")
    .to("geocoder:address:current")
-----------------------------------


include::spring-boot:partial$starter.adoc[]
