[fdo-users] MPolygon <-> FDO

djonio djonio at miami-airport.com
Mon Mar 10 10:39:30 EDT 2008


I apoligize to all if this is a duplicate. It appears ... after waiting some
hours, that Oulook/nabble did not like my reply

Gavin,
Sunday night? … you the man!!!

Obviously then, since my users and I are in no mood to move away from Map3d,
the issue: “MPolygon allows rings to be slightly open, while FDO does not.”,
creates some real-world dissonance.

BTW, Saturday I coded up the same method using OSGeo.MapGuide, not one of my
thirteen(13) test cases produced a closed MgCurveString(all produced valid
mgcurvestrings). OSGeo.Geometry produces nine(9) out of thirteen(13)
rings!!! :-) Good thing I didn’t start with the MapGuide API’s! It would
seem the lesson I must learn here is that MG’s definition of “closed” is
different from the other two(2) and I have 3 definitions of “closedness”.

Gee … do ya think I’ve got a problem here?

Ok … back to the real issue. Would you be kind enough to show me what more I
must do to make FDO curves work? I sincerely do not know what else to do to
make the start and end match to reach the FDO definition of closedness.


I know it is redundant but I include the MapGuide code in case you are
interested. (and maybe I am doing it wrong)

public static MgGeometry MGGeometryInterfaceFromMPolygon(MPolygon mpoly) {
	Document doc =
Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
	Editor ed = doc.Editor;
	MgGeometry rtn_geometry = null;
	MgGeometryFactory mggf = new MgGeometryFactory();
	MgCurveRing mgExternalRing = null;
	MgCurveString mgcs_TestCase = null;
	MgArcSegment mgArcSeg;
	MgLinearSegment mgLinearSeg;
	MgCoordinateCollection mgCoorColl = new MgCoordinateCollection();
	MgCurveSegmentCollection mgCurveSegColl = new MgCurveSegmentCollection();
	MgCurveRingCollection mgCurveRingColl = new MgCurveRingCollection();
	if (IsItACurvePolygon(mpoly) == true)
	{
		int loops = mpoly.NumMPolygonLoops;
		for (int i = 0; i < loops; i++)
		{
			MPolygonLoop mPolygonLoop = mpoly.GetMPolygonLoopAt(i);
			Point2d[] pts = new Point2d[mPolygonLoop.Count];
			double[] blgs = new double[mPolygonLoop.Count];
			int z = 0;
			for (; z < mPolygonLoop.Count; z++)
			{
				Point2d tmp_pt;
				if (z == mPolygonLoop.Count - 1)
				{
					pts[z] = pts[0];
				}
				else
				{
					double X = Math.Round(mPolygonLoop[z].Vertex.X, 10,
MidpointRounding.AwayFromZero);
					double Y = Math.Round(mPolygonLoop[z].Vertex.Y, 10,
MidpointRounding.AwayFromZero);
					tmp_pt = new Point2d(X, Y);
					pts[z] = tmp_pt;
				}
				blgs[z] = mPolygonLoop[z].Bulge;
			}

			for (int j = 0; j < mPolygonLoop.Count - 1; j++)
			{
				mgArcSeg = null;
				mgLinearSeg = null;
				double theBulge = blgs[j];
				if (theBulge != 0.0)
				{
					CircularArc2d ca2d = new CircularArc2d(pts[j], pts[j + 1], theBulge,
false);
					MgCoordinate dpi_start = mggf.CreateCoordinateXY(ca2d.StartPoint.X,
ca2d.StartPoint.Y);
					MgCoordinate dpi_end = mggf.CreateCoordinateXY(ca2d.EndPoint.X,
ca2d.EndPoint.Y);
					Point2d midpoint = ca2d.EvaluatePoint(0.5);
					double mp_X = Math.Round(midpoint.X, 10,
MidpointRounding.AwayFromZero);
					double mp_Y = Math.Round(midpoint.Y, 10,
MidpointRounding.AwayFromZero);
					midpoint = new Point2d(mp_X, mp_Y);
					MgCoordinate dpi_center = mggf.CreateCoordinateXY(midpoint.X,
midpoint.Y);
					mgArcSeg = mggf.CreateArcSegment(dpi_start, dpi_end, dpi_center);
				}
				else
				{
					mgCoorColl.Clear();
					MgCoordinate seg_s = mggf.CreateCoordinateXY(pts[j].X, pts[j].Y);
					MgCoordinate seg_e = mggf.CreateCoordinateXY(pts[j + 1].X, pts[j +
1].Y);
					mgCoorColl.Add(seg_s);
					mgCoorColl.Add(seg_e);
					mgLinearSeg = mggf.CreateLinearSegment(mgCoorColl);
				}
				if (mgLinearSeg != null)
					mgCurveSegColl.Add(mgLinearSeg);
				else
					mgCurveSegColl.Add(mgArcSeg);
			} // for vertex count

			mgcs_TestCase = mggf.CreateCurveString(mgCurveSegColl);
			MgCurveRing ring = null;
			if (mgcs_TestCase.IsClosed() == false)
			{
				ed.WriteMessage("\nNotClosed - Valid:{0}  Start:{1},{2} End:{3},{4}",
					mgcs_TestCase.IsValid(),
					mgcs_TestCase.StartCoordinate.X,
					mgcs_TestCase.StartCoordinate.Y,
					mgcs_TestCase.EndCoordinate.X,
					mgcs_TestCase.EndCoordinate.Y
					);
				ring = mggf.CreateCurveRing(mgCurveSegColl);
			}
			else
			{
				ring = mggf.CreateCurveRing(mgCurveSegColl);
			}
			if (i == 0)
			{
				if (ring != null)
					mgExternalRing = ring;
			}
			else
			{
				if (ring != null)
					mgCurveRingColl.Add(ring);
			}
		}// for each loop in the mpolygon
		if (mgcs_TestCase.IsClosed() == true)
			rtn_geometry = mggf.CreateCurvePolygon(mgExternalRing, mgCurveRingColl);
	}
	else
	{
		MgLinearRing mgExternalLinearRing = null;
		MgLinearRing mgLinearRingInner = null;
		
		MgLinearRingCollection mgLinearRingColl = new MgLinearRingCollection();
		int loops = mpoly.NumMPolygonLoops;
		for (int i = 0; i < loops; i++)
		{
			MPolygonLoop mPolygonLoop = mpoly.GetMPolygonLoopAt(i);
			mgCoorColl.Clear();
			foreach (BulgeVertex bv in mPolygonLoop)
			{
				MgCoordinate coor_start = mggf.CreateCoordinateXY(bv.Vertex.X,
bv.Vertex.Y);
				mgCoorColl.Add(coor_start);
			}
			if (i == 0)
			{
				mgExternalLinearRing = mggf.CreateLinearRing(mgCoorColl);
			}
			else
			{
				mgLinearRingInner = mggf.CreateLinearRing(mgCoorColl);
				mgLinearRingColl.Add(mgLinearRingInner);
			}
		}
		rtn_geometry = mggf.CreatePolygon(mgExternalLinearRing, mgLinearRingColl);
	}
	return rtn_geometry;
}


dennis

-----Original Message-----
From: fdo-users-bounces at lists.osgeo.org
[mailto:fdo-users-bounces at lists.osgeo.org] On Behalf Of Gavin Cramer
Sent: Sunday, March 09, 2008 10:02 PM
To: FDO Users Mail List
Subject: RE: [fdo-users] MPolygon <-> FDO

Hi, Dennis.  MPolygon allows rings to be slightly open, while FDO does not. 
Your data contains rings whose starting and ending positions have not been
latched.  Closing any of these slightly open rings will be required during
conversion.  That is all that there needs to be to this issue.

Your examples were useable to create CurveString instances.  However,
creating Ring values will require that the X and Y ordinates of the
start/end positions match.  There are lots of cases where datatype
conversion requires adaptations in conversion code.  In fact, your own code,
which computes the mid positions for arcs, is already such a case.

If you want to make a case for more flexibility should be allowed for the
reading of existing real-world data, you can propose it.  The requirement
for any Z ordinates to match at ring ends was removed in a previous release. 
While the FGF data format does redundantly store starting and ending
positions of rings, changing the matching requirement could introduce
defects in code that assumed the closedness of rings, however.  Plus, some
database formats may still require correctly closed rings, even if FDO does
not catch it.

Gavin

-- 
View this message in context: http://www.nabble.com/MPolygon-%3C-%3E-FDO-tp15873165s18162p15950788.html
Sent from the fdo-users mailing list archive at Nabble.com.



More information about the fdo-users mailing list