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

ShapeRecord::_loadPolygonZRecord()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
ccs 3
cts 3
cp 1
crap 1
rs 10
c 1
b 0
f 0
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