23 #include <grass/gis.h>
24 #include <grass/Vect.h>
25 #include <grass/glocale.h>
76 (
int *)G_realloc((
void *)parts->
part,
90 static void add_parts_to_offset(
struct Map_info *
Map,
GEOM_PARTS * parts)
94 if (Map->fInfo.ogr.offset_num + parts->
n_parts >=
95 Map->fInfo.ogr.offset_alloc) {
96 Map->fInfo.ogr.offset_alloc += parts->
n_parts + 1000;
97 Map->fInfo.ogr.offset = (
int *)G_realloc(Map->fInfo.ogr.offset,
98 Map->fInfo.ogr.offset_alloc *
101 j = Map->fInfo.ogr.offset_num;
102 for (i = 0; i < parts->
n_parts; i++) {
104 Map->fInfo.ogr.offset[j] = parts->
part[i];
107 Map->fInfo.ogr.offset_num += parts->
n_parts;
111 static int add_line(
struct Map_info *Map,
int type,
struct line_pnts *Points,
115 struct Plus_head *plus;
121 if (type != GV_CENTROID) {
122 offset = Map->fInfo.ogr.offset_num;
128 G_debug(4,
"Register line: FID = %d offset = %ld", FID, offset);
130 G_debug(4,
"Line registered with line = %d", line);
139 if (type != GV_BOUNDARY) {
146 if (type != GV_CENTROID)
147 add_parts_to_offset(Map, parts);
153 static int add_geometry(
struct Map_info *Map, OGRGeometryH hGeom,
int FID,
156 struct Plus_head *plus;
159 int area, isle, outer_area = 0;
161 static struct line_pnts **Points =
NULL;
162 static int alloc_points = 0;
165 double area_size, x,
y;
166 int eType, nRings, iPart, nParts, nPoints;
167 OGRGeometryH hGeom2, hRing;
169 G_debug(4,
"add_geometry() FID = %d", FID);
174 Points = (
struct line_pnts **)G_malloc(
sizeof(
struct line_pnts *));
179 eType = wkbFlatten(OGR_G_GetGeometryType(hGeom));
180 G_debug(4,
"OGR type = %d", eType);
186 OGR_G_GetY(hGeom, 0), OGR_G_GetZ(hGeom, 0));
187 add_line(Map, GV_POINT, Points[0], FID, parts);
192 nPoints = OGR_G_GetPointCount(hGeom);
193 for (i = 0; i < nPoints; i++) {
195 OGR_G_GetX(hGeom, i), OGR_G_GetY(hGeom, i),
196 OGR_G_GetZ(hGeom, i));
198 add_line(Map, GV_LINE, Points[0], FID, parts);
204 nRings = OGR_G_GetGeometryCount(hGeom);
205 G_debug(4,
"Number of rings: %d", nRings);
208 if (nRings >= alloc_points) {
209 Points = (
struct line_pnts **)G_realloc((
void *)Points,
211 sizeof(
struct line_pnts
213 for (i = alloc_points; i < nRings; i++) {
218 for (iPart = 0; iPart < nRings; iPart++) {
219 hRing = OGR_G_GetGeometryRef(hGeom, iPart);
220 nPoints = OGR_G_GetPointCount(hRing);
221 G_debug(4,
" ring %d : nPoints = %d", iPart, nPoints);
225 for (i = 0; i < nPoints; i++) {
227 OGR_G_GetX(hRing, i), OGR_G_GetY(hRing, i),
228 OGR_G_GetZ(hRing, i));
233 line = add_line(Map, GV_BOUNDARY, Points[iPart], FID, parts);
249 lines[0] = -lines[0];
260 Isle = plus->Isle[isle];
261 Isle->area = outer_area;
272 G_warning(_(
"Unable to calculate centroid for area %d"),
278 G_debug(4,
" Centroid: %f, %f", x, y);
281 line = add_line(Map, GV_CENTROID, Points[0], FID, parts);
285 Line = plus->Line[line];
286 Line->left = outer_area;
289 Area = plus->Area[outer_area];
290 Area->centroid = line;
295 case wkbMultiLineString:
296 case wkbMultiPolygon:
297 case wkbGeometryCollection:
298 nParts = OGR_G_GetGeometryCount(hGeom);
299 G_debug(4,
"%d geoms -> next level", nParts);
300 for (i = 0; i < nParts; i++) {
302 hGeom2 = OGR_G_GetGeometryRef(hGeom, i);
303 add_geometry(Map, hGeom2, FID, parts);
309 G_warning(_(
"OGR feature type %d not supported"), eType);
327 int iFeature,
count, FID;
329 OGRFeatureH hFeature;
332 if (build != GV_BUILD_ALL)
336 Map->fInfo.ogr.offset =
NULL;
337 Map->fInfo.ogr.offset_num = 0;
338 Map->fInfo.ogr.offset_alloc = 0;
341 if (!OGR_L_TestCapability(Map->fInfo.ogr.layer, OLCRandomRead)) {
342 G_warning(_(
"Random read is not supported by OGR for this layer, cannot build support"));
351 OGR_L_ResetReading(Map->fInfo.ogr.layer);
352 count = iFeature = 0;
353 while ((hFeature = OGR_L_GetNextFeature(Map->fInfo.ogr.layer)) !=
NULL) {
357 G_debug(4,
"---- Feature %d ----", iFeature);
359 hGeom = OGR_F_GetGeometryRef(hFeature);
361 G_warning(_(
"Feature %d without geometry ignored"), iFeature);
362 OGR_F_Destroy(hFeature);
366 FID = (
int)OGR_F_GetFID(hFeature);
367 if (FID == OGRNullFID) {
368 G_warning(_(
"OGR feature without ID ignored"));
369 OGR_F_Destroy(hFeature);
376 add_geometry(Map, hGeom, FID, &parts);
378 OGR_F_Destroy(hFeature);
382 Map->plus.built = GV_BUILD_ALL;
int dig_line_box(struct line_pnts *Points, BOUND_BOX *Box)
struct line_pnts * Vect_new_line_struct()
Creates and initializes a struct line_pnts.
int dig_add_line(struct Plus_head *plus, int type, struct line_pnts *Points, long offset)
Add new line to Plus_head structure.
int Vect_build_ogr(struct Map_info *Map, int build)
Build topology.
int Vect_reset_line(struct line_pnts *Points)
Reset line.
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_box_extend(BOUND_BOX *A, BOUND_BOX *B)
Extend box A by box B.
int dig_area_add_isle(struct Plus_head *plus, int area, int isle)
Add isle to area if does not exist yet.
void G_verbose_message(const char *msg,...)
Print a message to stderr but only if module is in verbose mode.
int dig_cidx_add_cat(struct Plus_head *Plus, int field, int cat, int line, int type)
int Vect_get_point_in_poly_isl(struct line_pnts *Points, struct line_pnts **IPoints, int n_isles, double *att_x, double *att_y)
Get point inside polygon but outside the islands specifiled in IPoints.
int dig_isle_set_box(struct Plus_head *plus, plus_t isle, BOUND_BOX *Box)
Set isle bounding box.
int Vect_box_copy(BOUND_BOX *A, BOUND_BOX *B)
Copy box B to box A.
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 dig_find_area_poly(struct line_pnts *Points, double *totalarea)
int dig_area_set_box(struct Plus_head *plus, plus_t area, BOUND_BOX *Box)
Set area bounding box.
int G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
int dig_add_isle(struct Plus_head *plus, int n_lines, plus_t *lines)
Allocate space for new island and create boundary info from array.
void add_part(SYMBOL *s, SYMBPART *p)
int dig_add_area(struct Plus_head *plus, int n_lines, plus_t *lines)
Allocate space for new area and create boundary info from array.
int dig_line_set_box(struct Plus_head *plus, plus_t line, BOUND_BOX *Box)
Set line bounding box.