Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
 public GraticuleLabel(LatLong worldLocation)
 {
     this.label         = null;
     this.location      = new PointInt(0, 0);
     this.worldLocation = worldLocation;
 }
Example #4
0
 public GraticuleLabel(string Label, PointInt Location)
 {
     this.label         = Label;
     this.location      = Location;
     this.worldLocation = new LatLong(0, 0);
 }
Example #5
0
 public MapTileInfo(PointInt xy, int zoom)
 {
     X    = xy.X;
     Y    = xy.Y;
     Zoom = zoom;
 }
Example #6
0
        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)
                {
                }
            }
        }