Exemple #1
0
void printLWCIRCSTRING(LWCIRCSTRING *curve)
{
	lwnotice("LWCIRCSTRING {");
	lwnotice("    ndims = %i", (int)FLAGS_NDIMS(curve->flags));
	lwnotice("    srid = %i", (int)curve->srid);
	printPA(curve->points);
	lwnotice("}");
}
Exemple #2
0
void printLWCIRCSTRING(LWCIRCSTRING *curve)
{
	lwnotice("LWCIRCSTRING {");
	lwnotice("    ndims = %i", (int)TYPE_NDIMS(curve->type));
	lwnotice("    SRID = %i", (int)curve->SRID);
	printPA(curve->points);
	lwnotice("}");
}
Exemple #3
0
void printLWLINE(LWLINE *line)
{
	lwnotice("LWLINE {");
	lwnotice("    ndims = %i", (int)TYPE_NDIMS(line->type));
	lwnotice("    SRID = %i", (int)line->SRID);
	printPA(line->points);
	lwnotice("}");
}
Exemple #4
0
void printLWPOINT(LWPOINT *point)
{
	lwnotice("LWPOINT {");
	lwnotice("    ndims = %i", (int)TYPE_NDIMS(point->type));
	lwnotice("    BBOX = %i", TYPE_HASBBOX(point->type) ? 1 : 0 );
	lwnotice("    SRID = %i", (int)point->SRID);
	printPA(point->point);
	lwnotice("}");
}
Exemple #5
0
void printLWPOINT(LWPOINT *point)
{
	lwnotice("LWPOINT {");
	lwnotice("    ndims = %i", (int)FLAGS_NDIMS(point->flags));
	lwnotice("    BBOX = %i", FLAGS_GET_BBOX(point->flags) ? 1 : 0 );
	lwnotice("    SRID = %i", (int)point->srid);
	printPA(point->point);
	lwnotice("}");
}
Exemple #6
0
void printLWTRIANGLE(LWTRIANGLE *triangle)
{
	if (triangle->type != TRIANGLETYPE)
                lwerror("printLWTRIANGLE called with something else than a Triangle");

	lwnotice("LWTRIANGLE {");
	lwnotice("    ndims = %i", (int)FLAGS_NDIMS(triangle->flags));
	lwnotice("    SRID = %i", (int)triangle->srid);
	printPA(triangle->points);
	lwnotice("}");
}
Exemple #7
0
/*
 * Construct a new LWCIRCSTRING.  points will *NOT* be copied
 * use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
 */
LWCIRCSTRING *
lwcircstring_construct(int srid, GBOX *bbox, POINTARRAY *points)
{
	LWCIRCSTRING *result;

	/*
	        * The first arc requires three points.  Each additional
	        * arc requires two more points.  Thus the minimum point count
	        * is three, and the count must be odd.
	        */
	if (points->npoints % 2 != 1 || points->npoints < 3)
	{
		lwnotice("lwcircstring_construct: invalid point count %d", points->npoints);
	}

	result = (LWCIRCSTRING*) lwalloc(sizeof(LWCIRCSTRING));

	result->type = CIRCSTRINGTYPE;
	
	result->flags = points->flags;
	FLAGS_SET_BBOX(result->flags, bbox?1:0);

	result->srid = srid;
	result->points = points;
	result->bbox = bbox;

	return result;
}
/* Print grid using given reporter */
static void
grid_print(const gridspec *grid)
{
	lwnotice("GRID(%g %g %g %g, %g %g %g %g)",
	         grid->ipx, grid->ipy, grid->ipz, grid->ipm,
	         grid->xsize, grid->ysize, grid->zsize, grid->msize);
}
Exemple #9
0
void printLWTIN(LWTIN *tin)
{
	int i;
	LWTRIANGLE *triangle;

	if (tin->type != TINTYPE)
		lwerror("printLWTIN called with something else than a TIN");

	lwnotice("LWTIN {");
	lwnotice("    ndims = %i", (int)FLAGS_NDIMS(tin->flags));
	lwnotice("    SRID = %i", (int)tin->srid);
	lwnotice("    ngeoms = %i", (int)tin->ngeoms);

	for (i=0; i<tin->ngeoms; i++)
	{
		triangle = (LWTRIANGLE *) tin->geoms[i];
		printPA(triangle->points);
	}
	lwnotice("}");
}
Exemple #10
0
int
clamp_srid(int srid)
{
	int newsrid = srid;

	if ( newsrid <= 0 ) {
		if ( newsrid != SRID_UNKNOWN ) {
			newsrid = SRID_UNKNOWN;
			lwnotice("SRID value %d converted to the officially unknown SRID value %d", srid, newsrid);
		}
	} else if ( srid > SRID_MAXIMUM ) {
    newsrid = SRID_USER_MAXIMUM + 1 +
      /* -1 is to reduce likelyhood of clashes */
      /* NOTE: must match implementation in postgis_restore.pl */
      ( srid % ( SRID_MAXIMUM - SRID_USER_MAXIMUM - 1 ) );
		lwnotice("SRID value %d > SRID_MAXIMUM converted to %d", srid, newsrid);
	}
	
	return newsrid;
}
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;
}
Exemple #12
0
int
clamp_srid(int srid)
{
	if ( srid <= 0 ) {
		if ( srid != SRID_UNKNOWN ) {
			lwnotice("SRID value %d converted to the officially unknown SRID value %d", srid, SRID_UNKNOWN);
			srid = SRID_UNKNOWN;
		}
	} else if ( srid > SRID_MAXIMUM ) {
		/* should this be a NOTICE instead ? */
		lwerror("SRID value %d > SRID_MAXIMUM (%d)",srid,SRID_MAXIMUM);
	}
	
	return srid;
}
Exemple #13
0
extern LWGEOM* lwgeom_remove_repeated_points(LWGEOM *in)
{
	LWDEBUGF(4, "lwgeom_remove_repeated_points got type %s",
	         lwtype_name(in->type));

	switch (in->type)
	{
	case MULTIPOINTTYPE:
		return lwmpoint_remove_repeated_points((LWMPOINT*)in);
		break;
	case LINETYPE:
		return lwline_remove_repeated_points((LWLINE*)in);

	case MULTILINETYPE:
	case COLLECTIONTYPE:
	case MULTIPOLYGONTYPE:
	case POLYHEDRALSURFACETYPE:
		return lwcollection_remove_repeated_points((LWCOLLECTION *)in);

	case POLYGONTYPE:
		return lwpoly_remove_repeated_points((LWPOLY *)in);
		break;

	case POINTTYPE:
	case TRIANGLETYPE:
	case TINTYPE:
		/* No point is repeated for a single point, or for Triangle or TIN */
		return in;

	case CIRCSTRINGTYPE:
	case COMPOUNDTYPE:
	case MULTICURVETYPE:
	case CURVEPOLYTYPE:
	case MULTISURFACETYPE:
		/* Dunno how to handle these, will return untouched */
		return in;

	default:
		lwnotice("lwgeom_remove_repeated_points: unsupported geometry type: %s",
		         lwtype_name(in->type));
		return in;
		break;
	}
	return 0;
}
Exemple #14
0
void printLWPOLY(LWPOLY *poly)
{
	int t;
	lwnotice("LWPOLY {");
	lwnotice("    ndims = %i", (int)FLAGS_NDIMS(poly->flags));
	lwnotice("    SRID = %i", (int)poly->srid);
	lwnotice("    nrings = %i", (int)poly->nrings);
	for (t=0; t<poly->nrings; t++)
	{
		lwnotice("    RING # %i :",t);
		printPA(poly->rings[t]);
	}
	lwnotice("}");
}
int
point4d_transform(POINT4D *pt, projPJ srcpj, projPJ dstpj)
{
	int* pj_errno_ref;
	POINT4D orig_pt;

	/* Make a copy of the input point so we can report the original should an error occur */
	orig_pt.x = pt->x;
	orig_pt.y = pt->y;
	orig_pt.z = pt->z;

	if (pj_is_latlong(srcpj)) to_rad(pt) ;

	LWDEBUGF(4, "transforming POINT(%f %f) from '%s' to '%s'", orig_pt.x, orig_pt.y, pj_get_def(srcpj,0), pj_get_def(dstpj,0));

	/* Perform the transform */
	pj_transform(srcpj, dstpj, 1, 0, &(pt->x), &(pt->y), &(pt->z));

	/* For NAD grid-shift errors, display an error message with an additional hint */
	pj_errno_ref = pj_get_errno_ref();

	if (*pj_errno_ref != 0)
	{
		if (*pj_errno_ref == -38)
		{
			lwnotice("PostGIS was unable to transform the point because either no grid shift files were found, or the point does not lie within the range for which the grid shift is defined. Refer to the ST_Transform() section of the PostGIS manual for details on how to configure PostGIS to alter this behaviour.");
			lwerror("transform: couldn't project point (%g %g %g): %s (%d)",
			        orig_pt.x, orig_pt.y, orig_pt.z, pj_strerrno(*pj_errno_ref), *pj_errno_ref);
			return 0;
		}
		else
		{
			lwerror("transform: couldn't project point (%g %g %g): %s (%d)",
			        orig_pt.x, orig_pt.y, orig_pt.z, pj_strerrno(*pj_errno_ref), *pj_errno_ref);
			return 0;
		}
	}

	if (pj_is_latlong(dstpj)) to_dec(pt);
	return 1;
}
Exemple #16
0
/**
	Function handling 3d min distance calculations and dwithin calculations.
	The difference is just the tolerance.
*/
double
lwgeom_mindistance3d_tolerance(const LWGEOM *lw1, const LWGEOM *lw2, double tolerance)
{
	if(!lwgeom_has_z(lw1) || !lwgeom_has_z(lw2))
	{
		lwnotice("One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
		
		return lwgeom_mindistance2d_tolerance(lw1, lw2, tolerance);	
	}
	DISTPTS3D thedl;
	LWDEBUG(2, "lwgeom_mindistance3d_tolerance is called");
	thedl.mode = DIST_MIN;
	thedl.distance= FLT_MAX;
	thedl.tolerance = tolerance;
	if (lw_dist3d_recursive(lw1, lw2, &thedl))
	{
		return thedl.distance;
	}
	/*should never get here. all cases ought to be error handled earlier*/
	lwerror("Some unspecified error.");
	return FLT_MAX;
}
Exemple #17
0
void printLWPSURFACE(LWPSURFACE *psurf)
{
	int i, j;
	LWPOLY *patch;

	if (psurf->type != POLYHEDRALSURFACETYPE)
		lwerror("printLWPSURFACE called with something else than a POLYHEDRALSURFACE");

	lwnotice("LWPSURFACE {");
	lwnotice("    ndims = %i", (int)FLAGS_NDIMS(psurf->flags));
	lwnotice("    SRID = %i", (int)psurf->srid);
	lwnotice("    ngeoms = %i", (int)psurf->ngeoms);

	for (i=0; i<psurf->ngeoms; i++)
	{
		patch = (LWPOLY *) psurf->geoms[i];
		for (j=0; j<patch->nrings; j++)
		{
			lwnotice("    RING # %i :",j);
			printPA(patch->rings[j]);
		}
	}
	lwnotice("}");
}
Exemple #18
0
GEOSGeometry*
LWGEOM_GEOS_buildArea(const GEOSGeometry* geom_in)
{
  GEOSGeometry *tmp;
  GEOSGeometry *geos_result, *shp;
  GEOSGeometry const *vgeoms[1];
  uint32_t i, ngeoms;
  int srid = GEOSGetSRID(geom_in);
  Face ** geoms;

  vgeoms[0] = geom_in;
#ifdef LWGEOM_PROFILE_BUILDAREA
  lwnotice("Polygonizing");
#endif
  geos_result = GEOSPolygonize(vgeoms, 1);

  LWDEBUGF(3, "GEOSpolygonize returned @ %p", geos_result);

  /* Null return from GEOSpolygonize (an exception) */
  if ( ! geos_result ) return 0;

  /*
   * We should now have a collection
   */
#if PARANOIA_LEVEL > 0
  if ( GEOSGeometryTypeId(geos_result) != COLLECTIONTYPE )
  {
    GEOSGeom_destroy(geos_result);
    lwerror("Unexpected return from GEOSpolygonize");
    return 0;
  }
#endif

  ngeoms = GEOSGetNumGeometries(geos_result);
#ifdef LWGEOM_PROFILE_BUILDAREA
  lwnotice("Num geometries from polygonizer: %d", ngeoms);
#endif


  LWDEBUGF(3, "GEOSpolygonize: ngeoms in polygonize output: %d", ngeoms);
  LWDEBUGF(3, "GEOSpolygonize: polygonized:%s",
              lwgeom_to_ewkt(GEOS2LWGEOM(geos_result, 0)));

  /*
   * No geometries in collection, early out
   */
  if ( ngeoms == 0 )
  {
    GEOSSetSRID(geos_result, srid);
    return geos_result;
  }

  /*
   * Return first geometry if we only have one in collection,
   * to avoid the unnecessary Geometry clone below.
   */
  if ( ngeoms == 1 )
  {
    tmp = (GEOSGeometry *)GEOSGetGeometryN(geos_result, 0);
    if ( ! tmp )
    {
      GEOSGeom_destroy(geos_result);
      return 0; /* exception */
    }
    shp = GEOSGeom_clone(tmp);
    GEOSGeom_destroy(geos_result); /* only safe after the clone above */
    GEOSSetSRID(shp, srid);
    return shp;
  }

  LWDEBUGF(2, "Polygonize returned %d geoms", ngeoms);

  /*
   * Polygonizer returns a polygon for each face in the built topology.
   *
   * This means that for any face with holes we'll have other faces
   * representing each hole. We can imagine a parent-child relationship
   * between these faces.
   *
   * In order to maximize the number of visible rings in output we
   * only use those faces which have an even number of parents.
   *
   * Example:
   *
   *   +---------------+
   *   |     L0        |  L0 has no parents 
   *   |  +---------+  |
   *   |  |   L1    |  |  L1 is an hole of L0
   *   |  |  +---+  |  |
   *   |  |  |L2 |  |  |  L2 is an hole of L1 (which is an hole of L0)
   *   |  |  |   |  |  |
   *   |  |  +---+  |  |
   *   |  +---------+  |
   *   |               |
   *   +---------------+
   * 
   * See http://trac.osgeo.org/postgis/ticket/1806
   *
   */

#ifdef LWGEOM_PROFILE_BUILDAREA
  lwnotice("Preparing face structures");
#endif

  /* Prepare face structures for later analysis */
  geoms = lwalloc(sizeof(Face**)*ngeoms);
  for (i=0; i<ngeoms; ++i)
    geoms[i] = newFace(GEOSGetGeometryN(geos_result, i));

#ifdef LWGEOM_PROFILE_BUILDAREA
  lwnotice("Finding face holes");
#endif

  /* Find faces representing other faces holes */
  findFaceHoles(geoms, ngeoms);

#ifdef LWGEOM_PROFILE_BUILDAREA
  lwnotice("Colletting even ancestor faces");
#endif

  /* Build a MultiPolygon composed only by faces with an
   * even number of ancestors */
  tmp = collectFacesWithEvenAncestors(geoms, ngeoms);

#ifdef LWGEOM_PROFILE_BUILDAREA
  lwnotice("Cleaning up");
#endif

  /* Cleanup face structures */
  for (i=0; i<ngeoms; ++i) delFace(geoms[i]);
  lwfree(geoms);

  /* Faces referenced memory owned by geos_result.
   * It is safe to destroy geos_result after deleting them. */
  GEOSGeom_destroy(geos_result);

#ifdef LWGEOM_PROFILE_BUILDAREA
  lwnotice("Self-unioning");
#endif

  /* Run a single overlay operation to dissolve shared edges */
  shp = GEOSUnionCascaded(tmp);
  if ( ! shp )
  {
    GEOSGeom_destroy(tmp);
    return 0; /* exception */
  }

#ifdef LWGEOM_PROFILE_BUILDAREA
  lwnotice("Final cleanup");
#endif

  GEOSGeom_destroy(tmp);

  GEOSSetSRID(shp, srid);

  return shp;
}
LWCOLLECTION*
lwgeom_clip_to_ordinate_range(const LWGEOM *lwin, char ordinate, double from, double to, double offset)
{
	LWCOLLECTION *out_col;
	LWCOLLECTION *out_offset;
	int i;
	
	if ( ! lwin )
		lwerror("lwgeom_clip_to_ordinate_range: null input geometry!");
		
	switch ( lwin->type )
	{
		case LINETYPE:
			out_col = lwline_clip_to_ordinate_range((LWLINE*)lwin, ordinate, from, to);
			break;
		case MULTILINETYPE:
			out_col = lwmline_clip_to_ordinate_range((LWMLINE*)lwin, ordinate, from, to);
			break;
		case MULTIPOINTTYPE:
			out_col = lwmpoint_clip_to_ordinate_range((LWMPOINT*)lwin, ordinate, from, to);
			break;
		case POINTTYPE:
			out_col = lwpoint_clip_to_ordinate_range((LWPOINT*)lwin, ordinate, from, to);
			break;
		default:
			lwerror("This function does not accept %s geometries.", lwtype_name(lwin->type));
			return NULL;;
	}
	
	/* Stop if result is NULL */
	if ( out_col == NULL )
		lwerror("lwgeom_clip_to_ordinate_range clipping routine returned NULL");
	
	/* Return if we aren't going to offset the result */
	if ( FP_EQUALS(offset, 0.0) || lwgeom_is_empty(lwcollection_as_lwgeom(out_col)) )
		return out_col;
	
	/* Construct a collection to hold our outputs. */
	/* Things get ugly: GEOS offset drops Z's and M's so we have to drop ours */
	out_offset = lwcollection_construct_empty(MULTILINETYPE, lwin->srid, 0, 0);
	
	/* Try and offset the linear portions of the return value */
	for ( i = 0; i < out_col->ngeoms; i++ )
	{
		int type = out_col->geoms[i]->type;
		if ( type == POINTTYPE )
		{
			lwnotice("lwgeom_clip_to_ordinate_range cannot offset a clipped point");
			continue;
		}
		else if ( type == LINETYPE )
		{
			/* lwgeom_offsetcurve(line, offset, quadsegs, joinstyle (round), mitrelimit) */
			LWGEOM *lwoff = lwgeom_offsetcurve(lwgeom_as_lwline(out_col->geoms[i]), offset, 8, 1, 5.0);
			if ( ! lwoff )
			{
				lwerror("lwgeom_offsetcurve returned null");
			}
			lwcollection_add_lwgeom(out_offset, lwoff);
		}
		else 
		{
			lwerror("lwgeom_clip_to_ordinate_range found an unexpected type (%s) in the offset routine",lwtype_name(type));
		}
	}

	return out_offset;
}
Exemple #20
0
/**
Function initializing 3dshortestline and 3dlongestline calculations.
*/
LWGEOM *
lw_dist3d_distanceline(const LWGEOM *lw1, const LWGEOM *lw2, int srid, int mode)
{
	LWDEBUG(2, "lw_dist3d_distanceline is called");
	double x1,x2,y1,y2, z1, z2, x, y;
	double initdistance = ( mode == DIST_MIN ? FLT_MAX : -1.0);
	DISTPTS3D thedl;
	LWPOINT *lwpoints[2];
	LWGEOM *result;

	thedl.mode = mode;
	thedl.distance = initdistance;
	thedl.tolerance = 0.0;

	/*Check if we really have 3D geoemtries*/
	/*If not, send it to 2D-calculations which will give the same result*/
	/*as an infinite z-value at one or two of the geometries*/
	if(!lwgeom_has_z(lw1) || !lwgeom_has_z(lw2))
	{
		
		lwnotice("One or both of the geometries is missing z-value. The unknown z-value will be regarded as \"any value\"");
		
		if(!lwgeom_has_z(lw1) && !lwgeom_has_z(lw2))
			return lw_dist2d_distanceline(lw1, lw2, srid, mode);	
		
		DISTPTS thedl2d;
		thedl2d.mode = mode;
		thedl2d.distance = initdistance;
		thedl2d.tolerance = 0.0;
		if (!lw_dist2d_comp( lw1,lw2,&thedl2d))
		{
			/*should never get here. all cases ought to be error handled earlier*/
			lwerror("Some unspecified error.");
			result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
		}
		LWGEOM *vertical_line;
		if(!lwgeom_has_z(lw1))
		{
			x=thedl2d.p1.x;
			y=thedl2d.p1.y;

			vertical_line = create_v_line(lw2,x,y,srid);
			if (!lw_dist3d_recursive(vertical_line, lw2, &thedl))
			{
				/*should never get here. all cases ought to be error handled earlier*/
				lwfree(vertical_line);
				lwerror("Some unspecified error.");
				result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
			}			
			lwfree(vertical_line);	
		}	
		if(!lwgeom_has_z(lw2))
		{
			x=thedl2d.p2.x;
			y=thedl2d.p2.y;			
			
			vertical_line = create_v_line(lw1,x,y,srid);
			if (!lw_dist3d_recursive(lw1, vertical_line, &thedl))
			{
				/*should never get here. all cases ought to be error handled earlier*/
				lwfree(vertical_line);
				lwerror("Some unspecified error.");
				return (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
			}	
			lwfree(vertical_line);		
		}			
				
	}
	else
	{		
		if (!lw_dist3d_recursive(lw1, lw2, &thedl))
		{
			/*should never get here. all cases ought to be error handled earlier*/
			lwerror("Some unspecified error.");
			result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
		}
	}
	/*if thedl.distance is unchanged there where only empty geometries input*/
	if (thedl.distance == initdistance)
	{
		LWDEBUG(3, "didn't find geometries to measure between, returning null");
		result = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, srid, 0, 0);
	}
	else
	{
		x1=thedl.p1.x;
		y1=thedl.p1.y;
		z1=thedl.p1.z;
		x2=thedl.p2.x;
		y2=thedl.p2.y;
		z2=thedl.p2.z;

		lwpoints[0] = lwpoint_make3dz(srid, x1, y1, z1);
		lwpoints[1] = lwpoint_make3dz(srid, x2, y2, z2);

		result = (LWGEOM *)lwline_from_ptarray(srid, 2, lwpoints);
	}

	return result;
}