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 }
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); }
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(); } }
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 }