20 #include <grass/gis.h>
21 #include <grass/Vect.h>
22 #include <grass/glocale.h>
39 static int cache_feature(
struct Map_info *
Map, OGRGeometryH hGeom,
int ftype)
41 int line, i, np, ng, tp;
42 OGRwkbGeometryType
type;
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 *));
56 Map->fInfo.ogr.lines_types =
57 (
int *)G_realloc(Map->fInfo.ogr.lines_types,
58 Map->fInfo.ogr.lines_alloc *
sizeof(
int));
60 for (i = Map->fInfo.ogr.lines_num; i < Map->fInfo.ogr.lines_alloc;
67 type = wkbFlatten(OGR_G_GetGeometryType(hGeom));
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++;
82 np = OGR_G_GetPointCount(hGeom);
83 for (i = 0; i < np; i++) {
85 OGR_G_GetX(hGeom, i), OGR_G_GetY(hGeom, i),
86 OGR_G_GetZ(hGeom, i));
90 Map->fInfo.ogr.lines_types[line] = ftype;
93 Map->fInfo.ogr.lines_types[line] = GV_LINE;
95 Map->fInfo.ogr.lines_num++;
100 case wkbMultiLineString:
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) {
112 for (i = 0; i < ng; i++) {
113 hGeom2 = OGR_G_GetGeometryRef(hGeom, i);
114 cache_feature(Map, hGeom2, tp);
120 G_warning(_(
"OGR feature type %d not supported"), type);
144 struct line_cats *line_c)
147 BOUND_BOX lbox, mbox;
148 OGRFeatureH hFeature;
151 G_debug(3,
"V1_read_next_line_ogr()");
158 if (Map->Constraint_region_flag)
163 while (Map->fInfo.ogr.lines_next == Map->fInfo.ogr.lines_num) {
164 hFeature = OGR_L_GetNextFeature(Map->fInfo.ogr.layer);
166 if (hFeature ==
NULL) {
170 hGeom = OGR_F_GetGeometryRef(hFeature);
172 OGR_F_Destroy(hFeature);
176 Map->fInfo.ogr.feature_cache_id = (
int)OGR_F_GetFID(hFeature);
177 if (Map->fInfo.ogr.feature_cache_id == OGRNullFID) {
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);
187 Map->fInfo.ogr.lines_next = 0;
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];
197 if (Map->Constraint_type_flag) {
198 if (!(itype & Map->Constraint_type)) {
199 Map->fInfo.ogr.lines_next++;
205 if (Map->Constraint_region_flag) {
206 Vect_line_box(Map->fInfo.ogr.lines[Map->fInfo.ogr.lines_next],
210 Map->fInfo.ogr.lines_next++;
217 Map->fInfo.ogr.lines[Map->fInfo.ogr.
218 lines_next], GV_FORWARD);
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);
223 Map->fInfo.ogr.lines_next++;
224 G_debug(4,
"next line read, type = %d", itype);
243 struct line_cats *line_c)
245 if (Map->next_line > Map->plus.n_lines)
262 static int read_line(
struct Map_info *Map, OGRGeometryH hGeom,
long offset,
263 struct line_pnts *Points)
272 G_debug(4,
"read_line() offset = %ld", offset);
274 eType = wkbFlatten(OGR_G_GetGeometryType(hGeom));
275 G_debug(4,
"OGR Geometry of type: %d", eType);
281 OGR_G_GetZ(hGeom, 0));
287 nPoints = OGR_G_GetPointCount(hGeom);
288 for (i = 0; i < nPoints; i++) {
290 OGR_G_GetY(hGeom, i), OGR_G_GetZ(hGeom, i));
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));
306 G_warning(_(
"OGR feature type %d not supported"), eType);
326 struct line_cats *line_c,
int line)
335 G_debug(4,
"V2_read_line_ogr() line = %d", line);
342 Line = Map->plus.Line[line];
343 offset = (
int)Line->offset;
345 if (Line->type == GV_CENTROID) {
348 Node = Map->plus.Node[node];
351 if (line_p !=
NULL) {
356 if (line_c !=
NULL) {
361 return (GV_CENTROID);
364 FID = Map->fInfo.ogr.offset[offset];
368 if (line_p !=
NULL) {
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);
375 Map->fInfo.ogr.feature_cache =
376 OGR_L_GetFeature(Map->fInfo.ogr.layer, FID);
377 if (Map->fInfo.ogr.feature_cache ==
NULL) {
381 Map->fInfo.ogr.feature_cache_id = FID;
384 hGeom = OGR_F_GetGeometryRef(Map->fInfo.ogr.feature_cache);
390 read_line(Map, hGeom, Line->offset + 1, line_p);
394 if (line_c !=
NULL) {
int Vect_line_box(struct line_pnts *Points, BOUND_BOX *Box)
Get bounding box of line.
int Vect_get_constraint_box(struct Map_info *Map, BOUND_BOX *Box)
Get constraint box.
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.
struct line_pnts * Vect_new_line_struct()
Creates and initializes a struct line_pnts.
int Vect_box_overlap(BOUND_BOX *A, BOUND_BOX *B)
Tests for overlap of two boxes.
int Vect_append_points(struct line_pnts *Points, struct line_pnts *APoints, int direction)
Appends points to the end of a line.
int Vect_reset_line(struct line_pnts *Points)
Reset line.
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.
int Vect_cat_set(struct line_cats *Cats, int field, int cat)
Add new field/cat to category structure if doesn'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.
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.
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int G_debug(int level, const char *msg,...)
Print debugging message.
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.