コード例 #1
0
ファイル: lwin_geojson.c プロジェクト: gbroccolo/postgis
static LWGEOM*
parse_geojson_multilinestring(json_object *geojson, int *hasz, int root_srid)
{
	LWGEOM *geom = NULL;
	int i, j;
	json_object* poObjLines = NULL;

	if (!root_srid)
	{
		geom = (LWGEOM *)lwcollection_construct_empty(MULTILINETYPE, root_srid, 1, 0);
	}
	else
	{
		geom = (LWGEOM *)lwcollection_construct_empty(MULTILINETYPE, -1, 1, 0);
	}

	poObjLines = findMemberByName( geojson, "coordinates" );
	if ( ! poObjLines ) 
	{
		geojson_lwerror("Unable to find 'coordinates' in GeoJSON string", 4);
		return NULL;
	}

	if( json_type_array == json_object_get_type( poObjLines ) )
	{
		const int nLines = json_object_array_length( poObjLines );
		for( i = 0; i < nLines; ++i)
		{
			POINTARRAY *pa = NULL;
			json_object* poObjLine = NULL;
			poObjLine = json_object_array_get_idx( poObjLines, i );
			pa = ptarray_construct_empty(1, 0, 1);

			if( json_type_array == json_object_get_type( poObjLine ) )
			{
				const int nPoints = json_object_array_length( poObjLine );
				for(j = 0; j < nPoints; ++j)
				{
					json_object* coords = NULL;
					coords = json_object_array_get_idx( poObjLine, j );
					parse_geojson_coord(coords, hasz, pa);
				}

				geom = (LWGEOM*)lwmline_add_lwline((LWMLINE*)geom,
				                                   (LWLINE*)lwline_construct(root_srid, NULL, pa));
			}
		}
	}

	return geom;
}
コード例 #2
0
static LWGEOM*
lwline_split_by_point(const LWLINE* lwline_in, const LWPOINT* blade_in)
{
	LWMLINE* out;

	out = lwmline_construct_empty(lwline_in->srid,
		FLAGS_GET_Z(lwline_in->flags),
		FLAGS_GET_M(lwline_in->flags));
	if ( lwline_split_by_point_to(lwline_in, blade_in, out) < 2 )
	{
		lwmline_add_lwline(out, lwline_clone_deep(lwline_in));
	}

	/* Turn multiline into collection */
	out->type = COLLECTIONTYPE;

	return (LWGEOM*)out;
}
コード例 #3
0
static LWGEOM*
lwline_split_by_mpoint(const LWLINE* lwline_in, const LWMPOINT* mp)
{
  LWMLINE* out;
  int i, j;

  out = lwmline_construct_empty(lwline_in->srid,
          FLAGS_GET_Z(lwline_in->flags),
          FLAGS_GET_M(lwline_in->flags));
  lwmline_add_lwline(out, lwline_clone_deep(lwline_in));

  for (i=0; i<mp->ngeoms; ++i)
  {
    for (j=0; j<out->ngeoms; ++j)
    {
      lwline_in = out->geoms[j];
      LWPOINT *blade_in = mp->geoms[i];
      int ret = lwline_split_by_point_to(lwline_in, blade_in, out);
      if ( 2 == ret )
      {
        /* the point splits this line,
         * 2 splits were added to collection.
         * We'll move the latest added into
         * the slot of the current one.
         */
        lwline_free(out->geoms[j]);
        out->geoms[j] = out->geoms[--out->ngeoms];
      }
    }
  }

  /* Turn multiline into collection */
  out->type = COLLECTIONTYPE;

  return (LWGEOM*)out;
}
コード例 #4
0
int
lwline_split_by_point_to(const LWLINE* lwline_in, const LWPOINT* blade_in,
                         LWMLINE* v)
{
	double mindist = -1;
	POINT4D pt, pt_projected;
	POINT4D p1, p2;
	POINTARRAY *ipa = lwline_in->points;
	POINTARRAY* pa1;
	POINTARRAY* pa2;
	int i, nsegs, seg = -1;

	/* Possible outcomes:
	 *
	 *  1. The point is not on the line or on the boundary
	 *      -> Leave collection untouched, return 0
	 *  2. The point is on the boundary
	 *      -> Leave collection untouched, return 1
	 *  3. The point is in the line
	 *      -> Push 2 elements on the collection:
	 *         o start_point - cut_point
	 *         o cut_point - last_point
	 *      -> Return 2
	 */

	getPoint4d_p(blade_in->point, 0, &pt);

	/* Find closest segment */
	getPoint4d_p(ipa, 0, &p1);
	nsegs = ipa->npoints - 1;
	for ( i = 0; i < nsegs; i++ )
	{
		getPoint4d_p(ipa, i+1, &p2);
		double dist;
		dist = distance2d_pt_seg((POINT2D*)&pt, (POINT2D*)&p1, (POINT2D*)&p2);
		LWDEBUGF(4, " Distance of point %g %g to segment %g %g, %g %g: %g", pt.x, pt.y, p1.x, p1.y, p2.x, p2.y, dist);
		if (i==0 || dist < mindist )
		{
			mindist = dist;
			seg=i;
			if ( mindist == 0.0 ) break; /* can't be closer than ON line */
		}
		p1 = p2;
	}

	LWDEBUGF(3, "Closest segment: %d", seg);
	LWDEBUGF(3, "mindist: %g", mindist);

	/* No intersection */
	if ( mindist > 0 ) return 0;

	/* empty or single-point line, intersection on boundary */
	if ( seg < 0 ) return 1;

	/*
	 * We need to project the
	 * point on the closest segment,
	 * to interpolate Z and M if needed
	 */
	getPoint4d_p(ipa, seg, &p1);
	getPoint4d_p(ipa, seg+1, &p2);
	closest_point_on_segment(&pt, &p1, &p2, &pt_projected);
	/* But X and Y we want the ones of the input point,
	 * as on some architectures the interpolation math moves the
	 * coordinates (see #3422)
	 */
	pt_projected.x = pt.x;
	pt_projected.y = pt.y;

	LWDEBUGF(3, "Projected point:(%g %g), seg:%d, p1:(%g %g), p2:(%g %g)", pt_projected.x, pt_projected.y, seg, p1.x, p1.y, p2.x, p2.y);

	/* When closest point == an endpoint, this is a boundary intersection */
	if ( ( (seg == nsegs-1) && p4d_same(&pt_projected, &p2) ) ||
	     ( (seg == 0)       && p4d_same(&pt_projected, &p1) ) )
	{
		return 1;
	}

	/* This is an internal intersection, let's build the two new pointarrays */

	pa1 = ptarray_construct_empty(FLAGS_GET_Z(ipa->flags), FLAGS_GET_M(ipa->flags), seg+2);
	/* TODO: replace with a memcpy ? */
	for (i=0; i<=seg; ++i)
	{
		getPoint4d_p(ipa, i, &p1);
		ptarray_append_point(pa1, &p1, LW_FALSE);
	}
	ptarray_append_point(pa1, &pt_projected, LW_FALSE);

	pa2 = ptarray_construct_empty(FLAGS_GET_Z(ipa->flags), FLAGS_GET_M(ipa->flags), ipa->npoints-seg);
	ptarray_append_point(pa2, &pt_projected, LW_FALSE);
	/* TODO: replace with a memcpy (if so need to check for duplicated point) ? */
	for (i=seg+1; i<ipa->npoints; ++i)
	{
		getPoint4d_p(ipa, i, &p1);
		ptarray_append_point(pa2, &p1, LW_FALSE);
	}

	/* NOTE: I've seen empty pointarrays with loc != 0 and loc != 1 */
	if ( pa1->npoints == 0 || pa2->npoints == 0 ) {
		ptarray_free(pa1);
		ptarray_free(pa2);
		/* Intersection is on the boundary */
		return 1;
	}

	lwmline_add_lwline(v, lwline_construct(SRID_UNKNOWN, NULL, pa1));
	lwmline_add_lwline(v, lwline_construct(SRID_UNKNOWN, NULL, pa2));
	return 2;
}
コード例 #5
0
int
lwline_split_by_point_to(const LWLINE* lwline_in, const LWPOINT* blade_in,
                         LWMLINE* v)
{
	double loc, dist;
	POINT4D pt, pt_projected;
	POINTARRAY* pa1;
	POINTARRAY* pa2;
	double vstol; /* vertex snap tolerance */

	/* Possible outcomes:
	 *
	 *  1. The point is not on the line or on the boundary
	 *      -> Leave collection untouched, return 0
	 *  2. The point is on the boundary
	 *      -> Push 1 element on the collection:
	 *         o the original line
	 *      -> Return 1
	 *  3. The point is in the line
	 *      -> Push 2 elements on the collection:
	 *         o start_point - cut_point
	 *         o cut_point - last_point
	 *      -> Return 2
	 */

	getPoint4d_p(blade_in->point, 0, &pt);
	loc = ptarray_locate_point(lwline_in->points, &pt, &dist, &pt_projected);

	/* lwnotice("Location: %g -- Distance: %g", loc, dist); */

	if ( dist > 0 )   /* TODO: accept a tolerance ? */
	{
		/* No intersection */
		return 0;
	}

	if ( loc == 0 || loc == 1 )
	{
		/* Intersection is on the boundary */
		return 1;
	}

	/* There is a real intersection, let's get two substrings */

	/* Compute vertex snap tolerance based on line length
	 * TODO: take as parameter ? */
	vstol = ptarray_length_2d(lwline_in->points) / 1e14;

	pa1 = ptarray_substring(lwline_in->points, 0, loc, vstol);
	pa2 = ptarray_substring(lwline_in->points, loc, 1, vstol);

	/* NOTE: I've seen empty pointarrays with loc != 0 and loc != 1 */
	if ( pa1->npoints == 0 || pa2->npoints == 0 ) {
		ptarray_free(pa1);
		ptarray_free(pa2);
		/* Intersection is on the boundary */
		return 1;
	}

	lwmline_add_lwline(v, lwline_construct(SRID_UNKNOWN, NULL, pa1));
	lwmline_add_lwline(v, lwline_construct(SRID_UNKNOWN, NULL, pa2));
	return 2;
}