// This is where the real work is done.
        public void AddLine(double x, double y, double?z, double?m)
        {
            // If we've already found a point, then we're done.  We just need to keep ignoring these
            // pesky calls.
            if (_foundPoint != null)
            {
                return;
            }

            // Make a point for our current position.
            var thisPoint = CheckShapePointAndGet(m, Ext.GetPoint(x, y, z, m, _srid));

            // is the found point between this point and the last, or past this point?
            if (m != null && _measure.IsWithinRange(_lastPoint.M.Value, m.Value))
            {
                // now we need to do the hard work and find the point in between these two
                _foundPoint = Functions.LRS.Geometry.InterpolateBetweenGeom(_lastPoint, thisPoint, _measure);
                if (_lastPoint.IsWithinTolerance(_foundPoint, _tolerance))
                {
                    _foundPoint  = _lastPoint;
                    IsShapePoint = true;
                }
                else if (thisPoint.IsWithinTolerance(_foundPoint, _tolerance))
                {
                    _foundPoint  = thisPoint;
                    IsShapePoint = true;
                }
            }
            else
            {
                // it's past this point---just step along the line
                _lastPoint = thisPoint;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Utility Method for removing the consecutive duplicate vertices
        /// </summary>
        /// <param name="geometry"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public static SqlGeometry RemoveDuplicateVertices(SqlGeometry geometry, double tolerance = Constants.Tolerance)
        {
            if (!geometry.STIsValid())
            {
                Ext.ThrowIfInvalidGeometry();
            }

            return(geometry.Reduce(tolerance));
        }
        // Start the figure.  Note that since we only operate on LineStrings, this should only be executed
        // once.
        public void BeginFigure(double x, double y, double?z, double?m)
        {
            if (_foundPoint != null)
            {
                return;
            }

            // Memorize the point.
            _lastPoint = CheckShapePointAndGet(m, Ext.GetPoint(x, y, z, m, _srid));
        }
Exemplo n.º 4
0
        // This is where the real work is done.
        public void AddLine(double x, double y, double?z, double?m)
        {
            // To unify code for ascending and descending measures - clipPointMeasure
            double?clipPointMeasure = GetClipPointMeasure(m);
            double newX, newY;

            // If current measure is between start measure and end measure,
            // we should add segment to the result linestring
            if (m.IsWithinRange(_clipStartMeasure, _clipEndMeasure))
            {
                // if the geometry is started, just add the point to line
                if (_started)
                {
                    _target.AddLine(x, y, z, m);
                }
                // Else we need to begin the geom figure first
                else
                {
                    var isShapePoint = false;
                    // if clip point is shape point measure then add the point without computation
                    if (m.EqualsTo(clipPointMeasure))
                    {
                        _target.BeginFigure(x, y, null, m);
                        isShapePoint = true;
                    }
                    else
                    {
                        ComputePointCoordinates(clipPointMeasure, m, x, y, out newX, out newY);

                        // if computed point is within tolerance of last point then begin figure with last point
                        if (Ext.IsWithinTolerance(_previousX, _previousY, newX, newY, _tolerance))
                        {
                            _target.BeginFigure(_previousX, _previousY, null, _retainClipMeasure ? _clipStartMeasure : _previousM);
                        }

                        // check with current point against new computed point
                        else if (Ext.IsWithinTolerance(x, y, newX, newY, _tolerance))
                        {
                            _target.BeginFigure(x, y, null, m);
                            isShapePoint = true;
                        }

                        // else begin figure with clipped point
                        else
                        {
                            _target.BeginFigure(newX, newY, null, clipPointMeasure);
                        }
                    }

                    _started = true;
                    if (_clipStartMeasure.EqualsTo(_clipEndMeasure) || isShapePoint)
                    {
                        UpdateLastPoint(x, y, m);
                        return;
                    }

                    _target.AddLine(x, y, z, m);
                }
            }
            // We may still need to add last segment,
            // if current point is the first one after we passed range of interest
            else
            {
                if (!_started)
                {
                    var isShapePoint = false;
                    if (clipPointMeasure.IsWithinRange(m, _previousM))
                    {
                        ComputePointCoordinates(clipPointMeasure, m, x, y, out newX, out newY);

                        // if computed point is within tolerance of last point then begin figure with last point
                        if (Ext.IsWithinTolerance(_previousX, _previousY, newX, newY, _tolerance))
                        {
                            _target.BeginFigure(_previousX, _previousY, null, _retainClipMeasure ? clipPointMeasure : _previousM);
                        }
                        // check with current point against new computed point
                        else if (Ext.IsWithinTolerance(x, y, newX, newY, _tolerance))
                        {
                            _target.BeginFigure(x, y, null, _retainClipMeasure ? clipPointMeasure : m);
                            isShapePoint = true;
                        }
                        // else begin figure with clipped point
                        else
                        {
                            _target.BeginFigure(newX, newY, null, clipPointMeasure);
                        }

                        _started = true;
                        if (_clipStartMeasure.EqualsTo(_clipEndMeasure) || isShapePoint)
                        {
                            UpdateLastPoint(x, y, m);
                            return;
                        }
                    }
                }
                if (_started && !_finished)
                {
                    // re calculate clip point measure as it can be changed from above condition.
                    clipPointMeasure = GetClipPointMeasure(m);

                    if (clipPointMeasure.IsWithinRange(m, _previousM))
                    {
                        ComputePointCoordinates(clipPointMeasure, m, x, y, out newX, out newY);

                        var isWithinLastPoint    = Ext.IsWithinTolerance(_previousX, _previousY, newX, newY, _tolerance);
                        var isWithinCurrentPoint = Ext.IsWithinTolerance(x, y, newX, newY, _tolerance);

                        // if computed point is within tolerance of last point then skip
                        if (!isWithinLastPoint)
                        {
                            // if within current point then add current point
                            if (isWithinCurrentPoint)
                            {
                                _target.AddLine(x, y, null, _retainClipMeasure ? clipPointMeasure : m);
                            }
                            // else add computed point
                            else
                            {
                                _target.AddLine(newX, newY, null, clipPointMeasure);
                            }
                        }

                        _finished = true;
                    }
                }
            }

            // re-assign the current co-ordinates to match for next iteration.
            UpdateLastPoint(x, y, m);
        }
Exemplo n.º 5
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);
        }