/// <summary>
        /// Get more comprehensive information about the indicated place such as its complete address,
        /// phone number, user rating and reviews.
        /// </summary>
        /// <param name="placeId">A textual identifier that uniquely identifies a place</param>
        /// <param name="extensions">Response should include additional fields.</param>
        /// <param name="language">The language code, indicating in which language the results should be returned</param>
        /// <returns>Results</returns>
        public PlaceDetailsResponse GetPlaceDetails(string placeId, PlaceDetailsExtensionEnum?extensions = null,
                                                    string language = null)
        {
            // Assign query params
            var queryParams = new QueryParams
            {
                ["placeid"] = placeId
            };

            // Extensions
            if (extensions.HasValue)
            {
                queryParams["extensions"] = Converter.EnumFlagsList(extensions.Value);
            }

            // Language
            if (language != null)
            {
                queryParams["language"] = language;
            }

            // Get API response result
            var response = Client.APIGet <PlaceDetailsResponse>("/maps/api/place/details/json", queryParams);

            // Return it
            return(response);
        }
Exemple #2
0
        /// <summary>
        /// A Find Place request takes a text input, and returns a place.
        /// The text input can be any kind of Places data, for example, a name, address, or phone number.
        /// </summary>
        /// <param name="input">The text input specifying which place to search for (for example, a name, address, or phone number).</param>
        /// <param name="inputType">The type of input. This can be one of either textquery or phonenumber.
        ///     Phone numbers must be in international format (prefixed by a plus sign ("+"),
        ///     followed by the country code, then the phone number itself).
        /// </param>
        /// <param name="language">The language code, indicating in which language the results should be returned, if possible.</param>
        /// <param name="fields">The fields specifying the types of place data to return, separated by a comma.</param>
        /// <param name="locationBias">Prefer results in a specified area, by specifying either a radius plus lat/lng, or
        ///     two lat/lng pairs representing the points of a rectangle.  If this parameter is not specified, the API uses
        ///     IP address biasing by default.</param>
        public FindPlaceResponse FindPlace(string input, FindPlaceInputTypeEnum inputType,
                                           string language = null, FindPlaceFieldsEnum[] fields = null, LocationBias locationBias = null)
        {
            var queryParams = new QueryParams
            {
                ["input"]     = input,
                ["inputtype"] = inputType.GetSerializationName()
            };

            if (language != null)
            {
                queryParams["language"] = language;
            }
            if (fields != null)
            {
                queryParams["fields"] = string.Join(",", fields);
            }
            if (locationBias != null)
            {
                queryParams["locationbias"] = locationBias.ToString();
            }

            var response = Client.APIGet <FindPlaceResponse>("/maps/api/place/findplacefromtext/json", queryParams);

            return(response);
        }
        /// <summary>
        /// Reverse geocoding is the process of converting geographic coordinates into a
        /// human-readable address.
        /// </summary>
        /// <param name="location">The place for which you wish to obtain the closest, human-readable address.</param>
        /// <param name="language">The language in which to return results.</param>
        /// <param name="addressType">One or more address types to restrict results to.</param>
        /// <param name="locationType">One or more location types to restrict results to.</param>
        /// <returns>Reverse geocoding results</returns>
        public ReverseGeocodeResultResponse ReverseGeocode(PlaceLocation location, string language = null,
                                                           AddressTypeEnum?addressType             = null, GeometryLocationType?locationType = null)
        {
            // Assign query params
            var queryParams = new QueryParams()
            {
                ["latlng"] = Converter.Location(location)
            };

            if (language != null)
            {
                queryParams["language"] = language;
            }
            if (addressType != null)
            {
                queryParams["result_type"] = Converter.EnumFlagsList(addressType.Value);
            }
            if (locationType != null)
            {
                queryParams["location_type"] = Converter.EnumFlagsList(locationType.Value);
            }

            // Get API response result
            var response = Client.APIGet <ReverseGeocodeResultResponse>("/maps/api/geocode/json", queryParams);

            // Return it
            return(response);
        }
Exemple #4
0
        /// <summary>
        /// Get the posted speed limit for a given road segment
        /// </summary>
        /// <param name="places">Places on the road segment</param>
        /// <param name="units">Speed limits units</param>
        /// <returns>result</returns>
        public SpeedLimitsResponse SpeedLimits(List <IPlaceLocation> places, SpeedUnitEnum?units = null)
        {
            // Build url directly without using the usual QueryParams since the API V1 handles multiple values differently
            var queryParams = new StringBuilder();

            // Places (as repeated entries)
            foreach (var place in places)
            {
                queryParams.Append($"placeId={place.PlaceId}&");
            }

            // Speed limits units
            if (units.HasValue)
            {
                queryParams.Append($"units={units.Value.GetSerializationName()}&");
            }

            // Get API response result
            var response = Client.APIGet <SpeedLimitsResponse>(
                "https://roads.googleapis.com/v1/speedLimits?" + queryParams,
                new QueryParams(),
                baseUrl: "");

            // Return it
            return(response);
        }
        /// <summary>
        /// Returns Place predictions given a textual search string and optional geographic bounds.
        /// </summary>
        /// <param name="input">The text string on which to search</param>
        /// <param name="offset">The position, in the input term, of the last character that
        /// the service uses to match predictions.For example, if the input is 'Google' and
        /// the offset is 3, the service will match on 'Goo'.</param>
        /// <param name="location">The latitude/longitude value for which you wish to obtain
        /// the closest, human-readable address.</param>
        /// <param name="radius">The distance (in meters) within which to return place results.</param>
        /// <param name="language">The language code, indicating in which language the results should be returned, if possible</param>
        /// <param name="types">The types of place results to return</param>
        /// <param name="components">A grouping of places to which you would like to restrict your results.</param>
        /// <returns>Result</returns>
        public PlaceAutocompleteResponse AutoComplete(string input, int?offset = null, IGeoCoordinatesLocation location = null,
                                                      int?radius = null, string language = null, IEnumerable <string> types = null,
                                                      ComponentsFilter components = null)
        {
            // Assign query params
            var queryParams = new QueryParams
            {
                ["input"] = input
            };

            // Offset
            if (offset.HasValue)
            {
                queryParams["offset"] = Converter.Number(offset.Value);
            }

            // Location
            if (location != null)
            {
                queryParams["location"] = Converter.Location(location);
            }

            // Radius
            if (radius.HasValue)
            {
                queryParams["radius"] = Converter.Number(radius.Value);
            }

            // Language
            if (language != null)
            {
                queryParams["language"] = language;
            }

            // Types
            if (types != null)
            {
                queryParams["types"] = Converter.JoinList(types);
            }

            // Components
            if (components != null)
            {
                queryParams["components"] = Converter.Components(components);
            }

            // Get API response result
            var response = Client.APIGet <PlaceAutocompleteResponse>("/maps/api/place/autocomplete/json", queryParams);

            // Return it
            return(response);
        }
        /// <summary>
        /// Get elevations
        /// </summary>
        /// <param name="locations">Locations</param>
        /// <param name="locationsPerQueries">Locations per queries</param>
        /// <returns>Results</returns>
        public GetElevationResponse GetElevations(IEnumerable <IGeoCoordinatesLocation> locations, int locationsPerQueries = 50)
        {
            // Assign query params
            var queryParams = new QueryParams
            {
                ["locations"] = Converter.ShortestPath(locations)
            };

            // Get API response result
            var response = Client.APIGet <GetElevationResponse>("/maps/api/elevation/json", queryParams);

            // Return it
            return(response);
        }
        /// <summary>
        /// Provides elevation data sampled along a path on the surface of the earth.
        /// </summary>
        /// <param name="locations">List of latitude/longitude values from which you wish to calculate elevation data</param>
        /// <param name="samples">The number of sample points along a path for which to return elevation data.</param>
        /// <returns>Results</returns>
        public GetElevationResponse ElevationAlongPath(List <GeoCoordinatesLocation> locations, int samples)
        {
            // Assign query params
            var queryParams = new QueryParams
            {
                ["path"]    = Converter.ShortestPath(locations),
                ["samples"] = samples.ToString()
            };

            // Get API response result
            var response = Client.APIGet <GetElevationResponse>("/maps/api/elevation/json", queryParams);

            // Return it
            return(response);
        }
        /// <summary>
        /// Provides elevation data sampled along a path on the surface of the earth.
        /// </summary>
        /// <param name="polylinePath">Polyline path from which you wish to calculate elevation data</param>
        /// <param name="samples">The number of sample points along a path for which to return elevation data.</param>
        /// <returns>Results</returns>
        public GetElevationResponse ElevationAlongPath(EncodedPolyline polylinePath, int samples)
        {
            // Assign query params
            var queryParams = new QueryParams
            {
                ["path"]    = $"enc:{polylinePath.EncodedPoints}",
                ["samples"] = samples.ToString()
            };

            // Get API response result
            var response = Client.APIGet <GetElevationResponse>("/maps/api/elevation/json", queryParams);

            // Return it
            return(response);
        }
        /// <summary>
        /// Provides time offset data for locations on the surface of the earth
        /// </summary>
        /// <param name="location">The location to look up.</param>
        /// <param name="timestamp">The desired time as seconds since midnight, January 1, 1970 UTC. The Google Maps Time
        /// Zone API uses the timestamp to determine whether or not Daylight Savings should be applied. Times before 1970
        /// can be expressed as negative values.</param>
        /// <param name="language">The language in which to return results.</param>
        /// <returns>Result</returns>
        public GetTimeZoneResponse GetTimeZone(GeoCoordinatesLocation location, long timestamp, string language = null)
        {
            // Assign query params
            var queryParams = new QueryParams
            {
                ["location"]  = Converter.Location(location),
                ["timestamp"] = Converter.Time(timestamp)
            };

            // Get API response result
            var response = Client.APIGet <GetTimeZoneResponse>("/maps/api/timezone/json", queryParams);

            // Return it
            return(response);
        }
        /// <summary>
        /// Geocoding is the process of converting addresses
        /// (like "1600 Amphitheatre Parkway, Mountain View, CA") into geographic
        /// coordinates(like latitude 37.423021 and longitude -122.083739), which you
        /// can use to place markers or position the map.
        /// </summary>
        /// <param name="address">
        /// The address to geocode.
        /// </param>
        /// <param name="components">
        /// A component filter for which you wish to obtain a
        /// geocode, for example: {"administrative_area": "TX","country": "US"}
        /// </param>
        /// <param name="bounds">
        /// The bounding box of the viewport within which to bias geocode
        /// results more prominently.
        /// </param>
        /// <param name="region">
        /// The region code, specified as a ccTLD ("top-level domain") two-character value.
        /// </param>
        /// <param name="language">
        /// The language in which to return results.
        /// </param>
        /// <returns>Geocoding results</returns>
        public GeocodeResponse Geocode(string address             = null, ComponentsFilter components = null,
                                       ViewportBoundingBox bounds = null, string region               = null, string language = null)
        {
            // Assign query params
            var queryParams = new QueryParams();

            // Address
            if (address != null)
            {
                queryParams["address"] = address;
            }

            // Components
            if (components != null)
            {
                queryParams["components"] = Converter.Components(components);
            }

            // Bounds
            if (bounds != null)
            {
                queryParams["bounds"] = Converter.Bounds(bounds);
            }

            // Regions
            if (region != null)
            {
                queryParams["region"] = region;
            }

            // Language
            if (language != null)
            {
                queryParams["language"] = language;
            }

            // Get API response result
            var response = Client.APIGet <GeocodeResponse>("/maps/api/geocode/json", queryParams);

            // Return it
            return(response);
        }
Exemple #11
0
        /// <summary>
        /// Get the posted speed limit for a given road segment
        /// </summary>
        /// <param name="path">The path to be snapped</param>
        /// <param name="units">Speed limits units</param>
        /// <returns>result</returns>
        public SpeedLimitsResponse SpeedLimits(List <IGeoCoordinatesLocation> path, SpeedUnitEnum?units = null)
        {
            // Assign query params
            var queryParams = new QueryParams
            {
                ["path"] = Converter.Location(path)
            };

            // Speed limits units
            if (units.HasValue)
            {
                queryParams["units"] = units.Value.GetSerializationName();
            }

            // Get API response result
            var response = Client.APIGet <SpeedLimitsResponse>("/v1/speedLimits", queryParams,
                                                               baseUrl: "https://roads.googleapis.com");

            // Return it
            return(response);
        }
Exemple #12
0
        /// <summary>
        /// takes up to 100 GPS points collected along a route, and returns a similar set of data, with the points snapped
        /// to the most likely roads the vehicle was traveling along
        /// </summary>
        /// <param name="path">The path to be snapped</param>
        /// <param name="interpolate">Whether to interpolate a path to include all points forming the full road-geometry</param>
        /// <returns>Result</returns>
        public SnapToRoadsResponse SnapToRoads(List <IGeoCoordinatesLocation> path, bool?interpolate = null)
        {
            // Assign query params
            var queryParams = new QueryParams
            {
                ["path"] = Converter.Location(path)
            };

            // Interpolate
            if (interpolate.HasValue)
            {
                queryParams["interpolate"] = "true";
            }

            // Get API response result
            var response = Client.APIGet <SnapToRoadsResponse>("/v1/snapToRoads", queryParams,
                                                               baseUrl: "https://roads.googleapis.com");

            // Return it
            return(response);
        }
        /// <summary>
        /// Returns Place predictions given a textual search query, such as
        /// "pizza near New York", and optional geographic bounds.
        /// </summary>
        /// <param name="input">The text query on which to search</param>
        /// <param name="offset">The position, in the input term, of the last character that
        /// the service uses to match predictions.For example, if the input is 'Google' and
        /// the offset is 3, the service will match on 'Goo'.</param>
        /// <param name="location">The latitude/longitude value for which you wish to obtain
        /// the closest, human-readable address.</param>
        /// <param name="radius">The distance (in meters) within which to return place results.</param>
        /// <param name="language">The language code, indicating in which language the results should be returned, if possible</param>
        /// <returns>Result</returns>
        public PlaceQueryAutoCompleteResponse QueryAutoComplete(string input, int?offset = null, IGeoCoordinatesLocation location = null,
                                                                int?radius = null, string language = null)
        {
            // Assign query params
            var queryParams = new QueryParams
            {
                ["input"] = input
            };

            // Offset
            if (offset.HasValue)
            {
                queryParams["offset"] = Converter.Number(offset.Value);
            }

            // Location
            if (location != null)
            {
                queryParams["location"] = Converter.Location(location);
            }

            // Radius
            if (radius.HasValue)
            {
                queryParams["radius"] = Converter.Number(radius.Value);
            }

            // Language
            if (language != null)
            {
                queryParams["language"] = language;
            }

            // Get API response result
            var response = Client.APIGet <PlaceQueryAutoCompleteResponse>("/maps/api/place/queryautocomplete/json", queryParams);

            // Return it
            return(response);
        }
        /// <summary>
        /// Lets you search for places within a specified area.
        /// Google Maps APIs Premium Plan customers should not include a client or signature parameter with their requests.
        /// </summary>
        /// <param name="location">The latitude/longitude around which to retrieve place information</param>
        /// <param name="radius">the distance (in meters) within which to return place results. The maximum allowed
        /// radius is 50 000 meters.</param>
        /// <param name="keyword">A term to be matched against all content that Google has indexed for this place.</param>
        /// <param name="language">The language code, indicating in which language the results should be returned, if possible.</param>
        /// <param name="minprice">Restricts results to only those places within the specified range.</param>
        /// <param name="maxPrice">Restricts results to only those places within the specified range.</param>
        /// <param name="name">One or more terms to be matched against the names of places</param>
        /// <param name="openNow">Returns only those places that are open for business at the time the query is sent.</param>
        /// <param name="rankBy">The order in which results are listed</param>
        /// <param name="placeType">Restricts the results to places matching the specified type.</param>
        /// <param name="pageToken">Returns the next 20 results from a previously run search</param>
        /// <param name="zagatSelected">Restrict your search to locations that are Zagat selected businesses</param>
        /// <returns>Result</returns>
        public PlaceSearchResponse NearbySearch(IGeoCoordinatesLocation location, int?radius = null, string keyword = null, string language = null,
                                                int?minprice = null, int?maxPrice = null, IEnumerable <string> name = null, bool?openNow = null, PlaceRankByEnum?rankBy = null,
                                                PlaceSearchTypeEnum?placeType = null, string pageToken = null, bool?zagatSelected = null)
        {
            // Validations
            if (rankBy.HasValue && rankBy.Value == PlaceRankByEnum.Distance)
            {
                if (!(keyword != null || name != null || placeType != null))
                {
                    throw new ArgumentException(
                              "Either a keyword, name, or type arg is required when rankBy is set to Distance");
                }

                if (radius != null)
                {
                    throw new ArgumentException("Radius cannot be specified when rankBY is set to Distance");
                }
            }

            // Assign query params
            var queryParams = new QueryParams
            {
                ["location"] = Converter.Location(location)
            };

            // Radius
            if (radius.HasValue)
            {
                queryParams["radius"] = Converter.Number(radius.Value);
            }

            // Keyword
            if (keyword != null)
            {
                queryParams["keyword"] = keyword;
            }

            // Language
            if (language != null)
            {
                queryParams["language"] = language;
            }

            // Min/Max price
            if (minprice.HasValue)
            {
                queryParams["minprice"] = Converter.Number(minprice.Value);
            }
            if (maxPrice.HasValue)
            {
                queryParams["maxprice"] = Converter.Number(maxPrice.Value);
            }

            // Name
            if (name != null)
            {
                queryParams["name"] = Converter.JoinList(name);
            }

            // Open now
            if (openNow.HasValue)
            {
                queryParams["opennow"] = Converter.Value(openNow.Value);
            }

            // Rank by
            if (rankBy.HasValue)
            {
                queryParams["rankby"] = rankBy.Value.GetSerializationName();
            }

            // Place type
            if (placeType.HasValue)
            {
                queryParams["type"] = placeType.Value.GetSerializationName();
            }

            // Page token
            if (pageToken != null)
            {
                queryParams["pagetoken"] = pageToken;
            }

            // Zatgat selected
            if (zagatSelected.HasValue)
            {
                queryParams["zatgatselected"] = "";
            }

            // Get API response result
            var response = Client.APIGet <PlaceSearchResponse>("/maps/api/place/nearbysearch/json", queryParams);

            // Return it
            return(response);
        }
        /// <summary>
        /// Get directions between an origin point and a destination point.
        /// </summary>
        /// <param name="origin">
        /// The address or latitude/longitude value from which you wish
        /// to calculate directions.
        /// </param>
        /// <param name="destination">
        /// The address or latitude/longitude value from which
        /// you wish to calculate directions.
        /// </param>
        /// <param name="mode">
        /// Specifies the mode of transport to use when calculating directions.
        /// </param>
        /// <param name="waypoints">
        /// Specifies an array of waypoints. Waypoints alter a route by routing it through the specified location(s).
        /// </param>
        /// <param name="alternatives">
        /// If True, more than one route may be returned in the response.
        /// </param>
        /// <param name="avoid">
        /// Indicates that the calculated route(s) should avoid the indicated features.
        /// </param>
        /// <param name="language">
        /// The language in which to return results.
        /// </param>
        /// <param name="units">
        /// Specifies the unit system to use when displaying results.
        /// "metric" or "imperial"
        /// </param>
        /// <param name="region">
        /// The region code, specified as a ccTLD ("top-level domain"
        /// two-character value.
        /// </param>
        /// <param name="departureTime">
        /// Specifies the desired time of departure.
        /// </param>
        /// <param name="arrivalTime">
        /// Specifies the desired time of arrival for transit
        /// directions.Note: you can't specify both departureTime and
        /// arrivalTime.
        /// </param>
        /// <param name="optimizeWaypoints">
        /// Optimize the provided route by rearranging the
        /// waypoints in a more efficient order.
        /// </param>
        /// <param name="transitMode">
        /// Specifies one or more preferred modes of transit.
        /// This parameter may only be specified for requests where the mode is
        /// transit.Valid values are "bus", "subway", "train", "tram", "rail".
        /// "rail" is equivalent to ["train", "tram", "subway"].
        /// </param>
        /// <param name="transitRoutingPreference">
        /// Specifies preferences for transit
        /// requests.Valid values are "less_walking" or "fewer_transfers"
        /// </param>
        /// <param name="trafficModel">
        /// Specifies the predictive travel time model to use.
        /// Valid values are "best_guess" or "optimistic" or "pessimistic".
        /// The trafficModel parameter may only be specified for requests where
        /// the travel mode is driving, and where the request includes a
        /// departureTime.
        /// </param>
        /// <exception cref="ArgumentException"></exception>
        /// <returns>Result</returns>
        public GetDirectionsResponse GetDirections(Location origin, Location destination,
                                                   TransportationModeEnum?mode = null, IList <Location> waypoints = null,
                                                   bool alternatives           = false, AvoidFeaturesEnum?avoid   = null,
                                                   string language             = null, UnitSystemEnum?units   = null, string region = null, DateTime?departureTime = null,
                                                   DateTime?arrivalTime        = null, bool optimizeWaypoints = false, TransitModeEnum?transitMode = null,
                                                   TransitRoutingPreferenceEnum?transitRoutingPreference = null, TrafficModelEnum?trafficModel = null)
        {
            // Assign query params
            var queryParams = new QueryParams
            {
                ["origin"]      = Converter.Location(origin),
                ["destination"] = Converter.Location(destination)
            };

            // Transportation mode
            if (mode.HasValue)
            {
                queryParams["mode"] = mode.Value.GetSerializationName();
            }

            // Waypoints
            if (waypoints != null)
            {
                var waypointsValue = Converter.Location(waypoints);
                if (optimizeWaypoints)
                {
                    waypointsValue = "optimize:true|" + waypointsValue;
                }
                queryParams["waypoints"] = waypointsValue;
            }

            // Alternatives
            if (alternatives)
            {
                queryParams["alternatives"] = "true";
            }

            // Features to avoid
            if (avoid.HasValue)
            {
                queryParams["avoid"] = Converter.EnumFlagsList(avoid.Value);
            }

            // Language
            if (language != null)
            {
                queryParams["language"] = language;
            }

            // Units system
            if (units != null)
            {
                queryParams["units"] = units.Value.GetSerializationName();
            }

            // Region
            if (region != null)
            {
                queryParams["region"] = region;
            }

            // Departure time
            if (departureTime != null)
            {
                queryParams["departure_time"] = Converter.Time(departureTime.Value);
            }

            // Arrival time
            if (arrivalTime != null)
            {
                queryParams["arrival_time"] = Converter.Time(arrivalTime.Value);
            }

            // Should not specify both departure and arrival time
            if (departureTime != null && arrivalTime != null)
            {
                throw new ArgumentException("Should not specify both departure and arrival time.");
            }

            // Transit mode
            if (transitMode != null)
            {
                queryParams["transit_mode"] = Converter.EnumFlagsList(transitMode.Value);
            }

            // Transit routing preference
            if (transitRoutingPreference != null)
            {
                queryParams["transit_routing_preference"] = transitRoutingPreference.Value.GetSerializationName();
            }

            // Traffic model
            if (trafficModel != null)
            {
                queryParams["traffic_model"] = trafficModel.Value.GetSerializationName();
            }

            // Get API response result
            var response = Client.APIGet <GetDirectionsResponse>("/maps/api/directions/json", queryParams);

            // Return it
            return(response);
        }
        /// <summary>
        /// Returns information about a set of places based on a string
        /// </summary>
        /// <param name="query">The text string on which to search,</param>
        /// <param name="location">The latitude/longitude around which to retrieve place information</param>
        /// <param name="radius">the distance (in meters) within which to return place results. The maximum allowed
        /// radius is 50 000 meters.</param>
        /// <param name="language">The language code, indicating in which language the results should be returned, if possible.</param>
        /// <param name="minprice">Restricts results to only those places within the specified range.</param>
        /// <param name="maxPrice">Restricts results to only those places within the specified range.</param>
        /// <param name="openNow">Returns only those places that are open for business at the time the query is sent.</param>
        /// <param name="placeType">Restricts the results to places matching the specified type.</param>
        /// <param name="pageToken">Returns the next 20 results from a previously run search</param>
        /// <param name="zagatSelected">Restrict your search to locations that are Zagat selected businesses</param>
        /// <returns>Results</returns>
        public PlaceSearchResponse TextSearch(string query, IGeoCoordinatesLocation location = null, int?radius = null, string language    = null, int?minprice = null, int?maxPrice = null, bool?openNow = null,
                                              PlaceSearchTypeEnum?placeType = null, string pageToken            = null, bool?zagatSelected = null)
        {
            // Assign query params
            var queryParams = new QueryParams
            {
                ["query"] = query
            };

            // Location
            if (location != null)
            {
                queryParams["location"] = Converter.Location(location);
            }

            // Radius
            if (radius.HasValue)
            {
                queryParams["radius"] = Converter.Number(radius.Value);
            }

            // Language
            if (language != null)
            {
                queryParams["language"] = language;
            }

            // Min/Max price
            if (minprice.HasValue)
            {
                queryParams["minprice"] = Converter.Number(minprice.Value);
            }
            if (maxPrice.HasValue)
            {
                queryParams["maxprice"] = Converter.Number(maxPrice.Value);
            }

            // Open now
            if (openNow.HasValue)
            {
                queryParams["opennow"] = Converter.Value(openNow.Value);
            }

            // Place type
            if (placeType.HasValue)
            {
                queryParams["type"] = placeType.Value.GetSerializationName();
            }

            // Page token
            if (pageToken != null)
            {
                queryParams["pagetoken"] = pageToken;
            }

            // Zatgat selected
            if (zagatSelected.HasValue)
            {
                queryParams["zatgatselected"] = "";
            }

            // Get API response result
            var response = Client.APIGet <PlaceSearchResponse>("/maps/api/place/textsearch/json", queryParams);

            // Return it
            return(response);
        }
        /// <summary>
        /// Get travel distance and time for a matrix of origins and destinations
        /// </summary>
        /// <param name="origins">One or more locations to use as the starting point for calculating travel distance and time.</param>
        /// <param name="destinations">One or more locations to use as the finishing point for calculating travel distance and time.</param>
        /// <param name="mode">The mode of transport to use when calculating distance.</param>
        /// <param name="language">The language in which to return results.</param>
        /// <param name="avoid">Introduces restrictions to the route.</param>
        /// <param name="units">The unit system to use when expressing distance as text</param>
        /// <param name="arrivalTime">The desired time of arrival for transit requests</param>
        /// <param name="departureTime">The desired time of departure</param>
        /// <param name="trafficModel">Specifies the assumptions to use when calculating time in traffic. </param>
        /// <param name="transitMode">Specifies one or more preferred modes of transit.</param>
        /// <param name="transitRoutingPreference">Specifies preferences for transit requests.</param>
        /// <returns></returns>
        public GetDistanceMatrixResponse GetDistanceMatrix(IEnumerable <IAddressOrGeoCoordinatesLocation> origins,
                                                           IEnumerable <IAddressOrGeoCoordinatesLocation> destinations, TransportationModeEnum?mode = null,
                                                           string language        = null, AvoidFeaturesEnum?avoid = null, UnitSystemEnum?units = null, DateTime?arrivalTime = null,
                                                           DateTime?departureTime = null, TrafficModelEnum?trafficModel = null, TransitModeEnum?transitMode = null,
                                                           TransitRoutingPreferenceEnum?transitRoutingPreference = null)
        {
            // Assign query params
            var queryParams = new QueryParams
            {
                ["origins"]      = Converter.Location(origins),
                ["destinations"] = Converter.Location(destinations)
            };

            // Transportation mode
            if (mode.HasValue)
            {
                queryParams["mode"] = mode.Value.GetSerializationName();
            }

            // Language
            if (language != null)
            {
                queryParams["language"] = language;
            }

            // Features to avoid
            if (avoid.HasValue)
            {
                // Only one restriction can be specified.
                var selectedRestrictions = avoid.Value.GetFlags();
                if (selectedRestrictions.Count() == 1)
                {
                    queryParams["avoid"] = Converter.EnumFlagsList(avoid.Value);
                }
                else
                {
                    throw new ArgumentOutOfRangeException(nameof(avoid), "Only one restriction can be specified.");
                }
            }

            // Units system
            if (units != null)
            {
                queryParams["units"] = units.Value.GetSerializationName();
            }

            // Departure time
            if (departureTime != null)
            {
                queryParams["departure_time"] = Converter.Time(departureTime.Value);
            }

            // Arrival time
            if (arrivalTime != null)
            {
                queryParams["arrival_time"] = Converter.Time(arrivalTime.Value);
            }

            // Should not specify both departure and arrival time
            if (departureTime != null && arrivalTime != null)
            {
                throw new ArgumentException("Should not specify both departure and arrival time.");
            }

            // Traffic model
            if (trafficModel != null)
            {
                queryParams["traffic_model"] = trafficModel.Value.GetSerializationName();
            }

            // Transit mode
            if (transitMode != null)
            {
                queryParams["transit_mode"] = Converter.EnumFlagsList(transitMode.Value);
            }

            // Transit routing preference
            if (transitRoutingPreference != null)
            {
                queryParams["transit_routing_preference"] = transitRoutingPreference.Value.GetSerializationName();
            }

            // Get API response result
            var response = Client.APIGet <GetDistanceMatrixResponse>("/maps/api/distancematrix/json", queryParams);

            // Return it
            return(response);
        }