Passed
Push — master ( dd7d26...914783 )
by Michal
03:38
created

ShapeRecord::_loadBBox()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 5
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 7
rs 9.4285
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
 * http://www.gnu.org/copyleft/gpl.html.
21
 */
22
namespace ShapeFile;
23
24
class ShapeRecord {
25
    private $SHPFile = null;
26
    private $DBFFile = null;
27
    private $ShapeFile = null;
28
29
    private $size = 0;
30
    private $read = 0;
31
32
    public $recordNumber = null;
33
    public $shapeType = null;
34
35
    public $lastError = '';
36
37
    public $SHPData = array();
38
    public $DBFData = array();
39
40
    /**
41
     * @param integer $shapeType
42
     */
43
    public function __construct($shapeType) {
44
        $this->shapeType = $shapeType;
45
    }
46
47
    public function loadFromFile(&$ShapeFile, &$SHPFile, &$DBFFile) {
48
        $this->ShapeFile = $ShapeFile;
49
        $this->SHPFile = $SHPFile;
50
        $this->DBFFile = $DBFFile;
51
        $this->_loadHeaders();
52
53
        /* No header read */
54
        if ($this->read == 0) {
55
            return;
56
        }
57
58
        switch ($this->shapeType) {
59
            case 0:
60
                $this->_loadNullRecord();
61
                break;
62
            case 1:
63
                $this->_loadPointRecord();
64
                break;
65
            case 21:
66
                $this->_loadPointMRecord();
67
                break;
68
            case 11:
69
                $this->_loadPointZRecord();
70
                break;
71
            case 3:
72
                $this->_loadPolyLineRecord();
73
                break;
74
            case 23:
75
                $this->_loadPolyLineMRecord();
76
                break;
77
            case 13:
78
                $this->_loadPolyLineZRecord();
79
                break;
80
            case 5:
81
                $this->_loadPolygonRecord();
82
                break;
83
            case 25:
84
                $this->_loadPolygonMRecord();
85
                break;
86
            case 15:
87
                $this->_loadPolygonZRecord();
88
                break;
89
            case 8:
90
                $this->_loadMultiPointRecord();
91
                break;
92
            case 28:
93
                $this->_loadMultiPointMRecord();
94
                break;
95
            case 18:
96
                $this->_loadMultiPointZRecord();
97
                break;
98
            default:
99
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
100
                break;
101
        }
102
103
        /* We need to skip rest of the record */
104
        while ($this->read < $this->size) {
105
            $this->_loadData('V', 4);
106
        }
107
108
        /* Check if we didn't read too much */
109
        if ($this->read != $this->size) {
110
            $this->setError(sprintf('Failed to parse record, read=%d, size=%d', $this->read, $this->size));
111
        }
112
113
        if (ShapeFile::supports_dbase() && isset($this->DBFFile)) {
114
            $this->_loadDBFData();
115
        }
116
    }
117
118
    public function saveToFile(&$SHPFile, &$DBFFile, $recordNumber) {
119
        $this->SHPFile = $SHPFile;
120
        $this->DBFFile = $DBFFile;
121
        $this->recordNumber = $recordNumber;
122
        $this->_saveHeaders();
123
124
        switch ($this->shapeType) {
125
            case 0:
126
                // Nothing to save
127
                break;
128
            case 1:
129
                $this->_savePointRecord();
130
                break;
131
            case 21:
132
                $this->_savePointMRecord();
133
                break;
134
            case 11:
135
                $this->_savePointZRecord();
136
                break;
137
            case 3:
138
                $this->_savePolyLineRecord();
139
                break;
140
            case 23:
141
                $this->_savePolyLineMRecord();
142
                break;
143
            case 13:
144
                $this->_savePolyLineZRecord();
145
                break;
146
            case 5:
147
                $this->_savePolygonRecord();
148
                break;
149
            case 25:
150
                $this->_savePolygonMRecord();
151
                break;
152
            case 15:
153
                $this->_savePolygonZRecord();
154
                break;
155
            case 8:
156
                $this->_saveMultiPointRecord();
157
                break;
158
            case 28:
159
                $this->_saveMultiPointMRecord();
160
                break;
161
            case 18:
162
                $this->_saveMultiPointZRecord();
163
                break;
164
            default:
165
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
166
                break;
167
        }
168
        $this->_saveDBFData();
169
    }
170
171
    public function updateDBFInfo($header) {
172
        $tmp = $this->DBFData;
173
        unset($this->DBFData);
174
        $this->DBFData = array();
175
        foreach ($header as $value) {
176
            $this->DBFData[$value[0]] = (isset($tmp[$value[0]])) ? $tmp[$value[0]] : '';
177
        }
178
    }
179
180
    /**
181
     * Reads data
182
     *
183
     * @param string $type type for unpack()
184
     * @param int    $count number of bytes
185
     *
186
     * @return mixed
187
     */
188
    private function _loadData($type, $count)
189
    {
190
        $data = $this->ShapeFile->readSHP($count);
191
        if ($data !== false) {
192
            $this->read += strlen($data);
193
        }
194
        return Util::loadData($type, $data);
195
    }
196
197
    private function _loadHeaders() {
198
        $this->recordNumber = $this->_loadData('N', 4);
199
        // We read the length of the record
200
        $this->size = $this->_loadData('N', 4) * 2 + 8;
0 ignored issues
show
Documentation Bug introduced by
The property $size was declared of type integer, but $this->_loadData('N', 4) * 2 + 8 is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
201
        $this->shapeType = $this->_loadData('V', 4);
202
    }
203
204
    private function _saveHeaders() {
205
        fwrite($this->SHPFile, pack('N', $this->recordNumber));
206
        fwrite($this->SHPFile, pack('N', $this->getContentLength()));
207
        fwrite($this->SHPFile, pack('V', $this->shapeType));
208
    }
209
210
    private function _loadPoint() {
211
        $data = array();
212
213
        $data['x'] = $this->_loadData('d', 8);
214
        $data['y'] = $this->_loadData('d', 8);
215
216
        return $data;
217
    }
218
219
    private function _loadPointM() {
220
        $data = $this->loadPoint();
0 ignored issues
show
Bug introduced by
The method loadPoint() does not exist on ShapeFile\ShapeRecord. Did you maybe mean _loadPoint()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
221
222
        $data['m'] = $this->_loadData('d', 8);
223
224
        return $data;
225
    }
226
227
    private function _loadPointZ() {
228
        $data = $this->loadPoint();
0 ignored issues
show
Bug introduced by
The method loadPoint() does not exist on ShapeFile\ShapeRecord. Did you maybe mean _loadPoint()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
229
230
        $data['z'] = $this->_loadData('d', 8);
231
        $data['m'] = $this->_loadData('d', 8);
232
233
        return $data;
234
    }
235
236
    private function _savePoint($data) {
237
        fwrite($this->SHPFile, Util::packDouble($data['x']));
238
        fwrite($this->SHPFile, Util::packDouble($data['y']));
239
    }
240
241
    private function _savePointM($data) {
242
        fwrite($this->SHPFile, Util::packDouble($data['x']));
243
        fwrite($this->SHPFile, Util::packDouble($data['y']));
244
        fwrite($this->SHPFile, Util::packDouble($data['m']));
245
    }
246
247
    private function _savePointZ($data) {
248
        fwrite($this->SHPFile, Util::packDouble($data['x']));
249
        fwrite($this->SHPFile, Util::packDouble($data['y']));
250
        fwrite($this->SHPFile, Util::packDouble($data['z']));
251
        fwrite($this->SHPFile, Util::packDouble($data['m']));
252
    }
253
254
    private function _loadNullRecord() {
255
        $this->SHPData = array();
256
    }
257
258
    private function _loadPointRecord() {
259
        $this->SHPData = $this->_loadPoint();
260
    }
261
262
    private function _loadPointMRecord() {
263
        $this->SHPData = $this->_loadPointM();
264
    }
265
266
    private function _loadPointZRecord() {
267
        $this->SHPData = $this->_loadPointZ();
268
    }
269
270
    private function _savePointRecord() {
271
        $this->_savePoint($this->SHPData);
272
    }
273
274
    private function _savePointMRecord() {
275
        $this->_savePointM($this->SHPData);
276
    }
277
278
    private function _savePointZRecord() {
279
        $this->_savePointZ($this->SHPData);
280
    }
281
282
    private function _loadBBox()
283
    {
284
        $this->SHPData['xmin'] = $this->_loadData('d', 8);
285
        $this->SHPData['ymin'] = $this->_loadData('d', 8);
286
        $this->SHPData['xmax'] = $this->_loadData('d', 8);
287
        $this->SHPData['ymax'] = $this->_loadData('d', 8);
288
    }
289
290
    private function _loadMultiPointRecord() {
291
        $this->SHPData = array();
292
        $this->_loadBBox();
293
294
        $this->SHPData['numpoints'] = $this->_loadData('V', 4);
295
296
        for ($i = 0; $i < $this->SHPData['numpoints']; $i++) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
297
            $this->SHPData['points'][] = $this->_loadPoint();
298
        }
299
    }
300
301
    /**
302
     * @param string $type
303
     */
304
    private function _loadMultiPointMZRecord($type)
305
    {
306
        /* The m dimension is optional, depends on bounding box data */
307
        if ($type == 'm' && ! $this->ShapeFile->hasMeasure()) {
308
            return;
309
        }
310
311
        $this->SHPData[$type.'min'] = $this->_loadData('d', 8);
312
        $this->SHPData[$type.'max'] = $this->_loadData('d', 8);
313
314
        for ($i = 0; $i < $this->SHPData['numpoints']; $i++) {
315
            $this->SHPData['points'][$i][$type] = $this->_loadData('d', 8);
316
        }
317
    }
318
319
    private function _loadMultiPointMRecord() {
320
        $this->_loadMultiPointRecord();
321
322
        $this->_loadMultiPointMZRecord('m');
323
    }
324
325
    private function _loadMultiPointZRecord() {
326
        $this->_loadMultiPointRecord();
327
328
        $this->_loadMultiPointMZRecord('z');
329
        $this->_loadMultiPointMZRecord('m');
330
    }
331
332
    private function _saveMultiPointRecord() {
333
        fwrite($this->SHPFile, pack('dddd', $this->SHPData['xmin'], $this->SHPData['ymin'], $this->SHPData['xmax'], $this->SHPData['ymax']));
334
335
        fwrite($this->SHPFile, pack('V', $this->SHPData['numpoints']));
336
337
        for ($i = 0; $i <= $this->SHPData['numpoints']; $i++) {
338
            $this->_savePoint($this->SHPData['points'][$i]);
339
        }
340
    }
341
342
    /**
343
     * @param string $type
344
     */
345
    private function _saveMultiPointMZRecord($type) {
346
347
        fwrite($this->SHPFile, pack('dd', $this->SHPData[$type.'min'], $this->SHPData[$type.'max']));
348
349
        for ($i = 0; $i <= $this->SHPData['numpoints']; $i++) {
350
            fwrite($this->SHPFile, Util::packDouble($this->SHPData['points'][$type]));
351
        }
352
    }
353
354
    private function _saveMultiPointMRecord() {
355
        $this->_saveMultiPointRecord();
356
357
        $this->_saveMultiPointMZRecord('m');
358
    }
359
360
    private function _saveMultiPointZRecord() {
361
        $this->_saveMultiPointRecord();
362
363
        $this->_saveMultiPointMZRecord('z');
364
        $this->_saveMultiPointMZRecord('m');
365
    }
366
367
    private function _loadPolyLineRecord() {
368
        $this->SHPData = array();
369
        $this->_loadBBox();
370
371
        $this->SHPData['numparts']  = $this->_loadData('V', 4);
372
        $this->SHPData['numpoints'] = $this->_loadData('V', 4);
373
374
        $numparts = $this->SHPData['numparts'];
375
        $numpoints = $this->SHPData['numpoints'];
376
377
        for ($i = 0; $i < $numparts; $i++) {
378
            $this->SHPData['parts'][$i] = $this->_loadData('V', 4);
379
        }
380
381
        $part = 0;
382
        for ($i = 0; $i < $numpoints; $i++) {
383 View Code Duplication
            if ($part + 1 < $numparts && $this->SHPData['parts'][$part + 1] == $i) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
384
                $part++;
385
            }
386
            if (!isset($this->SHPData['parts'][$part]['points']) || !is_array($this->SHPData['parts'][$part]['points'])) {
387
                $this->SHPData['parts'][$part] = array('points' => array());
388
            }
389
            $this->SHPData['parts'][$part]['points'][] = $this->_loadPoint();
390
        }
391
    }
392
393
    /**
394
     * @param string $type
395
     */
396
    private function _loadPolyLineMZRecord($type) {
397
        /* The m dimension is optional, depends on bounding box data */
398
        if ($type == 'm' && ! $this->ShapeFile->hasMeasure()) {
399
            return;
400
        }
401
402
        $this->SHPData[$type.'min'] = $this->_loadData('d', 8);
403
        $this->SHPData[$type.'max'] = $this->_loadData('d', 8);
404
405
        $numparts = $this->SHPData['numparts'];
406
        $numpoints = $this->SHPData['numpoints'];
407
408
        $part = 0;
409
        for ($i = 0; $i < $numpoints; $i++) {
410 View Code Duplication
            if ($part + 1 < $numparts && $this->SHPData['parts'][$part + 1] == $i) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
411
                $part++;
412
            }
413
            $this->SHPData['parts'][$part]['points'][$i][$type] = $this->_loadData('d', 8);
414
        }
415
    }
416
417
    private function _loadPolyLineMRecord() {
418
        $this->_loadPolyLineRecord();
419
420
        $this->_loadPolyLineMZRecord('m');
421
    }
422
423
    private function _loadPolyLineZRecord() {
424
        $this->_loadPolyLineRecord();
425
426
        $this->_loadPolyLineMZRecord('z');
427
        $this->_loadPolyLineMZRecord('m');
428
    }
429
430
    private function _savePolyLineRecord() {
431
        fwrite($this->SHPFile, pack('dddd', $this->SHPData['xmin'], $this->SHPData['ymin'], $this->SHPData['xmax'], $this->SHPData['ymax']));
432
433
        fwrite($this->SHPFile, pack('VV', $this->SHPData['numparts'], $this->SHPData['numpoints']));
434
435
        for ($i = 0; $i < $this->SHPData['numparts']; $i++) {
436
            fwrite($this->SHPFile, pack('V', count($this->SHPData['parts'][$i]) - 1));
437
        }
438
439
        foreach ($this->SHPData['parts'] as $partData) {
440
            foreach ($partData['points'] as $pointData) {
441
                $this->_savePoint($pointData);
442
            }
443
        }
444
    }
445
446
    /**
447
     * @param string $type
448
     */
449
    private function _savePolyLineMZRecord($type) {
450
        fwrite($this->SHPFile, pack('dd', $this->SHPData[$type.'min'], $this->SHPData[$type.'max']));
451
452
        foreach ($this->SHPData['parts'] as $partData) {
453
            foreach ($partData['points'] as $pointData) {
454
                fwrite($this->SHPFile, Util::packDouble($pointData[$type]));
455
            }
456
        }
457
    }
458
459
    private function _savePolyLineMRecord() {
460
        $this->_savePolyLineRecord();
461
462
        $this->_savePolyLineMZRecord('m');
463
    }
464
465
    private function _savePolyLineZRecord() {
466
        $this->_savePolyLineRecord();
467
468
        $this->_savePolyLineMZRecord('z');
469
        $this->_savePolyLineMZRecord('m');
470
    }
471
472
    private function _loadPolygonRecord() {
473
        $this->_loadPolyLineRecord();
474
    }
475
476
    private function _loadPolygonMRecord() {
477
        $this->_loadPolyLineMRecord();
478
    }
479
480
    private function _loadPolygonZRecord() {
481
        $this->_loadPolyLineZRecord();
482
    }
483
484
    private function _savePolygonRecord() {
485
        $this->_savePolyLineRecord();
486
    }
487
488
    private function _savePolygonMRecord() {
489
        $this->_savePolyLineMRecord();
490
    }
491
492
    private function _savePolygonZRecord() {
493
        $this->_savePolyLineZRecord();
494
    }
495
496
    private function _adjustBBox($point) {
497
        // Adjusts bounding box based on point
498
        $directions = array('x', 'y', 'z', 'm');
499
        foreach ($directions as $direction) {
500
            if (!isset($point[$direction])) {
501
                continue;
502
            }
503
            $min = $direction.'min';
504
            $max = $direction.'max';
505
            if (!isset($this->SHPData[$min]) || ($this->SHPData[$min] > $point[$direction])) {
506
                $this->SHPData[$min] = $point[$direction];
507
            }
508
            if (!isset($this->SHPData[$max]) || ($this->SHPData[$max] < $point[$direction])) {
509
                $this->SHPData[$max] = $point[$direction];
510
            }
511
        }
512
    }
513
514
    public function addPoint($point, $partIndex = 0) {
515
        switch ($this->shapeType) {
516
            case 0:
517
                //Don't add anything
518
                break;
519
            case 1:
520
            case 11:
521
            case 21:
522
                if (in_array($this->shapeType, array(11, 21)) && !isset($point['m'])) {
523
                    $point['m'] = 0.0; // no_value
524
                }
525
                if (in_array($this->shapeType, array(11)) && !isset($point['z'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
526
                    $point['z'] = 0.0; // no_value
527
                }
528
529
                //Substitutes the value of the current point
530
                $this->SHPData = $point;
531
                $this->_adjustBBox($point);
532
                break;
533
            case 3:
534
            case 5:
535
            case 13:
536
            case 15:
537
            case 23:
538
            case 25:
539
                if (in_array($this->shapeType, array(13, 15, 23, 25)) && !isset($point['m'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
540
                    $point['m'] = 0.0; // no_value
541
                }
542
                if (in_array($this->shapeType, array(13, 15)) && !isset($point['z'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
543
                    $point['z'] = 0.0; // no_value
544
                }
545
546
                $this->_adjustBBox($point);
547
548
                //Adds a new point to the selected part
549
                $this->SHPData['parts'][$partIndex]['points'][] = $point;
550
551
                $this->SHPData['numparts'] = count($this->SHPData['parts']);
552
                $this->SHPData['numpoints'] = 1 + (isset($this->SHPData['numpoints']) ? $this->SHPData['numpoints'] : 0);
553
                break;
554
            case 8:
555
            case 18:
556
            case 28:
557
                if (in_array($this->shapeType, array(18, 28)) && !isset($point['m'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
558
                    $point['m'] = 0.0; // no_value
559
                }
560
                if (in_array($this->shapeType, array(18)) && !isset($point['z'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
561
                    $point['z'] = 0.0; // no_value
562
                }
563
564
                $this->_adjustBBox($point);
565
566
                //Adds a new point
567
                $this->SHPData['points'][] = $point;
568
                $this->SHPData['numpoints'] = 1 + (isset($this->SHPData['numpoints']) ? $this->SHPData['numpoints'] : 0);
569
                break;
570
            default:
571
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
572
                break;
573
        }
574
    }
575
576
    public function deletePoint($pointIndex = 0, $partIndex = 0) {
577
        switch ($this->shapeType) {
578
            case 0:
579
                //Don't delete anything
580
                break;
581
            case 1:
582
            case 11:
583
            case 21:
584
                //Sets the value of the point to zero
585
                $this->SHPData['x'] = 0.0;
586
                $this->SHPData['y'] = 0.0;
587
                if (in_array($this->shapeType, array(11, 21))) {
588
                    $this->SHPData['m'] = 0.0;
589
                }
590
                if (in_array($this->shapeType, array(11))) {
591
                    $this->SHPData['z'] = 0.0;
592
                }
593
                break;
594
            case 3:
595
            case 5:
596
            case 13:
597
            case 15:
598
            case 23:
599
            case 25:
600
                //Deletes the point from the selected part, if exists
601
                if (isset($this->SHPData['parts'][$partIndex]) && isset($this->SHPData['parts'][$partIndex]['points'][$pointIndex])) {
602
                    $count = count($this->SHPData['parts'][$partIndex]['points']) - 1;
603
                    for ($i = $pointIndex; $i < $count; $i++) {
604
                        $this->SHPData['parts'][$partIndex]['points'][$i] = $this->SHPData['parts'][$partIndex]['points'][$i + 1];
605
                    }
606
                    unset($this->SHPData['parts'][$partIndex]['points'][count($this->SHPData['parts'][$partIndex]['points']) - 1]);
607
608
                    $this->SHPData['numparts'] = count($this->SHPData['parts']);
609
                    $this->SHPData['numpoints']--;
610
                }
611
                break;
612
            case 8:
613
            case 18:
614
            case 28:
615
                //Deletes the point, if exists
616
                if (isset($this->SHPData['points'][$pointIndex])) {
617
                    $count = count($this->SHPData['points']) - 1;
618
                    for ($i = $pointIndex; $i < $count; $i++) {
619
                        $this->SHPData['points'][$i] = $this->SHPData['points'][$i + 1];
620
                    }
621
                    unset($this->SHPData['points'][count($this->SHPData['points']) - 1]);
622
623
                    $this->SHPData['numpoints']--;
624
                }
625
                break;
626
            default:
627
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
628
                break;
629
        }
630
    }
631
632
    public function getContentLength() {
633
        // The content length for a record is the length of the record contents section measured in 16-bit words.
634
        // one coordinate makes 4 16-bit words (64 bit double)
635
        switch ($this->shapeType) {
636
            case 0:
637
                $result = 0;
638
                break;
639
            case 1:
640
                $result = 10;
641
                break;
642
            case 21:
643
                $result = 10 + 4;
644
                break;
645
            case 11:
646
                $result = 10 + 8;
647
                break;
648
            case 3:
649
            case 5:
650
                $count = count($this->SHPData['parts']);
651
                $result = 22 + 2 * $count;
652
                for ($i = 0; $i < $count; $i++) {
653
                    $result += 8 * count($this->SHPData['parts'][$i]['points']);
654
                }
655
                break;
656
            case 23:
657 View Code Duplication
            case 25:
658
                $count = count($this->SHPData['parts']);
659
                $result = 22 + (2 * 4) + 2 * $count;
660
                for ($i = 0; $i < $count; $i++) {
661
                    $result += (8 + 4) * count($this->SHPData['parts'][$i]['points']);
662
                }
663
                break;
664
            case 13:
665 View Code Duplication
            case 15:
666
                $count = count($this->SHPData['parts']);
667
                $result = 22 + (4 * 4) + 2 * $count;
668
                for ($i = 0; $i < $count; $i++) {
669
                    $result += (8 + 8) * count($this->SHPData['parts'][$i]['points']);
670
                }
671
                break;
672
            case 8:
673
                $result = 20 + 8 * count($this->SHPData['points']);
674
                break;
675 View Code Duplication
            case 28:
676
                $result = 20 + (2 * 4) + (8 + 4) * count($this->SHPData['points']);
677
                break;
678 View Code Duplication
            case 18:
679
                $result = 20 + (4 * 4) + (8 + 8) * count($this->SHPData['points']);
680
                break;
681
            default:
682
                $result = false;
683
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
684
                break;
685
        }
686
        return $result;
687
    }
688
689
    private function _loadDBFData() {
690
        $this->DBFData = @dbase_get_record_with_names($this->DBFFile, $this->recordNumber);
691
        unset($this->DBFData['deleted']);
692
    }
693
694
    private function _saveDBFData() {
695
        unset($this->DBFData['deleted']);
696
        if ($this->recordNumber <= dbase_numrecords($this->DBFFile)) {
697
            if (!dbase_replace_record($this->DBFFile, array_values($this->DBFData), $this->recordNumber)) {
698
                $this->setError('I wasn\'t possible to update the information in the DBF file.');
699
            }
700
        } else {
701
            if (!dbase_add_record($this->DBFFile, array_values($this->DBFData))) {
702
                $this->setError('I wasn\'t possible to add the information to the DBF file.');
703
            }
704
        }
705
    }
706
707
    /**
708
     * Sets error message
709
     *
710
     * @param string $error
711
     *
712
     * @return void
713
     */
714
    public function setError($error) {
715
        $this->lastError = $error;
716
    }
717
718
    /**
719
     * Returns shape name
720
     *
721
     * @return string
722
     */
723
    public function getShapeName()
724
    {
725
        return ShapeFile::nameShape($this->shapeType);
726
    }
727
}
728