PHPackages                             teamzac/points-of-interest - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. teamzac/points-of-interest

ActiveLibrary[API Development](/categories/api)

teamzac/points-of-interest
==========================

Fetch POIs from a variety of sources

v0.5.0(3mo ago)0187MITPHPPHP &gt;=8.2CI failing

Since Mar 1Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/teamzac/points-of-interest)[ Packagist](https://packagist.org/packages/teamzac/points-of-interest)[ Docs](https://github.com/teamzac/points-of-interest)[ RSS](/packages/teamzac-points-of-interest/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (2)Dependencies (8)Versions (9)Used By (0)

Search for points of interest
=============================

[](#search-for-points-of-interest)

[![Latest Version on Packagist](https://camo.githubusercontent.com/19421248b0aec6018407f11f5e4be4dbcd24a960479d036e656b6841a3f49a85/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7465616d7a61632f706f696e74732d6f662d696e7465726573742e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/teamzac/points-of-interest)

A package, which includes Laravel support, for searching multiple providers of point-of-interest (POI) data. Currently includes support for Google, Yelp, FourSquare, and Here.com.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require teamzac/points-of-interest
```

Once installed, Laravel 8+ will auto-discover the package. If you do not, or cannot, use auto-discovery, you may manually install by adding the following to `config/app.php`:

```
    // providers
    \TeamZac\POI\PointsOfInterestServiceProvider::class,

    // aliases
    'POI' => \TeamZac\POI\Facades\POI::class,
```

If you would like to override the default configuration, you may run:

```
php artisan vendor:publish --provider="TeamZac\POI\PointsOfInterestServiceProvider"
```

Usage
-----

[](#usage)

This package uses the manager strategy to handle switching between different data providers. You can set a default provider as well as any other providers through the configuration file. If you need to retrieve a specific driver, you can use the driver() method on the POI facade:

```
POI::driver('google');
```

This will return the driver instance, on which you can specify your query type. If you omit the explicit call to a driver, you'll receive the default driver specified in the configuration.

Data Providers
--------------

[](#data-providers)

We currently support:

- Google Places
- Yelp Fusion
- Here.com Places API
- FourSquare

Query Types
-----------

[](#query-types)

This package supports three types of queries: **retrieving** a POI based on the unique ID from the provider, **matching** a POI based on some known attributes, and **searching** for POIs based on certain criteria.

The match and search query types return a fluent query object on which your search parameters can be set. The retrieve query type only accepts the unique ID;

### Retrieve a POI based on the provider's unique ID

[](#retrieve-a-poi-based-on-the-providers-unique-id)

If you know the provider's ID for the POI, you can fetch their record using the retrieve query:

```
$place = POI::retrieve('provider-id');

$place = POI::driver('yelp')->retrieve('provider-id');
```

Unlike the other two queries, the retrieve query directly returns an instance of `TeamZac\POI\Support\Place`.

### Matching based on known attributes

[](#matching-based-on-known-attributes)

If you have some known attributes for a POI and would like to retrieve a matching copy from a specific provider, you should use the match query.

```
$query = POI::match('walmart supercenter')
    ->near(Address::make([
        'street' => '123 Main Street',
        'city' => 'Fort Worth',
        'state' => 'Texas',
        'country' => 'US',
        'postalCode' => 76102,
        'latLng' => LatLng::make(32, -97)
    ]);

$place = $query->get();
```

Available methods on the match query are:

```
$query->search('search term')
    ->address(/** @var TeamZac\POI\Support\Address */)
    ->phone(/** use a phone number instead of a search query, where available */);

// use the get() method to perform the query
```

The `get()` method of the match query returns in instance of `TeamZac\POI\Support\Place`.

### Searching for POIs

[](#searching-for-pois)

If you want to search around a specific address or lat/lng coordinate pair, you should use the search query.

```
$query = POI::search(/** optional search term goes here */);

$collection = $query->get();
```

The `get()` method returns an instance of `TeamZac\POI\Support\PlaceCollection`, which is a subclass of `Illuminate\Support\Collection` that adds a few properties and methods for retrieving additional results. Learn more about the `PlaceCollection` here.

We've done our best to provide a standardized interface across all platforms, even though there are at times significant differences between them. Some providers allow searching within arbitrary geometries and/or bounding boxes, while others only allow you to search near a specified address or lat/lng pair.

#### Searching near a location

[](#searching-near-a-location)

To search near a specific address or location, you can use the `near()` method, which accepts an instance of `TeamZac\POI\Support\Address`. Address is a value object that holds information about a street address, including the street name/number, city, state, country, postal code, and latitude/longitude pair (which should be an instance of `TeamZac\POI\Support\LatLng`).

```
// Google requires a lat/lng pair with optional radius
POI::driver('google')->search()->near(Address::make([
    'latLng' => LatLng::make(32, -97),
])->radius(500); // meters

// Yelp requires an address, including country code
POI::driver('yelp')->search()->near(Address::make([
    'street' => '123 Main Street',
    'city' => 'Fort Worth',
    'state' => 'Texas',
    'postalCode' => 76102,
    'country' => 'US',
]);
```

If possible, it's recommended to provide a full address including lat/lng when making your request and let the provider convert it to the correct request format. If your Address does not contain sufficient information to run the query, an `InsufficientAddressExeption` will be thrown.

#### Searching within a geometry or bounding box

[](#searching-within-a-geometry-or-bounding-box)

Coming soon...

#### Filtering by category

[](#filtering-by-category)

When available, you may filter your searches by business category. Yelp allows filtering by multiple categories, while Google only allows a single type to be used. If multiple categories are provided to the Google driver, it will use only the first.

```
$query = POI::search()->near(/** @var Address */);

// you can narrow your search by category where available
// if the provider does not support this option, it will result in a no-op
$query->categories(['retail', 'restaurant']);
```

We provide a generic set of categories that each provider is responsible for mapping to its own specific category codes. For more information, go here. **TODO: add something about this**

The following providers support searching within arbitrary polygons:

- Here

The following only allow searching about a specific location:

- Google
- Yelp

Classes
-------

[](#classes)

### Address

[](#address)

A value object that is used to standardize address syntax across the various platforms.

```
Address::make([
    'street' => '123 Main Street',
    // etc
]);
```

### LatLng

[](#latlng)

A value object that is used to hold a lat/lng coordinate pair

```
LatLng::make(32, -97);
```

### Place

[](#place)

A value object that is used to standardized POI responses across the various platforms. You most likely will not need to create an instance of this object directly unless you're extending the `TeamZac\POI\Manager` by adding a new provider.

```
$place = POI::driver('google')->retrieve('provider-id');

$place->getProvider();      // 'google'
$place->getId();            // 'provider-id'
$place->getName();          // business name
$place->getAddress();       // TeamZac\POI\Support\Address
$place->getPhone();         // phone number
$place->getCategories();    // array of category strings
$place->getRaw();           // array containing the raw results from the provider
```

### PlaceCollection

[](#placecollection)

The `TeamZac\POI\Support\PlaceCollection` is a subclass of `Illuminate\Support\Collection` that provides the ability to query for additional results when available.

```
$collection = POI::search()->near($address)->get();

// get a new instance of PlaceCollection containing the next page of search results
$collection->nextPage();

// get the total number of results found
$collection->getTotal();
```

Extending
---------

[](#extending)

If you need to add additional data providers, you can extend the Manager class.

```
POI::extend('new-provider', function($app) {
    // create and return your driver here
});
```

Your provider should implement the `TeamZac\POI\Contracts\ProviderInterface` interface, which includes the following methods:

### match()

[](#match)

The `match()` method accepts an optional search term and returns a query object that implements `TeamZac\POI\Contracts\MatchQueryInterface`.

The `MatchQueryInterface` requires the following methods:

- `search($term = null)`
- `phone($number = null)`
- `near(Address $addess)`
- `get()`

The `get()` method should return an instance of `TeamZac\POI\Support\Place`.

### search()

[](#search)

The `search()` method accepts an optional search term and returns a query object that implements `TeamZac\POI\Contracts\SearchQueryInterface`.

The `SearchQueryInterface` requires the following methods:

- `search($term = null)`
- `near(Address $address)`
- `within($tbd)`
- `get()`

The `get()` method should return an instance of `TeamZac\POI\Support\PlaceCollection`.

### retrieve()

[](#retrieve)

The `retrieve()` method accepts an ID and returns an instance of `TeamZac\POI\Support\Place`.

### Testing

[](#testing)

```
composer test
```

### Changelog

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

### Security

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Chad Janicek](https://github.com/teamzac)
- [All Contributors](../../contributors)
- [Laravel Package Boilerplate](https://laravelpackageboilerplate.com)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

46

—

FairBetter than 92% of packages

Maintenance81

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~398 days

Recently: every ~552 days

Total

7

Last Release

100d ago

PHP version history (5 changes)v0.1.0PHP ^7.1

v0.1.1PHP ^7.2

v0.2PHP &gt;=7.2.5

v0.3PHP &gt;=7.3

v0.5.0PHP &gt;=8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/6fd7317d975889db1c4dc0aec0dfcd3f9f4e284634e6719891d3f47f46238be6?d=identicon)[teamzac](/maintainers/teamzac)

---

Top Contributors

[![chadjanicek](https://avatars.githubusercontent.com/u/18754689?v=4)](https://github.com/chadjanicek "chadjanicek (50 commits)")

---

Tags

points of interestteamzac

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/teamzac-points-of-interest/health.svg)

```
[![Health](https://phpackages.com/badges/teamzac-points-of-interest/health.svg)](https://phpackages.com/packages/teamzac-points-of-interest)
```

###  Alternatives

[craftcms/cms

Craft CMS

3.6k3.6M3.1k](/packages/craftcms-cms)[tencentcloud/tencentcloud-sdk-php

TencentCloudApi php sdk

3741.3M46](/packages/tencentcloud-tencentcloud-sdk-php)[spatie/laravel-export

Create a static site bundle from a Laravel app

674146.0k6](/packages/spatie-laravel-export)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5022.0k](/packages/simplestats-io-laravel-client)[eslazarev/wildberries-sdk

Wildberries OpenAPI clients (generated).

273.0k](/packages/eslazarev-wildberries-sdk)[jasara/php-amzn-selling-partner-api

A fluent interface for Amazon's Selling Partner API in PHP

1348.7k1](/packages/jasara-php-amzn-selling-partner-api)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
