Passed
Push — master ( f71bba...a12491 )
by Maurício
01:50
created

ShapeRecord::addPoint()   C

Complexity

Conditions 16
Paths 23

Size

Total Lines 37
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 16.747

Importance

Changes 0
Metric Value
cc 16
eloc 29
nc 23
nop 2
dl 0
loc 37
rs 5.5666
c 0
b 0
f 0
ccs 24
cts 28
cp 0.8571
crap 16.747

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * phpMyAdmin ShapeFile library
4
 * <https://github.com/phpmyadmin/shapefile/>.
5
 *
6
 * Copyright 2006-2007 Ovidio <ovidio AT users.sourceforge.net>
7
 * Copyright 2016 - 2017 Michal Čihař <[email protected]>
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, you can download one from
20
 * https://www.gnu.org/copyleft/gpl.html.
21
 */
22
23
namespace PhpMyAdmin\ShapeFile;
24
25
/**
26
 * ShapeFile record class.
27
 */
28
class ShapeRecord
29
{
30
    private $SHPFile = null;
31
    private $DBFFile = null;
32
    private $ShapeFile = null;
33
34
    private $size = 0;
35
    private $read = 0;
36
37
    public $recordNumber = null;
38
    public $shapeType = null;
39
40
    public $lastError = '';
41
42
    public $SHPData = [];
43
    public $DBFData = [];
44
45
    /**
46
     * @param int $shapeType
47
     */
48 20
    public function __construct($shapeType)
49
    {
50 20
        $this->shapeType = $shapeType;
51 20
    }
52
53
    /**
54
     * Loads record from files.
55
     *
56
     * @param ShapeFile $ShapeFile
57
     * @param file      &$SHPFile  Opened SHP file
0 ignored issues
show
Bug introduced by
The type PhpMyAdmin\ShapeFile\file was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
58
     * @param file      &$DBFFile  Opened DBF file
59
     */
60 19
    public function loadFromFile(&$ShapeFile, &$SHPFile, &$DBFFile)
61
    {
62 19
        $this->ShapeFile = $ShapeFile;
63 19
        $this->SHPFile = $SHPFile;
64 19
        $this->DBFFile = $DBFFile;
65 19
        $this->_loadHeaders();
66
67
        /* No header read */
68 19
        if ($this->read == 0) {
69 19
            return;
70
        }
71
72 19
        switch ($this->shapeType) {
73 19
            case 0:
74
                $this->_loadNullRecord();
75
                break;
76 19
            case 1:
77 4
                $this->_loadPointRecord();
78 4
                break;
79 15
            case 21:
80 1
                $this->_loadPointMRecord();
81 1
                break;
82 14
            case 11:
83 1
                $this->_loadPointZRecord();
84 1
                break;
85 13
            case 3:
86 1
                $this->_loadPolyLineRecord();
87 1
                break;
88 12
            case 23:
89 1
                $this->_loadPolyLineMRecord();
90 1
                break;
91 11
            case 13:
92 1
                $this->_loadPolyLineZRecord();
93 1
                break;
94 10
            case 5:
95 3
                $this->_loadPolygonRecord();
96 3
                break;
97 7
            case 25:
98 1
                $this->_loadPolygonMRecord();
99 1
                break;
100 6
            case 15:
101 2
                $this->_loadPolygonZRecord();
102 2
                break;
103 4
            case 8:
104 1
                $this->_loadMultiPointRecord();
105 1
                break;
106 3
            case 28:
107 1
                $this->_loadMultiPointMRecord();
108 1
                break;
109 2
            case 18:
110 2
                $this->_loadMultiPointZRecord();
111 2
                break;
112
            default:
113
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
0 ignored issues
show
Bug introduced by
It seems like $this->shapeType can also be of type false; however, parameter $args of sprintf() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

113
                $this->setError(sprintf('The Shape Type "%s" is not supported.', /** @scrutinizer ignore-type */ $this->shapeType));
Loading history...
114
                break;
115 19
        }
116
117
        /* We need to skip rest of the record */
118 19
        while ($this->read < $this->size) {
119 6
            $this->_loadData('V', 4);
120 6
        }
121
122
        /* Check if we didn't read too much */
123 19
        if ($this->read != $this->size) {
124
            $this->setError(sprintf('Failed to parse record, read=%d, size=%d', $this->read, $this->size));
125
        }
126
127 19
        if (ShapeFile::supportsDbase() && isset($this->DBFFile)) {
128
            $this->_loadDBFData();
129
        }
130 19
    }
131
132
    /**
133
     * Saves record to files.
134
     *
135
     * @param file &$SHPFile     Opened SHP file
136
     * @param file &$DBFFile     Opened DBF file
137
     * @param int  $recordNumber Record number
138
     */
139 12
    public function saveToFile(&$SHPFile, &$DBFFile, $recordNumber)
140
    {
141 12
        $this->SHPFile = $SHPFile;
142 12
        $this->DBFFile = $DBFFile;
143 12
        $this->recordNumber = $recordNumber;
144 12
        $this->_saveHeaders();
145
146 12
        switch ($this->shapeType) {
147 12
            case 0:
148
                // Nothing to save
149
                break;
150 12
            case 1:
151 1
                $this->_savePointRecord();
152 1
                break;
153 11
            case 21:
154 1
                $this->_savePointMRecord();
155 1
                break;
156 10
            case 11:
157 1
                $this->_savePointZRecord();
158 1
                break;
159 9
            case 3:
160 1
                $this->_savePolyLineRecord();
161 1
                break;
162 8
            case 23:
163 1
                $this->_savePolyLineMRecord();
164 1
                break;
165 7
            case 13:
166 1
                $this->_savePolyLineZRecord();
167 1
                break;
168 6
            case 5:
169 1
                $this->_savePolygonRecord();
170 1
                break;
171 5
            case 25:
172 1
                $this->_savePolygonMRecord();
173 1
                break;
174 4
            case 15:
175 1
                $this->_savePolygonZRecord();
176 1
                break;
177 3
            case 8:
178 1
                $this->_saveMultiPointRecord();
179 1
                break;
180 2
            case 28:
181 1
                $this->_saveMultiPointMRecord();
182 1
                break;
183 1
            case 18:
184 1
                $this->_saveMultiPointZRecord();
185 1
                break;
186
            default:
187
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
188
                break;
189 12
        }
190 12
        if (ShapeFile::supportsDbase() && ! is_null($this->DBFFile)) {
191
            $this->_saveDBFData();
192
        }
193 12
    }
194
195
    /**
196
     * Updates DBF data to match header.
197
     *
198
     * @param array $header DBF structure header
199
     */
200 12
    public function updateDBFInfo($header)
201
    {
202 12
        $tmp = $this->DBFData;
203 12
        unset($this->DBFData);
204 12
        $this->DBFData = [];
205 12
        foreach ($header as $value) {
206 12
            $this->DBFData[$value[0]] = (isset($tmp[$value[0]])) ? $tmp[$value[0]] : '';
207 12
        }
208 12
    }
209
210
    /**
211
     * Reads data.
212
     *
213
     * @param string $type  type for unpack()
214
     * @param int    $count number of bytes
215
     *
216
     * @return mixed
217
     */
218 19
    private function _loadData($type, $count)
219
    {
220 19
        $data = $this->ShapeFile->readSHP($count);
221 19
        if ($data === false) {
222
            return false;
223
        }
224 19
        $this->read += strlen($data);
225
226 19
        return Util::loadData($type, $data);
227
    }
228
229
    /**
230
     * Loads metadata header from a file.
231
     */
232 19
    private function _loadHeaders()
233
    {
234 19
        $this->shapeType = false;
235 19
        $this->recordNumber = $this->_loadData('N', 4);
236 19
        if ($this->recordNumber === false) {
237 19
            return;
238
        }
239
        // We read the length of the record
240 19
        $this->size = $this->_loadData('N', 4);
241 19
        if ($this->size === false) {
242
            return;
243
        }
244 19
        $this->size = $this->size * 2 + 8;
245 19
        $this->shapeType = $this->_loadData('V', 4);
246 19
    }
247
248
    /**
249
     * Saves metadata header to a file.
250
     */
251 12
    private function _saveHeaders()
252
    {
253 12
        fwrite($this->SHPFile, pack('N', $this->recordNumber));
254 12
        fwrite($this->SHPFile, pack('N', $this->getContentLength()));
255 12
        fwrite($this->SHPFile, pack('V', $this->shapeType));
256 12
    }
257
258 19
    private function _loadPoint()
259
    {
260 19
        $data = [];
261
262 19
        $data['x'] = $this->_loadData('d', 8);
263 19
        $data['y'] = $this->_loadData('d', 8);
264
265 19
        return $data;
266
    }
267
268 1
    private function _loadPointM()
269
    {
270 1
        $data = $this->_loadPoint();
271
272 1
        $data['m'] = $this->_loadData('d', 8);
273
274 1
        return $data;
275
    }
276
277 1
    private function _loadPointZ()
278
    {
279 1
        $data = $this->_loadPoint();
280
281 1
        $data['z'] = $this->_loadData('d', 8);
282 1
        $data['m'] = $this->_loadData('d', 8);
283
284 1
        return $data;
285
    }
286
287 10
    private function _savePoint($data)
288
    {
289 10
        fwrite($this->SHPFile, Util::packDouble($data['x']));
290 10
        fwrite($this->SHPFile, Util::packDouble($data['y']));
291 10
    }
292
293 1
    private function _savePointM($data)
294
    {
295 1
        fwrite($this->SHPFile, Util::packDouble($data['x']));
296 1
        fwrite($this->SHPFile, Util::packDouble($data['y']));
297 1
        fwrite($this->SHPFile, Util::packDouble($data['m']));
298 1
    }
299
300 1
    private function _savePointZ($data)
301
    {
302 1
        fwrite($this->SHPFile, Util::packDouble($data['x']));
303 1
        fwrite($this->SHPFile, Util::packDouble($data['y']));
304 1
        fwrite($this->SHPFile, Util::packDouble($data['z']));
305 1
        fwrite($this->SHPFile, Util::packDouble($data['m']));
306 1
    }
307
308
    private function _loadNullRecord()
309
    {
310
        $this->SHPData = [];
311
    }
312
313 4
    private function _loadPointRecord()
314
    {
315 4
        $this->SHPData = $this->_loadPoint();
316 4
    }
317
318 1
    private function _loadPointMRecord()
319
    {
320 1
        $this->SHPData = $this->_loadPointM();
321 1
    }
322
323 1
    private function _loadPointZRecord()
324
    {
325 1
        $this->SHPData = $this->_loadPointZ();
326 1
    }
327
328 1
    private function _savePointRecord()
329
    {
330 1
        $this->_savePoint($this->SHPData);
331 1
    }
332
333 1
    private function _savePointMRecord()
334
    {
335 1
        $this->_savePointM($this->SHPData);
336 1
    }
337
338 1
    private function _savePointZRecord()
339
    {
340 1
        $this->_savePointZ($this->SHPData);
341 1
    }
342
343 13
    private function _loadBBox()
344
    {
345 13
        $this->SHPData['xmin'] = $this->_loadData('d', 8);
346 13
        $this->SHPData['ymin'] = $this->_loadData('d', 8);
347 13
        $this->SHPData['xmax'] = $this->_loadData('d', 8);
348 13
        $this->SHPData['ymax'] = $this->_loadData('d', 8);
349 13
    }
350
351 4
    private function _loadMultiPointRecord()
352
    {
353 4
        $this->SHPData = [];
354 4
        $this->_loadBBox();
355
356 4
        $this->SHPData['numpoints'] = $this->_loadData('V', 4);
357
358 4
        for ($i = 0; $i < $this->SHPData['numpoints']; ++$i) {
359 4
            $this->SHPData['points'][] = $this->_loadPoint();
360 4
        }
361 4
    }
362
363
    /**
364
     * @param string $type
365
     */
366 3
    private function _loadMultiPointMZRecord($type)
367
    {
368
        /* The m dimension is optional, depends on bounding box data */
369 3
        if ($type == 'm' && ! $this->ShapeFile->hasMeasure()) {
370 3
            return;
371
        }
372
373 2
        $this->SHPData[$type . 'min'] = $this->_loadData('d', 8);
374 2
        $this->SHPData[$type . 'max'] = $this->_loadData('d', 8);
375
376 2
        for ($i = 0; $i < $this->SHPData['numpoints']; ++$i) {
377 2
            $this->SHPData['points'][$i][$type] = $this->_loadData('d', 8);
378 2
        }
379 2
    }
380
381 1
    private function _loadMultiPointMRecord()
382
    {
383 1
        $this->_loadMultiPointRecord();
384
385 1
        $this->_loadMultiPointMZRecord('m');
386 1
    }
387
388 2
    private function _loadMultiPointZRecord()
389
    {
390 2
        $this->_loadMultiPointRecord();
391
392 2
        $this->_loadMultiPointMZRecord('z');
393 2
        $this->_loadMultiPointMZRecord('m');
394 2
    }
395
396 3
    private function _saveMultiPointRecord()
397
    {
398 3
        fwrite($this->SHPFile, pack('dddd', $this->SHPData['xmin'], $this->SHPData['ymin'], $this->SHPData['xmax'], $this->SHPData['ymax']));
399
400 3
        fwrite($this->SHPFile, pack('V', $this->SHPData['numpoints']));
401
402 3
        for ($i = 0; $i < $this->SHPData['numpoints']; ++$i) {
403 3
            $this->_savePoint($this->SHPData['points'][$i]);
404 3
        }
405 3
    }
406
407
    /**
408
     * @param string $type
409
     */
410 2
    private function _saveMultiPointMZRecord($type)
411
    {
412 2
        fwrite($this->SHPFile, pack('dd', $this->SHPData[$type . 'min'], $this->SHPData[$type . 'max']));
413
414 2
        for ($i = 0; $i < $this->SHPData['numpoints']; ++$i) {
415 2
            fwrite($this->SHPFile, Util::packDouble($this->SHPData['points'][$i][$type]));
416 2
        }
417 2
    }
418
419 1
    private function _saveMultiPointMRecord()
420
    {
421 1
        $this->_saveMultiPointRecord();
422
423 1
        $this->_saveMultiPointMZRecord('m');
424 1
    }
425
426 1
    private function _saveMultiPointZRecord()
427
    {
428 1
        $this->_saveMultiPointRecord();
429
430 1
        $this->_saveMultiPointMZRecord('z');
431 1
        $this->_saveMultiPointMZRecord('m');
432 1
    }
433
434 9
    private function _loadPolyLineRecord()
435
    {
436 9
        $this->SHPData = [];
437 9
        $this->_loadBBox();
438
439 9
        $this->SHPData['numparts'] = $this->_loadData('V', 4);
440 9
        $this->SHPData['numpoints'] = $this->_loadData('V', 4);
441
442 9
        $numparts = $this->SHPData['numparts'];
443 9
        $numpoints = $this->SHPData['numpoints'];
444
445 9
        for ($i = 0; $i < $numparts; ++$i) {
446 9
            $this->SHPData['parts'][$i] = $this->_loadData('V', 4);
447 9
        }
448
449 9
        $part = 0;
450 9
        for ($i = 0; $i < $numpoints; ++$i) {
451 9
            if ($part + 1 < $numparts && $i == $this->SHPData['parts'][$part + 1]) {
452 8
                ++$part;
453 8
            }
454 9
            if (! isset($this->SHPData['parts'][$part]['points']) || ! is_array($this->SHPData['parts'][$part]['points'])) {
455 9
                $this->SHPData['parts'][$part] = ['points' => []];
456 9
            }
457 9
            $this->SHPData['parts'][$part]['points'][] = $this->_loadPoint();
458 9
        }
459 9
    }
460
461
    /**
462
     * @param string $type
463
     */
464 5
    private function _loadPolyLineMZRecord($type)
465
    {
466
        /* The m dimension is optional, depends on bounding box data */
467 5
        if ($type == 'm' && ! $this->ShapeFile->hasMeasure()) {
468 5
            return;
469
        }
470
471 3
        $this->SHPData[$type . 'min'] = $this->_loadData('d', 8);
472 3
        $this->SHPData[$type . 'max'] = $this->_loadData('d', 8);
473
474 3
        $numparts = $this->SHPData['numparts'];
475 3
        $numpoints = $this->SHPData['numpoints'];
476
477 3
        $part = 0;
478 3
        for ($i = 0; $i < $numpoints; ++$i) {
479 3
            if ($part + 1 < $numparts && $i == $this->SHPData['parts'][$part + 1]) {
480
                ++$part;
481
            }
482 3
            $this->SHPData['parts'][$part]['points'][$i][$type] = $this->_loadData('d', 8);
483 3
        }
484 3
    }
485
486 2
    private function _loadPolyLineMRecord()
487
    {
488 2
        $this->_loadPolyLineRecord();
489
490 2
        $this->_loadPolyLineMZRecord('m');
491 2
    }
492
493 3
    private function _loadPolyLineZRecord()
494
    {
495 3
        $this->_loadPolyLineRecord();
496
497 3
        $this->_loadPolyLineMZRecord('z');
498 3
        $this->_loadPolyLineMZRecord('m');
499 3
    }
500
501 6
    private function _savePolyLineRecord()
502
    {
503 6
        fwrite($this->SHPFile, pack('dddd', $this->SHPData['xmin'], $this->SHPData['ymin'], $this->SHPData['xmax'], $this->SHPData['ymax']));
504
505 6
        fwrite($this->SHPFile, pack('VV', $this->SHPData['numparts'], $this->SHPData['numpoints']));
506
507 6
        $part_index = 0;
508 6
        for ($i = 0; $i < $this->SHPData['numparts']; ++$i) {
509 6
            fwrite($this->SHPFile, pack('V', $part_index));
510 6
            $part_index += count($this->SHPData['parts'][$i]['points']);
511 6
        }
512
513 6
        foreach ($this->SHPData['parts'] as $partData) {
514 6
            foreach ($partData['points'] as $pointData) {
515 6
                $this->_savePoint($pointData);
516 6
            }
517 6
        }
518 6
    }
519
520
    /**
521
     * @param string $type
522
     */
523 4
    private function _savePolyLineMZRecord($type)
524
    {
525 4
        fwrite($this->SHPFile, pack('dd', $this->SHPData[$type . 'min'], $this->SHPData[$type . 'max']));
526
527 4
        foreach ($this->SHPData['parts'] as $partData) {
528 4
            foreach ($partData['points'] as $pointData) {
529 4
                fwrite($this->SHPFile, Util::packDouble($pointData[$type]));
530 4
            }
531 4
        }
532 4
    }
533
534 2
    private function _savePolyLineMRecord()
535
    {
536 2
        $this->_savePolyLineRecord();
537
538 2
        $this->_savePolyLineMZRecord('m');
539 2
    }
540
541 2
    private function _savePolyLineZRecord()
542
    {
543 2
        $this->_savePolyLineRecord();
544
545 2
        $this->_savePolyLineMZRecord('z');
546 2
        $this->_savePolyLineMZRecord('m');
547 2
    }
548
549 3
    private function _loadPolygonRecord()
550
    {
551 3
        $this->_loadPolyLineRecord();
552 3
    }
553
554 1
    private function _loadPolygonMRecord()
555
    {
556 1
        $this->_loadPolyLineMRecord();
557 1
    }
558
559 2
    private function _loadPolygonZRecord()
560
    {
561 2
        $this->_loadPolyLineZRecord();
562 2
    }
563
564 1
    private function _savePolygonRecord()
565
    {
566 1
        $this->_savePolyLineRecord();
567 1
    }
568
569 1
    private function _savePolygonMRecord()
570
    {
571 1
        $this->_savePolyLineMRecord();
572 1
    }
573
574 1
    private function _savePolygonZRecord()
575
    {
576 1
        $this->_savePolyLineZRecord();
577 1
    }
578
579 12
    private function _adjustBBox($point)
580
    {
581
        // Adjusts bounding box based on point
582 12
        $directions = [
583 12
            'x',
584 12
            'y',
585 8
            'z',
586
            'm',
587 12
        ];
588 12
        foreach ($directions as $direction) {
589 12
            if (! isset($point[$direction])) {
590 12
                continue;
591 12
            }
592 12
            $min = $direction . 'min';
593 12
            $max = $direction . 'max';
594 12
            if (! isset($this->SHPData[$min]) || ($this->SHPData[$min] > $point[$direction])) {
595 12
                $this->SHPData[$min] = $point[$direction];
596 12
            }
597
            if (! isset($this->SHPData[$max]) || ($this->SHPData[$max] < $point[$direction])) {
598
                $this->SHPData[$max] = $point[$direction];
599
            }
600
        }
601
    }
602
603
    /**
604
     * Sets dimension to 0 if not set.
605
     *
606 8
     * @param array  $point     Point to check
607
     * @param string $dimension Dimension to check
608 8
     *
609 8
     * @return array
610 8
     */
611
    private function _fixPoint($point, $dimension)
612 8
    {
613
        if (! isset($point[$dimension])) {
614
            $point[$dimension] = 0.0; // no_value
615
        }
616
617
        return $point;
618
    }
619
620
    /**
621
     * Adjust point and bounding box when adding point.
622 12
     *
623
     * @param array $point Point data
624 12
     *
625 12
     * @return array Fixed point data
626 4
     */
627 12
    private function _adjustPoint($point)
628 4
    {
629 4
        $type = $this->shapeType / 10;
630 4
        if ($type >= 2) {
631
            $point = $this->_fixPoint($point, 'm');
632 12
        } elseif ($type >= 1) {
633
            $point = $this->_fixPoint($point, 'z');
634
            $point = $this->_fixPoint($point, 'm');
635
        }
636
637
        return $point;
638
    }
639
640
    /**
641 12
     * Adds point to a record.
642
     *
643 12
     * @param array $point     Point data
644 12
     * @param int   $partIndex Part index
645 12
     */
646
    public function addPoint($point, $partIndex = 0)
647
    {
648 12
        $point = $this->_adjustPoint($point);
649 12
        switch ($this->shapeType) {
650 12
            case 0:
651
                //Don't add anything
652 3
                return;
653 3
            case 1:
654 9
            case 11:
655 9
            case 21:
656 9
                //Substitutes the value of the current point
657 9
                $this->SHPData = $point;
658 9
                break;
659 9
            case 3:
660
            case 5:
661 6
            case 13:
662 6
            case 15:
663 6
            case 23:
664 6
            case 25:
665 3
                //Adds a new point to the selected part
666 3
                $this->SHPData['parts'][$partIndex]['points'][] = $point;
667 3
                $this->SHPData['numparts'] = count($this->SHPData['parts']);
668
                $this->SHPData['numpoints'] = 1 + (isset($this->SHPData['numpoints']) ? $this->SHPData['numpoints'] : 0);
669 3
                break;
670 3
            case 8:
671 3
            case 18:
672
            case 28:
673
                //Adds a new point
674
                $this->SHPData['points'][] = $point;
675
                $this->SHPData['numpoints'] = 1 + (isset($this->SHPData['numpoints']) ? $this->SHPData['numpoints'] : 0);
676 12
                break;
677 12
            default:
678 12
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
679
680
                return;
681
        }
682
        $this->_adjustBBox($point);
683
    }
684
685
    /**
686 12
     * Deletes point from a record.
687
     *
688 12
     * @param int $pointIndex Point index
689 12
     * @param int $partIndex  Part index
690
     */
691
    public function deletePoint($pointIndex = 0, $partIndex = 0)
692 12
    {
693 12
        switch ($this->shapeType) {
694 12
            case 0:
695
                //Don't delete anything
696 3
                break;
697 3
            case 1:
698 3
            case 11:
699 2
            case 21:
700 2
                //Sets the value of the point to zero
701 3
                $this->SHPData['x'] = 0.0;
702 1
                $this->SHPData['y'] = 0.0;
703 1
                if (in_array($this->shapeType, [11, 21])) {
704 3
                    $this->SHPData['m'] = 0.0;
705 9
                }
706 9
                if (in_array($this->shapeType, [11])) {
707 9
                    $this->SHPData['z'] = 0.0;
708 9
                }
709 9
                break;
710 9
            case 3:
711
            case 5:
712 6
            case 13:
713 6
            case 15:
714 6
            case 23:
715 6
            case 25:
716 6
                //Deletes the point from the selected part, if exists
717 6
                if (isset($this->SHPData['parts'][$partIndex]) && isset($this->SHPData['parts'][$partIndex]['points'][$pointIndex])) {
718
                    $count = count($this->SHPData['parts'][$partIndex]['points']) - 1;
719 6
                    for ($i = $pointIndex; $i < $count; ++$i) {
720 6
                        $this->SHPData['parts'][$partIndex]['points'][$i] = $this->SHPData['parts'][$partIndex]['points'][$i + 1];
721 6
                    }
722 6
                    unset($this->SHPData['parts'][$partIndex]['points'][count($this->SHPData['parts'][$partIndex]['points']) - 1]);
723 3
724 3
                    $this->SHPData['numparts'] = count($this->SHPData['parts']);
725 3
                    --$this->SHPData['numpoints'];
726
                }
727 3
                break;
728 3
            case 8:
729 3
            case 18:
730 3
            case 28:
731 3
                //Deletes the point, if exists
732 3
                if (isset($this->SHPData['points'][$pointIndex])) {
733
                    $count = count($this->SHPData['points']) - 1;
734 3
                    for ($i = $pointIndex; $i < $count; ++$i) {
735 3
                        $this->SHPData['points'][$i] = $this->SHPData['points'][$i + 1];
736 3
                    }
737
                    unset($this->SHPData['points'][count($this->SHPData['points']) - 1]);
738
739
                    --$this->SHPData['numpoints'];
740 12
                }
741 12
                break;
742
            default:
743
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
744
                break;
745
        }
746
    }
747
748 12
    /**
749
     * Returns length of content.
750
     *
751
     * @return int
752 12
     */
753 12
    public function getContentLength()
754
    {
755
        // The content length for a record is the length of the record contents section measured in 16-bit words.
756 12
        // one coordinate makes 4 16-bit words (64 bit double)
757 1
        switch ($this->shapeType) {
758 1
            case 0:
759 11
                $result = 0;
760 1
                break;
761 1
            case 1:
762 10
                $result = 10;
763 1
                break;
764 1
            case 21:
765 9
                $result = 10 + 4;
766 9
                break;
767 2
            case 11:
768 2
                $result = 10 + 8;
769 2
                break;
770 2
            case 3:
771 2
            case 5:
772 2
                $count = count($this->SHPData['parts']);
773 7
                $result = 22 + 2 * $count;
774 7
                for ($i = 0; $i < $count; ++$i) {
775 2
                    $result += 8 * count($this->SHPData['parts'][$i]['points']);
776 2
                }
777 2
                break;
778 2
            case 23:
779 2
            case 25:
780 2
                $count = count($this->SHPData['parts']);
781 5
                $result = 22 + (2 * 4) + 2 * $count;
782 5
                for ($i = 0; $i < $count; ++$i) {
783 2
                    $result += (8 + 4) * count($this->SHPData['parts'][$i]['points']);
784 2
                }
785 2
                break;
786 2
            case 13:
787 2
            case 15:
788 2
                $count = count($this->SHPData['parts']);
789 3
                $result = 22 + (4 * 4) + 2 * $count;
790 1
                for ($i = 0; $i < $count; ++$i) {
791 1
                    $result += (8 + 8) * count($this->SHPData['parts'][$i]['points']);
792 2
                }
793 1
                break;
794 1
            case 8:
795 1
                $result = 20 + 8 * count($this->SHPData['points']);
796 1
                break;
797 1
            case 28:
798
                $result = 20 + (2 * 4) + (8 + 4) * count($this->SHPData['points']);
799
                break;
800
            case 18:
801
                $result = 20 + (4 * 4) + (8 + 8) * count($this->SHPData['points']);
802 12
                break;
803
            default:
804 12
                $result = false;
805
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
806
                break;
807
        }
808
809
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result could also return false which is incompatible with the documented return type integer. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
810
    }
811
812
    private function _loadDBFData()
813
    {
814
        $this->DBFData = @dbase_get_record_with_names($this->DBFFile, $this->recordNumber);
0 ignored issues
show
Bug introduced by
The function dbase_get_record_with_names was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

814
        $this->DBFData = @/** @scrutinizer ignore-call */ dbase_get_record_with_names($this->DBFFile, $this->recordNumber);
Loading history...
815
        unset($this->DBFData['deleted']);
816
    }
817
818
    private function _saveDBFData()
819
    {
820
        if (count($this->DBFData) == 0) {
821
            return;
822
        }
823
        unset($this->DBFData['deleted']);
824
        if ($this->recordNumber <= dbase_numrecords($this->DBFFile)) {
0 ignored issues
show
Bug introduced by
The function dbase_numrecords was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

824
        if ($this->recordNumber <= /** @scrutinizer ignore-call */ dbase_numrecords($this->DBFFile)) {
Loading history...
825
            if (! dbase_replace_record($this->DBFFile, array_values($this->DBFData), $this->recordNumber)) {
0 ignored issues
show
Bug introduced by
The function dbase_replace_record was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

825
            if (! /** @scrutinizer ignore-call */ dbase_replace_record($this->DBFFile, array_values($this->DBFData), $this->recordNumber)) {
Loading history...
826
                $this->setError('I wasn\'t possible to update the information in the DBF file.');
827
            }
828
        } else {
829
            if (! dbase_add_record($this->DBFFile, array_values($this->DBFData))) {
0 ignored issues
show
Bug introduced by
The function dbase_add_record was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

829
            if (! /** @scrutinizer ignore-call */ dbase_add_record($this->DBFFile, array_values($this->DBFData))) {
Loading history...
830
                $this->setError('I wasn\'t possible to add the information to the DBF file.');
831
            }
832
        }
833
    }
834
835
    /**
836
     * Sets error message.
837
     *
838
     * @param string $error
839
     */
840
    public function setError($error)
841
    {
842
        $this->lastError = $error;
843
    }
844
845 1
    /**
846
     * Returns shape name.
847 1
     *
848
     * @return string
849
     */
850
    public function getShapeName()
851
    {
852
        return Util::nameShape($this->shapeType);
853
    }
854
}
855