Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
4.17% |
4 / 96 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
Geocoders | |
4.17% |
4 / 96 |
|
0.00% |
0 / 5 |
1308.92 | |
0.00% |
0 / 1 |
getCoordinates | |
57.14% |
4 / 7 |
|
0.00% |
0 / 1 |
5.26 | |||
performRequest | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getCoordinatesUseGoogle | |
0.00% |
0 / 24 |
|
0.00% |
0 / 1 |
90 | |||
getCoordinatesUseYandex | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
72 | |||
getCoordinatesUseMapquestNominatim | |
0.00% |
0 / 37 |
|
0.00% |
0 / 1 |
272 |
1 | <?php |
2 | namespace MultiMaps; |
3 | |
4 | use MediaWiki\MediaWikiServices; |
5 | |
6 | /** |
7 | * |
8 | * |
9 | * @file Geocoders.php |
10 | * @ingroup MultiMaps |
11 | * @author Pavel Astakhov <pastakhov@yandex.ru> |
12 | * @license GPL-2.0-or-later |
13 | */ |
14 | |
15 | class Geocoders { |
16 | |
17 | public static function getCoordinates( $address, $service, $params = null ) { |
18 | switch ( $service ) { |
19 | case 'google': |
20 | return self::getCoordinatesUseGoogle( $address ); |
21 | case 'yandex': |
22 | return self::getCoordinatesUseYandex( $address ); |
23 | case 'leaflet': |
24 | return self::getCoordinatesUseMapquestNominatim( $address, $params ); |
25 | } |
26 | return false; |
27 | } |
28 | |
29 | private static function performRequest( $url, $urlArgs ) { |
30 | return MediaWikiServices::getInstance()->getHttpRequestFactory()->get( $url . wfArrayToCgi( $urlArgs ) ); |
31 | } |
32 | |
33 | private static function getCoordinatesUseGoogle( $address ) { |
34 | $return = false; |
35 | |
36 | $urlArgs = [ |
37 | 'sensor' => 'false', |
38 | 'address' => $address, |
39 | ]; |
40 | $response = self::performRequest( 'https://maps.googleapis.com/maps/api/geocode/json?', $urlArgs ); |
41 | |
42 | if ( $response !== null ) { |
43 | $data = \FormatJson::decode( $response ); |
44 | if ( $data !== null ) { |
45 | if ( $data->status == 'OK' ) { |
46 | $geometry = $data->results[0]->geometry; |
47 | $location = $geometry->location; |
48 | $lat = $location->lat; |
49 | $lon = $location->lng; |
50 | if ( $lat !== null && $lon !== null ) { |
51 | $return = [ 'lat' => $lat, 'lon' => $lon ]; |
52 | $bounds = $geometry->bounds; |
53 | if ( $bounds !== null ) { |
54 | $bounds_ne = new Point( $bounds->northeast->lat, $bounds->northeast->lng ); |
55 | $bounds_sw = new Point( $bounds->southwest->lat, $bounds->southwest->lng ); |
56 | if ( $bounds_ne->isValid() && $bounds_sw->isValid() ) { |
57 | $b = new Bounds( [ $bounds_ne, $bounds_sw ] ); |
58 | $return['bounds'] = $b; |
59 | } |
60 | } |
61 | } |
62 | } |
63 | } |
64 | } |
65 | return $return; |
66 | } |
67 | |
68 | private static function getCoordinatesUseYandex( $address ) { |
69 | $return = false; |
70 | |
71 | $urlArgs = [ |
72 | 'format' => 'json', |
73 | 'results' => '1', |
74 | 'geocode' => $address, |
75 | ]; |
76 | $response = self::performRequest( 'https://geocode-maps.yandex.ru/1.x/?', $urlArgs ); |
77 | |
78 | if ( $response !== null ) { |
79 | $data = \FormatJson::decode( $response ); |
80 | if ( $data !== null ) { |
81 | $geoObjectCollection = $data->response->GeoObjectCollection; |
82 | if ( $geoObjectCollection->metaDataProperty->GeocoderResponseMetaData->found > 0 ) { |
83 | $geoObject = $geoObjectCollection->featureMember[0]->GeoObject; |
84 | [ $lon, $lat ] = explode( ' ', $geoObject->Point->pos ); |
85 | $point = new Point( $lat, $lon ); |
86 | if ( $point->isValid() ) { |
87 | $return = $point->pos; |
88 | $envelope = $geoObject->boundedBy->Envelope; |
89 | if ( $envelope !== null ) { |
90 | [ $lon, $lat ] = explode( ' ', $envelope->upperCorner ); |
91 | $bounds_ne = new Point( $lat, $lon ); |
92 | [ $lon, $lat ] = explode( ' ', $envelope->lowerCorner ); |
93 | $bounds_sw = new Point( $lat, $lon ); |
94 | if ( $bounds_ne->isValid() && $bounds_sw->isValid() ) { |
95 | $b = new Bounds( [ $bounds_ne, $bounds_sw ] ); |
96 | $return['bounds'] = $b; |
97 | } |
98 | } |
99 | } |
100 | } |
101 | } |
102 | } |
103 | return $return; |
104 | } |
105 | |
106 | public static function getCoordinatesUseMapquestNominatim( $address, $params ) { |
107 | $return = false; |
108 | $param_polygon = ( isset( $params['polygon'] ) && $params['polygon'] === true ) ? true : false; |
109 | |
110 | $urlArgs = [ |
111 | 'format' => 'json', |
112 | 'addressdetails' => '0', |
113 | 'limit' => 1, |
114 | 'q' => $address, |
115 | ]; |
116 | if ( $param_polygon ) { |
117 | $urlArgs['polygon'] = '1'; |
118 | } |
119 | $response = self::performRequest( 'https://open.mapquestapi.com/nominatim/v1/search.php?', $urlArgs ); |
120 | |
121 | if ( $response !== null ) { |
122 | $data = \FormatJson::decode( $response ); |
123 | if ( isset( $data[0] ) ) { |
124 | $data = $data[0]; |
125 | $lat = $data->lat; |
126 | $lon = $data->lon; |
127 | if ( $lat !== null && $lon !== null ) { |
128 | $return = [ 'lat' => $lat, 'lon' => $lon ]; |
129 | $bounds = $data->boundingbox; |
130 | if ( $bounds !== null ) { |
131 | $bounds_ne = new Point( $bounds[1], $bounds[3] ); |
132 | $bounds_sw = new Point( $bounds[0], $bounds[2] ); |
133 | if ( $bounds_ne->isValid() && $bounds_sw->isValid() ) { |
134 | $b = new Bounds( [ $bounds_ne, $bounds_sw ] ); |
135 | $return['bounds'] = $b; |
136 | } |
137 | } |
138 | if ( $param_polygon ) { |
139 | $polygonpoints = $data->polygonpoints; |
140 | if ( count( $polygonpoints ) > 1 ) { |
141 | $points = []; |
142 | foreach ( $polygonpoints as $value ) { |
143 | $p = new Point( $value[1], $value[0] ); |
144 | if ( $p->isValid() ) { |
145 | $points[] = $p; |
146 | } |
147 | } |
148 | if ( count( $points ) > 1 ) { |
149 | $return['polygon'] = $points; |
150 | } |
151 | } |
152 | } |
153 | } |
154 | } |
155 | } |
156 | return $return; |
157 | } |
158 | |
159 | } |