Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Bing Maps Provider Laravel Package

geocoder-php/bing-maps-provider

Bing Maps provider for PHP Geocoder. Adds forward and reverse geocoding using Microsoft Bing Maps APIs, returning standardized Geocoder results. Plug into geocoder-php with your Bing key for address lookup and coordinates.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require geocoder-php/bing-maps-provider
    

    Ensure geocoder-php/geocoder is also installed (required dependency).

  2. First Use Case:

    use Geocoder\Geocoder;
    use Geocoder\Provider\BingMaps\BingMaps;
    
    $geocoder = new Geocoder();
    $geocoder->registerProvider(new BingMaps('YOUR_BING_MAPS_API_KEY'));
    
    // Reverse geocode (lat/lng → address)
    $results = $geocoder->reverseQuery('51.5074, -0.1278');
    
    // Forward geocode (address → lat/lng)
    $results = $geocoder->query('1600 Amphitheatre Parkway, Mountain View');
    
  3. Where to Look First:

    • Bing Maps API Documentation (for rate limits, quotas, and feature support).
    • BingMaps::class source code (focus on createClient(), getApiKey(), and query() methods).
    • geocoder-php/geocoder docs for provider-agnostic patterns (e.g., result handling, fallbacks).

Implementation Patterns

Core Workflows

  1. Provider Registration:

    $geocoder = new Geocoder();
    $geocoder->registerProvider(new BingMaps(config('services.bing.key')));
    
    • Store API key in .env (e.g., BING_MAPS_API_KEY=your_key_here).
    • Use dependency injection for testability:
      $provider = new BingMaps($apiKey);
      $geocoder->registerProvider($provider);
      
  2. Result Handling:

    • Bing returns structured data; normalize responses with Geocoder\Result\ResultSet:
      foreach ($results as $result) {
          $coordinates = $result->getCoordinates(); // \Geocoder\Result\Address::getCoordinates()
          $formattedAddress = $result->getFormattedAddress();
      }
      
    • Handle partial failures (e.g., ambiguous queries) via ResultSet::getResults().
  3. Fallbacks and Caching:

    • Combine with other providers (e.g., Google, OpenStreetMap) for redundancy:
      $geocoder->registerProvider(new \Geocoder\Provider\GoogleMaps\GoogleMaps($googleKey));
      $geocoder->registerProvider(new BingMaps($bingKey));
      
    • Cache results with Geocoder\Cache\Cache (e.g., Redis):
      $cache = new \Geocoder\Cache\RedisCache($redisClient, 3600);
      $geocoder->registerCache($cache);
      
  4. Batch Processing:

    • Use Geocoder\Provider\MultiProvider for bulk queries:
      $multiProvider = new \Geocoder\Provider\MultiProvider([
          new BingMaps($bingKey),
          new \Geocoder\Provider\OpenStreetMap\OpenStreetMap(),
      ]);
      $geocoder->registerProvider($multiProvider);
      

Integration Tips

  • Laravel Service Provider: Bind the geocoder instance in AppServiceProvider:
    $this->app->singleton(Geocoder::class, function ($app) {
        $geocoder = new Geocoder();
        $geocoder->registerProvider(new BingMaps(config('services.bing.key')));
        return $geocoder;
    });
    
  • API Key Management: Rotate keys via environment variables and use config('services.bing.key') to avoid hardcoding.
  • Rate Limiting: Monitor Bing’s usage limits and implement retries with exponential backoff:
    use GuzzleHttp\Exception\RequestException;
    
    try {
        $results = $geocoder->query('...');
    } catch (RequestException $e) {
        if ($e->getCode() === 429) {
            sleep(2); // Retry after delay
            $results = $geocoder->query('...');
        }
    }
    

Gotchas and Tips

Pitfalls

  1. API Key Restrictions:

    • Bing Maps requires a valid subscription (free tier has strict limits).
    • Keys are region-locked; ensure your key matches the target country’s endpoint (e.g., https://dev.virtualearth.net/REST/v1/).
    • Error 401: Invalid/expired keys. Validate keys via Bing Maps Portal.
  2. Rate Limits:

    • Free tier: 50,000 transactions/month (shared across all Bing APIs).
    • Error 429: Exceeded quota. Implement caching or switch providers for high-volume apps.
    • Check usage via Bing Maps Account Center.
  3. Response Parsing:

    • Bing’s JSON structure differs from other providers. The package handles most cases, but custom fields may require extending:
      // Example: Accessing raw Bing data
      $rawData = $result->getData(); // \stdClass object
      $bounds = $rawData->ResourceSets[0]->Resources[0]->Bbox;
      
  4. Timeouts:

    • Default Guzzle timeout (30s) may be too short for slow responses. Configure:
      $client = new \GuzzleHttp\Client(['timeout' => 60]);
      $provider = new BingMaps($apiKey, $client);
      
  5. Character Encoding:

    • Non-ASCII addresses (e.g., Café) may fail. URL-encode queries:
      $encodedQuery = urlencode('Café de la Paix, Paris');
      $results = $geocoder->query($encodedQuery);
      

Debugging

  • Enable Guzzle Debugging:
    $client = new \GuzzleHttp\Client([
        'debug' => fopen('bing_debug.log', 'w'),
    ]);
    
  • Log Raw Responses: Override BingMaps::createClient() to log requests/responses:
    $provider->setClient($client);
    $provider->setLogger(new \Monolog\Logger('bing'));
    

Extension Points

  1. Custom Endpoints: Override the base URL for testing/staging:

    $provider = new BingMaps($apiKey, null, 'https://sandbox.dev.virtualearth.net/REST/v1/');
    
  2. Result Transformers: Extend Geocoder\Provider\BingMaps\BingMaps to modify responses:

    class CustomBingMaps extends BingMaps {
        protected function parseResults($data) {
            // Custom logic (e.g., reformat addresses)
            return parent::parseResults($data);
        }
    }
    
  3. Fallback Logic: Implement a custom Geocoder\Provider\ProviderInterface to chain Bing with other providers:

    class BingFallbackProvider implements ProviderInterface {
        public function query($query) {
            try {
                return $this->bingProvider->query($query);
            } catch (Exception $e) {
                return $this->fallbackProvider->query($query);
            }
        }
    }
    
  4. Testing: Use a mock client for unit tests:

    $mock = Mockery::mock(\GuzzleHttp\Client::class);
    $mock->shouldReceive('get')->andReturn(new \GuzzleHttp\Psr7\Response(200, [], file_get_contents('tests/fixtures/bing_response.json')));
    $provider = new BingMaps($apiKey, $mock);
    

Configuration Quirks

  • Case Sensitivity: Bing’s API is case-insensitive, but some fields (e.g., Address.Locality) may return mixed case. Normalize with:
    $locality = strtolower($result->getLocality());
    
  • Empty Results: Bing may return empty arrays for invalid queries. Validate with:
    if (empty($results->getResults())) {
        throw new \RuntimeException('No results found for query.');
    }
    
  • Coordinate Precision: Bing’s default precision is 7 decimal places. Trim for storage:
    $lat = round($coordinates->getLatitude(), 6);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky