public void GetCameraSampleForPixels() { var start = new PixelCoordinate(0, 0); var end = new PixelCoordinate(100, 100); var area = new PixelArea(start, end); var hs = new HaltonSampler(10, area); var arena = new ObjectArena(); hs.StartPixel(in start); var cs = hs.GetCameraSample(in start, arena); cs.FilmPoint.X.Should().BeInRange(0f, 1f); cs.FilmPoint.Y.Should().BeInRange(0f, 1f); cs.LensPoint.X.Should().BeInRange(0f, 1f); cs.LensPoint.Y.Should().BeInRange(0f, 1f); var next = new PixelCoordinate(1, 0); hs.StartPixel(in next); var csn = hs.GetCameraSample(in next, arena); csn.FilmPoint.X.Should().BeInRange(1f, 2f); csn.FilmPoint.Y.Should().BeInRange(0f, 1f); csn.LensPoint.X.Should().BeInRange(0f, 1f); csn.LensPoint.Y.Should().BeInRange(0f, 1f); cs.FilmPoint.X.Should().NotBe(csn.FilmPoint.X); cs.FilmPoint.Y.Should().NotBe(csn.FilmPoint.Y); cs.LensPoint.X.Should().NotBe(csn.LensPoint.X); cs.LensPoint.Y.Should().NotBe(csn.LensPoint.Y); }
/// <inheritdoc cref="ToMercatorCoordinates(Size, bool)"/> /// <param name="number"><see cref="Number"/> to convert</param> /// <param name="tileSize"></param> /// <param name="tmsCompatible"></param> public static (MercatorCoordinate minCoordinate, MercatorCoordinate maxCoordinate) ToMercatorCoordinates( Number number, Size tileSize, bool tmsCompatible) { #region Preconditions checks if (number == null) { throw new ArgumentNullException(nameof(number)); } if (tileSize == null) { throw new ArgumentNullException(nameof(tileSize)); } #endregion if (!tmsCompatible) { number = Flip(number); } PixelCoordinate minPixelCoordinate = new PixelCoordinate(number.X * tileSize.Width, number.Y * tileSize.Height); PixelCoordinate maxPixelCoordinate = new PixelCoordinate((number.X + 1) * tileSize.Width, (number.Y + 1) * tileSize.Height); MercatorCoordinate minCoordinate = minPixelCoordinate.ToMercatorCoordinate(CoordinateSystem.Epsg3857, number.Z, tileSize); MercatorCoordinate maxCoordinate = maxPixelCoordinate.ToMercatorCoordinate(CoordinateSystem.Epsg3857, number.Z, tileSize); return(minCoordinate, maxCoordinate); }
public void ToPixelCoordinateTest() { PixelCoordinate pCoord = null; Assert.DoesNotThrow(() => pCoord = Locations.TokyoGeodeticCoordinate .ToPixelCoordinate(10, Tile.DefaultSize)); Assert.True(pCoord == Locations.TokyoGeodeticPixelCoordinate); }
public void CreateAreaNormal() { PixelCoordinate coord = new PixelCoordinate(0.0, 0.0); Assert.DoesNotThrow(() => { Area area = new Area(coord, Tile.DefaultSize); }); }
public void CreateAreaNullSize() { PixelCoordinate coord = new PixelCoordinate(0.0, 0.0); Assert.Throws <ArgumentNullException>(() => { Area area = new Area(coord, null); }); }
public void ToRasterPixelCoordinateNotSquareTileSize() { Size size = new Size(10, 20); Assert.Throws <ArgumentException>(() => { PixelCoordinate pCoord = Locations.TokyoMercatorPixelCoordinate .ToRasterPixelCoordinate(10, size); }); }
public void GetProperties() { PixelCoordinate coord = new PixelCoordinate(0.0, 0.0); Area area = new Area(coord, Tile.DefaultSize); Assert.DoesNotThrow(() => { Size size = area.Size; PixelCoordinate ori = area.OriginCoordinate; }); }
private static void RenderToCanvas(PixelArea area, Canvas canvas, RenderPipeline pipeline, ISampler sampler) { for (var y = area.Min.Y; y < area.Max.Y; y++) { for (var x = area.Min.X; x < area.Max.X; x++) { var pixel = new PixelCoordinate(x, y); var c = pipeline.Capture(new PixelInformation(pixel, canvas.Width, canvas.Height), sampler); canvas.WritePixel(in c, pixel.X, pixel.Y); } } }
public void RayThroughCornerOfCanvas() { var width = 201; var height = 101; var c = new PinholeCamera(in Transform.Identity, MathF.PI / 2f, (float)width / height); var coordinate = new PixelCoordinate(0, 0); var(r, _) = c.CameraRay( new PixelSample(new PixelInformation(coordinate, width, height), new UVPoint(0.5f, 0.5f)), new TestSampler(0f, 0f, 0.5f)); r.Origin.Should().Be(Point.Zero); r.Direction.Should().Be(new Vector(0.66519f, 0.33259f, -0.66851f)); }
public void RayAfterCameraTransform() { var width = 201; var height = 101; var transform = Transform.RotateY(MathF.PI / 4f) * Transform.Translate(0, -2, 5); var c = new PinholeCamera(transform, MathF.PI / 2f, (float)width / height); var coordinate = new PixelCoordinate(100, 50); var(r, _) = c.CameraRay( new PixelSample(new PixelInformation(coordinate, width, height), new UVPoint(0.5f, 0.5f)), new TestSampler(0f, 0f, 0.5f)); r.Origin.Should().Be(new Point(0, 2, -5)); r.Direction.Should().Be(new Vector(MathF.Sqrt(2f) / 2f, 0.0f, -MathF.Sqrt(2f) / 2f)); }
/// <summary> /// Creates new <see cref="Area"/> /// </summary> /// <param name="originCoordinate"><see cref="OriginCoordinate"/></param> /// <param name="size"><see cref="Size"/></param> /// <exception cref="ArgumentNullException"/> public Area(PixelCoordinate originCoordinate, Size size) { #region Preconditions checks if (originCoordinate == null) { throw new ArgumentNullException(nameof(originCoordinate)); } if (size == null) { throw new ArgumentNullException(nameof(size)); } #endregion (OriginCoordinate, Size) = (originCoordinate, size); }
public void GetAreasGeoTiffNormal() { using IGeoTiff image = new Raster(_in4326, Cs4326); using ITile tile = new RasterTile(Locations.TokyoGeodeticTmsNumber, image.GeoCoordinateSystem, tmsCompatible: true); PixelCoordinate expectedReadCoord = new PixelCoordinate(0.0, 218.0); PixelCoordinate expectedWriteCoord = new PixelCoordinate(5.6875, 0.0); Size expectedReadSize = new Size(4473, 3293); Size expectedWriteSize = new Size(140, 102); Area calcReadArea = null; Area calcWriteArea = null; Assert.DoesNotThrow(() => (calcReadArea, calcWriteArea) = Area.GetAreas(image, tile)); Assert.True(calcReadArea.OriginCoordinate == expectedReadCoord && calcReadArea.Size == expectedReadSize); Assert.True(calcWriteArea.OriginCoordinate == expectedWriteCoord && calcWriteArea.Size == expectedWriteSize); }
public void GetAreasCoordsNormal() { GeodeticCoordinate minImgCoord = new GeodeticCoordinate(139.74999904632568, 35.61293363571167); GeodeticCoordinate maxImgCoord = new GeodeticCoordinate(139.8459792137146, 35.688271522521973); GeodeticCoordinate minTileCoord = new GeodeticCoordinate(139.74609375, 35.68359375); GeodeticCoordinate maxTileCoord = new GeodeticCoordinate(139.921875, 35.859375); Size tileSize = Tile.DefaultSize; PixelCoordinate expectedReadCoord = new PixelCoordinate(0.0, 0.0); PixelCoordinate expectedWriteCoord = new PixelCoordinate(5.6875, 249.1875); Size expectedReadSize = new Size(4473, 218); Size expectedWriteSize = new Size(140, 7); Area calcReadArea = null; Area calcWriteArea = null; Assert.DoesNotThrow(() => (calcReadArea, calcWriteArea) = Area.GetAreas(minImgCoord, maxImgCoord, _in4326Size, minTileCoord, maxTileCoord, tileSize)); Assert.True(calcReadArea.OriginCoordinate == expectedReadCoord && calcReadArea.Size == expectedReadSize); Assert.True(calcWriteArea.OriginCoordinate == expectedWriteCoord && calcWriteArea.Size == expectedWriteSize); }
public void Render() { const int chunkSize = 4; var queue = new ConcurrentQueue <PixelArea>(); for (var y = 0; y < Canvas.Height;) { var yEnd = Math.Min(Canvas.Height, y + chunkSize); for (var x = 0; x < Canvas.Width;) { var xEnd = Math.Min(Canvas.Width, x + chunkSize); var min = new PixelCoordinate(x, y); var max = new PixelCoordinate(xEnd, yEnd); queue.Enqueue(new PixelArea(min, max)); x = xEnd; } y = yEnd; } var sampler = new QuasiRandomSampler(0); Parallel.ForEach(queue, a => RenderToCanvas(a, Canvas, Pipeline, sampler)); }
public void ToRasterPixelCoordinateNormal() => Assert.DoesNotThrow(() => { PixelCoordinate pCoord = Locations.TokyoMercatorPixelCoordinate .ToRasterPixelCoordinate(10, Tile.DefaultSize); });
/// <inheritdoc cref="GetAreas(IGeoTiff, ITile)"/> /// <param name="imageMinCoordinate">Minimal <see cref="GeoCoordinate"/> /// of <see cref="IGeoTiff"/></param> /// <param name="imageMaxCoordinate">Maximal <see cref="GeoCoordinate"/> /// of <see cref="IGeoTiff"/></param> /// <param name="imageSize"><see cref="Images.Size"/> of <see cref="IGeoTiff"/></param> /// <param name="tileMinCoordinate">Minimal <see cref="GeoCoordinate"/> /// of <see cref="ITile"/></param> /// <param name="tileMaxCoordinate">Maximal <see cref="GeoCoordinate"/> /// of <see cref="ITile"/></param> /// <param name="tileSize"><see cref="Images.Size"/> of <see cref="ITile"/></param> /// <returns></returns> /// <exception cref="ArgumentNullException"/> /// <exception cref="ArgumentException"/> public static (Area readArea, Area writeArea) GetAreas(GeoCoordinate imageMinCoordinate, GeoCoordinate imageMaxCoordinate, Size imageSize, GeoCoordinate tileMinCoordinate, GeoCoordinate tileMaxCoordinate, Size tileSize) { #region Preconditions checks if (imageMinCoordinate == null) { throw new ArgumentNullException(nameof(imageMinCoordinate)); } if (imageMaxCoordinate == null) { throw new ArgumentNullException(nameof(imageMaxCoordinate)); } string err = string.Format(Strings.Culture, Strings.Equal, nameof(imageMinCoordinate), nameof(imageMaxCoordinate)); // This is to prevent unclear DivideByZeroException exception if (imageMinCoordinate == imageMaxCoordinate) { throw new ArgumentException(err); } if (imageSize == null) { throw new ArgumentNullException(nameof(imageSize)); } if (tileMinCoordinate == null) { throw new ArgumentNullException(nameof(tileMinCoordinate)); } if (tileMaxCoordinate == null) { throw new ArgumentNullException(nameof(tileMaxCoordinate)); } err = string.Format(Strings.Culture, Strings.Equal, nameof(tileMinCoordinate), nameof(tileMaxCoordinate)); // This is to prevent unclear DivideByZeroException exception if (tileMinCoordinate == tileMaxCoordinate) { throw new ArgumentException(err); } if (tileSize == null) { throw new ArgumentNullException(nameof(tileSize)); } #endregion // Read from input geotiff in pixels double readPosMinX = imageSize.Width * (tileMinCoordinate.X - imageMinCoordinate.X) / (imageMaxCoordinate.X - imageMinCoordinate.X); double readPosMaxX = imageSize.Width * (tileMaxCoordinate.X - imageMinCoordinate.X) / (imageMaxCoordinate.X - imageMinCoordinate.X); double readPosMinY = imageSize.Height - imageSize.Height * (tileMaxCoordinate.Y - imageMinCoordinate.Y) / (imageMaxCoordinate.Y - imageMinCoordinate.Y); double readPosMaxY = imageSize.Height - imageSize.Height * (tileMinCoordinate.Y - imageMinCoordinate.Y) / (imageMaxCoordinate.Y - imageMinCoordinate.Y); // If outside of tiff -- set to 0.0/Max readPosMinX = readPosMinX <0.0 ? 0.0 : readPosMinX> imageSize.Width ? imageSize.Width : readPosMinX; readPosMaxX = readPosMaxX <0.0 ? 0.0 : readPosMaxX> imageSize.Width ? imageSize.Width : readPosMaxX; readPosMinY = readPosMinY <0.0 ? 0.0 : readPosMinY> imageSize.Height ? imageSize.Height : readPosMinY; readPosMaxY = readPosMaxY <0.0 ? 0.0 : readPosMaxY> imageSize.Height ? imageSize.Height : readPosMaxY; // Output tile's borders in pixels double tilePixMinX = readPosMinX.Equals(0.0) ? imageMinCoordinate.X : readPosMinX.Equals(imageSize.Width) ? imageMaxCoordinate.X : tileMinCoordinate.X; double tilePixMaxX = readPosMaxX.Equals(0.0) ? imageMinCoordinate.X : readPosMaxX.Equals(imageSize.Width) ? imageMaxCoordinate.X : tileMaxCoordinate.X; double tilePixMinY = readPosMaxY.Equals(0.0) ? imageMaxCoordinate.Y : readPosMaxY.Equals(imageSize.Height) ? imageMinCoordinate.Y : tileMinCoordinate.Y; double tilePixMaxY = readPosMinY.Equals(0.0) ? imageMaxCoordinate.Y : readPosMinY.Equals(imageSize.Height) ? imageMinCoordinate.Y : tileMaxCoordinate.Y; // Positions of dataset to write in tile double writePosMinX = tileSize.Width - tileSize.Width * (tileMaxCoordinate.X - tilePixMinX) / (tileMaxCoordinate.X - tileMinCoordinate.X); double writePosMaxX = tileSize.Width - tileSize.Width * (tileMaxCoordinate.X - tilePixMaxX) / (tileMaxCoordinate.X - tileMinCoordinate.X); double writePosMinY = tileSize.Height * (tileMaxCoordinate.Y - tilePixMaxY) / (tileMaxCoordinate.Y - tileMinCoordinate.Y); double writePosMaxY = tileSize.Height * (tileMaxCoordinate.Y - tilePixMinY) / (tileMaxCoordinate.Y - tileMinCoordinate.Y); // Sizes to read and write double readXSize = readPosMaxX - readPosMinX; double writeXSize = writePosMaxX - writePosMinX; double readYSize = Math.Abs(readPosMaxY - readPosMinY); double writeYSize = Math.Abs(writePosMaxY - writePosMinY); // Shifts double readXShift = readPosMinX - (int)readPosMinX; readXSize += readXShift; double readYShift = readPosMinY - (int)readPosMinY; readYSize += readYShift; double writeXShift = writePosMinX - (int)writePosMinX; writeXSize += writeXShift; double writeYShift = writePosMinY - (int)writePosMinY; writeYSize += writeYShift; // If output image sides are lesser then 1 - make image 1x1 pixels to prevent division by 0 writeXSize = writeXSize > 1.0 ? writeXSize : 1.0; writeYSize = writeYSize > 1.0 ? writeYSize : 1.0; PixelCoordinate readOriginCoordinate = new PixelCoordinate(readPosMinX, readPosMinY); PixelCoordinate writeOriginCoordinate = new PixelCoordinate(writePosMinX, writePosMinY); Size readSize = new Size((int)readXSize, (int)readYSize); Size writeSize = new Size((int)writeXSize, (int)writeYSize); Area readArea = new Area(readOriginCoordinate, readSize); Area writeArea = new Area(writeOriginCoordinate, writeSize); return(readArea, writeArea); }
public void ToRasterPixelCoordinateSmallZ() => Assert.Throws <ArgumentOutOfRangeException>(() => { PixelCoordinate pCoord = Locations.TokyoMercatorPixelCoordinate .ToRasterPixelCoordinate(-1, Tile.DefaultSize); });
public void ToRasterPixelCoordinateNullTileSize() => Assert.Throws <ArgumentNullException>(() => { PixelCoordinate pCoord = Locations.TokyoMercatorPixelCoordinate .ToRasterPixelCoordinate(10, null); });
public void CreatePixelCoordinateNormal() => Assert.DoesNotThrow(() => { PixelCoordinate coord = new PixelCoordinate(Locations.TokyoMercatorPixelLongitude, Locations.TokyoMercatorPixelLatitude); });
public void CreatePixelCoordinateSmallLat() => Assert.Throws <ArgumentOutOfRangeException>(() => { PixelCoordinate coord = new PixelCoordinate(Locations.TokyoMercatorPixelLongitude, -1.0); });
public PixelArea(PixelCoordinate min, PixelCoordinate max) { Min = min; Max = max; }