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