{"id":13508228,"url":"https://github.com/CyrusNuevoDia/geocoder","last_synced_at":"2025-03-30T10:30:44.518Z","repository":{"id":36790346,"uuid":"41097131","full_name":"CyrusNuevoDia/geocoder","owner":"CyrusNuevoDia","description":"An Elixir Geocoder/Reverse Geocoder","archived":false,"fork":false,"pushed_at":"2025-03-01T17:23:45.000Z","size":353,"stargazers_count":127,"open_issues_count":4,"forks_count":60,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-28T13:12:54.734Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CyrusNuevoDia.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-08-20T13:28:05.000Z","updated_at":"2025-03-13T08:51:20.000Z","dependencies_parsed_at":"2023-07-12T16:16:24.349Z","dependency_job_id":"f30c1843-5dd8-426b-a79b-c8705d9bfe67","html_url":"https://github.com/CyrusNuevoDia/geocoder","commit_stats":null,"previous_names":["daodecyrus/geocoder","knrz/geocoder","cyrusnuevodia/geocoder"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CyrusNuevoDia%2Fgeocoder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CyrusNuevoDia%2Fgeocoder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CyrusNuevoDia%2Fgeocoder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CyrusNuevoDia%2Fgeocoder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CyrusNuevoDia","download_url":"https://codeload.github.com/CyrusNuevoDia/geocoder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246307578,"owners_count":20756473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T02:00:50.109Z","updated_at":"2025-03-30T10:30:44.491Z","avatar_url":"https://github.com/CyrusNuevoDia.png","language":"Elixir","funding_links":[],"categories":["Geolocation"],"sub_categories":[],"readme":"# Geocoder\n\n[![Build Status](https://github.com/knrz/geocoder/actions/workflows/elixir.yml/badge.svg)](https://github.com/knrz/geocoder/actions/workflows/elixir.yml)\n[![Inline docs](http://inch-ci.org/github/knrz/geocoder.svg?branch=master)](http://inch-ci.org/github/knrz/geocoder)\n[![Coverage Status](https://coveralls.io/repos/github/knrz/geocoder/badge.svg?branch=master)](https://coveralls.io/github/knrz/geocoder?branch=master)\n[![Module Version](https://img.shields.io/hexpm/v/geocoder.svg)](https://hex.pm/packages/geocoder)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/geocoder/)\n[![Total Download](https://img.shields.io/hexpm/dt/geocoder.svg)](https://hex.pm/packages/geocoder)\n[![License](https://img.shields.io/hexpm/l/geocoder.svg)](https://github.com/knrz/geocoder/blob/master/LICENSE)\n[![Last Updated](https://img.shields.io/github/last-commit/knrz/geocoder.svg)](https://github.com/knrz/geocoder/commits/master)\n\nA simple, efficient geocoder/reverse geocoder with a built-in cache. This libary is quite felxible and extensible. You can pretty much extend any part of geocoder: caching store, workers, http client, JSON Codec, Provider, etc..\n\nIt supports the current providers out of box\n- Google map\n- OpenCageData\n- Openstreet maps\n\nIt supports the current http clients out of the box\n- :httpoison\n- :hackney\n\nIt supports the current JSON clients out of the box\n- :jason\n- :jsx\n\nIt supports the current caching store out of the box\n- In memory store (`Geocoder.Store`)\n\n## Installation\n\nadd `:geocoder` to your `mix.exs` dependencies:\n\n```elixir\ndef deps do\n  [\n    {:geocoder, \"~\u003e 2.0\"}\n  ]\nend\n```\n\nUpdate your mix dependencies:\n\n```bash\nmix deps.get\n```\n\n**Notes:** If you are Elixir \u003c 1.9, you'll need to use a version before `1.0`.\n\n## Configuration\n\nConfiguration is done by passing options to the `Geocoder.Supervisor`. See the `Geocoder.Config` for all possible configuration options. But you can just get started\nby adding this to your application tree\n\n```elixir\n[\n  Geocoder.Supervisor,\n]\n```\n\nThis will start the geocoder processes with all the default options, and should be compatible with 1.x (process + API + functionality)\n\n### Using a different Provider\n\nThe default client for Geocoder is OpenStreeMaps. You can easily switch to other providers  option. Or you can build your own as long as you implement the behavior `Geocoder.Provider` correctly. You can look at some examples inside the `lib/geocoder/providers/*`\n\nThen you can configure the different or custom provider with the following configuration:\n\n```elixir\n[\n  {Geocoder.Supervisor, worker_config: [provider: MyApp.Client,  key: \"some_api_key\"]},\n]\n```\n**NOTES**: OpenStreetMaps does not require key. Others provider do.\n\n### Using a different HTTP Client\n\nThe default client for Geocoder is HTTPoison. You can easily switch to Hackney as it comes as an option. Or you can build your own as long as you implement the behavior `Geocoder.HttpClient` correctly in your client\n\n\nThen you can configure the different or custom client with the following configuration:\n\n```elixir\n[\n  {Geocoder.Supervisor, worker_config: [http_client: MyApp.Client,  http_client_opts: []]}\n]\n```\n\nIf you need to set a proxy (or any other option supported by `HTTPoison.get/3`):\n\n```elixir\n[\n  {Geocoder.Supervisor, worker_config:\n    [\n      http_client_opts: [proxy: \"my.proxy.server:3128\", proxy_auth: {\"username\", \"password\"}]\n    ]\n   }\n  ...\n]\n```\n\n### Using a different Store\n\nThe default caching store is `Geocoder.Store`. This is a simple in memory cache (in a process basically) and is started by default.\n\nIf you want to change the Store, you can provide your own store implementation as well. See how the `Geocoder.Store` is implemented for an example. Then you will need to configure it using:\n\n```elixir\n[\n  {Geocoder.Supervisor, store_module: MyApp.MyStore},\n  ...\n]\n```\n### JSON Codec Configuration\n\nThe default JSON codec is Jason. You can create you custom codec or use different one as long as you implement the behavior `Geocoder.JSONCodec`.\n\nThen you can configure the different or custom JSON codec with the following configuration:\n\n```elixir\n[\n  {Geocoder.Supervisor, worker_config:\n    [\n      json_codec: Jason\n    ]\n   }\n  ...\n]\n```\n\n## Usage\n\n```elixir\n{:ok, coordinates } = Geocoder.call(\"Toronto, ON\")\n{:ok, coordinates } = Geocoder.call({43.653226, -79.383184})\n\ncoordinates.location.formatted_address\n```\n\nYou can pass options to the function that will be passed to the geocoder provider, for example:\n\n```elixir\nGeocoder.call(address: \"Toronto, ON\", language: \"es\", key: \"...\", ...)\n```\n\nYou can also change the provider on a per-call basis:\n\n```elixir\n{:ok, coordinates } =\n  with\n    # use the default provider\n    {:error, nil} \u003c- Geocoder.call(query),\n    # use an alternative provider. If `key` is not specified here the globally defined key will be used.\n    {:error, nil} \u003c- Geocoder.call(query, worker_config: [provider: Geocoder.Providers.OpenCageData, key: \"123\"]),\n    do: {:error}\n```\n\nSee [here](https://developers.google.com/maps/documentation/geocoding/intro#geocoding) and [here](https://developers.google.com/maps/documentation/geocoding/intro#ReverseGeocoding) for a list of supported parameters for the google maps geocoder provider (`Geocoder.Provider.GoogleMaps`).\n\nAnd you're done! How simple was that?\n\n## Development\n\nRight now, `:geocoder` supports three external providers (i.e. sources):\n\n* `Geocoder.Providers.GoogleMaps`\n* `Geocoder.Providers.OpenCageData`\n* `Geocoder.Providers.OpenStreetMaps`\n\nTo run the tests for these, and any future providers, you'll want to pass a `PROVIDER` environment variable as well as the `API_KEY`:\n\n```shell\nPROVIDER=google API_KEY=\"mykey\" mix test\n```\n\nBy default, the tests against the [`Fake`](./lib/geocoder/providers/fake.ex) provider.\n\nTo avoid making external requests in the context of the test suite, usage of the [`Fake`](./lib/geocoder/providers/fake.ex) provider is recommended.\n\nThe fake provider can be configured by adding a `:data` tuple to the configuration as shown below.\n\nThe keys of the data map must be in either [regex](https://hexdocs.pm/elixir/Regex.html) or\n[tuple](https://hexdocs.pm/elixir/Tuple.html) format (specifically a `{lat, lng}` style pair of floats).\n\n```elixir\n[\n  {Geocoder.Supervisor, worker_config:\n    [\n      data: %{\n        ~r/.*New York, NY.*/ =\u003e %{\n          lat: 40.7587905,\n          lon: -73.9787755,\n          bounds: %{\n            bottom: 40.7587405,\n            left: -73.9788255,\n            right: -73.9787255,\n            top: 40.7588405,\n          },\n          location: %{\n            city: \"New York\",\n            country: \"United States\",\n            country_code: \"us\",\n            county: \"New York County\",\n            formatted_address: \"30 Rockefeller Plaza, New York, NY 10112, United States of America\",\n            postal_code: \"10112\",\n            state: \"New York\",\n            street: \"Rockefeller Plaza\",\n            street_number: \"30\"\n          },\n        },\n        {40.7587905, -73.9787755} =\u003e %{\n          lat: 40.7587905,\n          lon: -73.9787755,\n          bounds: %{\n            bottom: 40.7587405,\n            left: -73.9788255,\n            right: -73.9787255,\n            top: 40.7588405,\n          },\n          location: %{\n            city: \"New York\",\n            country: \"United States\",\n            country_code: \"us\",\n            county: \"New York County\",\n            formatted_address: \"30 Rockefeller Plaza, New York, NY 10112, United States of America\",\n            postal_code: \"10112\",\n            state: \"New York\",\n            street: \"Rockefeller Plaza\",\n            street_number: \"30\"\n          },\n        }\n      }\n    ]\n   }\n  ...\n]\n```\n\n## Related \u0026 Alternative Packages\n\n* https://github.com/amotion-city/lib_lat_lon\n* https://github.com/navinpeiris/geoip\n* https://github.com/elixir-geolix/geolix\n\n## Copyright and License\n\nCopyright (c) 2023 Cyrus Nouroozi\n\nThe source code is licensed under the [MIT License](./LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCyrusNuevoDia%2Fgeocoder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FCyrusNuevoDia%2Fgeocoder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCyrusNuevoDia%2Fgeocoder/lists"}