shp 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +34 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +28 -0
  6. data/README.md +30 -0
  7. data/Rakefile +23 -0
  8. data/ext/shp/base.hpp +113 -0
  9. data/ext/shp/dbf.cpp +381 -0
  10. data/ext/shp/dbf.hpp +44 -0
  11. data/ext/shp/extconf.rb +13 -0
  12. data/ext/shp/shape_object.cpp +58 -0
  13. data/ext/shp/shape_object.hpp +27 -0
  14. data/ext/shp/shapefile.cpp +299 -0
  15. data/ext/shp/shapefile.hpp +35 -0
  16. data/ext/shp/shapelib/.cvsignore +15 -0
  17. data/ext/shp/shapelib/ChangeLog +450 -0
  18. data/ext/shp/shapelib/HOWTO-RELEASE +16 -0
  19. data/ext/shp/shapelib/LICENSE.LGPL +483 -0
  20. data/ext/shp/shapelib/Makefile +113 -0
  21. data/ext/shp/shapelib/README +41 -0
  22. data/ext/shp/shapelib/README.tree +172 -0
  23. data/ext/shp/shapelib/contrib/.cvsignore +12 -0
  24. data/ext/shp/shapelib/contrib/Makefile +66 -0
  25. data/ext/shp/shapelib/contrib/ShapeFileII.pas +234 -0
  26. data/ext/shp/shapelib/contrib/Shape_PointInPoly.cpp +238 -0
  27. data/ext/shp/shapelib/contrib/Shape_PointInPoly_README.txt +59 -0
  28. data/ext/shp/shapelib/contrib/csv2shp.c +558 -0
  29. data/ext/shp/shapelib/contrib/dbfcat.c +166 -0
  30. data/ext/shp/shapelib/contrib/dbfinfo.c +106 -0
  31. data/ext/shp/shapelib/contrib/makefile.vc +34 -0
  32. data/ext/shp/shapelib/contrib/my_nan.h +46 -0
  33. data/ext/shp/shapelib/contrib/shpcat.c +100 -0
  34. data/ext/shp/shapelib/contrib/shpcentrd.c +159 -0
  35. data/ext/shp/shapelib/contrib/shpdata.c +129 -0
  36. data/ext/shp/shapelib/contrib/shpdxf.c +340 -0
  37. data/ext/shp/shapelib/contrib/shpfix.c +110 -0
  38. data/ext/shp/shapelib/contrib/shpgeo.c +1595 -0
  39. data/ext/shp/shapelib/contrib/shpgeo.h +154 -0
  40. data/ext/shp/shapelib/contrib/shpinfo.c +113 -0
  41. data/ext/shp/shapelib/contrib/shpproj.c +260 -0
  42. data/ext/shp/shapelib/contrib/shpsort.c +605 -0
  43. data/ext/shp/shapelib/contrib/shpsort.txt +44 -0
  44. data/ext/shp/shapelib/contrib/shpwkb.c +123 -0
  45. data/ext/shp/shapelib/contrib/tests/shpproj.sh +38 -0
  46. data/ext/shp/shapelib/dbfopen.c +2221 -0
  47. data/ext/shp/shapelib/makefile.vc +86 -0
  48. data/ext/shp/shapelib/makeshape.sh +21 -0
  49. data/ext/shp/shapelib/mkdist.sh +37 -0
  50. data/ext/shp/shapelib/mkinstalldirs +38 -0
  51. data/ext/shp/shapelib/mkrelease.sh +55 -0
  52. data/ext/shp/shapelib/safileio.c +286 -0
  53. data/ext/shp/shapelib/shapefil.h +647 -0
  54. data/ext/shp/shapelib/shapelib.def +46 -0
  55. data/ext/shp/shapelib/shpopen.c +2388 -0
  56. data/ext/shp/shapelib/shptree.c +1187 -0
  57. data/ext/shp/shapelib/shputils.c +1072 -0
  58. data/ext/shp/shapelib/stream1.out +1465 -0
  59. data/ext/shp/shapelib/stream1.sh +28 -0
  60. data/ext/shp/shapelib/stream2.out +530 -0
  61. data/ext/shp/shapelib/stream2.sh +11 -0
  62. data/ext/shp/shapelib/stream3.out +37 -0
  63. data/ext/shp/shapelib/web/.cvsignore +2 -0
  64. data/ext/shp/shapelib/web/codepage.html +403 -0
  65. data/ext/shp/shapelib/web/dbf_api.html +436 -0
  66. data/ext/shp/shapelib/web/index.html +235 -0
  67. data/ext/shp/shapelib/web/license.html +78 -0
  68. data/ext/shp/shapelib/web/manifest.html +87 -0
  69. data/ext/shp/shapelib/web/release.html +80 -0
  70. data/ext/shp/shapelib/web/shapelib-tools.html +352 -0
  71. data/ext/shp/shapelib/web/shp_api.html +376 -0
  72. data/ext/shp/shp.cpp +19 -0
  73. data/ext/shp/shp.hpp +47 -0
  74. data/lib/shp.rb +35 -0
  75. data/lib/shp/version.rb +3 -0
  76. data/shp.gemspec +23 -0
  77. data/spec/shp_spec.rb +127 -0
  78. metadata +176 -0
@@ -0,0 +1,110 @@
1
+ /******************************************************************************
2
+ * Copyright (c) 1999, Carl Anderson
3
+ *
4
+ * This code is based in part on the earlier work of Frank Warmerdam
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included
14
+ * in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
+ * DEALINGS IN THE SOFTWARE.
23
+ ******************************************************************************
24
+ * shpfix
25
+ *
26
+ *
27
+ * gcc -c shpfix.c shpopen.c -o shpfix
28
+ *
29
+ * Utility program to fix nulls and inconsistencies in Shapefiles
30
+ * as happens from time to time
31
+ *
32
+ * Simply load and rewrite each record, parameter fixrex allow user to null
33
+ * a particularly nasty record if needed
34
+ *
35
+ */
36
+
37
+ #include <stdlib.h>
38
+ #include <string.h>
39
+ #include "shapefil.h"
40
+
41
+ int main( int argc, char ** argv )
42
+
43
+ {
44
+ SHPHandle hSHP, cSHP;
45
+ int nShapeType, cShapeType, nEntities, i;
46
+ double adBounds[4];
47
+ SHPObject *shape;
48
+ int fix_rec;
49
+
50
+ /* -------------------------------------------------------------------- */
51
+ /* Display a usage message. */
52
+ /* -------------------------------------------------------------------- */
53
+ if( argc <= 3 )
54
+ {
55
+ printf( "shpfix shpfile new_file <Record# to Blank>\n" );
56
+ exit( 1 );
57
+ }
58
+
59
+ fix_rec = atoi (argv[3]);
60
+ fix_rec --;
61
+
62
+ /* -------------------------------------------------------------------- */
63
+ /* Open the passed shapefile. */
64
+ /* -------------------------------------------------------------------- */
65
+ hSHP = SHPOpen( argv[1], "rb+" );
66
+
67
+ if( hSHP == NULL )
68
+ {
69
+ printf( "Unable to open:%s\n", argv[1] );
70
+ exit( 1 );
71
+ }
72
+
73
+ SHPGetInfo( hSHP, &nEntities, &nShapeType, NULL, NULL );
74
+
75
+
76
+ /* -------------------------------------------------------------------- */
77
+ /* Open the passed shapefile. */
78
+ /* -------------------------------------------------------------------- */
79
+ cSHP = SHPCreate( argv[2], nShapeType );
80
+
81
+ if( cSHP == NULL )
82
+ {
83
+ printf( "Unable to open:%s\n", argv[2] );
84
+ exit( 1 );
85
+ }
86
+
87
+ SHPGetInfo( cSHP, NULL, &cShapeType, &(adBounds[0]), &(adBounds[2]) );
88
+
89
+
90
+ /* -------------------------------------------------------------------- */
91
+ /* Skim over the list of shapes, printing all the vertices. */
92
+ /* -------------------------------------------------------------------- */
93
+
94
+ for( i = 0; i < nEntities; i++ )
95
+ {
96
+
97
+ shape = SHPReadObject( hSHP, i );
98
+ if ( i == fix_rec )
99
+ { shape->nParts = 0;
100
+ shape->nVertices = 0;
101
+ }
102
+ SHPWriteObject( cSHP, -1, shape );
103
+ SHPDestroyObject ( shape );
104
+
105
+ }
106
+
107
+
108
+ SHPClose ( hSHP );
109
+ SHPClose ( cSHP );
110
+ }
@@ -0,0 +1,1595 @@
1
+ /******************************************************************************
2
+ * Copyright (c) 1999, Carl Anderson
3
+ *
4
+ * This code is based in part on the earlier work of Frank Warmerdam
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a
7
+ * copy of this software and associated documentation files (the "Software"),
8
+ * to deal in the Software without restriction, including without limitation
9
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
+ * and/or sell copies of the Software, and to permit persons to whom the
11
+ * Software is furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included
14
+ * in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
+ * DEALINGS IN THE SOFTWARE.
23
+ ******************************************************************************
24
+ *
25
+ * requires shapelib 1.2
26
+ * gcc shpproj shpopen.o dbfopen.o -lm -lproj -o shpproj
27
+ *
28
+ * this may require linking with the PROJ4 projection library available from
29
+ *
30
+ * http://www.remotesensing.org/proj
31
+ *
32
+ * use -DPROJ4 to compile in Projection support
33
+ *
34
+ * $Log: shpgeo.c,v $
35
+ * Revision 1.13 2011-07-24 03:17:46 fwarmerdam
36
+ * include string.h and stdlib.h where needed in contrib (#2146)
37
+ *
38
+ * Revision 1.12 2007-09-03 23:17:46 fwarmerdam
39
+ * fix SHPDimension() function
40
+ *
41
+ * Revision 1.11 2006/11/06 20:45:58 fwarmerdam
42
+ * Fixed SHPProject.
43
+ *
44
+ * Revision 1.10 2006/11/06 20:44:58 fwarmerdam
45
+ * SHPProject() uses pj_transform now
46
+ *
47
+ * Revision 1.9 2006/01/25 15:33:50 fwarmerdam
48
+ * fixed ppsC assignment maptools bug 1263
49
+ *
50
+ * Revision 1.8 2002/01/15 14:36:56 warmerda
51
+ * upgrade to use proj_api.h
52
+ *
53
+ * Revision 1.7 2002/01/11 15:22:04 warmerda
54
+ * fix many warnings. Lots of this code is cruft.
55
+ *
56
+ * Revision 1.6 2001/08/30 13:42:31 warmerda
57
+ * avoid use of auto initialization of PT for VC++
58
+ *
59
+ * Revision 1.5 2000/04/26 13:24:06 warmerda
60
+ * made projUV handling safer
61
+ *
62
+ * Revision 1.4 2000/04/26 13:17:15 warmerda
63
+ * check if projUV or UV
64
+ *
65
+ * Revision 1.3 2000/03/17 14:15:16 warmerda
66
+ * Don't try to use system nan.h ... doesn't always exist.
67
+ *
68
+ * Revision 1.2 1999/05/26 02:56:31 candrsn
69
+ * updates to shpdxf, dbfinfo, port from Shapelib 1.1.5 of dbfcat and shpinfo
70
+ *
71
+ */
72
+
73
+ #include <stdlib.h>
74
+ #include <string.h>
75
+ #include "shapefil.h"
76
+
77
+ #ifndef NAN
78
+ #include "my_nan.h"
79
+ #endif
80
+
81
+ #include "shpgeo.h"
82
+
83
+
84
+ /* I'm using some shorthand throughout this file
85
+ * R+ is a Clockwise Ring and is the positive portion of an object
86
+ * R- is a CounterClockwise Ring and is a hole in a R+
87
+ * A complex object is one having at least one R-
88
+ * A compound object is one having more than one R+
89
+ * A simple object has one and only one element (R+ or R-)
90
+ *
91
+ * The closed ring constraint is for polygons and assumed here
92
+ * Arcs or LineStrings I am calling Rings (generically open or closed)
93
+ * Point types are vertices or lists of vertices but not Rings
94
+ *
95
+ * SHPT_POLYGON, SHPT_POLYGONZ, SHPT_POLYGONM and SHPT_MULTIPATCH
96
+ * can have SHPObjects that are compound as well as complex
97
+ *
98
+ * SHP_POINT and its Z and M derivatives are strictly simple
99
+ * MULTI_POINT, SHPT_ARC and their derivatives may be simple or compound
100
+ *
101
+ */
102
+
103
+
104
+ /* **************************************************************************
105
+ * asFileName
106
+ *
107
+ * utility function, toss part of filename after last dot
108
+ *
109
+ * **************************************************************************/
110
+ char * asFileName ( const char *fil, char *ext ) {
111
+ char pszBasename[120];
112
+ static char pszFullname[120];
113
+ int i;
114
+ /* -------------------------------------------------------------------- */
115
+ /* Compute the base (layer) name. If there is any extension */
116
+ /* on the passed in filename we will strip it off. */
117
+ /* -------------------------------------------------------------------- */
118
+ // pszFullname = (char*) malloc(( strlen(fil)+5 ));
119
+ // pszBasename = (char *) malloc(strlen(fil)+5);
120
+ strcpy( pszBasename, fil );
121
+ for( i = strlen(pszBasename)-1;
122
+ i > 0 && pszBasename[i] != '.' && pszBasename[i] != '/'
123
+ && pszBasename[i] != '\\';
124
+ i-- ) {}
125
+
126
+ if( pszBasename[i] == '.' )
127
+ pszBasename[i] = '\0';
128
+
129
+ /* -------------------------------------------------------------------- */
130
+ /* Note that files pulled from */
131
+ /* a PC to Unix with upper case filenames won't work! */
132
+ /* -------------------------------------------------------------------- */
133
+ // pszFullname = (char *) malloc(strlen(pszBasename) + 5);
134
+ sprintf( pszFullname, "%s.%s", pszBasename, ext );
135
+
136
+ return ( pszFullname );
137
+ }
138
+
139
+
140
+ /************************************************************************/
141
+ /* SfRealloc() */
142
+ /* */
143
+ /* A realloc cover function that will access a NULL pointer as */
144
+ /* a valid input. */
145
+ /************************************************************************/
146
+ /* copied directly from shpopen.c -- maybe expose this in shapefil.h */
147
+ static void * SfRealloc( void * pMem, int nNewSize )
148
+
149
+ {
150
+ if( pMem == NULL )
151
+ return( (void *) malloc(nNewSize) );
152
+ else
153
+ return( (void *) realloc(pMem,nNewSize) );
154
+ }
155
+
156
+
157
+ /* **************************************************************************
158
+ * SHPPRoject
159
+ *
160
+ * Project points using projection handles, for use with PROJ4.3
161
+ *
162
+ * act as a wrapper to protect against library changes in PROJ
163
+ *
164
+ * **************************************************************************/
165
+ int SHPProject ( SHPObject *psCShape, projPJ inproj, projPJ outproj ) {
166
+ #ifdef PROJ4
167
+
168
+ int j;
169
+
170
+ if ( pj_is_latlong(inproj) ) {
171
+ for(j=0; j < psCShape->nVertices; j++) {
172
+ psCShape->padfX[j] *= DEG_TO_RAD;
173
+ psCShape->padfY[j] *= DEG_TO_RAD;
174
+ }
175
+ }
176
+
177
+ pj_transform(inproj, outproj, psCShape->nVertices, 0, psCShape->padfX,
178
+ psCShape->padfY, NULL);
179
+
180
+ if ( pj_is_latlong(outproj) ) {
181
+ for(j=0; j < psCShape->nVertices; j++) {
182
+ psCShape->padfX[j] *= RAD_TO_DEG;
183
+ psCShape->padfY[j] *= RAD_TO_DEG;
184
+ }
185
+ }
186
+
187
+ /* Recompute new Extents of projected Object */
188
+ SHPComputeExtents ( psCShape );
189
+ #endif
190
+
191
+ return ( 1 );
192
+ }
193
+
194
+
195
+ /* **************************************************************************
196
+ * SHPSetProjection
197
+ *
198
+ * establish a projection handle for use with PROJ4.3
199
+ *
200
+ * act as a wrapper to protect against library changes in PROJ
201
+ *
202
+ * **************************************************************************/
203
+ projPJ SHPSetProjection ( int param_cnt, char **params ) {
204
+ #ifdef PROJ4
205
+ projPJ *p = NULL;
206
+
207
+ if ( param_cnt > 0 && params[0] )
208
+ { p = pj_init ( param_cnt, params ); }
209
+
210
+ return ( p );
211
+ #else
212
+ return ( NULL );
213
+ #endif
214
+ }
215
+
216
+
217
+ /* **************************************************************************
218
+ * SHPFreeProjection
219
+ *
220
+ * release a projection handle for use with PROJ4.3
221
+ *
222
+ * act as a wrapper to protect against library changes in PROJ
223
+ *
224
+ * **************************************************************************/
225
+ int SHPFreeProjection ( projPJ p) {
226
+ #ifdef PROJ4
227
+ if ( p )
228
+ pj_free ( p );
229
+ #endif
230
+ return ( 1 );
231
+ }
232
+
233
+
234
+ /* **************************************************************************
235
+ * SHPOGisType
236
+ *
237
+ * Convert Both ways from and to OGIS Geometry Types
238
+ *
239
+ * **************************************************************************/
240
+ int SHPOGisType ( int GeomType, int toOGis) {
241
+
242
+ if ( toOGis == 0 ) /* connect OGis -> SHP types */
243
+ switch (GeomType) {
244
+ case (OGIST_POINT): return ( SHPT_POINT ); break;
245
+ case (OGIST_LINESTRING): return ( SHPT_ARC ); break;
246
+ case (OGIST_POLYGON): return ( SHPT_POLYGON ); break;
247
+ case (OGIST_MULTIPOINT): return ( SHPT_MULTIPOINT ); break;
248
+ case (OGIST_MULTILINE): return ( SHPT_ARC ); break;
249
+ case (OGIST_MULTIPOLYGON): return ( SHPT_POLYGON ); break;
250
+ }
251
+ else /* ok so its SHP->OGis types */
252
+ switch (GeomType) {
253
+ case (SHPT_POINT): return ( OGIST_POINT ); break;
254
+ case (SHPT_POINTM): return ( OGIST_POINT ); break;
255
+ case (SHPT_POINTZ): return ( OGIST_POINT ); break;
256
+ case (SHPT_ARC): return ( OGIST_LINESTRING );break;
257
+ case (SHPT_ARCZ): return ( OGIST_LINESTRING );break;
258
+ case (SHPT_ARCM): return ( OGIST_LINESTRING );break;
259
+ case (SHPT_POLYGON): return ( OGIST_MULTIPOLYGON );break;
260
+ case (SHPT_POLYGONZ): return ( OGIST_MULTIPOLYGON );break;
261
+ case (SHPT_POLYGONM): return ( OGIST_MULTIPOLYGON );break;
262
+ case (SHPT_MULTIPOINT): return ( OGIST_MULTIPOINT );break;
263
+ case (SHPT_MULTIPOINTZ): return ( OGIST_MULTIPOINT );break;
264
+ case (SHPT_MULTIPOINTM): return ( OGIST_MULTIPOINT );break;
265
+ case (SHPT_MULTIPATCH): return ( OGIST_GEOMCOLL ); break;
266
+ }
267
+
268
+ return 0;
269
+ }
270
+
271
+
272
+ /* **************************************************************************
273
+ * SHPReadSHPStream
274
+ *
275
+ * Encapsulate entire SHPObject for use with Postgresql
276
+ *
277
+ * **************************************************************************/
278
+ int SHPReadSHPStream ( SHPObject *psCShape, char *stream_obj) {
279
+
280
+ int obj_storage;
281
+ int my_order, need_swap =0, GeoType ;
282
+ int use_Z = 0;
283
+ int use_M = 0;
284
+
285
+ need_swap = stream_obj[0];
286
+ my_order = 1;
287
+ my_order = ((char*) (&my_order))[0];
288
+ need_swap = need_swap & my_order;
289
+
290
+ if ( need_swap )
291
+ swapW (stream_obj, (void*) &GeoType, sizeof (GeoType) );
292
+ else
293
+ memcpy (stream_obj, &GeoType, sizeof (GeoType) );
294
+
295
+
296
+ if ( need_swap ) {
297
+
298
+ } else {
299
+ memcpy (stream_obj, &(psCShape->nSHPType), sizeof (psCShape->nSHPType) );
300
+ memcpy (stream_obj, &(psCShape->nShapeId), sizeof (psCShape->nShapeId) );
301
+ memcpy (stream_obj, &(psCShape->nVertices), sizeof (psCShape->nVertices) );
302
+ memcpy (stream_obj, &(psCShape->nParts), sizeof (psCShape->nParts) );
303
+ memcpy (stream_obj, &(psCShape->dfXMin), sizeof (psCShape->dfXMin) );
304
+ memcpy (stream_obj, &(psCShape->dfYMin), sizeof (psCShape->dfYMin) );
305
+ memcpy (stream_obj, &(psCShape->dfXMax), sizeof (psCShape->dfXMax) );
306
+ memcpy (stream_obj, &(psCShape->dfYMax), sizeof (psCShape->dfYMax) );
307
+ if ( use_Z ) {
308
+ memcpy (stream_obj, &(psCShape->dfZMin), sizeof (psCShape->dfZMin) );
309
+ memcpy (stream_obj, &(psCShape->dfZMax), sizeof (psCShape->dfZMax) );
310
+ }
311
+
312
+ memcpy (stream_obj, psCShape->panPartStart, psCShape->nParts * sizeof (int) );
313
+ memcpy (stream_obj, psCShape->panPartType, psCShape->nParts * sizeof (int) );
314
+
315
+ /* get X and Y coordinate arrarys */
316
+ memcpy (stream_obj, psCShape->padfX, psCShape->nVertices * 2 * sizeof (double) );
317
+
318
+ /* get Z coordinate array if used */
319
+ if ( use_Z )
320
+ memcpy (stream_obj, psCShape->padfZ, psCShape->nVertices * 2 * sizeof (double) );
321
+ /* get Measure coordinate array if used */
322
+ if ( use_M )
323
+ memcpy (stream_obj, psCShape->padfM, psCShape->nVertices * 2 * sizeof (double) );
324
+ } /* end put data without swap */
325
+
326
+ return (0);
327
+ }
328
+
329
+
330
+ /* **************************************************************************
331
+ * SHPWriteSHPStream
332
+ *
333
+ * Encapsulate entire SHPObject for use with Postgresql
334
+ *
335
+ * **************************************************************************/
336
+ int SHPWriteSHPStream ( WKBStreamObj *stream_obj, SHPObject *psCShape ) {
337
+
338
+ int obj_storage = 0;
339
+ int need_swap = 0, my_order, GeoType;
340
+ int use_Z = 0;
341
+ int use_M = 0;
342
+
343
+ need_swap = 1;
344
+ need_swap = ((char*) (&need_swap))[0];
345
+
346
+ realloc (stream_obj, obj_storage );
347
+
348
+ if ( need_swap ) {
349
+
350
+ } else {
351
+ memcpy (stream_obj, psCShape, 4 * sizeof (int) );
352
+ memcpy (stream_obj, psCShape, 4 * sizeof (double) );
353
+ if ( use_Z )
354
+ memcpy (stream_obj, psCShape, 2 * sizeof (double) );
355
+ if ( use_M )
356
+ memcpy (stream_obj, psCShape, 2 * sizeof (double) );
357
+
358
+ memcpy (stream_obj, psCShape, psCShape->nParts * 2 * sizeof (int) );
359
+ memcpy (stream_obj, psCShape, psCShape->nVertices * 2 * sizeof (double) );
360
+ if ( use_Z )
361
+ memcpy (stream_obj, psCShape, psCShape->nVertices * 2 * sizeof (double) );
362
+ if ( use_M )
363
+ memcpy (stream_obj, psCShape, psCShape->nVertices * 2 * sizeof (double) );
364
+ }
365
+
366
+ return (0);
367
+ }
368
+
369
+
370
+ /* **************************************************************************
371
+ * WKBStreamWrite
372
+ *
373
+ * Encapsulate entire SHPObject for use with Postgresql
374
+ *
375
+ * **************************************************************************/
376
+ int WKBStreamWrite ( WKBStreamObj* wso, void* this, int tcount, int tsize ) {
377
+
378
+ if ( wso->NeedSwap )
379
+ SwapG ( &(wso->wStream[wso->StreamPos]), this, tcount, tsize );
380
+ else
381
+ memcpy ( &(wso->wStream[wso->StreamPos]), this, tsize * tcount );
382
+
383
+ wso->StreamPos += tsize;
384
+
385
+ return 0;
386
+ }
387
+
388
+
389
+
390
+ /* **************************************************************************
391
+ * WKBStreamRead
392
+ *
393
+ * Encapsulate entire SHPObject for use with Postgresql
394
+ *
395
+ * **************************************************************************/
396
+ int WKBStreamRead ( WKBStreamObj* wso, void* this, int tcount, int tsize ) {
397
+
398
+ if ( wso->NeedSwap )
399
+ SwapG ( this, &(wso->wStream[wso->StreamPos]), tcount, tsize );
400
+ else
401
+ memcpy ( this, &(wso->wStream[wso->StreamPos]), tsize * tcount );
402
+
403
+ wso->StreamPos += tsize;
404
+
405
+ return 0;
406
+ }
407
+
408
+
409
+
410
+ /* **************************************************************************
411
+ * SHPReadOGisWKB
412
+ *
413
+ * Encapsulate entire SHPObject for use with Postgresql
414
+ *
415
+ * **************************************************************************/
416
+ SHPObject* SHPReadOGisWKB ( WKBStreamObj *stream_obj) {
417
+ SHPObject *psCShape;
418
+ char WKB_order;
419
+ int need_swap = 0, my_order, GeoType = 0;
420
+ int use_Z = 0, use_M = 0;
421
+ int nSHPType, thisDim;
422
+
423
+ WKBStreamRead ( stream_obj, &WKB_order, 1, sizeof(char));
424
+ my_order = 1;
425
+ my_order = ((char*) (&my_order))[0];
426
+ stream_obj->NeedSwap = !(WKB_order & my_order);
427
+
428
+ /* convert OGis Types to SHP types */
429
+ nSHPType = SHPOGisType ( GeoType, 0 );
430
+
431
+ WKBStreamRead ( stream_obj, &GeoType, 1, sizeof(int));
432
+
433
+ thisDim = SHPDimension ( nSHPType );
434
+
435
+ if ( thisDim && SHPD_AREA )
436
+ { psCShape = SHPReadOGisPolygon ( stream_obj ); }
437
+ else {
438
+ if ( thisDim && SHPD_LINE )
439
+ { psCShape = SHPReadOGisLine ( stream_obj ); }
440
+ else {
441
+ if ( thisDim && SHPD_POINT )
442
+ { psCShape = SHPReadOGisPoint ( stream_obj ); }
443
+ }
444
+ }
445
+
446
+
447
+ return (0);
448
+ }
449
+
450
+
451
+
452
+ /* **************************************************************************
453
+ * SHPWriteOGisWKB
454
+ *
455
+ * Encapsulate entire SHPObject for use with Postgresql
456
+ *
457
+ * **************************************************************************/
458
+ int SHPWriteOGisWKB ( WKBStreamObj* stream_obj, SHPObject *psCShape ) {
459
+
460
+ int need_swap = 0, my_order, GeoType, thisDim;
461
+ int use_Z = 0, use_M = 0;
462
+ char LSB = 1;
463
+ /* indicate that this WKB is in LSB Order */
464
+
465
+ /* OGis WKB can handle either byte order, but if I get to choose I'd
466
+ /* rather have it predicatable system-to-system */
467
+
468
+ if ( stream_obj ) {
469
+ if ( stream_obj->wStream )
470
+ free ( stream_obj->wStream );
471
+ } else
472
+ { stream_obj = calloc ( 3, sizeof (int ) ); }
473
+
474
+ /* object size needs to be 9 bytes for the wrapper, and for each polygon */
475
+ /* another 9 bytes all plus twice the total number of vertices */
476
+ /* times the sizeof (double) and just pad with 10 more chars for fun */
477
+ stream_obj->wStream = calloc (1, (9 * (psCShape->nParts + 1)) +
478
+ ( sizeof(double) * 2 * psCShape->nVertices ) + 10 );
479
+
480
+ #ifdef DEBUG2
481
+ printf (" I just allocated %d bytes to wkbObj \n",
482
+ sizeof (int) + sizeof (int) + sizeof(int) +
483
+ ( sizeof(int) * psCShape->nParts + 1 ) +
484
+ ( sizeof(double) * 2 * psCShape->nVertices ) + 10 );
485
+ #endif
486
+
487
+ my_order = 1;
488
+ my_order = ((char*) (&my_order))[0];
489
+ /* Need to swap if this system is not LSB (Intel Order) */
490
+ stream_obj->NeedSwap = ( my_order != LSB );
491
+
492
+ stream_obj->StreamPos = 0;
493
+
494
+
495
+ #ifdef DEBUG2
496
+ printf ("this system is (%d) LSB recorded as needSwap %d\n",my_order, stream_obj->NeedSwap);
497
+ #endif
498
+
499
+ WKBStreamWrite ( stream_obj, & LSB, 1, sizeof(char) );
500
+
501
+ #ifdef DEBUG2
502
+ printf ("this system in (%d) LSB \n");
503
+ #endif
504
+
505
+
506
+ /* convert SHP Types to OGis types */
507
+ GeoType = SHPOGisType ( psCShape->nSHPType, 1 );
508
+ WKBStreamWrite ( stream_obj, &GeoType, 1, sizeof(int) );
509
+
510
+ thisDim = SHPDimension ( psCShape->nSHPType );
511
+
512
+ if ( thisDim && SHPD_AREA )
513
+ { SHPWriteOGisPolygon ( stream_obj, psCShape ); }
514
+ else {
515
+ if ( thisDim && SHPD_LINE )
516
+ { SHPWriteOGisLine ( stream_obj, psCShape ); }
517
+ else {
518
+ if ( thisDim && SHPD_POINT )
519
+ { SHPWriteOGisPoint ( stream_obj, psCShape ); }
520
+ }
521
+ }
522
+
523
+ #ifdef DEBUG2
524
+ printf("(SHPWriteOGisWKB) outta here when stream pos is %d \n", stream_obj->StreamPos);
525
+ #endif
526
+ return (0);
527
+ }
528
+
529
+
530
+ /* **************************************************************************
531
+ * SHPWriteOGisPolygon
532
+ *
533
+ * for this pass code to more generic OGis MultiPolygon Type
534
+ * later add support for OGis Polygon Type
535
+ *
536
+ * Encapsulate entire SHPObject for use with Postgresql
537
+ *
538
+ * **************************************************************************/
539
+ int SHPWriteOGisPolygon ( WKBStreamObj *stream_obj, SHPObject *psCShape ) {
540
+ SHPObject **ppsC;
541
+ SHPObject *psC;
542
+ int rPart, ring, rVertices, cpart, cParts, nextring, i, j;
543
+ char Flag = 1;
544
+ int GeoType = OGIST_POLYGON;
545
+
546
+ /* cant have more than nParts complex objects in this object */
547
+ ppsC = calloc ( psCShape->nParts, sizeof(int) );
548
+
549
+
550
+ nextring = 0;
551
+ cParts=0;
552
+ while ( nextring >= 0 ) {
553
+ ppsC[cParts] = SHPUnCompound ( psCShape, &nextring );
554
+ cParts++;
555
+ }
556
+
557
+ #ifdef DEBUG2
558
+ printf ("(SHPWriteOGisPolygon) Uncompounded into %d parts \n", cParts);
559
+ #endif
560
+
561
+ WKBStreamWrite ( stream_obj, &cParts, 1, sizeof(int) );
562
+
563
+ for ( cpart = 0; cpart < cParts; cpart++) {
564
+
565
+ WKBStreamWrite ( stream_obj, & Flag, 1, sizeof(char) );
566
+ WKBStreamWrite ( stream_obj, & GeoType, 1, sizeof(int) );
567
+
568
+ psC = (SHPObject*) ppsC[cpart];
569
+ WKBStreamWrite ( stream_obj, &(psC->nParts), 1, sizeof(int) );
570
+
571
+ for ( ring = 0; (ring < (psC->nParts)) && (psC->nParts > 0); ring ++) {
572
+ if ( ring < (psC->nParts-2) )
573
+ { rVertices = psC->panPartStart[ring+1] - psC->panPartStart[ring]; }
574
+ else
575
+ { rVertices = psC->nVertices - psC->panPartStart[ring]; }
576
+ #ifdef DEBUG2
577
+ printf ("(SHPWriteOGisPolygon) scanning part %d, ring %d %d vtxs \n",
578
+ cpart, ring, rVertices);
579
+ #endif
580
+ rPart = psC->panPartStart[ring];
581
+ WKBStreamWrite ( stream_obj, &rVertices, 1, sizeof(int) );
582
+ for ( j=rPart; j < (rPart + rVertices); j++ ) {
583
+ WKBStreamWrite ( stream_obj, &(psC->padfX[j]), 1, sizeof(double) );
584
+ WKBStreamWrite ( stream_obj, &(psC->padfY[j]), 1, sizeof(double) );
585
+ } /* for each vertex */
586
+ } /* for each ring */
587
+ } /* for each complex part */
588
+
589
+ #ifdef DEBUG2
590
+ printf ("(SHPWriteOGisPolygon) outta here \n");
591
+ #endif
592
+ return (1);
593
+ }
594
+
595
+
596
+ /* **************************************************************************
597
+ * SHPWriteOGisLine
598
+ *
599
+ * for this pass code to more generic OGis MultiXXXXXXX Type
600
+ * later add support for OGis LineString Type
601
+ *
602
+ * Encapsulate entire SHPObject for use with Postgresql
603
+ *
604
+ * **************************************************************************/
605
+ int SHPWriteOGisLine ( WKBStreamObj *stream_obj, SHPObject *psCShape ) {
606
+
607
+ return ( SHPWriteOGisPolygon( stream_obj, psCShape ));
608
+ }
609
+
610
+
611
+ /* **************************************************************************
612
+ * SHPWriteOGisPoint
613
+ *
614
+ * for this pass code to more generic OGis MultiPoint Type
615
+ * later add support for OGis Point Type
616
+ *
617
+ * Encapsulate entire SHPObject for use with Postgresql
618
+ *
619
+ * **************************************************************************/
620
+ int SHPWriteOGisPoint ( WKBStreamObj *stream_obj, SHPObject *psCShape ) {
621
+ int j;
622
+
623
+ WKBStreamWrite ( stream_obj, &(psCShape->nVertices), 1, sizeof(int) );
624
+
625
+ for ( j=0; j < psCShape->nVertices; j++ ) {
626
+ WKBStreamWrite ( stream_obj, &(psCShape->padfX[j]), 1, sizeof(double) );
627
+ WKBStreamWrite ( stream_obj, &(psCShape->padfY[j]), 1, sizeof(double) );
628
+ } /* for each vertex */
629
+
630
+ return (1);
631
+ }
632
+
633
+
634
+
635
+ /* **************************************************************************
636
+ * SHPReadOGisPolygon
637
+ *
638
+ * for this pass code to more generic OGis MultiPolygon Type
639
+ * later add support for OGis Polygon Type
640
+ *
641
+ * Encapsulate entire SHPObject for use with Postgresql
642
+ *
643
+ * **************************************************************************/
644
+ SHPObject* SHPReadOGisPolygon ( WKBStreamObj *stream_obj ) {
645
+ SHPObject **ppsC;
646
+ SHPObject *psC;
647
+ int rPart, ring, rVertices, cpart, cParts, nextring, i, j;
648
+ int totParts, totVertices, pRings, nParts;
649
+
650
+ psC = SHPCreateObject ( SHPT_POLYGON, -1, 0, NULL, NULL, 0,
651
+ NULL, NULL, NULL, NULL );
652
+ /* initialize a blank SHPObject */
653
+
654
+ WKBStreamRead ( stream_obj, &cParts, 1, sizeof(char) );
655
+
656
+ totParts = cParts;
657
+ totVertices = 0;
658
+
659
+ SfRealloc ( psC->panPartStart, cParts * sizeof(int));
660
+ SfRealloc ( psC->panPartType, cParts * sizeof(int));
661
+
662
+ for ( cpart = 0; cpart < cParts; cpart++) {
663
+ WKBStreamRead ( stream_obj, &nParts, 1, sizeof(int) );
664
+ pRings = nParts;
665
+ /* pRings is the number of rings prior to the Ring loop below */
666
+
667
+ if ( nParts > 1 ) {
668
+ totParts += nParts - 1;
669
+ SfRealloc ( psC->panPartStart, totParts * sizeof(int));
670
+ SfRealloc ( psC->panPartType, totParts * sizeof(int));
671
+ }
672
+
673
+ rPart = 0;
674
+ for ( ring = 0; ring < (nParts - 1); ring ++) {
675
+ WKBStreamRead ( stream_obj, &rVertices, 1, sizeof(int) );
676
+ totVertices += rVertices;
677
+
678
+ psC->panPartStart[ring+pRings] = rPart;
679
+ if ( ring == 0 )
680
+ { psC->panPartType[ring + pRings] = SHPP_OUTERRING; }
681
+ else
682
+ { psC->panPartType[ring + pRings] = SHPP_INNERRING; }
683
+
684
+ SfRealloc ( psC->padfX, totVertices * sizeof (double));
685
+ SfRealloc ( psC->padfY, totVertices * sizeof (double));
686
+
687
+ for ( j=rPart; j < (rPart + rVertices); j++ ) {
688
+ WKBStreamRead ( stream_obj, &(psC->padfX[j]), 1, sizeof(double) );
689
+ WKBStreamRead ( stream_obj, &(psC->padfY[j]), 1, sizeof(double) );
690
+ } /* for each vertex */
691
+ rPart += rVertices;
692
+
693
+ } /* for each ring */
694
+
695
+ } /* for each complex part */
696
+
697
+ return ( psC );
698
+
699
+ }
700
+
701
+
702
+ /* **************************************************************************
703
+ * SHPReadOGisLine
704
+ *
705
+ * for this pass code to more generic OGis MultiLineString Type
706
+ * later add support for OGis LineString Type
707
+ *
708
+ * Encapsulate entire SHPObject for use with Postgresql
709
+ *
710
+ * **************************************************************************/
711
+ SHPObject* SHPReadOGisLine ( WKBStreamObj *stream_obj ) {
712
+ SHPObject **ppsC;
713
+ SHPObject *psC;
714
+ int rPart, ring, rVertices, cpart, cParts, nextring, i, j;
715
+ int totParts, totVertices, pRings, nParts;
716
+
717
+ psC = SHPCreateObject ( SHPT_ARC, -1, 0, NULL, NULL, 0,
718
+ NULL, NULL, NULL, NULL );
719
+ /* initialize a blank SHPObject */
720
+
721
+ WKBStreamRead ( stream_obj, &cParts, 1, sizeof(int) );
722
+
723
+ totParts = cParts;
724
+ totVertices = 0;
725
+
726
+ SfRealloc ( psC->panPartStart, cParts * sizeof(int));
727
+ SfRealloc ( psC->panPartType, cParts * sizeof(int));
728
+
729
+ for ( cpart = 0; cpart < cParts; cpart++) {
730
+ WKBStreamRead ( stream_obj, &nParts, 1, sizeof(int) );
731
+ pRings = totParts;
732
+ /* pRings is the number of rings prior to the Ring loop below */
733
+
734
+ if ( nParts > 1 ) {
735
+ totParts += nParts - 1;
736
+ SfRealloc ( psC->panPartStart, totParts * sizeof(int));
737
+ SfRealloc ( psC->panPartType, totParts * sizeof(int));
738
+ }
739
+
740
+ rPart = 0;
741
+ for ( ring = 0; ring < (nParts - 1); ring ++) {
742
+ WKBStreamRead ( stream_obj, &rVertices, 1, sizeof(int) );
743
+ totVertices += rVertices;
744
+
745
+ psC->panPartStart[ring+pRings] = rPart;
746
+ if ( ring == 0 )
747
+ { psC->panPartType[ring + pRings] = SHPP_OUTERRING; }
748
+ else
749
+ { psC->panPartType[ring + pRings] = SHPP_INNERRING; }
750
+
751
+ SfRealloc ( psC->padfX, totVertices * sizeof (double));
752
+ SfRealloc ( psC->padfY, totVertices * sizeof (double));
753
+
754
+ for ( j=rPart; j < (rPart + rVertices); j++ ) {
755
+ WKBStreamRead ( stream_obj, &(psC->padfX[j]), 1, sizeof(double) );
756
+ WKBStreamRead ( stream_obj, &(psC->padfY[j]), 1, sizeof(double) );
757
+ } /* for each vertex */
758
+ rPart += rVertices;
759
+
760
+ } /* for each ring */
761
+
762
+ } /* for each complex part */
763
+
764
+ return ( psC );
765
+ }
766
+
767
+
768
+ /* **************************************************************************
769
+ * SHPReadOGisPoint
770
+ *
771
+ * Encapsulate entire SHPObject for use with Postgresql
772
+ *
773
+ * **************************************************************************/
774
+ SHPObject* SHPReadOGisPoint ( WKBStreamObj *stream_obj ) {
775
+ SHPObject *psC;
776
+ int nVertices, j;
777
+
778
+ psC = SHPCreateObject ( SHPT_MULTIPOINT, -1, 0, NULL, NULL, 0,
779
+ NULL, NULL, NULL, NULL );
780
+ /* initialize a blank SHPObject */
781
+
782
+ WKBStreamRead ( stream_obj, &nVertices, 1, sizeof(int) );
783
+
784
+ SfRealloc ( psC->padfX, nVertices * sizeof (double));
785
+ SfRealloc ( psC->padfY, nVertices * sizeof (double));
786
+
787
+ for ( j=0; j < nVertices; j++ ) {
788
+ WKBStreamRead ( stream_obj, &(psC->padfX[j]), 1, sizeof(double) );
789
+ WKBStreamRead ( stream_obj, &(psC->padfY[j]), 1, sizeof(double) );
790
+ } /* for each vertex */
791
+
792
+ return ( psC );
793
+ }
794
+
795
+
796
+
797
+
798
+ /* **************************************************************************
799
+ * RingReadOGisWKB
800
+ *
801
+ * this accepts OGisLineStrings which are basic building blocks
802
+ *
803
+ * Encapsulate entire SHPObject for use with Postgresql
804
+ *
805
+ * **************************************************************************/
806
+ int RingReadOgisWKB ( SHPObject *psCShape, char *stream_obj) {
807
+ return 0;
808
+ }
809
+
810
+
811
+ /* **************************************************************************
812
+ * RingWriteOGisWKB
813
+ *
814
+ * this emits OGisLineStrings which are basic building blocks
815
+ *
816
+ * Encapsulate entire SHPObject for use with Postgresql
817
+ *
818
+ * **************************************************************************/
819
+ int RingWriteOgisWKB ( SHPObject *psCShape, char *stream_obj) {
820
+
821
+ return 0;
822
+ }
823
+
824
+
825
+ /* **************************************************************************
826
+ * SHPDimension
827
+ *
828
+ * Return the Dimensionality of the SHPObject
829
+ * a handy utility function
830
+ *
831
+ * **************************************************************************/
832
+ int SHPDimension ( int SHPType ) {
833
+ int dimension;
834
+
835
+ dimension = 0;
836
+
837
+ switch ( SHPType ) {
838
+ case SHPT_POINT : dimension = SHPD_POINT; break;
839
+ case SHPT_ARC : dimension = SHPD_LINE; break;
840
+ case SHPT_POLYGON : dimension = SHPD_AREA; break;
841
+ case SHPT_MULTIPOINT : dimension = SHPD_POINT; break;
842
+ case SHPT_POINTZ : dimension = SHPD_POINT | SHPD_Z; break;
843
+ case SHPT_ARCZ : dimension = SHPD_LINE | SHPD_Z; break;
844
+ case SHPT_POLYGONZ : dimension = SHPD_AREA | SHPD_Z; break;
845
+ case SHPT_MULTIPOINTZ : dimension = SHPD_POINT | SHPD_Z; break;
846
+ case SHPT_POINTM : dimension = SHPD_POINT | SHPD_MEASURE; break;
847
+ case SHPT_ARCM : dimension = SHPD_LINE | SHPD_MEASURE; break;
848
+ case SHPT_POLYGONM : dimension = SHPD_AREA | SHPD_MEASURE; break;
849
+ case SHPT_MULTIPOINTM : dimension = SHPD_POINT | SHPD_MEASURE; break;
850
+ case SHPT_MULTIPATCH : dimension = SHPD_AREA; break;
851
+ }
852
+
853
+ return ( dimension );
854
+ }
855
+
856
+
857
+ /* **************************************************************************
858
+ * SHPPointinPoly_2d
859
+ *
860
+ * Return a Point inside an R+ of a potentially
861
+ * complex/compound SHPObject suitable for labelling
862
+ * return only one point even if if is a compound object
863
+ *
864
+ * reject non area SHP Types
865
+ *
866
+ * **************************************************************************/
867
+ PT SHPPointinPoly_2d ( SHPObject *psCShape ) {
868
+ PT *sPT, rPT;
869
+
870
+ if ( !(SHPDimension (psCShape->nSHPType) & SHPD_AREA) )
871
+ {
872
+ rPT.x = NAN;
873
+ rPT.y = NAN;
874
+ return rPT;
875
+ }
876
+
877
+ sPT = SHPPointsinPoly_2d ( psCShape );
878
+
879
+ if ( sPT ) {
880
+ rPT.x = sPT[0].x;
881
+ rPT.y = sPT[0].y;
882
+ } else {
883
+ rPT.x = NAN;
884
+ rPT.y = NAN;
885
+ }
886
+ return ( rPT );
887
+ }
888
+
889
+
890
+ /* **************************************************************************
891
+ * SHPPointsinPoly_2d
892
+ *
893
+ * Return a Point inside each R+ of a potentially
894
+ * complex/compound SHPObject suitable for labelling
895
+ * return one point for each R+ even if it is a compound object
896
+ *
897
+ * reject non area SHP Types
898
+ *
899
+ * **************************************************************************/
900
+ PT* SHPPointsinPoly_2d ( SHPObject *psCShape ) {
901
+ PT *PIP = NULL;
902
+ int cRing;
903
+ SHPObject *psO, *psInt, *CLine;
904
+ double *CLx, *CLy;
905
+ int *CLstt, *CLst, nPIP, ring, rMpart, ring_vtx, ring_nVertices;
906
+ double rLen, rLenMax;
907
+
908
+ if ( !(SHPDimension (psCShape->nSHPType) & SHPD_AREA) )
909
+ return ( NULL );
910
+
911
+ while ( psO = SHPUnCompound (psCShape, &cRing)) {
912
+ CLx = calloc ( 4, sizeof(double));
913
+ CLy = calloc ( 4, sizeof(double));
914
+ CLst = calloc ( 2, sizeof(int));
915
+ CLstt = calloc ( 2, sizeof(int));
916
+
917
+ /* a horizontal & vertical compound line though the middle of the */
918
+ /* extents */
919
+ CLx [0] = psO->dfXMin;
920
+ CLy [0] = (psO->dfYMin + psO->dfYMax ) * 0.5;
921
+ CLx [1] = psO->dfXMax;
922
+ CLy [1] = (psO->dfYMin + psO->dfYMax ) * 0.5;
923
+
924
+ CLx [2] = (psO->dfXMin + psO->dfXMax ) * 0.5;
925
+ CLy [2] = psO->dfYMin;
926
+ CLx [3] = (psO->dfXMin + psO->dfXMax ) * 0.5;
927
+ CLy [3] = psO->dfYMax;
928
+
929
+ CLst[0] = 0; CLst[1] = 2;
930
+ CLstt[0] = SHPP_RING; CLstt[1] = SHPP_RING;
931
+
932
+ CLine = SHPCreateObject ( SHPT_POINT, -1, 2, CLst, CLstt, 4,
933
+ CLx, CLy, NULL, NULL );
934
+
935
+ /* with the H & V centrline compound object, intersect it with the OBJ */
936
+ psInt = SHPIntersect_2d ( CLine, psO );
937
+ /* return SHP type is lowest common dimensionality of the input types */
938
+
939
+
940
+ /* find the longest linestring returned by the intersection */
941
+ ring_vtx = psInt->nVertices ;
942
+ for ( ring = (psInt->nParts - 1); ring >= 0; ring-- ) {
943
+ ring_nVertices = ring_vtx - psInt->panPartStart[ring];
944
+
945
+ rLen += RingLength_2d ( ring_nVertices,
946
+ (double*) &(psInt->padfX [psInt->panPartStart[ring]]),
947
+ (double*) &(psInt->padfY [psInt->panPartStart[ring]]) );
948
+
949
+ if ( rLen > rLenMax )
950
+ { rLenMax = rLen;
951
+ rMpart = psInt->panPartStart[ring];
952
+ }
953
+ ring_vtx = psInt->panPartStart[ring];
954
+ }
955
+
956
+ /* add the centerpoint of the longest ARC of the intersection to the */
957
+ /* PIP list */
958
+ nPIP ++;
959
+ SfRealloc ( PIP, sizeof(double) * 2 * nPIP);
960
+ PIP[nPIP].x = (psInt ->padfX [rMpart] + psInt ->padfX [rMpart]) * 0.5;
961
+ PIP[nPIP].y = (psInt ->padfY [rMpart] + psInt ->padfY [rMpart]) * 0.5;
962
+
963
+ SHPDestroyObject ( psO );
964
+ SHPDestroyObject ( CLine );
965
+
966
+ /* does SHPCreateobject use preallocated memory or does it copy the */
967
+ /* contents. To be safe conditionally release CLx, CLy, CLst, CLstt */
968
+ if ( CLx ) free ( CLx );
969
+ if ( CLy ) free ( CLy );
970
+ if ( CLst ) free ( CLst );
971
+ if ( CLstt ) free ( CLstt );
972
+ }
973
+
974
+ return ( PIP );
975
+ }
976
+
977
+
978
+ /* **************************************************************************
979
+ * SHPCentrd_2d
980
+ *
981
+ * Return the single mathematical / geometric centroid of a potentially
982
+ * complex/compound SHPObject
983
+ *
984
+ * reject non area SHP Types
985
+ *
986
+ * **************************************************************************/
987
+ PT SHPCentrd_2d ( SHPObject *psCShape ) {
988
+ int ring, ringPrev, ring_nVertices, rStart;
989
+ double Area, ringArea;
990
+ PT ringCentrd, C;
991
+
992
+
993
+ if ( !(SHPDimension (psCShape->nSHPType) & SHPD_AREA) )
994
+ {
995
+ C.x = NAN;
996
+ C.y = NAN;
997
+ return C;
998
+ }
999
+
1000
+ #ifdef DEBUG
1001
+ printf ("for Object with %d vtx, %d parts [ %d, %d] \n",
1002
+ psCShape->nVertices, psCShape->nParts,
1003
+ psCShape->panPartStart[0],psCShape->panPartStart[1]);
1004
+ #endif
1005
+
1006
+ Area = 0;
1007
+ C.x = 0.0;
1008
+ C.y = 0.0;
1009
+
1010
+ /* for each ring in compound / complex object calc the ring cntrd */
1011
+
1012
+ ringPrev = psCShape->nVertices;
1013
+ for ( ring = (psCShape->nParts - 1); ring >= 0; ring-- ) {
1014
+ rStart = psCShape->panPartStart[ring];
1015
+ ring_nVertices = ringPrev - rStart;
1016
+
1017
+ RingCentroid_2d ( ring_nVertices, (double*) &(psCShape->padfX [rStart]),
1018
+ (double*) &(psCShape->padfY [rStart]), &ringCentrd, &ringArea);
1019
+
1020
+ #ifdef DEBUG
1021
+ printf ("(SHPCentrd_2d) Ring %d, vtxs %d, area: %f, ring centrd %f, %f \n",
1022
+ ring, ring_nVertices, ringArea, ringCentrd.x, ringCentrd.y);
1023
+ #endif
1024
+
1025
+ /* use Superposition of these rings to build a composite Centroid */
1026
+ /* sum the ring centrds * ringAreas, at the end divide by total area */
1027
+ C.x += ringCentrd.x * ringArea;
1028
+ C.y += ringCentrd.y * ringArea;
1029
+ Area += ringArea;
1030
+ ringPrev = rStart;
1031
+ }
1032
+
1033
+ /* hold on the division by AREA until were at the end */
1034
+ C.x = C.x / Area;
1035
+ C.y = C.y / Area;
1036
+ #ifdef DEBUG
1037
+ printf ("SHPCentrd_2d) Overall Area: %f, Centrd %f, %f \n",
1038
+ Area, C.x, C.y);
1039
+ #endif
1040
+ return ( C );
1041
+ }
1042
+
1043
+
1044
+ /* **************************************************************************
1045
+ * RingCentroid_2d
1046
+ *
1047
+ * Return the mathematical / geometric centroid of a single closed ring
1048
+ *
1049
+ * **************************************************************************/
1050
+ int RingCentroid_2d ( int nVertices, double *a, double *b, PT *C, double *Area ) {
1051
+ int iv,jv;
1052
+ int sign_x, sign_y;
1053
+ double dy_Area, dx_Area, Cx_accum, Cy_accum, ppx, ppy;
1054
+ double x_base, y_base, x, y;
1055
+
1056
+ /* the centroid of a closed Ring is defined as
1057
+ *
1058
+ * Cx = sum (cx * dArea ) / Total Area
1059
+ * and
1060
+ * Cy = sum (cy * dArea ) / Total Area
1061
+ */
1062
+
1063
+ x_base = a[0];
1064
+ y_base = b[0];
1065
+
1066
+ Cy_accum = 0.0;
1067
+ Cx_accum = 0.0;
1068
+
1069
+ ppx = a[1] - x_base;
1070
+ ppy = b[1] - y_base;
1071
+ *Area = 0;
1072
+
1073
+ /* Skip the closing vector */
1074
+ for ( iv = 2; iv <= nVertices - 2; iv++ ) {
1075
+ x = a[iv] - x_base;
1076
+ y = b[iv] - y_base;
1077
+
1078
+ /* calc the area and centroid of triangle built out of an arbitrary */
1079
+ /* base_point on the ring and each successive pair on the ring */
1080
+
1081
+ /* Area of a triangle is the cross product of its defining vectors */
1082
+ /* Centroid of a triangle is the average of its vertices */
1083
+
1084
+ dx_Area = ((x * ppy) - (y * ppx)) * 0.5;
1085
+ *Area += dx_Area;
1086
+
1087
+ Cx_accum += ( ppx + x ) * dx_Area;
1088
+ Cy_accum += ( ppy + y ) * dx_Area;
1089
+ #ifdef DEBUG2
1090
+ printf("(ringcentrd_2d) Pp( %f, %f), P(%f, %f)\n", ppx, ppy, x, y);
1091
+ printf("(ringcentrd_2d) dA: %f, sA: %f, Cx: %f, Cy: %f \n",
1092
+ dx_Area, *Area, Cx_accum, Cy_accum);
1093
+ #endif
1094
+ ppx = x;
1095
+ ppy = y;
1096
+ }
1097
+
1098
+ #ifdef DEBUG2
1099
+ printf("(ringcentrd_2d) Cx: %f, Cy: %f \n",
1100
+ ( Cx_accum / ( *Area * 3) ), ( Cy_accum / (*Area * 3) ));
1101
+ #endif
1102
+
1103
+ /* adjust back to world coords */
1104
+ C->x = ( Cx_accum / ( *Area * 3)) + x_base;
1105
+ C->y = ( Cy_accum / ( *Area * 3)) + y_base;
1106
+
1107
+ return ( 1 );
1108
+ }
1109
+
1110
+
1111
+
1112
+
1113
+ /* **************************************************************************
1114
+ * SHPRingDir_2d
1115
+ *
1116
+ * Test Polygon for CW / CCW ( R+ / R- )
1117
+ *
1118
+ * return 1 for R+
1119
+ * return -1 for R-
1120
+ * return 0 for error
1121
+ * **************************************************************************/
1122
+ int SHPRingDir_2d ( SHPObject *psCShape, int Ring ) {
1123
+ int i, ti, last_vtx;
1124
+ double tX;
1125
+ double *a, *b;
1126
+ double dx0, dx1, dy0, dy1, v1, v2 ,v3;
1127
+
1128
+ tX = 0.0;
1129
+ a = psCShape->padfX;
1130
+ b = psCShape->padfY;
1131
+
1132
+ if ( Ring >= psCShape->nParts ) return ( 0 );
1133
+
1134
+ if ( Ring >= psCShape->nParts -1 )
1135
+ { last_vtx = psCShape->nVertices; }
1136
+ else
1137
+ { last_vtx = psCShape->panPartStart[Ring + 1]; }
1138
+
1139
+ /* All vertices at the corners of the extrema (rightmost lowest, leftmost lowest, */
1140
+ /* topmost rightest, ...) must be less than pi wide. If they werent they couldnt be */
1141
+ /* extrema. */
1142
+ /* of course the following will fail if the Extents are even a little wrong */
1143
+
1144
+ for ( i = psCShape->panPartStart[Ring]; i < last_vtx; i++ ) {
1145
+ if ( b[i] == psCShape->dfYMax && a[i] > tX )
1146
+ { ti = i; }
1147
+ }
1148
+
1149
+ #ifdef DEBUG2
1150
+ printf ("(shpgeo:SHPRingDir) highest Rightmost Pt is vtx %d (%f, %f)\n", ti, a[ti], b[ti]);
1151
+ #endif
1152
+
1153
+ /* cross product */
1154
+ /* the sign of the cross product of two vectors indicates the right or left half-plane */
1155
+ /* which we can use to indicate Ring Dir */
1156
+ if ( ti > psCShape->panPartStart[Ring] & ti < last_vtx )
1157
+ { dx0 = a[ti-1] - a[ti];
1158
+ dx1 = a[ti+1] - a[ti];
1159
+ dy0 = b[ti-1] - b[ti];
1160
+ dy1 = b[ti+1] - b[ti];
1161
+ }
1162
+ else
1163
+ /* if the tested vertex is at the origin then continue from 0 */
1164
+ { dx1 = a[1] - a[0];
1165
+ dx0 = a[last_vtx] - a[0];
1166
+ dy1 = b[1] - b[0];
1167
+ dy0 = b[last_vtx] - b[0];
1168
+ }
1169
+
1170
+ // v1 = ( (dy0 * 0) - (0 * dy1) );
1171
+ // v2 = ( (0 * dx1) - (dx0 * 0) );
1172
+ /* these above are always zero so why do the math */
1173
+ v3 = ( (dx0 * dy1) - (dx1 * dy0) );
1174
+
1175
+ #ifdef DEBUG2
1176
+ printf ("(shpgeo:SHPRingDir) cross product for vtx %d was %f \n", ti, v3);
1177
+ #endif
1178
+
1179
+ if ( v3 > 0 )
1180
+ { return (1); }
1181
+ else
1182
+ { return (-1); }
1183
+ }
1184
+
1185
+
1186
+
1187
+ /* **************************************************************************
1188
+ * SHPArea_2d
1189
+ *
1190
+ * Calculate the XY Area of Polygon ( can be compound / complex )
1191
+ *
1192
+ * **************************************************************************/
1193
+ double SHPArea_2d ( SHPObject *psCShape ) {
1194
+ double cArea;
1195
+ int ring, ring_vtx, ringDir, ring_nVertices;
1196
+
1197
+ cArea = 0;
1198
+ if ( !(SHPDimension (psCShape->nSHPType) & SHPD_AREA) )
1199
+ return ( -1 );
1200
+
1201
+
1202
+ /* Walk each ring adding its signed Area, R- will return a negative */
1203
+ /* area, so we don't have to test for them */
1204
+
1205
+ /* I just start at the last ring and work down to the first */
1206
+ ring_vtx = psCShape->nVertices ;
1207
+ for ( ring = (psCShape->nParts - 1); ring >= 0; ring-- ) {
1208
+ ring_nVertices = ring_vtx - psCShape->panPartStart[ring];
1209
+
1210
+ #ifdef DEBUG2
1211
+ printf("(shpgeo:SHPArea_2d) part %d, vtx %d \n", ring, ring_nVertices);
1212
+ #endif
1213
+ cArea += RingArea_2d ( ring_nVertices,
1214
+ (double*) &(psCShape->padfX [psCShape->panPartStart[ring]]),
1215
+ (double*) &(psCShape->padfY [psCShape->panPartStart[ring]]) );
1216
+
1217
+ ring_vtx = psCShape->panPartStart[ring];
1218
+ }
1219
+
1220
+ #ifdef DEBUG2
1221
+ printf ("(shpgeo:SHPArea_2d) Area = %f \n", cArea);
1222
+ #endif
1223
+
1224
+ /* Area is signed, negative Areas are R- */
1225
+ return ( cArea );
1226
+
1227
+ }
1228
+
1229
+
1230
+ /* **************************************************************************
1231
+ * SHPLength_2d
1232
+ *
1233
+ * Calculate the Planar ( XY ) Length of Polygon ( can be compound / complex )
1234
+ * or Polyline ( can be compound ). Length on Polygon is its Perimeter
1235
+ *
1236
+ * **************************************************************************/
1237
+ double SHPLength_2d ( SHPObject *psCShape ) {
1238
+ double Length;
1239
+ int i, j;
1240
+ double dx, dy;
1241
+
1242
+ if ( !(SHPDimension (psCShape->nSHPType) & (SHPD_AREA || SHPD_LINE)) )
1243
+ return ( (double) -1 );
1244
+
1245
+ Length = 0;
1246
+ j = 1;
1247
+ for ( i = 1; i < psCShape->nVertices; i++ ) {
1248
+ if ( psCShape->panPartStart[j] == i )
1249
+ { j ++; }
1250
+ /* skip the moves with "pen up" from ring to ring */
1251
+ else
1252
+ {
1253
+ dx = psCShape->padfX[i] - psCShape->padfX[i-1];
1254
+ dy = psCShape->padfY[i] - psCShape->padfY[i-1];
1255
+ Length += sqrt ( ( dx * dx ) + ( dy * dy ) );
1256
+ }
1257
+ /* simplify this equation */
1258
+ }
1259
+
1260
+ return ( Length );
1261
+ }
1262
+
1263
+
1264
+ /* **************************************************************************
1265
+ * RingLength_2d
1266
+ *
1267
+ * Calculate the Planar ( XY ) Length of Polygon ( can be compound / complex )
1268
+ * or Polyline ( can be compound ). Length of Polygon is its Perimeter
1269
+ *
1270
+ * **************************************************************************/
1271
+ double RingLength_2d ( int nVertices, double *a, double *b ) {
1272
+ double Length;
1273
+ int i, j;
1274
+ double dx, dy;
1275
+
1276
+ Length = 0;
1277
+ j = 1;
1278
+ for ( i = 1; i < nVertices; i++ ) {
1279
+ dx = a[i] - b[i-1];
1280
+ dy = b[i] - b[i-1];
1281
+ Length += sqrt ( ( dx * dx ) + ( dy * dy ) );
1282
+ /* simplify this equation */
1283
+ }
1284
+
1285
+ return ( Length );
1286
+ }
1287
+
1288
+
1289
+ /* **************************************************************************
1290
+ * RingArea_2d
1291
+ *
1292
+ * Calculate the Planar Area of a single closed ring
1293
+ *
1294
+ * **************************************************************************/
1295
+ double RingArea_2d ( int nVertices, double *a, double *b ) {
1296
+ int iv,jv;
1297
+ double ppx, ppy;
1298
+ static double Area;
1299
+ double dx_Area;
1300
+ double x_base, y_base, x, y;
1301
+
1302
+ x_base = a[0];
1303
+ y_base = b[0];
1304
+
1305
+ ppx = a[1] - x_base;
1306
+ ppy = b[1] - y_base;
1307
+ Area = 0.0;
1308
+ #ifdef DEBUG2
1309
+ printf("(shpgeo:RingArea) %d vertices \n", nVertices);
1310
+ #endif
1311
+ for ( iv = 2; iv <= ( nVertices - 1 ); iv++ ) {
1312
+ x = a[iv] - x_base;
1313
+ y = b[iv] - y_base;
1314
+
1315
+ /* Area of a triangle is the cross product of its defining vectors */
1316
+
1317
+ dx_Area = ((x * ppy) - (y * ppx)) * 0.5;
1318
+
1319
+ Area += dx_Area;
1320
+ #ifdef DEBUG2
1321
+ printf ("(shpgeo:RingArea) dxArea %f sArea %f for pt(%f, %f)\n",
1322
+ dx_Area, Area, x, y);
1323
+ #endif
1324
+
1325
+ ppx = x;
1326
+ ppy = y;
1327
+ }
1328
+
1329
+ #ifdef DEBUG2
1330
+ printf ("(shpgeo:RingArea) total RingArea %f \n", Area);
1331
+ #endif
1332
+ return ( Area );
1333
+
1334
+ }
1335
+
1336
+
1337
+
1338
+ /* **************************************************************************
1339
+ * SHPUnCompound
1340
+ *
1341
+ * ESRI calls this function explode
1342
+ * Return a non compound ( possibly complex ) object
1343
+ *
1344
+ * ring_number is R+ number corresponding to object
1345
+ *
1346
+ *
1347
+ * ignore complexity in Z dimension for now
1348
+ *
1349
+ * **************************************************************************/
1350
+ SHPObject* SHPUnCompound ( SHPObject *psCShape, int * ringNumber ) {
1351
+ int ringDir, ring, lRing;
1352
+
1353
+ if ( (*ringNumber >= psCShape->nParts) || *ringNumber == -1 ) {
1354
+ *ringNumber = -1;
1355
+ return (NULL);
1356
+ }
1357
+
1358
+
1359
+ if ( *ringNumber == (psCShape->nParts - 1) ) {
1360
+ *ringNumber = -1;
1361
+ return ( SHPClone(psCShape, (psCShape->nParts - 1), -1) );
1362
+ }
1363
+
1364
+ lRing = *ringNumber;
1365
+ ringDir = -1;
1366
+ for ( ring = (lRing + 1); (ring < psCShape->nParts) && ( ringDir < 0 ); ring ++)
1367
+ ringDir = SHPRingDir_2d ( psCShape, ring);
1368
+
1369
+ if ( ring == psCShape->nParts )
1370
+ *ringNumber = -1;
1371
+ else
1372
+ *ringNumber = ring;
1373
+ /* I am strictly assuming that all R- parts of a complex object
1374
+ * directly follow their R+, so when we hit a new R+ its a
1375
+ * new part of a compound object
1376
+ * a SHPClean may be needed to enforce this as it is not part
1377
+ * of ESRI's definition of a SHPfile
1378
+ */
1379
+
1380
+ #ifdef DEBUG2
1381
+ printf ("(SHPUnCompound) asked for ring %d, lastring is %d \n", lRing, ring);
1382
+ #endif
1383
+ return ( SHPClone(psCShape, lRing, ring ) );
1384
+
1385
+ }
1386
+
1387
+
1388
+ /* **************************************************************************
1389
+ * SHPIntersect_2d
1390
+ *
1391
+ *
1392
+ * prototype only for now
1393
+ *
1394
+ * return object with lowest common dimensionality of objects
1395
+ *
1396
+ * **************************************************************************/
1397
+ SHPObject* SHPIntersect_2d ( SHPObject* a, SHPObject* b ) {
1398
+ SHPObject *C;
1399
+
1400
+ if ( (SHPDimension(a->nSHPType) && SHPD_POINT) || ( SHPDimension(b->nSHPType) && SHPD_POINT ) )
1401
+ return ( NULL );
1402
+ /* there is no intersect function like this for points */
1403
+
1404
+ C = SHPClone ( a, 0 , -1 );
1405
+
1406
+ return ( C);
1407
+
1408
+ }
1409
+
1410
+
1411
+
1412
+ /* **************************************************************************
1413
+ * SHPClean
1414
+ *
1415
+ * Test and fix normalization problems in shapes
1416
+ * Different tests need to be implemented for different SHPTypes
1417
+ * SHPT_POLYGON check ring directions CW / CCW ( R+ / R- )
1418
+ * put all R- after the R+ they are members of
1419
+ * i.e. each complex object is completed before the
1420
+ * next object is started
1421
+ * check for closed rings
1422
+ * ring must not intersect itself, even on edge
1423
+ *
1424
+ * no other types implemented yet
1425
+ *
1426
+ * not sure why but return object in place
1427
+ * use for object casting and object verification
1428
+ * **************************************************************************/
1429
+ int SHPClean ( SHPObject *psCShape ) {
1430
+
1431
+
1432
+ return (0);
1433
+ }
1434
+
1435
+
1436
+ /* **************************************************************************
1437
+ * SHPClone
1438
+ *
1439
+ * Clone a SHPObject, replicating all data
1440
+ *
1441
+ * **************************************************************************/
1442
+ SHPObject* SHPClone ( SHPObject *psCShape, int lowPart, int highPart ) {
1443
+ SHPObject *psObject;
1444
+ int newParts, newVertices;
1445
+ #ifdef DEBUG
1446
+ int i;
1447
+ #endif
1448
+
1449
+ if ( highPart >= psCShape->nParts || highPart == -1 )
1450
+ highPart = psCShape->nParts ;
1451
+
1452
+ #ifdef DEBUG
1453
+ printf (" cloning SHP (%d parts) from ring %d upto ring %d \n",
1454
+ psCShape->nParts, lowPart, highPart);
1455
+ #endif
1456
+
1457
+ newParts = highPart - lowPart;
1458
+ if ( newParts == 0 ) { return ( NULL ); }
1459
+
1460
+ psObject = (SHPObject *) calloc(1,sizeof(SHPObject));
1461
+ psObject->nSHPType = psCShape->nSHPType;
1462
+ psObject->nShapeId = psCShape->nShapeId;
1463
+
1464
+ psObject->nParts = newParts;
1465
+ if ( psCShape->padfX ) {
1466
+ psObject->panPartStart = (int*) calloc (newParts, sizeof (int));
1467
+ memcpy ( psObject->panPartStart, psCShape->panPartStart,
1468
+ newParts * sizeof (int) );
1469
+ }
1470
+ if ( psCShape->padfX ) {
1471
+ psObject->panPartType = (int*) calloc (newParts, sizeof (int));
1472
+ memcpy ( psObject->panPartType,
1473
+ (int *) &(psCShape->panPartType[lowPart]),
1474
+ newParts * sizeof (int) );
1475
+ }
1476
+
1477
+ if ( highPart != psCShape->nParts ) {
1478
+ newVertices = psCShape->panPartStart[highPart] -
1479
+ psCShape->panPartStart[lowPart];
1480
+ }
1481
+ else
1482
+ { newVertices = psCShape->nVertices - psCShape->panPartStart[lowPart]; }
1483
+
1484
+
1485
+ #ifdef DEBUG
1486
+ if ( highPart = psCShape->nParts )
1487
+ i = psCShape->nVertices;
1488
+ else
1489
+ i = psCShape->panPartStart[highPart];
1490
+ printf (" from part %d (%d) to %d (%d) is %d vertices \n",
1491
+ lowPart, psCShape->panPartStart[lowPart], highPart,
1492
+ i, newVertices);
1493
+ #endif
1494
+ psObject->nVertices = newVertices;
1495
+ if ( psCShape->padfX ) {
1496
+ psObject->padfX = (double*) calloc (newVertices, sizeof (double));
1497
+ memcpy ( psObject->padfX,
1498
+ (double *) &(psCShape->padfX[psCShape->panPartStart[lowPart]]),
1499
+ newVertices * sizeof (double) );
1500
+ }
1501
+ if ( psCShape->padfY ) {
1502
+ psObject->padfY = (double*) calloc (newVertices, sizeof (double));
1503
+ memcpy ( psObject->padfY,
1504
+ (double *) &(psCShape->padfY[psCShape->panPartStart[lowPart]]),
1505
+ newVertices * sizeof (double) );
1506
+ }
1507
+ if ( psCShape->padfZ ) {
1508
+ psObject->padfZ = (double*) calloc (newVertices, sizeof (double));
1509
+ memcpy ( psObject->padfZ,
1510
+ (double *) &(psCShape->padfZ[psCShape->panPartStart[lowPart]]),
1511
+ newVertices * sizeof (double) );
1512
+ }
1513
+ if ( psCShape->padfM ) {
1514
+ psObject->padfM = (double*) calloc (newVertices, sizeof (double));
1515
+ memcpy ( psObject->padfM,
1516
+ (double *) &(psCShape->padfM[psCShape->panPartStart[lowPart]]),
1517
+ newVertices * sizeof (double) );
1518
+ }
1519
+
1520
+ psObject->dfXMin = psCShape->dfXMin;
1521
+ psObject->dfYMin = psCShape->dfYMin;
1522
+ psObject->dfZMin = psCShape->dfZMin;
1523
+ psObject->dfMMin = psCShape->dfMMin;
1524
+
1525
+ psObject->dfXMax = psCShape->dfXMax;
1526
+ psObject->dfYMax = psCShape->dfYMax;
1527
+ psObject->dfZMax = psCShape->dfZMax;
1528
+ psObject->dfMMax = psCShape->dfMMax;
1529
+
1530
+ SHPComputeExtents ( psObject );
1531
+ return ( psObject );
1532
+ }
1533
+
1534
+
1535
+
1536
+ /************************************************************************/
1537
+ /* SwapG */
1538
+ /* */
1539
+ /* Swap a 2, 4 or 8 byte word. */
1540
+ /************************************************************************/
1541
+ void SwapG( void *so, void *in, int this_cnt, int this_size ) {
1542
+ int i, j;
1543
+ unsigned char temp;
1544
+
1545
+ /* return to a new pointer otherwise it would invalidate existing data */
1546
+ /* as prevent further use of it */
1547
+
1548
+ for( j=0; j < this_cnt; j++ )
1549
+ {
1550
+ for( i=0; i < this_size/2; i++ )
1551
+ {
1552
+ ((unsigned char *) so)[i] = ((unsigned char *) in)[this_size-i-1];
1553
+ ((unsigned char *) so)[this_size-i-1] = ((unsigned char *) in)[i];
1554
+ }
1555
+ }
1556
+ }
1557
+
1558
+
1559
+ /* **************************************************************************
1560
+ * SwapW
1561
+ *
1562
+ * change byte order on an array of 16 bit words
1563
+ * need to change this over to shapelib, Frank Warmerdam's functions
1564
+ *
1565
+ * **************************************************************************/
1566
+ void swapW (void *so, unsigned char *in, long bytes) {
1567
+ int i, j;
1568
+ unsigned char map[4] = {3,2,1,0};
1569
+ unsigned char *out;
1570
+
1571
+ out = so;
1572
+ for (i=0; i <= (bytes/4); i++)
1573
+ for (j=0; j < 4; j++)
1574
+ out[(i*4)+map[j]] = in[(i*4)+j];
1575
+ }
1576
+
1577
+
1578
+ /* **************************************************************************
1579
+ * SwapD
1580
+ *
1581
+ * change byte order on an array of (double) 32 bit words
1582
+ * need to change this over to shapelib, Frank Warmerdam's functons
1583
+ *
1584
+ * **************************************************************************/
1585
+ void swapD (void *so, unsigned char *in, long bytes) {
1586
+ int i, j;
1587
+ unsigned char map[8] = {7,6,5,4,3,2,1,0};
1588
+ unsigned char *out;
1589
+
1590
+ out = so;
1591
+ for (i=0; i <= (bytes/8); i++)
1592
+ for (j=0; j < 8; j++)
1593
+ out[(i*8)+map[j]] = in[(i*8)+j];
1594
+ }
1595
+