Example #1
0
 /**
  * Calculates whether the measures in the CoordinateSequence are monotone
  * and strict monotone. The strict parameter indicates whether the
  * determination should apply the definition of "strict monotonicity" or
  * non-strict.
  *
  * @see #IsMonotone()
  * @see #isStrictMonotone()
  */
 private void DetermineMonotone()
 {
     this.monotone       = true;
     this.strictMonotone = true;
     if (!this.IsEmpty)
     {
         double[] m = this.GetMeasures();
         // short circuit if the first value is NaN
         if (Double.IsNaN(m[0]))
         {
             this.monotone       = false;
             this.strictMonotone = false;
         }
         else
         {
             int result     = 0;
             int prevResult = 0;
             for (int i = 1; i < m.Length && this.monotone; i++)
             {
                 result               = DoubleComparator.Compare(m[i - 1], m[i]);
                 this.monotone        = !(result * prevResult < 0 || Double.IsNaN(m[i]));
                 this.strictMonotone &= this.monotone && result != 0;
                 prevResult           = result;
             }
         }
     }
     // if not monotone, then certainly not strictly monotone
     Debug.Assert(!(this.strictMonotone && !this.monotone));
 }
Example #2
0
        public bool Equals3DWithMeasure(Coordinate other)
        {
            bool result = this.Equals3D(other);

            if (result)
            {
                MCoordinate mc = ConvertCoordinate(other);
                result = (DoubleComparator.Compare(M, mc.M) == 0);
            }
            return(result);
        }
Example #3
0
        public MLineString UnionM(MLineString l)
        {
            if (!this.monotone || !l.monotone)
            {
                throw new ApplicationException("MGeometryException.OPERATION_REQUIRES_MONOTONE");
            }
            ICoordinate[] linecoar = l.Coordinates;
            if (l.GetMeasureDirection() == MGeometryType.Decreasing)
            {
                CoordinateArrays.Reverse(linecoar);
            }
            ICoordinate[] thiscoar = this.Coordinates;
            if (this.GetMeasureDirection() == MGeometryType.Decreasing)
            {
                CoordinateArrays.Reverse(thiscoar);
            }

            // either the last coordinate in thiscoar Equals the first in linecoar;
            // or the last in linecoar Equals the first in thiscoar;
            MCoordinate lasttco  = (MCoordinate)thiscoar[thiscoar.Length - 1];
            MCoordinate firsttco = (MCoordinate)thiscoar[0];
            MCoordinate lastlco  = (MCoordinate)linecoar[linecoar.Length - 1];
            MCoordinate firstlco = (MCoordinate)linecoar[0];

            MCoordinate[] newcoar = new MCoordinate[thiscoar.Length
                                                    + linecoar.Length - 1];
            if (lasttco.Equals2D(firstlco) &&
                DoubleComparator.Equals(lasttco.M, firstlco.M))
            {
                Array.Copy(thiscoar, 0, newcoar, 0, thiscoar.Length);
                Array.Copy(linecoar, 1, newcoar, thiscoar.Length,
                           linecoar.Length - 1);
            }
            else if (lastlco.Equals2D(firsttco) &&
                     DoubleComparator.Equals(lastlco.M, firsttco.M))
            {
                Array.Copy(linecoar, 0, newcoar, 0, linecoar.Length);
                Array.Copy(thiscoar, 1, newcoar, linecoar.Length,
                           thiscoar.Length - 1);
            }
            else
            {
                throw new ApplicationException("MGeometryException.UNIONM_ON_DISJOINT_MLINESTRINGS");
            }

            ICoordinateSequence mcs = this.Factory.CoordinateSequenceFactory.Create(newcoar);
            MLineString         returnmlinestring = new MLineString(mcs, this.Factory);

            Debug.Assert(returnmlinestring.IsMonotone(false), "new UnionM-ed MLineString is not monotone");
            return(returnmlinestring);
        }
Example #4
0
        /**
         * Assigns the first coordinate in the CoordinateSequence to the
         * <code>beginMeasure</code> and the last coordinate in the
         * CoordinateSequence to the <code>endMeasure</code>. Measure values for
         * intermediate coordinates are then interpolated proportionally based on
         * their 2d offset of the overall 2d length of the LineString.
         * <p>
         * If the beginMeasure and endMeasure values are equal it is assumed that
         * all intermediate coordinates shall be the same value.
         *
         * @param beginMeasure
         *            Measure value for first coordinate
         * @param endMeasure
         *            Measure value for last coordinate
         */
        public void Interpolate(double beginMeasure, double endMeasure)
        {
            if (this.IsEmpty)
            {
                return;
            }
            // interpolate with first vertex = beginMeasure; last vertex =
            // endMeasure
            ICoordinate[] coordinates = this.Coordinates;
            double        length      = this.Length;
            double        mLength     = endMeasure - beginMeasure;
            double        d           = 0;
            bool          continuous  = DoubleComparator.Equals(beginMeasure, endMeasure);
            double        m           = beginMeasure;
            MCoordinate   prevCoord   = MCoordinate.ConvertCoordinate(coordinates[0]);

            prevCoord.M = m;
            MCoordinate curCoord;

            for (int i = 1; i < coordinates.Length; i++)
            {
                curCoord = MCoordinate.ConvertCoordinate(coordinates[i]);
                if (continuous)
                {
                    curCoord.M = beginMeasure;
                }
                else
                {
                    d         += curCoord.Distance(prevCoord);
                    m          = beginMeasure + (d / length) * mLength;
                    curCoord.M = m;
                    prevCoord  = curCoord;
                }
            }
            this.GeometryChanged();
            Debug.Assert(this.IsMonotone(false), "interpolate function should always leave IMGeometry monotone");
        }
Example #5
0
        /*
         * (non-Javadoc)
         *
         * @see org.hibernatespatial.mgeom.IMGeometry#GetCoordinatesBetween(double,double)
         */
        public ICoordinateSequence[] GetCoordinatesBetween(double fromM, double toM)
        {
            if (!this.IsMonotone(false))
            {
                throw new ApplicationException("MGeometryException.OPERATION_REQUIRES_MONOTONE");
            }

            if (this.IsEmpty || !this.IsMonotone(false))
            {
                return(new MCoordinateSequence[0]);
            }
            else
            {
                double[] mval = this.GetMeasures();

                // determin upper and lower boundaries for the MLineString Measures
                double lb = Math.Min(mval[0], mval[mval.Length - 1]);
                double up = Math.Max(mval[0], mval[mval.Length - 1]);

                // set fromM and toM to maximal/minimal values when they exceed
                // lowerbound-upperbound
                fromM = Math.Max(lb, Math.Min(fromM, up));
                toM   = Math.Max(lb, Math.Min(toM, up));

                // if at this point the fromM and toM are equal, then return an
                // empty MCoordinateSequence
                if (DoubleComparator.Equals(fromM, toM))
                {
                    return(new MCoordinateSequence[0]);
                }
                MCoordinate[] mcoords = (MCoordinate[])this.Coordinates;
                // ensure that we traverse the coordinate array in ascending M-order
                if (GetMeasureDirection() == MGeometryType.Decreasing)
                {
                    CoordinateArrays.Reverse(mcoords);
                }

                double             minM    = Math.Min(fromM, toM);
                double             maxM    = Math.Max(fromM, toM);
                List <MCoordinate> mcolist = new List <MCoordinate>();
                for (int i = 0; i < mcoords.Length; i++)
                {
                    if (mcolist.Count == 0 && mcoords[i].M >= minM)
                    {
                        MCoordinate mco2 = mcoords[i];
                        if (DoubleComparator.Equals(mcoords[i].M, minM))
                        {
                            mcolist.Add(mco2);
                        }
                        else
                        {
                            MCoordinate mco1 = mcoords[i - 1];
                            double      r    = (minM - mco1.M) / (mco2.M - mco1.M);
                            Debug.Assert(DoubleComparator.Equals(mco1.M + r * (mco2.M - mco1.M), minM), "Error on assumption on r");
                            MCoordinate mc = new MCoordinate(
                                mco1.X + r * (mco2.X - mco1.X),
                                mco1.Y + r * (mco2.Y - mco1.Y),
                                mco1.Z + r * (mco2.Z - mco1.Z),
                                minM);
                            mcolist.Add(mc);
                        }
                    }
                    else if (mcoords[i].M >= minM && mcoords[i].M <= maxM)
                    {
                        mcolist.Add(mcoords[i]);
                        if (DoubleComparator.Equals(mcoords[i].M, maxM))
                        {
                            break;
                        }
                    }
                    else if (mcoords[i].M > maxM)
                    {
                        // mcoords[i] > Math.max(fromM, toM
                        Debug.Assert(i > 0, "mistaken assumption");
                        MCoordinate mco2 = mcoords[i];
                        MCoordinate mco1 = mcoords[i - 1];
                        double      r    = (maxM - mco1.M) / (mco2.M - mco1.M);
                        MCoordinate mc   = new MCoordinate(
                            mco1.X + r * (mco2.X - mco1.X),
                            mco1.Y + r * (mco2.Y - mco1.Y),
                            mco1.Z + r * (mco2.Z - mco1.Z),
                            maxM
                            );
                        mcolist.Add(mc);
                        break;
                    }
                }
                // copy over, but only to the length of numPnts
                MCoordinate[] h = new MCoordinate[mcolist.Count];
                for (int i = 0; i < mcolist.Count; i++)
                {
                    h[i] = (MCoordinate)mcolist[i];
                }

                if (!DoubleComparator.Equals(minM, fromM))
                {
                    CoordinateArrays.Reverse(h);
                }

                MCoordinateSequence mc2 = new MCoordinateSequence(h);
                return(new MCoordinateSequence[] { mc2 });
            }
        }