Example #1
0
 public bool Equals(TileRange tileRange)
 {
     return
       this.firstCol == tileRange.firstCol &&
       this.lastCol == tileRange.lastCol &&
       this.firstRow == tileRange.firstRow &&
       this.lastRow == tileRange.lastRow;
 }
Example #2
0
 public bool Equals(TileRange tileRange)
 {
     return
       FirstCol == tileRange.FirstCol &&
       ColCount == tileRange.ColCount &&
       FirstRow == tileRange.FirstRow &&
       RowCount == tileRange.RowCount;
 }
Example #3
0
        public void WorldToTileShouldReturnCorrectTileRange()
        {
            // arrange
            var expectedRange = new TileRange(1, 2);
            var schema = new SphericalMercatorWorldSchema();
            var extent = new Extent(-15028130, -10018753, -10018755, -5009378);
            
            // act
            var range = TileTransform.WorldToTile(extent, 3, schema);

            // assert
            Assert.AreEqual(range, expectedRange);
        }
Example #4
0
 /**
  * @inheritDoc
  */
 public override bool ForEachTileCoordParentTileRange(int[] tileCoord, Func<int, TileRange, bool> callback, TileRange opt_tileRange = null, double[] opt_extent = null)
 {
     var tileRange = TileRange.CreateOrUpdate(
       0, tileCoord[1], 0, tileCoord[2], opt_tileRange);
       int z;
       for (z = tileCoord[0] - 1; z >= this.MinZoom; --z) {
     tileRange.MinX = tileRange.MaxX >>= 1;
     tileRange.MinY = tileRange.MaxY >>= 1;
     if (callback(z, tileRange)) {
       return true;
     }
       }
       return false;
 }
Example #5
0
        public void TileToWorldShouldReturnCorrectExtent()
        {
            // arrange
            var range = new TileRange(1, 2);
            var schema = new SphericalMercatorWorldSchema();
            var expectedExtent = new Extent(-15028131.257989,-10018754.173189,-10018754.173189,-5009377.088389);
              
            // act
            var extent = TileTransform.TileToWorld(range, 3, schema);

            // assert
            Assert.AreEqual(extent.MinX, expectedExtent.MinX, 0.0001);
            Assert.AreEqual(extent.MinY, expectedExtent.MinY, 0.0001);
            Assert.AreEqual(extent.MaxX, expectedExtent.MaxX, 0.0001);
            Assert.AreEqual(extent.MaxY, expectedExtent.MaxY, 0.0001);
        }
Example #6
0
        public override Func<int[], DotSpatial.Projections.ProjectionInfo, int[], int[]> CreateTileCoordTransform()
        {
            var minZ = this.MinZoom;
            var maxZ = this.MaxZoom;
            TileRange[] tileRangeByZ = null;//new TileRange[maxZ + 1];
            if (false) //https://github.com/openlayers/ol3/blob/afd43687f2b9c1f686c6588aaa50bb1cc1457f21/src/ol/tilegrid/xyztilegrid.js#L46
            {
                 tileRangeByZ = new TileRange[maxZ + 1];
                for (var z = 0; z <= maxZ; ++z)
            {
                if (z < minZ)
                {
                    tileRangeByZ[z] = null;
                }
                else
                {
                    tileRangeByZ[z] = GetTileRangeForExtentAndZ(null, z);
                }
                }
            }

            return (tileCoord,projection,opt_tileCoord) => {
                var z = tileCoord[0];
                if (z < minZ || maxZ < z) {
                  return null;
                }
                var n = 1<< z;
                var x = tileCoord[1];
                if (true){ //wrapx) {
                  x = (x%n);
                } else if (x < 0 || n <= x) {
                  return null;
                }
                var y = tileCoord[2];
                if (y < -n || -1 < y) {
                  return null;
                }
                if (tileRangeByZ!=null) {
                  if (!tileRangeByZ[z].ContainsXY(x, y)) {
                    return null;
                  }
                }
                return TileCoord.CreateOrUpdate(z, x, -y - 1, opt_tileCoord);
            };
        }
Example #7
0
        /// <summary>
        /// Notifies this layer the mapview has changed.
        /// </summary>
        /// <param name="map"></param>
        /// <param name="zoomFactor"></param>
        /// <param name="center"></param>
        /// <param name="view"></param>
        public void ViewChanged(Map map, float zoomFactor, GeoCoordinate center, View2D view)
        {
            // calculate the current zoom level.
            var zoomLevel = (int)System.Math.Round(map.Projection.ToZoomLevel(zoomFactor), 0);

            // reset stack when zoom level changed.
            if (_previousZoomLevel != zoomLevel)
            {
                _previousZoomLevel = zoomLevel;
                _tilesStack.Clear();
            }

            // build the boundingbox.
            // build the boundingbox.
            var viewBox = view.OuterBox;
            var box     = new GeoCoordinateBox(map.Projection.ToGeoCoordinates(viewBox.Min [0], viewBox.Min [1]),
                                               map.Projection.ToGeoCoordinates(viewBox.Max [0], viewBox.Max [1]));

            // build the tile range.
            TileRange range = TileRange.CreateAroundBoundingBox(box, zoomLevel);
            DateTime  now   = DateTime.Now;

            foreach (var tile in range)
            {
                if (_primitivePerTile.ContainsKey(tile))
                { // the tile is here already.
                    _lastAccessed[tile] = now;
                }
                else
                { // queue the tile to be loaded.
                    lock (_tilesStack)
                    {
                        _tilesStack.Push(tile);
                    }
                }
            }

            if (_thread == null)
            { // the loading thread does not exist yet.
                _thread = new Thread(TilesLoading);
                _thread.Start(map.Projection);
            }
        }
Example #8
0
        private readonly string[] _serverEndpoints = { "a", "b", "c" }; // OSM server addreses

        void Awake()
        {
            // Create a TileRange based on the corner coordinates of the GPX
            // track.
            _gpxInput.Initialize(_zoom); // initialize _gpxInput obj
            var bounds = _gpxInput.ComputeMapCoordinateBounds();
            var tiles  = new TileRange((int)bounds.minLon, (int)bounds.minLat,
                                       (int)bounds.maxLon, (int)bounds.maxLat,
                                       _zoom);

            // init list of tex2D that forms the tiles in the tilemap
            var tileTexList = new List <(int X, int Y, Texture2D texture)>();

            // system path to save the png OSM tile images and later load them
            // from dir
            string tilesDataPath = Path.Combine(Application.persistentDataPath,
                                                "Assets/Resources");

            // for each tile in the tilerange, download from server and save to
            // file or load from file if it already exists/
            foreach (var tile in tiles)
            {
                var random   = new System.Random();
                var savePath = Path.Combine(tilesDataPath, "Tiles",
                                            $"{_zoom}/{tile.X}/{tile.Y}.png");
                if (!File.Exists(savePath))
                {
                    // Download new map tile
                    var url =
                        $"http://{_serverEndpoints[random.Next(0, 2)]}.tile.openstreetmap.org/{_zoom}/{tile.X}/{tile.Y}.png";
                    WebRequests.GetTexture(url,
                                           (string error) =>
                    {
                        // Net error.
                        // Debug.Log("Error: " + error);
                    }, (Texture2D texture2D) =>
                    {
                        // Save Image
                        ImageLoader.SaveImage(savePath, texture2D.EncodeToPNG());
                        tileTexList.Add((tile.X, -tile.Y, texture2D));
                    });
Example #9
0
        /// <summary>
        /// Loads all vertices inside the given boundingbox.
        /// </summary>
        /// <param name="box"></param>
        /// <returns></returns>
        private List <uint> LoadVerticesIn(GeoCoordinateBox box)
        {
            List <uint> vertices = new List <uint>();
            TileRange   range    = TileRange.CreateAroundBoundingBox(box, _zoom);

            foreach (Tile tile in range)
            {
                CHVertexRegion region;
                if (!_regions.TryGet(tile.Id, out region))
                {
                    region = this.DeserializeRegion(tile.Id);
                    if (region != null)
                    {
                        _regions.Add(tile.Id, region);
                    }
                }
                if (region != null)
                {
                    vertices.AddRange(region.Vertices);
                }
            }
            return(vertices);
        }
        /// <summary>
        /// Returns all data within the given bounding box and filtered by the given filter.
        /// </summary>
        /// <param name="box"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public override IList <OsmGeo> Get(GeoCoordinateBox box, OsmSharp.Osm.Filters.Filter filter)
        {
            // initialize connection.
            NpgsqlConnection con = this.CreateConnection();
            List <OsmGeo>    res = new List <OsmGeo>();

            // calculate bounding box parameters to query db.
            long latitude_min  = (long)(box.MinLat * 10000000.0);
            long longitude_min = (long)(box.MinLon * 10000000.0);
            long latitude_max  = (long)(box.MaxLat * 10000000.0);
            long longitude_max = (long)(box.MaxLon * 10000000.0);

            // calculate bounding box parameters to query db.
            TileRange range = TileRange.CreateAroundBoundingBox(box, 14);

            IList <long> boxes = new List <long>();

            foreach (Tile tile in range)
            {
                boxes.Add((long)tile.Id);
            }

            // STEP 1: query nodes table.
            //id	latitude	longitude	changeset_id	visible	timestamp	tile	version
            string sql
                = "SELECT id, latitude, longitude, changeset_id, visible, timestamp, tile, version, usr, usr_id FROM node WHERE (visible = true) AND  (tile IN ({4})) AND (latitude >= {0} AND latitude < {1} AND longitude >= {2} AND longitude < {3})";

            sql = string.Format(sql,
                                latitude_min.ToString(),
                                latitude_max.ToString(),
                                longitude_min.ToString(),
                                longitude_max.ToString(),
                                this.ConstructIdList(boxes));

            // TODO: parameters.
            NpgsqlCommand com = new NpgsqlCommand(sql);

            com.Connection = con;
            NpgsqlDataReader        reader  = com.ExecuteReader();
            Node                    node    = null;
            Dictionary <long, Node> nodes   = new Dictionary <long, Node>();
            List <long>             nodeIds = new List <long>();

            while (reader.Read())
            {
                // load/parse data.
                long     returned_id   = reader.GetInt64(0);
                int      latitude_int  = reader.GetInt32(1);
                int      longitude_int = reader.GetInt32(2);
                long?    changeset_id  = reader.IsDBNull(3) ? null : (long?)reader.GetInt64(3);
                bool?    visible       = reader.IsDBNull(4) ? null : (bool?)reader.GetBoolean(4);
                DateTime?timestamp     = reader.IsDBNull(5) ? null : (DateTime?)reader.GetDateTime(5);
                long     tile          = reader.GetInt64(6);
                ulong?   version       = reader.IsDBNull(7) ? null : (ulong?)reader.GetInt32(7);
                string   usr           = reader.IsDBNull(8) ? null : reader.GetString(8);
                long?    usr_id        = reader.IsDBNull(9) ? null : (long?)reader.GetInt32(9);

                if (!nodes.ContainsKey(returned_id))
                {
                    // create node.
                    node             = new Node();
                    node.Id          = returned_id;
                    node.Version     = version;
                    node.UserId      = usr_id;
                    node.UserName    = usr;
                    node.TimeStamp   = timestamp;
                    node.ChangeSetId = changeset_id;
                    node.Latitude    = ((double)latitude_int) / 10000000.0;
                    node.Longitude   = ((double)longitude_int) / 10000000.0;
                    node.Visible     = visible;

                    nodes.Add(node.Id.Value, node);
                    nodeIds.Add(node.Id.Value);
                }
            }
            reader.Close();

            // STEP2: Load all node tags.
            this.LoadNodeTags(nodes);
            res.AddRange(nodes.Values);

            // load all ways that contain the nodes that have been found.
            res.AddRange(this.GetWaysFor(nodeIds));

            // get relations containing any of the nodes or ways in the current results-list.
            List <Relation> relations   = new List <Relation>();
            HashSet <long>  relationIds = new HashSet <long>();

            foreach (OsmGeo osmGeo in res)
            {
                IList <Relation> relationsFor = this.GetRelationsFor(osmGeo);
                foreach (Relation relation in relationsFor)
                {
                    if (!relationIds.Contains(relation.Id.Value))
                    {
                        relations.Add(relation);
                        relationIds.Add(relation.Id.Value);
                    }
                }
            }

            // recursively add all relations containing other relations as a member.
            do
            {
                res.AddRange(relations); // add previous relations-list.
                List <Relation> newRelations = new List <Relation>();
                foreach (OsmGeo osmGeo in relations)
                {
                    IList <Relation> relationsFor = this.GetRelationsFor(osmGeo);
                    foreach (Relation relation in relationsFor)
                    {
                        if (!relationIds.Contains(relation.Id.Value))
                        {
                            newRelations.Add(relation);
                            relationIds.Add(relation.Id.Value);
                        }
                    }
                }
                relations = newRelations;
            } while (relations.Count > 0);

            if (filter != null)
            {
                var filtered = new List <OsmGeo>();
                foreach (OsmGeo geo in res)
                {
                    if (filter.Evaluate(geo))
                    {
                        filtered.Add(geo);
                    }
                }
                return(filtered);
            }

            return(res);
        }
Example #11
0
        public TileRange GetTileToLoadFor(GeoCoordinateBox bbox,
            int zoom)
        {
            int n = (int)System.Math.Floor(System.Math.Pow(2, zoom));

            Radian rad = new Degree(bbox.MaxLat);

            int x_tile_min = (int)(((bbox.MinLon + 180.0f) / 360.0f) * (double)n);
            int y_tile_min = (int)(
                (1.0f - (System.Math.Log(System.Math.Tan(rad.Value) + (1.0f / System.Math.Cos(rad.Value))))
                / System.Math.PI) / 2f * (double)n);

            rad = new Degree(bbox.MinLat);
            int x_tile_max = (int)(((bbox.MaxLon + 180.0f) / 360.0f) * (double)n);
            int y_tile_max = (int)(
                (1.0f - (System.Math.Log(System.Math.Tan(rad.Value) + (1.0f / System.Math.Cos(rad.Value))))
                / System.Math.PI) / 2f * (double)n);

            TileRange range = new TileRange();
            range.XMax = x_tile_max;
            range.XMin = x_tile_min;
            range.YMax = y_tile_max;
            range.YMin = y_tile_min;
            return range;
        }
Example #12
0
        public void TestTileRangeEnumerator()
        {
            TileRange range = new TileRange(0, 0, 1, 1, 16);

            HashSet<Tile> tiles = new HashSet<Tile>(range);

            Assert.IsTrue(tiles.Contains(new Tile(0, 0, 16)));
            Assert.IsTrue(tiles.Contains(new Tile(0, 1, 16)));
            Assert.IsTrue(tiles.Contains(new Tile(1, 1, 16)));
            Assert.IsTrue(tiles.Contains(new Tile(0, 1, 16)));
        }
Example #13
0
 public TileRangeEnumerator(TileRange tileRange)
 {
     _tileRange = tileRange;
     _x         = uint.MaxValue;
     _y         = uint.MaxValue;
 }
Example #14
0
        public void TileToWorldShouldReturnCorrectExtent()
        {
            // arrange
            var range = new TileRange(1, 2);
            var schema = new GlobalSphericalMercator(YAxis.TMS);
            var expectedExtent = new Extent(-15028131.257989, -10018754.173189, -10018754.173189, -5009377.088389);
            const double toleratedDelta = 0.01;

            // act
            var extent = TileTransform.TileToWorld(range, "3", schema);

            // assert
            Assert.AreEqual(extent.MinX, expectedExtent.MinX, toleratedDelta);
            Assert.AreEqual(extent.MinY, expectedExtent.MinY, toleratedDelta);
            Assert.AreEqual(extent.MaxX, expectedExtent.MaxX, toleratedDelta);
            Assert.AreEqual(extent.MaxY, expectedExtent.MaxY, toleratedDelta);
        }
Example #15
0
        internal void ExportVisualTopoToGLB(VisualTopoModel visualTopoModel, DEMDataSet dataset, string outputFile, bool drawOnTexture, float marginMeters, float zFactor, ImageryProvider imageryProvider)
        {
            int   outputSrid       = 3857;
            float lineWidth        = 1.0F;
            int   numTilesPerImage = 4;


            BoundingBox bbox = visualTopoModel.BoundingBox                                                                                                      // relative coords
                               .Translate(visualTopoModel.EntryPoint.Longitude, visualTopoModel.EntryPoint.Latitude, visualTopoModel.EntryPoint.Elevation ?? 0) // absolute coords
                               .Pad(marginMeters)                                                                                                               // margin around model
                               .ReprojectTo(visualTopoModel.SRID, dataset.SRID);                                                                                // DEM coords

            //=======================
            // Height map (get dem elevation for bbox)
            //
            // Get height map
            // Note that ref Bbox means that the bbox will be adjusted to match DEM data
            var heightMap        = elevationService.GetHeightMap(ref bbox, dataset, downloadMissingFiles: true);
            var bboxTerrainSpace = bbox.ReprojectTo(dataset.SRID, outputSrid); // terrain coords

            // Model origin
            GeoPoint axisOriginWorldSpace = visualTopoModel.EntryPoint.ReprojectTo(visualTopoModel.SRID, outputSrid)
                                            .CenterOnOrigin(bboxTerrainSpace);
            Vector3 axisOriginModelSpace = visualTopoModel.EntryPoint.AsVector3();

            //await signalR.ReportGenerateProgressAsync(signalRConnectionId, "Getting GPX extent elevation...", 20);
            //=======================
            // Local transform function from model coordinates (relative to entry, in meters)
            // and global coordinates absolute in final 3D model space
            //
            IEnumerable <GeoPoint> TransformLine(IEnumerable <GeoPoint> line)
            {
                var newLine = line.Translate(visualTopoModel.EntryPoint)     // Translate to entry (=> global topo coord space)
                              .ReprojectTo(visualTopoModel.SRID, outputSrid) // Reproject to terrain coord space
                              .CenterOnOrigin(bboxTerrainSpace)              // Center on terrain space origin
                              .CenterOnOrigin(axisOriginWorldSpace);

                return(newLine);
            };

            //=======================
            // 3D model
            //
            var gltfModel = sharpGltfService.CreateNewModel();

            // Add X/Y/Z axis on entry point
            var axis = meshService.CreateAxis();

            sharpGltfService.AddMesh(gltfModel, "Axis", axis, doubleSided: false);

            int i = 0;

            var triangulation = visualTopoModel.TriangulationFull3D.Clone()
                                .Translate(axisOriginModelSpace)             // already zScaled if zFactor > 1
                                .ReprojectTo(visualTopoModel.SRID, outputSrid)
                                .CenterOnOrigin(bboxTerrainSpace)
                                .CenterOnOrigin(axisOriginWorldSpace.AsVector3());

            gltfModel = sharpGltfService.AddMesh(gltfModel, "Cavite3D", triangulation, VectorsExtensions.CreateColor(0, 255, 0), doubleSided: false);

            ////=======================
            //// 3D cavity model
            //foreach (var line in visualTopoModel.Topology3D) // model.Topology3D is the graph of topo paths
            //{
            //    // Add line to model
            //    gltfModel = sharpGltfService.AddLine(gltfModel
            //                                    , string.Concat("CavitySection", i++)     // name of 3D node
            //                                    , TransformLine(line)               // call transform function
            //                                    , color: VectorsExtensions.CreateColor(255, 0, 0, 128)
            //                                    , lineWidth);
            //}

            // Reproject and center height map coordinates
            heightMap = heightMap.ReprojectTo(dataset.SRID, outputSrid)
                        .CenterOnOrigin(bboxTerrainSpace)
                        .ZScale(zFactor)
                        .CenterOnOrigin(axisOriginWorldSpace);

            //=======================
            // Textures
            //
            PBRTexture pbrTexture = null;

            if (imageryProvider != null)
            {
                TileRange tiles    = imageryService.DownloadTiles(bbox, imageryProvider, numTilesPerImage);
                string    fileName = Path.Combine(Path.GetDirectoryName(outputFile), "Texture.jpg");

                Console.WriteLine("Construct texture...");
                TextureInfo texInfo = null;
                if (drawOnTexture)
                {
                    var topoTexture = visualTopoModel.Topology3D.SelectMany(l => l).Translate(visualTopoModel.EntryPoint).ReprojectTo(visualTopoModel.SRID, 4326);
                    texInfo = imageryService.ConstructTextureWithGpxTrack(tiles, bbox, fileName, TextureImageFormat.image_jpeg
                                                                          , topoTexture, drawGpxVertices: true);
                }
                else
                {
                    texInfo = imageryService.ConstructTexture(tiles, bbox, fileName, TextureImageFormat.image_jpeg);
                }



                pbrTexture = PBRTexture.Create(texInfo, null);
            }
            //
            //=======================

            gltfModel = sharpGltfService.AddTerrainMesh(gltfModel, heightMap, pbrTexture);
            gltfModel.SaveGLB(outputFile);
        }
Example #16
0
    public static List <Tile> GetRangeObstacles(Tile startTile, int range, GridInfo gridInfo, out ThisIsCool cool)
    {
        List <TileRange> openSet   = new List <TileRange>();
        HashSet <Tile>   closedSet = new HashSet <Tile>();
        HashSet <Tile>   finalSet  = new HashSet <Tile>();

        cool.outerTiles = new List <Tile>();

        if (gridInfo == null)
        {
            gridInfo                           = new GridInfo();
            gridInfo.cleanse                   = false;
            gridInfo.useLineOfSight            = false;
            gridInfo.useMovementPenalty        = false;
            gridInfo.useThisIsCool             = false;
            gridInfo.allowEntitiesToBeTargeted = false;
        }

        foreach (Tile t in GridManager.grid)
        {
            t.isAvailableToPathfinding = true;
            t.isClickableForInput      = true;
        }

        openSet.Add(new TileRange(startTile, range));

        while (openSet.Count > 0)
        {
            TileRange currentTile = openSet[0];

            openSet.Remove(currentTile);
            finalSet.Add(currentTile.tile);
            cool.outerTiles.Add(currentTile.tile);

            foreach (Tile n in GetNeighbors(currentTile.tile))
            {
                if (finalSet.Contains(n))
                {
                    continue;
                }

                if (gridInfo.unreachableTiles != null)
                {
                    if (gridInfo.unreachableTiles.Contains(n) == true)
                    {
                        continue;
                    }
                }

                int comparerWeight = BattleManager.distanceCoefficient;
                if (gridInfo.useMovementPenalty == true)
                {
                    comparerWeight = n.baseWeight;
                }

                if (currentTile.rangeLeft >= comparerWeight && ((n.isEmpty || gridInfo.allowEntitiesToBeTargeted) || gridInfo.useThisIsCool))
                {
                    if (cool.outerTiles.Contains(currentTile.tile))
                    {
                        cool.outerTiles.Remove(currentTile.tile);
                    }

                    if (gridInfo.cleanse)
                    {
                        if (gridInfo.unPathableTiles.Contains(n))
                        {
                            finalSet.Add(n);
                        }
                        else if (closedSet.Contains(n) == false)
                        {
                            openSet.Add(new TileRange(n, currentTile.rangeLeft - comparerWeight));
                            closedSet.Add(n);
                        }
                    }
                    else if (closedSet.Contains(n) == false)
                    {
                        openSet.Add(new TileRange(n, currentTile.rangeLeft - comparerWeight));
                        closedSet.Add(n);
                    }
                    else
                    {
                        finalSet.Add(n);
                    }
                }
            }
        }

        List <Tile> result = new List <Tile>();

        foreach (Tile t in GridManager.grid)
        {
            if (finalSet.Contains(t))
            {
                result.Add(t);
            }
            else
            {
                t.isAvailableToPathfinding = false;
                t.isClickableForInput      = false;
            }
        }

        result.Remove(startTile);

        return(result);
    }
Example #17
0
        /**
         * @inheritDoc
         */
        public override bool ForEachTileCoordParentTileRange(int[] tileCoord, Func <int, TileRange, bool> callback, TileRange opt_tileRange = null, double[] opt_extent = null)
        {
            var tileRange = TileRange.CreateOrUpdate(
                0, tileCoord[1], 0, tileCoord[2], opt_tileRange);
            int z;

            for (z = tileCoord[0] - 1; z >= this.MinZoom; --z)
            {
                tileRange.MinX = tileRange.MaxX >>= 1;
                tileRange.MinY = tileRange.MaxY >>= 1;
                if (callback(z, tileRange))
                {
                    return(true);
                }
            }
            return(false);
        }
Example #18
0
        /// <summary>
        /// Constructs an id list from the given tilerange object
        /// </summary>
        public static List<long> ConstructIdList(TileRange tile_range)
        {
            var tile_ids = new List<long>();

            foreach (var tile in tile_range)
            {
                tile_ids.Add((long)tile.Id);
            }

            return tile_ids;
        }
Example #19
0
        /// <summary>
        /// Returns all objects with the given bounding box and valid for the given filter;
        /// </summary>
        /// <param name="box"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public override IList <OsmGeo> Get(GeoCoordinateBox box, Filter filter)
        {
            // initialize connection.
            OracleConnection con = this.CreateConnection();
            List <OsmGeo>    res = new List <OsmGeo>();

            // calculate bounding box parameters to query db.
            long latitudeMin  = (long)(box.MinLat * 10000000.0);
            long longitudeMin = (long)(box.MinLon * 10000000.0);
            long latitudeMax  = (long)(box.MaxLat * 10000000.0);
            long longitudeMax = (long)(box.MaxLon * 10000000.0);

            IList <long> boxes = new List <long>();

            TileRange tileRange = TileRange.CreateAroundBoundingBox(box, 14);

            foreach (Tile tile in tileRange)
            {
                boxes.Add((long)tile.Id);
            }

            // STEP 1: query nodes table.
            //id	latitude	longitude	changeset_id	visible	timestamp	tile	version
            //string sql
            //        = "SELECT node.id, node.latitude, node.longitude, node.changeset_id, node.timestamp, node.version, " +
            //          "node.usr, node.usr_id, node.visible FROM node WHERE  (tile IN ({4})) AND (visible = 1) AND (latitude BETWEEN {0} AND {1} AND longitude BETWEEN {2} AND {3})";
            // remove this nasty BETWEEN operation because it depends on the database (!) what results are returned (including or excluding bounds!!!)
            string sql
                = "SELECT id, latitude, longitude, changeset_id, visible, timestamp, tile, version, usr, usr_id " +
                  "FROM node WHERE  (tile IN ({4})) AND (visible = 1) AND (latitude >= {0} AND latitude < {1} AND longitude >= {2} AND longitude < {3})";

            sql = string.Format(sql,
                                latitudeMin.ToString(System.Globalization.CultureInfo.InvariantCulture),
                                latitudeMax.ToString(System.Globalization.CultureInfo.InvariantCulture),
                                longitudeMin.ToString(System.Globalization.CultureInfo.InvariantCulture),
                                longitudeMax.ToString(System.Globalization.CultureInfo.InvariantCulture),
                                this.ConstructIdList(boxes));

            // TODO: parameters.
            var com = new OracleCommand(sql);

            com.Connection = con;
            OracleDataReader reader = com.ExecuteReader();
            Node             node   = null;
            var nodes   = new Dictionary <long, Node>();
            var nodeIds = new List <long>();

            while (reader.Read())
            {
                // load/parse data.
                long     returned_id   = reader.GetInt64(0);
                int      latitude_int  = reader.GetInt32(1);
                int      longitude_int = reader.GetInt32(2);
                long?    changeset_id  = reader.IsDBNull(3) ? null : (long?)reader.GetInt64(3);
                bool?    visible       = reader.IsDBNull(4) ? null : (bool?)(reader.GetInt32(4) == 1);
                DateTime?timestamp     = reader.IsDBNull(5) ? null : (DateTime?)reader.GetDateTime(5);
                long     tile          = reader.GetInt64(6);
                ulong?   version       = reader.IsDBNull(7) ? null : (ulong?)(ulong)reader.GetInt64(7);
                string   usr           = reader.IsDBNull(8) ? null : reader.GetString(8);
                long?    usr_id        = reader.IsDBNull(9) ? null : (long?)reader.GetInt64(9);

                if (!nodes.ContainsKey(returned_id))
                {
                    // create node.
                    node             = new Node();
                    node.Id          = returned_id;
                    node.Version     = version;
                    node.UserId      = usr_id;
                    node.TimeStamp   = timestamp;
                    node.ChangeSetId = changeset_id;
                    node.Visible     = visible;
                    node.Latitude    = ((double)latitude_int) / 10000000.0;
                    node.Longitude   = ((double)longitude_int) / 10000000.0;
                    node.UserName    = usr;

                    nodeIds.Add(node.Id.Value);
                    nodes.Add(node.Id.Value, node);
                }
            }
            reader.Close();

            // STEP2: Load all node tags.
            this.LoadNodeTags(nodes);
            res.AddRange(nodes.Values);

            // load all ways that contain the nodes that have been found.
            res.AddRange(this.GetWaysFor(nodeIds));

            // get relations containing any of the nodes or ways in the current results-list.
            List <Relation> relations   = new List <Relation>();
            HashSet <long>  relationIds = new HashSet <long>();

            foreach (OsmGeo osmGeo in res)
            {
                IList <Relation> relationsFor = this.GetRelationsFor(osmGeo);
                foreach (Relation relation in relationsFor)
                {
                    if (!relationIds.Contains(relation.Id.Value))
                    {
                        relations.Add(relation);
                        relationIds.Add(relation.Id.Value);
                    }
                }
            }

            // recursively add all relations containing other relations as a member.
            do
            {
                res.AddRange(relations); // add previous relations-list.
                List <Relation> newRelations = new List <Relation>();
                foreach (OsmGeo osmGeo in relations)
                {
                    IList <Relation> relationsFor = this.GetRelationsFor(osmGeo);
                    foreach (Relation relation in relationsFor)
                    {
                        if (!relationIds.Contains(relation.Id.Value))
                        {
                            newRelations.Add(relation);
                            relationIds.Add(relation.Id.Value);
                        }
                    }
                }
                relations = newRelations;
            } while (relations.Count > 0);

            if (filter != null)
            {
                List <OsmGeo> filtered = new List <OsmGeo>();
                foreach (OsmGeo geo in res)
                {
                    if (filter.Evaluate(geo))
                    {
                        filtered.Add(geo);
                    }
                }
            }

            return(res);
        }
Example #20
0
        public void Run(DEMDataSet dataset, bool withTexture = true)
        {
            try
            {
                int TEXTURE_TILES = 4; // 4: med, 8: high

                //_rasterService.GenerateDirectoryMetadata(dataset, false);
                Stopwatch       sw        = Stopwatch.StartNew();
                string          modelName = $"MontBlanc_{dataset.Name}";
                string          outputDir = Directory.GetCurrentDirectory();
                ImageryProvider provider  = ImageryProvider.EsriWorldImagery;// new TileDebugProvider(new GeoPoint(43.5,5.5));


                //// You can get your boox from https://geojson.net/ (save as WKT)
                //string bboxWKT = "POLYGON((5.54888 43.519525, 5.61209 43.519525, 5.61209 43.565225, 5.54888 43.565225, 5.54888 43.519525))";
                ////                string bboxWKT =
                ////                    "POLYGON((5.594457381483949 43.545276557046044,5.652135604140199 43.545276557046044,5.652135604140199 43.52038635099936,5.594457381483949 43.52038635099936,5.594457381483949 43.545276557046044))";
                ////                _logger.LogInformation($"Processing model {modelName}...");
                ////
                ////
                ////                _logger.LogInformation($"Getting bounding box geometry...");
                //var bbox = GeometryService.GetBoundingBox(bboxWKT);

                // DjebelMarra
                var bbox = new BoundingBox(24.098067346557492, 24.42468219234563, 12.7769822830208, 13.087504129660111);

                // MontBlanc
                //var bbox = GeometryService.GetBoundingBox("POLYGON((6.618804355541963 45.9658287141746,7.052764316479463 45.9658287141746,7.052764316479463 45.72379929776474,6.618804355541963 45.72379929776474,6.618804355541963 45.9658287141746))");

                //var bbox = new BoundingBox(5.5613898348431485,5.597185285307553,43.49372969433046,43.50939068558466);
                _logger.LogInformation($"Getting height map data...");

                var heightMap = _elevationService.GetHeightMap(ref bbox, dataset);
                ModelGenerationTransform transform = new ModelGenerationTransform(bbox, 3857, true, 1.5f, true);

                _logger.LogInformation($"Processing height map data ({heightMap.Count} coordinates)...");
                heightMap = transform.TransformHeightMap(heightMap);


                //=======================
                // Textures
                //
                PBRTexture pbrTexture = null;
                if (withTexture)
                {
                    Console.WriteLine("Download image tiles...");
                    TileRange tiles    = _imageryService.DownloadTiles(bbox, provider, TEXTURE_TILES);
                    string    fileName = Path.Combine(outputDir, "Texture.jpg");

                    Console.WriteLine("Construct texture...");
                    TextureInfo texInfo = _imageryService.ConstructTexture(tiles, bbox, fileName, TextureImageFormat.image_jpeg);

                    //
                    //=======================

                    //=======================
                    // Normal map
                    Console.WriteLine("Height map...");
                    //float Z_FACTOR = 0.00002f;

                    //hMap = hMap.CenterOnOrigin().ZScale(Z_FACTOR);
                    var normalMap = _imageryService.GenerateNormalMap(heightMap, outputDir);

                    pbrTexture = PBRTexture.Create(texInfo, normalMap);

                    //hMap = hMap.CenterOnOrigin(Z_FACTOR);
                    //
                    //=======================
                }
                // Triangulate height map
                // and add base and sides
                _logger.LogInformation($"Triangulating height map and generating 3D mesh...");

                var model = _sharpGltfService.CreateTerrainMesh(heightMap, pbrTexture);
                model.SaveGLB(Path.Combine(Directory.GetCurrentDirectory(), modelName + ".glb"));
                model.SaveAsWavefront(Path.Combine(Directory.GetCurrentDirectory(), modelName + ".obj"));

                model = _sharpGltfService.CreateTerrainMesh(heightMap, GenOptions.Normals | GenOptions.BoxedBaseElevationMin);
                model.SaveGLB(Path.Combine(Directory.GetCurrentDirectory(), modelName + "_normalsBox.glb"));
                model.SaveAsWavefront(Path.Combine(Directory.GetCurrentDirectory(), modelName + "_normalsBox.obj"));

                _logger.LogInformation($"Model exported as {Path.Combine(Directory.GetCurrentDirectory(), modelName + ".gltf")} and .glb");

                _logger.LogInformation($"Done in {sw.Elapsed:g}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
            }
        }
Example #21
0
        /// <summary>
        /// Generates a VisualTopo file 3D model
        /// </summary>
        /// <remarks>LT* (Lambert Carto) projections are not supported and could produce imprecise results (shifted by +10meters)</remarks>
        /// <param name="vtopoFile">VisualTopo .TRO file</param>
        /// <param name="imageryProvider">Imagery provider for terrain texture. Set to null for untextured model</param>
        /// <param name="bboxMarginMeters">Terrain margin (meters) around VisualTopo model</param>
        public void Run_3DModelGeneration(string vtopoFile, ImageryProvider imageryProvider, float bboxMarginMeters = 1000, bool generateTopoOnlyModel = false, float zFactor = 1f)
        {
            try
            {
                //=======================
                // Generation params
                //
                int    outputSRID      = 3857;                         // Output SRID
                float  lineWidth       = 1.0F;                         // Topo lines width (meters)
                var    dataset         = DEMDataSet.AW3D30;            // DEM dataset for terrain and elevation
                int    TEXTURE_TILES   = 8;                            // Texture quality (number of tiles for bigger side) 4: med, 8: high, 12: ultra
                string outputDir       = Directory.GetCurrentDirectory();
                bool   GENERATE_LINE3D = false;

                //=======================
                // Open and parse file
                //
                // model will have available properties
                // => Graph (nodes/arcs)
                // => BoundingBox
                // => Topology3D -> list of point-to-point lines
                // => SRID of model file
                StopwatchLog    timeLog = StopwatchLog.StartNew(_logger);
                VisualTopoModel model   = _visualTopoService.LoadFile(vtopoFile, Encoding.GetEncoding("ISO-8859-1")
                                                                      , decimalDegrees: true
                                                                      , ignoreRadialBeams: true
                                                                      , zFactor);
                timeLog.LogTime($"Loading {vtopoFile} model file");

                // for debug,
                //var b = GetBranches(model); // graph list of all nodes
                //var lowestPoint = model.Sets.Min(s => s.Data.Min(d => d.GlobalGeoPoint?.Elevation ?? 0));

                BoundingBox bbox = model.BoundingBox                                                                                  // relative coords
                                   .Translate(model.EntryPoint.Longitude, model.EntryPoint.Latitude, model.EntryPoint.Elevation ?? 0) // absolute coords
                                   .Pad(bboxMarginMeters)                                                                             // margin around model
                                   .ReprojectTo(model.SRID, dataset.SRID);                                                            // DEM coords
                                                                                                                                      // Get height map
                                                                                                                                      // Note that ref Bbox means that the bbox will be adjusted to match DEM data
                var heightMap        = _elevationService.GetHeightMap(ref bbox, dataset, downloadMissingFiles: true);
                var bboxTerrainSpace = bbox.ReprojectTo(dataset.SRID, outputSRID);                                                    // terrain coords
                timeLog.LogTime("Terrain height map");

                //=======================
                // Get entry elevation (need to reproject to DEM coordinate system first)
                // and sections entry elevations
                //
                _visualTopoService.ComputeFullCavityElevations(model, dataset, zFactor); // will add TerrainElevationAbove and entry elevations
                _visualTopoService.Create3DTriangulation(model);
                timeLog.LogTime("Cavity points elevation");

                // Model origin
                GeoPoint axisOriginWorldSpace = model.EntryPoint.ReprojectTo(model.SRID, outputSRID)
                                                .CenterOnOrigin(bboxTerrainSpace);
                Vector3 axisOriginModelSpace = model.EntryPoint.AsVector3();

                //=======================
                // Local transform function from model coordinates (relative to entry, in meters)
                // and global coordinates absolute in final 3D model space
                //
                IEnumerable <GeoPoint> TransformLine(IEnumerable <GeoPoint> line)
                {
                    var newLine = line.Translate(model.EntryPoint)             // Translate to entry (=> global topo coord space)
                                  .ReprojectTo(model.SRID, outputSRID)         // Reproject to terrain coord space
                                  .CenterOnOrigin(bboxTerrainSpace)            // Center on terrain space origin
                                  .CenterOnOrigin(axisOriginWorldSpace);

                    return(newLine);
                };


                //=======================
                // 3D model
                //
                var gltfModel = _gltfService.CreateNewModel();

                // Add X/Y/Z axis on entry point
                var axis = _meshService.CreateAxis();
                _gltfService.AddMesh(gltfModel, "Axis", axis, doubleSided: false);

                int i = 0;

                var triangulation = model.TriangulationFull3D.Clone()
                                    .Translate(axisOriginModelSpace)             // already zScaled if zFactor > 1
                                    .ReprojectTo(model.SRID, outputSRID)
                                    .CenterOnOrigin(bboxTerrainSpace)
                                    .CenterOnOrigin(axisOriginWorldSpace.AsVector3());
                gltfModel = _gltfService.AddMesh(gltfModel, "Cavite3D", model.TriangulationFull3D, VectorsExtensions.CreateColor(0, 255, 0), doubleSided: false);

                if (GENERATE_LINE3D)
                {
                    foreach (var line in model.Topology3D) // model.Topology3D is the graph of topo paths
                    {
                        // Add line to model
                        gltfModel = _gltfService.AddLine(gltfModel
                                                         , string.Concat("GPX", i++)    // name of 3D node
                                                         , TransformLine(line)          // call transform function
                                                         , color: VectorsExtensions.CreateColor(255, 0, 0, 128)
                                                         , lineWidth);
                    }
                }
                timeLog.LogTime("Topo 3D model");


                //axis = _meshService.CreateAxis(10,100);
                //_gltfService.AddMesh(gltfModel, "Axis", axis, doubleSided: false);

                if (generateTopoOnlyModel)
                {
                    // Uncomment this to save 3D model for topo only (without terrain)
                    gltfModel.SaveGLB(string.Concat(Path.GetFileNameWithoutExtension(vtopoFile) + $"Z{zFactor}_TopoOnly.glb"));
                }

                // Reproject and center height map coordinates
                heightMap = heightMap.ReprojectTo(dataset.SRID, outputSRID)
                            .CenterOnOrigin(bboxTerrainSpace)
                            .ZScale(zFactor)
                            .CenterOnOrigin(axisOriginWorldSpace);
                //.BakeCoordinates();
                timeLog.LogTime("Height map transform");

                //=======================
                // Textures
                //
                PBRTexture pbrTexture = null;
                if (imageryProvider != null)
                {
                    TileRange tiles    = _imageryService.DownloadTiles(bbox, imageryProvider, TEXTURE_TILES);
                    string    fileName = Path.Combine(outputDir, "Texture.jpg");
                    timeLog.LogTime("Imagery download");

                    Console.WriteLine("Construct texture...");
                    //TextureInfo texInfo = _imageryService.ConstructTexture(tiles, bbox, fileName, TextureImageFormat.image_jpeg);
                    var         topoTexture = model.Topology3D.SelectMany(l => l).Translate(model.EntryPoint).ReprojectTo(model.SRID, 4326);
                    TextureInfo texInfo     = _imageryService.ConstructTextureWithGpxTrack(tiles, bbox, fileName, TextureImageFormat.image_jpeg
                                                                                           , topoTexture, false);

                    pbrTexture = PBRTexture.Create(texInfo, null);
                    timeLog.LogTime("Texture creation");
                }
                //
                //=======================

                // Triangulate height map
                _logger.LogInformation($"Triangulating height map and generating 3D mesh...");

                gltfModel = _gltfService.AddTerrainMesh(gltfModel, heightMap, pbrTexture);
                gltfModel.SaveGLB(string.Concat(Path.GetFileNameWithoutExtension(vtopoFile) + $"Z{zFactor}.glb"));
                timeLog.LogTime("3D model");
            }
            catch (Exception ex)
            {
                _logger.LogError("Error :" + ex.Message);
            }
        }
Example #22
0
 /// <summary>
 /// Creates a new tile range index.
 /// </summary>
 /// <param name="tileRange"></param>
 public TileRangeIndex(TileRange tileRange)
 {
     _range = tileRange;
 }
        /// <summary>
        /// Returns all the nodes for the given tile range
        /// </summary>
        /// <param name="range">The tile range to match nodes against</param>
        /// <returns>The list of matching nodes from the db</returns>
        public IList<Node> GetNodes(TileRange range)
        {
            var tile_ids = SchemaTools.ConstructIdList(range);

            return GetNodesForTiles(tile_ids);
        }
Example #24
0
        private static string GetTileRange(int zoomLevel)
        {
            var z = TileRange.GetTileRangeForExtentAndZ(WebMercator.BoundingBox, zoomLevel, new TestTiledVectorLayer());

            return(z.ToString());
        }
Example #25
0
        /// <summary>
        /// Notifies this layer the mapview has changed.
        /// </summary>
        /// <param name="map"></param>
        /// <param name="zoomFactor"></param>
        /// <param name="center"></param>
        /// <param name="view"></param>
        /// <param name="extraView"></param>
        public override void ViewChanged(Map map, float zoomFactor, GeoCoordinate center, View2D view, View2D extraView)
        {
            if (_suspended)
            { // do not accept trigger changes if suspended.
                return;
            }

            if (!this.IsVisible)
            { // if the map is not visible also do not accept changes.
                return;
            }

            try
            {
                // calculate the current zoom level.
                var zoomLevel = (int)System.Math.Round(map.Projection.ToZoomLevel(zoomFactor), 0);

                if (zoomLevel >= _minZoomLevel && zoomLevel <= _maxZoomLevel)
                {
                    // build the bounding box.
                    var viewBox = view.OuterBox;
                    var box     = new GeoCoordinateBox(map.Projection.ToGeoCoordinates(viewBox.Min[0], viewBox.Min[1]),
                                                       map.Projection.ToGeoCoordinates(viewBox.Max[0], viewBox.Max[1]));

                    // build the tile range.
                    lock (_stack)
                    { // make sure the tile range is not in use.
                        _stack.Clear();

                        lock (_cache)
                        {
                            var tileRange = TileRange.CreateAroundBoundingBox(box, zoomLevel);
                            _currentZoom = zoomLevel;
                            foreach (var tile in tileRange.EnumerateInCenterFirst().Reverse())
                            {
                                if (tile.IsValid)
                                { // make sure all tiles are valid.
                                    Image2D temp;
                                    if (!_cache.TryPeek(tile, out temp) &&
                                        !_loading.Contains(tile))
                                    { // not cached and not loading.
                                        _stack.Push(tile);

                                        OsmSharp.Logging.Log.TraceEvent("LayerTile", Logging.TraceEventType.Information,
                                                                        "Queued tile: " + tile.ToString());
                                    }
                                }
                            }
                            _timer.Change(0, 250);
                        }

                        if (_stack.Count > 0)
                        { // reset the attempts.
                            lock (_attempts)
                            {
                                _attempts.Clear();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            { // don't worry about exceptions here.
                OsmSharp.Logging.Log.TraceEvent("LayerTile", Logging.TraceEventType.Error, ex.Message);
            }
        }
Example #26
0
        public void Run(DEMDataSet dataset, bool withTexture = true)
        {
            try
            {
                //_rasterService.GenerateDirectoryMetadata(dataset, false);
                Stopwatch sw        = Stopwatch.StartNew();
                string    modelName = $"Montagne Sainte Victoire {dataset.Name}";
                string    outputDir = Directory.GetCurrentDirectory();

                ImageryProvider provider = ImageryProvider.MapBoxSatelliteStreet;// new TileDebugProvider(new GeoPoint(43.5,5.5));

                // You can get your boox from https://geojson.net/ (save as WKT)
                string bboxWKT = "POLYGON((5.54888 43.519525, 5.61209 43.519525, 5.61209 43.565225, 5.54888 43.565225, 5.54888 43.519525))";
                //                string bboxWKT =
                //                    "POLYGON((5.594457381483949 43.545276557046044,5.652135604140199 43.545276557046044,5.652135604140199 43.52038635099936,5.594457381483949 43.52038635099936,5.594457381483949 43.545276557046044))";
                //                _logger.LogInformation($"Processing model {modelName}...");
                //
                //
                //                _logger.LogInformation($"Getting bounding box geometry...");
                var bbox = GeometryService.GetBoundingBox(bboxWKT);

                //var bbox = new BoundingBox(5.5613898348431485,5.597185285307553,43.49372969433046,43.50939068558466);
                _logger.LogInformation($"Getting height map data...");

                var heightMap = _elevationService.GetHeightMap(ref bbox, dataset);

                _logger.LogInformation($"Processing height map data ({heightMap.Count} coordinates)...");
                heightMap = heightMap
                            .ReprojectGeodeticToCartesian() // Reproject to 3857 (useful to get coordinates in meters)
                            .ZScale(2f);                    // Elevation exageration

                //=======================
                // Textures
                //
                PBRTexture pbrTexture = null;
                if (withTexture)
                {
                    Console.WriteLine("Download image tiles...");
                    TileRange tiles    = _imageryService.DownloadTiles(bbox, provider, TEXTURE_TILES);
                    string    fileName = Path.Combine(outputDir, "Texture.jpg");

                    Console.WriteLine("Construct texture...");
                    TextureInfo texInfo = _imageryService.ConstructTexture(tiles, bbox, fileName, TextureImageFormat.image_jpeg);

                    //
                    //=======================

                    //=======================
                    // Normal map
                    Console.WriteLine("Height map...");
                    //float Z_FACTOR = 0.00002f;

                    //hMap = hMap.CenterOnOrigin().ZScale(Z_FACTOR);
                    var normalMap = _imageryService.GenerateNormalMap(heightMap, outputDir);

                    pbrTexture = PBRTexture.Create(texInfo, normalMap);

                    //hMap = hMap.CenterOnOrigin(Z_FACTOR);
                    //
                    //=======================
                }
                // Triangulate height map
                // and add base and sides
                _logger.LogInformation($"Triangulating height map and generating 3D mesh...");

                var model = _sharpGltfService.CreateTerrainMesh(heightMap, pbrTexture);
                model.SaveGLB(Path.Combine(Directory.GetCurrentDirectory(), modelName + ".glb"));

                model = _sharpGltfService.CreateTerrainMesh(heightMap, GenOptions.Normals | GenOptions.BoxedBaseElevationMin);
                model.SaveGLB(Path.Combine(Directory.GetCurrentDirectory(), modelName + "_normalsBox.glb"));

                _logger.LogInformation($"Model exported as {Path.Combine(Directory.GetCurrentDirectory(), modelName + ".gltf")} and .glb");

                _logger.LogInformation($"Done in {sw.Elapsed:g}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
            }
        }
Example #27
0
        /// <summary>
        /// Notifies this layer the mapview has changed.
        /// </summary>
        /// <param name="map"></param>
        /// <param name="zoomFactor"></param>
        /// <param name="center"></param>
        /// <param name="view"></param>
        internal override void ViewChanged(Map map, float zoomFactor, GeoCoordinate center, View2D view)
        {
            // calculate the current zoom level.
            var zoomLevel = (int)System.Math.Round(map.Projection.ToZoomLevel(zoomFactor), 0);

            // build the boundingbox.
            var viewBox = view.OuterBox;
            var box = new GeoCoordinateBox (map.Projection.ToGeoCoordinates (viewBox.Min [0], viewBox.Min [1]),
                                            map.Projection.ToGeoCoordinates (viewBox.Max [0], viewBox.Max [1]));

            // build the tile range.
            lock (_tileRange)
            { // make sure the tile range is not in use.
                _tileRange = TileRange.CreateAroundBoundingBox(box, zoomLevel);
            }
        }
Example #28
0
        internal void Run(DEMDataSet dataSet, bool trackIn3D = true, bool generateTIN = false, int outputSrid = Reprojection.SRID_PROJECTED_LAMBERT_93)
        {
            try
            {
                string _gpxFile    = Path.Combine("SampleData", "GPX", "lake-pleasant-camping.gpx");
                bool   withTexture = true;
                float  Z_FACTOR    = 1.8f;
                float  Z_TRANSLATE_GPX_TRACK_METERS = 5;
                float  trailWidthMeters             = 5f;
                int    skipGpxPointsEvery           = 1;

                ImageryProvider provider = ImageryProvider.MapBoxSatellite; // new TileDebugProvider(null, maxDegreeOfParallelism: 1);//  ImageryProvider.MapBoxSatellite;

                string outputDir = Path.GetFullPath(".");

                //=======================
                /// Line strip from GPX
                ///
                // Get GPX points
                var segments = GpxImport.ReadGPX_Segments(_gpxFile);
                var points   = segments.SelectMany(seg => seg);
                var bbox     = points.GetBoundingBox().Scale(1.1, 1.1).ReprojectTo(4326, dataSet.SRID);
                // DEBUG
                // Test case : ASTER GDEMv3 : 5.5 43.5 Z=315
                // 303     307     308
                // 309    *315*    317
                // 314     321     324
                //points = GenerateDebugTrailPointsGenerateDebugTrailPoints(5.003, 5.006, 43.995, 43.997, 0.0001, 0.001);
                //points = GenerateDebugTrailPointsGenerateDebugTrailPoints(5.4990, 5.501, 43.4990, 43.501, 0.0001, 0.001);
                //points = GenerateDebugTrailPointsGenerateDebugTrailPoints(5.49, 5.51, 43.49, 43.51, 0.0005, 0.001);
                //bbox = points.GetBoundingBox().Scale(1.3,1.3);
                IEnumerable <GeoPoint> gpxPointsElevated = _elevationService.GetPointsElevation(points, dataSet);


                //
                //=======================

                //=======================
                /// Height map (get dem elevation for bbox)
                ///
                HeightMap hMap = _elevationService.GetHeightMap(ref bbox, dataSet);

                //                var refPoint = new GeoPoint(43.5, 5.5);
                //                hMap = hMap.BakeCoordinates();
                //                var hMapRefPoint = hMap.Coordinates.OrderBy(c => c.DistanceSquaredTo(refPoint)).First();
                //                var gpxRefPoint = gpxPointsElevated.OrderBy(c => c.DistanceSquaredTo(refPoint)).First();
                //                hMapRefPoint.Elevation += 60;
                //                gpxRefPoint.Elevation += 60;

                hMap = hMap.ReprojectTo(dataSet.SRID, outputSrid)
                       //.CenterOnOrigin()
                       .ZScale(Z_FACTOR)
                       .BakeCoordinates();
                //
                //=======================

                //=======================
                // Textures
                //
                PBRTexture pbrTexture = null;
                if (withTexture)
                {
                    Console.WriteLine("Download image tiles...");
                    TileRange tiles    = _imageryService.DownloadTiles(bbox, provider, 12);
                    string    fileName = Path.Combine(outputDir, "Texture.jpg");

                    Console.WriteLine("Construct texture...");
                    //TextureInfo texInfo = _imageryService.ConstructTextureWithGpxTrack(tiles, bbox, fileName, TextureImageFormat.image_jpeg, gpxPointsElevated, false);
                    TextureInfo texInfo = _imageryService.ConstructTexture(tiles, bbox, fileName, TextureImageFormat.image_jpeg);

                    //
                    //=======================

                    //=======================
                    // Normal map
                    Console.WriteLine("Height map...");
                    //float Z_FACTOR = 0.00002f;

                    //hMap = hMap.CenterOnOrigin().ZScale(Z_FACTOR);
                    //var normalMap = _imageryService.GenerateNormalMap(hMap, outputDir);
                    //pbrTexture = PBRTexture.Create(texInfo, normalMap);

                    pbrTexture = PBRTexture.Create(texInfo, null);

                    //hMap = hMap.CenterOnOrigin(Z_FACTOR);
                    //
                    //=======================
                }


                //=======================
                // MESH 3D terrain
                Console.WriteLine("Height map...");

                Console.WriteLine("GenerateTriangleMesh...");
                //hMap = _elevationService.GetHeightMap(bbox, _dataSet);
                ModelRoot model = null;
                if (generateTIN)
                {
                    model = TINGeneration.GenerateTIN(hMap, 10d, _sharpGltfService, pbrTexture, outputSrid);
                }
                else
                {
                    //hMap = hMap.CenterOnOrigin().ZScale(Z_FACTOR);
                    // generate mesh with texture
                    model = _sharpGltfService.CreateTerrainMesh(hMap, pbrTexture);
                }

                if (trackIn3D)
                {
                    // take 1 point evert nth
                    gpxPointsElevated = gpxPointsElevated.Where((x, i) => (i + 1) % skipGpxPointsEvery == 0);
                    gpxPointsElevated = gpxPointsElevated.ZTranslate(Z_TRANSLATE_GPX_TRACK_METERS)
                                        .ReprojectTo(dataSet.SRID, outputSrid)
                                        //.CenterOnOrigin()
                                        //.CenterOnOrigin(hMap.BoundingBox)
                                        .ZScale(Z_FACTOR);


                    model = _sharpGltfService.AddLine(model, "GPX", gpxPointsElevated, VectorsExtensions.CreateColor(255, 0, 0, 128), trailWidthMeters);
                }

                // model export
                Console.WriteLine("GenerateModel...");
                model.SaveGLB(Path.Combine(Directory.GetCurrentDirectory(), $"{GetType().Name} dst{dataSet.Name} TIN{generateTIN} Srid{outputSrid}.glb"));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
            }
        }
Example #29
0
 /**
  * @inheritDoc
  */
 public override TileRange GetTileCoordChildTileRange(int[] tileCoord, TileRange opt_tileRange = null, double[] opt_extent = null)
 {
     if (tileCoord[0] < this.MaxZoom) {
     var doubleX = 2 * tileCoord[1];
     var doubleY = 2 * tileCoord[2];
     return TileRange.CreateOrUpdate(
         doubleX, doubleX + 1,
         doubleY, doubleY + 1,
         opt_tileRange);
       } else {
     return null;
       }
 }
        public void GenerateModel(string bboxWkt, DEMDataSet litto3DDataset, ImageryProvider imageryProvider, float zFactor = 3f, bool withTexture = true, bool withboat = true, bool withWaterSurface = true, DEMDataSet fallbackDataset = null)
        {
            try
            {
                bool   centerOnOrigin = true;
                int    TEXTURE_TILES  = 20;
                string outputDir      = Directory.GetCurrentDirectory();

                string modelName = $"{litto3DDataset.ResolutionMeters}m_z{zFactor}_{imageryProvider.Name}-{DateTime.Now:yyyyMMdd-hhmmss}";

                _logger.LogInformation($"Getting height map data...");


                var bbox      = GeometryService.GetBoundingBox(bboxWkt).ReprojectTo(4326, litto3DDataset.SRID);
                var heightMap = _elevationService.GetHeightMap(ref bbox, litto3DDataset);

                heightMap = heightMap.BakeCoordinates();
                var nullCoordsEnumerator = heightMap.Coordinates.Where(c => (c.Elevation ?? litto3DDataset.NoDataValue) == litto3DDataset.NoDataValue);

                var interpolator = _elevationService.GetInterpolator(InterpolationMode.Bilinear);
                using (IRasterFile raster = _rasterService.OpenFile(@"D:\Data\ELEVATION_DO_NOT_DELETE\GEBCO2020\cote azur\gebco_2020_subset.tif", DEMFileType.GEOTIFF))
                    using (RasterFileDictionary dic = new RasterFileDictionary())
                    {
                        var metadata = raster.ParseMetaData(fallbackDataset.FileFormat);
                        dic.Add(metadata, raster);
                        foreach (var pt in nullCoordsEnumerator)
                        {
                            var proj = pt.ReprojectTo(litto3DDataset.SRID, fallbackDataset.SRID);
                            pt.Elevation = _elevationService.GetElevationAtPoint(raster, dic, metadata, proj.Latitude, proj.Longitude, 0, interpolator, NoDataBehavior.UseNoDataDefinedInDem);
                        }
                    }

                var nullCoords              = heightMap.Coordinates.Where(c => (c.Elevation ?? litto3DDataset.NoDataValue) == litto3DDataset.NoDataValue).ToList();
                var nullCoordsFallbackProj  = nullCoords.ReprojectTo(litto3DDataset.SRID, fallbackDataset.SRID, nullCoords.Count);
                var nullCoordsFallbackProj2 = _elevationService.GetPointsElevation(nullCoordsFallbackProj, fallbackDataset, InterpolationMode.Bilinear, NoDataBehavior.UseNoDataDefinedInDem);

                ModelGenerationTransform transform         = new ModelGenerationTransform(bbox, 3857, centerOnOrigin: centerOnOrigin, zFactor, centerOnZOrigin: false);
                ModelGenerationTransform transformFrom4326 = new ModelGenerationTransform(bbox.ReprojectTo(2154, 4326), 3857, centerOnOrigin: centerOnOrigin, zFactor, centerOnZOrigin: false);

                _logger.LogInformation($"Processing height map data ({heightMap.Count} coordinates)...");
                heightMap = transform.TransformHeightMap(heightMap);

                var min = heightMap.Coordinates.Where(g => (g.Elevation ?? 0d) > litto3DDataset.NoDataValue).Min(g => g.Elevation ?? 0d);
                heightMap.Coordinates = heightMap.Coordinates.Select(p =>
                {
                    if (p.Elevation.GetValueOrDefault(0) <= litto3DDataset.NoDataValue)
                    {
                        p.Elevation = min;
                    }
                    return(p);
                });

                //=======================
                // Textures
                //
                PBRTexture pbrTexture = null;
                if (withTexture)
                {
                    var bbox4326 = bbox.ReprojectTo(2154, 4326);
                    Console.WriteLine("Download image tiles...");
                    TileRange tiles    = _imageryService.DownloadTiles(bbox4326, imageryProvider, TEXTURE_TILES);
                    string    fileName = Path.Combine(outputDir, "Texture.jpg");

                    Console.WriteLine("Construct texture...");
                    //TextureInfo texInfo = _imageryService.ConstructTexture(tiles, bbox4326, fileName, TextureImageFormat.image_jpeg);

                    TextureInfo texInfo;
                    if (withboat)
                    {
                        var trackPoints = GetGeoPointFromGeoJson(BoatCourseGeoJson);
                        texInfo = _imageryService.ConstructTextureWithGpxTrack(tiles, bbox4326, fileName, TextureImageFormat.image_jpeg, trackPoints, drawGpxVertices: true, color: SixLabors.ImageSharp.PixelFormats.Rgba32.Green, 30);
                    }
                    else
                    {
                        texInfo = _imageryService.ConstructTexture(tiles, bbox4326, fileName, TextureImageFormat.image_jpeg);
                    }


                    //
                    //=======================

                    //=======================
                    // Normal map
                    Console.WriteLine("Height map...");
                    //float Z_FACTOR = 0.00002f;

                    //hMap = hMap.CenterOnOrigin().ZScale(Z_FACTOR);
                    //var normalMap = _imageryService.GenerateNormalMap(heightMap, outputDir);

                    pbrTexture = PBRTexture.Create(texInfo, null);// normalMap);

                    //hMap = hMap.CenterOnOrigin(Z_FACTOR);
                    //
                    //=======================
                }
                // Triangulate height map
                // and add base and sides
                _logger.LogInformation($"Triangulating height map and generating 3D mesh...");

                heightMap = heightMap.BakeCoordinates();
                var coords = heightMap.Coordinates.ToList();

                var model = _sharpGltfService.CreateTerrainMesh(heightMap, pbrTexture);



                if (withWaterSurface)
                {
                    var bottomLeft  = coords[heightMap.Width * (heightMap.Height - 1)].AsVector3(); bottomLeft.Z = 0;
                    var topRight    = coords[heightMap.Width - 1].AsVector3(); topRight.Z = 0;
                    var topLeft     = coords[0].AsVector3(); topLeft.Z = 0;
                    var bottomRight = coords.Last().AsVector3(); bottomRight.Z = 0;

                    var waterSurface = _meshService.CreateWaterSurface(bottomLeft, topRight, topLeft, bottomRight,
                                                                       minZ: (float)min,
                                                                       color: VectorsExtensions.CreateColor(0, 150, 255, 64));
                    model = _sharpGltfService.AddMesh(model, "Water", waterSurface, doubleSided: true);
                }

                if (withboat)
                {
                    var boatInitPos = centerOnOrigin ? new GeoPoint(0, 0).AsVector3() : new GeoPoint(43.010625204304304, 6.3711613671060086).ReprojectTo(4326, 3857).AsVector3();
                    var axis        = _meshService.CreateAxis(2, 10, 3, 3).Translate(boatInitPos);
                    model = _sharpGltfService.AddMesh(model, "Boat", axis, doubleSided: false);
                    var boatCourse = transformFrom4326.TransformPoints(GetGeoPointFromGeoJson(BoatCourseGeoJson)).ToList(); //ReprojectGeodeticToCartesian().CenterOnOrigin().ToList();
                    model = _sharpGltfService.AddLine(model, "BoatCourse", boatCourse, VectorsExtensions.CreateColor(255, 0, 0, 128), 4);
                }



                model.SaveGLB(Path.Combine(Directory.GetCurrentDirectory(), modelName + ".glb"));



                _logger.LogInformation($"Model exported as {Path.Combine(Directory.GetCurrentDirectory(), modelName + ".gltf")} and .glb");

                //var point = new GeoPoint(43.01142119356318, 6.385200681010872).ReprojectTo(4326, 2154);
                //point = _elevationService.GetPointElevation(point, litto3DDataset);
            }
            catch (Exception e)
            {
                _logger.LogError(e, e.Message);
            }
        }
Example #31
0
        public void TestTileSpiralEnumerator()
        {
            // simplest case, range with one tile.
            var range      = new TileRange(0, 0, 0, 0, 16);
            var enumerator = new TileRange.TileRangeCenteredEnumerator(range);

            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsFalse(enumerator.MoveNext());

            // a range with 2 tiles.
            range      = new TileRange(0, 0, 1, 0, 16);
            enumerator = new TileRange.TileRangeCenteredEnumerator(range);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsFalse(enumerator.MoveNext());

            // a range with 4 tiles.
            range      = new TileRange(0, 0, 1, 1, 16);
            enumerator = new TileRange.TileRangeCenteredEnumerator(range);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsFalse(enumerator.MoveNext());

            // a range with 6 tiles.
            range      = new TileRange(0, 0, 2, 1, 16);
            enumerator = new TileRange.TileRangeCenteredEnumerator(range);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(2, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(2, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsFalse(enumerator.MoveNext());

            // a range with 9 tiles.
            range      = new TileRange(0, 0, 2, 2, 16);
            enumerator = new TileRange.TileRangeCenteredEnumerator(range);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(2, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(2, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(2, enumerator.Current.X);
            Assert.AreEqual(2, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(2, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(2, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsFalse(enumerator.MoveNext());

            // rudementary tests.
            range = new TileRange(-10, -10, 10, 10, 16);
            var tiles = new HashSet <Tile>(range.EnumerateInCenterFirst());

            Assert.AreEqual(range.Count, tiles.Count);

            // rudementary tests.
            range = new TileRange(33638, 21862, 33640, 21864, 16);
            tiles = new HashSet <Tile>(range.EnumerateInCenterFirst());
            Assert.AreEqual(range.Count, tiles.Count);
        }
        private Location3DModelResponse Generate3DLocationModel(Location3DModelRequest request, Location3DModelSettings settings)
        {
            Location3DModelResponse response = new Location3DModelResponse();

            try
            {
                bool imageryFailed = false;
                using (TimeSpanBlock timer = new TimeSpanBlock($"3D model {request.Id}", _logger))
                {
                    BoundingBox bbox = GetBoundingBoxAroundLocation(request.Latitude, request.Longitude, settings.SideSizeKm);

                    HeightMap hMap      = _elevationService.GetHeightMap(ref bbox, settings.Dataset);
                    var       transform = new ModelGenerationTransform(bbox, Reprojection.SRID_PROJECTED_MERCATOR, centerOnOrigin: true, settings.ZScale, centerOnZOrigin: true);

                    response.Attributions.AddRange(settings.Attributions);   // will be added to the model
                    response.Attributions.Add(settings.Dataset.Attribution); // will be added to the model


                    PBRTexture pbrTexture = null;
                    if (settings.ImageryProvider != null)
                    {
                        response.Attributions.Add(settings.ImageryProvider.Attribution); // will be added to the model

                        // Imagery
                        TileRange tiles = _imageryService.ComputeBoundingBoxTileRange(bbox, settings.ImageryProvider, settings.MinTilesPerImage);
                        Debug.Assert(tiles.Count < 400);

                        tiles = _imageryService.DownloadTiles(tiles, settings.ImageryProvider);

                        string      fileName = Path.Combine(settings.OutputDirectory, $"{request.Id}_Texture.jpg");
                        TextureInfo texInfo  = _imageryService.ConstructTexture(tiles, bbox, fileName, TextureImageFormat.image_jpeg);

                        transform.BoundingBox = bbox;
                        hMap = transform.TransformHeightMap(hMap);


                        //var normalMap = _imageryService.GenerateNormalMap(hMap, settings.OutputDirectory, $"{request.Id}_normalmap.png");
                        pbrTexture = PBRTexture.Create(texInfo);
                    }

                    // Center on origin
                    //hMap = hMap.CenterOnOrigin(out Matrix4x4 transform).BakeCoordinates();
                    //response.Origin = new GeoPoint(request.Latitude, request.Longitude).ReprojectTo(Reprojection.SRID_GEODETIC, Reprojection.SRID_PROJECTED_MERCATOR);

                    ModelRoot model = _gltfService.CreateNewModel();

                    //=======================
                    // Buildings
                    if (settings.OsmBuildings)
                    {
                        model = _sampleOsmProcessor.Run(model, OsmLayer.Buildings, bbox, transform, computeElevations: true, settings.Dataset, settings.DownloadMissingFiles);
                    }


                    if (settings.GenerateTIN)
                    {
                        model = AddTINMesh(model, hMap, 2d, _gltfService, pbrTexture, Reprojection.SRID_PROJECTED_MERCATOR);
                    }
                    else
                    {
                        model = _gltfService.AddTerrainMesh(model, hMap, pbrTexture);
                    }
                    model.Asset.Generator = "DEM Net Elevation API with SharpGLTF";
                    //model.TryUseExtrasAsList(true).AddRange(response.Attributions);
                    model.SaveGLB(Path.Combine(settings.OutputDirectory, string.Concat(imageryFailed ? "imageryFailed_" : "", settings.ModelFileNameGenerator(settings, request))));

                    // cleanup
                    //if (pbrTexture != null)
                    //{
                    //    if (pbrTexture.NormalTexture != null) File.Delete(pbrTexture.NormalTexture.FilePath);
                    //    File.Delete(pbrTexture.BaseColorTexture.FilePath);
                    //}

                    response.Elapsed  = timer.Elapsed;
                    response.NumTiles = pbrTexture.BaseColorTexture.TileCount;
                }
            }
            catch (Exception)
            {
                throw;
            }
            return(response);
        }
Example #33
0
 public void TestTileRangeCount()
 {
     var range = new TileRange(0, 0, 0, 0, 16);
     Assert.AreEqual(1, range.Count);
     range = new TileRange(0, 0, 1, 0, 16);
     Assert.AreEqual(2, range.Count);
     range = new TileRange(0, 0, 1, 1, 16);
     Assert.AreEqual(4, range.Count);
 }
Example #34
0
        static void Main(string[] args)
        {
            OsmSharp.Logging.Log.Enable();
            OsmSharp.Logging.Log.RegisterListener(new OsmSharp.WinForms.UI.Logging.ConsoleTraceListener());

            var outputDir   = @"c:\temp\tiles";
            var mbtilesFile = outputDir + "\\tiles.mbtiles";

            SQLiteConnection.CreateFile(mbtilesFile);
            var mbtiles = new SQLiteConnection(string.Format("Data Source={0};Version=3;", mbtilesFile));

            mbtiles.Open();
            var query = new SQLiteCommand(mbtiles);

            query.CommandText = "CREATE TABLE metadata (name text, value text);";
            query.ExecuteNonQuery();
            new SQLiteCommand(mbtiles);
            query.CommandText = "CREATE TABLE tiles (zoom_level integer, tile_column integer, tile_row integer, tile_data blob);";
            query.ExecuteNonQuery();
            query             = new SQLiteCommand(mbtiles);
            query.CommandText = "INSERT INTO metadata (name, value) VALUES ('name', 'tiles');" +
                                "INSERT INTO metadata (name, value) VALUES ('type', 'baselayer');" +
                                "INSERT INTO metadata (name, value) VALUES ('version', '1');" +
                                "INSERT INTO metadata (name, value) VALUES ('minzoom', '5');" +
                                "INSERT INTO metadata (name, value) VALUES ('maxzoom', '6');" +
                                "INSERT INTO metadata (name, value) VALUES ('version', '1');" +
                                "INSERT INTO metadata (name, value) VALUES ('description', 'A description of this layer');" +
                                "INSERT INTO metadata (name, value) VALUES ('bounds', '-5.2294921875,42.195968776291780,8.50341796875,51.248163159055906');" +
                                "INSERT INTO metadata (name, value) VALUES ('format', 'png');";
            query.ExecuteNonQuery();
            query             = new SQLiteCommand(mbtiles);
            query.CommandText = "INSERT INTO tiles VALUES (:zoom_level, :tile_column, :tile_row, :tile_data) ;";
            query.Parameters.Add(new SQLiteParameter(@"zoom_level", DbType.Int64));
            query.Parameters.Add(new SQLiteParameter(@"tile_column", DbType.Int64));
            query.Parameters.Add(new SQLiteParameter(@"tile_row", DbType.Int64));
            query.Parameters.Add(new SQLiteParameter(@"tile_data", DbType.Binary));

            var url = "http://localhost:1234/default/{z}/{x}/{y}.png";
            var box = new GeoCoordinateBox(
                new GeoCoordinate(42.195968776291780, -5.2294921875),
                new GeoCoordinate(51.248163159055906, 8.50341796875));
            var minZoom = 5;
            var maxZoom = 6;

            // download tiles.
            for (var zoom = maxZoom; zoom >= minZoom; zoom--)
            {
                var tileRange = TileRange.CreateAroundBoundingBox(box, zoom);
                OsmSharp.Logging.Log.TraceEvent(string.Empty, OsmSharp.Logging.TraceEventType.Information,
                                                string.Format("Downloading {0} tiles at zoom {1}.",
                                                              tileRange.Count, zoom));
                foreach (var tile in tileRange)
                {
                    // download tile.
                    var data = Download(url, tile);

                    // save tile.
                    var tileDir = new DirectoryInfo(Path.Combine(outputDir,
                                                                 tile.Zoom.ToString(), tile.X.ToString()));
                    if (!tileDir.Exists)
                    { // creates target dir.
                        tileDir.Create();
                    }
                    var tileFile = new FileInfo(Path.Combine(tileDir.ToString(),
                                                             tile.Y.ToString() + ".png"));
                    using (var outputStream = tileFile.OpenWrite())
                    {
                        outputStream.Write(data, 0, data.Length);
                    }

                    var inverted = tile.InvertY();

                    query.Parameters[0].Value = zoom;
                    query.Parameters[1].Value = tile.X;
                    query.Parameters[2].Value = inverted.Y;
                    query.Parameters[3].Value = data;
                    query.ExecuteNonQuery();

                    Thread.Sleep(100);
                }
            }

            mbtiles.Close();
        }
Example #35
0
        public void TestTileSpiralEnumerator()
        {
            // simplest case, range with one tile.
            var range = new TileRange(0, 0, 0, 0, 16);
            var enumerator = new TileRange.TileRangeCenteredEnumerator(range);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsFalse(enumerator.MoveNext());

            // a range with 2 tiles.
            range = new TileRange(0, 0, 1, 0, 16);
            enumerator = new TileRange.TileRangeCenteredEnumerator(range);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsFalse(enumerator.MoveNext());

            // a range with 4 tiles.
            range = new TileRange(0, 0, 1, 1, 16);
            enumerator = new TileRange.TileRangeCenteredEnumerator(range);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsFalse(enumerator.MoveNext());

            // a range with 6 tiles.
            range = new TileRange(0, 0, 2, 1, 16);
            enumerator = new TileRange.TileRangeCenteredEnumerator(range);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(2, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(2, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsFalse(enumerator.MoveNext());

            // a range with 9 tiles.
            range = new TileRange(0, 0, 2, 2, 16);
            enumerator = new TileRange.TileRangeCenteredEnumerator(range);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(2, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(2, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(2, enumerator.Current.X);
            Assert.AreEqual(2, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(1, enumerator.Current.X);
            Assert.AreEqual(2, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(2, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(1, enumerator.Current.Y);
            Assert.IsTrue(enumerator.MoveNext());
            Assert.AreEqual(0, enumerator.Current.X);
            Assert.AreEqual(0, enumerator.Current.Y);
            Assert.IsFalse(enumerator.MoveNext());

            // rudementary tests.
            range = new TileRange(-10, -10, 10, 10, 16);
            var tiles = new HashSet<Tile>(range.EnumerateInCenterFirst());
            Assert.AreEqual(range.Count, tiles.Count);

            // rudementary tests.
            range = new TileRange(33638, 21862, 33640, 21864, 16);
            tiles = new HashSet<Tile>(range.EnumerateInCenterFirst());
            Assert.AreEqual(range.Count, tiles.Count);
        }
Example #36
0
        /// <summary>
        /// Returns all objects in the given bounding box and that pass the given filter.
        /// </summary>
        /// <param name="box"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public override IList <OsmGeo> Get(GeoCoordinateBox box, OsmSharp.Osm.Filters.Filter filter)
        {
            List <OsmGeo> res = new List <OsmGeo>();

            // create a range or tiles around the given bounding box.
            TileRange range = TileRange.CreateAroundBoundingBox(box, 14);

            // build all redis keys for the given boxes.
            var hashKeys = new List <string>();

            foreach (Tile tile in range)
            {
                hashKeys.Add(tile.Id.ToString());
            }

            byte[][]         box_members = _client.SUnion(hashKeys.ToArray());
            HashSet <string> nodeKeys    = new HashSet <string>();

            foreach (byte[] box_member in box_members)
            {
                long   node_id  = BitConverter.ToInt64(box_member, 0);
                string node_key = PrimitiveExtensions.BuildNodeRedisKey(node_id);
                nodeKeys.Add(node_key);
            }

            List <RedisNode> redisNodes = _clientNode.GetValues(new List <string>(nodeKeys));
            var nodeIds = new List <long>();

            foreach (RedisNode redisNode in redisNodes)
            {
                // test if the node is in the given bb.
                GeoCoordinate coordinate = new GeoCoordinate(redisNode.Latitude.Value, redisNode.Longitude.Value);
                if (box.IsInside(coordinate))
                {
                    res.Add(PrimitiveExtensions.ConvertFrom(redisNode));
                    nodeIds.Add(redisNode.Id.Value);
                }
            }

            // load all ways that contain the nodes that have been found.
            res.AddRange(this.GetWaysFor(nodeIds));

            // get relations containing any of the nodes or ways in the current results-list.
            List <Relation> relations   = new List <Relation>();
            HashSet <long>  relationIds = new HashSet <long>();

            foreach (OsmGeo osmGeo in res)
            {
                IList <Relation> relationsFor = this.GetRelationsFor(osmGeo);
                foreach (Relation relation in relationsFor)
                {
                    if (!relationIds.Contains(relation.Id.Value))
                    {
                        relations.Add(relation);
                        relationIds.Add(relation.Id.Value);
                    }
                }
            }

            // recursively add all relations containing other relations as a member.
            do
            {
                res.AddRange(relations); // add previous relations-list.
                List <Relation> newRelations = new List <Relation>();
                foreach (OsmGeo osmGeo in relations)
                {
                    IList <Relation> relationsFor = this.GetRelationsFor(osmGeo);
                    foreach (Relation relation in relationsFor)
                    {
                        if (!relationIds.Contains(relation.Id.Value))
                        {
                            newRelations.Add(relation);
                            relationIds.Add(relation.Id.Value);
                        }
                    }
                }
                relations = newRelations;
            } while (relations.Count > 0);

            if (filter != null)
            {
                List <OsmGeo> filtered = new List <OsmGeo>();
                foreach (OsmGeo geo in res)
                {
                    if (filter.Evaluate(geo))
                    {
                        filtered.Add(geo);
                    }
                }
            }

            return(res);
        }
Example #37
0
        internal void Run(ServiceProvider serviceProvider)
        {
            bool              useTIN           = false; // still buggy with SRID 3857
            int               v_outSrid        = Reprojection.SRID_PROJECTED_MERCATOR;
            IglTFService      glTF             = serviceProvider.GetService <IglTFService>();
            IElevationService elevationService = serviceProvider.GetService <IElevationService>();

            string outputDir = Path.GetFullPath(Path.Combine(_outputDirectory, "glTF"));

            Logger.Info("============================");
            Logger.Info($"= {nameof(TextureSamples)}");
            Logger.Info("============================");
            Logger.Info($"= {nameof(TextureSamples)} : Datadirectory report");


            // Get GPX points
            var bbox = GeometryService.GetBoundingBox(_bboxWkt);

            //=======================
            // Textures
            //
            TextureInfo texInfo = null;


            ImageryService imageryService = new ImageryService();

            Console.WriteLine("Download image tiles...");
            TileRange tiles = imageryService.DownloadTiles(bbox, ImageryProvider.StamenToner, 1);

            Console.WriteLine("Construct texture...");
            string fileName = Path.Combine(outputDir, "Texture.jpg");

            texInfo = imageryService.ConstructTexture(tiles, bbox, fileName, TextureImageFormat.image_jpeg);

            //
            //=======================

            //=======================
            // Normal map
            Console.WriteLine("Height map...");
            float     Z_FACTOR   = 2f;
            HeightMap hMapNormal = elevationService.GetHeightMap(bbox, _normalsDataSet);

            //HeightMap hMapNormal = _elevationService.GetHeightMap(bbox, Path.Combine(_localdatadir, "ETOPO1", "ETOPO1_Bed_g_geotiff.tif"), DEMFileFormat.GEOTIFF);

            hMapNormal = hMapNormal.ReprojectTo(4326, v_outSrid);
            //hMapNormal = hMapNormal.ReprojectGeodeticToCartesian();

            Console.WriteLine("Generate normal map...");
            TextureInfo normal = imageryService.GenerateNormalMap(hMapNormal, outputDir);
            //
            //=======================

            //=======================
            // Get height map
            HeightMap hMap = elevationService.GetHeightMap(bbox, _meshDataSet);
            //HeightMap hMap = _elevationService.GetHeightMap(bbox, Path.Combine(_localdatadir, "ETOPO1","ETOPO1_Bed_g_geotiff.tif"), DEMFileFormat.GEOTIFF);

            //=======================
            // UV mapping (before projection)
            PBRTexture pBRTexture = PBRTexture.Create(texInfo, normal, imageryService.ComputeUVMap(hMap, texInfo));

            hMap = hMap.ReprojectTo(4326, v_outSrid);
            hMap = hMap.CenterOnOrigin().ZScale(Z_FACTOR);


            //=======================


            //=======================
            // MESH 3D terrain

            List <MeshPrimitive> meshes = new List <MeshPrimitive>();
            // generate mesh with texture
            MeshPrimitive triangleMesh;

            if (useTIN)
            {
                Console.WriteLine("Create TIN...");
                //triangleMesh = GenerateTIN(hMapTIN, glTF, pBRTexture);
                triangleMesh = TINGeneration.GenerateTIN(hMap, 10d, glTF, pBRTexture, v_outSrid);
            }
            else
            {
                Console.WriteLine("GenerateTriangleMesh...");
                triangleMesh = glTF.GenerateTriangleMesh_Boxed(hMap);
            }
            meshes.Add(triangleMesh);

            // model export
            Console.WriteLine("GenerateModel...");
            Model model = glTF.GenerateModel(meshes, this.GetType().Name);

            glTF.Export(model, outputDir, $"{GetType().Name} NONormal", false, true);
        }
Example #38
0
        /// <summary>
        /// Returns all primitives from this layer visible for the given parameters.
        /// </summary>
        /// <param name="zoomFactor"></param>
        /// <param name="view"></param>
        /// <returns></returns>
        public override IEnumerable <Primitive2D> Get(float zoomFactor, View2D view)
        {
            var primitives = new List <Primitive2D>();

            //if(_suspended)
            //{ // just return an empty primitives list if suspended.
            //    return primitives;
            //}
            try
            {
                // calculate the current zoom level.
                var zoomLevel = (int)System.Math.Round(_projection.ToZoomLevel(zoomFactor), 0);

                if (zoomLevel >= _minZoomLevel && zoomLevel <= _maxZoomLevel)
                {
                    // build the bounding box.
                    var viewBox = view.OuterBox;
                    var box     = new GeoCoordinateBox(_projection.ToGeoCoordinates(viewBox.Min[0], viewBox.Min[1]),
                                                       _projection.ToGeoCoordinates(viewBox.Max[0], viewBox.Max[1]));

                    var tileRange      = TileRange.CreateAroundBoundingBox(box, zoomLevel);
                    var tileRangeIndex = new TileRangeIndex(tileRange);

                    var primitivePerTile = new Dictionary <Tile, Primitive2D>();
                    lock (_cache)
                    {
                        Image2D temp;
                        foreach (var tile in _cache)
                        {
                            if (tile.Value.IsVisibleIn(view))
                            {
                                tileRangeIndex.Add(tile.Key);
                                primitivePerTile.Add(tile.Key, tile.Value);

                                var minZoom = _projection.ToZoomFactor(tile.Key.Zoom - _zoomMinOffset);
                                var maxZoom = _projection.ToZoomFactor(tile.Key.Zoom + (1 - _zoomMinOffset));
                                if (zoomFactor < maxZoom && zoomFactor > minZoom)
                                { // just hit the cache for tiles of this zoom level.
                                    _cache.TryGet(tile.Key, out temp);
                                }
                            }
                        }

                        // set the ascending flag.
                        if (_previousZoomFactor != zoomFactor)
                        { // only change flag when difference.
                            _ascending          = (_previousZoomFactor < zoomFactor);
                            _previousZoomFactor = zoomFactor;
                        }

                        // get candidate tiles for every tile.
                        var selectedTiles = new List <Tile>();
                        foreach (var tile in tileRange)
                        {
                            var best = tileRangeIndex.ChooseBest(tile, _ascending);
                            foreach (var bestTile in best)
                            {
                                if (!selectedTiles.Contains(bestTile))
                                { // make sure no doubles are added!
                                    selectedTiles.Add(bestTile);
                                }
                            }
                        }

                        // sort according to the tiles index.
                        selectedTiles.Sort(delegate(Tile x, Tile y)
                        {
                            return(TileRangeIndex.TileWeight(tileRange.Zoom, x.Zoom, !_ascending).CompareTo(
                                       TileRangeIndex.TileWeight(tileRange.Zoom, y.Zoom, !_ascending)));
                        });
                        selectedTiles.Reverse();

                        // recursively remove tiles.
                        for (int idx = selectedTiles.Count; idx > 0; idx--)
                        {
                            if (selectedTiles[selectedTiles.Count - idx].IsOverlappedBy(
                                    selectedTiles.GetRange(selectedTiles.Count - idx + 1, selectedTiles.Count - (selectedTiles.Count - idx + 1))))
                            {
                                selectedTiles.RemoveAt(selectedTiles.Count - idx);
                            }
                        }

                        // TODO: trim this collection so that only tiles remain close to the zoom level not overlapping.
                        Image2D primitive;
                        foreach (Tile tile in selectedTiles)
                        {
                            if (_cache.TryPeek(tile, out primitive))
                            { // add to the primitives list.
                                primitives.Add(primitive);
                            }
                        }
                    }
                }
                OsmSharp.Logging.Log.TraceEvent("LayerTile", Logging.TraceEventType.Information,
                                                string.Format("LayerTile returned {0} primitives.", primitives.Count));
                return(primitives);
            }
            catch (Exception ex)
            { // don't worry about exceptions here.
                OsmSharp.Logging.Log.TraceEvent("LayerTile", Logging.TraceEventType.Error, ex.Message);
            }
            return(primitives);
        }
Example #39
0
        private void Buildings3DOnly()
        {
            string outputDir = Directory.GetCurrentDirectory();

            string WKT_SF_BIG        = "POLYGON((-122.53517427420718 37.81548554152065,-122.35149660086734 37.81548554152065,-122.35149660086734 37.70311455416941,-122.53517427420718 37.70311455416941,-122.53517427420718 37.81548554152065))";
            string WKT_SF_SMALL      = "POLYGON((-122.42722692299768 37.81034598808797, -122.38886060524865 37.81034598808797, -122.38886060524865 37.784573673820816, -122.42722692299768 37.784573673820816, -122.42722692299768 37.81034598808797))";
            string WKT_SF_SUPERSMALL = "POLYGON((-122.41063177228989 37.80707295150412,-122.40904390455307 37.80707295150412,-122.40904390455307 37.806064225434206,-122.41063177228989 37.806064225434206,-122.41063177228989 37.80707295150412))";

            // FULL
            string WKT_PRIPYAT_FULL = "POLYGON((30.021919548702254 51.41813804241615,30.083030998897566 51.41813804241615,30.083030998897566 51.389438684773985,30.021919548702254 51.389438684773985,30.021919548702254 51.41813804241615))";
            // Cas 1
            //string WKT_PRIPYAT = "POLYGON((30.05430313958436 51.404795567637294,30.055118531124887 51.404795567637294,30.055118531124887 51.40432372279637,30.05430313958436 51.40432372279637,30.05430313958436 51.404795567637294))";
            // cas 2
            //string WKT_PRIPYAT = "POLYGON((30.062877280833636 51.40748141189236,30.063456637980853 51.40748141189236,30.063456637980853 51.40716017522757,30.062877280833636 51.40716017522757,30.062877280833636 51.40748141189236))";
            // cas 3
            //string WKT_PRIPYAT = "POLYGON((30.065251398582948 51.407283441091266,30.066243815918458 51.407283441091266,30.066243815918458 51.40558353075506,30.065251398582948 51.40558353075506,30.065251398582948 51.407283441091266))";

            string WKT_PRIPRYAT_SOMEROADS = "POLYGON((30.062684362726948 51.40792711901257,30.064690655070088 51.40792711901257,30.064690655070088 51.40693664170241,30.062684362726948 51.40693664170241,30.062684362726948 51.40792711901257))";

            // SF Big: POLYGON((-122.53517427420718 37.81548554152065,-122.35149660086734 37.81548554152065,-122.35149660086734 37.70311455416941,-122.53517427420718 37.70311455416941,-122.53517427420718 37.81548554152065))
            // SF Small: POLYGON((-122.41967382241174 37.81034598808797,-122.39761533547326 37.81034598808797,-122.39761533547326 37.79162804294824,-122.41967382241174 37.79162804294824,-122.41967382241174 37.81034598808797))

            // Napoli, multi polygon (https://www.openstreetmap.org/relation/8955771)
            //new BoundingBox(14.364430059744153, 14.365218629194532, 40.78433307340424, 40.785023575175295);

            string WKT_AIX_FULL        = "POLYGON((5.402291662243135 43.565714431347274,5.48056925013376 43.565714431347274,5.48056925013376 43.50797300081391,5.402291662243135 43.50797300081391,5.402291662243135 43.565714431347274))";
            string WKT_AIX_WITHTERRAIN = "POLYGON((5.440657648511835 43.55957815383877,5.444434198804804 43.55957815383877,5.444434198804804 43.5579454365131,5.440657648511835 43.5579454365131,5.440657648511835 43.55957815383877))";
            string WKT_AIX_SMALLOSMBUG = "POLYGON((5.441805234256467 43.55910060792738,5.442684998813352 43.55910060792738,5.442684998813352 43.55877017799191,5.441805234256467 43.55877017799191,5.441805234256467 43.55910060792738))";
            string WKT_MONACO          = "POLYGON((7.392147587957001 43.75577569838535,7.4410710803886415 43.75577569838535,7.4410710803886415 43.71757458493263,7.392147587957001 43.71757458493263,7.392147587957001 43.75577569838535))";

            string WKT_MONACO_DEBUG = "POLYGON((7.421709439122424 43.73663530909531,7.433961769902453 43.73663530909531,7.433961769902453 43.733007331111345,7.421709439122424 43.733007331111345,7.421709439122424 43.73663530909531))";//"POLYGON((7.426780270757294 43.73870913810349,7.432520198049164 43.73870913810349,7.432520198049164 43.73501926928533,7.426780270757294 43.73501926928533,7.426780270757294 43.73870913810349))";
            string WKT_HK           = "POLYGON((114.13119740014092 22.360520982593926,114.21050495629326 22.360520982593926,114.21050495629326 22.28874575980822,114.13119740014092 22.28874575980822,114.13119740014092 22.360520982593926))";
            string WKT_FRISCO       = "POLYGON((-122.5235839391063 37.81433638393927,-122.36222224477036 37.81433638393927,-122.36222224477036 37.71228516909579,-122.5235839391063 37.71228516909579,-122.5235839391063 37.81433638393927))";
            string WKT_DEFENSE      = "POLYGON((2.222075572216413 48.902615468120246,2.3024130966304757 48.902615468120246,2.3024130966304757 48.86355756505397,2.222075572216413 48.86355756505397,2.222075572216413 48.902615468120246))";

            DEMDataSet dataset           = DEMDataSet.NASADEM;
            var        name              = nameof(WKT_DEFENSE);
            var        bbox              = GeometryService.GetBoundingBox(WKT_DEFENSE);
            bool       computeElevations = true;

            ModelRoot model       = _gltfService.CreateNewModel();
            bool      withTerrain = false;

            if (withTerrain)
            {
                var heightMap = _elevationService.GetHeightMap(ref bbox, dataset);
                var transform = new ModelGenerationTransform(bbox, Reprojection.SRID_PROJECTED_MERCATOR, centerOnOrigin: true, ZScale, centerOnZOrigin: true);
                heightMap = transform.TransformHeightMap(heightMap);
                TileRange tiles = _imageryService.DownloadTiles(bbox, ImageryProvider.MapBoxSatellite, 15);

                string      fileName   = Path.Combine(outputDir, "Texture.jpg");
                TextureInfo texInfo    = _imageryService.ConstructTexture(tiles, bbox, fileName, TextureImageFormat.image_jpeg);
                var         pbrTexture = PBRTexture.Create(texInfo, null);

                model = _osmProcessor.Run(model, OsmLayer.Buildings | OsmLayer.Highways, bbox, transform, computeElevations, dataset, downloadMissingFiles: true);
                model = _gltfService.AddTerrainMesh(model, heightMap, pbrTexture);
            }
            else
            {
                var transform = new ModelGenerationTransform(bbox, Reprojection.SRID_PROJECTED_MERCATOR, centerOnOrigin: true, ZScale, centerOnZOrigin: true);
                model = _osmProcessor.Run(model, OsmLayer.Buildings | OsmLayer.Highways, bbox, transform, computeElevations, dataset, downloadMissingFiles: true);
            }

            model.SaveGLB(Path.Combine(Directory.GetCurrentDirectory(), name + ".glb"));
        }
Example #40
0
        private (ModelRoot Model, double widthMeters, double heightMeters, double averageElevation, BoundingBox projectedBbox) GenerateSampleModel(BoundingBox bbox, DEMDataSet dataset, bool withTexture = true)
        {
            try
            {
                int    TEXTURE_TILES = 8; // 4: med, 8: high
                string outputDir     = Directory.GetCurrentDirectory();

                //_rasterService.GenerateDirectoryMetadata(dataset, false);

                ImageryProvider provider = ImageryProvider.MapBoxSatellite;// new TileDebugProvider(new GeoPoint(43.5,5.5));


                _logger.LogInformation($"Getting height map data...");

                var heightMap = _elevationService.GetHeightMap(ref bbox, dataset);

                var wgs84bbox = bbox;
                ModelGenerationTransform transform = new ModelGenerationTransform(bbox, 3857, true, 1.5f, true);

                _logger.LogInformation($"Processing height map data ({heightMap.Count} coordinates)...");
                heightMap = transform.TransformHeightMap(heightMap);


                //=======================
                // Textures
                //
                PBRTexture pbrTexture = null;
                if (withTexture)
                {
                    Console.WriteLine("Download image tiles...");
                    TileRange tiles    = _imageryService.DownloadTiles(bbox, provider, TEXTURE_TILES);
                    string    fileName = Path.Combine(outputDir, "Texture.jpg");

                    Console.WriteLine("Construct texture...");
                    TextureInfo texInfo = _imageryService.ConstructTexture(tiles, bbox, fileName, TextureImageFormat.image_jpeg);

                    //
                    //=======================

                    //=======================
                    // Normal map
                    Console.WriteLine("Height map...");
                    //float Z_FACTOR = 0.00002f;

                    //hMap = hMap.CenterOnOrigin().ZScale(Z_FACTOR);
                    //var normalMap = _imageryService.GenerateNormalMap(heightMap, outputDir);

                    pbrTexture = PBRTexture.Create(texInfo, null);

                    //hMap = hMap.CenterOnOrigin(Z_FACTOR);
                    //
                    //=======================
                }
                // Triangulate height map
                // and add base and sides
                _logger.LogInformation($"Triangulating height map and generating 3D mesh...");

                var model = _sharpGltfService.CreateTerrainMesh(heightMap, pbrTexture);

                var width  = new GeoPoint(wgs84bbox.Center[1], bbox.Center[0] - bbox.Width / 2f).DistanceTo(new GeoPoint(wgs84bbox.Center[1], bbox.Center[0] + bbox.Width / 2f));
                var height = new GeoPoint(bbox.Center[1] - bbox.Height / 2f, wgs84bbox.Center[0]).DistanceTo(new GeoPoint(bbox.Center[1] + bbox.Height, wgs84bbox.Center[0]));

                return(model, width, height, wgs84bbox.Center[2], heightMap.BoundingBox);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                return(null, 0, 0, 0, null);
            }
        }