/*! \file vector/Vlib/simple_features.c \brief Vector library - OGC Simple Features Access Note: In progress. Currently on GV_POINT, GV_LINE are supported. Higher level functions for reading/writing/manipulating vectors. (C) 2009 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS for details. \author Martin Landa */ #include #include #include static int check_sftype(const struct line_pnts *, int, int, int); static int get_sftype(const struct line_pnts *, int, int); static void print_point(const struct line_pnts *, int, int, int, FILE *); /*! \brief Get SF type of given vector feature List of supported feature types: - GV_POINT -> SF_POINT - GV_LINE -> SF_LINE / SF_LINESTRING / SF_LINEARRING \param Points pointer to line_pnts structure \param type feature type (GV_POINT, GV_LINE, ...) \param with_z non-zero value for 3D data \return SF type identificator (see list of supported types) \return -1 on error */ int Vect_sfa_get_line_type(const struct line_pnts *Points, int type, int with_z) { return get_sftype(Points, type, with_z); } /*! \brief Check SF type E.g. if type is GV_LINE with two or more segments and the start node is identical with the end node, and sftype is SF_LINEARRING, functions returns 1, otherwise 0. \param Points pointer to line_pnts structure \param type feature type (GV_POINT, GV_LINE, ...) \param sftype SF type to be checked (SF_POINT, SF_LINE, ...) \param with_z non-zero value for 3D data \return 1 if type is sftype \return 0 type differs from sftype */ int Vect_sfa_check_line_type(const struct line_pnts *Points, int type, int sftype, int with_z) { return check_sftype(Points, type, sftype, with_z); } /*! \brief Print feature in Well-Known Text format \param Points pointer to line_pnts structure \param type feature type \param with_z non-zero value for 3D data \param precision floating number precision \param[out] file file where to write the output */ void Vect_sfa_write_line_wkt(const struct line_pnts *Points, int type, int with_z, int precision, FILE *file) { int sftype; sftype = Vect_sfa_get_line_type(Points, type, with_z); switch(sftype) { case SF_POINT: { fprintf(file, "POINT("); print_point(Points, 0, with_z, precision, file); fprintf(file, ")\n"); break; } case SF_LINESTRING: case SF_LINE: case SF_LINEARRING: { int i; if (sftype == SF_LINESTRING) fprintf(file, "LINESTRING("); else if (sftype == SF_LINE) fprintf(file, "LINE("); else fprintf(file, "LINEARRING("); for (i = 0; i < Points->n_points; i++) { print_point(Points, i, with_z, precision, file); if (i < Points->n_points - 1) fprintf(file, ", "); } fprintf(file, ")\n"); break; } default: { G_warning(_("Unknown Simple Features type (%d)"), sftype); break; } } fflush(file); } int check_sftype(const struct line_pnts *points, int type, int sftype, int with_z) { if (type == GV_POINT && sftype == SF_POINT) { return 1; } if (type == GV_LINE) { if (sftype == SF_LINESTRING) { return 1; } if (sftype == SF_LINE && Vect_get_num_line_points(points) == 2) { return 1; } if (sftype == SF_LINEARRING) { int num = Vect_get_num_line_points(points); if (points->x[0] == points->x[num-1] && points->y[0] == points->y[num-1]) { if (!with_z) { return 1; } else if (points->z[0] == points->z[num-1]) { return 1; } } } } return 0; } int get_sftype(const struct line_pnts *points, int type, int with_z) { if (check_sftype(points, type, SF_POINT, with_z)) return SF_POINT; if (check_sftype(points, type, SF_LINE, with_z)) return SF_LINE; if (check_sftype(points, type, SF_LINEARRING, with_z)) return SF_LINEARRING; if (check_sftype(points, type, SF_LINESTRING, with_z)) return SF_LINESTRING; return -1; } void print_point(const struct line_pnts *Points, int index, int with_z, int precision, FILE *file) { fprintf(file, "%.*f %.*f", precision, Points->x[index], precision, Points->y[index]); if (with_z) fprintf(file, " %.*f", precision, Points->z[index]); }