예제 #1
0
파일: write_ogr.c 프로젝트: caomw/grass
/*!
   \brief Create new OGR layer in given OGR datasource (internal use only)

   V1_open_new_ogr() is required to be called before this function.

   List of currently supported types:
    - GV_POINT     (wkbPoint)
    - GV_LINE      (wkbLineString)
    - GV_BOUNDARY  (wkb_Polygon)
   \param[in,out] Map pointer to Map_info structure
   \param type feature type (GV_POINT, GV_LINE, ...)

   \return 0 success
   \return -1 error 
*/
int create_ogr_layer(struct Map_info *Map, int type)
{
    int ndblinks;
    OGRLayerH            Ogr_layer;
    OGRSpatialReferenceH Ogr_spatial_ref;
    
    struct field_info *Fi;
    struct Key_Value *projinfo, *projunits;
    struct Format_info_ogr *ogr_info;
    
    OGRwkbGeometryType Ogr_geom_type;
    char             **Ogr_layer_options;
    
    ogr_info = &(Map->fInfo.ogr);
    
    if (!ogr_info->driver_name ||
	!ogr_info->layer_name ||
	!ogr_info->ds)
	return -1;
    
    /* get spatial reference */
    projinfo  = G_get_projinfo();
    projunits = G_get_projunits();
    Ogr_spatial_ref = GPJ_grass_to_osr(projinfo, projunits);
    G_free_key_value(projinfo);
    G_free_key_value(projunits);
    
    /* determine geometry type */
    switch(type) {
    case GV_POINT:
	Ogr_geom_type = wkbPoint;
	break;
    case GV_LINE:
	Ogr_geom_type = wkbLineString;
	break;
    case GV_BOUNDARY:
	Ogr_geom_type = wkbPolygon;
	break;
    default:
	G_warning(_("Unsupported geometry type (%d)"), type);
	return -1;
    }
    
    /* check creation options */
    Ogr_layer_options = ogr_info->layer_options;
    if (Vect_is_3d(Map)) {
	if (strcmp(ogr_info->driver_name, "PostgreSQL") == 0) {
	    Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "3");
	}
    }
    else {
	if (strcmp(ogr_info->driver_name, "PostgreSQL") == 0) {
	    Ogr_layer_options = CSLSetNameValue(Ogr_layer_options, "DIM", "2");
	}
    }

    /* create new OGR layer */
    Ogr_layer = OGR_DS_CreateLayer(ogr_info->ds, ogr_info->layer_name,
				   Ogr_spatial_ref, Ogr_geom_type, Ogr_layer_options);
    CSLDestroy(Ogr_layer_options);
    if (!Ogr_layer) {
	G_warning(_("Unable to create OGR layer <%s> in '%s'"),
		  ogr_info->layer_name, ogr_info->dsn);
	return -1;
    }
    ogr_info->layer = Ogr_layer;

    ndblinks = Vect_get_num_dblinks(Map);
    if (ndblinks > 0) {
	/* write also attributes */
	Fi = Vect_get_dblink(Map, 0);
	if (Fi) {
	    if (ndblinks > 1)
		G_warning(_("More layers defined, using driver <%s> and "
			    "database <%s>"), Fi->driver, Fi->database);
	    ogr_info->dbdriver = create_table(ogr_info->layer, Fi);
	    G_free(Fi);
	}
	else
	  G_warning(_("Database connection not defined. "
		      "Unable to write attributes."));
    }
    
    if (OGR_L_TestCapability(ogr_info->layer, OLCTransactions))
	OGR_L_StartTransaction(ogr_info->layer);

    return 0;
}
예제 #2
0
/*!
   \brief Open existing OGR layer on non-topological level

   Note: Map->name, Map->mapset, Map->fInfo.ogr.dsn and
   Map->fInfo.ogr.layer_name must be set before.

   \param[in,out] Map pointer to Map_info structure
   \param update TRUE for write mode, otherwise read-only
   
   \return 0 success
   \return -1 error
*/
int V1_open_old_ogr(struct Map_info *Map, int update)
{
#ifdef HAVE_OGR
    int i, layer, nLayers;

    struct Format_info_ogr *ogr_info;
    
    OGRDataSourceH Ogr_ds;
    OGRLayerH Ogr_layer;
    OGRFeatureDefnH Ogr_featuredefn;
    OGRwkbGeometryType Ogr_geom_type;
    
    Ogr_layer = NULL;
    Ogr_geom_type = wkbUnknown;

    ogr_info = &(Map->fInfo.ogr);
    if (!ogr_info->dsn) {
	G_fatal_error(_("OGR datasource not defined"));
	return -1;
    }
    
    if (!ogr_info->layer_name) {
	G_fatal_error(_("OGR layer not defined"));
	return -1;
    }
    
    G_debug(2, "V1_open_old_ogr(): dsn = %s layer = %s", ogr_info->dsn,
	    ogr_info->layer_name);

    OGRRegisterAll();

    /* open data source handle */
    Ogr_ds = OGROpen(ogr_info->dsn, FALSE, NULL);
    if (Ogr_ds == NULL)
	G_fatal_error(_("Unable to open OGR data source '%s'"),
		      ogr_info->dsn);
    ogr_info->ds = Ogr_ds;

    /* get layer number */
    layer = -1;
    nLayers = OGR_DS_GetLayerCount(Ogr_ds);
    G_debug(2, "%d layers found in data source", nLayers);

    for (i = 0; i < nLayers; i++) {
	Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i);	
	Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer);
	if (strcmp(OGR_FD_GetName(Ogr_featuredefn), ogr_info->layer_name) == 0) {
	    Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn);
	    layer = i;
	    break;
	}
    }
    if (layer == -1) {
	OGR_DS_Destroy(Ogr_ds);
	G_fatal_error(_("OGR layer <%s> not found"),
		      ogr_info->layer_name);
    }
    G_debug(2, "OGR layer %d opened", layer);

    ogr_info->layer = Ogr_layer;
    if (update && OGR_L_TestCapability(ogr_info->layer, OLCTransactions))
	OGR_L_StartTransaction(ogr_info->layer);
    
    switch(Ogr_geom_type) {
    case wkbPoint25D: case wkbLineString25D: case wkbPolygon25D:
    case wkbMultiPoint25D: case wkbMultiLineString25D: case wkbMultiPolygon25D:
    case wkbGeometryCollection25D:
	Map->head.with_z = WITH_Z;
	break;
    default:
	Map->head.with_z = WITHOUT_Z;
	break;
    }
    
    ogr_info->cache.fid = -1;	/* FID >= 0 */
    
    return 0;
#else
    G_fatal_error(_("GRASS is not compiled with OGR support"));
    return -1;
#endif
}