SPW   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 157
Duplicated Lines 0 %

Test Coverage

Coverage 97.65%

Importance

Changes 5
Bugs 0 Features 0
Metric Value
wmc 24
eloc 81
c 5
b 0
f 0
dl 0
loc 157
ccs 83
cts 85
cp 0.9765
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
C geocodeQuery() 0 58 12
B reverseQuery() 0 50 8
A executeQuery() 0 11 2
A getName() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Geocoder package.
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license    MIT License
11
 */
12
13
namespace Geocoder\Provider\SPW;
14
15
use Geocoder\Collection;
16
use Geocoder\Exception\InvalidArgument;
17
use Geocoder\Exception\InvalidServerResponse;
18
use Geocoder\Exception\UnsupportedOperation;
19
use Geocoder\Http\Provider\AbstractHttpProvider;
20
use Geocoder\Model\Address;
21
use Geocoder\Model\AddressBuilder;
22
use Geocoder\Model\AddressCollection;
23
use Geocoder\Provider\Provider;
24
use Geocoder\Query\GeocodeQuery;
25
use Geocoder\Query\ReverseQuery;
26
use Http\Client\HttpClient;
27
use proj4php\Point;
28
use proj4php\Proj;
29
use proj4php\Proj4php;
30
use SoapClient;
31
32
/**
33
 * @author Jonathan Beliën <[email protected]>
34
 */
35
final class SPW extends AbstractHttpProvider implements Provider
36
{
37
    /**
38
     * @var string
39
     */
40
    const WSDL_ENDPOINT_URL = 'https://geoservices.wallonie.be/geolocalisation/soap/?wsdl';
41
42
    /**
43
     * @param HttpClient $client an HTTP adapter
44
     */
45 6
    public function __construct(HttpClient $client)
46
    {
47 6
        parent::__construct($client);
48 6
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 5
    public function geocodeQuery(GeocodeQuery $query): Collection
54
    {
55 5
        $address = $query->getText();
56
        // This API does not support IP
57 5
        if (filter_var($address, FILTER_VALIDATE_IP)) {
58 3
            throw new UnsupportedOperation('The SPW provider does not support IP addresses, only street addresses.');
59
        }
60
61
        // Save a request if no valid address entered
62 2
        if (empty($address)) {
63
            throw new InvalidArgument('Address cannot be empty.');
64
        }
65
66 2
        $result = $this->executeQuery('searchPositionScored', ['search' => $address]);
67
68
        // no result
69 2
        if (!isset($result->x) || !isset($result->y)) {
70 1
            return new AddressCollection([]);
71
        }
72
73 1
        $results = [];
74
75 1
        $proj4 = new Proj4php();
76
77 1
        $proj31370 = new Proj('EPSG:31370', $proj4);
78 1
        $proj4326 = new Proj('EPSG:4326', $proj4);
79
80 1
        $pointSrc = new Point($result->x, $result->y, $proj31370);
81 1
        $coordinates = $proj4->transform($proj4326, $pointSrc);
82
83 1
        $streetName = !empty($result->rue->nom) ? $result->rue->nom : null;
84 1
        $number = !empty($result->num) ? $result->num : null;
85 1
        $municipality = !empty($result->rue->commune) ? $result->rue->commune : null;
86 1
        $postCode = !empty($result->rue->cps) ? (is_array($result->rue->cps) ? implode(', ', $result->rue->cps) : (string) $result->rue->cps) : null;
87 1
        $subLocality = !empty($result->rue->localites) ? (is_array($result->rue->localites) ? implode(', ', $result->rue->localites) : $result->rue->localites) : null;
88
89 1
        $lowerLeftSrc = new Point($result->rue->xMin, $result->rue->yMin, $proj31370);
90 1
        $lowerLeft = $proj4->transform($proj4326, $lowerLeftSrc);
91 1
        $upperRightSrc = new Point($result->rue->xMax, $result->rue->yMax, $proj31370);
92 1
        $upperRight = $proj4->transform($proj4326, $upperRightSrc);
93
94 1
        $builder = new AddressBuilder($this->getName());
95 1
        $builder->setCoordinates($coordinates->y, $coordinates->x)
96 1
            ->setStreetNumber($number)
97 1
            ->setStreetName($streetName)
98 1
            ->setLocality($municipality)
99 1
            ->setPostalCode($postCode)
100 1
            ->setSubLocality($subLocality)
101 1
            ->setBounds(
102 1
                $lowerLeft->y,
103 1
                $lowerLeft->x,
104 1
                $upperRight->y,
105 1
                $upperRight->x
106
            );
107
108 1
        $results[] = $builder->build();
109
110 1
        return new AddressCollection($results);
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116 1
    public function reverseQuery(ReverseQuery $query): Collection
117
    {
118 1
        $coordinates = $query->getCoordinates();
119
120 1
        $proj4 = new Proj4php();
121
122 1
        $proj31370 = new Proj('EPSG:31370', $proj4);
123 1
        $proj4326 = new Proj('EPSG:4326', $proj4);
124
125 1
        $queryPointSrc = new Point($coordinates->getLongitude(), $coordinates->getLatitude(), $proj4326);
126 1
        $queryCoordinates = $proj4->transform($proj31370, $queryPointSrc);
127
128 1
        $result = $this->executeQuery('getNearestPosition', [
129 1
            'x' => $queryCoordinates->x,
130 1
            'y' => $queryCoordinates->y,
131
        ]);
132
133 1
        $results = [];
134
135 1
        $pointSrc = new Point($result->x, $result->y, $proj31370);
136 1
        $coordinates = $proj4->transform($proj4326, $pointSrc);
137
138 1
        $streetName = !empty($result->rue->nom) ? $result->rue->nom : null;
139 1
        $number = !empty($result->num) ? $result->num : null;
140 1
        $municipality = !empty($result->rue->commune) ? $result->rue->commune : null;
141 1
        $postCode = !empty($result->rue->cps) ? (is_array($result->rue->cps) ? implode(', ', $result->rue->cps) : (string) $result->rue->cps) : null;
142 1
        $subLocality = !empty($result->rue->localites) ? (is_array($result->rue->localites) ? implode(', ', $result->rue->localites) : $result->rue->localites) : null;
143
144 1
        $lowerLeftSrc = new Point($result->rue->xMin, $result->rue->yMin, $proj31370);
145 1
        $lowerLeft = $proj4->transform($proj4326, $lowerLeftSrc);
146 1
        $upperRightSrc = new Point($result->rue->xMax, $result->rue->yMax, $proj31370);
147 1
        $upperRight = $proj4->transform($proj4326, $upperRightSrc);
148
149 1
        $builder = new AddressBuilder($this->getName());
150 1
        $builder->setCoordinates($coordinates->y, $coordinates->x)
151 1
            ->setStreetNumber($number)
152 1
            ->setStreetName($streetName)
153 1
            ->setLocality($municipality)
154 1
            ->setPostalCode($postCode)
155 1
            ->setSubLocality($subLocality)
156 1
            ->setBounds(
157 1
                $lowerLeft->y,
158 1
                $lowerLeft->x,
159 1
                $upperRight->y,
160 1
                $upperRight->x
161
            );
162
163 1
        $results[] = $builder->build();
164
165 1
        return new AddressCollection($results);
166
    }
167
168
    /**
169
     * {@inheritdoc}
170
     */
171 2
    public function getName(): string
172
    {
173 2
        return 'spw';
174
    }
175
176
    /**
177
     * @param string $url
178
     *
179
     * @return \stdClass
180
     */
181 3
    private function executeQuery(string $function, array $data): \stdClass
182
    {
183 3
        $client = new SoapClient(self::WSDL_ENDPOINT_URL);
184 3
        $result = $client->__soapCall($function, [$data]);
185
186
        // API error
187 3
        if (!isset($result->return)) {
188
            throw InvalidServerResponse::create(implode(', ', $data));
189
        }
190
191 3
        return $result->return;
192
    }
193
}
194