예제 #1
0
        public double GetMatCoordinate(ICoordinate co, double tolerance)
        {
            if (!this.IsMonotone(false))
            {
                throw new ApplicationException("MGeometryException.OPERATION_REQUIRES_MONOTONE");
            }

            double mval = Double.NaN;
            double dist = Double.PositiveInfinity;

            IPoint p = this.Factory.CreatePoint(co);

            // find points within tolerance for GetMatCoordinate
            for (int i = 0; i < this.NumGeometries; i++)
            {
                MLineString ml = (MLineString)this.GetGeometryN(i);
                // go to next MLineString if the input point is beyond tolerance
                if (ml.Distance(p) > tolerance)
                {
                    continue;
                }

                MCoordinate mc = ml.GetClosestPoint(co, tolerance);
                if (mc != null)
                {
                    double d = mc.Distance(co);
                    if (d <= tolerance && d < dist)
                    {
                        dist = d;
                        mval = mc.M;
                    }
                }
            }
            return(mval);
        }
예제 #2
0
 public static MultiMLineString GetLinearGeometry(IMGeometry lrs, double begin, double end)
 {
     MGeometryFactory factory = (MGeometryFactory) lrs.Factory;
     ICoordinateSequence[] cs = lrs.GetCoordinatesBetween(begin, end);
     MLineString[] mlar = new MLineString[cs.Length];
     for (int i = 0; i < cs.Length; i++) {
         MLineString ml = factory.CreateMLineString(cs[i]);
         mlar[i] = ml;
     }
     return factory.CreateMultiMLineString(mlar);
 }
예제 #3
0
        public static MultiMLineString GetLinearGeometry(IMGeometry lrs, double begin, double end)
        {
            MGeometryFactory factory = (MGeometryFactory)lrs.Factory;

            ICoordinateSequence[] cs   = lrs.GetCoordinatesBetween(begin, end);
            MLineString[]         mlar = new MLineString[cs.Length];
            for (int i = 0; i < cs.Length; i++)
            {
                MLineString ml = factory.CreateMLineString(cs[i]);
                mlar[i] = ml;
            }
            return(factory.CreateMultiMLineString(mlar));
        }
예제 #4
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);
        }
예제 #5
0
        /*
         * (non-Javadoc)
         *
         * @see org.hibernatespatial.mgeom.IMGeometry#GetMaxM()
         */
        public double GetMaxM()
        {
            double maxM = Double.NegativeInfinity;

            for (int i = 0; i < this.NumGeometries; i++)
            {
                MLineString ml = (MLineString)this.GetGeometryN(i);
                double      d  = ml.GetMaxM();
                if (d < maxM)
                {
                    maxM = d;
                }
            }
            return(maxM);
        }
예제 #6
0
        /*
         * (non-Javadoc)
         *
         * @see org.hibernatespatial.mgeom.IMGeometry#GetMinM()
         */
        public double GetMinM()
        {
            double minM = Double.PositiveInfinity;

            for (int i = 0; i < this.NumGeometries; i++)
            {
                MLineString ml = (MLineString)this.GetGeometryN(i);
                double      d  = ml.GetMinM();
                if (d < minM)
                {
                    minM = d;
                }
            }
            return(minM);
        }
예제 #7
0
        public void MeasureOnLength(bool keepBeginMeasure)
        {
            double startM = 0.0;

            for (int i = 0; i < this.NumGeometries; i++)
            {
                MLineString ml = (MLineString)this.GetGeometryN(i);
                if (i == 0)
                {
                    ml.MeasureOnLength(keepBeginMeasure);
                }
                else
                {
                    ml.MeasureOnLength(false);
                }
                if (startM != 0.0)
                {
                    ml.ShiftMeasure(startM);
                }
                startM += ml.Length + mGap;
            }
            this.GeometryChanged();
        }
예제 #8
0
        public ICoordinateSequence[] GetCoordinatesBetween(double begin, double end)
        {
            if (!this.IsMonotone(false))
            {
                throw new ApplicationException("MGeometryException.OPERATION_REQUIRES_MONOTONE");
            }

            if (this.IsEmpty)
            {
                return(null);
            }

            List <ICoordinateSequence> ar = new List <ICoordinateSequence>();

            for (int i = 0; i < this.NumGeometries; i++)
            {
                MLineString ml = (MLineString)this.GetGeometryN(i);
                foreach (ICoordinateSequence cs in ml.GetCoordinatesBetween(begin, end))
                {
                    ar.Add(cs);
                }
            }
            return(ar.ToArray());
        }
예제 #9
0
        /**
         * TODO Improve this, and add more unit tests
         */
        private void DetermineMonotone()
        {
            this.monotone       = true;
            this.strictMonotone = true;
            if (this.IsEmpty)
            {
                return;
            }
            MGeometryType mdir = ((MLineString)this.geometries[0]).GetMeasureDirection();

            for (int i = 0; i < this.geometries.Length; i++)
            {
                MLineString ml = (MLineString)this.geometries[i];
                // check whether mlinestrings are all pointing in same direction,
                // and
                // are monotone
                if (!ml.IsMonotone(false) ||
                    (ml.GetMeasureDirection() != mdir && !(ml
                                                           .GetMeasureDirection() == MGeometryType.Constant)))
                {
                    this.monotone = false;
                    break;
                }

                if (!ml.IsMonotone(true) || (ml.GetMeasureDirection() != mdir))
                {
                    this.strictMonotone = false;
                    break;
                }

                // check whether the geometry measures do not overlap or
                // are inconsistent with previous parts
                if (i > 0)
                {
                    MLineString mlp = (MLineString)this.geometries[i - 1];
                    if (mdir == MGeometryType.Increasing)
                    {
                        if (mlp.GetMaxM() > ml.GetMinM())
                        {
                            monotone = false;
                        }
                        else if (mlp.GetMaxM() >= ml.GetMinM())
                        {
                            strictMonotone = false;
                        }
                    }
                    else
                    {
                        if (mlp.GetMinM() < ml.GetMaxM())
                        {
                            monotone = false;
                        }
                        else if (mlp.GetMinM() <= ml.GetMaxM())
                        {
                            strictMonotone = false;
                        }
                    }
                }
            }
            if (!monotone)
            {
                this.strictMonotone = false;
            }
        }
		/**
		 * @param MlineStrings
		 *            the <code>MLineString</code>s for this
		 *            <code>MultiMLineString</code>, or <code>null</code> or an
		 *            empty array to create the empty geometry. Elements may be
		 *            empty <code>LineString</code>s, but not <code>null</code>s.
		 */
		public MultiMLineString(MLineString[] MlineStrings, double mGap, IGeometryFactory factory)
			: base(MlineStrings, factory)
		{
			this.mGap = mGap;
			DetermineMonotone();
		}
예제 #11
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;
		}
		public MultiMLineString CreateMultiMLineString(MLineString[] mlines)
		{
			return new MultiMLineString(mlines, 0.0d, this);
		}
		public MultiMLineString CreateMultiMLineString(MLineString[] mlines, double mGap)
		{
			return new MultiMLineString(mlines, mGap, this);
		}