Create a new internal node, calculating the new measure range for the node, and storing pointers to the child nodes.
232{
235 double new_radius;
236 double offset1, dist, D, r1, ri;
237 uint32_t i, new_geom_type;
238
239 LWDEBUGF(3,
"called with %d nodes --", num_nodes);
240
241
242 if ( num_nodes < 1 )
243 return node;
244
245
246 new_center = c[0]->
center;
247 new_radius = c[0]->
radius;
249
250
251 for ( i = 1; i < num_nodes; i++ )
252 {
253 c1 = new_center;
254 r1 = new_radius;
255
258
259
260
261 if ( ! new_geom_type )
262 {
264 }
265
267 {
268
269 if ( new_geom_type != c[i]->geom_type )
270 {
272 }
273 else
274 {
276 }
277 }
278
280 {
282 }
283
284
285 LWDEBUGF(3,
"distance between new (%g %g) and %i (%g %g) is %g", c1.
lon, c1.
lat, i, c[i]->center.lon, c[i]->center.lat, dist);
286
288 {
289 LWDEBUG(3,
" distance between centers is zero");
290 new_radius = r1 + 2*dist;
291 new_center = c1;
292 }
293 else if ( dist < fabs(r1 - ri) )
294 {
295
296 if ( r1 > ri )
297 {
299 new_center = c1;
300 new_radius = r1;
301 }
302
303 else
304 {
306 new_center = c[i]->
center;
307 new_radius = ri;
308 }
309 }
310 else
311 {
312 LWDEBUG(3,
" calculating new center");
313
314 D = dist + r1 + ri;
316
317
318 new_radius = D / 2.0;
319
320
321 offset1 = ri + (D - (2.0*r1 + 2.0*ri)) / 2.0;
322 LWDEBUGF(3,
" offset1 is %g", offset1);
323
324
325
326
327
329 {
331 new_radius *= 1.1;
332 }
333 }
334 LWDEBUGF(3,
" new center is (%g %g) new radius is %g", new_center.
lon, new_center.
lat, new_radius);
335 }
336
340 node->
center = new_center;
341 node->
radius = new_radius;
348 return node;
349}
uint32_t lwtype_get_collectiontype(uint8_t type)
Given an lwtype number, what homogeneous collection can hold it?
int lwtype_is_collection(uint8_t type)
Determine whether a type number is a collection or not.
void * lwalloc(size_t size)
double sphere_distance(const GEOGRAPHIC_POINT *s, const GEOGRAPHIC_POINT *e)
Given two points on a unit sphere, calculate their distance apart in radians.
static int circ_center_spherical(const GEOGRAPHIC_POINT *c1, const GEOGRAPHIC_POINT *c2, double distance, double offset, GEOGRAPHIC_POINT *center)
Given the centers of two circles, and the offset distance we want to put the new center between them ...
static int circ_center_cartesian(const GEOGRAPHIC_POINT *c1, const GEOGRAPHIC_POINT *c2, double distance, double offset, GEOGRAPHIC_POINT *center)
Where the circ_center_spherical() function fails, we need a fall-back.
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
Point in spherical coordinates on the world.
struct circ_node ** nodes
Note that p1 and p2 are pointers into an independent POINTARRAY, do not free them.