shp 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+