示例#1
0
/*!
  \brief Writes feature on level 1 (OGR interface)

  \param Map pointer to Map_info structure
  \param type feature type
  \param points pointer to line_pnts structure (feature geometry)
  \param cats pointer to line_cats structure (feature categories)

  \return feature offset into file
  \return -1 on error
*/
off_t V1_write_line_ogr(struct Map_info *Map, int type,
                        const struct line_pnts *points,
                        const struct line_cats *cats)
{
    int i, cat, ret;

    struct field_info *Fi;
    struct Format_info_ogr *fInfo;

    OGRGeometryH       Ogr_geometry;
    OGRFeatureH        Ogr_feature;
    OGRFeatureDefnH    Ogr_featuredefn;
    OGRwkbGeometryType Ogr_geom_type;

    if (!Map->fInfo.ogr.layer) {
        if (V2_open_new_ogr(Map, type) < 0)
            return -1;
    }

    cat = -1; /* no attributes to be written */
    if (cats->n_cats > 0) {
        /* check for attributes */
        Fi = Vect_get_dblink(Map, 0);
        if (Fi) {
            if (!Vect_cat_get(cats, Fi->number, &cat))
                G_warning(_("No category defined for layer %d"), Fi->number);
            if (cats->n_cats > 1) {
                G_warning(_("Feature has more categories, using "
                            "category %d (from layer %d)"),
                          cat, cats->field[0]);
            }
        }
    }

    fInfo = &(Map->fInfo.ogr);
    Ogr_featuredefn = OGR_L_GetLayerDefn(fInfo->layer);
    Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);

    /* determine matching OGR feature geometry type */
    /* NOTE: centroids are not supported in OGR,
     *       pseudotopo holds virtual centroids */
    /* NOTE: boundaries are not supported in OGR,
     *       pseudotopo treats polygons as boundaries */

    if (type & (GV_POINT | GV_KERNEL)) {
        if (Ogr_geom_type != wkbPoint &&
                Ogr_geom_type != wkbPoint25D) {
            G_warning(_("Feature is not a point. Skipping."));
            return -1;
        }
        Ogr_geometry = OGR_G_CreateGeometry(wkbPoint);
    }
    else if (type & GV_LINE) {
        if (Ogr_geom_type != wkbLineString &&
                Ogr_geom_type != wkbLineString25D) {
            G_warning(_("Feature is not a line. Skipping."));
            return -1;
        }
        Ogr_geometry = OGR_G_CreateGeometry(wkbLineString);
    }
    else if (type & GV_BOUNDARY) {
        if (Ogr_geom_type != wkbPolygon) {
            G_warning(_("Feature is not a polygon. Skipping."));
            return -1;
        }
        Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
    }
    else if (type & GV_FACE) {
        if (Ogr_geom_type != wkbPolygon25D) {
            G_warning(_("Feature is not a face. Skipping."));
            return -1;
        }
        Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon25D);
    }
    else {
        G_warning(_("Unsupported feature type (%d)"), type);
        return -1;
    }

    G_debug(3, "V1_write_line_ogr(): type = %d", type);

    if (Ogr_geom_type == wkbPolygon || Ogr_geom_type == wkbPolygon25D) {
        /* create exterior ring */
        OGRGeometryH Ogr_ring;
        int npoints;

        npoints = points->n_points - 1;
        Ogr_ring = OGR_G_CreateGeometry(wkbLinearRing);
        if (points->x[0] != points->x[npoints] ||
                points->y[0] != points->y[npoints] ||
                points->z[0] != points->z[npoints]) {
            G_warning(_("Boundary is not closed. Skipping."));
            return -1;
        }

        /* add points */
        for (i = 0; i < points->n_points; i++) {
            OGR_G_AddPoint(Ogr_ring, points->x[i], points->y[i],
                           points->z[i]);
        }
        OGR_G_AddGeometry(Ogr_geometry, Ogr_ring);
    }
    else {
        for (i = 0; i < points->n_points; i++) {
            OGR_G_AddPoint(Ogr_geometry, points->x[i], points->y[i],
                           points->z[i]);
        }
    }

    G_debug(4, "   n_points = %d", points->n_points);

    /* create feature & set geometry */
    Ogr_feature = OGR_F_Create(Ogr_featuredefn);
    OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);

    /* write attributes */
    if (cat > -1 && fInfo->dbdriver) {
        write_attributes(fInfo->dbdriver,
                         cat, Fi, fInfo->layer, Ogr_feature);
        G_free(Fi);
    }
    /* write feature into layer */
    ret = OGR_L_CreateFeature(fInfo->layer, Ogr_feature);

    /* update offset array */
    if (fInfo->offset_num >= fInfo->offset_alloc) {
        fInfo->offset_alloc += 1000;
        fInfo->offset = (int *) G_realloc(fInfo->offset,
                                          fInfo->offset_alloc *
                                          sizeof(int));
    }
    /* how to deal with OGRNullFID ? */
    fInfo->offset[fInfo->offset_num] = (int)OGR_F_GetFID(Ogr_feature);

    /* destroy */
    OGR_G_DestroyGeometry(Ogr_geometry);
    OGR_F_Destroy(Ogr_feature);

    if (ret != OGRERR_NONE)
        return -1;

    return fInfo->offset_num++;
}
示例#2
0
 void MultiGeometry::push_back (const Geometry& geom) {
     if (OGR_G_AddGeometry(outer, geom.handle()) != OGRERR_NONE) {
         throw runtime_error("Couldn't add geometry to multigeometry");
     }
 }
示例#3
0
文件: write_ogr.c 项目: caomw/grass
/*!
  \brief Write OGR feature

   \param Map pointer to Map_info structure
   \param type feature type (GV_POINT, GV_LINE, ...)
   \param bpoints feature geometry
   \param cats feature categories
   \param ipoints isle geometry for polygons on NULL
   \param nisles number of isles
   
   \return feature offset into file
   \return -1 on error
*/
off_t write_feature(struct Map_info *Map, int type,
                    const struct line_pnts **p_points, int nparts,
                    const struct line_cats *cats)
{
    int i, cat, ret;

    struct field_info *Fi;
    const struct line_pnts *points;
    struct Format_info_ogr *ogr_info;
    struct Format_info_offset *offset_info;
    
    off_t offset;
    
    OGRGeometryH       Ogr_geometry;
    OGRFeatureH        Ogr_feature;
    OGRFeatureDefnH    Ogr_featuredefn;
    OGRwkbGeometryType Ogr_geom_type;

    ogr_info = &(Map->fInfo.ogr);
    offset_info = &(ogr_info->offset);
    
    if (nparts < 1)
        return -1;
    
    points = p_points[0]; /* feature geometry */
    
    if (!ogr_info->layer) {
	/* create OGR layer if doesn't exist */
	if (create_ogr_layer(Map, type) < 0)
	    return -1;
    }

    if (!points)
        return 0;

    cat = -1; /* no attributes to be written */
    if (cats->n_cats > 0 && Vect_get_num_dblinks(Map) > 0) {
	/* check for attributes */
	Fi = Vect_get_dblink(Map, 0);
	if (Fi) {
	    if (!Vect_cat_get(cats, Fi->number, &cat))
		G_warning(_("No category defined for layer %d"), Fi->number);
	    if (cats->n_cats > 1) {
		G_warning(_("Feature has more categories, using "
			    "category %d (from layer %d)"),
			  cat, cats->field[0]);
	    }
	}
    }
    
    Ogr_featuredefn = OGR_L_GetLayerDefn(ogr_info->layer);
    Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);
    
    /* determine matching OGR feature geometry type */
    if (type & (GV_POINT | GV_KERNEL)) {
	if (Ogr_geom_type != wkbPoint &&
	    Ogr_geom_type != wkbPoint25D) {
	    G_warning(_("Feature is not a point. Skipping."));
	    return -1;
	}
	Ogr_geometry = OGR_G_CreateGeometry(wkbPoint);
    }
    else if (type & GV_LINE) {
	if (Ogr_geom_type != wkbLineString &&
	    Ogr_geom_type != wkbLineString25D) {
	    G_warning(_("Feature is not a line. Skipping."));
	    return -1;
	}
	Ogr_geometry = OGR_G_CreateGeometry(wkbLineString);
    }
    else if (type & GV_BOUNDARY) {
	if (Ogr_geom_type != wkbPolygon) {
	    G_warning(_("Feature is not a polygon. Skipping."));
	    return -1;
	}
	Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon);
    }
    else if (type & GV_FACE) {
	if (Ogr_geom_type != wkbPolygon25D) {
	    G_warning(_("Feature is not a face. Skipping."));
	    return -1;
	}
	Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon25D);
    }
    else {
	G_warning(_("Unsupported feature type (%d)"), type);
	return -1;
    }

    G_debug(3, "V1_write_line_ogr(): type = %d", type);

    if (Ogr_geom_type == wkbPolygon || Ogr_geom_type == wkbPolygon25D) {
	int iring, npoints;
	
        /* add rings (first is exterior ring) */
        for (iring = 0; iring < nparts; iring++) {
            OGRGeometryH Ogr_ring;
            
            points = p_points[iring];
            npoints = points->n_points - 1;
            Ogr_ring = OGR_G_CreateGeometry(wkbLinearRing);
            if (points->x[0] != points->x[npoints] ||
                points->y[0] != points->y[npoints] ||
                points->z[0] != points->z[npoints]) {
                G_warning(_("Boundary is not closed. Feature skipped."));
                return -1;
            }
	
            /* add points */
            for (i = 0; i < npoints; i++) {
                OGR_G_AddPoint(Ogr_ring, points->x[i], points->y[i],
                               points->z[i]);
            }
            G_debug(4, "   ring(%d): n_points = %d", iring, npoints);
            OGR_G_AddGeometry(Ogr_geometry, Ogr_ring);
        }
    }
    else {
	for (i = 0; i < points->n_points; i++) {
	    OGR_G_AddPoint(Ogr_geometry, points->x[i], points->y[i],
			   points->z[i]);
	}
        G_debug(4, "   n_points = %d", points->n_points);
    }
    
    /* create feature & set geometry */
    Ogr_feature = OGR_F_Create(Ogr_featuredefn);
    OGR_F_SetGeometry(Ogr_feature, Ogr_geometry);

    /* write attributes */
    if (cat > -1 && ogr_info->dbdriver) {
	if (0 > write_attributes(ogr_info->dbdriver,
                                 cat, Fi, ogr_info->layer, Ogr_feature))
            G_warning(_("Unable to writes feature attributes"));
	G_free(Fi);
    }
    /* write feature into layer */
    ret = OGR_L_CreateFeature(ogr_info->layer, Ogr_feature);

    /* update offset array */
    if (offset_info->array_num >= offset_info->array_alloc) {
	offset_info->array_alloc += 1000;
	offset_info->array = (int *) G_realloc(offset_info->array,
						offset_info->array_alloc *
						sizeof(int));
    }

    offset = offset_info->array_num;
    
    offset_info->array[offset_info->array_num++] = (int) OGR_F_GetFID(Ogr_feature);
    if (Ogr_geom_type == wkbPolygon || Ogr_geom_type == wkbPolygon25D) {
	/* register exterior ring in offset array */
	offset_info->array[offset_info->array_num++] = 0; 
    }
      
    /* destroy */
    OGR_G_DestroyGeometry(Ogr_geometry);
    OGR_F_Destroy(Ogr_feature);
    
    if (ret != OGRERR_NONE)
	return -1;
    
    G_debug(3, "write_feature(): -> offset = %lu offset_num = %d cat = %d",
	    (unsigned long) offset, offset_info->array_num, cat);

    return offset;
}