All Projects → craue → Crauegeobundle

craue / Crauegeobundle

Licence: other
Doctrine functions for calculating geographical distances in your Symfony project.

Projects that are alternatives of or similar to Crauegeobundle

Knpmenubundle
Object Oriented menus for your Symfony project.
Stars: ✭ 1,242 (+1008.93%)
Mutual labels:  bundle, symfony, symfony-bundle
Liipimaginebundle
Symfony Bundle to assist in imagine manipulation using the imagine library
Stars: ✭ 1,516 (+1253.57%)
Mutual labels:  bundle, symfony, symfony-bundle
Neo4j Symfony
Symfony Bundle for the Neo4j Graph Database
Stars: ✭ 69 (-38.39%)
Mutual labels:  bundle, symfony, symfony-bundle
Pugxautocompleterbundle
Add an autocomplete field to your Symfony forms
Stars: ✭ 83 (-25.89%)
Mutual labels:  bundle, symfony, symfony-bundle
Notification Bundle
A simple Symfony bundle to notify user
Stars: ✭ 103 (-8.04%)
Mutual labels:  bundle, symfony, symfony-bundle
Sonatacachebundle
This bundle provides caching services
Stars: ✭ 66 (-41.07%)
Mutual labels:  bundle, symfony, symfony-bundle
Easy Security Bundle
EasySecurityBundle
Stars: ✭ 95 (-15.18%)
Mutual labels:  bundle, symfony, symfony-bundle
Lexikcurrencybundle
This Symfony2 bundle provide a service and a Twig extension to convert and display currencies.
Stars: ✭ 59 (-47.32%)
Mutual labels:  bundle, symfony, symfony-bundle
Liipcachecontrolbundle
DEPRECATED! This bundle is superseded by FOSHttpCacheBundle. A migration guide is in the README of LiipCacheControlBundle
Stars: ✭ 108 (-3.57%)
Mutual labels:  bundle, symfony, symfony-bundle
Sonataclassificationbundle
Symfony SonataClassificationBundle
Stars: ✭ 76 (-32.14%)
Mutual labels:  bundle, symfony, symfony-bundle
Web Server Bundle
WebServerBundle provides commands for running applications using the PHP built-in web server. It simplifies your local development setup because you don't have to configure a proper web server such as Apache or Nginx to run your application.
Stars: ✭ 1,281 (+1043.75%)
Mutual labels:  bundle, symfony, symfony-bundle
Filemanagerbundle
FileManager is a simple Multilingual File Manager Bundle for Symfony
Stars: ✭ 105 (-6.25%)
Mutual labels:  bundle, symfony, symfony-bundle
Foselasticabundle
Elasticsearch PHP integration for your Symfony project using Elastica.
Stars: ✭ 1,142 (+919.64%)
Mutual labels:  bundle, symfony, symfony-bundle
Swarrotbundle
A symfony bundle for swarrot integration
Stars: ✭ 89 (-20.54%)
Mutual labels:  bundle, symfony, symfony-bundle
Featureflagsbundle
Symfony2 Bundle to implement Feature Flags to your Application
Stars: ✭ 63 (-43.75%)
Mutual labels:  bundle, symfony, symfony-bundle
Cronos Bundle
Easy update your crontab by using @cron annotations in Symfony commands.
Stars: ✭ 73 (-34.82%)
Mutual labels:  bundle, symfony, symfony-bundle
Fmbbcodebundle
🔠 BBCode bundle for Symfony projects
Stars: ✭ 56 (-50%)
Mutual labels:  bundle, symfony, symfony-bundle
Pugxgeneratorbundle
An enhancement of SensioGeneratorBundle
Stars: ✭ 58 (-48.21%)
Mutual labels:  bundle, symfony, symfony-bundle
Twigextensionsbundle
Useful Twig extensions for your Symfony project.
Stars: ✭ 75 (-33.04%)
Mutual labels:  bundle, symfony, symfony-bundle
Easy Doc Bundle
Symfony application documentation generator
Stars: ✭ 99 (-11.61%)
Mutual labels:  bundle, symfony, symfony-bundle

Information

Build Status

CraueGeoBundle provides Doctrine functions for your Symfony project which allow you to calculate geographical distances within database queries. This bundle is independent of any web service, so once you got it running, it will keep running. There are two Doctrine functions, which return a distance in km:

  • GEO_DISTANCE takes latitude + longitude for origin and destination
  • GEO_DISTANCE_BY_POSTAL_CODE takes country + postal code for origin and destination

Installation

Get the bundle

Let Composer download and install the bundle by running

composer require craue/geo-bundle

in a shell.

Enable the bundle

If you don't use Symfony Flex, register the bundle manually:

// in config/bundles.php
return [
	// ...
	Craue\GeoBundle\CraueGeoBundle::class => ['all' => true],
];

Or, for Symfony 3.4:

// in app/AppKernel.php
public function registerBundles() {
	$bundles = [
		// ...
		new Craue\GeoBundle\CraueGeoBundle(),
	];
	// ...
}

Prepare the table with geographical data needed for calculations

The GEO_DISTANCE_BY_POSTAL_CODE function, if you'd like to use it, relies on some data which has to be added to your database first.

Create the table

The GeoPostalCode entity provided contains the structure for the geographical data. You import it by calling either

# in a shell
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate

or

# in a shell
php bin/console doctrine:schema:update

or however you like.

Import the geographical data

This is probably the most annoying step: Storing all postal codes with their geographical positions for the countries you need. Fortunately, it's not that hard to get this information and import it into your database.

Go to http://download.geonames.org/export/zip/ and download the archives for the countries you need. Let's just take DE.zip. Unzip the included DE.txt file, e.g. to /tmp/DE.txt.

Create a fixture class (in a separate folder to be able to load only this one) which extends the provided base class:

// MyCompany/MyBundle/Doctrine/Fixtures/CraueGeo/MyGeonamesPostalCodeData.php
namespace MyCompany\MyBundle\Doctrine\Fixtures\CraueGeo;

use Craue\GeoBundle\Doctrine\Fixtures\GeonamesPostalCodeData;
use Doctrine\Common\Persistence\ObjectManager;

class MyGeonamesPostalCodeData extends GeonamesPostalCodeData {

	public function load(ObjectManager $manager) {
		$this->clearPostalCodesTable($manager);
		$this->addEntries($manager, '/tmp/DE.txt');
	}

}

Now, backup your database! Don't blame anyone else for data loss if something goes wrong. Then import the fixture and remember to use the --append parameter.

Choose the following steps depending on the version of DoctrineFixturesBundle you're using.

DoctrineFixturesBundle < 3.0

Load the fixture(s) in the given folder.

# in a shell
php bin/console doctrine:fixtures:load --append --fixtures="src/MyCompany/MyBundle/Doctrine/Fixtures/CraueGeo"
DoctrineFixturesBundle >= 3.1
  1. a) You first need to register the fixture as a service with a group of your choice.
# in app/config/config.yml
services:
  my_geonames_postal_code_data:
    class: MyCompany\MyBundle\Doctrine\Fixtures\CraueGeo\MyGeonamesPostalCodeData
    public: false
    tags:
     - { name: doctrine.fixture.orm, group: my_geo_data }
  1. b) It's also possible to register all classes in a specific folder as services.
# in app/config/config.yml
services:
  MyCompany\MyBundle\Doctrine\Fixtures\CraueGeo\:
    resource: '../../src/MyCompany/MyBundle/Doctrine/Fixtures/CraueGeo/*'
    public: false
    tags:
     - { name: doctrine.fixture.orm, group: my_geo_data }
  1. Then, load the fixture(s) of that group.
# in a shell
php bin/console doctrine:fixtures:load --append --group=my_geo_data

That's it.

You can also use other data sources you have access to, and write a custom fixture to import it.

If you have out of memory issues when importing a large number of entries try adding the --no-debug switch to avoid logging every single Doctrine query.

Usage

Let's say you have an entity Poi containing countries and postal codes. Now you wish to find all entities within a specific geographical distance with a radius of $radiusInKm from a given postal code $postalCode in country $country, and order them by distance.

use MyCompany\MyBundle\Entity\Poi;

// example values which could come from a form, remember to validate/sanitize them first
$country = 'DE';
$postalCode = '10115';
$radiusInKm = 10;

// create a query builder
$queryBuilder = $this->getDoctrine()->getEntityManager()->getRepository(Poi::class)->createQueryBuilder('poi');

// build the query
$queryBuilder
	->select('poi, GEO_DISTANCE_BY_POSTAL_CODE(:country, :postalCode, poi.country, poi.postalCode) AS HIDDEN distance')
	->having('distance <= :radius')
	->setParameter('country', $country)
	->setParameter('postalCode', $postalCode)
	->setParameter('radius', $radiusInKm)
	->orderBy('distance')
;

Advanced stuff

Using the Doctrine functions for a different database platform

By default, the Doctrine functions are automatically registered for usage with MySQL. But you can tell the bundle that you want to use them with a different database platform by setting a flavor:

# in app/config/config.yml
craue_geo:
  flavor: postgresql

Currently, the following flavors are supported:

  • mysql: MySQL (default value)
  • postgresql: PostgreSQL
  • none: prevents registration of the Doctrine functions in case you want to do it manually

As PostgreSQL doesn't support aliases in the HAVING clause and further requires poi to appear in the GROUP BY clause, you need to adapt the query (from the usage example above):

$queryBuilder
	->select('poi, GEO_DISTANCE_BY_POSTAL_CODE(:country, :postalCode, poi.country, poi.postalCode) AS HIDDEN distance')
	->having('GEO_DISTANCE_BY_POSTAL_CODE(:country, :postalCode, poi.country, poi.postalCode) <= :radius')
	->setParameter('country', $country)
	->setParameter('postalCode', $postalCode)
	->setParameter('radius', $radiusInKm)
	->groupBy('poi')
	->orderBy('distance')
;

Avoid creating the postal code table

If you want to avoid registering the GeoPostalCode entity (and as a result, avoid creating the craue_geo_postalcode table) at all, add

# in app/config/config.yml
craue_geo:
  enable_postal_code_entity: false

to your configuration.

Use custom names for the Doctrine functions

If you don't like the default names or need to avoid conflicts with other functions, you can set custom names:

# in app/config/config.yml
craue_geo:
  functions:
    geo_distance: MY_VERY_OWN_GEO_DISTANCE_FUNCTION
    geo_distance_by_postal_code: MY_VERY_OWN_GEO_DISTANCE_BY_POSTAL_CODE_FUNCTION
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].