public bool Equals(TileRange tileRange) { return this.firstCol == tileRange.firstCol && this.lastCol == tileRange.lastCol && this.firstRow == tileRange.firstRow && this.lastRow == tileRange.lastRow; }
public bool Equals(TileRange tileRange) { return FirstCol == tileRange.FirstCol && ColCount == tileRange.ColCount && FirstRow == tileRange.FirstRow && RowCount == tileRange.RowCount; }
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); }
/** * @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; }
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); }
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); }; }
/// <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); } }
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)); });
/// <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); }
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; }
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))); }
public TileRangeEnumerator(TileRange tileRange) { _tileRange = tileRange; _x = uint.MaxValue; _y = uint.MaxValue; }
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); }
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); }
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); }
/** * @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); }
/// <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; }
/// <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); }
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); } }
/// <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); } }
/// <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); }
private static string GetTileRange(int zoomLevel) { var z = TileRange.GetTileRangeForExtentAndZ(WebMercator.BoundingBox, zoomLevel, new TestTiledVectorLayer()); return(z.ToString()); }
/// <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); } }
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); } }
/// <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); } }
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); } }
/** * @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); } }
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); }
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); }
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(); }
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); }
/// <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); }
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); }
/// <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); }
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")); }
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); } }