123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 |
- /*!
- \file lib/vector/Vlib/level_two.c
- \brief Vector library - topology level functions
- (C) 2001-2009, 2011-2012 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 Original author CERL, probably Dave Gerdes or Mike Higgins.
- \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
- \author Update to GRASS 7 by Martin Landa <landa.martin gmail.com>
- */
- #include <stdlib.h>
- #include <grass/vector.h>
- #include <grass/glocale.h>
- static void check_level(const struct Map_info *Map)
- {
- if (Map->level < 2)
- G_fatal_error(_("Vector map <%s> is not open at topological level"),
- Vect_get_full_name(Map));
- }
- /*!
- \brief Get number of nodes in vector map
- \param Map pointer to Map_info struct
- \return number of nodes
- */
- plus_t Vect_get_num_nodes(const struct Map_info *Map)
- {
- return (Map->plus.n_nodes);
- }
- /*!
- \brief Get number of primitives in vector map
- \param Map pointer to Map_info struct
- \param type feature type
- \return number of primitives
- */
- plus_t Vect_get_num_primitives(const struct Map_info *Map, int type)
- {
- plus_t num = 0;
- if (type & GV_POINT)
- num += Map->plus.n_plines;
- if (type & GV_LINE)
- num += Map->plus.n_llines;
- if (type & GV_BOUNDARY)
- num += Map->plus.n_blines;
- if (type & GV_CENTROID)
- num += Map->plus.n_clines;
- if (type & GV_FACE)
- num += Map->plus.n_flines;
- if (type & GV_KERNEL)
- num += Map->plus.n_klines;
- return num;
- }
- /*!
- \brief Fetch number of features (points, lines, boundaries, centroids) in vector map
- \param Map pointer to Map_info struct
- \return number of features
- */
- plus_t Vect_get_num_lines(const struct Map_info *Map)
- {
- return (Map->plus.n_lines);
- }
- /*!
- \brief Get number of areas in vector map
- \param Map pointer to Map_info struct
- \return number of areas
- */
- plus_t Vect_get_num_areas(const struct Map_info *Map)
- {
- return (Map->plus.n_areas);
- }
- /*!
- \brief Fetch number of kernels in vector map
- \param Map pointer to Map_info struct
- \return number of kernels
- */
- plus_t Vect_get_num_kernels(const struct Map_info *Map)
- {
- return (Map->plus.n_klines);
- }
- /*!
- \brief Get number of faces in vector map
- \param Map pointer to Map_info struct
- \return number of faces
- */
- plus_t Vect_get_num_faces(const struct Map_info *Map)
- {
- return (Map->plus.n_flines);
- }
- /*!
- \brief Fetch number of volumes in vector map
- \param Map pointer to Map_info struct
- \return number of volumes
- */
- plus_t Vect_get_num_volumes(const struct Map_info *Map)
- {
- return (Map->plus.n_volumes);
- }
- /*!
- \brief Get number of islands in vector map
- \param Map pointer to Map_info struct
- \return number of islands
- */
- plus_t Vect_get_num_islands(const struct Map_info *Map)
- {
- return (Map->plus.n_isles);
- }
- /*!
- \brief Fetch number of holes in vector map
- \param Map pointer to Map_info struct
- \return number of holes
- */
- plus_t Vect_get_num_holes(const struct Map_info *Map)
- {
- return (Map->plus.n_holes);
- }
- /*!
- \brief Get number of defined dblinks
- \param Map pointer to Map_info struct
- \return number of dblinks
- */
- int Vect_get_num_dblinks(const struct Map_info *Map)
- {
- /* available on level 1 ? */
- return (Map->dblnk->n_fields);
- }
- /*!
- \brief Get number of updated features
- Note: Vect_set_updated() must be called to maintain list of updated
- features
- \param Map pointer to Map_info struct
- \return number of updated features
- */
- int Vect_get_num_updated_lines(const struct Map_info *Map)
- {
- return (Map->plus.uplist.n_uplines);
- }
- /*!
- \brief Get updated line by index
- Note: Vect_set_updated() must be called to maintain list of updated
- features
- \param Map pointer to Map_info struct
- \param idx index
- \return updated line
- */
- int Vect_get_updated_line(const struct Map_info *Map, int idx)
- {
- return (Map->plus.uplist.uplines[idx]);
- }
- /*!
- \brief Get updated line offset by index
- Note: Vect_set_updated() must be called to maintain list of updated
- features
- \param Map pointer to Map_info struct
- \param idx index
- \return updated line
- */
- off_t Vect_get_updated_line_offset(const struct Map_info *Map, int idx)
- {
- return (Map->plus.uplist.uplines_offset[idx]);
- }
- /*!
- \brief Get number of updated nodes
- \param Map pointer to Map_info struct
- \return number of updated nodes
- */
- int Vect_get_num_updated_nodes(const struct Map_info *Map)
- {
- return (Map->plus.uplist.n_upnodes);
- }
- /*!
- \brief Get updated (modified) node by index
- Note: Vect_set_updated() must be called to maintain list of updated
- features
- Negative id:
- - if Node[id] is not NULL then the node was added
- - if Node[id] is NULL then the node was deleted
- Positive id:
- - node was updated
- \param Map pointer to Map_info struct
- \param idx index
- \return id of modified node
- */
- int Vect_get_updated_node(const struct Map_info *Map, int idx)
- {
- return (Map->plus.uplist.upnodes[idx]);
- }
- /*!
- \brief Get line type
- \param Map pointer to Map_info struct
- \param line line id
- \return line type
- */
- int Vect_get_line_type(const struct Map_info *Map, int line)
- {
- check_level(Map);
-
- if (!Vect_line_alive(Map, line))
- return 0;
-
- return (Map->plus.Line[line]->type);
- }
- /*!
- \brief Get node coordinates
- \param Map pointer to Map_info struct
- \param num node id (starts at 1)
- \param[out] x,y,z coordinates values (for 2D coordinates z is NULL)
- \return 0 on success
- \return -1 on error
- */
- int Vect_get_node_coor(const struct Map_info *Map, int num, double *x, double *y,
- double *z)
- {
- struct P_node *Node;
- if (num < 1 || num > Map->plus.n_nodes) {
- G_warning(_("Invalid node id: %d"), num);
- return -1;
- }
-
- Node = Map->plus.Node[num];
- *x = Node->x;
- *y = Node->y;
- if (z != NULL)
- *z = Node->z;
- return 0;
- }
- /*!
- \brief Get line nodes
- \param Map pointer to Map_info struct
- \param line line id
- \param n1 (start node), n2 (end node) ids of line nodes (or NULL)
- \return 1
- */
- int Vect_get_line_nodes(const struct Map_info *Map, int line, int *n1, int *n2)
- {
- char type;
- check_level(Map);
- type = Vect_get_line_type(Map, line);
- if (!(type & GV_LINES))
- G_fatal_error(_("Nodes not available for line %d"), line);
-
- if (type == GV_LINE) {
- struct P_topo_l *topo = (struct P_topo_l *)Map->plus.Line[line]->topo;
- if (n1 != NULL)
- *n1 = topo->N1;
- if (n2 != NULL)
- *n2 = topo->N2;
- }
- else if (type == GV_BOUNDARY) {
- struct P_topo_b *topo = (struct P_topo_b *)Map->plus.Line[line]->topo;
- if (n1 != NULL)
- *n1 = topo->N1;
- if (n2 != NULL)
- *n2 = topo->N2;
- }
- return 1;
- }
- /*!
- \brief Get area id on the left and right side of the boundary
- Negative area id indicates an isle.
-
- \param Map pointer to Map_info struct
- \param line line id
- \param[out] left,right area id on the left and right side
- \return 1 on success
- \return -1 on failure (topology not available, line is not a boundary)
- */
- int Vect_get_line_areas(const struct Map_info *Map, int line, int *left, int *right)
- {
- struct P_topo_b *topo;
- check_level(Map);
-
- if (!Map->plus.Line[line]->topo) {
- G_warning(_("Areas not available for line %d"), line);
- return -1;
- }
- if (Vect_get_line_type(Map, line) != GV_BOUNDARY) {
- G_warning(_("Line %d is not a boundary"), line);
- return -1;
- }
- topo = (struct P_topo_b *)Map->plus.Line[line]->topo;
- if (left != NULL)
- *left = topo->left;
-
- if (right != NULL)
- *right = topo->right;
-
- return 1;
- }
- /*!
- \brief Get number of lines for node
- \param Map pointer to Map_info struct
- \param node node id
- \return numbers of lines
- */
- int Vect_get_node_n_lines(const struct Map_info *Map, int node)
- {
- check_level(Map);
-
- return (Map->plus.Node[node]->n_lines);
- }
- /*!
- \brief Get line id for node line index
- \param Map pointer to Map_info struct
- \param node node id
- \param line line index (range: 0 - Vect_get_node_n_lines())
- \return line id
- */
- int Vect_get_node_line(const struct Map_info *Map, int node, int line)
- {
- check_level(Map);
-
- return (Map->plus.Node[node]->lines[line]);
- }
- /*!
- \brief Angle of segment of the line connected to the node
- \param Map pointer to Map_info struct
- \param node node number
- \param line line index (range: 0 - Vect_get_node_n_lines())
- \return angle of segment of the line connected to the node
- */
- float Vect_get_node_line_angle(const struct Map_info *Map, int node, int line)
- {
- check_level(Map);
- return (Map->plus.Node[node]->angles[line]);
- }
- /*!
- \brief Get area id the centroid is within
- \param Map pointer to Map_info struct
- \param centroid centroid id
- \return area id the centroid is within
- \return 0 for not in area
- \return negative id if centroid is duplicated in the area
- */
- int Vect_get_centroid_area(const struct Map_info *Map, int centroid)
- {
- struct P_topo_c *topo;
- check_level(Map);
-
- if (Map->plus.Line[centroid]->type != GV_CENTROID)
- return 0;
-
- topo = (struct P_topo_c *)Map->plus.Line[centroid]->topo;
- if(!topo)
- G_fatal_error(_("Topology info not available for feature %d"), centroid);
-
- return (topo->area);
- }
- /*!
- \brief Enable/disable maintanance of list of updated lines/nodes
- See Plus_head.uplist for details.
-
- \param Map pointer to Map_info struct
- \param enable TRUE/FALSE to enable/disable
- */
- void Vect_set_updated(struct Map_info *Map, int enable)
- {
- G_debug(1, "Vect_set_updated(): name = '%s' enabled = %d", Map->name, enable);
-
- check_level(Map);
-
- Map->plus.uplist.do_uplist = enable != 0 ? TRUE : FALSE;
- }
- /*!
- \brief Reset list of updated lines/nodes
- \param Map pointer to Map_info struct
- */
- void Vect_reset_updated(struct Map_info *Map)
- {
- struct Plus_head *Plus;
- check_level(Map);
-
- Plus = &(Map->plus);
- dig_line_reset_updated(Plus);
- dig_node_reset_updated(Plus);
- }
|