Exemplo n.º 1
0
void Polygon::initializeFromBounds(const BOX3D& box)
{
    GEOSCoordSequence* coords = GEOSCoordSeq_create_r(m_ctx, 5, 3);
    auto set_coordinate = [coords, this](int pt_num, const double&x,
        const double& y, const double& z)
    {
        if (!GEOSCoordSeq_setX_r(m_ctx, coords, pt_num, x))
            throw pdal_error("unable to set x for coordinate sequence");
        if (!GEOSCoordSeq_setY_r(m_ctx, coords, pt_num, y))
            throw pdal_error("unable to set y for coordinate sequence");
        if (!GEOSCoordSeq_setZ_r(m_ctx, coords, pt_num, z))
            throw pdal_error("unable to set z for coordinate sequence");
    };

    set_coordinate(0, box.minx, box.miny, box.minz);
    set_coordinate(1, box.minx, box.maxy, box.minz);
    set_coordinate(2, box.maxx, box.maxy, box.maxz);
    set_coordinate(3, box.maxx, box.miny, box.maxz);
    set_coordinate(4, box.minx, box.miny, box.minz);


    GEOSGeometry* ring = GEOSGeom_createLinearRing_r(m_ctx, coords);
    if (!ring)
        throw pdal_error("unable to create linear ring from BOX2D");


    m_geom = GEOSGeom_createPolygon_r(m_ctx, ring, 0, 0);
    if (!m_geom)
        throw pdal_error("unable to create polygon from linear ring in "
            "BOX2D constructor");
    prepare();
}
Exemplo n.º 2
0
bool Polygon::covers(PointRef& ref) const
{
    GEOSCoordSequence* coords = GEOSCoordSeq_create_r(m_ctx, 1, 3);
    if (!coords)
        throw pdal_error("Unable to allocate coordinate sequence");

    const double x = ref.getFieldAs<double>(Dimension::Id::X);
    const double y = ref.getFieldAs<double>(Dimension::Id::Y);
    const double z = ref.getFieldAs<double>(Dimension::Id::Z);

    if (!GEOSCoordSeq_setX_r(m_ctx, coords, 0, x))
        throw pdal_error("unable to set x for coordinate sequence");
    if (!GEOSCoordSeq_setY_r(m_ctx, coords, 0, y))
        throw pdal_error("unable to set y for coordinate sequence");
    if (!GEOSCoordSeq_setZ_r(m_ctx, coords, 0, z))
        throw pdal_error("unable to set z for coordinate sequence");
    GEOSGeometry* p = GEOSGeom_createPoint_r(m_ctx, coords);
    if (!p)
        throw pdal_error("unable to allocate candidate test point");

    bool covers = (bool)(GEOSPreparedCovers_r(m_ctx, m_prepGeom, p));
    GEOSGeom_destroy_r(m_ctx, p);

    return covers;
}
Exemplo n.º 3
0
void QgsZonalStatistics::statisticsFromMiddlePointTest( void* band, QgsGeometry* poly, int pixelOffsetX,
    int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle& rasterBBox, double& sum, double& count )
{
  double cellCenterX, cellCenterY;

  float* scanLine = ( float * ) CPLMalloc( sizeof( float ) * nCellsX );
  cellCenterY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2;
  count = 0;
  sum = 0;

  const GEOSGeometry* polyGeos = poly->asGeos();
  if ( !polyGeos )
  {
    return;
  }

  GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler();
  const GEOSPreparedGeometry* polyGeosPrepared = GEOSPrepare_r( geosctxt, poly->asGeos() );
  if ( !polyGeosPrepared )
  {
    return;
  }

  GEOSCoordSequence* cellCenterCoords = 0;
  GEOSGeometry* currentCellCenter = 0;

  for ( int i = 0; i < nCellsY; ++i )
  {
    if ( GDALRasterIO( band, GF_Read, pixelOffsetX, pixelOffsetY + i, nCellsX, 1, scanLine, nCellsX, 1, GDT_Float32, 0, 0 )
         != CPLE_None )
    {
      continue;
    }
    cellCenterX = rasterBBox.xMinimum() + pixelOffsetX * cellSizeX + cellSizeX / 2;
    for ( int j = 0; j < nCellsX; ++j )
    {
      GEOSGeom_destroy_r( geosctxt, currentCellCenter );
      cellCenterCoords = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
      GEOSCoordSeq_setX_r( geosctxt, cellCenterCoords, 0, cellCenterX );
      GEOSCoordSeq_setY_r( geosctxt, cellCenterCoords, 0, cellCenterY );
      currentCellCenter = GEOSGeom_createPoint_r( geosctxt, cellCenterCoords );

      if ( scanLine[j] != mInputNodataValue ) //don't consider nodata values
      {
        if ( GEOSPreparedContains_r( geosctxt, polyGeosPrepared, currentCellCenter ) )
        {
          if ( !qIsNaN( scanLine[j] ) )
          {
            sum += scanLine[j];
          }
          ++count;
        }
      }
      cellCenterX += cellSizeX;
    }
    cellCenterY -= cellSizeY;
  }
  CPLFree( scanLine );
  GEOSPreparedGeom_destroy_r( geosctxt, polyGeosPrepared );
}
Exemplo n.º 4
0
void Crop::crop(PointBuffer& input, PointBuffer& output)
{
    bool logOutput = (log()->getLevel() > LogLevel::Debug4);
    if (logOutput)
        log()->floatPrecision(8);

    for (PointId idx = 0; idx < input.size(); ++idx)
    {
        double x = input.getFieldAs<double>(Dimension::Id::X, idx);
        double y = input.getFieldAs<double>(Dimension::Id::Y, idx);
        double z = input.getFieldAs<double>(Dimension::Id::Z, idx);

        if (logOutput)
        {
            log()->floatPrecision(10);
            log()->get(LogLevel::Debug5) << "input: " << x << " y: " << y <<
                " z: " << z << std::endl;
        }

        if (m_poly.empty())
        {
            // We don't have a polygon, just a bounds. Filter on that
            // by itself.
            if (!m_cropOutside && m_bounds.contains(x, y, z))
                output.appendPoint(input, idx);
        }
#ifdef PDAL_HAVE_GEOS
        else
        {
            int ret(0);

            // precise filtering based on the geometry
            GEOSCoordSequence* coords =
                GEOSCoordSeq_create_r(m_geosEnvironment, 1, 3);
            if (!coords)
                throw pdal_error("unable to allocate coordinate sequence");
            ret = GEOSCoordSeq_setX_r(m_geosEnvironment, coords, 0, x);
            if (!ret)
                throw pdal_error("unable to set x for coordinate sequence");
            ret = GEOSCoordSeq_setY_r(m_geosEnvironment, coords, 0, y);
            if (!ret)
                throw pdal_error("unable to set y for coordinate sequence");
            ret = GEOSCoordSeq_setZ_r(m_geosEnvironment, coords, 0, z);
            if (!ret)
                throw pdal_error("unable to set z for coordinate sequence");

            GEOSGeometry* p = GEOSGeom_createPoint_r(m_geosEnvironment, coords);
            if (!p)
                throw pdal_error("unable to allocate candidate test point");

            if (static_cast<bool>(GEOSPreparedContains_r(m_geosEnvironment,
                m_geosPreparedGeometry, p)) != m_cropOutside)
                output.appendPoint(input, idx);
            GEOSGeom_destroy_r(m_geosEnvironment, p);
        }
#endif
    }
}
void QgsZonalStatistics::statisticsFromMiddlePointTest( void* band, const QgsGeometry& poly, int pixelOffsetX,
    int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle& rasterBBox, FeatureStats &stats )
{
  double cellCenterX, cellCenterY;

  float* scanLine = ( float * ) CPLMalloc( sizeof( float ) * nCellsX );
  cellCenterY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2;
  stats.reset();

  GEOSGeometry* polyGeos = poly.exportToGeos();
  if ( !polyGeos )
  {
    return;
  }

  GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler();
  const GEOSPreparedGeometry* polyGeosPrepared = GEOSPrepare_r( geosctxt, polyGeos );
  if ( !polyGeosPrepared )
  {
    GEOSGeom_destroy_r( geosctxt, polyGeos );
    return;
  }

  GEOSCoordSequence* cellCenterCoords = nullptr;
  GEOSGeometry* currentCellCenter = nullptr;

  for ( int i = 0; i < nCellsY; ++i )
  {
    if ( GDALRasterIO( band, GF_Read, pixelOffsetX, pixelOffsetY + i, nCellsX, 1, scanLine, nCellsX, 1, GDT_Float32, 0, 0 )
         != CPLE_None )
    {
      continue;
    }
    cellCenterX = rasterBBox.xMinimum() + pixelOffsetX * cellSizeX + cellSizeX / 2;
    for ( int j = 0; j < nCellsX; ++j )
    {
      if ( validPixel( scanLine[j] ) )
      {
        GEOSGeom_destroy_r( geosctxt, currentCellCenter );
        cellCenterCoords = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
        GEOSCoordSeq_setX_r( geosctxt, cellCenterCoords, 0, cellCenterX );
        GEOSCoordSeq_setY_r( geosctxt, cellCenterCoords, 0, cellCenterY );
        currentCellCenter = GEOSGeom_createPoint_r( geosctxt, cellCenterCoords );
        if ( GEOSPreparedContains_r( geosctxt, polyGeosPrepared, currentCellCenter ) )
        {
          stats.addValue( scanLine[j] );
        }
      }
      cellCenterX += cellSizeX;
    }
    cellCenterY -= cellSizeY;
  }
  GEOSGeom_destroy_r( geosctxt, currentCellCenter );
  CPLFree( scanLine );
  GEOSPreparedGeom_destroy_r( geosctxt, polyGeosPrepared );
  GEOSGeom_destroy_r( geosctxt, polyGeos );
}
Exemplo n.º 6
0
void terms_to_coordseq(GEOSCommand *command) {
        char *buffer = command->param_bytes;
        int *index = &command->index;
        int size;
	GEOSCoordSequence *coordSeq = NULL;
	
	GEOSContextHandle_t handle = command->driver_data->handle;
        
	if(ei_decode_list_header(buffer, index, &size)) {
          	erl_send_error(command, "notalist");
		return;
	}

	unsigned int i;
	for(i = 0; i < size; i++) {
		//for each element
		int digitc;
		double x,y,z;

		if(ei_decode_tuple_header(buffer, index, &digitc)) {
          		erl_send_error(command, "invalidlist");
			if(coordSeq!=NULL) GEOSCoordSeq_destroy_r(handle, coordSeq);
			return;
        	}
		
		if(coordSeq == NULL) {
			coordSeq = GEOSCoordSeq_create_r(handle, size, digitc);
			if(coordSeq == NULL) {
				erl_send_error(command, "create");
				return;
			}
		}
		
		if(next_number(command, &x) || GEOSCoordSeq_setX_r(handle, coordSeq, i, x)==0) {
			erl_send_error(command, "setx");
			GEOSCoordSeq_destroy_r(handle, coordSeq);
			return;

		}	
		if(next_number(command, &y) || GEOSCoordSeq_setY_r(handle, coordSeq, i, y)==0) {
			erl_send_error(command, "sety");
			GEOSCoordSeq_destroy_r(handle, coordSeq);
			return;

		}
		if(digitc == 3) {
			if(next_number(command, &z) || GEOSCoordSeq_setZ_r(handle, coordSeq, i, z)==0) {
				erl_send_error(command, "setz");
				GEOSCoordSeq_destroy_r(handle, coordSeq);
				return;

			}
		}
	}
	ERL_WRITE_PTR_GEOSCOORDSEQUENCE(command, coordSeq);
}
Exemplo n.º 7
0
void QgsZonalStatistics::statisticsFromMiddlePointTest( const QgsGeometry &poly, int pixelOffsetX,
    int pixelOffsetY, int nCellsX, int nCellsY, double cellSizeX, double cellSizeY, const QgsRectangle &rasterBBox, FeatureStats &stats )
{
  double cellCenterX, cellCenterY;

  cellCenterY = rasterBBox.yMaximum() - pixelOffsetY * cellSizeY - cellSizeY / 2;
  stats.reset();

  GEOSGeometry *polyGeos = poly.exportToGeos();
  if ( !polyGeos )
  {
    return;
  }

  GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler();
  const GEOSPreparedGeometry *polyGeosPrepared = GEOSPrepare_r( geosctxt, polyGeos );
  if ( !polyGeosPrepared )
  {
    GEOSGeom_destroy_r( geosctxt, polyGeos );
    return;
  }

  GEOSCoordSequence *cellCenterCoords = nullptr;
  GEOSGeometry *currentCellCenter = nullptr;

  QgsRectangle featureBBox = poly.boundingBox().intersect( &rasterBBox );
  QgsRectangle intersectBBox = rasterBBox.intersect( &featureBBox );

  QgsRasterBlock *block = mRasterProvider->block( mRasterBand, intersectBBox, nCellsX, nCellsY );
  for ( int i = 0; i < nCellsY; ++i )
  {
    cellCenterX = rasterBBox.xMinimum() + pixelOffsetX * cellSizeX + cellSizeX / 2;
    for ( int j = 0; j < nCellsX; ++j )
    {
      if ( validPixel( block->value( i, j ) ) )
      {
        GEOSGeom_destroy_r( geosctxt, currentCellCenter );
        cellCenterCoords = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
        GEOSCoordSeq_setX_r( geosctxt, cellCenterCoords, 0, cellCenterX );
        GEOSCoordSeq_setY_r( geosctxt, cellCenterCoords, 0, cellCenterY );
        currentCellCenter = GEOSGeom_createPoint_r( geosctxt, cellCenterCoords );
        if ( GEOSPreparedContains_r( geosctxt, polyGeosPrepared, currentCellCenter ) )
        {
          stats.addValue( block->value( i, j ) );
        }
      }
      cellCenterX += cellSizeX;
    }
    cellCenterY -= cellSizeY;
  }

  GEOSGeom_destroy_r( geosctxt, currentCellCenter );
  GEOSPreparedGeom_destroy_r( geosctxt, polyGeosPrepared );
  GEOSGeom_destroy_r( geosctxt, polyGeos );
  delete block;
}
Exemplo n.º 8
0
GEOSGeometry *LineAccumulator::as_geom(GEOSContextHandle_t handle)
{
    m_lines.remove_if(degenerate_line);

    if(m_lines.size() > 1)
    {
        //std::cerr << "Checking first & last" << std::endl;
        Point first, last;
        first = m_lines.front().front();
        last = m_lines.back().back();
        //std::cerr << "first: " << first.x << ", " << first.y << std::endl;
        //std::cerr << "last: " << last.x << ", " << last.y << std::endl;
        if(close(first.x, last.x) && close(first.y, last.y))
        {
            m_lines.front().pop_front();
            m_lines.back().splice(m_lines.back().end(), m_lines.front());
            m_lines.pop_front();
        }
    }

    std::vector<GEOSGeometry *> geoms;
    std::list<Line>::const_iterator ilines;
    for(ilines = m_lines.begin(); ilines != m_lines.end(); ++ilines)
    {
        std::list<Point>::const_iterator ipoints;
        int i;

        GEOSCoordSequence *coords = GEOSCoordSeq_create_r(handle, (*ilines).size(), 2);
        for(ipoints = (*ilines).begin(), i = 0; ipoints != (*ilines).end(); ++ipoints, ++i)
        {
            GEOSCoordSeq_setX_r(handle, coords, i, ipoints->x);
            GEOSCoordSeq_setY_r(handle, coords, i, ipoints->y);
        }
        geoms.push_back(GEOSGeom_createLineString_r(handle, coords));
    }

    GEOSGeometry *geom;
    if(geoms.empty())
    {
        geom = GEOSGeom_createEmptyCollection_r(handle, GEOS_MULTILINESTRING);
    }
    else
    {
        geom = GEOSGeom_createCollection_r(handle, GEOS_MULTILINESTRING,
                                           &geoms[0], geoms.size());
    }
    return geom;
}
Exemplo n.º 9
0
static void populate_geom_into_coord_seq(GEOSContextHandle_t context, const GEOSGeometry* geom, GEOSCoordSequence* coord_seq, unsigned int i, char has_z)
{
  const GEOSCoordSequence* cs = GEOSGeom_getCoordSeq_r(context, geom);
  double x = 0;
  if (cs) {
    GEOSCoordSeq_getX_r(context, cs, 0, &x);
  }
  GEOSCoordSeq_setX_r(context, coord_seq, i, x);
  x = 0;
  if (cs) {
    GEOSCoordSeq_getY_r(context, cs, 0, &x);
  }
  GEOSCoordSeq_setY_r(context, coord_seq, i, x);
  x = 0;
  if (has_z && cs) {
    GEOSCoordSeq_getZ_r(context, cs, 0, &x);
  }
  GEOSCoordSeq_setZ_r(context, coord_seq, i, x);
}
Exemplo n.º 10
0
VALUE rgeo_create_geos_point(VALUE factory, double x, double y, double z)
{
  VALUE result = Qnil;
  RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(factory);
  GEOSContextHandle_t context = factory_data->geos_context;
  GEOSCoordSequence* coord_seq = GEOSCoordSeq_create_r(context, 1, 3);
  if (coord_seq) {
    if (GEOSCoordSeq_setX_r(context, coord_seq, 0, x)) {
      if (GEOSCoordSeq_setY_r(context, coord_seq, 0, y)) {
        if (GEOSCoordSeq_setZ_r(context, coord_seq, 0, z)) {
          GEOSGeometry* geom = GEOSGeom_createPoint_r(context, coord_seq);
          if (geom) {
            result = rgeo_wrap_geos_geometry(factory, geom, factory_data->globals->geos_point);
          }
        }
      }
    }
  }
  return result;
}
Exemplo n.º 11
0
State get_state(const Point &point, const GEOSPreparedGeometry *gp_domain,
                GEOSContextHandle_t handle)
{
    State state;

    if (isfinite(point.x) && isfinite(point.y))
    {
        // TODO: Avoid create-destroy
        GEOSCoordSequence *coords = GEOSCoordSeq_create_r(handle, 1, 2);
        GEOSCoordSeq_setX_r(handle, coords, 0, point.x);
        GEOSCoordSeq_setY_r(handle, coords, 0, point.y);
        GEOSGeometry *g_point = GEOSGeom_createPoint_r(handle, coords);
        state = GEOSPreparedCovers_r(handle, gp_domain, g_point) ? POINT_IN : POINT_OUT;
        GEOSGeom_destroy_r(handle, g_point);
    }
    else
    {
        state = POINT_NAN;
    }
    return state;
}
Exemplo n.º 12
0
GEOSGeometry* createGEOSPoint(GEOSContextHandle_t ctx, double x, double y, double z)
{
    int ret(0);

    // precise filtering based on the geometry
    GEOSCoordSequence* coords =
        GEOSCoordSeq_create_r(ctx, 1, 3);
    if (!coords)
        throw pdal_error("unable to allocate coordinate sequence");
    ret = GEOSCoordSeq_setX_r(ctx, coords, 0, x);
    if (!ret)
        throw pdal_error("unable to set x for coordinate sequence");
    ret = GEOSCoordSeq_setY_r(ctx, coords, 0, y);
    if (!ret)
        throw pdal_error("unable to set y for coordinate sequence");
    ret = GEOSCoordSeq_setZ_r(ctx, coords, 0, z);
    if (!ret)
        throw pdal_error("unable to set z for coordinate sequence");

    GEOSGeometry* p = GEOSGeom_createPoint_r(ctx, coords);
    if (!p)
        throw pdal_error("unable to allocate candidate test point");
    return p;
}
QgsGeometry QgsGeometryAnalyzer::createOffsetGeometry( const QgsGeometry& geom, const QgsGeometry& lineGeom, double offset )
{
  if ( !geom || lineGeom.isEmpty() )
  {
    return QgsGeometry();
  }

  QList<QgsGeometry> inputGeomList;

  if ( geom.isMultipart() )
  {
    inputGeomList = geom.asGeometryCollection();
  }
  else
  {
    inputGeomList.push_back( geom );
  }

  QList<GEOSGeometry*> outputGeomList;
  QList<QgsGeometry>::const_iterator inputGeomIt = inputGeomList.constBegin();
  GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler();
  for ( ; inputGeomIt != inputGeomList.constEnd(); ++inputGeomIt )
  {
    if ( geom.type() == QgsWkbTypes::LineGeometry )
    {
      GEOSGeometry* inputGeomItGeos = inputGeomIt->exportToGeos();
      GEOSGeometry* offsetGeom = GEOSOffsetCurve_r( geosctxt, inputGeomItGeos, -offset, 8 /*quadSegments*/, 0 /*joinStyle*/, 5.0 /*mitreLimit*/ );
      GEOSGeom_destroy_r( geosctxt, inputGeomItGeos );
      if ( !offsetGeom || !GEOSisValid_r( geosctxt, offsetGeom ) )
      {
        return QgsGeometry();
      }
      if ( !GEOSisValid_r( geosctxt, offsetGeom ) || GEOSGeomTypeId_r( geosctxt, offsetGeom ) != GEOS_LINESTRING || GEOSGeomGetNumPoints_r( geosctxt, offsetGeom ) < 1 )
      {
        GEOSGeom_destroy_r( geosctxt, offsetGeom );
        return QgsGeometry();
      }
      outputGeomList.push_back( offsetGeom );
    }
    else if ( geom.type() == QgsWkbTypes::PointGeometry )
    {
      QgsPoint p = ( *inputGeomIt ).asPoint();
      p = createPointOffset( p.x(), p.y(), offset, lineGeom );
      GEOSCoordSequence* ptSeq = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
      GEOSCoordSeq_setX_r( geosctxt, ptSeq, 0, p.x() );
      GEOSCoordSeq_setY_r( geosctxt, ptSeq, 0, p.y() );
      GEOSGeometry* geosPt = GEOSGeom_createPoint_r( geosctxt, ptSeq );
      outputGeomList.push_back( geosPt );
    }
  }

  QgsGeometry outGeometry;
  if ( !geom.isMultipart() )
  {
    GEOSGeometry* outputGeom = outputGeomList.at( 0 );
    if ( outputGeom )
    {
      outGeometry.fromGeos( outputGeom );
    }
  }
  else
  {
    GEOSGeometry** geomArray = new GEOSGeometry*[outputGeomList.size()];
    for ( int i = 0; i < outputGeomList.size(); ++i )
    {
      geomArray[i] = outputGeomList.at( i );
    }
    GEOSGeometry* collection = nullptr;
    if ( geom.type() == QgsWkbTypes::PointGeometry )
    {
      collection = GEOSGeom_createCollection_r( geosctxt, GEOS_MULTIPOINT, geomArray, outputGeomList.size() );
    }
    else if ( geom.type() == QgsWkbTypes::LineGeometry )
    {
      collection = GEOSGeom_createCollection_r( geosctxt, GEOS_MULTILINESTRING, geomArray, outputGeomList.size() );
    }
    outGeometry.fromGeos( collection );
    delete[] geomArray;
  }
  return outGeometry;
}
Exemplo n.º 14
0
void Layer::chopFeaturesAtRepeatDistance()
{
    GEOSContextHandle_t geosctxt = geosContext();
    QLinkedList<FeaturePart*> * newFeatureParts = new QLinkedList<FeaturePart*>;
    while ( !featureParts->isEmpty() )
    {
        FeaturePart* fpart = featureParts->takeFirst();
        const GEOSGeometry* geom = fpart->geos();
        double chopInterval = fpart->getFeature()->repeatDistance();
        if ( chopInterval != 0. && GEOSGeomTypeId_r( geosctxt, geom ) == GEOS_LINESTRING )
        {

            double bmin[2], bmax[2];
            fpart->getBoundingBox( bmin, bmax );
            rtree->Remove( bmin, bmax, fpart );

            const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosctxt, geom );

            // get number of points
            unsigned int n;
            GEOSCoordSeq_getSize_r( geosctxt, cs, &n );

            // Read points
            std::vector<Point> points( n );
            for ( unsigned int i = 0; i < n; ++i )
            {
                GEOSCoordSeq_getX_r( geosctxt, cs, i, &points[i].x );
                GEOSCoordSeq_getY_r( geosctxt, cs, i, &points[i].y );
            }

            // Cumulative length vector
            std::vector<double> len( n, 0 );
            for ( unsigned int i = 1; i < n; ++i )
            {
                double dx = points[i].x - points[i - 1].x;
                double dy = points[i].y - points[i - 1].y;
                len[i] = len[i - 1] + std::sqrt( dx * dx + dy * dy );
            }

            // Walk along line
            unsigned int cur = 0;
            double lambda = 0;
            std::vector<Point> part;
            for ( ;; )
            {
                lambda += chopInterval;
                for ( ; cur < n && lambda > len[cur]; ++cur )
                {
                    part.push_back( points[cur] );
                }
                if ( cur >= n )
                {
                    break;
                }
                double c = ( lambda - len[cur - 1] ) / ( len[cur] - len[cur - 1] );
                Point p;
                p.x = points[cur - 1].x + c * ( points[cur].x - points[cur - 1].x );
                p.y = points[cur - 1].y + c * ( points[cur].y - points[cur - 1].y );
                part.push_back( p );
                GEOSCoordSequence* cooSeq = GEOSCoordSeq_create_r( geosctxt, part.size(), 2 );
                for ( std::size_t i = 0; i < part.size(); ++i )
                {
                    GEOSCoordSeq_setX_r( geosctxt, cooSeq, i, part[i].x );
                    GEOSCoordSeq_setY_r( geosctxt, cooSeq, i, part[i].y );
                }

                GEOSGeometry* newgeom = GEOSGeom_createLineString_r( geosctxt, cooSeq );
                FeaturePart* newfpart = new FeaturePart( fpart->getFeature(), newgeom );
                newFeatureParts->append( newfpart );
                newfpart->getBoundingBox( bmin, bmax );
                rtree->Insert( bmin, bmax, newfpart );
                part.clear();
                part.push_back( p );
            }
            // Create final part
            part.push_back( points[n - 1] );
            GEOSCoordSequence* cooSeq = GEOSCoordSeq_create_r( geosctxt, part.size(), 2 );
            for ( std::size_t i = 0; i < part.size(); ++i )
            {
                GEOSCoordSeq_setX_r( geosctxt, cooSeq, i, part[i].x );
                GEOSCoordSeq_setY_r( geosctxt, cooSeq, i, part[i].y );
            }

            GEOSGeometry* newgeom = GEOSGeom_createLineString_r( geosctxt, cooSeq );
            FeaturePart* newfpart = new FeaturePart( fpart->getFeature(), newgeom );
            newFeatureParts->append( newfpart );
            newfpart->getBoundingBox( bmin, bmax );
            rtree->Insert( bmin, bmax, newfpart );
        }
        else
        {
            newFeatureParts->append( fpart );
        }
    }

    delete featureParts;
    featureParts = newFeatureParts;
}
Exemplo n.º 15
0
/*
 * Return whether the given line segment is suitable as an
 * approximation of the projection of the source line.
 *
 * t_start: Interpolation parameter for the start point.
 * p_start: Projected start point.
 * t_end: Interpolation parameter for the end point.
 * p_start: Projected end point.
 * interpolator: Interpolator for current source line.
 * threshold: Lateral tolerance in target projection coordinates.
 * handle: Thread-local context handle for GEOS.
 * gp_domain: Prepared polygon of target map domain.
 * inside: Whether the start point is within the map domain.
 */
bool straightAndDomain(double t_start, const Point &p_start,
                       double t_end, const Point &p_end,
                       Interpolator *interpolator, double threshold,
                       GEOSContextHandle_t handle,
                       const GEOSPreparedGeometry *gp_domain,
                       bool inside)
{
    // Straight and in-domain (de9im[7] == 'F')
    
    bool valid;

    // This could be optimised out of the loop.
    if (!(isfinite(p_start.x) && isfinite(p_start.y)))
    {
        valid = false;
    }
    else if (!(isfinite(p_end.x) && isfinite(p_end.y)))
    {
        valid = false;
    }
    else
    {
        // TODO: Re-use geometries, instead of create-destroy!

        // Create a LineString for the current end-point.
        GEOSCoordSequence *coords = GEOSCoordSeq_create_r(handle, 2, 2);
        GEOSCoordSeq_setX_r(handle, coords, 0, p_start.x);
        GEOSCoordSeq_setY_r(handle, coords, 0, p_start.y);
        GEOSCoordSeq_setX_r(handle, coords, 1, p_end.x);
        GEOSCoordSeq_setY_r(handle, coords, 1, p_end.y);
        GEOSGeometry *g_segment = GEOSGeom_createLineString_r(handle, coords);

        // Find the projected mid-point
        double t_mid = (t_start + t_end) * 0.5;
        Point p_mid = interpolator->interpolate(t_mid);

        // Make it into a GEOS geometry
        coords = GEOSCoordSeq_create_r(handle, 1, 2);
        GEOSCoordSeq_setX_r(handle, coords, 0, p_mid.x);
        GEOSCoordSeq_setY_r(handle, coords, 0, p_mid.y);
        GEOSGeometry *g_mid = GEOSGeom_createPoint_r(handle, coords);

        double along = GEOSProjectNormalized_r(handle, g_segment, g_mid);
        if(isnan(along))
        {
            valid = true;
        }
        else
        {
            valid = 0.0 < along && along < 1.0;
            if (valid)
            {
                double separation;
                GEOSDistance_r(handle, g_segment, g_mid, &separation);
                if (inside)
                {
                    // Scale the lateral threshold by the distance from
                    // the nearest end. I.e. Near the ends the lateral
                    // threshold is much smaller; it only has its full
                    // value in the middle.
                    valid = separation <= threshold * 2.0 *
                                            (0.5 - fabs(0.5 - along));
                }
                else
                {
                    // Check if the mid-point makes less than ~11 degree
                    // angle with the straight line.
                    // sin(11') => 0.2
                    // To save the square-root we just use the square of
                    // the lengths, hence:
                    // 0.2 ^ 2 => 0.04
                    double hypot_dx = p_mid.x - p_start.x;
                    double hypot_dy = p_mid.y - p_start.y;
                    double hypot = hypot_dx * hypot_dx + hypot_dy * hypot_dy;
                    valid = ((separation * separation) / hypot) < 0.04;
                }
            }
        }

        if (valid)
        {
            if(inside)
                valid = GEOSPreparedCovers_r(handle, gp_domain, g_segment);
            else
                valid = GEOSPreparedDisjoint_r(handle, gp_domain, g_segment);
        }

        GEOSGeom_destroy_r(handle, g_segment);
        GEOSGeom_destroy_r(handle, g_mid);
    }

    return valid;
}
Exemplo n.º 16
0
bool QgsGeometryAnalyzer::createOffsetGeometry( QgsGeometry* geom, QgsGeometry* lineGeom, double offset )
{
  if ( !geom || !lineGeom )
  {
    return false;
  }

  QList<QgsGeometry*> inputGeomList;

  if ( geom->isMultipart() )
  {
    inputGeomList = geom->asGeometryCollection();
  }
  else
  {
    inputGeomList.push_back( geom );
  }

  QList<GEOSGeometry*> outputGeomList;
  QList<QgsGeometry*>::const_iterator inputGeomIt = inputGeomList.constBegin();
  GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler();
  for ( ; inputGeomIt != inputGeomList.constEnd(); ++inputGeomIt )
  {
    if ( geom->type() == QGis::Line )
    {
      //geos 3.3 needed for line offsets
#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
      ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)))
      GEOSGeometry* offsetGeom = GEOSOffsetCurve_r( geosctxt, ( *inputGeomIt )->asGeos(), -offset, 8 /*quadSegments*/, 0 /*joinStyle*/, 5.0 /*mitreLimit*/ );
      if ( !offsetGeom || !GEOSisValid_r( geosctxt, offsetGeom ) )
      {
        return false;
      }
      if ( !GEOSisValid_r( geosctxt, offsetGeom ) || GEOSGeomTypeId_r( geosctxt, offsetGeom ) != GEOS_LINESTRING || GEOSGeomGetNumPoints_r( geosctxt, offsetGeom ) < 1 )
      {
        GEOSGeom_destroy_r( geosctxt, offsetGeom );
        return false;
      }
      outputGeomList.push_back( offsetGeom );
#else
      outputGeomList.push_back( GEOSGeom_clone_r( geosctxt, ( *inputGeomIt )->asGeos() ) );
#endif
    }
    else if ( geom->type() == QGis::Point )
    {
      QgsPoint p = ( *inputGeomIt )->asPoint();
      p = createPointOffset( p.x(), p.y(), offset, lineGeom );
      GEOSCoordSequence* ptSeq = GEOSCoordSeq_create_r( geosctxt, 1, 2 );
      GEOSCoordSeq_setX_r( geosctxt, ptSeq, 0, p.x() );
      GEOSCoordSeq_setY_r( geosctxt, ptSeq, 0, p.y() );
      GEOSGeometry* geosPt = GEOSGeom_createPoint_r( geosctxt, ptSeq );
      outputGeomList.push_back( geosPt );
    }
  }

  if ( !geom->isMultipart() )
  {
    GEOSGeometry* outputGeom = outputGeomList.at( 0 );
    if ( outputGeom )
    {
      geom->fromGeos( outputGeom );
    }
  }
  else
  {
    GEOSGeometry** geomArray = new GEOSGeometry*[outputGeomList.size()];
    for ( int i = 0; i < outputGeomList.size(); ++i )
    {
      geomArray[i] = outputGeomList.at( i );
    }
    GEOSGeometry* collection = 0;
    if ( geom->type() == QGis::Point )
    {
      collection = GEOSGeom_createCollection_r( geosctxt, GEOS_MULTIPOINT, geomArray, outputGeomList.size() );
    }
    else if ( geom->type() == QGis::Line )
    {
      collection = GEOSGeom_createCollection_r( geosctxt, GEOS_MULTILINESTRING, geomArray, outputGeomList.size() );
    }
    geom->fromGeos( collection );
    delete[] geomArray;
  }
  return true;
}
Exemplo n.º 17
0
static GEOSCoordSequence* coord_seq_from_array(VALUE factory, VALUE array, char close)
{
  Check_Type(array, T_ARRAY);
  RGeo_FactoryData* factory_data = RGEO_FACTORY_DATA_PTR(factory);
  VALUE point_type = factory_data->globals->feature_point;
  unsigned int len = (unsigned int)RARRAY_LEN(array);
  char has_z = (char)(RGEO_FACTORY_DATA_PTR(factory)->flags & RGEO_FACTORYFLAGS_SUPPORTS_Z_OR_M);
  unsigned int dims = has_z ? 3 : 2;
  double* coords = ALLOC_N(double, len == 0 ? 1 : len * dims);
  if (!coords) {
    return NULL;
  }
  GEOSContextHandle_t context = factory_data->geos_context;
  unsigned int i;
  for (i=0; i<len; ++i) {
    char good = 0;
    const GEOSGeometry* entry_geom = rgeo_convert_to_geos_geometry(factory, rb_ary_entry(array, i), point_type);
    if (entry_geom) {
      const GEOSCoordSequence* entry_cs = GEOSGeom_getCoordSeq_r(context, entry_geom);
      if (entry_cs) {
        double x;
        if (GEOSCoordSeq_getX_r(context, entry_cs, 0, &x)) {
          coords[i*dims] = x;
          if (GEOSCoordSeq_getY_r(context, entry_cs, 0, &x)) {
            coords[i*dims+1] = x;
            good = 1;
            if (has_z) {
              if (GEOSCoordSeq_getZ_r(context, entry_cs, 0, &x)) {
                coords[i*dims+2] = x;
              }
              else {
                good = 0;
              }
            }
          }
        }
      }
    }
    if (!good) {
      free(coords);
      return NULL;
    }
  }
  if (len > 0 && close) {
    if (coords[0] == coords[(len-1)*dims] && coords[1] == coords[(len-1)*dims+1]) {
      close = 0;
    }
  }
  else {
    close = 0;
  }
  GEOSCoordSequence* coord_seq = GEOSCoordSeq_create_r(context, len + close, 3);
  if (coord_seq) {
    for (i=0; i<len; ++i) {
      GEOSCoordSeq_setX_r(context, coord_seq, i, coords[i*dims]);
      GEOSCoordSeq_setY_r(context, coord_seq, i, coords[i*dims+1]);
      GEOSCoordSeq_setZ_r(context, coord_seq, i, has_z ? coords[i*dims+2] : 0);
    }
    if (close) {
      GEOSCoordSeq_setX_r(context, coord_seq, len, coords[0]);
      GEOSCoordSeq_setY_r(context, coord_seq, len, coords[1]);
      GEOSCoordSeq_setZ_r(context, coord_seq, len, has_z ? coords[2] : 0);
    }
  }
  free(coords);
  return coord_seq;
}
Exemplo n.º 18
0
Q_NOWARN_UNREACHABLE_POP

// Return Nth vertex in GEOSGeometry as a POINT.
// May return NULL if the geometry has NO vertexex.
static GEOSGeometry *LWGEOM_GEOS_getPointN( const GEOSGeometry *g_in, uint32_t n )
{
  GEOSContextHandle_t handle = QgsGeos::getGEOSHandler();

  uint32_t dims;
  const GEOSCoordSequence *seq_in = nullptr;
  GEOSCoordSeq seq_out;
  double val;
  uint32_t sz;
  int gn;
  GEOSGeometry *ret = nullptr;

  switch ( GEOSGeomTypeId_r( handle, g_in ) )
  {
    case GEOS_MULTIPOINT:
    case GEOS_MULTILINESTRING:
    case GEOS_MULTIPOLYGON:
    case GEOS_GEOMETRYCOLLECTION:
    {
      for ( gn = 0; gn < GEOSGetNumGeometries_r( handle, g_in ); ++gn )
      {
        const GEOSGeometry *g = GEOSGetGeometryN_r( handle, g_in, gn );
        ret = LWGEOM_GEOS_getPointN( g, n );
        if ( ret ) return ret;
      }
      break;
    }

    case GEOS_POLYGON:
    {
      ret = LWGEOM_GEOS_getPointN( GEOSGetExteriorRing_r( handle, g_in ), n );
      if ( ret ) return ret;
      for ( gn = 0; gn < GEOSGetNumInteriorRings_r( handle, g_in ); ++gn )
      {
        const GEOSGeometry *g = GEOSGetInteriorRingN_r( handle, g_in, gn );
        ret = LWGEOM_GEOS_getPointN( g, n );
        if ( ret ) return ret;
      }
      break;
    }

    case GEOS_POINT:
    case GEOS_LINESTRING:
    case GEOS_LINEARRING:
      break;

  }

  seq_in = GEOSGeom_getCoordSeq_r( handle, g_in );
  if ( ! seq_in ) return nullptr;
  if ( ! GEOSCoordSeq_getSize_r( handle, seq_in, &sz ) ) return nullptr;
  if ( ! sz ) return nullptr;

  if ( ! GEOSCoordSeq_getDimensions_r( handle, seq_in, &dims ) ) return nullptr;

  seq_out = GEOSCoordSeq_create_r( handle, 1, dims );
  if ( ! seq_out ) return nullptr;

  if ( ! GEOSCoordSeq_getX_r( handle, seq_in, n, &val ) ) return nullptr;
  if ( ! GEOSCoordSeq_setX_r( handle, seq_out, n, val ) ) return nullptr;
  if ( ! GEOSCoordSeq_getY_r( handle, seq_in, n, &val ) ) return nullptr;
  if ( ! GEOSCoordSeq_setY_r( handle, seq_out, n, val ) ) return nullptr;
  if ( dims > 2 )
  {
    if ( ! GEOSCoordSeq_getZ_r( handle, seq_in, n, &val ) ) return nullptr;
    if ( ! GEOSCoordSeq_setZ_r( handle, seq_out, n, val ) ) return nullptr;
  }

  return GEOSGeom_createPoint_r( handle, seq_out );
}