Exemplo n.º 1
0
static int treeNodeAddShapeId( treeNodeObj *node, int id, rectObj rect, int maxdepth)
{
  int i;

  /* -------------------------------------------------------------------- */
  /*      If there are subnodes, then consider whether this object        */
  /*      will fit in them.                                               */
  /* -------------------------------------------------------------------- */
  if( maxdepth > 1 && node->numsubnodes > 0 ) {
    for(i=0; i<node->numsubnodes; i++ ) {
      if( msRectContained(&rect, &node->subnode[i]->rect)) {
        return treeNodeAddShapeId( node->subnode[i], id, rect, maxdepth-1);
      }
    }
  }

  /* -------------------------------------------------------------------- */
  /*      Otherwise, consider creating four subnodes if could fit into    */
  /*      them, and adding to the appropriate subnode.                    */
  /* -------------------------------------------------------------------- */
#if MAX_SUBNODES == 4
  else if( maxdepth > 1 && node->numsubnodes == 0 ) {
    rectObj half1, half2, quad1, quad2, quad3, quad4;

    treeSplitBounds(&node->rect, &half1, &half2);
    treeSplitBounds(&half1, &quad1, &quad2);
    treeSplitBounds(&half2, &quad3, &quad4);

    if(msRectContained(&rect, &quad1) || msRectContained(&rect, &quad2) ||  msRectContained(&rect, &quad3) || msRectContained(&rect, &quad4)) {
      node->numsubnodes = 4;
      node->subnode[0] = treeNodeCreate(quad1);
      node->subnode[1] = treeNodeCreate(quad2);
      node->subnode[2] = treeNodeCreate(quad3);
      node->subnode[3] = treeNodeCreate(quad4);

      /* recurse back on this node now that it has subnodes */
      return(treeNodeAddShapeId(node, id, rect, maxdepth));
    }
  }
#endif

  /* -------------------------------------------------------------------- */
  /*      Otherwise, consider creating two subnodes if could fit into     */
  /*      them, and adding to the appropriate subnode.                    */
  /* -------------------------------------------------------------------- */
#if MAX_SUBNODE == 2
  else if( maxdepth > 1 && node->numsubnodes == 0 ) {
    rectObj half1, half2;

    treeSplitBounds(&node->rect, &half1, &half2);

    if( msRectContained(&rect, &half1)) {
      node->numsubnodes = 2;
      node->subnode[0] = treeNodeCreate(half1);
      node->subnode[1] = treeNodeCreate(half2);

      return(treeNodeAddShapeId(node->subnode[0], id, rect, maxdepth-1));
    } else if(msRectContained(&rect, &half2)) {
      node->numsubnodes = 2;
      node->subnode[0] = treeNodeCreate(&half1);
      node->subnode[1] = treeNodeCreate(&half2);

      return(treeNodeAddShapeId(node->subnode[1], id, rect, maxdepth-1));
    }
  }
#endif /* MAX_SUBNODE == 2 */

  /* -------------------------------------------------------------------- */
  /*      If none of that worked, just add it to this nodes list.         */
  /* -------------------------------------------------------------------- */
  node->numshapes++;

  node->ids = SfRealloc( node->ids, sizeof(ms_int32) * node->numshapes );
  node->ids[node->numshapes-1] = id;

  return MS_TRUE;
}
Exemplo n.º 2
0
/* adding the shape based on the shape bounds (point) */
static int treeNodeAddShape(msClusterLayerInfo* layerinfo, clusterTreeNode* node, clusterInfo* shape, int depth)
{
  int i;

  /* -------------------------------------------------------------------- */
  /*      If there are subnodes, then consider whether this object        */
  /*      will fit in them.                                               */
  /* -------------------------------------------------------------------- */
  if( depth > 1 && node->subnode[0] != NULL ) {
    for(i = 0; i < 4; i++ ) {
      if( msRectContained(&shape->shape.bounds, &node->subnode[i]->rect)) {
        return treeNodeAddShape( layerinfo, node->subnode[i], shape, depth-1);
      }
    }
  }

  /* -------------------------------------------------------------------- */
  /*      Otherwise, consider creating four subnodes if could fit into    */
  /*      them, and adding to the appropriate subnode.                    */
  /* -------------------------------------------------------------------- */
  else if( depth > 1 && node->subnode[0] == NULL ) {
    rectObj half1, half2, quad1, quad2, quad3, quad4;
    int subnode = -1;

    treeSplitBounds(&node->rect, &half1, &half2);
    treeSplitBounds(&half1, &quad1, &quad2);
    treeSplitBounds(&half2, &quad3, &quad4);

    if(msRectContained(&shape->shape.bounds, &quad1))
      subnode = 0;
    else if(msRectContained(&shape->shape.bounds, &quad2))
      subnode = 1;
    else if(msRectContained(&shape->shape.bounds, &quad3))
      subnode = 2;
    else if(msRectContained(&shape->shape.bounds, &quad4))
      subnode = 3;

    if (subnode >= 0) {
      if ((node->subnode[0] = clusterTreeNodeCreate(layerinfo, quad1)) == NULL)
        return MS_FAILURE;
      node->subnode[0]->position = node->position * 4;

      if ((node->subnode[1] = clusterTreeNodeCreate(layerinfo, quad2)) == NULL)
        return MS_FAILURE;
      node->subnode[1]->position = node->position * 4 + 1;

      if ((node->subnode[2] = clusterTreeNodeCreate(layerinfo, quad3)) == NULL)
        return MS_FAILURE;
      node->subnode[2]->position = node->position * 4 + 2;

      if ((node->subnode[3] = clusterTreeNodeCreate(layerinfo, quad4)) == NULL)
        return MS_FAILURE;
      node->subnode[3]->position = node->position * 4 + 3;

      /* add to subnode */
      return treeNodeAddShape(layerinfo, node->subnode[subnode], shape, depth-1);
    }
  }

  /* found the right place, add this shape to the node */
  node->numshapes++;
  shape->next = node->shapes;
  node->shapes = shape;
  shape->node = node;

  return MS_SUCCESS;
}