Remove `@access` annotations
[phpmyadmin.git] / libraries / classes / Gis / GisPoint.php
blob5fa88c5fe7728d600bc60d13af09e53fc20db974
1 <?php
2 /**
3 * Handles actions related to GIS POINT objects
4 */
6 declare(strict_types=1);
8 namespace PhpMyAdmin\Gis;
10 use PhpMyAdmin\Image\ImageWrapper;
11 use TCPDF;
13 use function hexdec;
14 use function json_encode;
15 use function mb_substr;
16 use function round;
17 use function trim;
19 /**
20 * Handles actions related to GIS POINT objects
22 class GisPoint extends GisGeometry
24 /** @var self */
25 private static $instance;
27 /**
28 * A private constructor; prevents direct creation of object.
30 private function __construct()
34 /**
35 * Returns the singleton.
37 * @return GisPoint the singleton
39 public static function singleton()
41 if (! isset(self::$instance)) {
42 self::$instance = new GisPoint();
45 return self::$instance;
48 /**
49 * Scales each row.
51 * @param string $spatial spatial data of a row
53 * @return array an array containing the min, max values for x and y coordinates
55 public function scaleRow($spatial)
57 // Trim to remove leading 'POINT(' and trailing ')'
58 $point = mb_substr($spatial, 6, -1);
60 return $this->setMinMax($point, []);
63 /**
64 * Adds to the PNG image object, the data related to a row in the GIS dataset.
66 * @param string $spatial GIS POLYGON object
67 * @param string|null $label Label for the GIS POLYGON object
68 * @param string $point_color Color for the GIS POLYGON object
69 * @param array $scale_data Array containing data related to scaling
71 public function prepareRowAsPng(
72 $spatial,
73 ?string $label,
74 $point_color,
75 array $scale_data,
76 ImageWrapper $image
77 ): ImageWrapper {
78 // allocate colors
79 $black = $image->colorAllocate(0, 0, 0);
80 $red = (int) hexdec(mb_substr($point_color, 1, 2));
81 $green = (int) hexdec(mb_substr($point_color, 3, 2));
82 $blue = (int) hexdec(mb_substr($point_color, 4, 2));
83 $color = $image->colorAllocate($red, $green, $blue);
85 $label = trim($label ?? '');
87 // Trim to remove leading 'POINT(' and trailing ')'
88 $point = mb_substr($spatial, 6, -1);
89 $points_arr = $this->extractPoints($point, $scale_data);
91 // draw a small circle to mark the point
92 if ($points_arr[0][0] != '' && $points_arr[0][1] != '') {
93 $image->arc(
94 (int) round($points_arr[0][0]),
95 (int) round($points_arr[0][1]),
99 360,
100 $color
102 // print label if applicable
103 if ($label !== '') {
104 $image->string(
106 (int) round($points_arr[0][0]),
107 (int) round($points_arr[0][1]),
108 $label,
109 $black
114 return $image;
118 * Adds to the TCPDF instance, the data related to a row in the GIS dataset.
120 * @param string $spatial GIS POINT object
121 * @param string|null $label Label for the GIS POINT object
122 * @param string $point_color Color for the GIS POINT object
123 * @param array $scale_data Array containing data related to scaling
124 * @param TCPDF $pdf TCPDF instance
126 * @return TCPDF the modified TCPDF instance
128 public function prepareRowAsPdf(
129 $spatial,
130 ?string $label,
131 $point_color,
132 array $scale_data,
133 $pdf
135 // allocate colors
136 $red = hexdec(mb_substr($point_color, 1, 2));
137 $green = hexdec(mb_substr($point_color, 3, 2));
138 $blue = hexdec(mb_substr($point_color, 4, 2));
139 $line = [
140 'width' => 1.25,
141 'color' => [
142 $red,
143 $green,
144 $blue,
148 $label = trim($label ?? '');
150 // Trim to remove leading 'POINT(' and trailing ')'
151 $point = mb_substr($spatial, 6, -1);
152 $points_arr = $this->extractPoints($point, $scale_data);
154 // draw a small circle to mark the point
155 if ($points_arr[0][0] != '' && $points_arr[0][1] != '') {
156 $pdf->Circle($points_arr[0][0], $points_arr[0][1], 2, 0, 360, 'D', $line);
157 // print label if applicable
158 if ($label !== '') {
159 $pdf->SetXY($points_arr[0][0], $points_arr[0][1]);
160 $pdf->SetFontSize(5);
161 $pdf->Cell(0, 0, $label);
165 return $pdf;
169 * Prepares and returns the code related to a row in the GIS dataset as SVG.
171 * @param string $spatial GIS POINT object
172 * @param string $label Label for the GIS POINT object
173 * @param string $point_color Color for the GIS POINT object
174 * @param array $scale_data Array containing data related to scaling
176 * @return string the code related to a row in the GIS dataset
178 public function prepareRowAsSvg($spatial, $label, $point_color, array $scale_data)
180 $point_options = [
181 'name' => $label,
182 'id' => $label . $this->getRandomId(),
183 'class' => 'point vector',
184 'fill' => 'white',
185 'stroke' => $point_color,
186 'stroke-width' => 2,
189 // Trim to remove leading 'POINT(' and trailing ')'
190 $point = mb_substr($spatial, 6, -1);
191 $points_arr = $this->extractPoints($point, $scale_data);
193 $row = '';
194 if (((float) $points_arr[0][0]) !== 0.0 && ((float) $points_arr[0][1]) !== 0.0) {
195 $row .= '<circle cx="' . $points_arr[0][0]
196 . '" cy="' . $points_arr[0][1] . '" r="3"';
197 foreach ($point_options as $option => $val) {
198 $row .= ' ' . $option . '="' . trim((string) $val) . '"';
201 $row .= '/>';
204 return $row;
208 * Prepares JavaScript related to a row in the GIS dataset
209 * to visualize it with OpenLayers.
211 * @param string $spatial GIS POINT object
212 * @param int $srid Spatial reference ID
213 * @param string $label Label for the GIS POINT object
214 * @param array $point_color Color for the GIS POINT object
215 * @param array $scale_data Array containing data related to scaling
217 * @return string JavaScript related to a row in the GIS dataset
219 public function prepareRowAsOl(
220 $spatial,
221 int $srid,
222 $label,
223 $point_color,
224 array $scale_data
226 $fill_style = ['color' => 'white'];
227 $stroke_style = [
228 'color' => $point_color,
229 'width' => 2,
231 $result = 'var fill = new ol.style.Fill(' . json_encode($fill_style) . ');'
232 . 'var stroke = new ol.style.Stroke(' . json_encode($stroke_style) . ');'
233 . 'var style = new ol.style.Style({'
234 . 'image: new ol.style.Circle({'
235 . 'fill: fill,'
236 . 'stroke: stroke,'
237 . 'radius: 3'
238 . '}),'
239 . 'fill: fill,'
240 . 'stroke: stroke';
242 if (trim($label) !== '') {
243 $text_style = [
244 'text' => trim($label),
245 'offsetY' => -9,
247 $result .= ',text: new ol.style.Text(' . json_encode($text_style) . ')';
250 $result .= '});';
252 if ($srid === 0) {
253 $srid = 4326;
256 $result .= $this->getBoundsForOl($srid, $scale_data);
258 // Trim to remove leading 'POINT(' and trailing ')'
259 $point = mb_substr($spatial, 6, -1);
260 $points_arr = $this->extractPoints($point, null);
262 if ($points_arr[0][0] != '' && $points_arr[0][1] != '') {
263 $result .= 'var point = new ol.Feature({geometry: '
264 . $this->getPointForOpenLayers($points_arr[0], $srid) . '});'
265 . 'point.setStyle(style);'
266 . 'vectorLayer.addFeature(point);';
269 return $result;
273 * Generate the WKT with the set of parameters passed by the GIS editor.
275 * @param array $gis_data GIS data
276 * @param int $index Index into the parameter object
277 * @param string|null $empty Point does not adhere to this parameter
279 * @return string WKT with the set of parameters passed by the GIS editor
281 public function generateWkt(array $gis_data, $index, $empty = '')
283 return 'POINT('
284 . (isset($gis_data[$index]['POINT']['x'])
285 && trim((string) $gis_data[$index]['POINT']['x']) != ''
286 ? $gis_data[$index]['POINT']['x'] : '')
287 . ' '
288 . (isset($gis_data[$index]['POINT']['y'])
289 && trim((string) $gis_data[$index]['POINT']['y']) != ''
290 ? $gis_data[$index]['POINT']['y'] : '') . ')';
294 * Generate the WKT for the data from ESRI shape files.
296 * @param array $row_data GIS data
298 * @return string the WKT for the data from ESRI shape files
300 public function getShape(array $row_data)
302 return 'POINT(' . ($row_data['x'] ?? '')
303 . ' ' . ($row_data['y'] ?? '') . ')';
307 * Generate parameters for the GIS data editor from the value of the GIS column.
309 * @param string $value of the GIS column
310 * @param int $index of the geometry
312 * @return array params for the GIS data editor from the value of the GIS column
314 public function generateParams($value, $index = -1)
316 $params = [];
317 if ($index == -1) {
318 $index = 0;
319 $data = GisGeometry::generateParams($value);
320 $params['srid'] = $data['srid'];
321 $wkt = $data['wkt'];
322 } else {
323 $params[$index]['gis_type'] = 'POINT';
324 $wkt = $value;
327 // Trim to remove leading 'POINT(' and trailing ')'
328 $point = mb_substr($wkt, 6, -1);
329 $points_arr = $this->extractPoints($point, null);
331 $params[$index]['POINT']['x'] = $points_arr[0][0];
332 $params[$index]['POINT']['y'] = $points_arr[0][1];
334 return $params;