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

◆ LWGEOM2GEOS()

GEOSGeometry * LWGEOM2GEOS ( const LWGEOM lwgeom,
uint8_t  autofix 
)

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

401{
402 GEOSCoordSeq sq;
403 GEOSGeom g, shell;
404 GEOSGeom* geoms = NULL;
405 uint32_t ngeoms, i, j;
406 int is_empty = LW_FALSE;
407#if LWDEBUG_LEVEL >= 4
408 char* wkt;
409#endif
410
411 if (autofix)
412 {
413 /* cross fingers and try without autofix, maybe it'll work? */
414 g = LWGEOM2GEOS(lwgeom, LW_FALSE);
415 if (g) return g;
416 }
417
418 LWDEBUGF(4, "LWGEOM2GEOS got a %s", lwtype_name(lwgeom->type));
419
420 if (lwgeom_type_arc(lwgeom))
421 {
422 LWGEOM* lwgeom_stroked = lwgeom_stroke(lwgeom, 32);
423 GEOSGeometry* g = LWGEOM2GEOS(lwgeom_stroked, autofix);
424 lwgeom_free(lwgeom_stroked);
425 return g;
426 }
427
428 is_empty = lwgeom_is_empty(lwgeom);
429
430 switch (lwgeom->type)
431 {
432 case POINTTYPE:
433 {
434 if (is_empty)
435 g = GEOSGeom_createEmptyPoint();
436 else
437 {
438 LWPOINT* lwp = (LWPOINT*)lwgeom;
439 if (lwgeom_has_z(lwgeom))
440 {
441 sq = ptarray_to_GEOSCoordSeq(lwp->point, 0);
442 g = GEOSGeom_createPoint(sq);
443 }
444 else
445 {
446 const POINT2D* p = getPoint2d_cp(lwp->point, 0);
447 g = GEOSGeom_createPointFromXY(p->x, p->y);
448 }
449 }
450 if (!g) return NULL;
451 break;
452 }
453
454 case LINETYPE:
455 {
456 if (is_empty)
457 g = GEOSGeom_createEmptyLineString();
458 else
459 {
460 LWLINE* lwl = (LWLINE*)lwgeom;
461 /* TODO: if (autofix) */
462 if (lwl->points->npoints == 1)
463 {
464 /* Duplicate point, to make geos-friendly */
465 lwl->points = ptarray_addPoint(lwl->points,
466 getPoint_internal(lwl->points, 0),
467 FLAGS_NDIMS(lwl->points->flags),
468 lwl->points->npoints);
469 }
470 sq = ptarray_to_GEOSCoordSeq(lwl->points, 0);
471 g = GEOSGeom_createLineString(sq);
472 }
473 if (!g) return NULL;
474 break;
475 }
476
477 case POLYGONTYPE:
478 {
479 LWPOLY* lwpoly = (LWPOLY*)lwgeom;
480 if (is_empty)
481 g = GEOSGeom_createEmptyPolygon();
482 else
483 {
484 shell = ptarray_to_GEOSLinearRing(lwpoly->rings[0], autofix);
485 if (!shell) return NULL;
486 ngeoms = lwpoly->nrings - 1;
487 if (ngeoms > 0) geoms = lwalloc(sizeof(GEOSGeom) * ngeoms);
488
489 for (i = 1; i < lwpoly->nrings; i++)
490 {
491 geoms[i - 1] = ptarray_to_GEOSLinearRing(lwpoly->rings[i], autofix);
492 if (!geoms[i - 1])
493 {
494 uint32_t k;
495 for (k = 0; k < i - 1; k++)
496 GEOSGeom_destroy(geoms[k]);
497 lwfree(geoms);
498 GEOSGeom_destroy(shell);
499 return NULL;
500 }
501 }
502 g = GEOSGeom_createPolygon(shell, geoms, ngeoms);
503 if (geoms) lwfree(geoms);
504 }
505 if (!g) return NULL;
506 break;
507 }
508
509 case TRIANGLETYPE:
510 {
511 if (is_empty)
512 g = GEOSGeom_createEmptyPolygon();
513 else
514 {
515 LWTRIANGLE *lwt = (LWTRIANGLE *)lwgeom;
516 shell = ptarray_to_GEOSLinearRing(lwt->points, autofix);
517 if (!shell) return NULL;
518 g = GEOSGeom_createPolygon(shell, NULL, 0);
519 }
520 if (!g) return NULL;
521 break;
522 }
523 case MULTIPOINTTYPE:
524 case MULTILINETYPE:
525 case MULTIPOLYGONTYPE:
526 case TINTYPE:
527 case COLLECTIONTYPE:
528 {
529 int geostype;
530 if (lwgeom->type == MULTIPOINTTYPE)
531 geostype = GEOS_MULTIPOINT;
532 else if (lwgeom->type == MULTILINETYPE)
533 geostype = GEOS_MULTILINESTRING;
534 else if (lwgeom->type == MULTIPOLYGONTYPE)
535 geostype = GEOS_MULTIPOLYGON;
536 else
537 geostype = GEOS_GEOMETRYCOLLECTION;
538
539 LWCOLLECTION* lwc = (LWCOLLECTION*)lwgeom;
540
541 ngeoms = lwc->ngeoms;
542 if (ngeoms > 0) geoms = lwalloc(sizeof(GEOSGeom) * ngeoms);
543
544 j = 0;
545 for (i = 0; i < ngeoms; ++i)
546 {
547 GEOSGeometry* g;
548
549 /* if (lwgeom_is_empty(lwc->geoms[i])) continue; */
550
551 g = LWGEOM2GEOS(lwc->geoms[i], 0);
552 if (!g)
553 {
554 uint32_t k;
555 for (k = 0; k < j; k++)
556 GEOSGeom_destroy(geoms[k]);
557 lwfree(geoms);
558 return NULL;
559 }
560 geoms[j++] = g;
561 }
562 g = GEOSGeom_createCollection(geostype, geoms, j);
563 if (ngeoms > 0) lwfree(geoms);
564 if (!g) return NULL;
565 break;
566 }
567
568 default:
569 {
570 lwerror("Unknown geometry type: %d - %s", lwgeom->type, lwtype_name(lwgeom->type));
571 return NULL;
572 }
573 }
574
575 GEOSSetSRID(g, lwgeom->srid);
576
577#if LWDEBUG_LEVEL >= 4
578 wkt = GEOSGeomToWKT(g);
579 LWDEBUGF(4, "LWGEOM2GEOS: GEOSGeom: %s", wkt);
580 GEOSFree(wkt);
581#endif
582
583 return g;
584}
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:94
#define COLLECTIONTYPE
Definition liblwgeom.h:108
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1246
#define MULTILINETYPE
Definition liblwgeom.h:106
#define LINETYPE
Definition liblwgeom.h:103
#define MULTIPOINTTYPE
Definition liblwgeom.h:105
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition lwgeom.c:962
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:102
void * lwalloc(size_t size)
Definition lwutil.c:227
int lwgeom_type_arc(const LWGEOM *geom)
Geometry type is one of the potentially "arc containing" types (circstring, multicurve,...
Definition lwstroke.c:89
#define TINTYPE
Definition liblwgeom.h:116
#define MULTIPOLYGONTYPE
Definition liblwgeom.h:107
void lwfree(void *mem)
Definition lwutil.c:248
#define FLAGS_NDIMS(flags)
Definition liblwgeom.h:179
#define POLYGONTYPE
Definition liblwgeom.h:104
POINTARRAY * ptarray_addPoint(const POINTARRAY *pa, uint8_t *p, size_t pdims, uint32_t where)
Add a point in a pointarray.
Definition ptarray.c:530
#define TRIANGLETYPE
Definition liblwgeom.h:115
LWGEOM * lwgeom_stroke(const LWGEOM *geom, uint32_t perQuad)
Convert type with arcs into equivalent linearized type.
Definition lwstroke.c:871
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:106
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition lwinline.h:75
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:199
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:97
uint32_t ngeoms
Definition liblwgeom.h:580
LWGEOM ** geoms
Definition liblwgeom.h:575
uint8_t type
Definition liblwgeom.h:462
int32_t srid
Definition liblwgeom.h:460
POINTARRAY * points
Definition liblwgeom.h:483
POINTARRAY * point
Definition liblwgeom.h:471
POINTARRAY ** rings
Definition liblwgeom.h:519
uint32_t nrings
Definition liblwgeom.h:524
POINTARRAY * points
Definition liblwgeom.h:495
double y
Definition liblwgeom.h:390
double x
Definition liblwgeom.h:390
lwflags_t flags
Definition liblwgeom.h:431
uint32_t npoints
Definition liblwgeom.h:427

References COLLECTIONTYPE, POINTARRAY::flags, FLAGS_NDIMS, LWCOLLECTION::geoms, getPoint2d_cp(), getPoint_internal(), LINETYPE, LW_FALSE, lwalloc(), LWDEBUGF, lwerror(), lwfree(), LWGEOM2GEOS(), lwgeom_free(), lwgeom_has_z(), lwgeom_is_empty(), lwgeom_stroke(), lwgeom_type_arc(), 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_AddLine(), _lwt_CheckEdgeCrossing(), _lwt_FindFaceContainingRing(), _lwt_GetEqualEdge(), _lwt_SnapEdge_checkMotion(), isvalid(), LWGEOM2GEOS(), lwgeom_buildarea(), lwgeom_centroid(), lwgeom_clip_by_rect(), lwgeom_concavehull(), lwgeom_delaunay_triangulation(), LWGEOM_dfullywithin(), lwgeom_difference_prec(), lwgeom_extract_unique_endpoints(), lwgeom_geos_noop(), lwgeom_intersection_prec(), lwgeom_is_simple(), lwgeom_linemerge_directed(), lwgeom_make_valid_params(), lwgeom_node(), lwgeom_normalize(), lwgeom_pointonsurface(), lwgeom_reduceprecision(), lwgeom_sharedpaths(), lwgeom_simplify_polygonal(), lwgeom_snap(), lwgeom_symdifference_prec(), lwgeom_triangulate_polygon(), lwgeom_unaryunion_prec(), lwgeom_union_prec(), LWGEOMARRAY2GEOS(), lwline_offsetcurve(), lwline_split_by_line(), lwpoly_split_by_line(), lwpoly_to_points(), lwt_AddPolygon(), POSTGIS2GEOS(), PrepGeomCacheBuilder(), read_geos_from_partition(), rt_raster_compute_skewed_raster(), 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: