示例#1
0
Datum ST_MakeValid(PG_FUNCTION_ARGS)
{
#if POSTGIS_GEOS_VERSION < 33
	elog(ERROR, "You need GEOS-3.3.0 or up for ST_MakeValid");
	PG_RETURN_NULL();
#else /* POSTGIS_GEOS_VERSION >= 33 */

	GSERIALIZED *in, *out;
	LWGEOM *lwgeom_in, *lwgeom_out;

	in = PG_GETARG_GSERIALIZED_P(0);
	lwgeom_in = lwgeom_from_gserialized(in);

	switch ( lwgeom_in->type )
	{
	case POINTTYPE:
	case MULTIPOINTTYPE:
	case LINETYPE:
	case POLYGONTYPE:
	case MULTILINETYPE:
	case MULTIPOLYGONTYPE:
	case COLLECTIONTYPE:
		break;

	default:
		lwerror("ST_MakeValid: unsupported geometry type %s",
		        lwtype_name(lwgeom_in->type));
		PG_RETURN_NULL();
		break;
	}

	lwgeom_out = lwgeom_make_valid(lwgeom_in);
	if ( ! lwgeom_out )
	{
		PG_FREE_IF_COPY(in, 0);
		PG_RETURN_NULL();
	}

	out = geometry_serialize(lwgeom_out);

	PG_RETURN_POINTER(out);
#endif /* POSTGIS_GEOS_VERSION >= 33 */
}
示例#2
0
// trying to make polygon to be valid
// accept only string-polygon in wkb format
static VALUE make_valid(VALUE self, VALUE geom_wkb)
{
  VALUE result;
  LWGEOM *valid_lwg;
  
  int wkb_size_a;
  wkb_size_a = RSTRING_LEN(geom_wkb);
  
  lwg = lwgeom_from_wkb(RSTRING_PTR(geom_wkb), wkb_size_a, 0);
  
  valid_lwg = lwgeom_make_valid(lwg);
  //make multi
  valid_lwg = lwgeom_as_multi(valid_lwg);

  char *wkb_str = (char*)lwgeom_to_wkb(valid_lwg, WKB_HEX, NULL);
  

  return rb_str_new2(wkb_str);
}
示例#3
0
static LWGEOM*
lwgeom_clean(LWGEOM* lwgeom_in)
{
	LWGEOM* lwgeom_out;

	lwgeom_out = lwgeom_make_valid(lwgeom_in);
	if ( ! lwgeom_out )
	{
		return NULL;
	}

	/* Check dimensionality is the same as input */
	if ( lwgeom_dimensionality(lwgeom_in) != lwgeom_dimensionality(lwgeom_out) )
	{
		lwnotice("lwgeom_clean: dimensional collapse (%d to %d)",
		         lwgeom_dimensionality(lwgeom_in), lwgeom_dimensionality(lwgeom_out));

		return NULL;
	}

	/* Check that the output is not a collection if the input wasn't */
	if ( lwgeom_out->type == COLLECTIONTYPE &&
	        lwgeom_in->type != COLLECTIONTYPE )
	{
		lwnotice("lwgeom_clean: mixed-type output (%s) "
		         "from single-type input (%s)",
		         lwtype_name(lwgeom_out->type),
		         lwtype_name(lwgeom_in->type));
		return NULL;
	}

	/* Force right-hand-rule (will only affect polygons) */
	/* gout := ST_ForceRHR(gout); */

	/* Remove repeated duplicated points ? */
	/* gout = ST_RemoveRepeatedPoints(gout); */

	return lwgeom_out;
}
示例#4
0
static void test_lwgeom_make_valid(void)
{
#if POSTGIS_GEOS_VERSION >= 33
	LWGEOM *gin, *gout, *gexp;
	char *ewkt;

	/* Because i don't trust that much prior tests...  ;) */
	cu_error_msg_reset();

	gin = lwgeom_from_wkt(
"MULTIPOLYGON(((1725063 4819121, 1725104 4819067, 1725060 4819087, 1725064.14183882 4819094.70208557,1725064.13656044 4819094.70235069,1725064.14210359 4819094.70227252,1725064.14210362 4819094.70227252,1725064.13656043 4819094.70235069,1725055. 4819094, 1725055 4819094, 1725055 4819094, 1725063 4819121)))",
		LW_PARSER_CHECK_NONE);
	CU_ASSERT(gin != NULL);

	gout = lwgeom_make_valid(gin);

	/* We're really only interested in avoiding a crash in here.
	 * See http://trac.osgeo.org/postgis/ticket/1738
	 * TODO: enhance the test if we find a workaround 
	 *       to the excepion:
	 * See http://trac.osgeo.org/postgis/ticket/1735
	 */

	lwgeom_free(gout);
	lwgeom_free(gin);

  /* Test for http://trac.osgeo.org/postgis/ticket/2307 */

  gin = lwgeom_from_hexwkb("0106000020E6100000010000000103000000010000000A0000004B7DA956B99844C0DB0790FE8B4D1DC010BA74A9AF9444C049AFFC5B8C4D1DC03FC6CC690D9844C0DD67E5628C4D1DC07117B56B0D9844C0C80ABA67C45E1DC0839166ABAF9444C0387D4568C45E1DC010BA74A9AF9444C049AFFC5B8C4D1DC040C3CD74169444C0362EC0608C4D1DC07C1A3B77169444C0DC3ADB40B2641DC03AAE5F68B99844C0242948DEB1641DC04B7DA956B99844C0DB0790FE8B4D1DC0", LW_PARSER_CHECK_NONE);
	CU_ASSERT(gin != NULL);

	gout = lwgeom_make_valid(gin);
	CU_ASSERT(gout != NULL);
	lwgeom_free(gin);

	/* We're really only interested in avoiding memory problems.
   * Convertion to ewkt ensures full scan of coordinates thus
   * triggering the error, if any
   */
	ewkt = lwgeom_to_ewkt(gout);
	lwgeom_free(gout);
	lwfree(ewkt);


	/* Test collection */

	gin = lwgeom_from_wkt(
"GEOMETRYCOLLECTION(LINESTRING(0 0, 0 0), POLYGON((0 0, 10 10, 10 0, 0 10, 0 0)), LINESTRING(10 0, 10 10))",
		LW_PARSER_CHECK_NONE);
	CU_ASSERT(gin != NULL);

	gout = lwgeom_make_valid(gin);
	CU_ASSERT(gout != NULL);

	ewkt = lwgeom_to_ewkt(gout);
	/* printf("c = %s\n", ewkt); */
	/*
	 TODO: This doesn't work on windows returns in different order. 
	 strk figure out why. For now will replace with normalized version
	*/
/*	CU_ASSERT_STRING_EQUAL(ewkt,
"GEOMETRYCOLLECTION(POINT(0 0),MULTIPOLYGON(((5 5,0 0,0 10,5 5)),((5 5,10 10,10 0,5 5))),LINESTRING(10 0,10 10))");*/
	gexp = lwgeom_from_wkt(
"GEOMETRYCOLLECTION(POINT(0 0),MULTIPOLYGON(((5 5,0 0,0 10,5 5)),((5 5,10 10,10 0,5 5))),LINESTRING(10 0,10 10))",
		LW_PARSER_CHECK_NONE);
	check_geom_equal(gout, gexp);
	lwfree(ewkt);

	lwgeom_free(gout);
	lwgeom_free(gin);
	lwgeom_free(gexp);

	/* Test multipoint */

	gin = lwgeom_from_wkt(
"MULTIPOINT(0 0,1 1,2 2)",
		LW_PARSER_CHECK_NONE);
	CU_ASSERT(gin != NULL);

	gout = lwgeom_make_valid(gin);
	CU_ASSERT(gout != NULL);

	ewkt = lwgeom_to_ewkt(gout);
	/* printf("c = %s\n", ewkt); */
	CU_ASSERT_STRING_EQUAL(ewkt,
"MULTIPOINT(0 0,1 1,2 2)");
	lwfree(ewkt);

	lwgeom_free(gout);
	lwgeom_free(gin);

#endif /* POSTGIS_GEOS_VERSION >= 33 */
}