/** * \file plus.c * * \brief Vector library - update topo structure (lower level functions) * * Lower level functions for reading/writing/manipulating vectors. * * This program is free software under the GNU General Public License * (>=v2). Read the file COPYING that comes with GRASS for details. * * \author CERL (probably Dave Gerdes), Radim Blazek * * \date 2001-2006 */ #include #include #include #include #include #include /*! * \brief Initialize Plus_head structure * * \param[in,out] Plus pointer to Plus_head structure * * \return 1 */ int dig_init_plus(struct Plus_head *Plus) { G_debug(3, "dig_init_plus()"); G_zero(Plus, sizeof(struct Plus_head)); Plus->built = GV_BUILD_NONE; dig_spidx_init(Plus); dig_cidx_init(Plus); return 1; } /*! * \brief Free Plus->Node structure * * \param[in] Plus pointer to Plus_head structure */ void dig_free_plus_nodes(struct Plus_head *Plus) { int i; struct P_node *Node; G_debug(2, "dig_free_plus_nodes()"); /* Nodes */ if (Plus->Node) { /* it may be that header only is loaded */ for (i = 1; i <= Plus->n_nodes; i++) { Node = Plus->Node[i]; if (Node == NULL) continue; dig_free_node(Node); } G_free(Plus->Node); } Plus->Node = NULL; Plus->n_nodes = 0; Plus->alloc_nodes = 0; } /*! * \brief Free Plus->Line structure * * \param[in] Plus pointer to Plus_head structure */ void dig_free_plus_lines(struct Plus_head *Plus) { int i; struct P_line *Line; G_debug(2, "dig_free_plus_lines()"); /* Lines */ if (Plus->Line) { /* it may be that header only is loaded */ for (i = 1; i <= Plus->n_lines; i++) { Line = Plus->Line[i]; if (Line == NULL) continue; dig_free_line(Line); } G_free(Plus->Line); } Plus->Line = NULL; Plus->n_lines = 0; Plus->alloc_lines = 0; Plus->n_plines = 0; Plus->n_llines = 0; Plus->n_blines = 0; Plus->n_clines = 0; Plus->n_flines = 0; Plus->n_klines = 0; } /*! * \brief Free Plus->Area structure * * \param[in] Plus pointer to Plus_head structure */ void dig_free_plus_areas(struct Plus_head *Plus) { int i; struct P_area *Area; G_debug(2, "dig_free_plus_areas()"); /* Areas */ if (Plus->Area) { /* it may be that header only is loaded */ for (i = 1; i <= Plus->n_areas; i++) { Area = Plus->Area[i]; if (Area == NULL) continue; dig_free_area(Area); } G_free(Plus->Area); } Plus->Area = NULL; Plus->n_areas = 0; Plus->alloc_areas = 0; } /*! * \brief Free Plus->Isle structure * * \param[in] Plus pointer to Plus_head structure */ void dig_free_plus_isles(struct Plus_head *Plus) { int i; struct P_isle *Isle; G_debug(2, "dig_free_plus_isles()"); /* Isles */ if (Plus->Isle) { /* it may be that header only is loaded */ for (i = 1; i <= Plus->n_isles; i++) { Isle = Plus->Isle[i]; if (Isle == NULL) continue; dig_free_isle(Isle); } G_free(Plus->Isle); } Plus->Isle = NULL; Plus->n_isles = 0; Plus->alloc_isles = 0; } /*! * \brief Free Plus structure. * * Structure is not inited and dig_init_plus() should follow. * * \param[in] Plus pointer to Plus_head structure */ void dig_free_plus(struct Plus_head *Plus) { G_debug(2, "dig_free_plus()"); dig_free_plus_nodes(Plus); dig_free_plus_lines(Plus); dig_free_plus_areas(Plus); dig_free_plus_isles(Plus); dig_spidx_free(Plus); dig_cidx_free(Plus); } /*! * \brief Reads topo file to topo structure. * * \param[in,out] Plus pointer to Plus_head structure * \param[in] plus topo file * \param[in] head_only read only head * * \return 1 on success * \return 0 on error */ int dig_load_plus(struct Plus_head *Plus, struct gvfile * plus, int head_only) { int i; G_debug(1, "dig_load_plus()"); /* TODO if (do_checks) dig_do_file_checks (map, map->plus_file, map->digit_file); */ /* free and init old */ dig_free_plus(Plus); dig_init_plus(Plus); /* Now let's begin reading the Plus file nodes, lines, areas and isles */ if (dig_Rd_Plus_head(plus, Plus) == -1) return 0; if (head_only) return 1; dig_set_cur_port(&(Plus->port)); /* Nodes */ if (dig_fseek(plus, Plus->Node_offset, 0) == -1) G_fatal_error(_("Unable read topology for nodes")); dig_alloc_nodes(Plus, Plus->n_nodes); for (i = 1; i <= Plus->n_nodes; i++) { if (dig_Rd_P_node(Plus, i, plus) == -1) G_fatal_error(_("Unable to read topology for node %d"), i); } /* Lines */ if (dig_fseek(plus, Plus->Line_offset, 0) == -1) G_fatal_error(_("Unable read topology for lines")); dig_alloc_lines(Plus, Plus->n_lines); for (i = 1; i <= Plus->n_lines; i++) { if (dig_Rd_P_line(Plus, i, plus) == -1) G_fatal_error(_("Unable to read topology for line %d"), i); } /* Areas */ if (dig_fseek(plus, Plus->Area_offset, 0) == -1) G_fatal_error(_("Unable to read topo for areas")); dig_alloc_areas(Plus, Plus->n_areas); for (i = 1; i <= Plus->n_areas; i++) { if (dig_Rd_P_area(Plus, i, plus) == -1) G_fatal_error(_("Unable read topology for area %d"), i); } /* Isles */ if (dig_fseek(plus, Plus->Isle_offset, 0) == -1) G_fatal_error(_("Unable to read topology for isles")); dig_alloc_isles(Plus, Plus->n_isles); for (i = 1; i <= Plus->n_isles; i++) { if (dig_Rd_P_isle(Plus, i, plus) == -1) G_fatal_error(_("Unable to read topology for isle %d"), i); } return (1); } /*! * \brief Writes topo structure to topo file * * \param[in,out] fp_plus topo file * \param[in] Plus pointer to Plus_head structure * * \return 0 on success * \return -1 on error */ int dig_write_plus_file(struct gvfile * fp_plus, struct Plus_head *Plus) { dig_set_cur_port(&(Plus->port)); dig_rewind(fp_plus); if (dig_Wr_Plus_head(fp_plus, Plus) < 0) { G_warning(_("Unable to write head to plus file")); return (-1); } if (dig_write_nodes(fp_plus, Plus) < 0) { G_warning(_("Unable to write nodes to plus file")); return (-1); } if (dig_write_lines(fp_plus, Plus) < 0) { G_warning(_("Unable to write lines to plus file")); return (-1); } if (dig_write_areas(fp_plus, Plus) < 0) { G_warning(_("Unable to write areas to plus file")); return (-1); } if (dig_write_isles(fp_plus, Plus) < 0) { G_warning(_("Unable to write isles to plus file")); return (-1); } dig_rewind(fp_plus); if (dig_Wr_Plus_head(fp_plus, Plus) < 0) { G_warning(_("Unable to write head to plus file")); return (-1); } dig_fflush(fp_plus); return (0); } /* write_plus_file() */ /*! * \brief Writes topo structure (nodes) to topo file * * \param[in,out] plus topo file * \param[in] Plus pointer to Plus_head structure * * \return 0 on success * \return -1 on error */ int dig_write_nodes(struct gvfile * plus, struct Plus_head *Plus) { int i; Plus->Node_offset = dig_ftell(plus); for (i = 1; i <= Plus->n_nodes; i++) { if (dig_Wr_P_node(Plus, i, plus) < 0) return (-1); } return (0); } /* write_nodes() */ /*! * \brief Writes topo structure (lines) to topo file * * \param[in,out] plus topo file * \param[in] Plus pointer to Plus_head structure * * \return 0 on success * \return -1 on error */ int dig_write_lines(struct gvfile * plus, struct Plus_head *Plus) { int i; Plus->Line_offset = dig_ftell(plus); for (i = 1; i <= Plus->n_lines; i++) { if (dig_Wr_P_line(Plus, i, plus) < 0) return (-1); } return (0); } /* write_line() */ /*! * \brief Writes topo structure (areas) to topo file * * \param[in,out] plus topo file * \param[in] Plus pointer to Plus_head structure * * \return 0 on success * \return -1 on error */ int dig_write_areas(struct gvfile * plus, struct Plus_head *Plus) { int i; Plus->Area_offset = dig_ftell(plus); for (i = 1; i <= Plus->n_areas; i++) { if (dig_Wr_P_area(Plus, i, plus) < 0) return (-1); } return (0); } /* write_areas() */ /*! * \brief Writes topo structure (isles) to topo file * * \param[in,out] plus topo file * \param[in] Plus pointer to Plus_head structure * * \return 0 on success * \return -1 on error */ int dig_write_isles(struct gvfile * plus, struct Plus_head *Plus) { int i; Plus->Isle_offset = dig_ftell(plus); for (i = 1; i <= Plus->n_isles; i++) { if (dig_Wr_P_isle(Plus, i, plus) < 0) return (-1); } return (0); } /* write_isles() */