Esempio n. 1
0
/*!
  \brief Read spatial index file 

  \param fp pointer to gvfile structure
  \param[in,out] plus pointer to Plus_head structure
  \param head_only non-zero to read only head

  \return 0 OK
  \return 1 error
*/
int dig_read_cidx(struct gvfile * fp, struct Plus_head *plus, int head_only)
{
    int i;

    G_debug(3, "dig_read_cidx()");

    dig_cidx_free(plus);
    dig_cidx_init(plus);

    dig_rewind(fp);
    if (dig_read_cidx_head(fp, plus) == -1) {
	G_debug(3, "Cannot read cidx head");
	return 1;
    }

    if (head_only) {
	plus->cidx_up_to_date = 1;	/* OK ? */
	return 0;
    }

    dig_set_cur_port(&(plus->cidx_port));

    /* Read category-type-id for each field */
    for (i = 0; i < plus->n_cidx; i++) {
	int j;
	struct Cat_index *ci;

	ci = &(plus->cidx[i]);
	ci->a_cats = ci->n_cats;
	ci->cat = G_malloc(ci->a_cats * 3 * sizeof(int));

	if (dig_fseek(fp, ci->offset, 0) == -1)
	    return 1;

	if (0 >= dig__fread_port_I((int *)ci->cat, 3 * ci->n_cats, fp))
	    return 1;

	/* convert type  */
	for (j = 0; j < ci->n_cats; j++)
	    ci->cat[j][1] = dig_type_from_store(ci->cat[j][1]);
    }


    plus->cidx_up_to_date = 1;

    return 0;
}
Esempio n. 2
0
/*!
   \brief Build partial topology for vector map.

   Should only be used in special cases of vector processing.

   This functions optionally builds only some parts of
   topology. Highest level is specified by build parameter which may
   be:
    - GV_BUILD_NONE - nothing is build
    - GV_BUILD_BASE - basic topology, nodes, lines, spatial index;
    - GV_BUILD_AREAS - build areas and islands, but islands are not attached to areas;
    - GV_BUILD_ATTACH_ISLES - attach islands to areas;
    - GV_BUILD_CENTROIDS - assign centroids to areas, build category index;
    - GV_BUILD_ALL - top level, the same as GV_BUILD_CENTROIDS.
    
   If functions is called with build lower than current value of the
   Map, the level is downgraded to requested value.

   All calls to Vect_write_line(), Vect_rewrite_line(),
   Vect_delete_line() respect the last value of build used in this
   function.

   Note that the functions has effect only if requested level is
   higher than current level, to rebuild part of topology, call first
   downgrade and then upgrade, for example:

   - Vect_build()
   - Vect_build_partial(,GV_BUILD_BASE,)
   - Vect_build_partial(,GV_BUILD_AREAS,) 

   \param Map vector map
   \param build highest level of build

   \return 1 on success
   \return 0 on error
 */
int Vect_build_partial(struct Map_info *Map, int build)
{
    struct Plus_head *plus;
    int ret;

    G_debug(3, "Vect_build(): build = %d", build);

    /* If topology is already build (map on > level 2), set level to 1
     * so that lines will be read by V1_read_ (all lines) */
    Map->level = LEVEL_1; /* may be not needed, because V1_read is used
                             directly by Vect_build_ */

    if (Map->format != GV_FORMAT_OGR_DIRECT &&
        !(Map->format == GV_FORMAT_POSTGIS && Map->fInfo.pg.toposchema_name))
        /* don't write support files for OGR direct and PostGIS Topology */
	Map->support_updated = TRUE;

    if (!Map->plus.Spidx_built) {
	if (Vect_open_sidx(Map, 2) < 0)
	    G_fatal_error(_("Unable to open spatial index file for vector map <%s>"),
			    Vect_get_full_name(Map));
    }

    plus = &(Map->plus);
    if (build > GV_BUILD_NONE && !Map->temporary) {
	G_message(_("Building topology for vector map <%s>..."),
		  Vect_get_full_name(Map));
    }
    plus->with_z = Map->head.with_z;
    plus->spidx_with_z = Map->head.with_z;

    if (build == GV_BUILD_ALL && plus->built < GV_BUILD_ALL) {
	dig_cidx_free(plus);	/* free old (if any) category index */
	dig_cidx_init(plus);
    }

    ret = ((*Build_array[Map->format]) (Map, build));
    if (ret == 0) {
	return 0;
    }

    if (build > GV_BUILD_NONE) {
        Map->level = LEVEL_2;
	G_verbose_message(_("Topology was built"));
    }

    plus->mode = GV_MODE_WRITE;

    if (build == GV_BUILD_ALL) {
	plus->cidx_up_to_date = TRUE;	/* category index was build */
	dig_cidx_sort(plus);
    }

    if (build > GV_BUILD_NONE) {
	G_message(_("Number of nodes: %d"), plus->n_nodes);
	G_message(_("Number of primitives: %d"), plus->n_lines);
	G_message(_("Number of points: %d"), plus->n_plines);
	G_message(_("Number of lines: %d"), plus->n_llines);
	G_message(_("Number of boundaries: %d"), plus->n_blines);
	G_message(_("Number of centroids: %d"), plus->n_clines);

	if (plus->n_flines > 0)
	    G_message(_("Number of faces: %d"), plus->n_flines);

	if (plus->n_klines > 0)
	    G_message(_("Number of kernels: %d"), plus->n_klines);
    }

    if (plus->built >= GV_BUILD_AREAS) {
	int line, nlines, area, nareas, err_boundaries, err_centr_out,
	    err_centr_dupl, err_nocentr;
	struct P_line *Line;
	struct Plus_head *Plus;

	/* Count errors (it does not take much time comparing to build process) */
	Plus = &(Map->plus);
	nlines = Vect_get_num_lines(Map);
	err_boundaries = err_centr_out = err_centr_dupl = 0;
	for (line = 1; line <= nlines; line++) {
	    Line = Plus->Line[line];
	    if (!Line)
		continue;
	    if (Line->type == GV_BOUNDARY) {
		struct P_topo_b *topo = (struct P_topo_b *)Line->topo;

		if (topo->left == 0 || topo->right == 0) {
		    G_debug(3, "line = %d left = %d right = %d", line, 
			    topo->left, topo->right);
		    err_boundaries++;
		}
	    }
	    if (Line->type == GV_CENTROID) {
		struct P_topo_c *topo = (struct P_topo_c *)Line->topo;

		if (topo->area == 0)
		    err_centr_out++;
		else if (topo->area < 0)
		    err_centr_dupl++;
	    }
	}

	err_nocentr = 0;
	nareas = Vect_get_num_areas(Map);
	for (area = 1; area <= nareas; area++) {
	    if (!Vect_area_alive(Map, area))
		continue;
	    line = Vect_get_area_centroid(Map, area);
	    if (line == 0)
		err_nocentr++;
	}

	G_message(_("Number of areas: %d"), plus->n_areas);
	G_message(_("Number of isles: %d"), plus->n_isles);

#if 0
	/* not an error, message disabled to avoid confusion */
	if (err_nocentr)
	    G_message(_("Number of areas without centroid: %d"),
		      err_nocentr);
#endif

	if (plus->n_clines > plus->n_areas)
	    G_warning(_("Number of centroids exceeds number of areas: %d > %d"),
		      plus->n_clines, plus->n_areas);

	if (err_boundaries)
	    G_warning(_("Number of incorrect boundaries: %d"),
		      err_boundaries);

	if (err_centr_out)
	    G_warning(_("Number of centroids outside area: %d"),
		      err_centr_out);

	if (err_centr_dupl)
	    G_warning(_("Number of duplicate centroids: %d"), err_centr_dupl);

    }
    else if (build > GV_BUILD_NONE) {
	G_message(_("Number of areas: -"));
	G_message(_("Number of isles: -"));
    }
    return 1;
}
Esempio n. 3
0
/*!
   \brief Close vector data file

   \param Map vector map to be closed

   \return 0 on success
   \return non-zero on error
 */
int Vect_close(struct Map_info *Map)
{
    struct Coor_info CInfo;

    G_debug(1,
	    "Vect_close(): name = %s, mapset = %s, format = %d, level = %d",
	    Map->name, Map->mapset, Map->format, Map->level);

    /* Store support files if in write mode on level 2 */
    if (strcmp(Map->mapset, G_mapset()) == 0 && Map->support_updated &&
	Map->plus.built == GV_BUILD_ALL) {
	char buf[GPATH_MAX];
	char file_path[GPATH_MAX];
	struct stat info;

	/* Delete old support files if available */
	sprintf(buf, "%s/%s", GRASS_VECT_DIRECTORY, Map->name);

	G__file_name(file_path, buf, GV_TOPO_ELEMENT, G_mapset());
	if (stat(file_path, &info) == 0)	/* file exists? */
	    unlink(file_path);

	G__file_name(file_path, buf, GV_SIDX_ELEMENT, G_mapset());
	if (stat(file_path, &info) == 0)	/* file exists? */
	    unlink(file_path);

	G__file_name(file_path, buf, GV_CIDX_ELEMENT, G_mapset());
	if (stat(file_path, &info) == 0)	/* file exists? */
	    unlink(file_path);

	Vect_coor_info(Map, &CInfo);
	Map->plus.coor_size = CInfo.size;
	Map->plus.coor_mtime = CInfo.mtime;

	Vect_save_topo(Map);

	/* Spatial index is not saved */
	/* Vect_save_spatial_index ( Map ); */

	Vect_cidx_save(Map);

#ifdef HAVE_OGR
	if (Map->format == GV_FORMAT_OGR)
	    V2_close_ogr(Map);
#endif
    }

    if (Map->level == 2 && Map->plus.release_support) {
	G_debug(1, "free topology");
	dig_free_plus(&(Map->plus));

	if (!Map->head_only) {
	    G_debug(1, "free spatial index");
	    dig_spidx_free(&(Map->plus));
	}

	G_debug(1, "free category index");
	dig_cidx_free(&(Map->plus));

    }

    if (Map->format == GV_FORMAT_NATIVE) {
	G_debug(1, "close history file");
	if (Map->hist_fp != NULL)
	    fclose(Map->hist_fp);
    }

    /* Close level 1 files / data sources if not head_only */
    if (!Map->head_only) {
	if (((*Close_array[Map->format][1]) (Map)) != 0) {
	    G_warning(_("Unable to close vector <%s>"),
		      Vect_get_full_name(Map));
	    return 1;
	}
    }

    G_free((void *)Map->name);
    Map->name = NULL;
    G_free((void *)Map->mapset);
    Map->mapset = NULL;

    Map->open = VECT_CLOSED_CODE;

    return 0;
}