GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
read_ogr.c
Go to the documentation of this file.
1 
20 #include <grass/gis.h>
21 #include <grass/Vect.h>
22 #include <grass/glocale.h>
23 
24 #ifdef HAVE_OGR
25 #include <ogr_api.h>
26 
39 static int cache_feature(struct Map_info *Map, OGRGeometryH hGeom, int ftype)
40 {
41  int line, i, np, ng, tp;
42  OGRwkbGeometryType type;
43  OGRGeometryH hGeom2;
44 
45  G_debug(4, "cache_feature");
46 
47  /* Alloc space */
48  line = Map->fInfo.ogr.lines_num;
49  if (line == Map->fInfo.ogr.lines_alloc) {
50  Map->fInfo.ogr.lines_alloc += 20;
51  Map->fInfo.ogr.lines =
52  (struct line_pnts **)G_realloc((void *)Map->fInfo.ogr.lines,
53  Map->fInfo.ogr.lines_alloc *
54  sizeof(struct line_pnts *));
55 
56  Map->fInfo.ogr.lines_types =
57  (int *)G_realloc(Map->fInfo.ogr.lines_types,
58  Map->fInfo.ogr.lines_alloc * sizeof(int));
59 
60  for (i = Map->fInfo.ogr.lines_num; i < Map->fInfo.ogr.lines_alloc;
61  i++)
62  Map->fInfo.ogr.lines[i] = Vect_new_line_struct();
63 
64  }
65  Vect_reset_line(Map->fInfo.ogr.lines[line]);
66 
67  type = wkbFlatten(OGR_G_GetGeometryType(hGeom));
68 
69  switch (type) {
70  case wkbPoint:
71  G_debug(4, "Point");
72  Vect_append_point(Map->fInfo.ogr.lines[line],
73  OGR_G_GetX(hGeom, 0), OGR_G_GetY(hGeom, 0),
74  OGR_G_GetZ(hGeom, 0));
75  Map->fInfo.ogr.lines_types[line] = GV_POINT;
76  Map->fInfo.ogr.lines_num++;
77  return 0;
78  break;
79 
80  case wkbLineString:
81  G_debug(4, "LineString");
82  np = OGR_G_GetPointCount(hGeom);
83  for (i = 0; i < np; i++) {
84  Vect_append_point(Map->fInfo.ogr.lines[line],
85  OGR_G_GetX(hGeom, i), OGR_G_GetY(hGeom, i),
86  OGR_G_GetZ(hGeom, i));
87  }
88 
89  if (ftype > 0) { /* Polygon rings */
90  Map->fInfo.ogr.lines_types[line] = ftype;
91  }
92  else {
93  Map->fInfo.ogr.lines_types[line] = GV_LINE;
94  }
95  Map->fInfo.ogr.lines_num++;
96  return 0;
97  break;
98 
99  case wkbMultiPoint:
100  case wkbMultiLineString:
101  case wkbPolygon:
102  case wkbMultiPolygon:
103  case wkbGeometryCollection:
104  ng = OGR_G_GetGeometryCount(hGeom);
105  G_debug(4, "%d geoms -> next level", ng);
106  if (type == wkbPolygon) {
107  tp = GV_BOUNDARY;
108  }
109  else {
110  tp = -1;
111  }
112  for (i = 0; i < ng; i++) {
113  hGeom2 = OGR_G_GetGeometryRef(hGeom, i);
114  cache_feature(Map, hGeom2, tp);
115  }
116  return 0;
117  break;
118 
119  default:
120  G_warning(_("OGR feature type %d not supported"), type);
121  return 1;
122  break;
123  }
124 }
125 
142 int
143 V1_read_next_line_ogr(struct Map_info *Map, struct line_pnts *line_p,
144  struct line_cats *line_c)
145 {
146  int itype;
147  BOUND_BOX lbox, mbox;
148  OGRFeatureH hFeature;
149  OGRGeometryH hGeom;
150 
151  G_debug(3, "V1_read_next_line_ogr()");
152 
153  if (line_p != NULL)
154  Vect_reset_line(line_p);
155  if (line_c != NULL)
156  Vect_reset_cats(line_c);
157 
158  if (Map->Constraint_region_flag)
159  Vect_get_constraint_box(Map, &mbox);
160 
161  while (1) {
162  /* Read feature to chache if necessary */
163  while (Map->fInfo.ogr.lines_next == Map->fInfo.ogr.lines_num) {
164  hFeature = OGR_L_GetNextFeature(Map->fInfo.ogr.layer);
165 
166  if (hFeature == NULL) {
167  return -2;
168  } /* no more features */
169 
170  hGeom = OGR_F_GetGeometryRef(hFeature);
171  if (hGeom == NULL) { /* feature without geometry */
172  OGR_F_Destroy(hFeature);
173  continue;
174  }
175 
176  Map->fInfo.ogr.feature_cache_id = (int)OGR_F_GetFID(hFeature);
177  if (Map->fInfo.ogr.feature_cache_id == OGRNullFID) {
178  G_warning(_("OGR feature without ID"));
179  }
180 
181  /* Cache the feature */
182  Map->fInfo.ogr.lines_num = 0;
183  cache_feature(Map, hGeom, -1);
184  G_debug(4, "%d lines read to cache", Map->fInfo.ogr.lines_num);
185  OGR_F_Destroy(hFeature);
186 
187  Map->fInfo.ogr.lines_next = 0; /* next to be read from cache */
188  }
189 
190  /* Read next part of the feature */
191  G_debug(4, "read next cached line %d", Map->fInfo.ogr.lines_next);
192  itype = Map->fInfo.ogr.lines_types[Map->fInfo.ogr.lines_next];
193 
194  /* Constraint on Type of line
195  * Default is all of Point, Line, Area and whatever else comes along
196  */
197  if (Map->Constraint_type_flag) {
198  if (!(itype & Map->Constraint_type)) {
199  Map->fInfo.ogr.lines_next++;
200  continue;
201  }
202  }
203 
204  /* Constraint on specified region */
205  if (Map->Constraint_region_flag) {
206  Vect_line_box(Map->fInfo.ogr.lines[Map->fInfo.ogr.lines_next],
207  &lbox);
208 
209  if (!Vect_box_overlap(&lbox, &mbox)) {
210  Map->fInfo.ogr.lines_next++;
211  continue;
212  }
213  }
214 
215  if (line_p != NULL)
216  Vect_append_points(line_p,
217  Map->fInfo.ogr.lines[Map->fInfo.ogr.
218  lines_next], GV_FORWARD);
219 
220  if (line_c != NULL && Map->fInfo.ogr.feature_cache_id != OGRNullFID)
221  Vect_cat_set(line_c, 1, Map->fInfo.ogr.feature_cache_id);
222 
223  Map->fInfo.ogr.lines_next++;
224  G_debug(4, "next line read, type = %d", itype);
225  return (itype);
226  }
227  return -2; /* not reached */
228 }
229 
241 int
242 V2_read_next_line_ogr(struct Map_info *Map, struct line_pnts *line_p,
243  struct line_cats *line_c)
244 {
245  if (Map->next_line > Map->plus.n_lines)
246  return -2;
247 
248  return V2_read_line_ogr(Map, line_p, line_c, Map->next_line++);
249 }
250 
262 static int read_line(struct Map_info *Map, OGRGeometryH hGeom, long offset,
263  struct line_pnts *Points)
264 {
265  int i, nPoints;
266  int eType;
267  OGRGeometryH hGeom2;
268 
269  /* Read coors if hGeom is a simple element (wkbPoint, wkbLineString) otherwise
270  * descend to geometry specified by offset[offset] */
271 
272  G_debug(4, "read_line() offset = %ld", offset);
273 
274  eType = wkbFlatten(OGR_G_GetGeometryType(hGeom));
275  G_debug(4, "OGR Geometry of type: %d", eType);
276 
277  switch (eType) {
278  case wkbPoint:
279  G_debug(4, "Point");
280  Vect_append_point(Points, OGR_G_GetX(hGeom, 0), OGR_G_GetY(hGeom, 0),
281  OGR_G_GetZ(hGeom, 0));
282  return 0;
283  break;
284 
285  case wkbLineString:
286  G_debug(4, "LineString");
287  nPoints = OGR_G_GetPointCount(hGeom);
288  for (i = 0; i < nPoints; i++) {
289  Vect_append_point(Points, OGR_G_GetX(hGeom, i),
290  OGR_G_GetY(hGeom, i), OGR_G_GetZ(hGeom, i));
291  }
292  return 0;
293  break;
294 
295  case wkbPolygon:
296  case wkbMultiPoint:
297  case wkbMultiLineString:
298  case wkbMultiPolygon:
299  case wkbGeometryCollection:
300  G_debug(4, " more geoms -> part %d", Map->fInfo.ogr.offset[offset]);
301  hGeom2 = OGR_G_GetGeometryRef(hGeom, Map->fInfo.ogr.offset[offset]);
302  return (read_line(Map, hGeom2, offset + 1, Points));
303  break;
304 
305  default:
306  G_warning(_("OGR feature type %d not supported"), eType);
307  break;
308  }
309  return 1;
310 }
311 
324 int
325 V2_read_line_ogr(struct Map_info *Map, struct line_pnts *line_p,
326  struct line_cats *line_c, int line)
327 {
328  int node;
329  int offset;
330  long FID;
331  P_LINE *Line;
332  P_NODE *Node;
333  OGRGeometryH hGeom;
334 
335  G_debug(4, "V2_read_line_ogr() line = %d", line);
336 
337  if (line_p != NULL)
338  Vect_reset_line(line_p);
339  if (line_c != NULL)
340  Vect_reset_cats(line_c);
341 
342  Line = Map->plus.Line[line];
343  offset = (int)Line->offset;
344 
345  if (Line->type == GV_CENTROID) {
346  G_debug(4, "Centroid");
347  node = Line->N1;
348  Node = Map->plus.Node[node];
349 
350  /* coordinates */
351  if (line_p != NULL) {
352  Vect_append_point(line_p, Node->x, Node->y, 0.0);
353  }
354 
355  /* category */
356  if (line_c != NULL) {
357  /* cat = FID and offset = FID for centroid */
358  Vect_cat_set(line_c, 1, (int)offset);
359  }
360 
361  return (GV_CENTROID);
362  }
363  else {
364  FID = Map->fInfo.ogr.offset[offset];
365  G_debug(4, " FID = %ld", FID);
366 
367  /* coordinates */
368  if (line_p != NULL) {
369  /* Read feature to cache if necessary */
370  if (Map->fInfo.ogr.feature_cache_id != FID) {
371  G_debug(4, "Read feature (FID = %ld) to cache.", FID);
372  if (Map->fInfo.ogr.feature_cache) {
373  OGR_F_Destroy(Map->fInfo.ogr.feature_cache);
374  }
375  Map->fInfo.ogr.feature_cache =
376  OGR_L_GetFeature(Map->fInfo.ogr.layer, FID);
377  if (Map->fInfo.ogr.feature_cache == NULL) {
378  G_fatal_error(_("Unable to get feature geometry, FID %ld"),
379  FID);
380  }
381  Map->fInfo.ogr.feature_cache_id = FID;
382  }
383 
384  hGeom = OGR_F_GetGeometryRef(Map->fInfo.ogr.feature_cache);
385  if (hGeom == NULL) {
386  G_fatal_error(_("Unable to get feature geometry, FID %ld"),
387  FID);
388  }
389 
390  read_line(Map, hGeom, Line->offset + 1, line_p);
391  }
392 
393  /* category */
394  if (line_c != NULL) {
395  Vect_cat_set(line_c, 1, (int)FID);
396  }
397 
398  return Line->type;
399  }
400 
401  return -2; /* not reached */
402 }
403 
404 #endif
int Vect_line_box(struct line_pnts *Points, BOUND_BOX *Box)
Get bounding box of line.
Definition: line.c:771
int Vect_get_constraint_box(struct Map_info *Map, BOUND_BOX *Box)
Get constraint box.
Definition: constraint.c:81
int V2_read_next_line_ogr(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c)
Read next line from OGR layer.
Definition: read_ogr.c:242
struct line_pnts * Vect_new_line_struct()
Creates and initializes a struct line_pnts.
Definition: line.c:57
Definition: index.h:56
int Vect_box_overlap(BOUND_BOX *A, BOUND_BOX *B)
Tests for overlap of two boxes.
Definition: Vlib/box.c:53
int Vect_append_points(struct line_pnts *Points, struct line_pnts *APoints, int direction)
Appends points to the end of a line.
Definition: line.c:312
int Vect_reset_line(struct line_pnts *Points)
Reset line.
Definition: line.c:148
int Vect_reset_cats(struct line_cats *Cats)
Reset category structure to make sure cats structure is clean to be re-used.
int Vect_append_point(struct line_pnts *Points, double x, double y, double z)
Appends one point to the end of a line.
Definition: line.c:168
int Vect_cat_set(struct line_cats *Cats, int field, int cat)
Add new field/cat to category structure if doesn&#39;t exist yet.
int V2_read_line_ogr(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, int line)
Read line from layer on given offset.
Definition: read_ogr.c:325
int
Definition: g3dcolor.c:48
int V1_read_next_line_ogr(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c)
Read next line from OGR layer. Skip empty features.
Definition: read_ogr.c:143
if(!YY_CURRENT_BUFFER)
Definition: lex.yy.c:799
return NULL
Definition: dbfopen.c:1394
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
tuple Map
Definition: render.py:1310
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.