Пример #1
0
        private async void Map_MapTapped(int tileX, int tileY, int zoomLevel)
        {
            float canvasScale = 1f;
            float canvasSize  = 768;
            float lineScale   = 1f;

            //int zoomLevel = Math.Min(14, Math.Max(1, (int)sender.ZoomLevel));
            //var tileAddr = MapUtil.WorldToTilePos(args.Location.Position.Longitude, args.Location.Position.Latitude, zoomLevel);
            System.Diagnostics.Debug.WriteLine($"{tileX} x {tileY}");
            System.Diagnostics.Debug.WriteLine($"zoom: {zoomLevel}");
            {
                var reader = await db.GetTile((int)tileX, (int)tileY, zoomLevel);

                if (!reader.HasRows)
                {
                    textOutput.Text = DateTime.Now + ": No data";
                }
                var tile = VectorTile.Parse(reader);
                if (tile.tile_data_raw != null)
                {
                    PBF pbf = new PBF(tile.tile_data_raw);
                    currentTile = ProtoBuf.Serializer.Deserialize <Tile>(new MemoryStream(tile.tile_data_raw));

                    if (GeometryDecoder.CanvasTileId != tile.id)
                    {
                        GeometryDecoder.CanvasTileId = tile.id;

                        if (GeometryDecoder.offscreen == null)
                        {
                            CanvasDevice device = CanvasDevice.GetSharedDevice();
                            GeometryDecoder.offscreen = new CanvasRenderTarget(device, canvasSize, canvasSize, Windows.Graphics.Display.DisplayInformation.GetForCurrentView().LogicalDpi *canvasScale);
                            //GeometryDecoder.offscreenText = new CanvasRenderTarget(device, canvasSize, canvasSize, Windows.Graphics.Display.DisplayInformation.GetForCurrentView().LogicalDpi * canvasScale);
                        }


                        //Performance benchmark
                        Tile.Layer layer_buildings           = null;
                        Tile.Layer layer_landcover           = null;
                        Tile.Layer layer_transportation      = null;
                        Tile.Layer layer_transportation_name = null;
                        Tile.Layer layer_housenumber         = null;
                        Tile.Layer layer_poi = null;

                        if (currentTile.Layers.Any(l => l.Name == "building"))
                        {
                            layer_buildings = currentTile.Layers.Where(l => l.Name == "building").ToList()?.First();
                        }
                        if (currentTile.Layers.Any(l => l.Name == "landcover"))
                        {
                            layer_landcover = currentTile.Layers.Where(l => l.Name == "landcover").ToList()?.First();
                        }
                        if (currentTile.Layers.Any(l => l.Name == "transportation"))
                        {
                            layer_transportation = currentTile.Layers.Where(l => l.Name == "transportation").ToList()?.First();
                        }
                        if (currentTile.Layers.Any(l => l.Name == "transportation_name"))
                        {
                            layer_transportation_name = currentTile.Layers.Where(l => l.Name == "transportation_name").ToList()?.First();
                        }
                        if (currentTile.Layers.Any(l => l.Name == "housenumber"))
                        {
                            layer_housenumber = currentTile.Layers.Where(l => l.Name == "housenumber").ToList()?.First();
                        }
                        if (currentTile.Layers.Any(l => l.Name == "poi"))
                        {
                            layer_poi = currentTile.Layers.Where(l => l.Name == "poi").ToList()?.First();
                        }

                        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
                        stopwatch.Start();

                        Dictionary <string, Windows.UI.Color> landColors = new Dictionary <string, Windows.UI.Color>();
                        landColors.Add("grass", Windows.UI.Colors.LawnGreen);
                        landColors.Add("meadow", Windows.UI.Colors.Green);
                        landColors.Add("wood", Windows.UI.Colors.ForestGreen);
                        landColors.Add("forest", Windows.UI.Colors.DarkGreen);
                        landColors.Add("park", Windows.UI.Colors.LightGreen);
                        landColors.Add("village_green", Windows.UI.Colors.GreenYellow);
                        landColors.Add("wetland", Windows.UI.Colors.CornflowerBlue);
                        landColors.Add("recreation_ground", Windows.UI.Colors.LightYellow);
                        landColors.Add("allotments", Windows.UI.Colors.Red);

                        Dictionary <string, Tuple <Color, float, Color, float> > roadProperties = new Dictionary <string, Tuple <Color, float, Color, float> >();
                        roadProperties.Add("transit", new Tuple <Color, float, Color, float>(Colors.Black, 0.5f, Colors.Black, 0.5f));
                        roadProperties.Add("primary", new Tuple <Color, float, Color, float>(Colors.LightYellow, 3, Colors.SandyBrown, 4.5f));
                        roadProperties.Add("secondary", new Tuple <Color, float, Color, float>(Colors.LightYellow, 2, Colors.SandyBrown, 3f));
                        roadProperties.Add("tertiary", new Tuple <Color, float, Color, float>(Colors.LightYellow, 2, Colors.SandyBrown, 3f));
                        roadProperties.Add("minor", new Tuple <Color, float, Color, float>(Colors.WhiteSmoke, 1.8f, Colors.Gray, 2.5f));
                        roadProperties.Add("service", new Tuple <Color, float, Color, float>(Colors.WhiteSmoke, 1.8f, Colors.Gray, 2.5f));
                        roadProperties.Add("track", new Tuple <Color, float, Color, float>(Colors.LightGray, 1, Colors.Gray, 2));
                        roadProperties.Add("path", new Tuple <Color, float, Color, float>(Colors.LightGray, 1, Colors.Gray, 2));
                        roadProperties.Add("rail", new Tuple <Color, float, Color, float>(Colors.Gainsboro, 0.75f, Colors.DimGray, 1.4f));
                        roadProperties.Add("motorway", new Tuple <Color, float, Color, float>(Colors.Orange, 3, Colors.Red, 4.5f));
                        roadProperties.Add("trunk", new Tuple <Color, float, Color, float>(Colors.Orange, 3, Colors.Red, 4.5f));


                        GeometryDecoder.renderList = new CanvasCommandList(GeometryDecoder.offscreen);
                        GeometryDecoder.renderText = new CanvasCommandList(GeometryDecoder.offscreen);

                        //using (CanvasDrawingSession ds = GeometryDecoder.offscreen.CreateDrawingSession())
                        using (CanvasDrawingSession textDs = GeometryDecoder.renderText.CreateDrawingSession())
                            using (CanvasDrawingSession ds = GeometryDecoder.renderList.CreateDrawingSession())
                                using (CanvasActiveLayer activeLayer = ds.CreateLayer(1, new Rect(0, 0, canvasSize, canvasSize)))
                                    using (CanvasActiveLayer activeTextLayer = textDs.CreateLayer(1, new Rect(0, 0, canvasSize, canvasSize)))
                                    {
                                        ds.Antialiasing = CanvasAntialiasing.Antialiased;
                                        ds.Clear(Windows.UI.Colors.Snow);
                                        for (int it = 0; it < 1; it++)
                                        {
                                            layer_landcover?.Features.ForEach(f =>
                                            {
                                                var tags  = GeometryDecoder.GetTags(f, layer_landcover);
                                                var color = Colors.LightGreen;
                                                if (tags.ContainsKey("subclass"))
                                                {
                                                    color = landColors.ContainsKey(tags["subclass"].StringValue) ? landColors[tags["subclass"].StringValue] : Windows.UI.Colors.LightGreen;
                                                }
                                                GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, color, color);
                                            });

                                            layer_buildings?.Features.ForEach(f =>
                                            {
                                                var tags = GeometryDecoder.GetTags(f, layer_buildings);
                                                GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, Windows.UI.Colors.SandyBrown, Windows.UI.Colors.Brown);
                                            });


                                            List <string> tagsNames = new List <string>();
                                            var           names     = layer_transportation?.Features.ConvertAll <Tuple <string, string> >(f =>
                                            {
                                                var tags = GeometryDecoder.GetTags(f, layer_transportation);

                                                foreach (var t in tags)
                                                {
                                                    tagsNames.Add(t.Key);
                                                }
                                                return(new Tuple <string, string>(tags.ContainsKey("class") ? tags["class"].StringValue : "", tags.ContainsKey("subclass") ? tags["subclass"].StringValue : ""));
                                            }).ToList().Distinct().ToList();

                                            var distinctTagsNames = tagsNames.Distinct().ToList();

                                            Tuple <Color, float, Color, float> rc = new Tuple <Color, float, Color, float>(Colors.Pink, 2, Colors.DeepPink, 2);


                                            Dictionary <int, List <Tile.Feature> > transportationFeatures = new Dictionary <int, List <Tile.Feature> >();
                                            foreach (var f in layer_transportation.Features)
                                            {
                                                var tags  = GeometryDecoder.GetTags(f, layer_transportation);
                                                int layer = tags.ContainsKey("layer") ? (int)tags["layer"].IntValue : 0;
                                                if (!transportationFeatures.ContainsKey(layer))
                                                {
                                                    transportationFeatures.Add(layer, new List <Tile.Feature>());
                                                }
                                                transportationFeatures[layer].Add(f);
                                            }

                                            foreach (int layerNo in transportationFeatures.Keys.OrderBy(k => k))
                                            {
                                                //background / stroke pass
                                                foreach (var f in transportationFeatures[layerNo])
                                                {
                                                    var tags = GeometryDecoder.GetTags(f, layer_transportation);

                                                    if (tags.ContainsKey("class"))
                                                    {
                                                        if (roadProperties.ContainsKey(tags["class"].StringValue))
                                                        {
                                                            var p = roadProperties[tags["class"].StringValue];
                                                            GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, p.Item1, p.Item3, 0, p.Item4 * lineScale, layerNo > 0 ? GeometryDecoder.openStrokeStyle : GeometryDecoder.normalStrokeStyle);
                                                        }
                                                        else
                                                        {
                                                            GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, rc.Item1, rc.Item3, 0, rc.Item4 * lineScale, GeometryDecoder.normalStrokeStyle);
                                                        }
                                                    }
                                                    else
                                                    {
                                                        GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, rc.Item1, rc.Item3, 0, rc.Item4 * lineScale, GeometryDecoder.normalStrokeStyle);
                                                    }
                                                }

                                                //foreground / fill pass
                                                foreach (var f in transportationFeatures[layerNo])
                                                {
                                                    var tags = GeometryDecoder.GetTags(f, layer_transportation);
                                                    if (tags.ContainsKey("class"))
                                                    {
                                                        if (roadProperties.ContainsKey(tags["class"].StringValue))
                                                        {
                                                            var p = roadProperties[tags["class"].StringValue];
                                                            if (tags["class"].StringValue == "rail" || tags["class"].StringValue == "transit")
                                                            {
                                                                GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, p.Item1, p.Item3, p.Item2 * lineScale, 0, GeometryDecoder.railStrokeStyle);
                                                                //												System.Diagnostics.Debug.WriteLine(t)
                                                            }
                                                            else
                                                            {
                                                                GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, p.Item1, p.Item3, p.Item2 * lineScale, 0, GeometryDecoder.normalStrokeStyle);
                                                            }
                                                        }
                                                        else
                                                        {
                                                            System.Diagnostics.Debug.WriteLine($"Unsupported class: {tags["class"]}");
                                                            GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, rc.Item1, rc.Item3, rc.Item2 * lineScale, 0, GeometryDecoder.normalStrokeStyle);
                                                        }
                                                    }
                                                    else
                                                    {
                                                        GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, rc.Item1, rc.Item3, rc.Item2 * lineScale, 0, GeometryDecoder.normalStrokeStyle);
                                                    }
                                                }
                                            }



                                            //								layer_transportation?.Features.ForEach(f =>
                                            //								{
                                            //									var tags = GeometryDecoder.GetTags(f, layer_transportation);

                                            //									if (tags.ContainsKey("class"))
                                            //									{
                                            //										if (roadProperties.ContainsKey(tags["class"].StringValue))
                                            //										{
                                            //											var p = roadProperties[tags["class"].StringValue];
                                            //											GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, p.Item1, p.Item3, 0, p.Item4 * lineScale);
                                            //										}
                                            //										else
                                            //										{
                                            //											GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, rc.Item1, rc.Item3, 0, rc.Item4 * lineScale);
                                            //										}
                                            //									}
                                            //									else
                                            //										GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, rc.Item1, rc.Item3, 0, rc.Item4 * lineScale);
                                            //								});

                                            //								layer_transportation?.Features.ForEach(f =>
                                            //								{
                                            //									var tags = GeometryDecoder.GetTags(f, layer_transportation);
                                            //									if (tags.ContainsKey("class"))
                                            //									{
                                            //										if (roadProperties.ContainsKey(tags["class"].StringValue))
                                            //										{
                                            //											var p = roadProperties[tags["class"].StringValue];
                                            //											if (tags["class"].StringValue == "rail")
                                            //											{
                                            //												GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, p.Item1, p.Item3, p.Item2 * lineScale, 0, GeometryDecoder.railStrokeStyle);
                                            ////												System.Diagnostics.Debug.WriteLine(t)
                                            //											}
                                            //											else
                                            //												GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, p.Item1, p.Item3, p.Item2 * lineScale, 0);
                                            //										}
                                            //										else
                                            //										{
                                            //											System.Diagnostics.Debug.WriteLine($"Unsupported class: {tags["class"]}");
                                            //											GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, rc.Item1, rc.Item3, rc.Item2 * lineScale, 0);
                                            //										}
                                            //									}
                                            //									else
                                            //										GeometryDecoder.DrawGeometry(f, canvasSize / 4096f, ds, rc.Item1, rc.Item3, rc.Item2 * lineScale, 0);
                                            //								});



                                            layer_housenumber?.Features.ForEach(f =>
                                            {
                                                var tags    = GeometryDecoder.GetTags(f, layer_housenumber);
                                                string text = tags["housenumber"].StringValue;
                                                //GeometryDecoder.DrawHousenumber(f, canvasSize / 4096f, textDs, Colors.Black, Colors.White, 1, 1.2f, text);
                                                GeometryDecoder.DrawText(f, canvasSize / 4096f, textDs, Colors.Black, Colors.White, 1, 1.2f, text, 2f);
                                            });

                                            layer_poi?.Features.ForEach(f => {
                                                var tags = GeometryDecoder.GetTags(f, layer_poi);
                                                if (tags.ContainsKey("subclass"))
                                                {
                                                    string subclass = tags["subclass"].StringValue;
                                                    if (icons.ContainsKey(subclass + "_11"))
                                                    {
                                                        GeometryDecoder.DrawIcon(f, canvasSize / 4096f, ds, icons[subclass + "_11"], Colors.Black, Colors.DarkGray);
                                                    }
                                                }
                                            });


                                            layer_transportation_name?.Features.ForEach(f =>
                                            {
                                                var tags = GeometryDecoder.GetTags(f, layer_transportation_name);
                                                if (tags.ContainsKey("name"))
                                                {
                                                    string text = tags["name"].StringValue;
                                                    GeometryDecoder.DrawText(f, canvasSize / 4096f, textDs, Colors.Black, Colors.White, 1, 1.2f, text, 3f);
                                                }
                                            });
                                        }
                                    }
                        //StorageFolder storageFolder = KnownFolders.PicturesLibrary;
                        //StorageFile file = await storageFolder.CreateFileAsync("map.bmp", CreationCollisionOption.ReplaceExisting);
                        //var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite);
                        //await GeometryDecoder.offscreen.SaveAsync(stream, CanvasBitmapFileFormat.Bmp);
                        //stream.Dispose();



                        stopwatch.Stop();


                        System.Diagnostics.Debug.WriteLine($"TIME: {stopwatch.ElapsedMilliseconds} ms");
                        textOutput.Text = $"TIME: {stopwatch.ElapsedMilliseconds} ms";
                    }
                }
                else
                {
                    currentTile = null;
                }
            }

            win2dCanvas.Invalidate();
        }