Object* OgrFileImport::importPointGeometry(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry) { auto style = OGR_F_GetStyleString(feature); auto symbol = getSymbol(Symbol::Point, style); if (symbol->getType() == Symbol::Point) { auto object = new PointObject(symbol); object->setPosition(toMapCoord(OGR_G_GetX(geometry, 0), OGR_G_GetY(geometry, 0))); map_part->addObject(object); return object; } else if (symbol->getType() == Symbol::Text) { const auto& description = symbol->getDescription(); auto length = description.length(); auto split = description.indexOf(QLatin1Char(' ')); Q_ASSERT(split > 0); Q_ASSERT(split < length); auto label = description.right(length - split - 1); if (label.startsWith('{') && label.endsWith('}')) { label.remove(0,1); label.chop(1); int index = OGR_F_GetFieldIndex(feature, label.toLatin1()); if (index >= 0) { label = QString(OGR_F_GetFieldAsString(feature, index)); } } if (!label.isEmpty()) { auto object = new TextObject(symbol); object->setAnchorPosition(toMapCoord(OGR_G_GetX(geometry, 0), OGR_G_GetY(geometry, 0))); // DXF observation label.replace(QRegularExpression("(\\\\[^;]*;)*", QRegularExpression::MultilineOption), QString::null); label.replace(QLatin1String("^I"), "\t"); object->setText(label); bool ok; auto anchor = QStringRef(&description, 1, 2).toInt(&ok); if (ok) { applyLabelAnchor(anchor, object); } auto angle = QStringRef(&description, 3, split-3).toFloat(&ok); if (ok) { object->setRotation(qDegreesToRadians(angle)); } map_part->addObject(object); return object; } } return nullptr; }
PathObject* OgrFileImport::importPolygonGeometry(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry) { auto num_geometries = OGR_G_GetGeometryCount(geometry); if (num_geometries < 1) { ++too_few_coordinates; return nullptr; } auto outline = OGR_G_ForceToLineString(OGR_G_GetGeometryRef(geometry, 0)); auto num_points = OGR_G_GetPointCount(outline); if (num_points < 3) { ++too_few_coordinates; return nullptr; } auto style = OGR_F_GetStyleString(feature); auto object = new PathObject(getSymbol(Symbol::Area, style)); for (int i = 0; i < num_points; ++i) { object->addCoordinate(toMapCoord(OGR_G_GetX(outline, i), OGR_G_GetY(outline, i))); } for (int g = 1; g < num_geometries; ++g) { bool start_new_part = true; auto hole = /*OGR_G_ForceToLineString*/(OGR_G_GetGeometryRef(geometry, g)); auto num_points = OGR_G_GetPointCount(hole); for (int i = 0; i < num_points; ++i) { object->addCoordinate(toMapCoord(OGR_G_GetX(hole, i), OGR_G_GetY(hole, i)), start_new_part); start_new_part = false; } } object->closeAllParts(); map_part->addObject(object); return object; }
PathObject* OgrFileImport::importLineStringGeometry(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry) { geometry = OGR_G_ForceToLineString(geometry); auto num_points = OGR_G_GetPointCount(geometry); if (num_points < 2) { ++too_few_coordinates; return nullptr; } auto style = OGR_F_GetStyleString(feature); auto object = new PathObject(getSymbol(Symbol::Line, style)); for (int i = 0; i < num_points; ++i) { object->addCoordinate(toMapCoord(OGR_G_GetX(geometry, i), OGR_G_GetY(geometry, i))); } map_part->addObject(object); return object; }
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; }
/* What we need: specific condition, is walk in , tactic, distance elevation * minsteps, maxsteps, waterdrops, pump/roll, fwa id. */ int main( int argc, char *argv[] ) { GDALAllRegister(); OGRRegisterAll(); const char *pszInputfile = NULL; const char *pszOutputfile = NULL; const char *pszOutputFormat = "CSV"; char **papszCreateOptions = NULL; const char *pszDataPath = NULL; const char *pszFpuCode = NULL; int nLimit = 0; int bProgress = TRUE; double dfMaxX, dfMinX, dfMaxY, dfMinY; int bLimit = FALSE; double dfBuffer = 0.0; int i = 1; while( i < argc ) { if( EQUAL( argv[i], "-p" ) ) { bProgress = TRUE; } else if( EQUAL( argv[i], "-d" ) ) { pszDataPath = argv[++i]; } else if( EQUAL( argv[i], "-of" ) ) { pszOutputFormat = argv[++i]; } else if( EQUAL( argv[i], "-co" ) ) { papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] ); } else if( EQUAL( argv[i], "-sl" ) ) { dfMaxX = atof(argv[++i]); dfMinX = atof(argv[++i]); dfMaxY = atof(argv[++i]); dfMinY = atof(argv[++i]); bLimit = TRUE; } else if( EQUAL( argv[i], "-fpu" ) ) { pszFpuCode = argv[++i]; } else if( EQUAL( argv[i], "-b" ) ) { dfBuffer = atof( argv[++i] ); } else if( EQUAL( argv[i], "-l" ) ) { nLimit = atoi( argv[++i] ); } else if( EQUAL( argv[i], "-h" ) ) { Usage(); } else if( pszInputfile == NULL ) { pszInputfile = argv[i]; } else if( pszOutputfile == NULL ) { pszOutputfile = argv[i]; } else { Usage(); } i++; } if( pszInputfile == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "No input file provided\n"); Usage(); } if( pszOutputfile == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Invalid output selected, " "use database and table or output file\n" ); Usage(); } pszDataPath = CPLGetConfigOption( "OMFFR_DATA", NULL ); OGRDataSourceH hInputDS = OGROpen( pszInputfile, FALSE, NULL ); if( hInputDS == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Cannot open input file\n" ); Usage(); } int year, num, day; const char *dow, *disc_time; int bi; double ros; int fuel; const char *spec_cond; int slope, walkin; const char *tactic; double dist; int elev; double ltow; int minsteps = 250; int maxsteps = 10000; const char *sunrise, *sunset; int waterdrops, pumproll; char *abyFwa; const char *fwaid; double lon, lat; OGRLayerH hInputLayer; hInputLayer = OGR_DS_GetLayerByName( hInputDS, CPLGetBasename( pszInputfile ) ); OGRFeatureDefnH hInputFeatureDefn; OGRFeatureH hInputFeature; OGRGeometryH hGeometry; hInputFeatureDefn = OGR_L_GetLayerDefn( hInputLayer ); const char *pszTmpFilename =CPLFormFilename( pszDataPath, "irs/FWA", ".dat" ); std::vector<CFWA>fwas = LoadFwas( pszTmpFilename ); int nFeatures = OGR_L_GetFeatureCount( hInputLayer, TRUE ); FILE *fout = fopen( pszOutputfile, "w" ); //CFWA *fwa; Random random; char pszDb[8192]; sprintf( pszDb, "%s/omffr.sqlite", pszDataPath ); IRSDataAccess *poDA = IRSDataAccess::Create( 0, pszDb ); int rc; sqlite3 *db; rc = sqlite3_open_v2( pszDb, &db, SQLITE_OPEN_READONLY, NULL ); rc = sqlite3_enable_load_extension( db, 1 ); rc = sqlite3_load_extension( db, "/usr/local/lib/libspatialite.so", 0, NULL ); sqlite3_stmt *stmt; rc = sqlite3_prepare_v2( db, "SELECT * from fwa join fwa_bndry USING(fwa_gis_id) " \ "WHERE ST_Contains(fwa_bndry.geometry, MakePoint(?, ?, 4269))", -1, &stmt, NULL ); if(rc) { CPLError( CE_Failure, CPLE_AppDefined, "Could not open DB"); } GDALTermProgress( 0.0, NULL, NULL ); OGR_L_ResetReading( hInputLayer ); const char *pszFwaName; int nDone = 0; while( ( hInputFeature = OGR_L_GetNextFeature( hInputLayer ) ) != NULL ) { /* fwaid = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "fwa_name" ) ); abyFwa = CPLStrdup( fwaid ); LaunderFwaName( abyFwa ); fwa = FindFwa( fwas, abyFwa ); if( fwa == NULL ) { CPLError( CE_Warning, CPLE_FileIO, "Could not load fwa (%s)from file, missing\n", abyFwa ); continue; } */ /* Get fwa by point */ hGeometry = OGR_F_GetGeometryRef( hInputFeature ); /* Try to handle non-geometry types (csv) */ if( hGeometry != NULL ) { lat = OGR_G_GetY( hGeometry, 0 ); lon = OGR_G_GetX( hGeometry, 0 ); } else { lat = OGR_F_GetFieldAsDouble( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "Y") ); lon = OGR_F_GetFieldAsDouble( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "X") ); } std::string oFwaName = poDA->PointQuery( "fwa_bndry", "fwa_lndr_name", lon, lat ); rc = sqlite3_bind_double( stmt, 1, lon ); rc = sqlite3_bind_double( stmt, 2, lat ); //sqlite3_bind_text( stmt, 1, oFwaName.c_str(), -1, SQLITE_TRANSIENT); rc = sqlite3_step( stmt ); if( rc != SQLITE_ROW && rc != SQLITE_DONE ) { CPLError( CE_Warning, CPLE_FileIO, "Could not load fwa (%s)from file, missing\n", oFwaName.c_str() ); sqlite3_reset(stmt); continue; } int nFwaWalkIn, nFwaHead, nFwaTail, nFwaPara, nFwaAttackD; int nFwaWaterDrop, nFwaPumpRoll; nFwaWalkIn = sqlite3_column_int( stmt, 4 ); nFwaHead = sqlite3_column_int( stmt, 6 ); nFwaTail = sqlite3_column_int( stmt, 7 ); nFwaPara = sqlite3_column_int( stmt, 8 ); nFwaAttackD = sqlite3_column_int( stmt, 9 ); nFwaWaterDrop = sqlite3_column_int( stmt, 10 ); nFwaPumpRoll = sqlite3_column_int( stmt, 5 ); year = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "year" ) ); num = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "fire_num" ) ); day = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "day" ) ); dow = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "week_day" ) ); disc_time = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "disc_time" ) ); bi = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "bi" ) ); ros = OGR_F_GetFieldAsDouble( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "ros" ) ); fuel = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "fuel" ) ); spec_cond = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "spec_cond" ) ); slope = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "slope_perc" ) ); //if( random.rand3() * 100 > fwa->GetWalkInPct() ) if( random.rand3() * 100 > nFwaWalkIn ) walkin = 0; else walkin = 1; //if( fwa->GetHead() == 100 ) if( nFwaHead == 100 ) tactic = "HEAD\0"; //else if( fwa->GetTail() == 100 ) else if( nFwaTail == 100 ) tactic = "TAIL\0"; //else if( fwa->GetParallel() == 100 ) else if( nFwaTail == 100 ) tactic = "PARALLEL\0"; else { int r = (int)(random.rand3() * 100 ); int total = 0; if( r < nFwaHead ) tactic = "HEAD\0"; else if( r < nFwaTail + nFwaTail ) tactic = "TAIL\0"; else tactic = "PARALLEL\0"; } //dist = fwa->GetAttackDist(); dist = nFwaAttackD; elev = OGR_F_GetFieldAsInteger( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "elev" ) ); ltow = OGR_F_GetFieldAsDouble( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "ratio" ) ); sunrise = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "sunrise" ) ); sunset = OGR_F_GetFieldAsString( hInputFeature, OGR_FD_GetFieldIndex( hInputFeatureDefn, "sunset" ) ); //if( fwa->GetWaterDrops() ) if( nFwaWaterDrop ) waterdrops = TRUE; else waterdrops = FALSE; //if( fwa->GetPumpnRoll() ) if( nFwaPumpRoll ) pumproll = TRUE; else pumproll = FALSE; fprintf( fout, "%d %d %d %s %s " "%d %lf %d %s %d " "%d %s %lf %d %lf " "%d %d %s %s %d " "%d %s %lf %lf\n", year, num, day, dow, disc_time, bi, ros, fuel, spec_cond, slope, walkin, tactic, dist, elev, ltow, minsteps, maxsteps, sunrise, sunset, waterdrops, pumproll, /* abyFwa */ oFwaName.c_str(), lat, lon ); sqlite3_reset(stmt); nDone++; GDALTermProgress( (float)nDone / (float)nFeatures, NULL, NULL ); } GDALTermProgress( 1.0, NULL, NULL ); fclose( fout ); OGR_DS_Destroy( hInputDS ); return 0; }
// Create and add a placement to the current lithograph if it doesn't overlap // with current labels. void simplet_lithograph_add_placement(simplet_lithograph_t *litho, OGRFeatureH feature, simplet_list_t *styles, cairo_t *proj_ctx) { simplet_style_t *field = simplet_lookup_style(styles, "text-field"); if(!field) return; OGRFeatureDefnH defn; if(!(defn = OGR_F_GetDefnRef(feature))) return; int idx = OGR_FD_GetFieldIndex(defn, (const char*) field->arg); if(idx < 0) return; // Find the largest sub geometry of a particular multi-geometry. OGRGeometryH super = OGR_F_GetGeometryRef(feature); OGRGeometryH geom = super; double area = 0.0; switch(wkbFlatten(OGR_G_GetGeometryType(super))) { case wkbMultiPolygon: case wkbGeometryCollection: for(int i = 0; i < OGR_G_GetGeometryCount(super); i++) { OGRGeometryH subgeom = OGR_G_GetGeometryRef(super, i); if(subgeom == NULL) continue; double ar = OGR_G_Area(subgeom); if(ar > area) { geom = subgeom; area = ar; } } break; default: ; } // Find the center of our geometry. This sometimes throws an invalid geometry // error, so there is a slight bug here somehow. OGRGeometryH center; if(!(center = OGR_G_CreateGeometry(wkbPoint))) return; if(OGR_G_Centroid(geom, center) == OGRERR_FAILURE) { OGR_G_DestroyGeometry(center); return; } // Turn font hinting off cairo_font_options_t *opts; if(!(opts = cairo_font_options_create())){ OGR_G_DestroyGeometry(center); return; } cairo_font_options_set_hint_style(opts, CAIRO_HINT_STYLE_NONE); cairo_font_options_set_hint_metrics(opts, CAIRO_HINT_METRICS_OFF); pango_cairo_context_set_font_options(litho->pango_ctx, opts); cairo_font_options_destroy(opts); // Get the field containing the text for the label. char *txt = simplet_copy_string(OGR_F_GetFieldAsString(feature, idx)); PangoLayout *layout = pango_layout_new(litho->pango_ctx); pango_layout_set_text(layout, txt, -1); free(txt); // Grab the font to use and apply tracking. simplet_style_t *font = simplet_lookup_style(styles, "font"); simplet_apply_styles(layout, styles, "letter-spacing", NULL); const char *font_family; if(!font) font_family = "helvetica 12px"; else font_family = font->arg; PangoFontDescription *desc = pango_font_description_from_string(font_family); pango_layout_set_font_description(layout, desc); pango_font_description_free(desc); double x = OGR_G_GetX(center, 0), y = OGR_G_GetY(center, 0); cairo_user_to_device(proj_ctx, &x, &y); // Finally try the placement and test for overlaps. try_and_insert_placement(litho, layout, x, y); OGR_G_DestroyGeometry(center); }
/*! \brief Recursively read feature and add all elements to points_cache and types_cache. ftype: if > 0 use this type (because parts of Polygon are read as wkbLineString) \param Map pointer to Map_info structure \param[out] hGeom OGR geometry \param ftype feature type \return 0 on success \return 1 on error */ static int cache_feature(struct Map_info *Map, OGRGeometryH hGeom, int ftype) { int line, i, np, ng, tp; OGRwkbGeometryType type; OGRGeometryH hGeom2; G_debug(4, "cache_feature() ftype = %d", ftype); /* Alloc space */ line = Map->fInfo.ogr.lines_num; if (line == Map->fInfo.ogr.lines_alloc) { Map->fInfo.ogr.lines_alloc += 20; Map->fInfo.ogr.lines = (struct line_pnts **)G_realloc((void *)Map->fInfo.ogr.lines, Map->fInfo.ogr.lines_alloc * sizeof(struct line_pnts *)); Map->fInfo.ogr.lines_types = (int *)G_realloc(Map->fInfo.ogr.lines_types, Map->fInfo.ogr.lines_alloc * sizeof(int)); for (i = Map->fInfo.ogr.lines_num; i < Map->fInfo.ogr.lines_alloc; i++) Map->fInfo.ogr.lines[i] = Vect_new_line_struct(); } Vect_reset_line(Map->fInfo.ogr.lines[line]); type = wkbFlatten(OGR_G_GetGeometryType(hGeom)); switch (type) { case wkbPoint: G_debug(4, "Point"); Vect_append_point(Map->fInfo.ogr.lines[line], OGR_G_GetX(hGeom, 0), OGR_G_GetY(hGeom, 0), OGR_G_GetZ(hGeom, 0)); Map->fInfo.ogr.lines_types[line] = GV_POINT; Map->fInfo.ogr.lines_num++; return 0; break; case wkbLineString: G_debug(4, "LineString"); np = OGR_G_GetPointCount(hGeom); for (i = 0; i < np; i++) { Vect_append_point(Map->fInfo.ogr.lines[line], OGR_G_GetX(hGeom, i), OGR_G_GetY(hGeom, i), OGR_G_GetZ(hGeom, i)); } if (ftype > 0) { /* Polygon rings */ Map->fInfo.ogr.lines_types[line] = ftype; } else { Map->fInfo.ogr.lines_types[line] = GV_LINE; } Map->fInfo.ogr.lines_num++; return 0; break; case wkbMultiPoint: case wkbMultiLineString: case wkbPolygon: case wkbMultiPolygon: case wkbGeometryCollection: ng = OGR_G_GetGeometryCount(hGeom); G_debug(4, "%d geoms -> next level", ng); if (type == wkbPolygon) { tp = GV_BOUNDARY; } else { tp = -1; } for (i = 0; i < ng; i++) { hGeom2 = OGR_G_GetGeometryRef(hGeom, i); cache_feature(Map, hGeom2, tp); } return 0; break; default: G_warning(_("OGR feature type %d not supported"), type); return 1; break; } }
/*! \brief Recursively descend to feature and read the part \param Map pointer to Map_info structure \param hGeom OGR geometry \param offset given offset \param[out] Points container used to store line pointes within \return feature type \return -1 on error */ static int read_line(const struct Map_info *Map, OGRGeometryH hGeom, long offset, struct line_pnts *Points) { int i, nPoints; int eType, line; OGRGeometryH hGeom2; /* Read coors if hGeom is a simple element (wkbPoint, * wkbLineString) otherwise descend to geometry specified by * offset[offset] */ eType = wkbFlatten(OGR_G_GetGeometryType(hGeom)); G_debug(4, "OGR geometry type: %d", eType); switch (eType) { case wkbPoint: G_debug(4, "\t->Point"); if (Points) { Vect_append_point(Points, OGR_G_GetX(hGeom, 0), OGR_G_GetY(hGeom, 0), OGR_G_GetZ(hGeom, 0)); } return GV_POINT; break; case wkbLineString: G_debug(4, "\t->LineString"); if (Points) { nPoints = OGR_G_GetPointCount(hGeom); for (i = 0; i < nPoints; i++) { Vect_append_point(Points, OGR_G_GetX(hGeom, i), OGR_G_GetY(hGeom, i), OGR_G_GetZ(hGeom, i)); } } return GV_LINE; break; case wkbPolygon: case wkbMultiPoint: case wkbMultiLineString: case wkbMultiPolygon: case wkbGeometryCollection: G_debug(4, " \t->more geoms -> part %d", Map->fInfo.ogr.offset[offset]); hGeom2 = OGR_G_GetGeometryRef(hGeom, Map->fInfo.ogr.offset[offset]); line = read_line(Map, hGeom2, offset + 1, Points); if (eType == wkbPolygon || wkbMultiPolygon) return GV_BOUNDARY; if (eType == wkbMultiPoint) return GV_POINT; if (eType == wkbMultiLineString) return GV_LINE; return line; break; default: G_warning(_("OGR feature type '%s' not supported"), OGRGeometryTypeToName(eType)); break; } return -1; }
static S57_geo *_ogrLoadObject(const char *objname, void *feature, OGRGeometryH hGeomNext) { S57_geo *geoData = NULL; OGRGeometryH hGeom = NULL; OGRwkbGeometryType eType = wkbNone; if (NULL != feature) hGeom = OGR_F_GetGeometryRef((OGRFeatureH)feature); else hGeom = hGeomNext; if (NULL != hGeom) eType = OGR_G_GetGeometryType(hGeom); else eType = wkbNone; // DSIS switch (eType) { // POINT case wkbPoint25D: case wkbPoint: { geocoord *pointxyz = g_new(geocoord, 3); pointxyz[0] = OGR_G_GetX(hGeom, 0); pointxyz[1] = OGR_G_GetY(hGeom, 0); pointxyz[2] = OGR_G_GetZ(hGeom, 0); geoData = S57_setPOINT(pointxyz); _setExtent(geoData, hGeom); break; } // LINE case wkbLineString25D: case wkbLineString: { int count = OGR_G_GetPointCount(hGeom); // NOTE: when S52_USE_SUPP_LINE_OVERLAP then Edge might have 0 node /* so this code fail if (count < 2) { PRINTF("WARNING: a line with less than 2 points!?\n"); g_assert(0); return NULL; } */ geocoord *linexyz = NULL; if (0 != count) linexyz = g_new(geocoord, 3*count); for (int node=0; node<count; ++node) { linexyz[node*3+0] = OGR_G_GetX(hGeom, node); linexyz[node*3+1] = OGR_G_GetY(hGeom, node); linexyz[node*3+2] = OGR_G_GetZ(hGeom, node); } geoData = S57_setLINES(count, linexyz); _setExtent(geoData, hGeom); break; } // AREA case wkbPolygon25D: case wkbPolygon: { // Note: S57 area have CW outer ring and CCW inner ring guint nRingCount = OGR_G_GetGeometryCount(hGeom); guint *ringxyznbr; geocoord **ringxyz; double area = 0; ringxyznbr = g_new(guint, nRingCount); ringxyz = g_new(geocoord *, nRingCount); // NOTE: to check winding on an open area //for (i = n-1, j = 0; j < n; i = j, j++) { // ai = x[i] * y[j] - x[j] * y[i]; //} for (guint iRing=0; iRing<nRingCount; ++iRing) { OGRGeometryH hRing; guint vert_count = _getGeoPtCount(hGeom, iRing, &hRing); ringxyznbr[iRing] = vert_count; // skip this ring if no vertex if (0 == vert_count) { // FIXME: what should be done here, // FIX: S52 - discard this ring or the object or the layer or the whole chart (update) // FIX: GDAL/OGR - is it a bug in the reader or in the chart it self (S57) // FIX: or this is an empty Geo PRINTF("WARNING: wkbPolygon, empty ring (%s)\n", objname); g_assert(0); continue; } ringxyz[iRing] = g_new(geocoord, vert_count*3*sizeof(geocoord)); // check if last vertex is NOT the first vertex (ie ring not close) if ((OGR_G_GetX(hRing, 0) != OGR_G_GetX(hRing, vert_count-1)) || (OGR_G_GetY(hRing, 0) != OGR_G_GetY(hRing, vert_count-1)) ) { PRINTF("ERROR: S-57 ring (AREA) not closed (%s)\n", objname); g_assert(0); continue; // Note: to compute area of an open poly //double area = 0; //for (guint i=vert_count-1, j=0; j<vert_count; i=j, ++j) { // double x1 = OGR_G_GetX(hRing, i); // double y1 = OGR_G_GetY(hRing, i); // double x2 = OGR_G_GetX(hRing, j); // double y2 = OGR_G_GetY(hRing, j); // area += (x1*y2) - (x2*y1); //} } for (guint i=0; (i+1)<vert_count; i++) { double x1 = OGR_G_GetX(hRing, i ); double y1 = OGR_G_GetY(hRing, i ); double x2 = OGR_G_GetX(hRing, i+1); double y2 = OGR_G_GetY(hRing, i+1); area += (x1*y2) - (x2*y1); } // CW if area is < 0, else CCW //PRINTF("AREA(ring=%i/%i): %s (%s)\n", iRing, nRingCount, (area <= 0.0) ? "CW" : "CCW", objname); // CCW winding if (area > 0.0) { // if first ring reverse winding to CW if (0 == iRing) { // debug //PRINTF("DEBUG: reversing S-57 outer ring to CW (%s)\n", objname); //g_assert(0); for (guint node=0; node<vert_count; ++node) { ringxyz[iRing][node*3+0] = OGR_G_GetX(hRing, vert_count - node-1); ringxyz[iRing][node*3+1] = OGR_G_GetY(hRing, vert_count - node-1); ringxyz[iRing][node*3+2] = OGR_G_GetZ(hRing, vert_count - node-1); } } else { for (guint node=0; node<vert_count; ++node) { ringxyz[iRing][node*3+0] = OGR_G_GetX(hRing, node); ringxyz[iRing][node*3+1] = OGR_G_GetY(hRing, node); ringxyz[iRing][node*3+2] = OGR_G_GetZ(hRing, node); } } } else { // CW winding if (0 == iRing) { for (guint node=0; node<vert_count; ++node) { ringxyz[iRing][node*3+0] = OGR_G_GetX(hRing, node); ringxyz[iRing][node*3+1] = OGR_G_GetY(hRing, node); ringxyz[iRing][node*3+2] = OGR_G_GetZ(hRing, node); } } else { // if NOT first ring reverse winding (CCW) //PRINTF("DEBUG: reversing S-57 inner ring to CCW (%s)\n", objname); //g_assert(0); for (guint node=0; node<vert_count; ++node) { ringxyz[iRing][node*3+0] = OGR_G_GetX(hRing, vert_count - node-1); ringxyz[iRing][node*3+1] = OGR_G_GetY(hRing, vert_count - node-1); ringxyz[iRing][node*3+2] = OGR_G_GetZ(hRing, vert_count - node-1); } } } } // for loop //geoData = S57_setAREAS(nRingCount, ringxyznbr, ringxyz, (area <= 0.0) ? S57_AW_CW : S57_AW_CCW); geoData = S57_setAREAS(nRingCount, ringxyznbr, ringxyz); _setExtent(geoData, hGeom); if (0 == g_strcmp0(WORLD_BASENM, objname)) { // Note: loading shapefile as a 'marfea' use a transparent fill so NODATA // is still visible (seem better than 'mnufea' wich has no colour fill) S57_setName(geoData, "marfea"); // pslb3_2.pdf (p. II-22): Mariners' Object Class: Manufacturers' feature // Note that manufacturers' areas, whether non-chart or chart areas, should not use area colour fill. //S57_setName(geoData, "mnufea"); } break; } #ifdef S52_USE_WORLD // shapefile area case wkbMultiPolygon: { guint nPolyCount = OGR_G_GetGeometryCount(hGeom); for (guint iPoly=0; iPoly<nPolyCount; ++iPoly) { OGRGeometryH hGeomNext = OGR_G_GetGeometryRef(hGeom, iPoly); // recursion S57_geo *geo = _ogrLoadObject(objname, NULL, hGeomNext); if (NULL == geoData) geoData = geo; else S57_setNextPoly(geoData, geo); } break; } #endif case wkbGeometryCollection: case wkbMultiLineString: { PRINTF("WARNING: wkbGeometryCollection & wkbMultiLineString not handled \n"); g_assert(0); // land here if GDAL/OGR was patched multi-line break; } case wkbNone: // DSID layer get here geoData = S57_set_META(); break; // META_T case wkbMultiPoint: // ogr SPLIT_MULTIPOINT prob !! PRINTF("DEBUG: Multi-Pass!!!\n"); //PRINTF("ERROR: set env var OGR_S57_OPTIONS to SPLIT_MULTIPOINT:ON\n"); //PRINTF("FIXME: or wkbMultiLineString found!\n"); //g_assert_not_reached(); // MultiLineString (need this for line removal) //geoData = S57_set_META(); //GvCollectionShape *collection = (GvCollectionShape *) shape; //int nCollection = gv_shape_collection_get_count(shape); break; default: // FIXME: find a decent default (see openev/gvshapes.h)!!! PRINTF("WKB type not handled = %i %0x\n", eType, eType); g_assert(0); } // debug //PRINTF("name: %s\n", objname); return geoData; }
inline double getX() { return OGR_G_GetX(m_current_geometry, 0); }
OGRErr OGRGmtLayer::WriteGeometry( OGRGeometryH hGeom, int bHaveAngle ) { /* -------------------------------------------------------------------- */ /* This is a geometry with sub-geometries. */ /* -------------------------------------------------------------------- */ if( OGR_G_GetGeometryCount( hGeom ) > 0 ) { OGRErr eErr = OGRERR_NONE; for( int iGeom = 0; iGeom < OGR_G_GetGeometryCount(hGeom) && eErr == OGRERR_NONE; iGeom++ ) { // We need to emit polygon @P and @H items while we still // know this is a polygon and which is the outer and inner // ring. if( wkbFlatten(OGR_G_GetGeometryType(hGeom)) == wkbPolygon ) { if( !bHaveAngle ) { VSIFPrintfL( fp, ">\n" ); bHaveAngle = TRUE; } if( iGeom == 0 ) VSIFPrintfL( fp, "# @P\n" ); else VSIFPrintfL( fp, "# @H\n" ); } eErr = WriteGeometry( OGR_G_GetGeometryRef( hGeom, iGeom ), bHaveAngle ); bHaveAngle = FALSE; } return eErr; } /* -------------------------------------------------------------------- */ /* If this is not a point we need to have an angle bracket to */ /* mark the vertex list. */ /* -------------------------------------------------------------------- */ if( wkbFlatten(OGR_G_GetGeometryType(hGeom)) != wkbPoint && !bHaveAngle ) VSIFPrintfL( fp, ">\n" ); /* -------------------------------------------------------------------- */ /* Dump vertices. */ /* -------------------------------------------------------------------- */ const int nPointCount = OGR_G_GetPointCount(hGeom); const int nDim = OGR_G_GetCoordinateDimension(hGeom); // For testing only. Ticket #6453 const bool bUseTab = CPLTestBool( CPLGetConfigOption("GMT_USE_TAB", "FALSE") ); for( int iPoint = 0; iPoint < nPointCount; iPoint++ ) { const double dfX = OGR_G_GetX( hGeom, iPoint ); const double dfY = OGR_G_GetY( hGeom, iPoint ); const double dfZ = OGR_G_GetZ( hGeom, iPoint ); sRegion.Merge( dfX, dfY ); char szLine[128]; OGRMakeWktCoordinate( szLine, dfX, dfY, dfZ, nDim ); if( bUseTab ) { for( char* szPtr = szLine; *szPtr != '\0'; ++szPtr ) { if( *szPtr == ' ' ) *szPtr = '\t'; } } if( VSIFPrintfL( fp, "%s\n", szLine ) < 1 ) { CPLError( CE_Failure, CPLE_FileIO, "Gmt write failure: %s", VSIStrerror( errno ) ); return OGRERR_FAILURE; } } return OGRERR_NONE; }