Example #1
0
        public override bool HandleGeometry(IGeometryHandler handler)
        {
            var decoder = new GeometryDecoder(feature, layer);

            // From https://github.com/mapbox/vector-tile-spec/tree/master/2.1
            //
            // The POINT geometry type encodes a point or multipoint geometry. The geometry command sequence for a point
            // geometry MUST consist of a single MoveTo command with a command count greater than 0.
            //
            // The LINESTRING geometry type encodes a linestring or multilinestring geometry. The geometry command sequence
            // for a linestring geometry MUST consist of one or more repetitions of the following sequence:
            //   1. A MoveTo command with a command count of 1
            //   2. A LineTo command with a command count greater than 0
            //
            // The POLYGON geometry type encodes a polygon or multipolygon geometry, each polygon consisting of exactly one
            // exterior ring that contains zero or more interior rings. The geometry command sequence for a polygon consists
            // of one or more repetitions of the following sequence:
            //   1. An ExteriorRing
            //   2. Zero or more InteriorRings
            // Each ExteriorRing and InteriorRing MUST consist of the following sequence:
            //   1. A MoveTo command with a command count of 1
            //   2. A LineTo command with a command count greater than 1
            //   3. A ClosePath command

            switch (feature.Type)
            {
            case PbfGeomType.Point:
                if (decoder.AdvanceCommand() && decoder.Command == CommandType.MoveTo)
                {
                    for (int i = 0; i < decoder.Repeat; i++)
                    {
                        decoder.AdvanceCursor();
                        handler.OnPoint(decoder.CurrentPoint());
                    }
                }
                break;

            case PbfGeomType.LineString:
                while (decoder.AdvanceCommand() && (decoder.Command == CommandType.MoveTo && decoder.Repeat == 1))
                {
                    decoder.AdvanceCursor();
                    if (decoder.AdvanceCommand() && (decoder.Command == CommandType.LineTo && decoder.Repeat > 0))
                    {
                        handler.OnBeginLineString();
                        handler.OnPoint(decoder.CurrentPoint());
                        for (int i = 0; i < decoder.Repeat; i++)
                        {
                            decoder.AdvanceCursor();
                            handler.OnPoint(decoder.CurrentPoint());
                        }
                        handler.OnEndLineString();
                    }
                }
                break;

            case PbfGeomType.Polygon:
                while (decoder.AdvanceCommand() && (decoder.Command == CommandType.MoveTo && decoder.Repeat == 1))
                {
                    handler.OnBeginPolygon();
                    decoder.AdvanceCursor();
                    if (decoder.AdvanceCommand() && (decoder.Command == CommandType.LineTo && decoder.Repeat > 0))
                    {
                        handler.OnBeginLinearRing();
                        var start = decoder.CurrentPoint();
                        handler.OnPoint(start);
                        for (int i = 0; i < decoder.Repeat; i++)
                        {
                            decoder.AdvanceCursor();
                            handler.OnPoint(decoder.CurrentPoint());
                        }
                        handler.OnPoint(start);
                        handler.OnEndLinearRing();
                    }
                    if (decoder.AdvanceCommand() && decoder.Command == CommandType.ClosePath)
                    {
                        // We should assert that this condition holds.
                    }
                    handler.OnEndPolygon();
                }
                break;

            case PbfGeomType.Unknown:
                break;
            }
            return(true);
        }