Completed
Push — master ( 67a9e5...5289c4 )
by Michal
03:56
created

ShapeRecord::addPoint()   C

Complexity

Conditions 16
Paths 23

Size

Total Lines 38
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 16.5

Importance

Changes 8
Bugs 0 Features 0
Metric Value
cc 16
eloc 30
c 8
b 0
f 0
nc 23
nop 2
dl 0
loc 38
ccs 28
cts 32
cp 0.875
crap 16.5
rs 5.0151

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 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 = array();
43
    public $DBFData = array();
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
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));
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::supports_dbase() && 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::supports_dbase() && !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 = array();
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 = array();
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 = array();
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 = array();
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 = array();
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 View Code Duplication
            if ($part + 1 < $numparts && $this->SHPData['parts'][$part + 1] == $i) {
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] = array('points' => array());
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 View Code Duplication
            if ($part + 1 < $numparts && $this->SHPData['parts'][$part + 1] == $i) {
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 = array('x', 'y', 'z', 'm');
583 12
        foreach ($directions as $direction) {
584 12
            if (!isset($point[$direction])) {
585 8
                continue;
586
            }
587 12
            $min = $direction . 'min';
588 12
            $max = $direction . 'max';
589 12
            if (!isset($this->SHPData[$min]) || ($this->SHPData[$min] > $point[$direction])) {
590 12
                $this->SHPData[$min] = $point[$direction];
591 12
            }
592 12
            if (!isset($this->SHPData[$max]) || ($this->SHPData[$max] < $point[$direction])) {
593 12
                $this->SHPData[$max] = $point[$direction];
594 12
            }
595 12
        }
596 12
    }
597
598
    /**
599
     * Sets dimension to 0 if not set.
600
     *
601
     * @param array  $point     Point to check
602
     * @param string $dimension Dimension to check
603
     *
604
     * @return array
605
     */
606 8
    private function _fixPoint($point, $dimension)
607
    {
608 8
        if (!isset($point[$dimension])) {
609 8
            $point[$dimension] = 0.0; // no_value
610 8
        }
611
612 8
        return $point;
613
    }
614
615
    /**
616
     * Adjust point and bounding box when adding point.
617
     *
618
     * @param array $point Point data
619
     *
620
     * @return array Fixed point data
621
     */
622 12
    private function _adjustPoint($point)
623
    {
624 12
        $type = $this->shapeType / 10;
625 12
        if ($type >= 2) {
626 4
            $point = $this->_fixPoint($point, 'm');
627 12
        } elseif ($type >= 1) {
628 4
            $point = $this->_fixPoint($point, 'z');
629 4
            $point = $this->_fixPoint($point, 'm');
630 4
        }
631
632 12
        return $point;
633
    }
634
635
    /**
636
     * Adds point to a record.
637
     *
638
     * @param array $point     Point data
639
     * @param int   $partIndex Part index
640
     */
641 12
    public function addPoint($point, $partIndex = 0)
642
    {
643 12
        $point = $this->_adjustPoint($point);
644 12
        switch ($this->shapeType) {
645 12
            case 0:
646
                //Don't add anything
647
                return;
648 12
            case 1:
649 12
            case 11:
650 12
            case 21:
651
                //Substitutes the value of the current point
652 3
                $this->SHPData = $point;
653 3
                break;
654 9
            case 3:
655 9
            case 5:
656 9
            case 13:
657 9
            case 15:
658 9
            case 23:
659 9
            case 25:
660
                //Adds a new point to the selected part
661 6
                $this->SHPData['parts'][$partIndex]['points'][] = $point;
662 6
                $this->SHPData['numparts'] = count($this->SHPData['parts']);
663 6
                $this->SHPData['numpoints'] = 1 + (isset($this->SHPData['numpoints']) ? $this->SHPData['numpoints'] : 0);
664 6
                break;
665 3
            case 8:
666 3
            case 18:
667 3
            case 28:
668
                //Adds a new point
669 3
                $this->SHPData['points'][] = $point;
670 3
                $this->SHPData['numpoints'] = 1 + (isset($this->SHPData['numpoints']) ? $this->SHPData['numpoints'] : 0);
671 3
                break;
672
            default:
673
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
674
675
                return;
676 12
        }
677 12
        $this->_adjustBBox($point);
678 12
    }
679
680
    /**
681
     * Deletes point from a record.
682
     *
683
     * @param int $pointIndex Point index
684
     * @param int $partIndex  Part index
685
     */
686 12
    public function deletePoint($pointIndex = 0, $partIndex = 0)
687
    {
688 12
        switch ($this->shapeType) {
689 12
            case 0:
690
                //Don't delete anything
691
                break;
692 12
            case 1:
693 12
            case 11:
694 12
            case 21:
695
                //Sets the value of the point to zero
696 3
                $this->SHPData['x'] = 0.0;
697 3
                $this->SHPData['y'] = 0.0;
698 3
                if (in_array($this->shapeType, array(11, 21))) {
699 2
                    $this->SHPData['m'] = 0.0;
700 2
                }
701 3
                if (in_array($this->shapeType, array(11))) {
702 1
                    $this->SHPData['z'] = 0.0;
703 1
                }
704 3
                break;
705 9
            case 3:
706 9
            case 5:
707 9
            case 13:
708 9
            case 15:
709 9
            case 23:
710 9
            case 25:
711
                //Deletes the point from the selected part, if exists
712 6
                if (isset($this->SHPData['parts'][$partIndex]) && isset($this->SHPData['parts'][$partIndex]['points'][$pointIndex])) {
713 6
                    $count = count($this->SHPData['parts'][$partIndex]['points']) - 1;
714 6
                    for ($i = $pointIndex; $i < $count; ++$i) {
715 6
                        $this->SHPData['parts'][$partIndex]['points'][$i] = $this->SHPData['parts'][$partIndex]['points'][$i + 1];
716 6
                    }
717 6
                    unset($this->SHPData['parts'][$partIndex]['points'][count($this->SHPData['parts'][$partIndex]['points']) - 1]);
718
719 6
                    $this->SHPData['numparts'] = count($this->SHPData['parts']);
720 6
                    --$this->SHPData['numpoints'];
721 6
                }
722 6
                break;
723 3
            case 8:
724 3
            case 18:
725 3
            case 28:
726
                //Deletes the point, if exists
727 3
                if (isset($this->SHPData['points'][$pointIndex])) {
728 3
                    $count = count($this->SHPData['points']) - 1;
729 3
                    for ($i = $pointIndex; $i < $count; ++$i) {
730 3
                        $this->SHPData['points'][$i] = $this->SHPData['points'][$i + 1];
731 3
                    }
732 3
                    unset($this->SHPData['points'][count($this->SHPData['points']) - 1]);
733
734 3
                    --$this->SHPData['numpoints'];
735 3
                }
736 3
                break;
737
            default:
738
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
739
                break;
740 12
        }
741 12
    }
742
743
    /**
744
     * Returns length of content.
745
     *
746
     * @return int
747
     */
748 12
    public function getContentLength()
749
    {
750
        // The content length for a record is the length of the record contents section measured in 16-bit words.
751
        // one coordinate makes 4 16-bit words (64 bit double)
752 12
        switch ($this->shapeType) {
753 12
            case 0:
754
                $result = 0;
755
                break;
756 12
            case 1:
757 1
                $result = 10;
758 1
                break;
759 11
            case 21:
760 1
                $result = 10 + 4;
761 1
                break;
762 10
            case 11:
763 1
                $result = 10 + 8;
764 1
                break;
765 9
            case 3:
766 9
            case 5:
767 2
                $count = count($this->SHPData['parts']);
768 2
                $result = 22 + 2 * $count;
769 2
                for ($i = 0; $i < $count; ++$i) {
770 2
                    $result += 8 * count($this->SHPData['parts'][$i]['points']);
771 2
                }
772 2
                break;
773 7
            case 23:
774 7 View Code Duplication
            case 25:
775 2
                $count = count($this->SHPData['parts']);
776 2
                $result = 22 + (2 * 4) + 2 * $count;
777 2
                for ($i = 0; $i < $count; ++$i) {
778 2
                    $result += (8 + 4) * count($this->SHPData['parts'][$i]['points']);
779 2
                }
780 2
                break;
781 5
            case 13:
782 5 View Code Duplication
            case 15:
783 2
                $count = count($this->SHPData['parts']);
784 2
                $result = 22 + (4 * 4) + 2 * $count;
785 2
                for ($i = 0; $i < $count; ++$i) {
786 2
                    $result += (8 + 8) * count($this->SHPData['parts'][$i]['points']);
787 2
                }
788 2
                break;
789 3
            case 8:
790 1
                $result = 20 + 8 * count($this->SHPData['points']);
791 1
                break;
792 2 View Code Duplication
            case 28:
793 1
                $result = 20 + (2 * 4) + (8 + 4) * count($this->SHPData['points']);
794 1
                break;
795 1 View Code Duplication
            case 18:
796 1
                $result = 20 + (4 * 4) + (8 + 8) * count($this->SHPData['points']);
797 1
                break;
798
            default:
799
                $result = false;
800
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
801
                break;
802 12
        }
803
804 12
        return $result;
805
    }
806
807
    private function _loadDBFData()
808
    {
809
        $this->DBFData = @dbase_get_record_with_names($this->DBFFile, $this->recordNumber);
810
        unset($this->DBFData['deleted']);
811
    }
812
813
    private function _saveDBFData()
814
    {
815
        if (count($this->DBFData) == 0) {
816
            return;
817
        }
818
        unset($this->DBFData['deleted']);
819
        if ($this->recordNumber <= dbase_numrecords($this->DBFFile)) {
820
            if (!dbase_replace_record($this->DBFFile, array_values($this->DBFData), $this->recordNumber)) {
821
                $this->setError('I wasn\'t possible to update the information in the DBF file.');
822
            }
823
        } else {
824
            if (!dbase_add_record($this->DBFFile, array_values($this->DBFData))) {
825
                $this->setError('I wasn\'t possible to add the information to the DBF file.');
826
            }
827
        }
828
    }
829
830
    /**
831
     * Sets error message.
832
     *
833
     * @param string $error
834
     */
835
    public function setError($error)
836
    {
837
        $this->lastError = $error;
838
    }
839
840
    /**
841
     * Returns shape name.
842
     *
843
     * @return string
844
     */
845 1
    public function getShapeName()
846
    {
847 1
        return Util::nameShape($this->shapeType);
848
    }
849
}
850