示例#1
0
double msGEOSLength(shapeObj *shape)
{
#if defined(USE_GEOS) && defined(GEOS_CAPI_VERSION_MAJOR) && defined(GEOS_CAPI_VERSION_MINOR) && (GEOS_CAPI_VERSION_MAJOR > 1 || GEOS_CAPI_VERSION_MINOR >= 1)

  GEOSGeom g;
  double length;
  int result;

  if(!shape) return -1;

  if(!shape->geometry) /* if no geometry for the shape then build one */
    shape->geometry = (GEOSGeom) msGEOSShape2Geometry(shape);
  g = (GEOSGeom) shape->geometry;
  if(!g) return -1;

  result = GEOSLength(g, &length);
  return  ((result==0) ? -1 : length);
#elif defined(USE_GEOS)
  msSetError(MS_GEOSERR, "GEOS support enabled, but old version lacks GEOSLength().", "msGEOSLength()");
  return -1;
#else
  msSetError(MS_GEOSERR, "GEOS support is not available.", "msGEOSLength()");
  return -1;
#endif
}
示例#2
0
Handle<Value> Geometry::GetLength(Local<String> name, const AccessorInfo& info)
{
    HandleScope scope;
    Geometry *geom = ObjectWrap::Unwrap<Geometry>(info.Holder());
    double length;
    int r = GEOSLength(geom->geos_geom_, &length);
    if (r != 1)
        return ThrowException(String::New("couldn't get length"));
    Handle<Value> length_obj = Number::New(length);
    return scope.Close(length_obj);
}
示例#3
0
void geo_length(sqlite3_context *context,int argc,sqlite3_value **argv)
{
	if(argc == 1 && sqlite3_value_type(argv[0]) == SQLITE_BLOB)
	{ 
		GEOSGeometry* geometry;
		const void* data = sqlite3_value_blob(argv[0]);
		size_t data_size = sqlite3_value_bytes(argv[0]);

		_init_geos();
		geometry = _geo_from_wkb((const unsigned char*)data,data_size);
		if(geometry != 0)
		{
			double length = 0;
			GEOSLength(geometry,&length);
			sqlite3_result_double(context,length);
		}
		GEOSGeom_destroy(geometry);
		finishGEOS();
	}
}
示例#4
0
  bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText,
                               double labelPosX, double labelPosY, bool fixedPos, double angle, bool fixedAngle,
                               int xQuadOffset, int yQuadOffset, double xOffset, double yOffset )
  {
    if ( !geom_id || label_x < 0 || label_y < 0 )
      return false;

    modMutex->lock();

    if ( hashtable->find( geom_id ) )
    {
      modMutex->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
    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 );
    }

    bool first_feat = true;

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

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

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

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

      int type = GEOSGeomTypeId( geom );

      if ( type != GEOS_POINT && type != GEOS_LINESTRING && type != GEOS_POLYGON )
      {
        modMutex->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 ( mode == LabelPerFeature && ( type == GEOS_POLYGON || type == GEOS_LINESTRING ) )
      {
        if ( type == GEOS_LINESTRING )
          GEOSLength( geom, &geom_size );
        else if ( type == GEOS_POLYGON )
          GEOSArea( 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 );

    modMutex->unlock();

    // if using only biggest parts...
    if (( mode == 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->push_back( f );
      hashtable->insertItem( geom_id, f );
    }
    else
    {
      delete f;
    }

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