Exemplo n.º 1
0
Object* OgrFileImport::importGeometry(MapPart* map_part, OGRFeatureH feature, OGRGeometryH geometry)
{
	auto geometry_type = wkbFlatten(OGR_G_GetGeometryType(geometry));
	switch (geometry_type)
	{
	case OGRwkbGeometryType::wkbPoint:
		return importPointGeometry(map_part, feature, geometry);
		
	case OGRwkbGeometryType::wkbLineString:
		return importLineStringGeometry(map_part, feature, geometry);
		
	case OGRwkbGeometryType::wkbPolygon:
		return importPolygonGeometry(map_part, feature, geometry);
		
	case OGRwkbGeometryType::wkbGeometryCollection:
	case OGRwkbGeometryType::wkbMultiLineString:
	case OGRwkbGeometryType::wkbMultiPoint:
	case OGRwkbGeometryType::wkbMultiPolygon:
		return importGeometryCollection(map_part, feature, geometry);
		
	default:
		qDebug("OgrFileImport: Unknown or unsupported geometry type: %d", geometry_type);
		++unsupported_geometry_type;
		return nullptr;
	}
}
Exemplo n.º 2
0
Polygon::Polygon(OGRGeometryH g, const SpatialReference& srs,
    geos::ErrorHandler& err) : m_srs(srs) , m_ctx(err.ctx)
{
    OGRwkbGeometryType t = OGR_G_GetGeometryType(g);

    if (!(t == wkbPolygon ||
        t == wkbMultiPolygon ||
        t == wkbPolygon25D ||
        t == wkbMultiPolygon25D))
    {
        std::ostringstream oss;
        oss << "pdal::Polygon cannot construct geometry because "
            "OGR geometry is not Polygon or MultiPolygon!";
        throw pdal::pdal_error(oss.str());
    }

    OGRGeometry *ogr_g = (OGRGeometry*)g;
    //
    // Convert the the GDAL geom to WKB in order to avoid the version
    // context issues with exporting directoly to GEOS.
    OGRwkbByteOrder bo =
        GEOS_getWKBByteOrder() == GEOS_WKB_XDR ? wkbXDR : wkbNDR;
    int wkbSize = ogr_g->WkbSize();
    std::vector<unsigned char> wkb(wkbSize);

    ogr_g->exportToWkb(bo, wkb.data());
    m_geom = GEOSGeomFromWKB_buf_r(m_ctx, wkb.data(), wkbSize);
    prepare();

}
Exemplo n.º 3
0
bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature ) const
{
  feature.setFeatureId( OGR_F_GetFID( fet ) );
  feature.initAttributes( mSource->mFields.count() );
  feature.setFields( mSource->mFields ); // allow name-based attribute lookups

  bool useIntersect = mRequest.flags() & QgsFeatureRequest::ExactIntersect;
  bool geometryTypeFilter = mSource->mOgrGeometryTypeFilter != wkbUnknown;
  if ( mFetchGeometry || useIntersect || geometryTypeFilter )
  {
    OGRGeometryH geom = OGR_F_GetGeometryRef( fet );

    if ( geom )
    {
      feature.setGeometry( QgsOgrUtils::ogrGeometryToQgsGeometry( geom ) );
    }
    else
      feature.clearGeometry();

    if ( mSource->mOgrGeometryTypeFilter == wkbGeometryCollection &&
         geom && wkbFlatten( OGR_G_GetGeometryType( geom ) ) == wkbGeometryCollection )
    {
      // OK
    }
    else if (( useIntersect && ( !feature.hasGeometry() || !feature.geometry().intersects( mRequest.filterRect() ) ) )
             || ( geometryTypeFilter && ( !feature.hasGeometry() || QgsOgrProvider::ogrWkbSingleFlatten(( OGRwkbGeometryType )feature.geometry().wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) )
    {
      OGR_F_Destroy( fet );
      return false;
    }
  }

  if ( !mFetchGeometry )
  {
    feature.clearGeometry();
  }

  // fetch attributes
  if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
  {
    QgsAttributeList attrs = mRequest.subsetOfAttributes();
    for ( QgsAttributeList::const_iterator it = attrs.begin(); it != attrs.end(); ++it )
    {
      getFeatureAttribute( fet, feature, *it );
    }
  }
  else
  {
    // all attributes
    for ( int idx = 0; idx < mSource->mFields.count(); ++idx )
    {
      getFeatureAttribute( fet, feature, idx );
    }
  }

  return true;
}
Exemplo n.º 4
0
/*!
  \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 get_line_type(const struct Map_info *Map, long FID)
{
    int eType;
    OGRFeatureH hFeat;
    OGRGeometryH hGeom;

    G_debug(4, "get_line_type() fid = %ld", FID);

    hFeat = OGR_L_GetFeature(Map->fInfo.ogr.layer, FID);
    if (hFeat == NULL)
	return -1;

    hGeom = OGR_F_GetGeometryRef(hFeat);
    if (hGeom == NULL)
	return -1;
    
    eType = wkbFlatten(OGR_G_GetGeometryType(hGeom));

    OGR_F_Destroy(hFeat);

    G_debug(4, "OGR Geometry of type: %d", eType);

    switch (eType) {
    case wkbPoint:
    case wkbMultiPoint:
	return GV_POINT;
	break;
	
    case wkbLineString:
    case wkbMultiLineString:
	return GV_LINE;
	break;

    case wkbPolygon:
    case wkbMultiPolygon:
    case wkbGeometryCollection:
	return GV_BOUNDARY;
	break;

    default:
	G_warning(_("OGR feature type %d not supported"), eType);
	break;
    }

    return -1;
}
Exemplo n.º 5
0
void AttributeFilter::UpdateGEOSBuffer(PointBuffer& buffer, AttributeInfo& info)
{
    QuadIndex idx(buffer);
    idx.build();

    if (!info.lyr) // wake up the layer
    {
        if (info.layer.size())
            info.lyr = OGR_DS_GetLayerByName(info.ds.get(), info.layer.c_str());
        else if (info.query.size())
        {
            info.lyr = OGR_DS_ExecuteSQL(info.ds.get(), info.query.c_str(), 0, 0);
        }
        else
            info.lyr = OGR_DS_GetLayer(info.ds.get(), 0);
        if (!info.lyr)
        {
            std::ostringstream oss;
            oss << "Unable to select layer '" << info.layer << "'";
            throw pdal_error(oss.str());
        }
    }

    OGRFeaturePtr feature = OGRFeaturePtr(OGR_L_GetNextFeature(info.lyr), OGRFeatureDeleter());

    int field_index(1); // default to first column if nothing was set
    if (info.column.size())
    {

        field_index = OGR_F_GetFieldIndex(feature.get(), info.column.c_str());
        if (field_index == -1)
        {
            std::ostringstream oss;
            oss << "No column name '" << info.column << "' was found.";
            throw pdal_error(oss.str());
        }
    }

    while(feature)
    {
        OGRGeometryH geom = OGR_F_GetGeometryRef(feature.get());
        OGRwkbGeometryType t = OGR_G_GetGeometryType(geom);

        int f_count = OGR_F_GetFieldCount (feature.get());

        if (!(t == wkbPolygon ||
            t == wkbMultiPolygon ||
            t == wkbPolygon25D ||
            t == wkbMultiPolygon25D))
        {
            std::ostringstream oss;
            oss << "Geometry is not Polygon or MultiPolygon!";
            throw pdal::pdal_error(oss.str());
        }

        OGRGeometry* ogr_g = (OGRGeometry*) geom;
        GEOSGeometry* geos_g (0);
        if (!m_geosEnvironment)
        {

#if (GDAL_VERSION_MINOR < 11) && (GDAL_VERSION_MAJOR == 1)
        geos_g = ogr_g->exportToGEOS();
#else
        m_geosEnvironment = ogr_g->createGEOSContext();
        geos_g = ogr_g->exportToGEOS(m_geosEnvironment);

#endif
        }

        GEOSPreparedGeometry const* geos_pg = GEOSPrepare_r(m_geosEnvironment, geos_g);
        if (!geos_pg)
            throw pdal_error("unable to prepare geometry for index-accelerated intersection");

        // Compute a total bounds for the geometry. Query the QuadTree to
        // find out the points that are inside the bbox. Then test each
        // point in the bbox against the prepared geometry.
        BOX3D box = computeBounds(m_geosEnvironment, geos_g);
        std::vector<std::size_t> ids = idx.getPoints(box);
        for (const auto& i : ids)
        {

            double x = buffer.getFieldAs<double>(Dimension::Id::X, i);
            double y = buffer.getFieldAs<double>(Dimension::Id::Y, i);
            double z = buffer.getFieldAs<double>(Dimension::Id::Z, i);

            GEOSGeometry* p = createGEOSPoint(m_geosEnvironment, x, y ,z);

            if (static_cast<bool>(GEOSPreparedContains_r(m_geosEnvironment, geos_pg, p)))
            {
                // We're in the poly, write the attribute value
                int32_t v = OGR_F_GetFieldAsInteger(feature.get(), field_index);
                buffer.setField(info.dim, i, v);
//                 log()->get(LogLevel::Debug) << "Setting value: " << v << std::endl;
            }

            GEOSGeom_destroy_r(m_geosEnvironment, p);

        }

        feature = OGRFeaturePtr(OGR_L_GetNextFeature(info.lyr), OGRFeatureDeleter());
    }
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
0
CPLErr
GDALWarpCutlineMasker( void *pMaskFuncArg,
                       CPL_UNUSED int nBandCount,
                       CPL_UNUSED GDALDataType eType,
                       int nXOff, int nYOff, int nXSize, int nYSize,
                       GByte ** /*ppImageData */,
                       int bMaskIsFloat, void *pValidityMask )

{
    GDALWarpOptions *psWO = (GDALWarpOptions *) pMaskFuncArg;
    float *pafMask = (float *) pValidityMask;
    CPLErr eErr;
    GDALDriverH hMemDriver;

    if( nXSize < 1 || nYSize < 1 )
        return CE_None;

/* -------------------------------------------------------------------- */
/*      Do some minimal checking.                                       */
/* -------------------------------------------------------------------- */
    if( !bMaskIsFloat )
    {
        CPLAssert( FALSE );
        return CE_Failure;
    }

    if( psWO == NULL || psWO->hCutline == NULL )
    {
        CPLAssert( FALSE );
        return CE_Failure;
    }

    hMemDriver = GDALGetDriverByName("MEM");
    if (hMemDriver == NULL)
    {
        CPLError(CE_Failure, CPLE_AppDefined, "GDALWarpCutlineMasker needs MEM driver");
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Check the polygon.                                              */
/* -------------------------------------------------------------------- */
    OGRGeometryH hPolygon = (OGRGeometryH) psWO->hCutline;
    OGREnvelope  sEnvelope;

    if( wkbFlatten(OGR_G_GetGeometryType(hPolygon)) != wkbPolygon
        && wkbFlatten(OGR_G_GetGeometryType(hPolygon)) != wkbMultiPolygon )
    {
        CPLAssert( FALSE );
        return CE_Failure;
    }

    OGR_G_GetEnvelope( hPolygon, &sEnvelope );

    if( sEnvelope.MaxX + psWO->dfCutlineBlendDist < nXOff
        || sEnvelope.MinX - psWO->dfCutlineBlendDist > nXOff + nXSize
        || sEnvelope.MaxY + psWO->dfCutlineBlendDist < nYOff
        || sEnvelope.MinY - psWO->dfCutlineBlendDist > nYOff + nYSize )
    {
        // We are far from the blend line - everything is masked to zero.
        // It would be nice to realize no work is required for this whole
        // chunk!
        memset( pafMask, 0, sizeof(float) * nXSize * nYSize );
        return CE_None;
    }

/* -------------------------------------------------------------------- */
/*      Create a byte buffer into which we can burn the                 */
/*      mask polygon and wrap it up as a memory dataset.                */
/* -------------------------------------------------------------------- */
    GByte *pabyPolyMask = (GByte *) CPLCalloc( nXSize, nYSize );
    GDALDatasetH hMemDS;
    double adfGeoTransform[6] = { 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 };

    char szDataPointer[100];
    char *apszOptions[] = { szDataPointer, NULL };

    memset( szDataPointer, 0, sizeof(szDataPointer) );
    sprintf( szDataPointer, "DATAPOINTER=" );
    CPLPrintPointer( szDataPointer+strlen(szDataPointer), 
                    pabyPolyMask, 
                     sizeof(szDataPointer) - strlen(szDataPointer) );

    hMemDS = GDALCreate( hMemDriver, "warp_temp", 
                         nXSize, nYSize, 0, GDT_Byte, NULL );
    GDALAddBand( hMemDS, GDT_Byte, apszOptions );
    GDALSetGeoTransform( hMemDS, adfGeoTransform );

/* -------------------------------------------------------------------- */
/*      Burn the polygon into the mask with 1.0 values.                 */
/* -------------------------------------------------------------------- */
    int nTargetBand = 1;
    double dfBurnValue = 255.0;
    int    anXYOff[2];
    char   **papszRasterizeOptions = NULL;
    

    if( CSLFetchBoolean( psWO->papszWarpOptions, "CUTLINE_ALL_TOUCHED", FALSE ))
        papszRasterizeOptions = 
            CSLSetNameValue( papszRasterizeOptions, "ALL_TOUCHED", "TRUE" );

    anXYOff[0] = nXOff;
    anXYOff[1] = nYOff;

    eErr = 
        GDALRasterizeGeometries( hMemDS, 1, &nTargetBand, 
                                 1, &hPolygon, 
                                 CutlineTransformer, anXYOff, 
                                 &dfBurnValue, papszRasterizeOptions, 
                                 NULL, NULL );

    CSLDestroy( papszRasterizeOptions );

    // Close and ensure data flushed to underlying array.
    GDALClose( hMemDS );

/* -------------------------------------------------------------------- */
/*      In the case with no blend distance, we just apply this as a     */
/*      mask, zeroing out everything outside the polygon.               */
/* -------------------------------------------------------------------- */
    if( psWO->dfCutlineBlendDist == 0.0 )
    {
        int i;

        for( i = nXSize * nYSize - 1; i >= 0; i-- )
        {
            if( pabyPolyMask[i] == 0 )
                ((float *) pValidityMask)[i] = 0.0;
        }
    }
    else
    {
        eErr = BlendMaskGenerator( nXOff, nYOff, nXSize, nYSize, 
                                   pabyPolyMask, (float *) pValidityMask,
                                   hPolygon, psWO->dfCutlineBlendDist );
    }

/* -------------------------------------------------------------------- */
/*      Clean up.                                                       */
/* -------------------------------------------------------------------- */
    CPLFree( pabyPolyMask );

    return eErr;
}
Exemplo n.º 8
0
/*!
  \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;
    }
}
Exemplo n.º 9
0
/*!
  \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;
}
Exemplo n.º 10
0
void AttributeFilter::UpdateGEOSBuffer(PointView& view)
{
    QuadIndex idx(view);

    if (m_layer.size())
        m_lyr = OGR_DS_GetLayerByName(m_ds.get(), m_layer.c_str());
    else if (m_query.size())
        m_lyr = OGR_DS_ExecuteSQL(m_ds.get(), m_query.c_str(), 0, 0);
    else
        m_lyr = OGR_DS_GetLayer(m_ds.get(), 0);

    if (!m_lyr)
    {
        std::ostringstream oss;
        oss << getName() << ": Unable to select layer '" << m_layer << "'";
        throw pdal_error(oss.str());
    }

    OGRFeaturePtr feature = OGRFeaturePtr(OGR_L_GetNextFeature(m_lyr),
        OGRFeatureDeleter());

    int field_index(1); // default to first column if nothing was set
    if (m_column.size())
    {
        field_index = OGR_F_GetFieldIndex(feature.get(), m_column.c_str());
        if (field_index == -1)
        {
            std::ostringstream oss;
            oss << getName() << ": No column name '" << m_column <<
                "' was found.";
            throw pdal_error(oss.str());
        }
    }

    while (feature)
    {
        OGRGeometryH geom = OGR_F_GetGeometryRef(feature.get());
        OGRwkbGeometryType t = OGR_G_GetGeometryType(geom);
        int32_t fieldVal = OGR_F_GetFieldAsInteger(feature.get(), field_index);

        if (!(t == wkbPolygon ||
            t == wkbMultiPolygon ||
            t == wkbPolygon25D ||
            t == wkbMultiPolygon25D))
        {
            std::ostringstream oss;
            oss << getName() << ": Geometry is not Polygon or MultiPolygon!";
            throw pdal::pdal_error(oss.str());
        }

        pdal::Polygon p(geom, view.spatialReference(), GlobalEnvironment::get().geos());

        // Compute a total bounds for the geometry. Query the QuadTree to
        // find out the points that are inside the bbox. Then test each
        // point in the bbox against the prepared geometry.
        BOX3D box = p.bounds();
        std::vector<PointId> ids = idx.getPoints(box);


        for (const auto& i : ids)
        {
            PointRef ref(view, i);
            if (p.covers(ref))
                view.setField(m_dim, i, fieldVal);
        }
        feature = OGRFeaturePtr(OGR_L_GetNextFeature(m_lyr),
            OGRFeatureDeleter());
    }
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
bool QgsOgrFeatureIterator::readFeature( gdal::ogr_feature_unique_ptr fet, QgsFeature &feature ) const
{
  feature.setId( OGR_F_GetFID( fet.get() ) );
  feature.initAttributes( mSource->mFields.count() );
  feature.setFields( mSource->mFields ); // allow name-based attribute lookups

  bool useIntersect = !mRequest.filterRect().isNull();
  bool geometryTypeFilter = mSource->mOgrGeometryTypeFilter != wkbUnknown;
  if ( mFetchGeometry || useIntersect || geometryTypeFilter )
  {
    OGRGeometryH geom = OGR_F_GetGeometryRef( fet.get() );

    if ( geom )
    {
      QgsGeometry g = QgsOgrUtils::ogrGeometryToQgsGeometry( geom );

      // Insure that multipart datasets return multipart geometry
      if ( QgsWkbTypes::isMultiType( mSource->mWkbType ) && !g.isMultipart() )
      {
        g.convertToMultiType();
      }

      feature.setGeometry( g );
    }
    else
      feature.clearGeometry();

    if ( mSource->mOgrGeometryTypeFilter == wkbGeometryCollection &&
         geom && wkbFlatten( OGR_G_GetGeometryType( geom ) ) == wkbGeometryCollection )
    {
      // OK
    }
    else if ( ( useIntersect && ( !feature.hasGeometry()
                                  || ( mRequest.flags() & QgsFeatureRequest::ExactIntersect && !feature.geometry().intersects( mFilterRect ) )
                                  || ( !( mRequest.flags() & QgsFeatureRequest::ExactIntersect ) && !feature.geometry().boundingBoxIntersects( mFilterRect ) )
                                )
              )
              || ( geometryTypeFilter && ( !feature.hasGeometry() || QgsOgrProvider::ogrWkbSingleFlatten( ( OGRwkbGeometryType )feature.geometry().wkbType() ) != mSource->mOgrGeometryTypeFilter ) ) )
    {
      return false;
    }
  }

  if ( !mFetchGeometry )
  {
    feature.clearGeometry();
  }

  // fetch attributes
  if ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes )
  {
    QgsAttributeList attrs = mRequest.subsetOfAttributes();
    for ( QgsAttributeList::const_iterator it = attrs.constBegin(); it != attrs.constEnd(); ++it )
    {
      getFeatureAttribute( fet.get(), feature, *it );
    }
  }
  else
  {
    // all attributes
    const auto fieldCount = mSource->mFields.count();
    for ( int idx = 0; idx < fieldCount; ++idx )
    {
      getFeatureAttribute( fet.get(), feature, idx );
    }
  }

  return true;
}
Exemplo n.º 13
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;
}