diff --git a/docs/google-maps.md b/docs/google-maps.md index 4455a47e49..e4be55c2be 100644 --- a/docs/google-maps.md +++ b/docs/google-maps.md @@ -1,8 +1,12 @@ # Google Maps -The Flex template for web uses the Google Maps API for showing a map and in searching locations in -the search autocompletion. This document describes how to setup the API key for the API requests to -work properly. +The Flex template for web can use the Google Maps API for showing a map and in searching locations +in the search autocompletion. This document describes how to set up the API key for the API requests +to work properly. + +> Note: before making the change to Google Map, you should consider if you are OK with their current +> pricing. There's a pricing calculator available in their +> [pricing page](https://cloud.google.com/maps-platform/pricing/) ## Generate a Google Maps API key @@ -28,15 +32,144 @@ REACT_APP_GOOGLE_MAPS_API_KEY=my-key-here ## Setup common locations to reduce typing -The location autocomplete input in the landing page and the topbar can -be configured to have specific locations shown by default when the -user focuses on the input and hasn't yet typed in any searches. This -reduces the typing required for common searches, and also reduces the -need to use the Google Places geolocation API that much. +The location autocomplete-input in the landing page and the topbar can be configured to have +specific locations shown by default when the user focuses on the input and hasn't yet typed in any +searches. This reduces the typing required for common searches and also reduces the need to use +Google Map Places API that much. + +To use default searches, another environment variable needs to be set: + +``` +REACT_APP_DEFAULT_SEARCHES_ENABLED=true +``` + +The default locations have been described in file: +[src/default-location-searches.js](../src/default-location-searches.js). + +The same environment variable also shows "current location" suggestion, which will make the browser +to ask user's current location. This is a fast way to search listings nearby. You can specify +whether to use the current location from [config.js](../src/config.js). Search for variables: +`suggestCurrentLocation` and `currentLocationBoundsDistance`. + +## Change components: use Google Map versions instead of Mapbox + +### 1. Include Google Map script instead of Mapbox scripts + +Mapbox related scripts can be removed from index.html and instead use Google Map script described in +comments. + +_public/index.html:_ + +```html + + + + + +``` + +### 2. Searching with Google's geocoding API + +Location search aka LocationAutocompleteInput should use Google Map specific geocoder. The correct +import is written to the comments of LocationAutocompleteInput component. + +_src/components/LocationAutocompleteInput/LocationAutocompleteInputImpl.js:_ + +```js +import Geocoder, { GeocoderAttribution, CURRENT_LOCATION_ID } from './GeocoderMapbox'; +// import Geocoder, { GeocoderAttribution, CURRENT_LOCATION_ID } from './GeocoderGoogleMaps'; +``` + +Furthermore, Google Map states in their terms of service that Google logo needs to be visible when +using their geocoding service. It is available as a background image below the autocomplete +predictions. However, there needs to be enough padding for that logo. You can change the padding +through `marketplace.css`. -The default locations can be configured in -[src/components/LocationAutocompleteInput/GeocoderGoogleMaps.js](../src/components/LocationAutocompleteInput/GeocoderGoogleMaps.js). +_src/marketplace.css:_ + +```js +/* Google Maps needs 72px bottom padding to accommodate logo, Mapbox doesn't have one */ +--locationAutocompleteBottomPadding: 8px; +``` + +### 3. Show correct map on ListingPage (Map component) + +Google Map version (containing both static and dynamic maps) can be taken into use by importing +correct map subcomponent. + +_src/components/Map/Map.js:_ + +```js +import { StaticMap, DynamicMap, isMapsLibLoaded } from './MapboxMap'; +// import { StaticMap, DynamicMap, isMapsLibLoaded } from './GoogleMap'; +``` + +### 4. SearchMap.js + +The most complex change is happening in SearchPage. First, you need to import `SearchMapWithMapbox` +instead of `SearchMapWithGoogleMap`. + +_src/components/SearchMap/SearchMap.js:_ + +Remove this: + +```js +import SearchMapWithMapbox, { + LABEL_HANDLE, + INFO_CARD_HANDLE, + getMapBounds, + getMapCenter, + fitMapToBounds, + isMapsLibLoaded, +} from './SearchMapWithMapbox'; +``` + +And add this instead: + +```js +import SearchMapWithGoogleMap, { + LABEL_HANDLE, + INFO_CARD_HANDLE, + getMapBounds, + getMapCenter, + fitMapToBounds, + isMapsLibLoaded, +} from './SearchMapWithGoogleMap'; +``` + +Then, in `render` method, you need to put `SearchMapWithGoogleMap` component into use by replacing +`SearchMapWithMapbox` which is defined inside `ReusableMapContainer`. The component with correct +props is already there in the comments: + +```js +// Using Google Maps as map provider should use following component +// instead of SearchMapWithMapbox: +// +// +// } +// mapElement={
} +// bounds={bounds} +// center={center} +// location={location} +// infoCardOpen={infoCardOpen} +// listings={listings} +// activeListingId={activeListingId} +// mapComponentRefreshToken={this.state.mapReattachmentCount} +// createURLToListing={this.createURLToListing} +// onListingClicked={this.onListingClicked} +// onListingInfoCardClicked={this.onListingInfoCardClicked} +// onMapLoad={this.onMapLoadHandler} +// onMapMoveEnd={onMapMoveEnd} +// zoom={zoom} +// /> +``` -You can also setup a default location that asks the user's current -location. This will enable e.g. searching listings near the user. The -current location is configured in the same file. +The only extra step is to make `mapRootClassName` property available from `this.props` at the +beginning of the `render` method. diff --git a/docs/map-providers.md b/docs/map-providers.md new file mode 100644 index 0000000000..9979438760 --- /dev/null +++ b/docs/map-providers.md @@ -0,0 +1,67 @@ +# Integrating to map providers + +> After Google made significant pricing changes to their Google Map APIs, we pushed hard to reduce +> the number of calls to the Google Maps API. After careful consideration, we also decided that +> there needs to be an alternative map provider available for users of Flex Template for Web. We +> ended up to choose Mapbox since they have been a major innovator in the field. + +## Setting up the Mapbox integration (the default map provider) + +### 1. Generate a Mapbox access key + +Sign up for a Mapbox and go to [account page](https://www.mapbox.com/account/). Then click +`Create access token`. + +> Read more about +> [access tokens and consider rotating them](https://www.mapbox.com/help/how-access-tokens-work/). + +### 2. Setup the application to use the access key + +The application uses the `REACT_APP_MAPBOX_ACCESS_TOKEN` environment variable for the key value. For +local development, you can add the variable in the Gitignored `.env` file in the project root: + +``` +REACT_APP_MAPBOX_ACCESS_TOKEN=my-access-token-here +``` + +### 3. Setup common locations to reduce typing + +The location autocomplete input in the landing page and the topbar can be configured to have +specific locations shown by default when the user focuses on the input and hasn't yet typed in any +searches. This reduces the typing required for common searches and also reduces the need to use +Mapbox geolocation API that much. + +To use default searches, another environment variable needs to be set: + +``` +REACT_APP_DEFAULT_SEARCHES_ENABLED=true +``` + +The default locations have been described in file: +[src/default-location-searches.js](../src/default-location-searches.js). + +The same environment variable also shows "current location" suggestion, which will make the browser +to ask user's current location. This is a fast way to search listings nearby. You can specify +whether to use the current location from [config.js](../src/config.js). Search for variables: +`suggestCurrentLocation` and `currentLocationBoundsDistance`. + +### 4. Check rare default configurations + +Mapbox geocoding API doesn't always return bounding boxes for locations. Without bounding box +SearchMap component can't adjust zoom level right for that particular place. Therefore there are +default bounding boxes defined to different place types in +[Mapbox specific geocoder](../src/components/LocationAutocompleteInput/GeocoderMapbox.js). + +## Changing to other map providers + +### How to change from Mapbox to Google Map + +It is possible to use Google Map instead of the default map provider. Read more from +[Google Map setup guide](./google-maps.md) + +### How to use other map providers + +Our default map setup uses library called `mapbox-gl-js`. It is supported by quite many other map +providers too. So, as a first step, check if the map provider you are considering is supporting it - +if so, the change might be quite easy. However, if you change the map tile provider you should also +change geocoding API too (i.e. the API endpoint for `LocationAutocompleteInput` component).