Completed
Push — master ( 387f8d...71c9c9 )
by Michal
03:08
created

ShapeRecord::addPoint()   C

Complexity

Conditions 16
Paths 23

Size

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