Skip to content

Commit

Permalink
Merge pull request #38 from sebalis/provider-de-postalcode
Browse files Browse the repository at this point in the history
provider for German postal codes (replaces #36)
  • Loading branch information
eileenmcnaughton authored Aug 6, 2023
2 parents 4d8e462 + e2c6dd8 commit 1c571a0
Show file tree
Hide file tree
Showing 4 changed files with 8,407 additions and 0 deletions.
82 changes: 82 additions & 0 deletions Provider/DEPlzProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

/*
* This file works with the Geocoder package.
*
* @author Detlev Sieber / civiservice.de <[email protected]>
*/

namespace Geocoder\Provider;

use Civi;
use Geocoder\Collection;
use Geocoder\Exception\UnsupportedOperation;
use Geocoder\Model\AddressBuilder;
use Geocoder\Model\AddressCollection;
use Geocoder\Query\GeocodeQuery;
use Geocoder\Query\ReverseQuery;
use Geocoder\Provider\AbstractProvider;
use Geocoder\Provider\Provider;
use Geocoder\Exception\CollectionIsEmpty;

final class DEPlzProvider extends AbstractProvider implements Provider
{
/**
* @param HttpClient $dummy (unused)
*
* @throws \Exception
*/
public function __construct($dummy) {
}

/**
* {@inheritdoc}
*/
public function geocodeQuery(GeocodeQuery $query): Collection {

if (!isset(Civi::$statics[__CLASS__])) {
Civi::$statics[__CLASS__] = (bool) (\CRM_Core_DAO::singleValueQuery("SHOW TABLES LIKE 'civicrm_geocoder_plzde_dataset'"));
}
if (!Civi::$statics[__CLASS__]) {
// We don't have the data table available.
throw new CollectionIsEmpty();
}

$postcodeNoSpace = preg_replace('/ +/', '', $query->getText());

$sql = "
SELECT *
FROM civicrm_geocoder_plzde_dataset
WHERE postcode_no_space = %1";

$result = \CRM_Core_DAO::executeQuery(
$sql,
[1 => [$postcodeNoSpace, 'String']]
);

$builder = new AddressBuilder($this->getName());
if ($result->fetch()) {
$builder->setCoordinates($result->latitude, $result->longitude);
$builder->setLocality($result->city);
$builder->setPostalCode($result->postcode);
return new AddressCollection([$builder->build()]);
}

throw new CollectionIsEmpty();
}

/**
* {@inheritdoc}
*/
public function reverseQuery(ReverseQuery $query): Collection
{
throw new UnsupportedOperation('The data table provider is not able to do reverse geocoding yet.');
}

/**
* {@inheritdoc}
*/
public function getName(): string {
return 'plzde';
}
}
21 changes: 21 additions & 0 deletions ProviderMetadata/7_DE_Plz.mgd.geo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
return [
[
'name' => 'de_plz',
'entity' => 'Geocoder',
'params' => [
'version' => 3,
'name' => 'de_plz',
'title' => 'DE PLZ based geocoding',
'class' => 'DEPlzProvider',
'valid_countries' => ['DE'],
'required_fields' => ['postal_code'],
'retained_response_fields' => '["geo_code_1","geo_code_2", "postal_code"]',
'datafill_response_fields' => ["city"],
],
'metadata' => [
'is_enabled_on_install' => FALSE,
]
]
];

37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ already have google configured as your provider. However the Terms of service su
- GeoName DB geocoder - this requires that you get a sample dataset from geonames. I will require a developer or similar to tweak the download into an sql table. There is a sample dataset for New Zealand in the install directory & if loaded it will work for New Zealand.
- Here (not enabled by default)
- Addok (not enabled by default)
- German Postalcode - see below

Features

Expand Down Expand Up @@ -144,3 +145,39 @@ The data came from https://www.getthedata.com/open-postcode-geo
ADD PRIMARY KEY (postcode_no_space);
```
5. Enable the UK Postcode geocoder. Not sure if there's a UI for this, but you can do it via the API (v3).
## German Postal Code geocoder
- Germany’s postal code(s) are known as ‘Postleitzahl(en)’, acronym PLZ.
- This provider derives coordinates from German PLZs *only*, so it is not very precise, but good enough for many purposes. It installs the required data as a local SQL table, so there are no online service, no fees, limits or latency.
- It can handle *and correct* postal codes with spaces missing/in wrong places.
- If the address contains a valid postal code, the geocodes, the city, and the federal state is filled (if empty)
- This Geocoding provider is not installed by default.
### Installation
1. The postcode-geo data is located in: org.wikimedia.geocoder/sql/PLZ.de.sql
2. Import that file with the data into your CiviCRM database. This will create a new table named "civicrm_geocoder_plzde_dataset". If that table existed before, it will be dropped.
3. Enable the UK Postcode geocoder by executing an SQL statement like this:
```sql
INSERT INTO civicrm_geocoder SET
name = 'de_plz',
title = 'DE Postleitzahlen',
class = 'DEPlzProvider',
is_active = 1,
weight = (SELECT MAX(weight) + 1 FROM civicrm_geocoder g),
api_key = NULL,
url = NULL,
required_fields = '["postal_code"]',
retained_response_fields = '["geo_code_1","geo_code_2"]',
datafill_response_fields = '["city"]',
threshold_standdown = 60,
threshold_last_hit = NULL,
valid_countries = '[1082]';
```
You may want to reassign weights for all geocoders registered in the `civicrm_geocoder` table.
Loading

0 comments on commit 1c571a0

Please sign in to comment.