In ArcObjects there is the IZAware interface we can use to make an existing 2D geometry aware of Z-values. I can't find the equivalent in the ArcGIS Pro SDK -- but there must be a way to do this. How can I, for example, change a polyline that may include a parametric curve from a 2D polyline to a 3D polyline?
geometries are immutable. to convert 2d to 3d u will need a builder. In your specific example, you will need a PolygonBuilderEx . Note that is has a HasZ property which is get and set. There is also a constructor overload that takes a polyline as its input.
Lots of examples here in the Geometry snippets. Ctrl-F "PolylineBuilderEx"
Right. I've looked at the examples in the Geometry snippets, but none seems to completely satisfy the need to ensure all components are z-aware. I could get all the points from the source polyline, update them to 3-D and re-create the polyline as 3-D, but that would lose any parametric curves.
If you set HasZ = true in the builder, then all start and end points will have the HasZ property set to true too. Here is some code to set the z-values in the points while still preserving the curve segments.
/////////////////////////////////
LineSegment line = LineBuilderEx.CreateLineSegment(new Coordinate2D(0, 0), new Coordinate2D(3, 3));
MapPoint start = MapPointBuilderEx.CreateMapPoint(3, 3);
MapPoint end = MapPointBuilderEx.CreateMapPoint(7, 3);
Coordinate2D center = new Coordinate2D(5, 5);
EllipticArcSegment arc = EllipticArcBuilderEx.CreateCircularArc(start, end, center, ArcOrientation.ArcCounterClockwise);
Polyline polyline = PolylineBuilderEx.CreatePolyline(new Segment[] { line, arc });
Assert.IsFalse(polyline.HasZ);
PolylineBuilderEx polylineBuilder = new PolylineBuilderEx(polyline);
polylineBuilder.HasZ = true;
Polyline polyline3D = polylineBuilder.ToGeometry();
var points = polyline3D.Points;
foreach (MapPoint p in points)
Assert.IsTrue(p.HasZ);
var part = polyline3D.Parts[0];
int numSegments = part.Count;
for (int i = 0; i < numSegments; i++)
{
Segment segment = part[i];
MapPointBuilderEx pointBuilder = new MapPointBuilderEx(segment.StartPoint);
pointBuilder.Z = i + 1;
MapPoint startPoint = pointBuilder.ToGeometry();
pointBuilder = new MapPointBuilderEx(segment.EndPoint);
pointBuilder.Z = i + 2;
MapPoint endPoint = pointBuilder.ToGeometry();
SegmentType segmentType = segment.SegmentType;
SegmentBuilderEx segmentBuilder = null;
switch (segmentType)
{
case SegmentType.Line:
segmentBuilder = new LineBuilderEx((LineSegment)segment);
break;
case SegmentType.Bezier:
segmentBuilder = new CubicBezierBuilderEx((CubicBezierSegment)segment);
break;
case SegmentType.EllipticArc:
segmentBuilder = new EllipticArcBuilderEx((EllipticArcSegment)segment);
break;
}
segmentBuilder.StartPoint = startPoint;
segmentBuilder.EndPoint = endPoint;
segment = segmentBuilder.ToSegment();
polylineBuilder.ReplaceSegment(0, i, segment);
}
polyline3D = polylineBuilder.ToGeometry();
/////////////////////////////////
Annette -
Pretty interesting. I will give this a try. Thanks much!
Ed