• Stars
    star
    1,037
  • Rank 44,435 (Top 0.9 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created almost 12 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A geocoding/address-lookup library supporting various api providers.

Leaflet.GeoSearch

All Contributors

Demo and Docs: smeijer.github.io/leaflet-geosearch

animation of geosearch

Installation

more docs @ https://smeijer.github.io/leaflet-geosearch/#installation

with npm:

npm install --save leaflet-geosearch

or yarn:

yarn add leaflet-geosearch

Browser support / Polyfills

more docs @ https://smeijer.github.io/leaflet-geosearch/#browser-support--polyfills

This library is written with the latest technologies in mind. Thereby it is required to include some polyfills when you wish to support older browsers. These polyfills are recommended for IE and Safari support:

About

This library adds support for geocoding (address lookup, a.k.a. geoseaching) to your (web) application. It comes with controls to be embedded in your Leaflet map.

Check out the docs for various possibilities.

The library uses so-called "providers" to take care of building the correct service URL and parsing the retrieved data into a uniform format. Thanks to this architecture, it is pretty easy to add your own providers, so you can use your own geocoding service(s).

The control comes with a number of default providers:

Although this project is still named leaflet-geosearch, this library is also usable without LeafletJS, and does not have any dependencies whatsoever.

Usage

more docs @ https://smeijer.github.io/leaflet-geosearch/usage

Let's first start with an little example on how to use this control without leaflet. For example as an address lookup on a webshop order form. Perhaps to search for the closest alternative package delivery point? Or to link it to your own custom map component.

// import
import { OpenStreetMapProvider } from 'leaflet-geosearch';

// setup
const provider = new OpenStreetMapProvider();

// search
const results = await provider.search({ query: input.value });

Of course, something like this should be bound to something like a form or input:

import { OpenStreetMapProvider } from 'leaflet-geosearch';

const form = document.querySelector('form');
const input = form.querySelector('input[type="text"]');

form.addEventListener('submit', async (event) => {
  event.preventDefault();

  const results = await provider.search({ query: input.value });
  console.log(results); // ยป [{}, {}, {}, ...]
});

Instead of es6 async / await you can also use promises like:

provider.search({ query: '...' }).then(function (result) {
  // do something with result;
});

Results

The search event of all providers return an array of result objects. The base structure is uniform between the providers. It provides a object like:

const result = {
  x: Number, // lon,
  y: Number, // lat,
  label: String, // formatted address
  bounds: [
    [Number, Number], // s, w - lat, lon
    [Number, Number], // n, e - lat, lon
  ],
  raw: {}, // raw provider result
};

The contents of the raw property differ per provider. This is the unprocessed result from the 3th party service. This property is included for developer convenience. leaflet-geosearch does not use it. If you need to know the contents of this property, you should check the 3th party developer docs. (or use your debugger)

Providers

When OpenStreetMap does not match your needs; you can also choose to use the Algolia, Bing, Esri, Geocode Earth, Google, LocationIQ, OpenCage, or Pelias providers. Most of those providers do however require API keys. See the documentation pages on the relevant organisations on how to obtain these keys.

In case you decide to write your own provider, please consider submitting a PR to share your work with us.

Providers are unaware of any options you can give them. They are simple proxies to their endpoints. There is only one special property, and that is the params option. The difference being; that params will be included in the endpoint url. Often being used for API KEYS, where as the other attributes can be used for provider configuration.

Using with LeafletJS

This project comes with a leaflet control to hook the search providers into leaflet. The example below uses the OpenStreetMap Provider, but you can exchange this with on of the other included providers as well as your own custom made providers. Remember to setup the provider with a key when required (Google and Bing for example).

search control

import L from 'leaflet';
import { GeoSearchControl, OpenStreetMapProvider } from 'leaflet-geosearch';

const provider = new OpenStreetMapProvider();

const searchControl = new GeoSearchControl({
  provider: provider,
});

const map = new L.Map('map');
map.addControl(searchControl);

Using with react-leaflet

Usage with react-leaflet is similar to the usage with plain Leaflet. This example uses the new MapBoxProvider and adds an api key to the params list when accessing the remote API. Note the useMap hook which is the only notable diffrence to the leaflet example.

import { GeoSearchControl, MapBoxProvider } from 'leaflet-geosearch';
import { useMap } from 'react-leaflet';
const SearchField = ({ apiKey }) => {
  const provider = new MapBoxProvider({
    params: {
      access_token: apiKey,
    },
  });

  // @ts-ignore
  const searchControl = new GeoSearchControl({
    provider: provider,
  });

  const map = useMap();
  useEffect(() => {
    map.addControl(searchControl);
    return () => map.removeControl(searchControl);
  }, []);

  return null;
};

The useEffect hook used in SearchField even allows for conditional rendering of the search field.

import { MapContainer } from 'react-leaflet';
const MyMap = () => {
  // ...
  return (
    <MapContainer>
      {showSearch && <SearchField apiKey={apiKey} />}

      {/* ... */}
    </MapContainer>
  );
};

GeoSearchControl

There are some configurable options like setting the position of the search input and whether or not a marker should be displayed at the position of the search result.

search button There are two visual styles of this control. One is the more 'leaflet-way' by putting the search control under a button (see image above). And one where the search control is permanently shown as a search bar (see image under using with LeafletJS).

Render style

This render style can be set by the optional style option.

new GeoSearchControl({
  provider: myProvider, // required
  style: 'bar', // optional: bar|button  - default button
}).addTo(map);

AutoComplete

Auto complete can be configured by the parameters autoComplete and autoCompleteDelay. A little delay is required to not DDOS the server on every keystroke.

new GeoSearchControl({
  provider: myProvider, // required
  autoComplete: true, // optional: true|false  - default true
  autoCompleteDelay: 250, // optional: number      - default 250
}).addTo(map);

Show result

There are a number of options to adjust the way results are visualized.

new GeoSearchControl({
  provider: myProvider, // required
  showMarker: true, // optional: true|false  - default true
  showPopup: false, // optional: true|false  - default false
  marker: {
    // optional: L.Marker    - default L.Icon.Default
    icon: new L.Icon.Default(),
    draggable: false,
  },
  popupFormat: ({ query, result }) => result.label, // optional: function    - default returns result label,
  resultFormat: ({ result }) => result.label, // optional: function    - default returns result label
  maxMarkers: 1, // optional: number      - default 1
  retainZoomLevel: false, // optional: true|false  - default false
  animateZoom: true, // optional: true|false  - default true
  autoClose: false, // optional: true|false  - default false
  searchLabel: 'Enter address', // optional: string      - default 'Enter address'
  keepResult: false, // optional: true|false  - default false
  updateMap: true, // optional: true|false  - default true
});

showMarker and showPopup determine whether or not to show a marker and/or open a popup with the location text.

marker can be set to any instance of a (custom) L.Icon.

popupFormat is callback function for displaying text on popup.

resultFormat is callback function for modifying the search result texts (e. g. in order to hide address components or change its ordering).

maxMarker determines how many last results are kept in memory. Default 1, but perhaps you want to show the last x results when searching for new queries as well.

retainZoomLevel is a setting that fixes the zoomlevel. Default behaviour is to zoom and pan to the search result. With retainZoomLevel on true, the map is only panned.

animateZoom controls whether or not the pan/zoom moment is being animated.

autoClose closes the result list if a result is selected by click/enter.

keepResult is used to keep the selected result in the search field. This prevents markers to disappear while using the autoClose feature.

updateMap controls whether or not the map re-centers on the selection.

Events

geosearch/showlocation is fired when location is chosen from the result list.

map.on('geosearch/showlocation', yourEventHandler);

geosearch/marker/dragend is fired when marker has been dragged.

map.on('geosearch/marker/dragend', yourEventHandler);

Development

Checkout the providers to see how easy it is to write your own. For research it can be interesting to see the difference between Bing and the others; because Bing does not support CORS, and requires jsonp to be used instead.

In case you decide to write your own provider, please consider submitting a PR to share your work with us.

You can use the docs as "development environment". Please run npm run start to get up and running. The docs will refresh when you change source files.

Contributors โœจ

Thanks goes to these wonderful people (emoji key):

Stephan Meijer
Stephan Meijer

๐Ÿค” ๐Ÿ’ป ๐Ÿš‡ ๐Ÿšง โš ๏ธ
Yurii Zinets
Yurii Zinets

๐Ÿ’ป โš ๏ธ ๐Ÿค”
David Hubner
David Hubner

๐Ÿ’ป
Nikolay Ninarski
Nikolay Ninarski

๐Ÿ’ป
Fredrik Ekelund
Fredrik Ekelund

๐Ÿ’ป
Rรฉmi Duraffort
Rรฉmi Duraffort

๐Ÿ’ป
Bung
Bung

๐Ÿ’ป
Cajus Pollmeier
Cajus Pollmeier

๐Ÿ’ป
Dan Dascalescu
Dan Dascalescu

๐Ÿ’ป
Devdatta Tengshe
Devdatta Tengshe

๐Ÿ’ป
emiltem
emiltem

๐Ÿ’ป
Johannes Raggam
Johannes Raggam

๐Ÿ’ป
Nathan Cahill
Nathan Cahill

๐Ÿ’ป
Tim Wisniewski
Tim Wisniewski

๐Ÿ’ป
Alex Balhatchet
Alex Balhatchet

๐Ÿ’ป โš ๏ธ ๐Ÿค”
Andreas Heigl
Andreas Heigl

๐Ÿ’ป
Arthur Toussaint
Arthur Toussaint

๐Ÿ’ป
Austin Brown
Austin Brown

๐Ÿ’ป
Brian Herbert
Brian Herbert

๐Ÿ’ป
Chris McDonald
Chris McDonald

๐Ÿ’ป
David Kobia
David Kobia

๐Ÿ’ป
 Dmytro Borysovskyi
Dmytro Borysovskyi

๐Ÿ’ป
Francis Lavoie
Francis Lavoie

๐Ÿ’ป
Ivan Gromov
Ivan Gromov

๐Ÿ’ป
Jason Pettett
Jason Pettett

๐Ÿ’ป
Johan
Johan

๐Ÿ’ป
Matt Krueger
Matt Krueger

๐Ÿ’ป
Mithgol
Mithgol

๐Ÿ’ป
mosh11
mosh11

๐Ÿ’ป
Sajjad Anwar
Sajjad Anwar

๐Ÿ’ป
Steve
Steve

๐Ÿ’ป
Stuart P. Bentley
Stuart P. Bentley

๐Ÿ’ป
joshrainwater
joshrainwater

๐Ÿ’ป
maxlath
maxlath

๐Ÿ’ป
Dariusz Pawlak
Dariusz Pawlak

๐Ÿ’ป
Ivelin Ralev
Ivelin Ralev

๐Ÿ’ป โš ๏ธ ๐Ÿค”
Srihari Thalla
Srihari Thalla

๐Ÿ’ป โš ๏ธ ๐Ÿค”
Kate Lizogubova
Kate Lizogubova

๐Ÿ’ป
Cory Leigh Rahman
Cory Leigh Rahman

๐Ÿค” ๐Ÿ’ป
Oliver Jรคgle
Oliver Jรคgle

๐Ÿ’ป
Kyle Houghton
Kyle Houghton

๐Ÿ’ป
nikitauskas
nikitauskas

๐Ÿ’ป
Patrice De Saint Steban
Patrice De Saint Steban

๐Ÿ’ป ๐Ÿ“–
AntoineAA
AntoineAA

๐Ÿ’ป
HolyMarcell
HolyMarcell

๐Ÿ“–
Grigor Pavlov
Grigor Pavlov

๐Ÿ’ป
Peter Johnson
Peter Johnson

๐Ÿ’ป โš ๏ธ
Arnaud Ferrand
Arnaud Ferrand

๐Ÿ“–
Konstantinos Stratis
Konstantinos Stratis

๐Ÿ’ป โš ๏ธ ๐Ÿ“–
Darren
Darren

๐Ÿ’ป โš ๏ธ ๐Ÿ“–
Paul Schreiber
Paul Schreiber

๐Ÿ’ป
Nick Silvestri
Nick Silvestri

๐Ÿค” ๐Ÿ’ป
teriblus
teriblus

๐Ÿ’ป
Caroline Vantim
Caroline Vantim

๐Ÿ’ป

This project follows the all-contributors specification. Contributions of any kind welcome!

More Repositories

1

unimported

Find and fix dangling files and unused dependencies in your JavaScript projects.
TypeScript
1,970
star
2

next-runtime

All you need to handle POST requests, file uploads, and api requests, in Next.js getServerSideProps.
TypeScript
589
star
3

spin-delay

Smart spinner helper for React, to manage the duration of loading states.
JavaScript
182
star
4

redux-define

Define action constants for Redux
JavaScript
174
star
5

where-broke

A CLI utility that helps finding breaking module versions using binary search and automated tests.
JavaScript
92
star
6

jest-partial

A partial matcher for Jest to simplify validation of complex structures.
JavaScript
20
star
7

latodoc

jsDoc3 Theme
JavaScript
19
star
8

graphql-args

A lib that parses the resolver ast, to return the requested object fields and provided params, at any nested level.
JavaScript
12
star
9

blocktober

say STOP to hacktoberfest spammers
JavaScript
11
star
10

paychecker

compare web developer salaries across the planet
TypeScript
5
star
11

issupported.com

Check if your browser is still supported by your favorite websites.
TypeScript
4
star
12

botz

TypeScript
4
star
13

open-api

TypeScript
3
star
14

git-prettier

Run prettier during git clean and smudge stages.
JavaScript
3
star
15

meijer.ws

MDX
2
star
16

cache-key

create stable cache keys from complex objects
TypeScript
2
star
17

smeijer

my โœจspecial โœจ profile repo
2
star
18

form-data-kit

a lib to parse, stringify, and expand FormData
TypeScript
2
star
19

geoxs-net

GeoXS website
CSS
1
star
20

eslint-config

JavaScript
1
star
21

meteor-prebuild

Compiler plugin to run node script prior to meteor build process
JavaScript
1
star
22

react-emotional

react-emotion extended with some plugins
JavaScript
1
star
23

fetch-addons

A collection of add-ons for the fetch API
TypeScript
1
star
24

something-new

whoei
TypeScript
1
star
25

nexis

CLI utils that help me bootstrap and manage my projects
TypeScript
1
star
26

fetch-repo

fetch a repo from github without git
TypeScript
1
star
27

sme-scripts

JavaScript
1
star
28

tsconfig

Shared TypeScript config for my projects
JavaScript
1
star
29

ts-project

JavaScript
1
star
30

link-workspaces

Link Yarn Workspaces while respecting publishConfig.directory
TypeScript
1
star
31

picoid

Nanoid configured to behave like Meteor Random.id
TypeScript
1
star
32

magicbell-react-nextjs

Next.js template for CodeSandbox Projects
TypeScript
1
star
33

gh-email

retrieve email address by github handle
JavaScript
1
star