public static IGeometry FromShapeMsg([CanBeNull] ShapeMsg shapeBuffer, [CanBeNull] ISpatialReference classSpatialRef = null) { if (shapeBuffer == null) { return(null); } if (shapeBuffer.FormatCase == ShapeMsg.FormatOneofCase.None) { return(null); } IGeometry result; switch (shapeBuffer.FormatCase) { case ShapeMsg.FormatOneofCase.EsriShape: if (shapeBuffer.EsriShape.IsEmpty) { return(null); } result = GeometryUtils.FromEsriShapeBuffer(shapeBuffer.EsriShape.ToByteArray()); break; case ShapeMsg.FormatOneofCase.Wkb: WkbGeometryReader wkbReader = new WkbGeometryReader(); result = wkbReader.ReadGeometry( new MemoryStream(shapeBuffer.Wkb.ToByteArray())); break; case ShapeMsg.FormatOneofCase.Envelope: result = FromEnvelopeMsg(shapeBuffer.Envelope); break; default: throw new NotImplementedException( $"Unsupported format: {shapeBuffer.FormatCase}"); } result.SpatialReference = FromSpatialReferenceMsg(shapeBuffer.SpatialReference, classSpatialRef); return(result); }
public void CanConvertMultipatchWithOuterInnerRingSequence() { ISpatialReference sr = SpatialReferenceUtils.CreateSpatialReference( WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95); IRing outerRing0 = GeometryUtils.GetRings( GeometryFactory.CreatePolygon( 2601000, 1200000, 2602000, 1201000, 432)) .Single(); outerRing0.SpatialReference = sr; IRing outerRing1 = GeometryUtils.GetRings( GeometryFactory.CreatePolygon( 2600000, 1200000, 2601000, 1201000, 432)) .Single(); outerRing1.SpatialReference = sr; IRing innerRing = GeometryFactory.CreateRing(new[] { new WKSPointZ() { X = 2600100, Y = 1200100, Z = 432 }, new WKSPointZ() { X = 2600200, Y = 1200100, Z = 432 }, new WKSPointZ() { X = 2600200, Y = 1200200, Z = 432 }, new WKSPointZ() { X = 2600100, Y = 1200200, Z = 432 }, new WKSPointZ() { X = 2600100, Y = 1200100, Z = 432 }, }); innerRing.SpatialReference = sr; IMultiPatch multipatch = GeometryFactory.CreateEmptyMultiPatch(outerRing0); object emptyRef = Type.Missing; ((IGeometryCollection)multipatch).AddGeometry(outerRing0, ref emptyRef, ref emptyRef); multipatch.PutRingType(outerRing0, esriMultiPatchRingType.esriMultiPatchFirstRing); ((IGeometryCollection)multipatch).AddGeometry(outerRing1, ref emptyRef, ref emptyRef); multipatch.PutRingType(outerRing1, esriMultiPatchRingType.esriMultiPatchOuterRing); ((IGeometryCollection)multipatch).AddGeometry(innerRing, ref emptyRef, ref emptyRef); multipatch.PutRingType(innerRing, esriMultiPatchRingType.esriMultiPatchInnerRing); WkbGeometryWriter writer = new WkbGeometryWriter(); byte[] wkb = writer.WriteMultipatch(multipatch); WkbGeometryReader reader = new WkbGeometryReader(); IGeometry rehydrated = reader.ReadGeometry(new MemoryStream(wkb)); Assert.IsTrue(GeometryUtils.AreEqual(multipatch, rehydrated)); }
public void CanReadWriteMultipartPolygonXyz() { ISpatialReference sr = SpatialReferenceUtils.CreateSpatialReference( WellKnownHorizontalCS.LV95, WellKnownVerticalCS.LHN95); IPolygon outerRing = GeometryFactory.CreatePolygon(2600000, 1200000, 2601000, 1201000, 432); outerRing.SpatialReference = sr; IPolygon innerRing = GeometryFactory.CreatePolygon(2600100, 1200100, 2600200, 1200200, 421); innerRing.SpatialReference = sr; IPolygon polyWithHole = (IPolygon)IntersectionUtils.Difference(outerRing, innerRing); IPolygon poly2 = GeometryFactory.CreatePolygon(2610000, 1200000, 2611000, 1201000, 543); poly2.SpatialReference = sr; IPolygon multiPolygon = (IPolygon)GeometryUtils.Union(polyWithHole, poly2); Assert.IsTrue(GeometryUtils.IsZAware(multiPolygon)); GeometryUtils.Simplify(multiPolygon); WkbGeometryWriter writer = new WkbGeometryWriter(); byte[] wkb = writer.WritePolygon(multiPolygon); // Wkx var ordinates = Ordinates.Xyz; IList <IGeometry> parts = GeometryUtils.GetParts(multiPolygon).ToList(); IGeometry exteriorRing = parts[0]; IGeometry interiorRing = parts[1]; IGeometry secondExteriorRing = parts[2]; LinearRing wkxOuterRing = ToWkxLinearRing(exteriorRing, ordinates); LinearRing wkxInnerRing = ToWkxLinearRing(interiorRing, ordinates); Polygon wkxPolygon1 = ToWkxPolygon(wkxOuterRing, new[] { wkxInnerRing }); Polygon wkxPolygon2 = ToWkxPolygon(ToWkxLinearRing(secondExteriorRing, ordinates)); MultiPolygon wkxMultiPolygon = new MultiPolygon(new[] { wkxPolygon1, wkxPolygon2 }); byte[] wkx = ToChristianSchwarzWkb(wkxMultiPolygon); Assert.AreEqual(wkx, wkb); // Bonus test: Geom WkbGeomWriter geomWriter = new WkbGeomWriter(); MultiPolycurve multiPly = GeometryConversionUtils.CreateMultiPolycurve(multiPolygon); byte[] wkbGeom = geomWriter.WriteMultipolygon(multiPly, ordinates); Assert.AreEqual(wkb, wkbGeom); WkbGeometryReader reader = new WkbGeometryReader(); IPolygon restored = reader.ReadPolygon(new MemoryStream(wkb)); Assert.IsTrue(GeometryUtils.AreEqual(multiPolygon, restored)); // Geom: WkbGeomReader geomReader = new WkbGeomReader(); IList <RingGroup> readMultiPolygon = geomReader.ReadMultiPolygon(new MemoryStream(wkbGeom)); var readMultiPolycurve = new MultiPolycurve( readMultiPolygon.SelectMany(g => g.GetLinestrings())); Assert.IsTrue(multiPly.Equals(readMultiPolycurve)); // As multipatch IMultiPatch multipatch = GeometryFactory.CreateMultiPatch(multiPolygon); wkb = writer.WriteMultipatch(multipatch); IMultiPatch readMultipatch = (IMultiPatch)reader.ReadGeometry(new MemoryStream(wkb)); // TODO: Implement AreEqual for multipatch that is more permissive regarding First/Outer ring type AssertEqual(multipatch, readMultipatch); }