/** * Constructs a MLineString using the given Coordinates; a null or empty * array will create an empty MLineString. * * @param coordinates * array of MCoordinate defining this geometry's vertices * @see #createLineString(com.vividsolutions.jts.geom.Coordinate[]) * @return An instance of MLineString containing the coordinates */ public MLineString CreateMLineString(MCoordinate[] coordinates) { return CreateMLineString( coordinates != null ? CoordinateSequenceFactory.Create(coordinates) : null); }
public static MCoordinate[] Copy(ICoordinateSequence coordSeq) { MCoordinate[] copy = new MCoordinate[coordSeq.Count]; for (int i = 0; i < coordSeq.Count; i++) { copy[i] = new MCoordinate(coordSeq.GetCoordinate(i)); } return copy; }
public static MCoordinate[] Copy(ICoordinate[] coordinates) { MCoordinate[] copy = new MCoordinate[coordinates.Length]; for (int i = 0; i < coordinates.Length; i++) { copy[i] = new MCoordinate(coordinates[i]); } return copy; }
public MCoordinate(MCoordinate coord) : base(coord) { M = coord.M; }
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; }
/* * (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 }; } }
/* * (non-Javadoc) * * @see org.hibernatespatial.mgeom.IMGeometry#GetCoordinateAtM(double) */ public ICoordinate GetCoordinateAtM(double m) { if (!this.IsMonotone(false)) { throw new ApplicationException("MGeometryException.OPERATION_REQUIRES_MONOTONE"); } if (this.IsEmpty) { return null; } else { double[] mval = this.GetMeasures(); double lb = GetMinM(); double up = GetMaxM(); if (m < lb || m > up) { return null; } else { // determine linesegment that contains M; for (int i = 1; i < mval.Length; i++) { if ((mval[i - 1] <= m && m <= mval[i]) || (mval[i] <= m && m <= mval[i - 1])) { MCoordinate p0 = (MCoordinate)this.GetCoordinateN(i - 1); MCoordinate p1 = (MCoordinate)this.GetCoordinateN(i); // r indicates how far in this segment the M-values lies double r = (m - mval[i - 1]) / (mval[i] - mval[i - 1]); double dx = r * (p1.X - p0.X); double dy = r * (p1.Y - p0.Y); double dz = r * (p1.Z - p0.Z); MCoordinate nc = new MCoordinate( p0.X + dx, p0.Y + dy, p0.Z + dz, m ); return nc; } } } } return null; }
/** * @param co * input coordinate in the neighbourhood of the MLineString * @param tolerance * max. distance that co may be from this MLineString * @return an MCoordinate on this MLineString with appropriate M-value */ public MCoordinate GetClosestPoint(ICoordinate co, double tolerance) { if (!this.IsMonotone(false)) { throw new ApplicationException("MGeometryException.OPERATION_REQUIRES_MONOTONE"); } if (!this.IsEmpty) { LineSegment seg = new LineSegment(); ICoordinate[] coAr = this.Coordinates; seg.P0 = coAr[0]; double d = 0.0; double projfact = 0.0; double minDist = Double.PositiveInfinity; MCoordinate mincp = null; for (int i = 1; i < coAr.Length; i++) { seg.P1 = coAr[i]; ICoordinate cp = seg.ClosestPoint(co); d = cp.Distance(co); if (d <= tolerance && d <= minDist) { MCoordinate testcp = new MCoordinate(cp); projfact = seg.ProjectionFactor(cp); testcp.M = ((MCoordinate)coAr[i - 1]).M + projfact * (((MCoordinate)coAr[i]).M - ((MCoordinate)coAr[i - 1]).M); if (d < minDist || testcp.M < mincp.M) { mincp = testcp; minDist = d; } } seg.P0 = seg.P1; } if (minDist > tolerance) { return null; } else { return mincp; } } else { return null; } }
/** * Copy constructor -- simply aliases the input array, for better * performance. * * @param coordinates */ public MCoordinateSequence(MCoordinate[] coordinates) { this.coordinates = coordinates; }
public Object Clone() { MCoordinate[] cloneCoordinates = new MCoordinate[Count]; for (int i = 0; i < coordinates.Length; i++) { cloneCoordinates[i] = (MCoordinate)coordinates[i].Clone(); } return new MCoordinateSequence(cloneCoordinates); }
/** * Constructs a sequence of a given size, populated with new * {@link MCoordinate}s. * * @param size * the size of the sequence to create */ public MCoordinateSequence(int size) { coordinates = new MCoordinate[size]; for (int i = 0; i < size; i++) { coordinates[i] = new MCoordinate(); } }
/* * (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 }); } }