Exemplo n.º 1
0
        public static SqlGeometry ExtractGeometry(SqlGeometry sqlGeometry, int elementIndex, int ringIndex = 0)
        {
            if (sqlGeometry.IsNullOrEmpty())
            {
                return(sqlGeometry);
            }

            // GEOMETRYCOLLECTION
            if (sqlGeometry.IsGeometryCollection())
            {
                if (elementIndex == 0 || elementIndex > sqlGeometry.STNumGeometries())
                {
                    Ext.ThrowInvalidElementIndex();
                }

                // reset geometry and element index and pass through
                sqlGeometry  = sqlGeometry.STGeometryN(elementIndex);
                elementIndex = 1;

                // if the resultant is MULTILINE; reset the ring index and assign it to element index
                if (sqlGeometry.IsMultiLineString())
                {
                    elementIndex = ringIndex;
                    ringIndex    = 0;
                }
            }

            // Handle for Curve Polygon with Compound Curve
            if (sqlGeometry.IsCurvePolygon())
            {
                if (elementIndex != 1)
                {
                    Ext.ThrowInvalidElementIndex();
                }
                if (ringIndex == 0)
                {
                    return(sqlGeometry);
                }
                // re-assign sub component; if it is a COMPOUND CURVE
                var subComponent = ringIndex == 1 ? sqlGeometry.STExteriorRing() : sqlGeometry.STInteriorRingN(ringIndex - 1); // subtracting exterior ring count
                if (subComponent.IsCompoundCurve())
                {
                    sqlGeometry  = subComponent;
                    elementIndex = 1;
                    ringIndex    = 1;
                }
            }

            var isSimpleType = sqlGeometry.IsPoint() || sqlGeometry.IsLineString() || sqlGeometry.IsCircularString();

            // if simple type then return input geometry when index is 1 or 0
            if (isSimpleType)
            {
                if (elementIndex != 1)
                {
                    Ext.ThrowInvalidElementIndex();
                }

                if (ringIndex > 1)
                {
                    Ext.ThrowInvalidSubElementIndex();
                }

                if (isSimpleType && ringIndex <= 1)
                {
                    return(sqlGeometry);
                }
            }

            // MULTIPOINT
            if (sqlGeometry.IsMultiPoint())
            {
                if (elementIndex != 1)
                {
                    Ext.ThrowInvalidElementIndex();
                }

                if (ringIndex == 0)
                {
                    return(sqlGeometry);
                }

                var obtainedGeom = sqlGeometry.STGeometryN(ringIndex);
                if (obtainedGeom == null || obtainedGeom.IsNull)
                {
                    Ext.ThrowInvalidSubElementIndex();
                }

                return(obtainedGeom);
            }

            // MULTILINESTRING
            if (sqlGeometry.IsMultiLineString())
            {
                if (elementIndex > sqlGeometry.STNumGeometries())
                {
                    Ext.ThrowInvalidElementIndex();
                }

                if (ringIndex > 1)
                {
                    Ext.ThrowInvalidSubElementIndex();
                }

                return(sqlGeometry.STGeometryN(elementIndex));
            }

            // COMPOUND CURVE
            if (sqlGeometry.IsCompoundCurve())
            {
                if (elementIndex != 1)
                {
                    Ext.ThrowInvalidElementIndex();
                }

                if (ringIndex > 1)
                {
                    Ext.ThrowInvalidSubElementIndex();
                }

                return(sqlGeometry);
            }

            // POLYGON and CURVEPOLYGON
            if (sqlGeometry.IsPolygon() || sqlGeometry.IsCurvePolygon())
            {
                if (elementIndex != 1)
                {
                    Ext.ThrowInvalidElementIndex();
                }

                // if sub element index is zero then return the input geometry
                if (ringIndex == 0)
                {
                    return(sqlGeometry);
                }

                if (ringIndex > sqlGeometry.STNumInteriorRing() + 1)
                {
                    Ext.ThrowInvalidSubElementIndex();
                }

                return(GetPolygon(sqlGeometry, ringIndex));
            }

            // MULTIPOLYGON
            if (sqlGeometry.IsMultiPolygon())
            {
                if (elementIndex == 0 || elementIndex > sqlGeometry.STNumGeometries())
                {
                    Ext.ThrowInvalidElementIndex();
                }

                sqlGeometry = sqlGeometry.STGeometryN(elementIndex);

                // if sub element index is zero then return the input geometry
                if (ringIndex == 0)
                {
                    return(sqlGeometry);
                }

                if (ringIndex > sqlGeometry.STNumInteriorRing() + 1)
                {
                    Ext.ThrowInvalidSubElementIndex();
                }

                return(GetPolygon(sqlGeometry, ringIndex));
            }

            return(sqlGeometry);
        }