PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ LWGEOM2GEOS()

GEOSGeometry * LWGEOM2GEOS ( const LWGEOM lwgeom,
uint8_t  autofix 
)

Definition at line 390 of file liblwgeom/lwgeom_geos.c.

391{
392 GEOSCoordSeq sq;
393 GEOSGeom g, shell;
394 GEOSGeom* geoms = NULL;
395 uint32_t ngeoms, i, j;
396 int geostype;
397#if LWDEBUG_LEVEL >= 4
398 char* wkt;
399#endif
400
401 if (autofix)
402 {
403 /* cross fingers and try without autofix, maybe it'll work? */
404 g = LWGEOM2GEOS(lwgeom, LW_FALSE);
405 if (g) return g;
406 }
407
408 LWDEBUGF(4, "LWGEOM2GEOS got a %s", lwtype_name(lwgeom->type));
409
410 if (lwgeom_has_arc(lwgeom))
411 {
412 LWGEOM* lwgeom_stroked = lwgeom_stroke(lwgeom, 32);
413 GEOSGeometry* g = LWGEOM2GEOS(lwgeom_stroked, autofix);
414 lwgeom_free(lwgeom_stroked);
415 return g;
416 }
417
418 LWPOINT* lwp = NULL;
419 LWPOLY* lwpoly = NULL;
420 LWLINE* lwl = NULL;
421 LWCOLLECTION* lwc = NULL;
422
423 switch (lwgeom->type)
424 {
425 case POINTTYPE:
426 lwp = (LWPOINT*)lwgeom;
427
428 if (lwgeom_is_empty(lwgeom))
429 g = GEOSGeom_createEmptyPolygon();
430 else
431 {
432#if POSTGIS_GEOS_VERSION < 38
433 sq = ptarray_to_GEOSCoordSeq(lwp->point, 0);
434 g = GEOSGeom_createPoint(sq);
435#else
436 if (lwgeom_has_z(lwgeom))
437 {
438 sq = ptarray_to_GEOSCoordSeq(lwp->point, 0);
439 g = GEOSGeom_createPoint(sq);
440 }
441 else
442 {
443 const POINT2D* p = getPoint2d_cp(lwp->point, 0);
444 g = GEOSGeom_createPointFromXY(p->x, p->y);
445 }
446#endif
447 }
448 if (!g) return NULL;
449 break;
450
451 case LINETYPE:
452 lwl = (LWLINE*)lwgeom;
453 /* TODO: if (autofix) */
454 if (lwl->points->npoints == 1)
455 {
456 /* Duplicate point, to make geos-friendly */
457 lwl->points = ptarray_addPoint(lwl->points,
458 getPoint_internal(lwl->points, 0),
459 FLAGS_NDIMS(lwl->points->flags),
460 lwl->points->npoints);
461 }
462 sq = ptarray_to_GEOSCoordSeq(lwl->points, 0);
463 g = GEOSGeom_createLineString(sq);
464 if (!g) return NULL;
465 break;
466
467 case POLYGONTYPE:
468 lwpoly = (LWPOLY*)lwgeom;
469 if (lwgeom_is_empty(lwgeom))
470 g = GEOSGeom_createEmptyPolygon();
471 else
472 {
473 shell = ptarray_to_GEOSLinearRing(lwpoly->rings[0], autofix);
474 if (!shell) return NULL;
475 ngeoms = lwpoly->nrings - 1;
476 if (ngeoms > 0) geoms = lwalloc(sizeof(GEOSGeom) * ngeoms);
477
478 for (i = 1; i < lwpoly->nrings; i++)
479 {
480 geoms[i - 1] = ptarray_to_GEOSLinearRing(lwpoly->rings[i], autofix);
481 if (!geoms[i - 1])
482 {
483 uint32_t k;
484 for (k = 0; k < i - 1; k++)
485 GEOSGeom_destroy(geoms[k]);
486 lwfree(geoms);
487 GEOSGeom_destroy(shell);
488 return NULL;
489 }
490 }
491 g = GEOSGeom_createPolygon(shell, geoms, ngeoms);
492 if (geoms) lwfree(geoms);
493 }
494 if (!g) return NULL;
495 break;
496
497 case TRIANGLETYPE:
498 if (lwgeom_is_empty(lwgeom))
499 g = GEOSGeom_createEmptyPolygon();
500 else
501 {
502 LWTRIANGLE *lwt = (LWTRIANGLE *)lwgeom;
503 shell = ptarray_to_GEOSLinearRing(lwt->points, autofix);
504 if (!shell)
505 return NULL;
506 g = GEOSGeom_createPolygon(shell, NULL, 0);
507 }
508 if (!g)
509 return NULL;
510 break;
511 case MULTIPOINTTYPE:
512 case MULTILINETYPE:
513 case MULTIPOLYGONTYPE:
514 case TINTYPE:
515 case COLLECTIONTYPE:
516 if (lwgeom->type == MULTIPOINTTYPE)
517 geostype = GEOS_MULTIPOINT;
518 else if (lwgeom->type == MULTILINETYPE)
519 geostype = GEOS_MULTILINESTRING;
520 else if (lwgeom->type == MULTIPOLYGONTYPE)
521 geostype = GEOS_MULTIPOLYGON;
522 else
523 geostype = GEOS_GEOMETRYCOLLECTION;
524
525 lwc = (LWCOLLECTION*)lwgeom;
526
527 ngeoms = lwc->ngeoms;
528 if (ngeoms > 0) geoms = lwalloc(sizeof(GEOSGeom) * ngeoms);
529
530 j = 0;
531 for (i = 0; i < ngeoms; ++i)
532 {
533 GEOSGeometry* g;
534
535 if (lwgeom_is_empty(lwc->geoms[i])) continue;
536
537 g = LWGEOM2GEOS(lwc->geoms[i], 0);
538 if (!g)
539 {
540 uint32_t k;
541 for (k = 0; k < j; k++)
542 GEOSGeom_destroy(geoms[k]);
543 lwfree(geoms);
544 return NULL;
545 }
546 geoms[j++] = g;
547 }
548 g = GEOSGeom_createCollection(geostype, geoms, j);
549 if (ngeoms > 0) lwfree(geoms);
550 if (!g) return NULL;
551 break;
552
553 default:
554 lwerror("Unknown geometry type: %d - %s", lwgeom->type, lwtype_name(lwgeom->type));
555 return NULL;
556 }
557
558 GEOSSetSRID(g, lwgeom->srid);
559
560#if LWDEBUG_LEVEL >= 4
561 wkt = GEOSGeomToWKT(g);
562 LWDEBUGF(4, "LWGEOM2GEOS: GEOSGeom: %s", wkt);
563 free(wkt);
564#endif
565
566 return g;
567}
static GEOSGeometry * ptarray_to_GEOSLinearRing(const POINTARRAY *pa, uint8_t autofix)
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
GEOSCoordSeq ptarray_to_GEOSCoordSeq(const POINTARRAY *, uint8_t fix_ring)
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition lwutil.c:216
#define LW_FALSE
Definition liblwgeom.h:108
#define COLLECTIONTYPE
Definition liblwgeom.h:122
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1138
#define MULTILINETYPE
Definition liblwgeom.h:120
#define LINETYPE
Definition liblwgeom.h:117
#define MULTIPOINTTYPE
Definition liblwgeom.h:119
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition lwgeom.c:916
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:116
void * lwalloc(size_t size)
Definition lwutil.c:227
#define TINTYPE
Definition liblwgeom.h:130
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:121
void lwfree(void *mem)
Definition lwutil.c:242
#define FLAGS_NDIMS(flags)
Definition liblwgeom.h:193
#define POLYGONTYPE
Definition liblwgeom.h:118
POINTARRAY * ptarray_addPoint(const POINTARRAY *pa, uint8_t *p, size_t pdims, uint32_t where)
Add a point in a pointarray.
Definition ptarray.c:509
#define TRIANGLETYPE
Definition liblwgeom.h:129
LWGEOM * lwgeom_stroke(const LWGEOM *geom, uint32_t perQuad)
Definition lwstroke.c:859
int lwgeom_has_arc(const LWGEOM *geom)
Definition lwstroke.c:55
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition lwutil.c:190
void free(void *)
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition lwinline.h:67
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition lwinline.h:193
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition lwinline.h:91
uint32_t ngeoms
Definition liblwgeom.h:566
LWGEOM ** geoms
Definition liblwgeom.h:561
uint8_t type
Definition liblwgeom.h:448
int32_t srid
Definition liblwgeom.h:446
POINTARRAY * points
Definition liblwgeom.h:469
POINTARRAY * point
Definition liblwgeom.h:457
POINTARRAY ** rings
Definition liblwgeom.h:505
uint32_t nrings
Definition liblwgeom.h:510
POINTARRAY * points
Definition liblwgeom.h:481
double y
Definition liblwgeom.h:376
double x
Definition liblwgeom.h:376
lwflags_t flags
Definition liblwgeom.h:417
uint32_t npoints
Definition liblwgeom.h:413

References COLLECTIONTYPE, POINTARRAY::flags, FLAGS_NDIMS, free(), LWCOLLECTION::geoms, getPoint2d_cp(), getPoint_internal(), LINETYPE, LW_FALSE, lwalloc(), LWDEBUGF, lwerror(), lwfree(), LWGEOM2GEOS(), lwgeom_free(), lwgeom_has_arc(), lwgeom_has_z(), lwgeom_is_empty(), lwgeom_stroke(), lwtype_name(), MULTILINETYPE, MULTIPOINTTYPE, MULTIPOLYGONTYPE, LWCOLLECTION::ngeoms, POINTARRAY::npoints, LWPOLY::nrings, LWPOINT::point, LWLINE::points, LWTRIANGLE::points, POINTTYPE, POLYGONTYPE, ptarray_addPoint(), ptarray_to_GEOSCoordSeq(), ptarray_to_GEOSLinearRing(), LWPOLY::rings, LWGEOM::srid, TINTYPE, TRIANGLETYPE, LWGEOM::type, POINT2D::x, and POINT2D::y.

Referenced by _lwt_CheckEdgeCrossing(), _lwt_FindFaceContainingRing(), _lwt_GetEqualEdge(), boundary(), isvalid(), LWGEOM2GEOS(), lwgeom_buildarea(), lwgeom_centroid(), lwgeom_clip_by_rect(), lwgeom_delaunay_triangulation(), lwgeom_difference(), lwgeom_extract_unique_endpoints(), lwgeom_geos_noop(), lwgeom_intersection(), lwgeom_is_simple(), lwgeom_linemerge(), lwgeom_make_valid(), lwgeom_node(), lwgeom_normalize(), lwgeom_pointonsurface(), lwgeom_sharedpaths(), lwgeom_snap(), lwgeom_symdifference(), lwgeom_unaryunion(), lwgeom_union(), LWGEOMARRAY2GEOS(), lwline_offsetcurve(), lwline_split_by_line(), lwpoly_split_by_line(), lwpoly_to_points(), lwt_AddPolygon(), mvt_grid_and_validate_geos(), mvt_safe_clip_polygon_by_box(), pgis_geometry_union_finalfn(), POSTGIS2GEOS(), PrepGeomCacheBuilder(), rt_raster_compute_skewed_raster(), rt_raster_gdal_polygonize(), rt_raster_geos_spatial_relationship(), rt_raster_intersects(), rt_raster_surface(), and topologypreservesimplify().

Here is the call graph for this function:
Here is the caller graph for this function: