示例#1
0
        /// <summary>
        /// Converts a Mapbox feature in Mapbox coordinates into a VectorTileFeature
        /// </summary>
        /// <param name="tileInfo">TileInfo for tile informations like left top coordinates</param>
        /// <param name="layerName">Name of vector tile layer to which this vector tile feature belongs</param>
        /// <param name="feature">Mapbox feature to convert</param>
        /// <param name="keys">List of known keys for this tile</param>
        /// <param name="values">List of known values for this tile</param>
        /// <param name="extent">Extent/width of this Mapbox formated tile (normally 4096)</param>
        /// <param name="scale">Factor for scaling of coordinates because of overzooming</param>
        /// <param name="offsetX">Offset in X direction because of overzooming</param>
        /// <param name="offsetY">Offset in Y direction because of overzooming</param>
        /// <returns></returns>
        public static VectorTileFeature Parse(TileInfo tileInfo, string layerName, Feature feature, List <string> keys, List <Value> values, uint extent, Overzoom overzoom, float scale)
        {
            var vtf = new VectorTileFeature(layerName, feature.Id.ToString());

            var geometries = GeometryParser.ParseGeometry(feature.Geometry, feature.Type, overzoom, scale);

            int i;

            // Add the geometry
            switch (feature.Type)
            {
            case GeomType.Point:
                // Convert all Points
                if (geometries.Count == 1)
                {
                    // Single point
                    vtf.Geometry = new Point(geometries[0][0]);
                }
                else
                {
                    // Multi point
                    var multiPoints = new List <Point>();
                    foreach (var points in geometries)
                    {
                        foreach (var point in points)
                        {
                            multiPoints.Add(new Point(point));
                        }
                    }
                    vtf.Geometry = new MultiPoint(multiPoints.ToArray());
                }
                break;

            case GeomType.LineString:
                // Convert all LineStrings
                if (geometries.Count == 1)
                {
                    // Single line
                    vtf.Geometry = new LineString(geometries[0].ToArray());
                }
                else
                {
                    // Multi line
                    var multiLines = new LineString[geometries.Count];
                    for (i = 0; i < geometries.Count; i++)
                    {
                        multiLines[i] = new LineString(geometries[i].ToArray());
                    }
                    vtf.Geometry = new MultiLineString(multiLines);
                }
                break;

            case GeomType.Polygon:
                // Convert all Polygons
                var polygons = new List <Polygon>();

                LinearRing        polygon = null;
                List <LinearRing> holes   = new List <LinearRing>();

                i = 0;
                do
                {
                    // Check, if first and last are the same points
                    if (!geometries[i].First().Equals(geometries[i].Last()))
                    {
                        geometries[i].Add(geometries[i].First());
                    }

                    // Convert all points of this ring
                    var ring = new LinearRing(geometries[i].ToArray());

                    // We must use CCW instead of CW, because y axis is oriented from up to down.
                    if (ring.IsCCW && polygon != null)
                    {
                        holes.Add(ring);
                    }
                    else
                    {
                        if (polygon != null)
                        {
                            polygons.Add(new Polygon(polygon, holes.ToArray()));
                        }
                        polygon = ring;
                        holes.Clear();
                    }

                    i++;
                } while (i < geometries.Count);

                // Save last one
                polygons.Add(new Polygon(polygon, holes.ToArray()));

                // Now save correct geometry
                if (polygons.Count == 1)
                {
                    vtf.Geometry = polygons[0];
                }
                else
                {
                    vtf.Geometry = new MultiPolygon(polygons.ToArray());
                }
                break;
            }

            // now add the tags
            vtf.Tags.Add(TagsParser.Parse(keys, values, feature.Tags));

            return(vtf);
        }
示例#2
0
        /// <summary>
        /// Parses a unzipped tile in Mapbox format
        /// </summary>
        /// <param name="tileInfo">TileInfo of this tile</param>
        /// <param name="stream">Stream containing tile data in Pbf format</param>
        /// <param name="scale">Factor for scaling of coordinates because of overzooming</param>
        /// <param name="offsetX">Offset in X direction because of overzooming</param>
        /// <param name="offsetY">Offset in Y direction because of overzooming</param>
        /// <returns>List of VectorTileLayers, which contain Name and VectorTilesFeatures of each layer, this tile containing</returns>
        public static IList <VectorTileFeature> Parse(TileInfo tileInfo, Stream stream, Overzoom overzoom, float scale)
        {
            // Get tile information from Pbf format
            var tile = Serializer.Deserialize <Tile>(stream);

            // Create new vector tile layer
            var features = new List <VectorTileFeature>();

            foreach (var layer in tile.Layers)
            {
                // Convert all features from Mapbox format into Mapsui format
                foreach (var feature in layer.Features)
                {
                    var vectorTileFeature = FeatureParser.Parse(tileInfo, layer.Name, feature, layer.Keys, layer.Values, layer.Extent, overzoom, scale);

                    // Add to layer
                    features.Add(vectorTileFeature);
                }
            }

            return(features);
        }
示例#3
0
        /// <summary>
        /// Convert Mapbox tile format (see https://www.mapbox.com/vector-tiles/specification/)
        /// </summary>
        /// <param name="geom">Geometry information in Mapbox format</param>
        /// <param name="geomType">GeometryType of this geometry</param>
        /// <param name="scale">Factor for scaling of coordinates because of overzooming</param>
        /// <param name="offsetX">Offset in X direction because of overzooming</param>
        /// <param name="offsetY">Offset in Y direction because of overzooming</param>
        /// <returns>List of list of points in world coordinates</returns>
        public static List <List <Coordinate> > ParseGeometry(List <uint> geom, GeomType geomType, Overzoom overzoom, float scale)
        {
            const uint cmdMoveTo = 1;
            //const uint cmdLineTo = 2;
            const uint cmdSegEnd = 7;
            //const uint cmdBits = 3;

            long x                   = 0;
            long y                   = 0;
            var  coordsList          = new List <List <Coordinate> >();
            List <Coordinate> coords = null;
            var  geometryCount       = geom.Count;
            uint length              = 0;
            uint command             = 0;
            var  i                   = 0;

            while (i < geometryCount)
            {
                if (length <= 0)
                {
                    length  = geom[i++];
                    command = length & ((1 << 3) - 1);
                    length  = length >> 3;
                }

                if (length > 0)
                {
                    if (command == cmdMoveTo)
                    {
                        coords = new List <Coordinate>();
                        coordsList.Add(coords);
                    }
                }

                if (command == cmdSegEnd)
                {
                    if (geomType != GeomType.Point && coords?.Count != 0)
                    {
                        coords?.Add(coords[0]);
                    }
                    length--;
                    continue;
                }

                var dx = geom[i++];
                var dy = geom[i++];

                length--;

                var ldx = ZigZag.Decode(dx);
                var ldy = ZigZag.Decode(dy);

                x = x + ldx;
                y = y + ldy;

                // Correct coordinates for overzoom
                var coord = new Coordinate((x * overzoom.Scale - overzoom.OffsetX) * scale,
                                           (y * overzoom.Scale - overzoom.OffsetY) * scale);

                coords?.Add(coord);
            }
            return(coordsList);
        }