private VectorTileLayer getLayer(byte[] data)
        {
            VectorTileLayer layer       = new VectorTileLayer(data);
            PbfReader       layerReader = new PbfReader(layer.Data);

            while (layerReader.NextByte())
            {
                int layerType = layerReader.Tag;
                if (_Validate)
                {
                    if (!ConstantsAsDictionary.LayerType.ContainsKey(layerType))
                    {
                        throw new System.Exception(string.Format("Unknown layer type: {0}", layerType));
                    }
                }
                switch ((LayerType)layerType)
                {
                case LayerType.Version:
                    ulong version = (ulong)layerReader.Varint();
                    layer.Version = version;
                    break;

                case LayerType.Name:
                    ulong strLength = (ulong)layerReader.Varint();
                    layer.Name = layerReader.GetString(strLength);
                    break;

                case LayerType.Extent:
                    layer.Extent = (ulong)layerReader.Varint();
                    break;

                case LayerType.Keys:
                    byte[] keyBuffer = layerReader.View();
                    string key       = Encoding.UTF8.GetString(keyBuffer, 0, keyBuffer.Length);
                    layer.Keys.Add(key);
                    break;

                case LayerType.Values:
                    byte[]    valueBuffer = layerReader.View();
                    PbfReader valReader   = new PbfReader(valueBuffer);
                    while (valReader.NextByte())
                    {
                        switch ((ValueType)valReader.Tag)
                        {
                        case ValueType.String:
                            byte[] stringBuffer = valReader.View();
                            string value        = Encoding.UTF8.GetString(stringBuffer, 0, stringBuffer.Length);
                            layer.Values.Add(value);
                            break;

                        case ValueType.Float:
                            float snglVal = valReader.GetFloat();
                            layer.Values.Add(snglVal);
                            break;

                        case ValueType.Double:
                            double dblVal = valReader.GetDouble();
                            layer.Values.Add(dblVal);
                            break;

                        case ValueType.Int:
                            long i64 = valReader.Varint();
                            layer.Values.Add(i64);
                            break;

                        case ValueType.UInt:
                            long u64 = valReader.Varint();
                            layer.Values.Add(u64);
                            break;

                        case ValueType.SInt:
                            long s64 = valReader.Varint();
                            layer.Values.Add(s64);
                            break;

                        case ValueType.Bool:
                            long b = valReader.Varint();
                            layer.Values.Add(b == 1);
                            break;

                        default:
                            throw new System.Exception(string.Format(
                                                           NumberFormatInfo.InvariantInfo
                                                           , "NOT IMPLEMENTED valueReader.Tag:{0} valueReader.WireType:{1}"
                                                           , valReader.Tag
                                                           , valReader.WireType
                                                           ));
                            //uncomment the following lines when not throwing!!
                            //valReader.Skip();
                            //break;
                        }
                    }
                    break;

                case LayerType.Features:
                    layer.AddFeatureData(layerReader.View());
                    break;

                default:
                    layerReader.Skip();
                    break;
                }
            }

            if (_Validate)
            {
                if (string.IsNullOrEmpty(layer.Name))
                {
                    throw new System.Exception("Layer has no name");
                }
                if (0 == layer.Version)
                {
                    throw new System.Exception(string.Format("Layer [{0}] has invalid version. Only version 2.x of 'Mapbox Vector Tile Specification' (https://github.com/mapbox/vector-tile-spec) is supported.", layer.Name));
                }
                if (2 != layer.Version)
                {
                    throw new System.Exception(string.Format("Layer [{0}] has invalid version: {1}. Only version 2.x of 'Mapbox Vector Tile Specification' (https://github.com/mapbox/vector-tile-spec) is supported.", layer.Name, layer.Version));
                }
                if (0 == layer.Extent)
                {
                    throw new System.Exception(string.Format("Layer [{0}] has no extent.", layer.Name));
                }
                if (0 == layer.FeatureCount())
                {
                    throw new System.Exception(string.Format("Layer [{0}] has no features.", layer.Name));
                }
                //TODO: find equivalent of 'Distinct()' for NET20
#if !NET20
                if (layer.Values.Count != layer.Values.Distinct().Count())
                {
                    throw new System.Exception(string.Format("Layer [{0}]: duplicate attribute values found", layer.Name));
                }
#endif
            }

            return(layer);
        }
Ejemplo n.º 2
0
        public static int Main(string[] args)
        {
            string vtIn       = string.Empty;
            uint?  clipBuffer = null;
            bool   outGeoJson = false;
            ulong? zoom       = null;
            ulong? tileCol    = null;
            ulong? tileRow    = null;

            for (int i = 0; i < args.Length; i++)
            {
                string argLow = args[i].ToLower();
                if (argLow.Contains("vt:"))
                {
                    vtIn = argLow.Replace("vt:", "");
                }
                else if (argLow.Contains("clip:"))
                {
                    clipBuffer = Convert.ToUInt32(argLow.Replace("clip:", ""));
                }
                else if (argLow.Contains("out:"))
                {
                    outGeoJson = argLow.Replace("out:", "").Equals("geojson");
                }
                else if (argLow.Contains("tileid:"))
                {
                    parseArg(argLow.Replace("tileid:", ""), out zoom, out tileCol, out tileRow);
                }
            }

            if (!File.Exists(vtIn))
            {
                Console.WriteLine($"file [{vtIn}] not found");
                usage();
                return(1);
            }

            // z-x-y weren't passed via parameters, try to get them from file name
            if (!zoom.HasValue || !tileCol.HasValue || !tileRow.HasValue)
            {
                if (!parseArg(Path.GetFileName(vtIn), out zoom, out tileCol, out tileRow))
                {
                    usage();
                    return(1);
                }
            }

            var bufferedData = File.ReadAllBytes(vtIn);

            VectorTile tile = new VectorTile(bufferedData);

            if (outGeoJson)
            {
                Console.WriteLine(tile.ToGeoJson(zoom.Value, tileCol.Value, tileRow.Value, clipBuffer));
            }
            else
            {
                foreach (string lyrName in tile.LayerNames())
                {
                    VectorTileLayer lyr = tile.GetLayer(lyrName);
                    Console.WriteLine(string.Format("------------ {0} ---------", lyrName));
                    //if (lyrName != "building") { continue; }
                    int featCnt = lyr.FeatureCount();
                    for (int i = 0; i < featCnt; i++)
                    {
                        VectorTileFeature feat = lyr.GetFeature(i, clipBuffer);
                        Console.WriteLine(string.Format("feature {0}: {1}", i, feat.GeometryType));
                        Dictionary <string, object> props = feat.GetProperties();
                        foreach (var prop in props)
                        {
                            Console.WriteLine(string.Format("   {0}\t : ({1}) {2}", prop.Key, prop.Value.GetType(), prop.Value));
                        }
                    }
                }
            }

            return(0);
        }