/* {ok, DataSource} = lgeo_ogr:open("test/polygon.shp"), {ok, Layer} = lgeo_ogr:ds_get_layer(DataSource, 0), {ok, Feature} = lgeo_ogr:l_get_feature(Layer, 0), {ok, Fields} = lgeo_ogr:f_get_fields(Feature). {1,"first"} */ static ERL_NIF_TERM f_get_fields(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { EnvFeature_t **feature; ERL_NIF_TERM eterm; if (argc != 1) { return enif_make_badarg(env); } if(!enif_get_resource(env, argv[0], OGR_F_RESOURCE, (void**)&feature)) { return enif_make_badarg(env); } OGRFeatureDefnH feature_defn = OGR_F_GetDefnRef((**feature).obj); int count = OGR_FD_GetFieldCount(feature_defn); ERL_NIF_TERM *arr = (ERL_NIF_TERM *) malloc(sizeof(ERL_NIF_TERM)*count); int index; for(index=0; index<count; index++) { OGRFieldDefnH field_defn = OGR_FD_GetFieldDefn(feature_defn, index); if(OGR_Fld_GetType(field_defn) == OFTInteger) { arr[index] = enif_make_int(env, OGR_F_GetFieldAsInteger((**feature).obj, index)); } else if(OGR_Fld_GetType(field_defn) == OFTReal) { arr[index] = enif_make_double(env, OGR_F_GetFieldAsDouble((**feature).obj, index)); } else if(OGR_Fld_GetType(field_defn) == OFTString) { arr[index] = enif_make_string(env, OGR_F_GetFieldAsString((**feature).obj, index), ERL_NIF_LATIN1); } else { arr[index] = enif_make_string(env, OGR_F_GetFieldAsString((**feature).obj, index), ERL_NIF_LATIN1); } } eterm = enif_make_tuple_from_array(env, arr, index); free(arr); return enif_make_tuple2(env, enif_make_atom(env, "ok"), eterm); }
// 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); }
bool QgsShapeFile::scanGeometries() { QProgressDialog *sg = new QProgressDialog(); sg->setMinimum( 0 ); sg->setMaximum( 0 ); QString label = tr( "Scanning " ); label += fileName; sg->setLabel( new QLabel( label ) ); sg->show(); qApp->processEvents(); OGRFeatureH feat; OGRwkbGeometryType currentType = wkbUnknown; bool multi = false; while (( feat = OGR_L_GetNextFeature( ogrLayer ) ) ) { qApp->processEvents(); // feat->DumpReadable(NULL); OGRGeometryH geom = OGR_F_GetGeometryRef( feat ); if ( geom ) { QString gml = OGR_G_ExportToGML( geom ); // QgsDebugMsg(gml); if ( gml.indexOf( "gml:Multi" ) > -1 ) { // QgsDebugMsg("MULTI Part Feature detected"); multi = true; } OGRFeatureDefnH fDef = OGR_F_GetDefnRef( feat ); OGRwkbGeometryType gType = OGR_FD_GetGeomType( fDef ); // QgsDebugMsg(gType); if ( gType > currentType ) { currentType = gType; } if ( gType < currentType ) { QgsDebugMsg( QString( "Encountered inconsistent geometry type %1" ).arg( gType ) ); } } } // a hack to support 2.5D geometries (their wkb is equivalent to 2D variants // except that the highest bit is set also). For now we will ignore 3rd coordinate. hasMoreDimensions = false; if ( currentType & wkb25DBit ) { QgsDebugMsg( "Got a shapefile with 2.5D geometry." ); currentType = wkbFlatten( currentType ); hasMoreDimensions = true; } OGR_L_ResetReading( ogrLayer ); geom_type = geometries[currentType]; if ( multi && ( geom_type.indexOf( "MULTI" ) == -1 ) ) { geom_type = "MULTI" + geom_type; } delete sg; // QgsDebugMsg(QString("Geometry type is %1 (%2)").arg(currentType).arg(geometries[currentType])); return multi; }