Пример #1
0
        public void TestCustemProjection()
        {
            var services = new ServiceCollection();

            services.AddSingleton <ILoggerFactory>(new LoggerFactory().AddConsole(LogLevel.Trace));

            services.AddNodeServices((o) =>
            {
                o.ProjectPath = PlatformServices.Default.Application.ApplicationBasePath + "/../../..";
            });

            var serviceProvider = services.BuildServiceProvider();
            var node            = serviceProvider.GetService <INodeServices>();


            var p1       = new[] { 12.62929948218958, 55.661805096493985 };
            var proj4Str = $"+proj=tmerc +lat_0={p1[1]} +lon_0={p1[0]} +x_0=0 +y_0=0 +towgs84=0,0,0,0,0,0,0 +units=m +vunits=m +no_defs";
            var extent   = new[] { -20000.0, -20000, 20000, 20000 };


            var tileConverter = new VectorTileConverter(new VectorTileConverterOptions
            {
                CoordinateTransform = async(p) =>
                {
                    var local = await node.InvokeAsync <double[]>("./proj4", "EPSG:4326", proj4Str, p);

                    return(new double[] { (local[0] - extent[0]) / (extent[2] - extent[0]), -(local[1] - extent[3]) / (extent[3] - extent[1]), 0 });
                }
            });


            var p2 = tileConverter.ProjectPoint(p1);

            Assert.AreEqual(0.5, p2[0], 10e-6, $"X {nameof(TestCustemProjection)} expected to be 0.5");
            Assert.AreEqual(0.5, p2[1], 10e-6, $"Y {nameof(TestCustemProjection)} expected to be 0.5");
            {
                var bottomLeft = tileConverter.ProjectPoint(node.InvokeAsync <double[]>("./proj4", proj4Str, "EPSG:4326", new[] { extent[0], extent[1] }).GetAwaiter().GetResult());

                Assert.AreEqual(0, bottomLeft[0], 10e-6, $"X {nameof(TestCustemProjection)} {nameof(bottomLeft)} expected to be 0");
                Assert.AreEqual(1, bottomLeft[1], 10e-6, $"Y {nameof(TestCustemProjection)}  {nameof(bottomLeft)} expected to be 1");
            }
            {
                var topLeft = tileConverter.ProjectPoint(node.InvokeAsync <double[]>("./proj4", proj4Str, "EPSG:4326", new[] { extent[0], extent[3] }).GetAwaiter().GetResult());

                Assert.AreEqual(0, topLeft[0], 10e-6, $"X {nameof(TestCustemProjection)} {nameof(topLeft)} expected to be 0");
                Assert.AreEqual(0, topLeft[1], 10e-6, $"Y {nameof(TestCustemProjection)}  {nameof(topLeft)} expected to be 0");
            }
            {
                var topRight = tileConverter.ProjectPoint(node.InvokeAsync <double[]>("./proj4", proj4Str, "EPSG:4326", new[] { extent[2], extent[3] }).GetAwaiter().GetResult());

                Assert.AreEqual(1, topRight[0], 10e-6, $"X {nameof(TestCustemProjection)} {nameof(topRight)} expected to be 1");
                Assert.AreEqual(0, topRight[1], 10e-6, $"Y {nameof(TestCustemProjection)}  {nameof(topRight)} expected to be 0");
            }
            {
                var bottomRight = tileConverter.ProjectPoint(node.InvokeAsync <double[]>("./proj4", proj4Str, "EPSG:4326", new[] { extent[2], extent[1] }).GetAwaiter().GetResult());

                Assert.AreEqual(1, bottomRight[0], 10e-6, $"X {nameof(TestCustemProjection)} {nameof(bottomRight)} expected to be 1");
                Assert.AreEqual(1, bottomRight[1], 10e-6, $"Y {nameof(TestCustemProjection)}  {nameof(bottomRight)} expected to be 1");
            }
        }
 public GeoJsonVectorTiles(ILoggerFactory loggerFactory, T options = null, VectorTileConverter converter = null, VectorTileWrapper wrapper = null, VectorTileClipper clipper = null, VectorTileTransformer transformer = null)
 {
     Logger      = loggerFactory.CreateLogger <GeoJsonVectorTiles <T> >();
     Converter   = converter ?? new VectorTileConverter();
     Clipper     = clipper ?? new VectorTileClipper();
     Wrapper     = wrapper ?? new VectorTileWrapper(Clipper);
     Options     = options ?? new T();
     Transformer = transformer ?? new VectorTileTransformer();
     Tiles       = Options.Tiles ?? new DefaultTileStore();
 }
Пример #3
0
        public void TestBottomRightLatLng()
        {
            var tileConverter = new VectorTileConverter();

            var p1 = new[] { 180.0, -90.0 };
            var p2 = tileConverter.ProjectPoint(p1);

            Assert.AreEqual(1, p2[0], $"Longtitude {nameof(TestBottomRightLatLng)} Test expected to be 1");
            Assert.AreEqual(1, p2[1], $"Latitude {nameof(TestBottomRightLatLng)} expected to be 1");
        }
Пример #4
0
        public void TestTopLeftLatLng()
        {
            var tileConverter = new VectorTileConverter();

            var p1 = new[] { -180.0, 90.0 };
            var p2 = tileConverter.ProjectPoint(p1);

            Assert.AreEqual(0, p2[0], $"Longtitude {nameof(TestTopLeftLatLng)} Test expected to be 0");
            Assert.AreEqual(0, p2[1], $"Latitude {nameof(TestTopLeftLatLng)} expected to be 0");
        }
Пример #5
0
        private static async Task RunAsync(string[] args, CancellationToken cannelcationtoken)
        {
            var services = new ServiceCollection();

            services.AddSingleton <ILoggerFactory>(new LoggerFactory().AddConsole(LogLevel.Trace));
            services.AddTransient <GeoJsonVectorTiles <GeoJsonVectorTilesOptions> >();


            services.AddNodeServices((o) =>
            {
                o.ProjectPath = Directory.GetCurrentDirectory(); // PlatformServices.Default.Application.ApplicationBasePath + "/../../..";
            });



            var serviceProvider = services.BuildServiceProvider();
            var node            = serviceProvider.GetService <INodeServices>();
            var logger          = serviceProvider.GetService <ILoggerFactory>().CreateLogger <Program>();


            var proj4Str = args[Array.IndexOf(args, "--proj") + 1];
            var extent   = args.Skip(Array.IndexOf(args, "--extent") + 1).Take(4).Select(double.Parse).ToArray();

            var maxZoom = 0;
            var max     = (extent[2] - extent[0]) / 4096.0;

            while (max > 0.01)
            {
                max /= 2;
                maxZoom++;
            }

            maxZoom = 22;

            var tileConverter = new VectorTileConverter(new VectorTileConverterOptions
            {
                CoordinateTransform = async(p) =>
                {
                    var local = await node.InvokeAsync <double[]>("./proj4", "EPSG:4326", proj4Str, p);

                    return(new double[] { (local[0] - extent[0]) / (extent[2] - extent[0]), -(local[1] - extent[3]) / (extent[3] - extent[1]), 0 });
                }
            });

            services.AddSingleton(new GeoJsonVectorTilesOptions()
            {
                MaxZoom = maxZoom
            });
            services.AddSingleton(tileConverter);
            serviceProvider = services.BuildServiceProvider();


            var points = File.ReadAllText(args[0]);

            var featureCollection = JsonConvert.DeserializeObject <GeoJsonObject>(points, new GeoJsonObjectConverter()) as GeoJsonFeatureCollection;


            var processor = serviceProvider.GetRequiredService <GeoJsonVectorTiles <GeoJsonVectorTilesOptions> >();

            processor.ProcessData(featureCollection);


            var q = new Queue <VectorTileCoord>(); q.Enqueue(new VectorTileCoord(0, 0, 0));

            while (q.Any())
            {
                var tileCoord = q.Dequeue();
                var tile      = processor.GetTile(tileCoord.Z, tileCoord.X, tileCoord.Y);

                if (tile != null && tileCoord.Z < maxZoom && tile.Features.Count > 10)
                {
                    logger.LogInformation("[{tileZ},{tileX},{tileY}] : Finding clusters for {featureCount}",
                                          tileCoord.Z, tileCoord.X, tileCoord.Y, tile.Features.Count);


                    List <ClusterId> centers = GetCenters(tile);
                    logger.LogInformation("[{tileZ},{tileX},{tileY}] : {clusterCount}|{singlePointCount}  clusters found for {featureCount} features",
                                          tileCoord.Z, tileCoord.X, tileCoord.Y, centers.Count, centers.Count(c => c.Features.Count == 1), tile.Features.Count);

                    if (centers.Any() && centers.Count < tile.Features.Count)
                    {
                        foreach (var child in tileCoord.GetChildCoordinate())
                        {
                            q.Enqueue(child);
                        }
                    }



                    tile.Features = new List <VectorTileFeature>();
                    foreach (var center in centers)
                    {
                        if (center.Features.Count == 1)
                        {
                            tile.Features.AddRange(center.Features);
                        }
                        else
                        {
                            tile.Features.Add(new VectorTileFeature
                            {
                                Type     = 1,
                                Geometry = new VectorTileGeometry()
                                {
                                    new[] {
                                        Math.Round(center.Features.Average(f => f.GetPoints().First()[0])),
                                        Math.Round(center.Features.Average(f => f.GetPoints().First()[1]))
                                    }
                                },
                                Tags = new Dictionary <string, object>
                                {
                                    { "clusterId", Guid.NewGuid().ToString() },
                                    { "count", center.Features.Count }
                                }
                            });
                        }
                    }
                }

                //  tile = tile ?? new VectorTile { X = tileCoord.X, Y = tileCoord.Y, Z2 = 1 << tileCoord.Z, Features = new List<VectorTileFeature>(), Transformed = true };

                if (tile != null)
                {
                    logger.LogInformation("[{tileZ},{tileX},{tileY}] : Writing tile with {featureCount}",
                                          tileCoord.Z, tileCoord.X, tileCoord.Y, tile.Features.Count);

                    var file = $"{args[1]}/{tileCoord.Z}/{tileCoord.X}/{tileCoord.Y}.vector.pbf";
                    Directory.CreateDirectory(Path.GetDirectoryName(file));

                    var stream = await node.InvokeAsync <NodeBuffer>("./topbf",
                                                                     new VectorTile { Features = tile.Features, X = tile.X, Y = tile.Y, Z2 = tile.Z2, Transformed = tile.Transformed }, file);



                    // File.WriteAllBytes(file+".pbf", stream.Data);


                    // return;
                }
            }
        }
Пример #6
0
        static async Task Main(string[] args)
        {
            var host = new WebHostBuilder()
                       .UseKestrel()
                       .ConfigureServices((ctx, appservices) =>
            {
                appservices.AddMvc();
            })
                       .Configure(app =>
            {
                app.UseDeveloperExceptionPage();

                //app.UseDirectoryBrowser(new DirectoryBrowserOptions
                //{
                //    FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "tmp")),

                //});
                app.UseStaticFiles(new StaticFileOptions
                {
                    FileProvider          = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "tmp")),
                    ServeUnknownFileTypes = true,
                    ContentTypeProvider   = new FileExtensionContentTypeProvider(new Dictionary <string, string> {
                        { ".vector.pdf", "vectorfile" }
                    })
                });

                app.UseMvc();
            })
                       .Build();

            await host.RunAsync();

            var services = new ServiceCollection();

            services.AddSingleton(new LoggerFactory().AddConsole(LogLevel.Trace));
            services.AddTransient <GeoJsonVectorTiles <GeoJsonVectorTilesOptions> >();


            services.AddNodeServices((o) =>
            {
                o.ProjectPath = Directory.GetCurrentDirectory(); // PlatformServices.Default.Application.ApplicationBasePath + "/../../..";
            });



            var maxZoom = 6;

            var serviceProvider = services.BuildServiceProvider();
            var node            = serviceProvider.GetService <INodeServices>();
            var logger          = serviceProvider.GetService <ILoggerFactory>().CreateLogger <Program>();

            var tileConverter = new VectorTileConverter();

            services.AddSingleton(new GeoJsonVectorTilesOptions()
            {
                MaxZoom = maxZoom, Buffer = 256
            });
            services.AddSingleton(tileConverter);
            serviceProvider = services.BuildServiceProvider();



            var points = File.ReadAllText(args[0]);

            var featureCollection = JsonConvert.DeserializeObject <GeoJsonObject>(points, new GeoJsonObjectConverter()) as GeoJsonFeatureCollection;

            //    featureCollection.Features = featureCollection.Features.Where(f => f.Geometry is Polygon).ToArray();
            foreach (var feature in featureCollection.Features)
            {
                feature.Properties = new Dictionary <string, object>
                {
                    { "tileId", Regex.Replace(feature.Properties["_font_COLOR_000000_TILE_ID_font"] as string, "<[^>]+>", string.Empty) }
                };
            }



            // var pointsList = new PointsList();
            // var features = featureCollection.Features.Where(f => f.Geometry is Point).ToArray();
            // for (uint i = 0; i < features.Length; i++)
            // {
            //     pointsList.AddPoint(i, (features[i].Geometry as Point).Coordinates);
            // }

            // double maxRadius = 0.1;
            // int minPoints = features.Length / 25;
            // var optics = new OPTICS(maxRadius, minPoints, pointsList);

            // optics.BuildReachability();

            // var reachablity = optics.ReachabilityPoints().GroupBy(k => k.Reachability);
            //var featuresList = new List<GeoJsonFeature>();
            // foreach (var item in reachablity)
            // {
            //     Console.WriteLine($"{item.Key}: {item.Count()} - {string.Join(",", item.Select(k => k.PointId))}");

            //     var hull = t.ComputeConvexHull(item.Select(k => features[k.PointId]).Select(k => (k.Geometry as Point).Coordinates));


            //     featuresList.Add(new GeoJsonFeature
            //     {
            //         //Type = 3,
            //         Geometry = new Polygon { Coordinates = new double[][][] { hull.ToArray() } },
            //         Properties = new Dictionary<string, object>
            //                      {
            //                          { "tileId", Math.Round( item.Key,2)},
            //                          {"count", item.Count() }
            //                      }
            //     });

            //     // Console.WriteLine(item.PointId + ";" + item.Reachability);
            // }
            // featureCollection.Features = featuresList.ToArray();


            //var clusters = featureCollection.Features.Where(f => f.Geometry is Polygon).GroupBy(f => (f.Properties["tileId"] as string).Substring(0, 3));
            //var fl = new List<GeoJsonFeature>();
            //foreach (var cluster in clusters)
            //{
            //    var b = cluster.SelectMany(c => (c.Geometry as Polygon).Coordinates[0]);
            //    var meanX = b.Select(b1 => b1[0]).Average();
            //    var meanY = b.Select(b1 => b1[1]).Average();
            //    fl.Add(new GeoJsonFeature {
            //        Geometry = new Point { Coordinates= new double[] { meanX,meanY} } ,
            //        Properties = new Dictionary<string, object> { { "tileId", cluster.Key },{ "label",true } } } );
            //}

            //    featureCollection.Features = featureCollection.Features.Concat(fl).ToArray();

            var processor = serviceProvider.GetRequiredService <GeoJsonVectorTiles <GeoJsonVectorTilesOptions> >();

            processor.ProcessData(featureCollection);


            var q = new Queue <VectorTileCoord>(); q.Enqueue(new VectorTileCoord(0, 0, 0));

            while (q.Any())
            {
                var tileCoord = q.Dequeue();
                var tile      = processor.GetTile(tileCoord.Z, tileCoord.X, tileCoord.Y);

                if (tile != null)
                {
                    if (tileCoord.Z < maxZoom)
                    {
                        if (tile.Features.Count > 0)
                        {
                            foreach (var child in tileCoord.GetChildCoordinate())
                            {
                                q.Enqueue(child);
                            }
                        }
                    }

                    if (tile.Features.Count > 25)
                    {
                    }
                    //   var groups = tile.Features.Where(f=>f.Type == 3).GroupBy(f => (f.Tags["tileId"] as string).Substring(0, 3));



                    //if (tile.NumPoints > 512)
                    //{

                    //    tile.Features = tile.Features.Where(f => f.Type == 1 && f.Tags.ContainsKey("label")).ToList();

                    //    foreach (var group in groups)
                    //    {

                    //        var hull = t.ComputeConvexHull(group.SelectMany(k => k.GetRings().SelectMany(m => m)));


                    //        tile.Features.Add(new VectorTileFeature
                    //        {
                    //            Type = 3,
                    //            Geometry = new[] { new VectorTileGeometry(hull) },
                    //            Tags = new Dictionary<string, object>
                    //             {
                    //                 { "tileId", group.Key},
                    //                 {"count", group.Count() }
                    //             }
                    //        });
                    //    }

                    //}


                    logger.LogInformation("[{tileZ},{tileX},{tileY}] : Writing tile with {featureCount}",
                                          tileCoord.Z, tileCoord.X, tileCoord.Y, tile.Features.Count);



                    var file = $"{args[1]}/{tileCoord.Z}/{tileCoord.X}/{tileCoord.Y}.vector.pbf";
                    Directory.CreateDirectory(Path.GetDirectoryName(file));

                    var stream = await node.InvokeAsync <NodeBuffer>("./topbf",
                                                                     new VectorTile { Features = tile.Features, X = tile.X, Y = tile.Y, Z2 = tile.Z2, Transformed = tile.Transformed }, file);



                    // File.WriteAllBytes(file+".pbf", stream.Data);


                    // return;
                }
            }
        }