void setFromLayer(OGRLayerH layer) { if (layer) { OGRSpatialReferenceH s = OGR_L_GetSpatialRef(layer); if (s) { OGRSpatialReferenceH clone = OSRClone(s); newRef(clone); } } }
GDALWSpatialInfo GDALWGetSpatialInfo(GDALWConnection conn) { GDALWSpatialInfo spatialInfo; OGRSpatialReferenceH spatialRef = OGR_L_GetSpatialRef(conn.layer); char * proj4, * srsText, * srid; OSRExportToProj4(spatialRef, &proj4); OSRExportToWkt(spatialRef, &srsText); srid = (char *) OSRGetAttrValue(spatialRef, "AUTHORITY", 1); if (srid == NULL) { spatialInfo.epsg = 4326; } else { spatialInfo.epsg = atoi(OSRGetAttrValue(spatialRef, "AUTHORITY", 1)); } spatialInfo.authName = OSRGetAttrValue(spatialRef, "AUTHORITY", 0); if (spatialInfo.authName == NULL) { spatialInfo.authName = "EPSG"; } spatialInfo.proj4Text = proj4; spatialInfo.srsText = srsText; return spatialInfo; }
int readoutlets(char *outletsds,char *lyrname, int uselayername,int outletslyr,OGRSpatialReferenceH hSRSRaster,int *noutlets, double*& x, double*& y,int*& id) { // initializing datasoruce,layer,feature, geomtery, spatial reference OGRSFDriverH driver; OGRDataSourceH hDS1; OGRLayerH hLayer1; OGRFeatureDefnH hFDefn1; OGRFieldDefnH hFieldDefn1; OGRFeatureH hFeature1; OGRGeometryH geometry, line; OGRSpatialReferenceH hRSOutlet; // register all ogr driver related to OGR OGRRegisterAll(); // open data source hDS1 = OGROpen(outletsds, FALSE, NULL ); if( hDS1 == NULL ) { printf( "Error Opening OGR Data Source .\n" ); return 1; } //get layer from layer name if(uselayername==1) { hLayer1 = OGR_DS_GetLayerByName(hDS1,lyrname);} //get layerinfo from layer number else { hLayer1 = OGR_DS_GetLayer(hDS1,outletslyr);} // get layerinfo from layername if(hLayer1 == NULL)getlayerfail(hDS1,outletsds,outletslyr); OGRwkbGeometryType gtype; gtype=OGR_L_GetGeomType(hLayer1); // Test that the type is a point if(gtype != wkbPoint)getlayerfail(hDS1,outletsds,outletslyr); const char* RasterProjectionName; const char* sprs; const char* sprso; const char* OutletProjectionName; int pj_raster,pj_outlet; // Spatial reference of outlet hRSOutlet = OGR_L_GetSpatialRef(hLayer1); if(hSRSRaster!=NULL){ pj_raster=OSRIsProjected(hSRSRaster); // find if projected or not if(pj_raster==0) {sprs="GEOGCS";} else { sprs="PROJCS"; } RasterProjectionName = OSRGetAttrValue(hSRSRaster,sprs,0); // get projection name } if(hRSOutlet!=NULL){ pj_outlet=OSRIsProjected(hRSOutlet); if(pj_outlet==0) {sprso="GEOGCS";} else { sprso="PROJCS"; } OutletProjectionName = OSRGetAttrValue(hRSOutlet,sprso,0); } //Write warnings where projections may not match if(hRSOutlet!=NULL && hSRSRaster!=NULL){ if (pj_raster==pj_outlet){ int rc= strcmp(RasterProjectionName,OutletProjectionName); // compare string if(rc!=0){ printf( "Warning: Projection of Outlet feature and Raster data may be different.\n" ); printf("Projection of Raster datasource %s.\n",RasterProjectionName); printf("Projection of Outlet feature %s.\n",OutletProjectionName); } } else { printf( "Warning: Spatial References of Outlet feature and Raster data are different.\n" ); printf("Projection of Raster datasource %s.\n",RasterProjectionName); printf("Projection of Outlet feature %s.\n",OutletProjectionName); } } else if(hSRSRaster==NULL && hRSOutlet!=NULL) { printf( "Warning: Spatial Reference of Raster is missing.\n" ); printf("Projection of Outlet feature %s.\n",OutletProjectionName); } else if(hSRSRaster!=NULL && hRSOutlet==NULL) { printf( "Warning: Spatial Reference of Outlet feature is missing.\n" ); printf("Projection of Raster datasource %s.\n",RasterProjectionName); } else { printf( "Warning: Spatial References of Outlet feature and Raster data are missing.\n" ); } long countPts=0; // count number of feature countPts=OGR_L_GetFeatureCount(hLayer1,0); // get schema i.e geometry, properties (e.g. ID) hFDefn1 = OGR_L_GetLayerDefn(hLayer1); x = new double[countPts]; y = new double[countPts]; int iField; int nxy=0; id = new int[countPts]; // loop through each feature and get lat,lon and id information OGR_L_ResetReading(hLayer1); while( (hFeature1 = OGR_L_GetNextFeature(hLayer1)) != NULL ) { //hFeature1=OGR_L_GetFeature(hLayer1,j); // get feature info geometry = OGR_F_GetGeometryRef(hFeature1); // get geometry x[nxy] = OGR_G_GetX(geometry, 0); y[nxy] = OGR_G_GetY(geometry, 0); int idfld =OGR_F_GetFieldIndex(hFeature1,"id"); if (idfld >= 0) { hFieldDefn1 = OGR_FD_GetFieldDefn( hFDefn1,idfld); // get field definiton based on index if( OGR_Fld_GetType(hFieldDefn1) == OFTInteger ) { id[nxy] =OGR_F_GetFieldAsInteger( hFeature1, idfld );} // get id value } else { id[nxy]=1;// if there is no id field } nxy++; // count number of outlets point OGR_F_Destroy( hFeature1 ); // destroy feature } *noutlets=nxy; OGR_DS_Destroy( hDS1); // destroy data source return 0; }
static GDALDatasetH CreateOutputDataset(std::vector<OGRLayerH> ahLayers, OGRSpatialReferenceH hSRS, int bGotBounds, OGREnvelope sEnvelop, GDALDriverH hDriver, const char* pszDest, int nXSize, int nYSize, double dfXRes, double dfYRes, int bTargetAlignedPixels, int nBandCount, GDALDataType eOutputType, char** papszCreationOptions, std::vector<double> adfInitVals, int bNoDataSet, double dfNoData) { int bFirstLayer = TRUE; char* pszWKT = NULL; GDALDatasetH hDstDS = NULL; unsigned int i; for( i = 0; i < ahLayers.size(); i++ ) { OGRLayerH hLayer = ahLayers[i]; if (!bGotBounds) { OGREnvelope sLayerEnvelop; if (OGR_L_GetExtent(hLayer, &sLayerEnvelop, TRUE) != OGRERR_NONE) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot get layer extent"); return NULL; } /* Voluntarily increase the extent by a half-pixel size to avoid */ /* missing points on the border */ if (!bTargetAlignedPixels && dfXRes != 0 && dfYRes != 0) { sLayerEnvelop.MinX -= dfXRes / 2; sLayerEnvelop.MaxX += dfXRes / 2; sLayerEnvelop.MinY -= dfYRes / 2; sLayerEnvelop.MaxY += dfYRes / 2; } if (bFirstLayer) { sEnvelop.MinX = sLayerEnvelop.MinX; sEnvelop.MinY = sLayerEnvelop.MinY; sEnvelop.MaxX = sLayerEnvelop.MaxX; sEnvelop.MaxY = sLayerEnvelop.MaxY; if (hSRS == NULL) hSRS = OGR_L_GetSpatialRef(hLayer); bFirstLayer = FALSE; } else { sEnvelop.MinX = MIN(sEnvelop.MinX, sLayerEnvelop.MinX); sEnvelop.MinY = MIN(sEnvelop.MinY, sLayerEnvelop.MinY); sEnvelop.MaxX = MAX(sEnvelop.MaxX, sLayerEnvelop.MaxX); sEnvelop.MaxY = MAX(sEnvelop.MaxY, sLayerEnvelop.MaxY); } } else { if (bFirstLayer) { if (hSRS == NULL) hSRS = OGR_L_GetSpatialRef(hLayer); bFirstLayer = FALSE; } } } if (dfXRes == 0 && dfYRes == 0) { dfXRes = (sEnvelop.MaxX - sEnvelop.MinX) / nXSize; dfYRes = (sEnvelop.MaxY - sEnvelop.MinY) / nYSize; } else if (bTargetAlignedPixels && dfXRes != 0 && dfYRes != 0) { sEnvelop.MinX = floor(sEnvelop.MinX / dfXRes) * dfXRes; sEnvelop.MaxX = ceil(sEnvelop.MaxX / dfXRes) * dfXRes; sEnvelop.MinY = floor(sEnvelop.MinY / dfYRes) * dfYRes; sEnvelop.MaxY = ceil(sEnvelop.MaxY / dfYRes) * dfYRes; } double adfProjection[6]; adfProjection[0] = sEnvelop.MinX; adfProjection[1] = dfXRes; adfProjection[2] = 0; adfProjection[3] = sEnvelop.MaxY; adfProjection[4] = 0; adfProjection[5] = -dfYRes; if (nXSize == 0 && nYSize == 0) { nXSize = (int)(0.5 + (sEnvelop.MaxX - sEnvelop.MinX) / dfXRes); nYSize = (int)(0.5 + (sEnvelop.MaxY - sEnvelop.MinY) / dfYRes); } hDstDS = GDALCreate(hDriver, pszDest, nXSize, nYSize, nBandCount, eOutputType, papszCreationOptions); if (hDstDS == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot create %s", pszDest); return NULL; } GDALSetGeoTransform(hDstDS, adfProjection); if (hSRS) OSRExportToWkt(hSRS, &pszWKT); if (pszWKT) GDALSetProjection(hDstDS, pszWKT); CPLFree(pszWKT); int iBand; /*if( nBandCount == 3 || nBandCount == 4 ) { for(iBand = 0; iBand < nBandCount; iBand++) { GDALRasterBandH hBand = GDALGetRasterBand(hDstDS, iBand + 1); GDALSetRasterColorInterpretation(hBand, (GDALColorInterp)(GCI_RedBand + iBand)); } }*/ if (bNoDataSet) { for(iBand = 0; iBand < nBandCount; iBand++) { GDALRasterBandH hBand = GDALGetRasterBand(hDstDS, iBand + 1); GDALSetRasterNoDataValue(hBand, dfNoData); } } if (adfInitVals.size() != 0) { for(iBand = 0; iBand < MIN(nBandCount,(int)adfInitVals.size()); iBand++) { GDALRasterBandH hBand = GDALGetRasterBand(hDstDS, iBand + 1); GDALFillRaster(hBand, adfInitVals[iBand], 0); } } return hDstDS; }
static CPLErr ProcessLayer( OGRLayerH hSrcLayer, int bSRSIsSet, GDALDatasetH hDstDS, std::vector<int> anBandList, const std::vector<double> &adfBurnValues, int b3D, int bInverse, const char *pszBurnAttribute, char **papszRasterizeOptions, GDALProgressFunc pfnProgress, void* pProgressData ) { /* -------------------------------------------------------------------- */ /* Checkout that SRS are the same. */ /* If -a_srs is specified, skip the test */ /* -------------------------------------------------------------------- */ OGRCoordinateTransformationH hCT = NULL; if (!bSRSIsSet) { OGRSpatialReferenceH hDstSRS = NULL; if( GDALGetProjectionRef( hDstDS ) != NULL ) { char *pszProjection; pszProjection = (char *) GDALGetProjectionRef( hDstDS ); hDstSRS = OSRNewSpatialReference(NULL); if( OSRImportFromWkt( hDstSRS, &pszProjection ) != OGRERR_NONE ) { OSRDestroySpatialReference(hDstSRS); hDstSRS = NULL; } } OGRSpatialReferenceH hSrcSRS = OGR_L_GetSpatialRef(hSrcLayer); if( hDstSRS != NULL && hSrcSRS != NULL ) { if( OSRIsSame(hSrcSRS, hDstSRS) == FALSE ) { hCT = OCTNewCoordinateTransformation(hSrcSRS, hDstSRS); if( hCT == NULL ) { CPLError(CE_Warning, CPLE_AppDefined, "The output raster dataset and the input vector layer do not have the same SRS.\n" "And reprojection of input data did not work. Results might be incorrect."); } } } else if( hDstSRS != NULL && hSrcSRS == NULL ) { CPLError(CE_Warning, CPLE_AppDefined, "The output raster dataset has a SRS, but the input vector layer SRS is unknown.\n" "Ensure input vector has the same SRS, otherwise results might be incorrect."); } else if( hDstSRS == NULL && hSrcSRS != NULL ) { CPLError(CE_Warning, CPLE_AppDefined, "The input vector layer has a SRS, but the output raster dataset SRS is unknown.\n" "Ensure output raster dataset has the same SRS, otherwise results might be incorrect."); } if( hDstSRS != NULL ) { OSRDestroySpatialReference(hDstSRS); } } /* -------------------------------------------------------------------- */ /* Get field index, and check. */ /* -------------------------------------------------------------------- */ int iBurnField = -1; if( pszBurnAttribute ) { iBurnField = OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hSrcLayer ), pszBurnAttribute ); if( iBurnField == -1 ) { CPLError(CE_Failure, CPLE_AppDefined, "Failed to find field %s on layer %s, skipping.", pszBurnAttribute, OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) ); if( hCT != NULL ) OCTDestroyCoordinateTransformation(hCT); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Collect the geometries from this layer, and build list of */ /* burn values. */ /* -------------------------------------------------------------------- */ OGRFeatureH hFeat; std::vector<OGRGeometryH> ahGeometries; std::vector<double> adfFullBurnValues; OGR_L_ResetReading( hSrcLayer ); while( (hFeat = OGR_L_GetNextFeature( hSrcLayer )) != NULL ) { OGRGeometryH hGeom; if( OGR_F_GetGeometryRef( hFeat ) == NULL ) { OGR_F_Destroy( hFeat ); continue; } hGeom = OGR_G_Clone( OGR_F_GetGeometryRef( hFeat ) ); if( hCT != NULL ) { if( OGR_G_Transform(hGeom, hCT) != OGRERR_NONE ) { OGR_F_Destroy( hFeat ); OGR_G_DestroyGeometry(hGeom); continue; } } ahGeometries.push_back( hGeom ); for( unsigned int iBand = 0; iBand < anBandList.size(); iBand++ ) { if( adfBurnValues.size() > 0 ) adfFullBurnValues.push_back( adfBurnValues[MIN(iBand,adfBurnValues.size()-1)] ); else if( pszBurnAttribute ) { adfFullBurnValues.push_back( OGR_F_GetFieldAsDouble( hFeat, iBurnField ) ); } /* I have made the 3D option exclusive to other options since it can be used to modify the value from "-burn value" or "-a attribute_name" */ if( b3D ) { // TODO: get geometry "z" value /* Points and Lines will have their "z" values collected at the point and line levels respectively. However filled polygons (GDALdllImageFilledPolygon) can use some help by getting their "z" values here. */ adfFullBurnValues.push_back( 0.0 ); } } OGR_F_Destroy( hFeat ); } if( hCT != NULL ) OCTDestroyCoordinateTransformation(hCT); /* -------------------------------------------------------------------- */ /* If we are in inverse mode, we add one extra ring around the */ /* whole dataset to invert the concept of insideness and then */ /* merge everything into one geometry collection. */ /* -------------------------------------------------------------------- */ if( bInverse ) { if( ahGeometries.size() == 0 ) { for( unsigned int iBand = 0; iBand < anBandList.size(); iBand++ ) { if( adfBurnValues.size() > 0 ) adfFullBurnValues.push_back( adfBurnValues[MIN(iBand,adfBurnValues.size()-1)] ); else /* FIXME? Not sure what to do exactly in the else case, but we must insert a value */ adfFullBurnValues.push_back( 0.0 ); } } InvertGeometries( hDstDS, ahGeometries ); } /* -------------------------------------------------------------------- */ /* Perform the burn. */ /* -------------------------------------------------------------------- */ CPLErr eErr = GDALRasterizeGeometries( hDstDS, static_cast<int>(anBandList.size()), &(anBandList[0]), static_cast<int>(ahGeometries.size()), &(ahGeometries[0]), NULL, NULL, &(adfFullBurnValues[0]), papszRasterizeOptions, pfnProgress, pProgressData ); /* -------------------------------------------------------------------- */ /* Cleanup geometries. */ /* -------------------------------------------------------------------- */ int iGeom; for( iGeom = static_cast<int>(ahGeometries.size())-1; iGeom >= 0; iGeom-- ) OGR_G_DestroyGeometry( ahGeometries[iGeom] ); return eErr; }
int main(int argc, char *argv[]) { struct GModule *module; struct _param { struct Option *dsn, *out, *layer, *spat, *where, *min_area; struct Option *snap, *type, *outloc, *cnames; } param; struct _flag { struct Flag *list, *tlist, *no_clean, *z, *notab, *region; struct Flag *over, *extend, *formats, *tolower, *no_import; } flag; int i, j, layer, arg_s_num, nogeom, ncnames; float xmin, ymin, xmax, ymax; int ncols = 0, type; double min_area, snap; char buf[2000], namebuf[2000], tempvect[GNAME_MAX]; char *separator; struct Key_Value *loc_proj_info, *loc_proj_units; struct Key_Value *proj_info, *proj_units; struct Cell_head cellhd, loc_wind, cur_wind; char error_msg[8192]; /* Vector */ struct Map_info Map, Tmp, *Out; int cat; /* Attributes */ struct field_info *Fi; dbDriver *driver; dbString sql, strval; int dim, with_z; /* OGR */ OGRDataSourceH Ogr_ds; OGRLayerH Ogr_layer; OGRFieldDefnH Ogr_field; char *Ogr_fieldname; OGRFieldType Ogr_ftype; OGRFeatureH Ogr_feature; OGRFeatureDefnH Ogr_featuredefn; OGRGeometryH Ogr_geometry, Ogr_oRing, poSpatialFilter; OGRSpatialReferenceH Ogr_projection; OGREnvelope oExt; OGRwkbGeometryType Ogr_geom_type; int OFTIntegerListlength; char *output; char **layer_names; /* names of layers to be imported */ int *layers; /* layer indexes */ int nlayers; /* number of layers to import */ char **available_layer_names; /* names of layers to be imported */ int navailable_layers; int layer_id; unsigned int n_features, feature_count; int overwrite; double area_size; int use_tmp_vect; xmin = ymin = xmax = ymax = 0.0; loc_proj_info = loc_proj_units = NULL; Ogr_ds = Ogr_oRing = poSpatialFilter = NULL; OFTIntegerListlength = 40; /* hack due to limitation in OGR */ area_size = 0.0; use_tmp_vect = FALSE; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("import")); module->description = _("Converts vector data into a GRASS vector map using OGR library."); param.dsn = G_define_option(); param.dsn->key = "dsn"; param.dsn->type = TYPE_STRING; param.dsn->required =YES; param.dsn->label = _("OGR datasource name"); param.dsn->description = _("Examples:\n" "\t\tESRI Shapefile: directory containing shapefiles\n" "\t\tMapInfo File: directory containing mapinfo files"); param.layer = G_define_option(); param.layer->key = "layer"; param.layer->type = TYPE_STRING; param.layer->required = NO; param.layer->multiple = YES; param.layer->label = _("OGR layer name. If not given, all available layers are imported"); param.layer->description = _("Examples:\n" "\t\tESRI Shapefile: shapefile name\n" "\t\tMapInfo File: mapinfo file name"); param.layer->guisection = _("Selection"); param.out = G_define_standard_option(G_OPT_V_OUTPUT); param.out->required = NO; param.out->guisection = _("Output"); param.spat = G_define_option(); param.spat->key = "spatial"; param.spat->type = TYPE_DOUBLE; param.spat->multiple = YES; param.spat->required = NO; param.spat->key_desc = "xmin,ymin,xmax,ymax"; param.spat->label = _("Import subregion only"); param.spat->guisection = _("Selection"); param.spat->description = _("Format: xmin,ymin,xmax,ymax - usually W,S,E,N"); param.where = G_define_standard_option(G_OPT_DB_WHERE); param.where->guisection = _("Selection"); param.min_area = G_define_option(); param.min_area->key = "min_area"; param.min_area->type = TYPE_DOUBLE; param.min_area->required = NO; param.min_area->answer = "0.0001"; param.min_area->label = _("Minimum size of area to be imported (square units)"); param.min_area->guisection = _("Selection"); param.min_area->description = _("Smaller areas and " "islands are ignored. Should be greater than snap^2"); param.type = G_define_standard_option(G_OPT_V_TYPE); param.type->options = "point,line,boundary,centroid"; param.type->answer = ""; param.type->description = _("Optionally change default input type"); param.type->descriptions = _("point;import area centroids as points;" "line;import area boundaries as lines;" "boundary;import lines as area boundaries;" "centroid;import points as centroids"); param.type->guisection = _("Selection"); param.snap = G_define_option(); param.snap->key = "snap"; param.snap->type = TYPE_DOUBLE; param.snap->required = NO; param.snap->answer = "-1"; param.snap->label = _("Snapping threshold for boundaries"); param.snap->description = _("'-1' for no snap"); param.outloc = G_define_option(); param.outloc->key = "location"; param.outloc->type = TYPE_STRING; param.outloc->required = NO; param.outloc->description = _("Name for new location to create"); param.outloc->key_desc = "name"; param.cnames = G_define_option(); param.cnames->key = "cnames"; param.cnames->type = TYPE_STRING; param.cnames->required = NO; param.cnames->multiple = YES; param.cnames->description = _("List of column names to be used instead of original names, " "first is used for category column"); param.cnames->guisection = _("Attributes"); flag.list = G_define_flag(); flag.list->key = 'l'; flag.list->description = _("List available OGR layers in data source and exit"); flag.list->suppress_required = YES; flag.list->guisection = _("Print"); flag.tlist = G_define_flag(); flag.tlist->key = 'a'; flag.tlist->description = _("List available OGR layers including feature types " "in data source and exit"); flag.tlist->suppress_required = YES; flag.tlist->guisection = _("Print"); flag.formats = G_define_flag(); flag.formats->key = 'f'; flag.formats->description = _("List supported formats and exit"); flag.formats->suppress_required = YES; flag.formats->guisection = _("Print"); /* if using -c, you lose topological information ! */ flag.no_clean = G_define_flag(); flag.no_clean->key = 'c'; flag.no_clean->description = _("Do not clean polygons (not recommended)"); flag.no_clean->guisection = _("Output"); flag.z = G_define_flag(); flag.z->key = 'z'; flag.z->description = _("Create 3D output"); flag.z->guisection = _("Output"); flag.notab = G_define_flag(); flag.notab->key = 't'; flag.notab->description = _("Do not create attribute table"); flag.notab->guisection = _("Attributes"); flag.over = G_define_flag(); flag.over->key = 'o'; flag.over->description = _("Override dataset projection (use location's projection)"); flag.region = G_define_flag(); flag.region->key = 'r'; flag.region->guisection = _("Selection"); flag.region->description = _("Limit import to the current region"); flag.extend = G_define_flag(); flag.extend->key = 'e'; flag.extend->description = _("Extend location extents based on new dataset"); flag.tolower = G_define_flag(); flag.tolower->key = 'w'; flag.tolower->description = _("Change column names to lowercase characters"); flag.tolower->guisection = _("Attributes"); flag.no_import = G_define_flag(); flag.no_import->key = 'i'; flag.no_import->description = _("Create the location specified by the \"location\" parameter and exit." " Do not import the vector data."); /* The parser checks if the map already exists in current mapset, this is * wrong if location options is used, so we switch out the check and do it * in the module after the parser */ overwrite = G_check_overwrite(argc, argv); if (G_parser(argc, argv)) exit(EXIT_FAILURE); G_begin_polygon_area_calculations(); /* Used in geom() */ OGRRegisterAll(); /* list supported formats */ if (flag.formats->answer) { int iDriver; G_message(_("Available OGR Drivers:")); for (iDriver = 0; iDriver < OGRGetDriverCount(); iDriver++) { OGRSFDriverH poDriver = OGRGetDriver(iDriver); const char *pszRWFlag; if (OGR_Dr_TestCapability(poDriver, ODrCCreateDataSource)) pszRWFlag = "rw"; else pszRWFlag = "ro"; fprintf(stdout, " %s (%s): %s\n", OGR_Dr_GetName(poDriver), pszRWFlag, OGR_Dr_GetName(poDriver)); } exit(EXIT_SUCCESS); } if (param.dsn->answer == NULL) { G_fatal_error(_("Required parameter <%s> not set"), param.dsn->key); } min_area = atof(param.min_area->answer); snap = atof(param.snap->answer); type = Vect_option_to_types(param.type); ncnames = 0; if (param.cnames->answers) { i = 0; while (param.cnames->answers[i++]) { ncnames++; } } /* Open OGR DSN */ Ogr_ds = NULL; if (strlen(param.dsn->answer) > 0) Ogr_ds = OGROpen(param.dsn->answer, FALSE, NULL); if (Ogr_ds == NULL) G_fatal_error(_("Unable to open data source <%s>"), param.dsn->answer); /* Make a list of available layers */ navailable_layers = OGR_DS_GetLayerCount(Ogr_ds); available_layer_names = (char **)G_malloc(navailable_layers * sizeof(char *)); if (flag.list->answer || flag.tlist->answer) G_message(_("Data source <%s> (format '%s') contains %d layers:"), param.dsn->answer, OGR_Dr_GetName(OGR_DS_GetDriver(Ogr_ds)), navailable_layers); for (i = 0; i < navailable_layers; i++) { Ogr_layer = OGR_DS_GetLayer(Ogr_ds, i); Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer); Ogr_geom_type = OGR_FD_GetGeomType(Ogr_featuredefn); available_layer_names[i] = G_store((char *)OGR_FD_GetName(Ogr_featuredefn)); if (flag.tlist->answer) fprintf(stdout, "%s (%s)\n", available_layer_names[i], OGRGeometryTypeToName(Ogr_geom_type)); else if (flag.list->answer) fprintf(stdout, "%s\n", available_layer_names[i]); } if (flag.list->answer || flag.tlist->answer) { fflush(stdout); exit(EXIT_SUCCESS); } /* Make a list of layers to be imported */ if (param.layer->answer) { /* From option */ nlayers = 0; while (param.layer->answers[nlayers]) nlayers++; layer_names = (char **)G_malloc(nlayers * sizeof(char *)); layers = (int *)G_malloc(nlayers * sizeof(int)); for (i = 0; i < nlayers; i++) { layer_names[i] = G_store(param.layer->answers[i]); /* Find it in the source */ layers[i] = -1; for (j = 0; j < navailable_layers; j++) { if (strcmp(available_layer_names[j], layer_names[i]) == 0) { layers[i] = j; break; } } if (layers[i] == -1) G_fatal_error(_("Layer <%s> not available"), layer_names[i]); } } else { /* use list of all layers */ nlayers = navailable_layers; layer_names = available_layer_names; layers = (int *)G_malloc(nlayers * sizeof(int)); for (i = 0; i < nlayers; i++) layers[i] = i; } if (param.out->answer) { output = G_store(param.out->answer); } else { if (nlayers < 1) G_fatal_error(_("No OGR layers available")); output = G_store(layer_names[0]); G_message(_("All available OGR layers will be imported into vector map <%s>"), output); } if (!param.outloc->answer) { /* Check if the map exists */ if (G_find_vector2(output, G_mapset()) && !overwrite) G_fatal_error(_("Vector map <%s> already exists"), output); } /* Get first imported layer to use for extents and projection check */ Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layers[0]); if (flag.region->answer) { if (param.spat->answer) G_fatal_error(_("Select either the current region flag or the spatial option, not both")); G_get_window(&cur_wind); xmin = cur_wind.west; xmax = cur_wind.east; ymin = cur_wind.south; ymax = cur_wind.north; } if (param.spat->answer) { /* See as reference: gdal/ogr/ogr_capi_test.c */ /* cut out a piece of the map */ /* order: xmin,ymin,xmax,ymax */ arg_s_num = 0; i = 0; while (param.spat->answers[i]) { if (i == 0) xmin = atof(param.spat->answers[i]); if (i == 1) ymin = atof(param.spat->answers[i]); if (i == 2) xmax = atof(param.spat->answers[i]); if (i == 3) ymax = atof(param.spat->answers[i]); arg_s_num++; i++; } if (arg_s_num != 4) G_fatal_error(_("4 parameters required for 'spatial' parameter")); } if (param.spat->answer || flag.region->answer) { G_debug(2, "cut out with boundaries: xmin:%f ymin:%f xmax:%f ymax:%f", xmin, ymin, xmax, ymax); /* in theory this could be an irregular polygon */ poSpatialFilter = OGR_G_CreateGeometry(wkbPolygon); Ogr_oRing = OGR_G_CreateGeometry(wkbLinearRing); OGR_G_AddPoint(Ogr_oRing, xmin, ymin, 0.0); OGR_G_AddPoint(Ogr_oRing, xmin, ymax, 0.0); OGR_G_AddPoint(Ogr_oRing, xmax, ymax, 0.0); OGR_G_AddPoint(Ogr_oRing, xmax, ymin, 0.0); OGR_G_AddPoint(Ogr_oRing, xmin, ymin, 0.0); OGR_G_AddGeometryDirectly(poSpatialFilter, Ogr_oRing); OGR_L_SetSpatialFilter(Ogr_layer, poSpatialFilter); } if (param.where->answer) { /* select by attribute */ OGR_L_SetAttributeFilter(Ogr_layer, param.where->answer); } /* fetch boundaries */ if ((OGR_L_GetExtent(Ogr_layer, &oExt, 1)) == OGRERR_NONE) { G_get_window(&cellhd); cellhd.north = oExt.MaxY; cellhd.south = oExt.MinY; cellhd.west = oExt.MinX; cellhd.east = oExt.MaxX; cellhd.rows = 20; /* TODO - calculate useful values */ cellhd.cols = 20; cellhd.ns_res = (cellhd.north - cellhd.south) / cellhd.rows; cellhd.ew_res = (cellhd.east - cellhd.west) / cellhd.cols; } else { cellhd.north = 1.; cellhd.south = 0.; cellhd.west = 0.; cellhd.east = 1.; cellhd.top = 1.; cellhd.bottom = 1.; cellhd.rows = 1; cellhd.rows3 = 1; cellhd.cols = 1; cellhd.cols3 = 1; cellhd.depths = 1; cellhd.ns_res = 1.; cellhd.ns_res3 = 1.; cellhd.ew_res = 1.; cellhd.ew_res3 = 1.; cellhd.tb_res = 1.; } /* suppress boundary splitting ? */ if (flag.no_clean->answer) { split_distance = -1.; } else { split_distance = 0.; area_size = sqrt((cellhd.east - cellhd.west) * (cellhd.north - cellhd.south)); } /* Fetch input map projection in GRASS form. */ proj_info = NULL; proj_units = NULL; Ogr_projection = OGR_L_GetSpatialRef(Ogr_layer); /* should not be freed later */ /* Do we need to create a new location? */ if (param.outloc->answer != NULL) { /* Convert projection information non-interactively as we can't * assume the user has a terminal open */ if (GPJ_osr_to_grass(&cellhd, &proj_info, &proj_units, Ogr_projection, 0) < 0) { G_fatal_error(_("Unable to convert input map projection to GRASS " "format; cannot create new location.")); } else { G_make_location(param.outloc->answer, &cellhd, proj_info, proj_units, NULL); G_message(_("Location <%s> created"), param.outloc->answer); } /* If the i flag is set, clean up? and exit here */ if(flag.no_import->answer) { exit(EXIT_SUCCESS); } } else { int err = 0; /* Projection only required for checking so convert non-interactively */ if (GPJ_osr_to_grass(&cellhd, &proj_info, &proj_units, Ogr_projection, 0) < 0) G_warning(_("Unable to convert input map projection information to " "GRASS format for checking")); /* Does the projection of the current location match the dataset? */ /* G_get_window seems to be unreliable if the location has been changed */ G__get_window(&loc_wind, "", "DEFAULT_WIND", "PERMANENT"); /* fetch LOCATION PROJ info */ if (loc_wind.proj != PROJECTION_XY) { loc_proj_info = G_get_projinfo(); loc_proj_units = G_get_projunits(); } if (flag.over->answer) { cellhd.proj = loc_wind.proj; cellhd.zone = loc_wind.zone; G_message(_("Over-riding projection check")); } else if (loc_wind.proj != cellhd.proj || (err = G_compare_projections(loc_proj_info, loc_proj_units, proj_info, proj_units)) != TRUE) { int i_value; strcpy(error_msg, _("Projection of dataset does not" " appear to match current location.\n\n")); /* TODO: output this info sorted by key: */ if (loc_wind.proj != cellhd.proj || err != -2) { if (loc_proj_info != NULL) { strcat(error_msg, _("GRASS LOCATION PROJ_INFO is:\n")); for (i_value = 0; i_value < loc_proj_info->nitems; i_value++) sprintf(error_msg + strlen(error_msg), "%s: %s\n", loc_proj_info->key[i_value], loc_proj_info->value[i_value]); strcat(error_msg, "\n"); } if (proj_info != NULL) { strcat(error_msg, _("Import dataset PROJ_INFO is:\n")); for (i_value = 0; i_value < proj_info->nitems; i_value++) sprintf(error_msg + strlen(error_msg), "%s: %s\n", proj_info->key[i_value], proj_info->value[i_value]); } else { strcat(error_msg, _("Import dataset PROJ_INFO is:\n")); if (cellhd.proj == PROJECTION_XY) sprintf(error_msg + strlen(error_msg), "Dataset proj = %d (unreferenced/unknown)\n", cellhd.proj); else if (cellhd.proj == PROJECTION_LL) sprintf(error_msg + strlen(error_msg), "Dataset proj = %d (lat/long)\n", cellhd.proj); else if (cellhd.proj == PROJECTION_UTM) sprintf(error_msg + strlen(error_msg), "Dataset proj = %d (UTM), zone = %d\n", cellhd.proj, cellhd.zone); else if (cellhd.proj == PROJECTION_SP) sprintf(error_msg + strlen(error_msg), "Dataset proj = %d (State Plane), zone = %d\n", cellhd.proj, cellhd.zone); else sprintf(error_msg + strlen(error_msg), "Dataset proj = %d (unknown), zone = %d\n", cellhd.proj, cellhd.zone); } } else { if (loc_proj_units != NULL) { strcat(error_msg, "GRASS LOCATION PROJ_UNITS is:\n"); for (i_value = 0; i_value < loc_proj_units->nitems; i_value++) sprintf(error_msg + strlen(error_msg), "%s: %s\n", loc_proj_units->key[i_value], loc_proj_units->value[i_value]); strcat(error_msg, "\n"); } if (proj_units != NULL) { strcat(error_msg, "Import dataset PROJ_UNITS is:\n"); for (i_value = 0; i_value < proj_units->nitems; i_value++) sprintf(error_msg + strlen(error_msg), "%s: %s\n", proj_units->key[i_value], proj_units->value[i_value]); } } sprintf(error_msg + strlen(error_msg), _("\nYou can use the -o flag to %s to override this projection check.\n"), G_program_name()); strcat(error_msg, _("Consider generating a new location with 'location' parameter" " from input data set.\n")); G_fatal_error(error_msg); } else { G_message(_("Projection of input dataset and current location " "appear to match")); } } db_init_string(&sql); db_init_string(&strval); /* open output vector */ /* strip any @mapset from vector output name */ G_find_vector(output, G_mapset()); Vect_open_new(&Map, output, flag.z->answer != 0); Out = ⤅ n_polygon_boundaries = 0; if (!flag.no_clean->answer) { /* check if we need a tmp vector */ /* estimate distance for boundary splitting --> */ for (layer = 0; layer < nlayers; layer++) { layer_id = layers[layer]; Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id); Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer); n_features = feature_count = 0; n_features = OGR_L_GetFeatureCount(Ogr_layer, 1); OGR_L_ResetReading(Ogr_layer); /* count polygons and isles */ G_message(_("Counting polygons for %d features (OGR layer <%s>)..."), n_features, layer_names[layer]); while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) { G_percent(feature_count++, n_features, 1); /* show something happens */ /* Geometry */ Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature); if (Ogr_geometry != NULL) { poly_count(Ogr_geometry, (type & GV_BOUNDARY)); } OGR_F_Destroy(Ogr_feature); } } G_debug(1, "n polygon boundaries: %d", n_polygon_boundaries); if (n_polygon_boundaries > 50) { split_distance = area_size / log(n_polygon_boundaries); /* divisor is the handle: increase divisor to decrease split_distance */ split_distance = split_distance / 5.; G_debug(1, "root of area size: %f", area_size); G_verbose_message(_("Boundary splitting distance in map units: %G"), split_distance); } /* <-- estimate distance for boundary splitting */ use_tmp_vect = n_polygon_boundaries > 0; if (use_tmp_vect) { /* open temporary vector, do the work in the temporary vector * at the end copy alive lines to output vector * in case of polygons this reduces the coor file size by a factor of 2 to 5 * only needed when cleaning polygons */ sprintf(tempvect, "%s_tmp", output); G_verbose_message(_("Using temporary vector <%s>"), tempvect); Vect_open_new(&Tmp, tempvect, flag.z->answer != 0); Out = &Tmp; } } Vect_hist_command(&Map); /* Points and lines are written immediately with categories. Boundaries of polygons are * written to the vector then cleaned and centroids are calculated for all areas in cleaan vector. * Then second pass through finds all centroids in each polygon feature and adds its category * to the centroid. The result is that one centroids may have 0, 1 ore more categories * of one ore more (more input layers) fields. */ with_z = 0; for (layer = 0; layer < nlayers; layer++) { layer_id = layers[layer]; Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id); Ogr_featuredefn = OGR_L_GetLayerDefn(Ogr_layer); /* Add DB link */ if (!flag.notab->answer) { char *cat_col_name = GV_KEY_COLUMN; if (nlayers == 1) { /* one layer only */ Fi = Vect_default_field_info(&Map, layer + 1, NULL, GV_1TABLE); } else { Fi = Vect_default_field_info(&Map, layer + 1, NULL, GV_MTABLE); } if (ncnames > 0) { cat_col_name = param.cnames->answers[0]; } Vect_map_add_dblink(&Map, layer + 1, layer_names[layer], Fi->table, cat_col_name, Fi->database, Fi->driver); ncols = OGR_FD_GetFieldCount(Ogr_featuredefn); G_debug(2, "%d columns", ncols); /* Create table */ sprintf(buf, "create table %s (%s integer", Fi->table, cat_col_name); db_set_string(&sql, buf); for (i = 0; i < ncols; i++) { Ogr_field = OGR_FD_GetFieldDefn(Ogr_featuredefn, i); Ogr_ftype = OGR_Fld_GetType(Ogr_field); G_debug(3, "Ogr_ftype: %i", Ogr_ftype); /* look up below */ if (i < ncnames - 1) { Ogr_fieldname = G_store(param.cnames->answers[i + 1]); } else { /* Change column names to [A-Za-z][A-Za-z0-9_]* */ Ogr_fieldname = G_store(OGR_Fld_GetNameRef(Ogr_field)); G_debug(3, "Ogr_fieldname: '%s'", Ogr_fieldname); G_str_to_sql(Ogr_fieldname); G_debug(3, "Ogr_fieldname: '%s'", Ogr_fieldname); } /* avoid that we get the 'cat' column twice */ if (strcmp(Ogr_fieldname, GV_KEY_COLUMN) == 0) { sprintf(namebuf, "%s_", Ogr_fieldname); Ogr_fieldname = G_store(namebuf); } /* captial column names are a pain in SQL */ if (flag.tolower->answer) G_str_to_lower(Ogr_fieldname); if (strcmp(OGR_Fld_GetNameRef(Ogr_field), Ogr_fieldname) != 0) { G_warning(_("Column name changed: '%s' -> '%s'"), OGR_Fld_GetNameRef(Ogr_field), Ogr_fieldname); } /** Simple 32bit integer OFTInteger = 0 **/ /** List of 32bit integers OFTIntegerList = 1 **/ /** Double Precision floating point OFTReal = 2 **/ /** List of doubles OFTRealList = 3 **/ /** String of ASCII chars OFTString = 4 **/ /** Array of strings OFTStringList = 5 **/ /** Double byte string (unsupported) OFTWideString = 6 **/ /** List of wide strings (unsupported) OFTWideStringList = 7 **/ /** Raw Binary data (unsupported) OFTBinary = 8 **/ /** OFTDate = 9 **/ /** OFTTime = 10 **/ /** OFTDateTime = 11 **/ if (Ogr_ftype == OFTInteger) { sprintf(buf, ", %s integer", Ogr_fieldname); } else if (Ogr_ftype == OFTIntegerList) { /* hack: treat as string */ sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname, OFTIntegerListlength); G_warning(_("Writing column <%s> with fixed length %d chars (may be truncated)"), Ogr_fieldname, OFTIntegerListlength); } else if (Ogr_ftype == OFTReal) { sprintf(buf, ", %s double precision", Ogr_fieldname); #if GDAL_VERSION_NUM >= 1320 } else if (Ogr_ftype == OFTDate) { sprintf(buf, ", %s date", Ogr_fieldname); } else if (Ogr_ftype == OFTTime) { sprintf(buf, ", %s time", Ogr_fieldname); } else if (Ogr_ftype == OFTDateTime) { sprintf(buf, ", %s datetime", Ogr_fieldname); #endif } else if (Ogr_ftype == OFTString) { int fwidth; fwidth = OGR_Fld_GetWidth(Ogr_field); /* TODO: read all records first and find the longest string length */ if (fwidth == 0) { G_warning(_("Width for column %s set to 255 (was not specified by OGR), " "some strings may be truncated!"), Ogr_fieldname); fwidth = 255; } sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname, fwidth); } else if (Ogr_ftype == OFTStringList) { /* hack: treat as string */ sprintf(buf, ", %s varchar ( %d )", Ogr_fieldname, OFTIntegerListlength); G_warning(_("Writing column %s with fixed length %d chars (may be truncated)"), Ogr_fieldname, OFTIntegerListlength); } else { G_warning(_("Column type not supported (%s)"), Ogr_fieldname); buf[0] = 0; } db_append_string(&sql, buf); G_free(Ogr_fieldname); } db_append_string(&sql, ")"); G_debug(3, db_get_string(&sql)); driver = db_start_driver_open_database(Fi->driver, Vect_subst_var(Fi->database, &Map)); if (driver == NULL) { G_fatal_error(_("Unable open database <%s> by driver <%s>"), Vect_subst_var(Fi->database, &Map), Fi->driver); } if (db_execute_immediate(driver, &sql) != DB_OK) { db_close_database(driver); db_shutdown_driver(driver); G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql)); } if (db_create_index2(driver, Fi->table, cat_col_name) != DB_OK) G_warning(_("Unable to create index for table <%s>, key <%s>"), Fi->table, cat_col_name); if (db_grant_on_table (driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK) G_fatal_error(_("Unable to grant privileges on table <%s>"), Fi->table); db_begin_transaction(driver); } /* Import feature */ cat = 1; nogeom = 0; OGR_L_ResetReading(Ogr_layer); n_features = feature_count = 0; n_features = OGR_L_GetFeatureCount(Ogr_layer, 1); G_important_message(_("Importing %d features (OGR layer <%s>)..."), n_features, layer_names[layer]); while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) { G_percent(feature_count++, n_features, 1); /* show something happens */ /* Geometry */ Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature); if (Ogr_geometry == NULL) { nogeom++; } else { dim = OGR_G_GetCoordinateDimension(Ogr_geometry); if (dim > 2) with_z = 1; geom(Ogr_geometry, Out, layer + 1, cat, min_area, type, flag.no_clean->answer); } /* Attributes */ if (!flag.notab->answer) { sprintf(buf, "insert into %s values ( %d", Fi->table, cat); db_set_string(&sql, buf); for (i = 0; i < ncols; i++) { Ogr_field = OGR_FD_GetFieldDefn(Ogr_featuredefn, i); Ogr_ftype = OGR_Fld_GetType(Ogr_field); if (OGR_F_IsFieldSet(Ogr_feature, i)) { if (Ogr_ftype == OFTInteger || Ogr_ftype == OFTReal) { sprintf(buf, ", %s", OGR_F_GetFieldAsString(Ogr_feature, i)); #if GDAL_VERSION_NUM >= 1320 /* should we use OGR_F_GetFieldAsDateTime() here ? */ } else if (Ogr_ftype == OFTDate || Ogr_ftype == OFTTime || Ogr_ftype == OFTDateTime) { char *newbuf; db_set_string(&strval, (char *) OGR_F_GetFieldAsString(Ogr_feature, i)); db_double_quote_string(&strval); sprintf(buf, ", '%s'", db_get_string(&strval)); newbuf = G_str_replace(buf, "/", "-"); /* fix 2001/10/21 to 2001-10-21 */ sprintf(buf, "%s", newbuf); #endif } else if (Ogr_ftype == OFTString || Ogr_ftype == OFTIntegerList) { db_set_string(&strval, (char *) OGR_F_GetFieldAsString(Ogr_feature, i)); db_double_quote_string(&strval); sprintf(buf, ", '%s'", db_get_string(&strval)); } } else { /* G_warning (_("Column value not set" )); */ if (Ogr_ftype == OFTInteger || Ogr_ftype == OFTReal) { sprintf(buf, ", NULL"); #if GDAL_VERSION_NUM >= 1320 } else if (Ogr_ftype == OFTString || Ogr_ftype == OFTIntegerList || Ogr_ftype == OFTDate) { #else } else if (Ogr_ftype == OFTString || Ogr_ftype == OFTIntegerList) { #endif sprintf(buf, ", ''"); } } db_append_string(&sql, buf); } db_append_string(&sql, " )"); G_debug(3, db_get_string(&sql)); if (db_execute_immediate(driver, &sql) != DB_OK) { db_close_database(driver); db_shutdown_driver(driver); G_fatal_error(_("Cannot insert new row: %s"), db_get_string(&sql)); } } OGR_F_Destroy(Ogr_feature); cat++; } G_percent(1, 1, 1); /* finish it */ if (!flag.notab->answer) { db_commit_transaction(driver); db_close_database_shutdown_driver(driver); } if (nogeom > 0) G_warning(_("%d %s without geometry"), nogeom, nogeom == 1 ? "feature" : "features"); } separator = "-----------------------------------------------------"; G_message("%s", separator); if (use_tmp_vect) { /* TODO: is it necessary to build here? probably not, consumes time */ /* GV_BUILD_BASE is sufficient to toggle boundary cleaning */ Vect_build_partial(&Tmp, GV_BUILD_BASE); } if (use_tmp_vect && !flag.no_clean->answer && Vect_get_num_primitives(Out, GV_BOUNDARY) > 0) { int ret, centr, ncentr, otype, n_overlaps, n_nocat; CENTR *Centr; struct spatial_index si; double x, y, total_area, overlap_area, nocat_area; struct bound_box box; struct line_pnts *Points; int nmodif; Points = Vect_new_line_struct(); G_message("%s", separator); G_warning(_("Cleaning polygons, result is not guaranteed!")); if (snap >= 0) { G_message("%s", separator); G_message(_("Snapping boundaries (threshold = %.3e)..."), snap); Vect_snap_lines(&Tmp, GV_BOUNDARY, snap, NULL); } /* It is not to clean to snap centroids, but I have seen data with 2 duplicate polygons * (as far as decimal places were printed) and centroids were not identical */ /* Disabled, because overlapping polygons result in many duplicate centroids anyway */ /* fprintf ( stderr, separator ); fprintf ( stderr, "Snap centroids (threshold 0.000001):\n" ); Vect_snap_lines ( &Map, GV_CENTROID, 0.000001, NULL, stderr ); */ G_message("%s", separator); G_message(_("Breaking polygons...")); Vect_break_polygons(&Tmp, GV_BOUNDARY, NULL); /* It is important to remove also duplicate centroids in case of duplicate input polygons */ G_message("%s", separator); G_message(_("Removing duplicates...")); Vect_remove_duplicates(&Tmp, GV_BOUNDARY | GV_CENTROID, NULL); /* in non-pathological cases, the bulk of the cleaning is now done */ /* Vect_clean_small_angles_at_nodes() can change the geometry so that new intersections * are created. We must call Vect_break_lines(), Vect_remove_duplicates() * and Vect_clean_small_angles_at_nodes() until no more small angles are found */ do { G_message("%s", separator); G_message(_("Breaking boundaries...")); Vect_break_lines(&Tmp, GV_BOUNDARY, NULL); G_message("%s", separator); G_message(_("Removing duplicates...")); Vect_remove_duplicates(&Tmp, GV_BOUNDARY, NULL); G_message("%s", separator); G_message(_("Cleaning boundaries at nodes...")); nmodif = Vect_clean_small_angles_at_nodes(&Tmp, GV_BOUNDARY, NULL); } while (nmodif > 0); /* merge boundaries */ G_message("%s", separator); G_message(_("Merging boundaries...")); Vect_merge_lines(&Tmp, GV_BOUNDARY, NULL, NULL); G_message("%s", separator); if (type & GV_BOUNDARY) { /* that means lines were converted to boundaries */ G_message(_("Changing boundary dangles to lines...")); Vect_chtype_dangles(&Tmp, -1.0, NULL); } else { G_message(_("Removing dangles...")); Vect_remove_dangles(&Tmp, GV_BOUNDARY, -1.0, NULL); } G_message("%s", separator); if (type & GV_BOUNDARY) { G_message(_("Changing boundary bridges to lines...")); Vect_chtype_bridges(&Tmp, NULL); } else { G_message(_("Removing bridges...")); Vect_remove_bridges(&Tmp, NULL); } /* Boundaries are hopefully clean, build areas */ G_message("%s", separator); Vect_build_partial(&Tmp, GV_BUILD_ATTACH_ISLES); /* Calculate new centroids for all areas, centroids have the same id as area */ ncentr = Vect_get_num_areas(&Tmp); G_debug(3, "%d centroids/areas", ncentr); Centr = (CENTR *) G_calloc(ncentr + 1, sizeof(CENTR)); Vect_spatial_index_init(&si, 0); for (centr = 1; centr <= ncentr; centr++) { Centr[centr].valid = 0; Centr[centr].cats = Vect_new_cats_struct(); ret = Vect_get_point_in_area(&Tmp, centr, &x, &y); if (ret < 0) { G_warning(_("Unable to calculate area centroid")); continue; } Centr[centr].x = x; Centr[centr].y = y; Centr[centr].valid = 1; box.N = box.S = y; box.E = box.W = x; box.T = box.B = 0; Vect_spatial_index_add_item(&si, centr, &box); } /* Go through all layers and find centroids for each polygon */ for (layer = 0; layer < nlayers; layer++) { G_message("%s", separator); G_message(_("Finding centroids for OGR layer <%s>..."), layer_names[layer]); layer_id = layers[layer]; Ogr_layer = OGR_DS_GetLayer(Ogr_ds, layer_id); n_features = OGR_L_GetFeatureCount(Ogr_layer, 1); OGR_L_ResetReading(Ogr_layer); cat = 0; /* field = layer + 1 */ G_percent(cat, n_features, 2); while ((Ogr_feature = OGR_L_GetNextFeature(Ogr_layer)) != NULL) { cat++; G_percent(cat, n_features, 2); /* Geometry */ Ogr_geometry = OGR_F_GetGeometryRef(Ogr_feature); if (Ogr_geometry != NULL) { centroid(Ogr_geometry, Centr, &si, layer + 1, cat, min_area, type); } OGR_F_Destroy(Ogr_feature); } } /* Write centroids */ G_message("%s", separator); G_message(_("Writing centroids...")); n_overlaps = n_nocat = 0; total_area = overlap_area = nocat_area = 0.0; for (centr = 1; centr <= ncentr; centr++) { double area; G_percent(centr, ncentr, 2); area = Vect_get_area_area(&Tmp, centr); total_area += area; if (!(Centr[centr].valid)) { continue; } if (Centr[centr].cats->n_cats == 0) { nocat_area += area; n_nocat++; continue; } if (Centr[centr].cats->n_cats > 1) { Vect_cat_set(Centr[centr].cats, nlayers + 1, Centr[centr].cats->n_cats); overlap_area += area; n_overlaps++; } Vect_reset_line(Points); Vect_append_point(Points, Centr[centr].x, Centr[centr].y, 0.0); if (type & GV_POINT) otype = GV_POINT; else otype = GV_CENTROID; Vect_write_line(&Tmp, otype, Points, Centr[centr].cats); } if (Centr) G_free(Centr); Vect_spatial_index_destroy(&si); if (n_overlaps > 0) { G_warning(_("%d areas represent more (overlapping) features, because polygons overlap " "in input layer(s). Such areas are linked to more than 1 row in attribute table. " "The number of features for those areas is stored as category in layer %d"), n_overlaps, nlayers + 1); } G_message("%s", separator); Vect_hist_write(&Map, separator); Vect_hist_write(&Map, "\n"); sprintf(buf, _("%d input polygons\n"), n_polygons); G_message(_("%d input polygons"), n_polygons); Vect_hist_write(&Map, buf); sprintf(buf, _("Total area: %G (%d areas)\n"), total_area, ncentr); G_message(_("Total area: %G (%d areas)"), total_area, ncentr); Vect_hist_write(&Map, buf); sprintf(buf, _("Overlapping area: %G (%d areas)\n"), overlap_area, n_overlaps); G_message(_("Overlapping area: %G (%d areas)"), overlap_area, n_overlaps); Vect_hist_write(&Map, buf); sprintf(buf, _("Area without category: %G (%d areas)\n"), nocat_area, n_nocat); G_message(_("Area without category: %G (%d areas)"), nocat_area, n_nocat); Vect_hist_write(&Map, buf); G_message("%s", separator); } /* needed? * OGR_DS_Destroy( Ogr_ds ); */ if (use_tmp_vect) { /* Copy temporary vector to output vector */ Vect_copy_map_lines(&Tmp, &Map); /* release memory occupied by topo, we may need that memory for main output */ Vect_set_release_support(&Tmp); Vect_close(&Tmp); Vect_delete(tempvect); } Vect_build(&Map); Vect_close(&Map); /* -------------------------------------------------------------------- */ /* Extend current window based on dataset. */ /* -------------------------------------------------------------------- */ if (flag.extend->answer) { G_get_default_window(&loc_wind); loc_wind.north = MAX(loc_wind.north, cellhd.north); loc_wind.south = MIN(loc_wind.south, cellhd.south); loc_wind.west = MIN(loc_wind.west, cellhd.west); loc_wind.east = MAX(loc_wind.east, cellhd.east); loc_wind.rows = (int)ceil((loc_wind.north - loc_wind.south) / loc_wind.ns_res); loc_wind.south = loc_wind.north - loc_wind.rows * loc_wind.ns_res; loc_wind.cols = (int)ceil((loc_wind.east - loc_wind.west) / loc_wind.ew_res); loc_wind.east = loc_wind.west + loc_wind.cols * loc_wind.ew_res; G__put_window(&loc_wind, "../PERMANENT", "DEFAULT_WIND"); } if (with_z && !flag.z->answer) G_warning(_("Input data contains 3D features. Created vector is 2D only, " "use -z flag to import 3D vector.")); exit(EXIT_SUCCESS); }
int main( int argc, char ** argv ) { GDALDriverH hDriver; const char *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff"; int bFormatExplicitelySet = FALSE; char **papszLayers = NULL; const char *pszBurnAttribute = NULL; double dfIncreaseBurnValue = 0.0; double dfMultiplyBurnValue = 1.0; const char *pszWHERE = NULL, *pszSQL = NULL; GDALDataType eOutputType = GDT_Float64; char **papszCreateOptions = NULL; GUInt32 nXSize = 0, nYSize = 0; double dfXMin = 0.0, dfXMax = 0.0, dfYMin = 0.0, dfYMax = 0.0; int bIsXExtentSet = FALSE, bIsYExtentSet = FALSE; GDALGridAlgorithm eAlgorithm = GGA_InverseDistanceToAPower; void *pOptions = NULL; char *pszOutputSRS = NULL; int bQuiet = FALSE; GDALProgressFunc pfnProgress = GDALTermProgress; int i; OGRGeometry *poSpatialFilter = NULL; int bClipSrc = FALSE; OGRGeometry *poClipSrc = NULL; const char *pszClipSrcDS = NULL; const char *pszClipSrcSQL = NULL; const char *pszClipSrcLayer = NULL; const char *pszClipSrcWhere = NULL; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(argv[0])) exit(1); GDALAllRegister(); OGRRegisterAll(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(argv[i],"--help") ) Usage(); else if( EQUAL(argv[i],"-of") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszFormat = argv[++i]; bFormatExplicitelySet = TRUE; } else if( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") ) { bQuiet = TRUE; pfnProgress = GDALDummyProgress; } else if( EQUAL(argv[i],"-ot") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); int iType; for( iType = 1; iType < GDT_TypeCount; iType++ ) { if( GDALGetDataTypeName((GDALDataType)iType) != NULL && EQUAL(GDALGetDataTypeName((GDALDataType)iType), argv[i+1]) ) { eOutputType = (GDALDataType) iType; } } if( eOutputType == GDT_Unknown ) { Usage(CPLSPrintf("Unknown output pixel type: %s.", argv[i + 1] )); } i++; } else if( EQUAL(argv[i],"-txe") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2); dfXMin = atof(argv[++i]); dfXMax = atof(argv[++i]); bIsXExtentSet = TRUE; } else if( EQUAL(argv[i],"-tye") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2); dfYMin = atof(argv[++i]); dfYMax = atof(argv[++i]); bIsYExtentSet = TRUE; } else if( EQUAL(argv[i],"-outsize") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2); nXSize = atoi(argv[++i]); nYSize = atoi(argv[++i]); } else if( EQUAL(argv[i],"-co") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] ); } else if( EQUAL(argv[i],"-zfield") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszBurnAttribute = argv[++i]; } else if( EQUAL(argv[i],"-z_increase") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); dfIncreaseBurnValue = atof(argv[++i]); } else if( EQUAL(argv[i],"-z_multiply") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); dfMultiplyBurnValue = atof(argv[++i]); } else if( EQUAL(argv[i],"-where") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszWHERE = argv[++i]; } else if( EQUAL(argv[i],"-l") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); papszLayers = CSLAddString( papszLayers, argv[++i] ); } else if( EQUAL(argv[i],"-sql") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszSQL = argv[++i]; } else if( EQUAL(argv[i],"-spat") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(4); OGRLinearRing oRing; oRing.addPoint( atof(argv[i+1]), atof(argv[i+2]) ); oRing.addPoint( atof(argv[i+1]), atof(argv[i+4]) ); oRing.addPoint( atof(argv[i+3]), atof(argv[i+4]) ); oRing.addPoint( atof(argv[i+3]), atof(argv[i+2]) ); oRing.addPoint( atof(argv[i+1]), atof(argv[i+2]) ); poSpatialFilter = new OGRPolygon(); ((OGRPolygon *) poSpatialFilter)->addRing( &oRing ); i += 4; } else if ( EQUAL(argv[i],"-clipsrc") ) { if (i + 1 >= argc) Usage(CPLSPrintf("%s option requires 1 or 4 arguments", argv[i])); bClipSrc = TRUE; errno = 0; const double unused = strtod( argv[i + 1], NULL ); // XXX: is it a number or not? if ( errno != 0 && argv[i + 2] != NULL && argv[i + 3] != NULL && argv[i + 4] != NULL) { OGRLinearRing oRing; oRing.addPoint( atof(argv[i + 1]), atof(argv[i + 2]) ); oRing.addPoint( atof(argv[i + 1]), atof(argv[i + 4]) ); oRing.addPoint( atof(argv[i + 3]), atof(argv[i + 4]) ); oRing.addPoint( atof(argv[i + 3]), atof(argv[i + 2]) ); oRing.addPoint( atof(argv[i + 1]), atof(argv[i + 2]) ); poClipSrc = new OGRPolygon(); ((OGRPolygon *) poClipSrc)->addRing( &oRing ); i += 4; (void)unused; } else if (EQUALN(argv[i + 1], "POLYGON", 7) || EQUALN(argv[i + 1], "MULTIPOLYGON", 12)) { OGRGeometryFactory::createFromWkt(&argv[i + 1], NULL, &poClipSrc); if ( poClipSrc == NULL ) { Usage("Invalid geometry. " "Must be a valid POLYGON or MULTIPOLYGON WKT."); } i++; } else if (EQUAL(argv[i + 1], "spat_extent") ) { i++; } else { pszClipSrcDS = argv[i + 1]; i++; } } else if ( EQUAL(argv[i], "-clipsrcsql") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszClipSrcSQL = argv[i + 1]; i++; } else if ( EQUAL(argv[i], "-clipsrclayer") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszClipSrcLayer = argv[i + 1]; i++; } else if ( EQUAL(argv[i], "-clipsrcwhere") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszClipSrcWhere = argv[i + 1]; i++; } else if( EQUAL(argv[i],"-a_srs") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); OGRSpatialReference oOutputSRS; if( oOutputSRS.SetFromUserInput( argv[i+1] ) != OGRERR_NONE ) { fprintf( stderr, "Failed to process SRS definition: %s\n", argv[i+1] ); GDALDestroyDriverManager(); exit( 1 ); } oOutputSRS.exportToWkt( &pszOutputSRS ); i++; } else if( EQUAL(argv[i],"-a") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); if ( ParseAlgorithmAndOptions( argv[++i], &eAlgorithm, &pOptions ) != CE_None ) { fprintf( stderr, "Failed to process algorithm name and parameters.\n" ); exit( 1 ); } } else if( argv[i][0] == '-' ) { Usage(CPLSPrintf("Unknown option name '%s'", argv[i])); } else if( pszSource == NULL ) { pszSource = argv[i]; } else if( pszDest == NULL ) { pszDest = argv[i]; } else { Usage("Too many command options."); } } if( pszSource == NULL ) { Usage("Source datasource is not specified."); } if( pszDest == NULL ) { Usage("Target dataset is not specified."); } if( pszSQL == NULL && papszLayers == NULL ) { Usage("Neither -sql nor -l are specified."); } if ( bClipSrc && pszClipSrcDS != NULL ) { poClipSrc = LoadGeometry( pszClipSrcDS, pszClipSrcSQL, pszClipSrcLayer, pszClipSrcWhere ); if ( poClipSrc == NULL ) { Usage("Cannot load source clip geometry."); } } else if ( bClipSrc && poClipSrc == NULL && !poSpatialFilter ) { Usage("-clipsrc must be used with -spat option or \n" "a bounding box, WKT string or datasource must be " "specified."); } if ( poSpatialFilter ) { if ( poClipSrc ) { OGRGeometry *poTemp = poSpatialFilter->Intersection( poClipSrc ); if ( poTemp ) { OGRGeometryFactory::destroyGeometry( poSpatialFilter ); poSpatialFilter = poTemp; } OGRGeometryFactory::destroyGeometry( poClipSrc ); poClipSrc = NULL; } } else { if ( poClipSrc ) { poSpatialFilter = poClipSrc; poClipSrc = NULL; } } /* -------------------------------------------------------------------- */ /* Find the output driver. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDriverByName( pszFormat ); if( hDriver == NULL ) { int iDr; fprintf( stderr, "FAILURE: Output driver `%s' not recognised.\n", pszFormat ); fprintf( stderr, "The following format drivers are configured and support output:\n" ); for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ ) { GDALDriverH hDriver = GDALGetDriver(iDr); if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, NULL ) != NULL ) { fprintf( stderr, " %s: %s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); } } printf( "\n" ); Usage(); } /* -------------------------------------------------------------------- */ /* Open input datasource. */ /* -------------------------------------------------------------------- */ OGRDataSourceH hSrcDS; hSrcDS = OGROpen( pszSource, FALSE, NULL ); if( hSrcDS == NULL ) { fprintf( stderr, "Unable to open input datasource \"%s\".\n", pszSource ); fprintf( stderr, "%s\n", CPLGetLastErrorMsg() ); exit( 3 ); } /* -------------------------------------------------------------------- */ /* Create target raster file. */ /* -------------------------------------------------------------------- */ GDALDatasetH hDstDS; int nLayerCount = CSLCount(papszLayers); int nBands = nLayerCount; if ( pszSQL ) nBands++; // FIXME if ( nXSize == 0 ) nXSize = 256; if ( nYSize == 0 ) nYSize = 256; if (!bQuiet && !bFormatExplicitelySet) CheckExtensionConsistency(pszDest, pszFormat); hDstDS = GDALCreate( hDriver, pszDest, nXSize, nYSize, nBands, eOutputType, papszCreateOptions ); if ( hDstDS == NULL ) { fprintf( stderr, "Unable to create target dataset \"%s\".\n", pszDest ); fprintf( stderr, "%s\n", CPLGetLastErrorMsg() ); exit( 3 ); } /* -------------------------------------------------------------------- */ /* If algorithm was not specified assigh default one. */ /* -------------------------------------------------------------------- */ if ( !pOptions ) ParseAlgorithmAndOptions( szAlgNameInvDist, &eAlgorithm, &pOptions ); /* -------------------------------------------------------------------- */ /* Process SQL request. */ /* -------------------------------------------------------------------- */ if( pszSQL != NULL ) { OGRLayerH hLayer; hLayer = OGR_DS_ExecuteSQL( hSrcDS, pszSQL, (OGRGeometryH)poSpatialFilter, NULL ); if( hLayer != NULL ) { // Custom layer will be rasterized in the first band. ProcessLayer( hLayer, hDstDS, poSpatialFilter, nXSize, nYSize, 1, bIsXExtentSet, bIsYExtentSet, dfXMin, dfXMax, dfYMin, dfYMax, pszBurnAttribute, dfIncreaseBurnValue, dfMultiplyBurnValue, eOutputType, eAlgorithm, pOptions, bQuiet, pfnProgress ); } } /* -------------------------------------------------------------------- */ /* Process each layer. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nLayerCount; i++ ) { OGRLayerH hLayer = OGR_DS_GetLayerByName( hSrcDS, papszLayers[i]); if( hLayer == NULL ) { fprintf( stderr, "Unable to find layer \"%s\", skipping.\n", papszLayers[i] ); continue; } if( pszWHERE ) { if( OGR_L_SetAttributeFilter( hLayer, pszWHERE ) != OGRERR_NONE ) break; } if ( poSpatialFilter != NULL ) OGR_L_SetSpatialFilter( hLayer, (OGRGeometryH)poSpatialFilter ); // Fetch the first meaningful SRS definition if ( !pszOutputSRS ) { OGRSpatialReferenceH hSRS = OGR_L_GetSpatialRef( hLayer ); if ( hSRS ) OSRExportToWkt( hSRS, &pszOutputSRS ); } ProcessLayer( hLayer, hDstDS, poSpatialFilter, nXSize, nYSize, i + 1 + nBands - nLayerCount, bIsXExtentSet, bIsYExtentSet, dfXMin, dfXMax, dfYMin, dfYMax, pszBurnAttribute, dfIncreaseBurnValue, dfMultiplyBurnValue, eOutputType, eAlgorithm, pOptions, bQuiet, pfnProgress ); } /* -------------------------------------------------------------------- */ /* Apply geotransformation matrix. */ /* -------------------------------------------------------------------- */ double adfGeoTransform[6]; adfGeoTransform[0] = dfXMin; adfGeoTransform[1] = (dfXMax - dfXMin) / nXSize; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = dfYMin; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = (dfYMax - dfYMin) / nYSize; GDALSetGeoTransform( hDstDS, adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Apply SRS definition if set. */ /* -------------------------------------------------------------------- */ if ( pszOutputSRS ) { GDALSetProjection( hDstDS, pszOutputSRS ); CPLFree( pszOutputSRS ); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ OGR_DS_Destroy( hSrcDS ); GDALClose( hDstDS ); OGRGeometryFactory::destroyGeometry( poSpatialFilter ); CPLFree( pOptions ); CSLDestroy( papszCreateOptions ); CSLDestroy( argv ); CSLDestroy( papszLayers ); OGRCleanupAll(); GDALDestroyDriverManager(); return 0; }