/[thuban]/branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2744 - (show annotations)
Thu Mar 15 13:48:58 2007 UTC (18 years ago) by bramz
File MIME type: text/plain
File size: 18428 byte(s)
shapelibmodule.c, dbflibmodule.c: added some Unicode support for the filenames (no internal encoding for DBFFile yet).  It now should similar Unicode support Python's file() (concerning the filename, that is).
1 #include "pyshapelib_common.h"
2
3 /* --- SHPObject ----------------------------------------------------------------------------------------------------- */
4
5 typedef struct
6 {
7 PyObject_HEAD
8 SHPObject* shpObject;
9 }
10 SHPObjectObject;
11
12 enum {
13 vtXY,
14 vtXYM,
15 vtXYZM,
16 vtInvalid
17 } VertexType;
18
19 int determine_vertex_type(int shape_type, int* has_z, int* has_m)
20 {
21 switch (shape_type)
22 {
23 case SHPT_POINT:
24 case SHPT_ARC:
25 case SHPT_POLYGON:
26 case SHPT_MULTIPOINT:
27 if (has_z) *has_z = 0;
28 if (has_m) *has_m = 0;
29 return vtXY;
30 case SHPT_POINTM:
31 case SHPT_ARCM:
32 case SHPT_POLYGONM:
33 case SHPT_MULTIPOINTM:
34 if (has_z) *has_z = 0;
35 if (has_m) *has_m = 1;
36 case SHPT_POINTZ:
37 case SHPT_ARCZ:
38 case SHPT_POLYGONZ:
39 case SHPT_MULTIPOINTZ:
40 case SHPT_MULTIPATCH:
41 if (has_z) *has_z = 1;
42 if (has_m) *has_m = 1;
43 return vtXYZM;
44 default:
45 if (has_z) *has_z = 0;
46 if (has_m) *has_m = 0;
47 return vtInvalid;
48 }
49 }
50
51 /* allocator
52 */
53 static PyObject* shpobject_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
54 {
55 SHPObjectObject* self;
56 self = (SHPObjectObject*) type->tp_alloc(type, 0);
57 self->shpObject = NULL;
58 return (PyObject*) self;
59 }
60
61 /* deallocator
62 */
63 static void shpobject_dealloc(SHPObjectObject* self)
64 {
65 SHPDestroyObject(self->shpObject);
66 self->shpObject = NULL;
67 self->ob_type->tp_free((PyObject*)self);
68 }
69
70 /* The constructor of SHPObject. parts is a list of lists of tuples
71 * describing the parts and their vertices just likethe output of the
72 * vertices() method. part_type_list is the list of part-types and may
73 * be NULL. For the meaning of the part-types and their default value
74 * see the Shaplib documentation.
75 */
76 static int shpobject_init(SHPObjectObject* self, PyObject* args, PyObject* kwds)
77 {
78 int type;
79 int id;
80 PyObject* parts = NULL;
81 PyObject* part_type_list = NULL;
82
83 int num_parts;
84 int num_vertices;
85 int part_start;
86
87 double* xs = NULL;
88 double* ys = NULL;
89 double* zs = NULL;
90 double* ms = NULL;
91 int* part_starts = NULL;
92 int* part_types = NULL;
93
94 PyObject* part;
95 int vertex_type;
96 int has_z;
97 int has_m;
98
99 int i;
100 int ok, return_code = -1;
101
102 /* first, unpack parameters */
103 if (kwds != NULL && PyDict_Size(kwds) > 0)
104 {
105 PyErr_Format(PyExc_TypeError, "shapelib.SHPObject.__init__ takes no keyword arguments");
106 return -1;
107 }
108 if (!PyArg_ParseTuple(args, "iiO|O:__init__", &type, &id, &parts, &part_type_list)) return -1;
109
110 /* check parts */
111 if (!PySequence_Check(parts))
112 {
113 PyErr_SetString(PyExc_TypeError, "parts is not a sequence");
114 return -1;
115 }
116 num_parts = PySequence_Length(parts);
117 if (num_parts < 0)
118 {
119 PyErr_SetString(PyExc_TypeError, "cannot determine length of parts");
120 return -1;
121 }
122
123 /* parts and part_types have to have the same lengths */
124 if (part_type_list == Py_None)
125 {
126 Py_DECREF(part_type_list);
127 part_type_list = NULL;
128 }
129 if (part_type_list)
130 {
131 if (!PySequence_Check(parts))
132 {
133 PyErr_SetString(PyExc_TypeError, "part_type_list is not a sequence");
134 return -1;
135 }
136 if (PySequence_Length(part_type_list) != num_parts)
137 {
138 PyErr_SetString(PyExc_TypeError, "parts and part_types have to have the same lengths");
139 return -1;
140 }
141 }
142
143 /* determine how many vertices there are altogether */
144 num_vertices = 0;
145 for (i = 0; i < num_parts; ++i)
146 {
147 PyObject* part = PySequence_ITEM(parts, i);
148 if (!PySequence_Check(part))
149 {
150 PyErr_SetString(PyExc_TypeError, "at least one item in parts is not a sequence");
151 Py_DECREF(part);
152 return -1;
153 }
154 num_vertices += PySequence_Length(part);
155 Py_DECREF(part);
156 }
157
158
159 vertex_type = determine_vertex_type(type, &has_z, &has_m);
160
161 /* allocate the memory for the various arrays and check for memory errors */
162 xs = malloc(num_vertices * sizeof(double));
163 ys = malloc(num_vertices * sizeof(double));
164 zs = has_z ? malloc(num_vertices * sizeof(double)) : NULL;
165 ms = has_m ? malloc(num_vertices * sizeof(double)) : NULL;
166 part_starts = malloc(num_parts * sizeof(int));
167 part_types = part_type_list ? malloc(num_parts * sizeof(int)) : 0;
168
169 if (!xs || !ys || (has_z && !zs) || (has_m && !ms) || !part_starts || (part_type_list && !part_types))
170 {
171 PyErr_NoMemory();
172 goto exit;
173 }
174
175 /* convert the part types */
176 if (part_type_list)
177 {
178 for (i = 0; i < num_parts; i++)
179 {
180 PyObject* otype = PySequence_ITEM(part_type_list, i);
181 part_types[i] = PyInt_AsLong(otype);
182 Py_DECREF(otype);
183 if (part_types[i] < 0)
184 {
185 PyErr_SetString(PyExc_TypeError, "at least one item in part_type_list is not an integer or is negative");
186 goto exit;
187 }
188 }
189 }
190
191 /* convert the list of parts */
192 part_start = 0;
193 for (i = 0; i < num_parts; ++i)
194 {
195 int j, length;
196
197 part = PySequence_ITEM(parts, i);
198 length = PySequence_Length(part);
199 if (length < 0) goto exit;
200 part_starts[i] = part_start;
201
202 for (j = 0; j < length; ++j)
203 {
204 PyObject* vertex = PySequence_ITEM(part, j);
205 switch (vertex_type)
206 {
207 case vtXY:
208 ok = PyArg_ParseTuple(vertex, "dd:__init__", xs + part_start + j, ys + part_start + j);
209 break;
210 case vtXYM:
211 ok = PyArg_ParseTuple(vertex, "ddd:__init__", xs + part_start + j, ys + part_start + j, ms + part_start + j);
212 break;
213 case vtXYZM:
214 ms[part_start + j] = 0.;
215 ok = PyArg_ParseTuple(vertex, "ddd|d:__init__", xs + part_start + j, ys + part_start + j, zs + part_start + j,
216 ms + part_start + j);
217 break;
218 }
219 Py_DECREF(vertex);
220 if (!ok)
221 {
222 PyErr_SetString(PyExc_TypeError, "at least one vertex is of the wrong format");
223 goto exit;
224 }
225 }
226 Py_DECREF(part);
227 part = NULL;
228 part_start += length;
229 }
230
231 self->shpObject = SHPCreateObject(type, id, num_parts, part_starts, part_types, num_vertices, xs, ys, zs, ms);
232 return_code = 0;
233
234 exit:
235 Py_XDECREF(part);
236 free(xs);
237 free(ys);
238 free(zs);
239 free(ms);
240 free(part_starts);
241 free(part_types);
242 return return_code;
243 }
244
245 /*
246 * The extents() method of SHPObject.
247 *
248 * Return the extents as a tuple of two 4-element lists with the min.
249 * and max. values of x, y, z, m.
250 */
251 static PyObject* shpobject_extents(SHPObjectObject* self)
252 {
253 SHPObject* object = self->shpObject;
254 return Py_BuildValue("(dddd)(dddd)",
255 object->dfXMin, object->dfYMin, object->dfZMin, object->dfMMin,
256 object->dfXMax, object->dfYMax, object->dfZMax, object->dfMMax);
257 }
258
259
260 /*
261 * The vertices() method of SHPObject.
262 *
263 * Return the x and y coords of the vertices as a list of lists of
264 * tuples.
265 */
266
267 static PyObject* build_vertex_list(SHPObject *object, int index, int length, int vertex_type);
268
269 static PyObject* shpobject_vertices(SHPObjectObject* self)
270 {
271 PyObject *result = NULL;
272 PyObject *part = NULL;
273 int part_idx, vertex_idx;
274 int length = 0;
275 int vertex_type;
276
277 SHPObject* object = self->shpObject;
278 vertex_type = determine_vertex_type(object->nSHPType, NULL, NULL);
279
280 if (object->nParts > 0)
281 {
282 /* A multipart shape. Usual for SHPT_ARC and SHPT_POLYGON */
283
284 result = PyList_New(object->nParts);
285 if (!result)
286 return NULL;
287
288 for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts; part_idx++)
289 {
290 if (part_idx < object->nParts - 1)
291 length = (object->panPartStart[part_idx + 1]
292 - object->panPartStart[part_idx]);
293 else
294 length = object->nVertices - object->panPartStart[part_idx];
295
296 part = build_vertex_list(object, vertex_idx, length, vertex_type);
297 if (!part) goto fail;
298
299 if (PyList_SetItem(result, part_idx, part) < 0) goto fail;
300
301 vertex_idx += length;
302 }
303 }
304 else
305 {
306 /* only one part. usual for SHPT_POINT */
307 result = build_vertex_list(object, 0, object->nVertices, vertex_type);
308 }
309
310 return result;
311
312 fail:
313 Py_XDECREF(part);
314 Py_DECREF(result);
315 return NULL;
316 }
317
318
319 /* Return the length coordinates of the shape object starting at vertex
320 * index as a Python-list of tuples. Helper function for
321 * SHPObject_vertices.
322 */
323 static PyObject* build_vertex_list(SHPObject *object, int index, int length, int vertex_type)
324 {
325 int i;
326 PyObject * list;
327 PyObject * vertex = NULL;
328
329 list = PyList_New(length);
330 if (!list)
331 return NULL;
332
333 for (i = 0; i < length; i++, index++)
334 {
335 switch (vertex_type)
336 {
337 case vtXY:
338 vertex = Py_BuildValue("dd", object->padfX[index], object->padfY[index]);
339 break;
340 case vtXYM:
341 vertex = Py_BuildValue("ddd", object->padfX[index], object->padfY[index],
342 object->padfM[index]);
343 case vtXYZM:
344 vertex = Py_BuildValue("dddd", object->padfX[index], object->padfY[index],
345 object->padfZ[index], object->padfM[index]);
346 break;
347 default:
348 goto fail;
349 }
350
351 if (!vertex || PyList_SetItem(list, i, vertex) < 0) goto fail;
352 }
353
354 return list;
355
356 fail:
357 Py_DECREF(list);
358 return NULL;
359 }
360
361
362
363 static PyObject* shpobject_part_types(SHPObjectObject* self)
364 {
365 int i;
366 PyObject* result = NULL;
367 SHPObject* object = self->shpObject;
368
369 if (object->nParts == 0 || object->panPartType == 0)
370 {
371 Py_RETURN_NONE;
372 }
373
374 result = PyTuple_New(object->nParts);
375 if (!result) return NULL;
376
377 for (i = 0; i < object->nParts; ++i)
378 {
379 /* PyTuple_SetItem steals a reference */
380 PyObject* part_type = PyInt_FromLong((long)object->panPartType[i]);
381 if (!part_type || PyTuple_SetItem(result, i, part_type) < 0) goto fail;
382 }
383 return result;
384
385 fail:
386 Py_DECREF(result);
387 return NULL;
388 }
389
390
391
392 static PyObject* shpobject_type(SHPObjectObject* self, void* closure)
393 {
394 return PyInt_FromLong(self->shpObject->nSHPType);
395 }
396
397
398
399 static PyObject* shpobject_id(SHPObjectObject* self, void* closure)
400 {
401 return PyInt_FromLong(self->shpObject->nShapeId);
402 }
403
404
405
406 /* return a string that can be feeded to eval() to reconstruct the object,
407 * assuming a proper context
408 */
409 static PyObject* shpobject_repr(SHPObjectObject* self)
410 {
411 PyObject* format = NULL;
412 PyObject* args = NULL;
413 PyObject* result = NULL;
414
415 format = PyString_FromString("shapelib.SHPObject(%i, %i, %s, %s)");
416 if (!format) return NULL;
417
418 args = Py_BuildValue("iiNN",
419 self->shpObject->nSHPType,
420 self->shpObject->nShapeId,
421 shpobject_vertices(self),
422 shpobject_part_types(self));
423 if (!args)
424 {
425 Py_DECREF(format);
426 return NULL;
427 }
428
429 result = PyString_Format(format, args);
430 Py_DECREF(args);
431 Py_DECREF(format);
432 return result;
433 }
434
435
436
437 static struct PyMethodDef shpobject_methods[] =
438 {
439 {"extents", (PyCFunction)shpobject_extents, METH_NOARGS,
440 "extents()\n"
441 "returns ((x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max)), the 4D bounding box of the SHPObject"},
442 {"vertices", (PyCFunction)shpobject_vertices, METH_NOARGS,
443 "vertices()\n"
444 "returns [[(x, y, ...), ...], ...], a list of object parts, where each part is again a list of vertices.\n"
445 "each vertex is a tuple of two to four doubles, depending on the object type."},
446 {"part_types", (PyCFunction)shpobject_part_types, METH_NOARGS,
447 "part_types()\n"
448 "returns a tuple of integers, each integer indicating the type of the corresponding part in vertices()"},
449 {NULL}
450 };
451
452 static struct PyGetSetDef shpobject_getsetters[] =
453 {
454 {"type", (getter)shpobject_type, NULL, "type of the object (read-only)" },
455 {"id", (getter)shpobject_id, NULL, "id of the object (read-only)" },
456 {NULL}
457 };
458
459 static PyTypeObject SHPObjectType = PYSHAPELIB_DEFINE_TYPE(SHPObjectObject, shpobject, "shapelib.SHPObject", 0);
460
461
462 /* --- ShapeFile ----------------------------------------------------------------------------------------------------- */
463
464 typedef struct
465 {
466 PyObject_HEAD
467 SHPHandle handle;
468 }
469 ShapeFileObject;
470
471 /* allocator
472 */
473 static PyObject* shapefile_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
474 {
475 ShapeFileObject* self;
476 self = (ShapeFileObject*) type->tp_alloc(type, 0);
477 self->handle = NULL;
478 return (PyObject*) self;
479 }
480
481 /* destructor
482 */
483 static void shapefile_dealloc(ShapeFileObject* self)
484 {
485 SHPClose(self->handle);
486 self->ob_type->tp_free((PyObject*)self);
487 }
488
489 /* constructor
490 */
491 static int shapefile_init(ShapeFileObject* self, PyObject* args, PyObject* kwds)
492 {
493 char* file;
494 char* mode = "rb";
495 if (kwds != NULL && PyDict_Size(kwds) > 0)
496 {
497 PyErr_Format(PyExc_TypeError, "shapelib.ShapeFile.__init__ takes no keyword arguments");
498 return -1;
499 }
500 if (!PyArg_ParseTuple(args, "et|s:__init__", Py_FileSystemDefaultEncoding, &file, &mode)) return -1;
501
502 self->handle = SHPOpen(file, mode);
503 return self->handle ? 0 : -1;
504 }
505
506 static PyObject* shapefile_close(ShapeFileObject* self)
507 {
508 SHPClose(self->handle);
509 self->handle = NULL;
510 Py_RETURN_NONE;
511 }
512
513 static PyObject* shapefile_info(ShapeFileObject* self)
514 {
515 SHPHandle handle = self->handle;
516 return Py_BuildValue("ii(dddd)(dddd)",
517 handle->nRecords, handle->nShapeType,
518 handle->adBoundsMin[0], handle->adBoundsMin[1], handle->adBoundsMin[2], handle->adBoundsMin[3],
519 handle->adBoundsMax[0], handle->adBoundsMax[1], handle->adBoundsMax[2], handle->adBoundsMax[3]);
520 }
521
522 static PyObject* shapefile_read_object(ShapeFileObject* self, PyObject* args)
523 {
524 int index;
525 SHPObject* object;
526 SHPObjectObject* result;
527
528 if (!PyArg_ParseTuple(args, "i:read_object", &index)) return NULL;
529
530 object = SHPReadObject(self->handle, index);
531 if (!object)
532 {
533 PyErr_SetString(PyExc_RuntimeError, "failed to read object");
534 return NULL;
535 }
536
537 result = PyObject_New(SHPObjectObject, &SHPObjectType);
538 if (!result)
539 {
540 return PyErr_NoMemory();
541 }
542
543 result->shpObject = object;
544 return (PyObject*) result;
545 }
546
547 static PyObject* shapefile_write_object(ShapeFileObject* self, PyObject* args)
548 {
549 int index, result;
550 PyObject* object;
551
552 if (!PyArg_ParseTuple(args, "iO:write_object", &index, &object)) return NULL;
553
554 if (!PyObject_IsInstance(object, (PyObject*)&SHPObjectType))
555 {
556 PyErr_SetString(PyExc_TypeError, "object is not a SHPObject");
557 return NULL;
558 }
559
560 result = SHPWriteObject(self->handle, index, ((SHPObjectObject*)object)->shpObject);
561 if (result < 0)
562 {
563 PyErr_SetString(PyExc_RuntimeError, "failed to write object");
564 return NULL;
565 }
566 return PyInt_FromLong((long)result);
567 }
568
569 static PyObject* shapefile_cobject(ShapeFileObject* self)
570 {
571 return PyCObject_FromVoidPtr(self->handle, NULL);
572 }
573
574 static PyObject* shapefile_repr(ShapeFileObject* self)
575 {
576 /* TODO: it would be nice to do something like "shapelib.ShapeFile(filename, mode)" instead */
577 return PyString_FromFormat("<shapelib.ShapeFile object at %p>", self->handle);
578 }
579
580 static struct PyMethodDef shapefile_methods[] =
581 {
582 {"close", (PyCFunction)shapefile_close, METH_NOARGS,
583 "close()\n"
584 "close the shape file" },
585 {"info", (PyCFunction)shapefile_info, METH_NOARGS,
586 "info()\n"
587 "returns (num_shapes, type, (x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max)) with:\n"
588 "-num_shapes: the number of the objects in the file\n"
589 "-type: the type of the shape file (SHPT_POINT, SHPT_POLYGON, ...)\n"
590 "-(x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max): 4D bounding box of the data in the shape file" },
591 {"read_object", (PyCFunction)shapefile_read_object, METH_VARARGS,
592 "read_object(id)\n"
593 "Return object indexed by id" },
594 {"write_object", (PyCFunction)shapefile_write_object, METH_VARARGS,
595 "write_object(id, object)\n"
596 "Write an object at index id.\n"
597 "If id == -1, the object is appended at the end of the shape file"},
598 {"cobject", (PyCFunction)shapefile_cobject, METH_NOARGS,
599 "cobject()\n"
600 "Return the shapelib SHPHandle as a Python CObject"},
601 {NULL}
602 };
603
604 static struct PyGetSetDef shapefile_getsetters[] =
605 {
606 {NULL}
607 };
608
609 static PyTypeObject ShapeFileType = PYSHAPELIB_DEFINE_TYPE(ShapeFileObject, shapefile, "shapelib.ShapeFile", 0);
610
611 /* --- shapelib ------------------------------------------------------------------------------------------------------ */
612
613 static PyObject* shapelib_open(PyObject* module, PyObject* args)
614 {
615 return PyObject_CallObject((PyObject*)&ShapeFileType, args);
616 }
617
618 static PyObject* shapelib_create(PyObject* module, PyObject* args)
619 {
620 char* file;
621 int type;
622 ShapeFileObject* result;
623
624 if (!PyArg_ParseTuple(args, "eti:create", Py_FileSystemDefaultEncoding, &file, &type)) return NULL;
625
626 result = PyObject_New(ShapeFileObject, &ShapeFileType);
627 if (!result)
628 {
629 return PyErr_NoMemory();
630 }
631
632 result->handle = SHPCreate(file, type);
633 if (!result->handle)
634 {
635 PyObject_Del((PyObject*)result);
636 PyErr_SetString(PyExc_RuntimeError, "Failed to create ShapeFile");
637 return NULL;
638 }
639
640 return (PyObject*) result;
641 }
642
643 static PyShapeLibAPI shapelib_the_api =
644 {
645 SHPReadObject,
646 SHPDestroyObject,
647 SHPCreateTree,
648 SHPDestroyTree,
649 SHPTreeFindLikelyShapes
650 };
651
652 static PyObject* shapelib_c_api(PyObject* module)
653 {
654 return PyCObject_FromVoidPtr(&shapelib_the_api, NULL);
655 }
656
657 static PyObject* shapelib_type_name(PyObject* module, PyObject* args)
658 {
659 int type;
660 if (!PyArg_ParseTuple(args, "i:type_name", &type)) return NULL;
661 return PyString_FromString(SHPTypeName(type));
662 }
663
664 static PyObject* shapelib_part_type_name(PyObject* module, PyObject* args)
665 {
666 int type;
667 if (!PyArg_ParseTuple(args, "i:part_type_name", &type)) return NULL;
668 return PyString_FromString(SHPPartTypeName(type));
669 }
670
671 static struct PyMethodDef shapelib_methods[] =
672 {
673 {"open", (PyCFunction)shapelib_open, METH_VARARGS,
674 "open(filename [, mode='rb'])\n"
675 "open a ShapeFile" },
676 {"create", (PyCFunction)shapelib_create, METH_VARARGS,
677 "create(filename, type)\n"
678 "create a ShapeFile of a certain type (one of SHPT_POINT, SHPT_POLYGON)" },
679 {"c_api", (PyCFunction)shapelib_c_api, METH_NOARGS,
680 "c_api()\n"
681 "get C API of shapelib" },
682 {"type_name", (PyCFunction)shapelib_type_name, METH_VARARGS,
683 "type_name(type)\n"
684 "return type as string" },
685 {"part_type_name", (PyCFunction)shapelib_part_type_name, METH_VARARGS,
686 "part_type_name(part_type)\n"
687 "return part type as string" },
688 {NULL}
689 };
690
691 PyMODINIT_FUNC initshapelib(void)
692 {
693 PyObject* module = Py_InitModule("shapelib", shapelib_methods);
694 if (!module) return;
695
696 PYSHAPELIB_ADD_TYPE(SHPObjectType, "SHPObject");
697 PYSHAPELIB_ADD_TYPE(ShapeFileType, "ShapeFile");
698
699 PYSHAPELIB_ADD_CONSTANT(SHPT_NULL);
700 PYSHAPELIB_ADD_CONSTANT(SHPT_POINT);
701 PYSHAPELIB_ADD_CONSTANT(SHPT_ARC);
702 PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGON);
703 PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINT);
704 PYSHAPELIB_ADD_CONSTANT(SHPT_POINTZ);
705 PYSHAPELIB_ADD_CONSTANT(SHPT_ARCZ);
706 PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGONZ);
707 PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINTZ);
708 PYSHAPELIB_ADD_CONSTANT(SHPT_POINTM);
709 PYSHAPELIB_ADD_CONSTANT(SHPT_ARCM);
710 PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGONM);
711 PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINTM);
712 PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPATCH);
713 PYSHAPELIB_ADD_CONSTANT(SHPP_TRISTRIP);
714 PYSHAPELIB_ADD_CONSTANT(SHPP_TRIFAN);
715 PYSHAPELIB_ADD_CONSTANT(SHPP_OUTERRING);
716 PYSHAPELIB_ADD_CONSTANT(SHPP_INNERRING);
717 PYSHAPELIB_ADD_CONSTANT(SHPP_FIRSTRING);
718 PYSHAPELIB_ADD_CONSTANT(SHPP_RING);
719 }
720

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26