Completed
Push — master ( 9056dc...e53124 )
by Michal
03:18
created

ShapeRecord::_savePointM()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 4
nc 1
nop 1
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
    public $recordNumber = null;
30
    private $shapeType = null;
31
32
    public $lastError = '';
33
34
    public $SHPData = array();
35
    public $DBFData = array();
36
37
    static $shape_names = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $shape_names.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
38
        0 => 'Null Shape',
39
        1 => 'Point',
40
        3 => 'PolyLine',
41
        5 => 'Polygon',
42
        8 => 'MultiPoint',
43
        11 => 'PointZ',
44
        13 => 'PolyLineZ',
45
        15 => 'PolygonZ',
46
        18 => 'MultiPointZ',
47
        21 => 'PointM',
48
        23 => 'PolyLineM',
49
        25 => 'PolygonM',
50
        28 => 'MultiPointM',
51
        31 => 'MultiPatch',
52
    );
53
54
    /**
55
     * @param integer $shapeType
56
     */
57
    public function __construct($shapeType) {
58
        $this->shapeType = $shapeType;
59
    }
60
61
    public function loadFromFile(&$ShapeFile, &$SHPFile, &$DBFFile) {
62
        $this->ShapeFile = $ShapeFile;
63
        $this->SHPFile = $SHPFile;
64
        $this->DBFFile = $DBFFile;
65
        $this->_loadHeaders();
66
67
        switch ($this->shapeType) {
68
            case 0:
69
                $this->_loadNullRecord();
70
                break;
71
            case 1:
72
                $this->_loadPointRecord();
73
                break;
74
            case 21:
75
                $this->_loadPointMRecord();
76
                break;
77
            case 11:
78
                $this->_loadPointZRecord();
79
                break;
80
            case 3:
81
                $this->_loadPolyLineRecord();
82
                break;
83
            case 23:
84
                $this->_loadPolyLineMRecord();
85
                break;
86
            case 13:
87
                $this->_loadPolyLineZRecord();
88
                break;
89
            case 5:
90
                $this->_loadPolygonRecord();
91
                break;
92
            case 25:
93
                $this->_loadPolygonMRecord();
94
                break;
95
            case 15:
96
                $this->_loadPolygonZRecord();
97
                break;
98
            case 8:
99
                $this->_loadMultiPointRecord();
100
                break;
101
            case 28:
102
                $this->_loadMultiPointMRecord();
103
                break;
104
            case 18:
105
                $this->_loadMultiPointZRecord();
106
                break;
107
            default:
108
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
109
                break;
110
        }
111
        if (ShapeFile::supports_dbase() && isset($this->DBFFile)) {
112
            $this->_loadDBFData();
113
        }
114
    }
115
116
    public function saveToFile(&$SHPFile, &$DBFFile, $recordNumber) {
117
        $this->SHPFile = $SHPFile;
118
        $this->DBFFile = $DBFFile;
119
        $this->recordNumber = $recordNumber;
120
        $this->_saveHeaders();
121
122
        switch ($this->shapeType) {
123
            case 0:
124
                // Nothing to save
125
                break;
126
            case 1:
127
                $this->_savePointRecord();
128
                break;
129
            case 21:
130
                $this->_savePointMRecord();
131
                break;
132
            case 11:
133
                $this->_savePointZRecord();
134
                break;
135
            case 3:
136
                $this->_savePolyLineRecord();
137
                break;
138
            case 23:
139
                $this->_savePolyLineMRecord();
140
                break;
141
            case 13:
142
                $this->_savePolyLineZRecord();
143
                break;
144
            case 5:
145
                $this->_savePolygonRecord();
146
                break;
147
            case 25:
148
                $this->_savePolygonMRecord();
149
                break;
150
            case 15:
151
                $this->_savePolygonZRecord();
152
                break;
153
            case 8:
154
                $this->_saveMultiPointRecord();
155
                break;
156
            case 28:
157
                $this->_saveMultiPointMRecord();
158
                break;
159
            case 18:
160
                $this->_saveMultiPointZRecord();
161
                break;
162
            default:
163
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
164
                break;
165
        }
166
        $this->_saveDBFData();
167
    }
168
169
    public function updateDBFInfo($header) {
170
        $tmp = $this->DBFData;
171
        unset($this->DBFData);
172
        $this->DBFData = array();
173
        foreach ($header as $value) {
174
            $this->DBFData[$value[0]] = (isset($tmp[$value[0]])) ? $tmp[$value[0]] : '';
175
        }
176
    }
177
178
    private function _loadHeaders() {
179
        $this->recordNumber = Util::loadData('N', $this->ShapeFile->readSHP(4));
180
        // We read the length of the record
181
        Util::loadData('N', $this->ShapeFile->readSHP(4));
182
        $this->shapeType = Util::loadData('V', $this->ShapeFile->readSHP(4));
183
    }
184
185
    private function _saveHeaders() {
186
        fwrite($this->SHPFile, pack('N', $this->recordNumber));
187
        fwrite($this->SHPFile, pack('N', $this->getContentLength()));
188
        fwrite($this->SHPFile, pack('V', $this->shapeType));
189
    }
190
191
    private function _loadPoint() {
192
        $data = array();
193
194
        $data['x'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
195
        $data['y'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
196
197
        return $data;
198
    }
199
200
    private function _loadPointM() {
201
        $data = array();
202
203
        $data['x'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
204
        $data['y'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
205
        $data['m'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
206
207
        return $data;
208
    }
209
210
    private function _loadPointZ() {
211
        $data = array();
212
213
        $data['x'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
214
        $data['y'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
215
        $data['z'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
216
        $data['m'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
217
218
        return $data;
219
    }
220
221
    private function _savePoint($data) {
222
        fwrite($this->SHPFile, Util::packDouble($data['x']));
223
        fwrite($this->SHPFile, Util::packDouble($data['y']));
224
    }
225
226
    private function _savePointM($data) {
227
        fwrite($this->SHPFile, Util::packDouble($data['x']));
228
        fwrite($this->SHPFile, Util::packDouble($data['y']));
229
        fwrite($this->SHPFile, Util::packDouble($data['m']));
230
    }
231
232
    private function _savePointZ($data) {
233
        fwrite($this->SHPFile, Util::packDouble($data['x']));
234
        fwrite($this->SHPFile, Util::packDouble($data['y']));
235
        fwrite($this->SHPFile, Util::packDouble($data['z']));
236
        fwrite($this->SHPFile, Util::packDouble($data['m']));
237
    }
238
239
    private function _loadNullRecord() {
240
        $this->SHPData = array();
241
    }
242
243
    private function _loadPointRecord() {
244
        $this->SHPData = $this->_loadPoint();
245
    }
246
247
    private function _loadPointMRecord() {
248
        $this->SHPData = $this->_loadPointM();
249
    }
250
251
    private function _loadPointZRecord() {
252
        $this->SHPData = $this->_loadPointZ();
253
    }
254
255
    private function _savePointRecord() {
256
        $this->_savePoint($this->SHPData);
257
    }
258
259
    private function _savePointMRecord() {
260
        $this->_savePointM($this->SHPData);
261
    }
262
263
    private function _savePointZRecord() {
264
        $this->_savePointZ($this->SHPData);
265
    }
266
267
    private function _loadMultiPointRecord() {
268
        $this->SHPData = array();
269
        $this->SHPData['xmin'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
270
        $this->SHPData['ymin'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
271
        $this->SHPData['xmax'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
272
        $this->SHPData['ymax'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
273
274
        $this->SHPData['numpoints'] = Util::loadData('V', $this->ShapeFile->readSHP(4));
275
276 View Code Duplication
        for ($i = 0; $i <= $this->SHPData['numpoints']; $i++) {
0 ignored issues
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...
277
            $this->SHPData['points'][] = $this->_loadPoint();
278
        }
279
    }
280
281
    /**
282
     * @param string $type
283
     */
284
    private function _loadMultiPointMZRecord($type) {
285
286
        $this->SHPData[$type.'min'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
287
        $this->SHPData[$type.'max'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
288
289 View Code Duplication
        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...
290
            $this->SHPData['points'][$i][$type] = Util::loadData('d', $this->ShapeFile->readSHP(8));
291
        }
292
    }
293
294
    private function _loadMultiPointMRecord() {
295
        $this->_loadMultiPointRecord();
296
297
        $this->_loadMultiPointMZRecord('m');
298
    }
299
300
    private function _loadMultiPointZRecord() {
301
        $this->_loadMultiPointRecord();
302
303
        $this->_loadMultiPointMZRecord('z');
304
        $this->_loadMultiPointMZRecord('m');
305
    }
306
307
    private function _saveMultiPointRecord() {
308
        fwrite($this->SHPFile, pack('dddd', $this->SHPData['xmin'], $this->SHPData['ymin'], $this->SHPData['xmax'], $this->SHPData['ymax']));
309
310
        fwrite($this->SHPFile, pack('V', $this->SHPData['numpoints']));
311
312 View Code Duplication
        for ($i = 0; $i <= $this->SHPData['numpoints']; $i++) {
313
            $this->_savePoint($this->SHPData['points'][$i]);
314
        }
315
    }
316
317
    /**
318
     * @param string $type
319
     */
320
    private function _saveMultiPointMZRecord($type) {
321
322
        fwrite($this->SHPFile, pack('dd', $this->SHPData[$type . 'min'], $this->SHPData[$type . 'max']));
323
324
        for ($i = 0; $i <= $this->SHPData['numpoints']; $i++) {
325
            fwrite($this->SHPFile, Util::packDouble($this->SHPData['points'][$type]));
326
        }
327
    }
328
329
    private function _saveMultiPointMRecord() {
330
        $this->_saveMultiPointRecord();
331
332
        $this->_saveMultiPointMZRecord('m');
333
    }
334
335
    private function _saveMultiPointZRecord() {
336
        $this->_saveMultiPointRecord();
337
338
        $this->_saveMultiPointMZRecord('z');
339
        $this->_saveMultiPointMZRecord('m');
340
    }
341
342
    private function _loadPolyLineRecord() {
343
        $this->SHPData = array();
344
        $this->SHPData['xmin'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
345
        $this->SHPData['ymin'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
346
        $this->SHPData['xmax'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
347
        $this->SHPData['ymax'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
348
349
        $this->SHPData['numparts']  = Util::loadData('V', $this->ShapeFile->readSHP(4));
350
        $this->SHPData['numpoints'] = Util::loadData('V', $this->ShapeFile->readSHP(4));
351
352 View Code Duplication
        for ($i = 0; $i < $this->SHPData['numparts']; $i++) {
353
            $this->SHPData['parts'][$i] = Util::loadData('V', $this->ShapeFile->readSHP(4));
354
        }
355
356
        $firstIndex = ftell($this->SHPFile);
357
        $readPoints = 0;
358
        foreach ($this->SHPData['parts'] as $partIndex => $partData) {
359
            if (!isset($this->SHPData['parts'][$partIndex]['points']) || !is_array($this->SHPData['parts'][$partIndex]['points'])) {
360
                $this->SHPData['parts'][$partIndex] = array();
361
                $this->SHPData['parts'][$partIndex]['points'] = array();
362
            }
363
            while (!in_array($readPoints, $this->SHPData['parts']) && ($readPoints < ($this->SHPData['numpoints'])) && !feof($this->SHPFile)) {
364
                $this->SHPData['parts'][$partIndex]['points'][] = $this->_loadPoint();
365
                $readPoints++;
366
            }
367
        }
368
369
        fseek($this->SHPFile, $firstIndex + ($readPoints * 16));
370
    }
371
372
    /**
373
     * @param string $type
374
     */
375
    private function _loadPolyLineMZRecord($type) {
376
377
        $this->SHPData[$type.'min'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
378
        $this->SHPData[$type.'max'] = Util::loadData('d', $this->ShapeFile->readSHP(8));
379
380
        $firstIndex = ftell($this->SHPFile);
381
        $readPoints = 0;
382
        foreach ($this->SHPData['parts'] as $partIndex => $partData) {
383
            while (!in_array($readPoints, $this->SHPData['parts']) && ($readPoints < ($this->SHPData['numpoints'])) && !feof($this->SHPFile)) {
384
                $this->SHPData['parts'][$partIndex]['points'][$readPoints][$type] = Util::loadData('d', $this->ShapeFile->readSHP(8));
385
                $readPoints++;
386
            }
387
        }
388
389
        fseek($this->SHPFile, $firstIndex + ($readPoints * 24));
390
    }
391
392
    private function _loadPolyLineMRecord() {
393
        $this->_loadPolyLineRecord();
394
395
        $this->_loadPolyLineMZRecord('m');
396
    }
397
398
    private function _loadPolyLineZRecord() {
399
        $this->_loadPolyLineRecord();
400
401
        $this->_loadPolyLineMZRecord('z');
402
        $this->_loadPolyLineMZRecord('m');
403
    }
404
405
    private function _savePolyLineRecord() {
406
        fwrite($this->SHPFile, pack('dddd', $this->SHPData['xmin'], $this->SHPData['ymin'], $this->SHPData['xmax'], $this->SHPData['ymax']));
407
408
        fwrite($this->SHPFile, pack('VV', $this->SHPData['numparts'], $this->SHPData['numpoints']));
409
410
        for ($i = 0; $i < $this->SHPData['numparts']; $i++) {
411
            fwrite($this->SHPFile, pack('V', count($this->SHPData['parts'][$i]) - 1));
412
        }
413
414
        foreach ($this->SHPData['parts'] as $partData) {
415
            foreach ($partData['points'] as $pointData) {
416
                $this->_savePoint($pointData);
417
            }
418
        }
419
    }
420
421
    /**
422
     * @param string $type
423
     */
424
    private function _savePolyLineMZRecord($type) {
425
        fwrite($this->SHPFile, pack('dd', $this->SHPData[$type.'min'], $this->SHPData[$type.'max']));
426
427
        foreach ($this->SHPData['parts'] as $partData) {
428
            foreach ($partData['points'] as $pointData) {
429
                fwrite($this->SHPFile, Util::packDouble($pointData[$type]));
430
            }
431
        }
432
    }
433
434
    private function _savePolyLineMRecord() {
435
        $this->_savePolyLineRecord();
436
437
        $this->_savePolyLineMZRecord('m');
438
    }
439
440
    private function _savePolyLineZRecord() {
441
        $this->_savePolyLineRecord();
442
443
        $this->_savePolyLineMZRecord('z');
444
        $this->_savePolyLineMZRecord('m');
445
    }
446
447
    private function _loadPolygonRecord() {
448
        $this->_loadPolyLineRecord();
449
    }
450
451
    private function _loadPolygonMRecord() {
452
        $this->_loadPolyLineMRecord();
453
    }
454
455
    private function _loadPolygonZRecord() {
456
        $this->_loadPolyLineZRecord();
457
    }
458
459
    private function _savePolygonRecord() {
460
        $this->_savePolyLineRecord();
461
    }
462
463
    private function _savePolygonMRecord() {
464
        $this->_savePolyLineMRecord();
465
    }
466
467
    private function _savePolygonZRecord() {
468
        $this->_savePolyLineZRecord();
469
    }
470
471
    private function _adjustBBox($point) {
472
        // Adjusts bounding box based on point
473
        $directions = array('x', 'y', 'z', 'm');
474
        foreach ($directions as $direction) {
475
            if (!isset($point[$direction])) {
476
                continue;
477
            }
478
            $min = $direction . 'min';
479
            $max = $direction . 'max';
480
            if (!isset($this->SHPData[$min]) || ($this->SHPData[$min] > $point[$direction])) {
481
                $this->SHPData[$min] = $point[$direction];
482
            }
483
            if (!isset($this->SHPData[$max]) || ($this->SHPData[$max] < $point[$direction])) {
484
                $this->SHPData[$max] = $point[$direction];
485
            }
486
        }
487
    }
488
489
    public function addPoint($point, $partIndex = 0) {
490
        switch ($this->shapeType) {
491
            case 0:
492
                //Don't add anything
493
                break;
494
            case 1:
495
            case 11:
496
            case 21:
497 View Code Duplication
                if (in_array($this->shapeType, array(11, 21)) && !isset($point['m'])) {
498
                    $point['m'] = 0.0; // no_value
499
                }
500 View Code Duplication
                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...
501
                    $point['z'] = 0.0; // no_value
502
                }
503
504
                //Substitutes the value of the current point
505
                $this->SHPData = $point;
506
                $this->_adjustBBox($point);
507
                break;
508
            case 3:
509
            case 5:
510
            case 13:
511
            case 15:
512
            case 23:
513
            case 25:
514 View Code Duplication
                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...
515
                    $point['m'] = 0.0; // no_value
516
                }
517 View Code Duplication
                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...
518
                    $point['z'] = 0.0; // no_value
519
                }
520
521
                $this->_adjustBBox($point);
522
523
                //Adds a new point to the selected part
524
                $this->SHPData['parts'][$partIndex]['points'][] = $point;
525
526
                $this->SHPData['numparts'] = count($this->SHPData['parts']);
527
                $this->SHPData['numpoints'] = 1 + (isset($this->SHPData['numpoints']) ? $this->SHPData['numpoints'] : 0);
528
                break;
529
            case 8:
530
            case 18:
531
            case 28:
532 View Code Duplication
                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...
533
                    $point['m'] = 0.0; // no_value
534
                }
535 View Code Duplication
                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...
536
                    $point['z'] = 0.0; // no_value
537
                }
538
539
                $this->_adjustBBox($point);
540
541
                //Adds a new point
542
                $this->SHPData['points'][] = $point;
543
                $this->SHPData['numpoints'] = 1 + (isset($this->SHPData['numpoints']) ? $this->SHPData['numpoints'] : 0);
544
                break;
545
            default:
546
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
547
                break;
548
        }
549
    }
550
551
    public function deletePoint($pointIndex = 0, $partIndex = 0) {
552
        switch ($this->shapeType) {
553
            case 0:
554
                //Don't delete anything
555
                break;
556
            case 1:
557
            case 11:
558
            case 21:
559
                //Sets the value of the point to zero
560
                $this->SHPData['x'] = 0.0;
561
                $this->SHPData['y'] = 0.0;
562
                if (in_array($this->shapeType, array(11, 21))) {
563
                    $this->SHPData['m'] = 0.0;
564
                }
565
                if (in_array($this->shapeType, array(11))) {
566
                    $this->SHPData['z'] = 0.0;
567
                }
568
                break;
569
            case 3:
570
            case 5:
571
            case 13:
572
            case 15:
573
            case 23:
574
            case 25:
575
                //Deletes the point from the selected part, if exists
576
                if (isset($this->SHPData['parts'][$partIndex]) && isset($this->SHPData['parts'][$partIndex]['points'][$pointIndex])) {
577
                    $count = count($this->SHPData['parts'][$partIndex]['points']) - 1;
578
                    for ($i = $pointIndex; $i < $count; $i++) {
579
                        $this->SHPData['parts'][$partIndex]['points'][$i] = $this->SHPData['parts'][$partIndex]['points'][$i + 1];
580
                    }
581
                    unset($this->SHPData['parts'][$partIndex]['points'][count($this->SHPData['parts'][$partIndex]['points']) - 1]);
582
583
                    $this->SHPData['numparts'] = count($this->SHPData['parts']);
584
                    $this->SHPData['numpoints']--;
585
                }
586
                break;
587
            case 8:
588
            case 18:
589
            case 28:
590
                //Deletes the point, if exists
591
                if (isset($this->SHPData['points'][$pointIndex])) {
592
                    $count = count($this->SHPData['points']) - 1;
593
                    for ($i = $pointIndex; $i < $count; $i++) {
594
                        $this->SHPData['points'][$i] = $this->SHPData['points'][$i + 1];
595
                    }
596
                    unset($this->SHPData['points'][count($this->SHPData['points']) - 1]);
597
598
                    $this->SHPData['numpoints']--;
599
                }
600
                break;
601
            default:
602
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
603
                break;
604
        }
605
    }
606
607
    public function getContentLength() {
608
        // The content length for a record is the length of the record contents section measured in 16-bit words.
609
        // one coordinate makes 4 16-bit words (64 bit double)
610
        switch ($this->shapeType) {
611
            case 0:
612
                $result = 0;
613
                break;
614
            case 1:
615
                $result = 10;
616
                break;
617
            case 21:
618
                $result = 10 + 4;
619
                break;
620
            case 11:
621
                $result = 10 + 8;
622
                break;
623
            case 3:
624
            case 5:
625
                $count = count($this->SHPData['parts']);
626
                $result = 22 + 2 * $count;
627
                for ($i = 0; $i < $count; $i++) {
628
                    $result += 8 * count($this->SHPData['parts'][$i]['points']);
629
                }
630
                break;
631
            case 23:
632 View Code Duplication
            case 25:
633
                $count = count($this->SHPData['parts']);
634
                $result = 22 + (2 * 4) + 2 * $count;
635
                for ($i = 0; $i < $count; $i++) {
636
                    $result += (8 + 4) * count($this->SHPData['parts'][$i]['points']);
637
                }
638
                break;
639
            case 13:
640 View Code Duplication
            case 15:
641
                $count = count($this->SHPData['parts']);
642
                $result = 22 + (4 * 4) + 2 * $count;
643
                for ($i = 0; $i < $count; $i++) {
644
                    $result += (8 + 8) * count($this->SHPData['parts'][$i]['points']);
645
                }
646
                break;
647
            case 8:
648
                $result = 20 + 8 * count($this->SHPData['points']);
649
                break;
650 View Code Duplication
            case 28:
651
                $result = 20 + (2 * 4) + (8 + 4) * count($this->SHPData['points']);
652
                break;
653 View Code Duplication
            case 18:
654
                $result = 20 + (4 * 4) + (8 + 8) * count($this->SHPData['points']);
655
                break;
656
            default:
657
                $result = false;
658
                $this->setError(sprintf('The Shape Type "%s" is not supported.', $this->shapeType));
659
                break;
660
        }
661
        return $result;
662
    }
663
664
    private function _loadDBFData() {
665
        $this->DBFData = @dbase_get_record_with_names($this->DBFFile, $this->recordNumber);
666
        unset($this->DBFData['deleted']);
667
    }
668
669
    private function _saveDBFData() {
670
        unset($this->DBFData['deleted']);
671
        if ($this->recordNumber <= dbase_numrecords($this->DBFFile)) {
672
            if (!dbase_replace_record($this->DBFFile, array_values($this->DBFData), $this->recordNumber)) {
673
                $this->setError('I wasn\'t possible to update the information in the DBF file.');
674
            }
675
        } else {
676
            if (!dbase_add_record($this->DBFFile, array_values($this->DBFData))) {
677
                $this->setError('I wasn\'t possible to add the information to the DBF file.');
678
            }
679
        }
680
    }
681
682
    /**
683
     * @param string $error
684
     */
685
    public function setError($error) {
686
        $this->lastError = $error;
687
        return false;
688
    }
689
690
    /**
691
     * Returns shape name
692
     *
693
     * @return string
694
     */
695
    public function getShapeName()
696
    {
697
        if (isset(ShapeRecord::$shape_names[$this->shapeType])) {
698
            return ShapeRecord::$shape_names[$this->shapeType];
699
        }
700
        return sprintf('Shape %d', $this->shapeType);
701
    }
702
}
703