/************************************************************************/ /* SHPTreeAddShapeId() */ /* */ /* Add a shape to the tree, but don't keep a pointer to the */ /* object data, just keep the shapeid. */ /************************************************************************/ public bool AddShapeId(SHPObject psObject) { SHPTree psTree = this; /* do not free! */ return(NodeAddShapeId(psTree.psRoot, psObject, psTree.nMaxDepth, psTree.nDimension)); }
/************************************************************************/ /* SHPCheckObjectContained() */ /* */ /* Does the given shape fit within the indicated extents? */ /************************************************************************/ private static bool CheckObjectContained(SHPObject psObject, int nDimension, double[] padfBoundsMin, double[] padfBoundsMax) { if (psObject.dfXMin < padfBoundsMin[0] || psObject.dfXMax > padfBoundsMax[0]) { return(false); } if (psObject.dfYMin < padfBoundsMin[1] || psObject.dfYMax > padfBoundsMax[1]) { return(false); } if (nDimension == 2) { return(true); } if (psObject.dfZMin < padfBoundsMin[2] || psObject.dfZMax < padfBoundsMax[2]) { return(false); } if (nDimension == 3) { return(true); } if (psObject.dfMMin < padfBoundsMin[3] || psObject.dfMMax < padfBoundsMax[3]) { return(false); } return(true); }
/************************************************************************/ /* SHPTreeNodeAddShapeId() */ /************************************************************************/ private static bool NodeAddShapeId( SHPTreeNode psTreeNode, SHPObject psObject, int nMaxDepth, int nDimension) { int i; /* -------------------------------------------------------------------- */ /* If there are subnodes, then consider wiether this object */ /* will fit in them. */ /* -------------------------------------------------------------------- */ if (nMaxDepth > 1 && psTreeNode.nSubNodes > 0) { for (i = 0; i < psTreeNode.nSubNodes; i++) { if (CheckObjectContained(psObject, nDimension, psTreeNode.apsSubNode[i].adfBoundsMin, psTreeNode.apsSubNode[i].adfBoundsMax)) { return(NodeAddShapeId(psTreeNode.apsSubNode[i], psObject, nMaxDepth - 1, nDimension)); } } } /* -------------------------------------------------------------------- */ /* Otherwise, consider creating four subnodes if could fit into */ /* them, and adding to the appropriate subnode. */ /* -------------------------------------------------------------------- */ #if MAX_SUBNODE_QUAD else if (nMaxDepth > 1 && psTreeNode.nSubNodes == 0) { double[] adfBoundsMinH1 = new double[4], adfBoundsMaxH1 = new double[4]; double[] adfBoundsMinH2 = new double[4], adfBoundsMaxH2 = new double[4]; double[] adfBoundsMin1 = new double[4], adfBoundsMax1 = new double[4]; double[] adfBoundsMin2 = new double[4], adfBoundsMax2 = new double[4]; double[] adfBoundsMin3 = new double[4], adfBoundsMax3 = new double[4]; double[] adfBoundsMin4 = new double[4], adfBoundsMax4 = new double[4]; SplitBounds(psTreeNode.adfBoundsMin, psTreeNode.adfBoundsMax, adfBoundsMinH1, adfBoundsMaxH1, adfBoundsMinH2, adfBoundsMaxH2); SplitBounds(adfBoundsMinH1, adfBoundsMaxH1, adfBoundsMin1, adfBoundsMax1, adfBoundsMin2, adfBoundsMax2); SplitBounds(adfBoundsMinH2, adfBoundsMaxH2, adfBoundsMin3, adfBoundsMax3, adfBoundsMin4, adfBoundsMax4); if (CheckObjectContained(psObject, nDimension, adfBoundsMin1, adfBoundsMax1) || CheckObjectContained(psObject, nDimension, adfBoundsMin2, adfBoundsMax2) || CheckObjectContained(psObject, nDimension, adfBoundsMin3, adfBoundsMax3) || CheckObjectContained(psObject, nDimension, adfBoundsMin4, adfBoundsMax4)) { psTreeNode.nSubNodes = 4; psTreeNode.apsSubNode[0] = NodeCreate(adfBoundsMin1, adfBoundsMax1); psTreeNode.apsSubNode[1] = NodeCreate(adfBoundsMin2, adfBoundsMax2); psTreeNode.apsSubNode[2] = NodeCreate(adfBoundsMin3, adfBoundsMax3); psTreeNode.apsSubNode[3] = NodeCreate(adfBoundsMin4, adfBoundsMax4); /* recurse back on this node now that it has subnodes */ return(NodeAddShapeId(psTreeNode, psObject, nMaxDepth, nDimension)); } } #else // MAX_SUBNODE_QUAD /* -------------------------------------------------------------------- */ /* Otherwise, consider creating two subnodes if could fit into */ /* them, and adding to the appropriate subnode. */ /* -------------------------------------------------------------------- */ else if (nMaxDepth > 1 && psTreeNode.nSubNodes == 0) { double[] adfBoundsMin1 = new double[4], adfBoundsMax1 = new double[4]; double[] adfBoundsMin2 = new double[4], adfBoundsMax2 = new double[4]; SplitBounds(psTreeNode.adfBoundsMin, psTreeNode.adfBoundsMax, adfBoundsMin1, adfBoundsMax1, adfBoundsMin2, adfBoundsMax2); if (CheckObjectContained(psObject, nDimension, adfBoundsMin1, adfBoundsMax1)) { psTreeNode.nSubNodes = 2; psTreeNode.apsSubNode[0] = NodeCreate(adfBoundsMin1, adfBoundsMax1); psTreeNode.apsSubNode[1] = NodeCreate(adfBoundsMin2, adfBoundsMax2); return(NodeAddShapeId(psTreeNode.apsSubNode[0], psObject, nMaxDepth - 1, nDimension)); } else if (CheckObjectContained(psObject, nDimension, adfBoundsMin2, adfBoundsMax2)) { psTreeNode.nSubNodes = 2; psTreeNode.apsSubNode[0] = NodeCreate(adfBoundsMin1, adfBoundsMax1); psTreeNode.apsSubNode[1] = NodeCreate(adfBoundsMin2, adfBoundsMax2); return(NodeAddShapeId(psTreeNode.apsSubNode[1], psObject, nMaxDepth - 1, nDimension)); } } #endif // MAX_SUBNODE_QUAD /* -------------------------------------------------------------------- */ /* If none of that worked, just add it to this nodes list. */ /* -------------------------------------------------------------------- */ psTreeNode.nShapeCount++; psTreeNode.panShapeIds = SfRealloc(ref psTreeNode.panShapeIds, psTreeNode.nShapeCount); psTreeNode.panShapeIds[psTreeNode.nShapeCount - 1] = psObject.nShapeId; if (psTreeNode.papsShapeObj != null) { psTreeNode.papsShapeObj = SfRealloc(ref psTreeNode.papsShapeObj, psTreeNode.nShapeCount); psTreeNode.papsShapeObj[psTreeNode.nShapeCount - 1] = null; } return(true); }