Esempio n. 1
0
static VALUE method_line_string_length(VALUE self)
{
  VALUE result = Qnil;
  RGeo_GeometryData* self_data = RGEO_GEOMETRY_DATA_PTR(self);
  const GEOSGeometry* self_geom = self_data->geom;
  if (self_geom) {
    double len;
    if (GEOSLength_r(self_data->geos_context, self_geom, &len)) {
      result = rb_float_new(len);
    }
  }
  return result;
}
Esempio n. 2
0
bool Layer::registerFeature( const QString& geom_id, PalGeometry *userGeom, double label_x, double label_y, const QString &labelText,
                             double labelPosX, double labelPosY, bool fixedPos, double angle, bool fixedAngle,
                             int xQuadOffset, int yQuadOffset, double xOffset, double yOffset, bool alwaysShow, double repeatDistance )
{
    if ( geom_id.isEmpty() || label_x < 0 || label_y < 0 )
        return false;

    mMutex.lock();

    if ( hashtable->contains( geom_id ) )
    {
        mMutex.unlock();
        //A feature with this id already exists. Don't throw an exception as sometimes,
        //the same feature is added twice (dateline split with otf-reprojection)
        return false;
    }

    // Split MULTI GEOM and Collection in simple geometries
    const GEOSGeometry *the_geom = userGeom->getGeosGeometry();

    Feature* f = new Feature( this, geom_id, userGeom, label_x, label_y );
    if ( fixedPos )
    {
        f->setFixedPosition( labelPosX, labelPosY );
    }
    if ( xQuadOffset != 0 || yQuadOffset != 0 )
    {
        f->setQuadOffset( xQuadOffset, yQuadOffset );
    }
    if ( xOffset != 0.0 || yOffset != 0.0 )
    {
        f->setPosOffset( xOffset, yOffset );
    }
    if ( fixedAngle )
    {
        f->setFixedAngle( angle );
    }
    // use layer-level defined rotation, but not if position fixed
    if ( !fixedPos && angle != 0.0 )
    {
        f->setFixedAngle( angle );
    }
    f->setRepeatDistance( repeatDistance );

    f->setAlwaysShow( alwaysShow );

    bool first_feat = true;

    double geom_size = -1, biggest_size = -1;
    FeaturePart* biggest_part = NULL;

    // break the (possibly multi-part) geometry into simple geometries
    QLinkedList<const GEOSGeometry*>* simpleGeometries = unmulti( the_geom );
    if ( simpleGeometries == NULL ) // unmulti() failed?
    {
        mMutex.unlock();
        throw InternalException::UnknownGeometry();
    }

    GEOSContextHandle_t geosctxt = geosContext();

    while ( simpleGeometries->size() > 0 )
    {
        const GEOSGeometry* geom = simpleGeometries->takeFirst();

        // ignore invalid geometries (e.g. polygons with self-intersecting rings)
        if ( GEOSisValid_r( geosctxt, geom ) != 1 ) // 0=invalid, 1=valid, 2=exception
        {
//        std::cerr << "ignoring invalid feature " << geom_id << std::endl;
            continue;
        }

        int type = GEOSGeomTypeId_r( geosctxt, geom );

        if ( type != GEOS_POINT && type != GEOS_LINESTRING && type != GEOS_POLYGON )
        {
            mMutex.unlock();
            throw InternalException::UnknownGeometry();
        }

        FeaturePart* fpart = new FeaturePart( f, geom );

        // ignore invalid geometries
        if (( type == GEOS_LINESTRING && fpart->nbPoints < 2 ) ||
                ( type == GEOS_POLYGON && fpart->nbPoints < 3 ) )
        {
            delete fpart;
            continue;
        }

        // polygons: reorder coordinates
        if ( type == GEOS_POLYGON && reorderPolygon( fpart->nbPoints, fpart->x, fpart->y ) != 0 )
        {
            delete fpart;
            continue;
        }

        if ( mMode == LabelPerFeature && ( type == GEOS_POLYGON || type == GEOS_LINESTRING ) )
        {
            if ( type == GEOS_LINESTRING )
                GEOSLength_r( geosctxt, geom, &geom_size );
            else if ( type == GEOS_POLYGON )
                GEOSArea_r( geosctxt, geom, &geom_size );

            if ( geom_size > biggest_size )
            {
                biggest_size = geom_size;
                delete biggest_part; // safe with NULL part
                biggest_part = fpart;
            }
            continue; // don't add the feature part now, do it later
            // TODO: we should probably add also other parts to act just as obstacles
        }

        // feature part is ready!
        addFeaturePart( fpart, labelText );

        first_feat = false;
    }
    delete simpleGeometries;

    userGeom->releaseGeosGeometry( the_geom );

    mMutex.unlock();

    // if using only biggest parts...
    if (( mMode == LabelPerFeature || f->fixedPosition() ) && biggest_part != NULL )
    {
        addFeaturePart( biggest_part, labelText );
        first_feat = false;
    }

    // add feature to layer if we have added something
    if ( !first_feat )
    {
        features->append( f );
        hashtable->insert( geom_id, f );
    }
    else
    {
        delete f;
    }

    return !first_feat; // true if we've added something
}