Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
69.57% |
64 / 92 |
|
60.00% |
6 / 10 |
CRAP | |
0.00% |
0 / 1 |
Map | |
69.57% |
64 / 92 |
|
60.00% |
6 / 10 |
66.59 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
4 | |||
supportsAjax | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDescription | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getMapGraticule | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getBasemap | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isActive | |
75.00% |
3 / 4 |
|
0.00% |
0 / 1 |
2.06 | |||
getGeoLocationCoords | |
92.31% |
12 / 13 |
|
0.00% |
0 / 1 |
4.01 | |||
getDisplayCoords | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
4 | |||
getMapLabels | |
0.00% |
0 / 23 |
|
0.00% |
0 / 1 |
90 | |||
getMapTabData | |
88.46% |
23 / 26 |
|
0.00% |
0 / 1 |
7.08 |
1 | <?php |
2 | |
3 | /** |
4 | * Map tab |
5 | * |
6 | * PHP version 8 |
7 | * |
8 | * Copyright (C) Villanova University 2010. |
9 | * |
10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2, |
12 | * as published by the Free Software Foundation. |
13 | * |
14 | * This program is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | * GNU General Public License for more details. |
18 | * |
19 | * You should have received a copy of the GNU General Public License |
20 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
22 | * |
23 | * @category VuFind |
24 | * @package RecordTabs |
25 | * @author Demian Katz <demian.katz@villanova.edu> |
26 | * @author Leila Gonzales <lmg@agiweb.org> |
27 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
28 | * @link https://vufind.org/wiki/development:plugins:record_tabs Wiki |
29 | */ |
30 | |
31 | namespace VuFind\RecordTab; |
32 | |
33 | use VuFind\Config\PathResolver; |
34 | |
35 | use function count; |
36 | |
37 | /** |
38 | * Map tab |
39 | * |
40 | * @category VuFind |
41 | * @package RecordTabs |
42 | * @author Demian Katz <demian.katz@villanova.edu> |
43 | * @author Leila Gonzales <lmg@agiweb.org> |
44 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
45 | * @link https://vufind.org/wiki/development:plugins:record_tabs Wiki |
46 | */ |
47 | class Map extends AbstractBase |
48 | { |
49 | /** |
50 | * Should Map Tab be displayed? |
51 | * |
52 | * @var bool |
53 | */ |
54 | protected $mapTabDisplay = false; |
55 | |
56 | /** |
57 | * Should we display coordinates as part of labels? |
58 | * |
59 | * @var bool |
60 | */ |
61 | protected $displayCoords = false; |
62 | |
63 | /** |
64 | * Map labels setting from config.ini. |
65 | * |
66 | * @var string |
67 | */ |
68 | protected $mapLabels = null; |
69 | |
70 | /** |
71 | * Display graticule / map lat long grid? |
72 | * |
73 | * @var bool |
74 | */ |
75 | protected $graticule = false; |
76 | |
77 | /** |
78 | * Basemap settings |
79 | * |
80 | * @var array |
81 | */ |
82 | protected $basemapOptions = []; |
83 | |
84 | /** |
85 | * Configuration file path resolver |
86 | * |
87 | * @var PathResolver |
88 | */ |
89 | protected $pathResolver; |
90 | |
91 | /** |
92 | * Constructor |
93 | * |
94 | * @param bool $mapTabDisplay Display Map |
95 | * @param array $basemapOptions basemap settings |
96 | * @param array $mapTabOptions MapTab settings |
97 | * @param PathResolver $pathResolver Config file path resolver |
98 | */ |
99 | public function __construct( |
100 | $mapTabDisplay = false, |
101 | $basemapOptions = [], |
102 | $mapTabOptions = [], |
103 | PathResolver $pathResolver = null |
104 | ) { |
105 | if ($mapTabDisplay) { |
106 | $this->mapTabDisplay = $mapTabDisplay; |
107 | $legalOptions = ['displayCoords', 'mapLabels', 'graticule']; |
108 | foreach ($legalOptions as $option) { |
109 | if (isset($mapTabOptions[$option])) { |
110 | $this->$option = $mapTabOptions[$option]; |
111 | } |
112 | } |
113 | $this->basemapOptions[0] = $basemapOptions['basemap_url']; |
114 | $this->basemapOptions[1] = $basemapOptions['basemap_attribution']; |
115 | } |
116 | $this->pathResolver = $pathResolver; |
117 | } |
118 | |
119 | /** |
120 | * Can this tab be loaded via AJAX? |
121 | * |
122 | * @return bool |
123 | */ |
124 | public function supportsAjax() |
125 | { |
126 | // No, magic required |
127 | return false; |
128 | } |
129 | |
130 | /** |
131 | * Get the on-screen description for this tab. |
132 | * |
133 | * @return string |
134 | */ |
135 | public function getDescription() |
136 | { |
137 | return 'Map View'; |
138 | } |
139 | |
140 | /** |
141 | * Get the map graticule setting. |
142 | * |
143 | * @return string |
144 | */ |
145 | public function getMapGraticule() |
146 | { |
147 | return $this->graticule; |
148 | } |
149 | |
150 | /** |
151 | * Get the basemap configuration settings. |
152 | * |
153 | * @return array |
154 | */ |
155 | public function getBasemap() |
156 | { |
157 | return $this->basemapOptions; |
158 | } |
159 | |
160 | /** |
161 | * Is this tab active? |
162 | * |
163 | * @return bool |
164 | */ |
165 | public function isActive() |
166 | { |
167 | if ($this->mapTabDisplay) { |
168 | $geocoords = $this->getRecordDriver()->tryMethod('getGeoLocation'); |
169 | return !empty($geocoords); |
170 | } |
171 | return false; |
172 | } |
173 | |
174 | /** |
175 | * Get the bbox-geo coordinates. |
176 | * |
177 | * @return array |
178 | */ |
179 | public function getGeoLocationCoords() |
180 | { |
181 | $geoCoords = $this->getRecordDriver()->tryMethod('getGeoLocation'); |
182 | if (empty($geoCoords)) { |
183 | return []; |
184 | } |
185 | $coordarray = []; |
186 | /* Extract coordinates from long_lat field */ |
187 | foreach ($geoCoords as $value) { |
188 | $match = []; |
189 | if (preg_match('/ENVELOPE\((.*),(.*),(.*),(.*)\)/', $value, $match)) { |
190 | $lonW = (float)$match[1]; |
191 | $lonE = (float)$match[2]; |
192 | $latN = (float)$match[3]; |
193 | $latS = (float)$match[4]; |
194 | // Coordinates ordered for display as WSEN |
195 | array_push($coordarray, [$lonW, $latS, $lonE, $latN]); |
196 | } |
197 | } |
198 | return $coordarray; |
199 | } |
200 | |
201 | /** |
202 | * Get the map display coordinates. |
203 | * |
204 | * @return array |
205 | */ |
206 | public function getDisplayCoords() |
207 | { |
208 | $label_coords = []; |
209 | $coords = $this->getRecordDriver()->tryMethod('getDisplayCoordinates'); |
210 | foreach ($coords as $val) { |
211 | $coord = explode(' ', $val); |
212 | $labelW = $coord[0]; |
213 | $labelE = $coord[1]; |
214 | $labelN = $coord[2]; |
215 | $labelS = $coord[3]; |
216 | /* Create coordinate label for map display */ |
217 | if (($labelW == $labelE) && ($labelN == $labelS)) { |
218 | $labelcoord = $labelS . ' ' . $labelE; |
219 | } else { |
220 | /* Coordinate order is min to max on lat and long axes */ |
221 | $labelcoord = $labelS . ' ' . $labelN . ' ' . |
222 | $labelW . ' ' . $labelE; |
223 | } |
224 | array_push($label_coords, $labelcoord); |
225 | } |
226 | return $label_coords; |
227 | } |
228 | |
229 | /** |
230 | * Get the map labels. |
231 | * |
232 | * @return array |
233 | */ |
234 | public function getMapLabels() |
235 | { |
236 | $mapLabelData = explode(':', $this->mapLabels); |
237 | if ($mapLabelData[0] == 'driver') { |
238 | return $this->getRecordDriver()->tryMethod('getCoordinateLabels') ?? []; |
239 | } |
240 | $labels = []; |
241 | if ($mapLabelData[0] == 'file') { |
242 | $coords = $this->getRecordDriver()->tryMethod('getDisplayCoordinates'); |
243 | /* read lookup file into array */ |
244 | $label_lookup = []; |
245 | $file = $this->pathResolver |
246 | ? $this->pathResolver->getConfigPath($mapLabelData[1]) |
247 | : \VuFind\Config\Locator::getConfigPath($mapLabelData[1]); |
248 | if (file_exists($file)) { |
249 | $fp = fopen($file, 'r'); |
250 | while (($line = fgetcsv($fp, 0, "\t")) !== false) { |
251 | if (count($line) > 1) { |
252 | $label_lookup[$line[0]] = $line[1]; |
253 | } |
254 | } |
255 | fclose($fp); |
256 | } |
257 | $labels = []; |
258 | if (null !== $coords) { |
259 | foreach ($coords as $val) { |
260 | /* Collapse spaces to make combined coordinate string to match |
261 | against lookup table coordinate */ |
262 | $coordmatch = implode('', explode(' ', $val)); |
263 | /* See if coordinate string matches lookup |
264 | table coordinates and if so return label */ |
265 | $labelname = $label_lookup[$coordmatch] ?? ''; |
266 | array_push($labels, $labelname); |
267 | } |
268 | } |
269 | } |
270 | return $labels; |
271 | } |
272 | |
273 | /** |
274 | * Construct the map coordinates and labels array. |
275 | * |
276 | * @return array |
277 | */ |
278 | public function getMapTabData() |
279 | { |
280 | $geoCoords = $this->getGeoLocationCoords(); |
281 | if (empty($geoCoords)) { |
282 | return []; |
283 | } |
284 | $mapTabData = []; |
285 | $mapDisplayCoords = []; |
286 | $mapDisplayLabels = []; |
287 | if ($this->displayCoords) { |
288 | $mapDisplayCoords = $this->getDisplayCoords(); |
289 | } |
290 | if (isset($this->mapLabels)) { |
291 | $mapDisplayLabels = $this->getMapLabels(); |
292 | } |
293 | // Pass coordinates, display coordinates, and labels |
294 | foreach (array_keys($geoCoords) as $key) { |
295 | $mapCoords = ''; |
296 | $mapLabel = ''; |
297 | if ($this->displayCoords) { |
298 | $mapCoords = $mapDisplayCoords[$key]; |
299 | } |
300 | if (isset($this->mapLabels)) { |
301 | $mapLabel = $mapDisplayLabels[$key]; |
302 | } |
303 | array_push( |
304 | $mapTabData, |
305 | [ |
306 | $geoCoords[$key][0], $geoCoords[$key][1], |
307 | $geoCoords[$key][2], $geoCoords[$key][3], |
308 | $mapLabel, $mapCoords, |
309 | ] |
310 | ); |
311 | } |
312 | return $mapTabData; |
313 | } |
314 | } |