/*
		 * (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 };
			}
		}
Exemple #2
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 });
            }
        }