public List <Vector2> ComputeUVMap(HeightMap heightMap, TextureInfo textureInfo) { /********************************** * We need to map texture pixels to heightmap points * Linear mapping does not work because or Mercator projection distortion * Pseudo code : * for each point * project to texture coordinates (pixelXY at same zoom than texture) * get pixel offset from origin * map this offset to (0 -> texWidth, 0 -> textHeight) => (0->1, 0->1) */ List <Vector2> uvs = new List <Vector2>(heightMap.Count); var bbox = textureInfo.ProjectedBounds; foreach (GeoPoint geoPoint in heightMap.Coordinates) { PointInt projPoint = TileUtils.LatLongToPixelXY(geoPoint.Latitude, geoPoint.Longitude, textureInfo.ProjectedZoom); float xOffset = projPoint.X - (float)bbox.xMin; float uvX = MathHelper.Map(1, textureInfo.Width, 0, 1, xOffset, true); float yOffset = projPoint.Y - (float)bbox.yMin; float uvY = MathHelper.Map(1, textureInfo.Height, 0, 1, yOffset, true); uvs.Add(new Vector2(uvX, uvY)); } return(uvs); }
public TileRange DownloadTiles(BoundingBox bbox, ImageryProvider provider, int minTilesPerImage = 4) { TileRange tiles = new TileRange(provider); BoundingBox mapBbox = null; PointInt topLeft = new PointInt(); PointInt bottomRight = new PointInt(); // optimal zoom calculation (maybe there's a direct way) // calculate the size of the full bbox at increasing zoom levels // until the full image would be greater than a tile int zoom = 0; do { zoom++; // coords are pixels in global map image (see TileUtils.MapSize(zoom)) topLeft = TileUtils.LatLongToPixelXY(bbox.yMax, bbox.xMin, zoom); bottomRight = TileUtils.LatLongToPixelXY(bbox.yMin, bbox.xMax, zoom); mapBbox = new BoundingBox(topLeft.X, bottomRight.X, topLeft.Y, bottomRight.Y); }while (zoom < provider.MaxZoom && (mapBbox.Width < provider.TileSize * minTilesPerImage && mapBbox.Height < provider.TileSize * minTilesPerImage)); // now we have the minimum zoom without image // we can know which tiles are needed tiles.Start = new MapTileInfo(TileUtils.PixelXYToTileXY(topLeft.X, topLeft.Y), zoom); tiles.End = new MapTileInfo(TileUtils.PixelXYToTileXY(bottomRight.X, bottomRight.Y), zoom); tiles.AreaOfInterest = mapBbox; // downdload tiles Stopwatch swDownload = Stopwatch.StartNew(); _logger?.LogTrace("Starting images download"); // 2 max download threads var options = new ParallelOptions() { MaxDegreeOfParallelism = provider.MaxDegreeOfParallelism }; var range = tiles.EnumerateRange().ToList(); _logger.LogInformation($"Downloading {range.Count} tiles..."); Parallel.ForEach(range, options, tileInfo => { Uri tileUri = BuildUri(provider, tileInfo.X, tileInfo.Y, tileInfo.Zoom); _logger?.LogInformation($"Downloading {tileUri}"); var contentbytes = _httpClient.GetByteArrayAsync(tileUri).Result; tiles.Add(new MapTile(contentbytes, provider.TileSize, tileUri, tileInfo)); } ); swDownload.Stop(); _logger?.LogInformation($"DownloadImages done in : {swDownload.Elapsed:g}"); return(tiles); }
public GraticuleLabel(LatLong worldLocation) { this.label = null; this.location = new PointInt(0, 0); this.worldLocation = worldLocation; }
public GraticuleLabel(string Label, PointInt Location) { this.label = Label; this.location = Location; this.worldLocation = new LatLong(0, 0); }
public MapTileInfo(PointInt xy, int zoom) { X = xy.X; Y = xy.Y; Zoom = zoom; }
private void DrawGraticules(IImageProcessingContext img, GraticuleLabels graticules, PointInt corner, int zoom) { var font = SixLabors.Fonts.SystemFonts.CreateFont("Arial", 8); foreach (var meridian in graticules.VerticalLabels) { var loc = meridian.worldLocation; var pt = TileUtils.LatLongToPixelXY(loc.Lat, loc.Long, zoom); var xpos = pt.X - corner.X; var start = new PointF(xpos, 0); var end = new PointF(xpos, TileSize); img.DrawLines(Rgba32.Gray, 1f, new PointF[] { start, end }); try { if (xpos < TileSize - 10) { img.DrawText(Math.Round(loc.Long, 2).ToString(), font, Rgba32.Black, new PointF(xpos, 50)); } } catch (Exception) { } } foreach (var parallel in graticules.HorizontalLabels) { var loc = parallel.worldLocation; var pt = TileUtils.LatLongToPixelXY(loc.Lat, loc.Long, zoom); var ypos = pt.Y - corner.Y; var start = new PointF(0, ypos); var end = new PointF(TileSize, ypos); img.DrawLines(Rgba32.Gray, 1f, new PointF[] { start, end }); try { img.DrawText(Math.Round(loc.Lat, 4).ToString(), font, Rgba32.Black, new PointF(50, ypos)); } catch (Exception) { } } }