protected function generateUrl(DistanceMatrixRequest $distanceMatrixRequest)
    {
        $httpQuery = array(
            'origins'      => array(),
            'destinations' => array(),
        );

        foreach ($distanceMatrixRequest->getOrigins() as $origin) {
            if (is_string($origin)) {
                $httpQuery['origins'][] = $origin;
            } else {
                $httpQuery['origins'][] = sprintf(
                    '%s,%s',
                    $origin->getLatitude(),
                    $origin->getLongitude()
                );
            }
        }

        foreach ($distanceMatrixRequest->getDestinations() as $destination) {
            if (is_string($destination)) {
                $httpQuery['destinations'][] = $destination;
            } else {
                $httpQuery['destinations'][] = sprintf(
                    '%s,%s',
                    $destination->getLatitude(),
                    $destination->getLongitude()
                );
            }
        }

        $httpQuery['origins'] = implode('|', $httpQuery['origins']);
        $httpQuery['destinations'] = implode('|', $httpQuery['destinations']);

        if ($distanceMatrixRequest->hasTravelMode()) {
            $httpQuery['mode'] = strtolower($distanceMatrixRequest->getTravelMode());
        }

        if ($distanceMatrixRequest->hasAvoidTolls() && $distanceMatrixRequest->getAvoidTolls()) {
            $httpQuery['avoidTolls'] = true;
        }

        if ($distanceMatrixRequest->hasAvoidHighways() && $distanceMatrixRequest->getAvoidHighways()) {
            $httpQuery['avoidHighways'] = true;
        }

        if ($distanceMatrixRequest->hasUnitSystem()) {
            $httpQuery['units'] = strtolower($distanceMatrixRequest->getUnitSystem());
        }

        if ($distanceMatrixRequest->hasRegion()) {
            $httpQuery['region'] = $distanceMatrixRequest->getRegion();
        }

        if ($distanceMatrixRequest->hasLanguage()) {
            $httpQuery['language'] = $distanceMatrixRequest->getLanguage();
        }

        $httpQuery['sensor'] = $distanceMatrixRequest->hasSensor() ? 'true' : 'false';

        $url = sprintf('%s/%s?%s', $this->getUrl(), $this->getFormat(), http_build_query($httpQuery));

        return $this->signUrl($url);
    }