Disabled external gits

This commit is contained in:
2022-04-07 18:43:21 +02:00
parent 182267a8cb
commit 88cb3426ad
1067 changed files with 102374 additions and 6 deletions

View File

@@ -0,0 +1,117 @@
package ch.epfl.alpano.dem;
import static ch.epfl.test.TestRandomizer.RANDOM_ITERATIONS;
import static ch.epfl.test.TestRandomizer.newRandom;
import static java.lang.Math.toRadians;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Random;
import org.junit.Test;
import ch.epfl.alpano.Interval1D;
import ch.epfl.alpano.Interval2D;
public class CompositeDiscreteElevationModelTest {
private final static Interval2D ext1 = new Interval2D(
new Interval1D(-100_000, 100_000),
new Interval1D(0, 100_000));
private final static Interval2D ext2 = new Interval2D(
new Interval1D(-100_000, 100_000),
new Interval1D(100_001, 200_000));
private final static Interval2D ext12 = new Interval2D(
new Interval1D(-100_000, 100_000),
new Interval1D(0, 200_000));
private final static Interval2D ext3 = new Interval2D(
new Interval1D(0, 99_999),
new Interval1D(0, 100_001));
@Test
public void samplesPerRadiansHasCorrectValue() {
assertEquals(206264.80624709636, DiscreteElevationModel.SAMPLES_PER_RADIAN, 1e-8);
}
@Test
public void sampleIndexWorksOnRandomValues() {
Random rng = newRandom();
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
int arcSeconds = rng.nextInt(2_000_000) - 1_000_000;
double angle = toRadians(arcSeconds / 3_600d);
assertEquals(arcSeconds, DiscreteElevationModel.sampleIndex(angle), 1e-5);
}
}
@SuppressWarnings("resource")
@Test(expected = IllegalArgumentException.class)
public void unionFailsIfExtentsNotUnionable() {
ConstantElevationDEM dem1 = new ConstantElevationDEM(ext1, 0);
ConstantElevationDEM dem2 = new ConstantElevationDEM(ext3, 0);
dem1.union(dem2);
}
@SuppressWarnings("resource")
@Test
public void extentOfUnionIsUnionOfExtent() {
ConstantElevationDEM dem1 = new ConstantElevationDEM(ext1, 0);
ConstantElevationDEM dem2 = new ConstantElevationDEM(ext2, 0);
DiscreteElevationModel dem12 = dem1.union(dem2);
assertEquals(ext12, dem12.extent());
}
@SuppressWarnings("resource")
@Test(expected = IllegalArgumentException.class)
public void elevationSampleFailsWhenOutsideOfExtent() {
ConstantElevationDEM dem1 = new ConstantElevationDEM(ext1, 0);
ConstantElevationDEM dem2 = new ConstantElevationDEM(ext2, 0);
DiscreteElevationModel dem12 = dem1.union(dem2);
dem12.elevationSample(0, 200_001);
}
@SuppressWarnings("resource")
@Test
public void elevationSampleWorksOnBothSubDEMs() {
ConstantElevationDEM dem1 = new ConstantElevationDEM(ext1, 1);
ConstantElevationDEM dem2 = new ConstantElevationDEM(ext2, 2);
DiscreteElevationModel dem12 = dem1.union(dem2);
assertEquals(1, dem12.elevationSample(-100_000, 0), 0);
assertEquals(1, dem12.elevationSample(100_000, 0), 0);
assertEquals(1, dem12.elevationSample(100_000, 100_000), 0);
assertEquals(1, dem12.elevationSample(-100_000, 100_000), 0);
assertEquals(2, dem12.elevationSample(-100_000, 100_001), 0);
assertEquals(2, dem12.elevationSample(100_000, 100_001), 0);
assertEquals(2, dem12.elevationSample(100_000, 200_000), 0);
assertEquals(2, dem12.elevationSample(-100_000, 200_000), 0);
}
@SuppressWarnings("resource")
@Test
public void closeClosesBothSubDEMs() throws Exception {
ConstantElevationDEM dem1 = new ConstantElevationDEM(ext1, 0);
ConstantElevationDEM dem2 = new ConstantElevationDEM(ext2, 0);
DiscreteElevationModel dem12 = dem1.union(dem2);
dem12.close();
assertTrue(dem1.isClosed);
assertTrue(dem2.isClosed);
}
}
class ConstantElevationDEM implements DiscreteElevationModel {
private final Interval2D extent;
private final double elevation;
boolean isClosed = false;
public ConstantElevationDEM(Interval2D extent, double elevation) {
this.extent = extent;
this.elevation = elevation;
}
@Override
public void close() throws Exception { isClosed = true; }
@Override
public Interval2D extent() { return extent; }
@Override
public double elevationSample(int x, int y) { return elevation; }
}

View File

@@ -0,0 +1,170 @@
package ch.epfl.alpano.dem;
import static ch.epfl.test.TestRandomizer.RANDOM_ITERATIONS;
import static ch.epfl.test.TestRandomizer.newRandom;
import static java.lang.Math.toDegrees;
import static java.lang.Math.toRadians;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Random;
import org.junit.Test;
import ch.epfl.alpano.GeoPoint;
import ch.epfl.alpano.Interval1D;
import ch.epfl.alpano.Interval2D;
public class ContinuousElevationModelTest {
private final static Interval2D EXT_100_100 = new Interval2D(
new Interval1D(0, 100),
new Interval1D(0, 100));
private final static Interval2D EXT_13_13 = new Interval2D(
new Interval1D(0, 13),
new Interval1D(0, 13));
@Test(expected = NullPointerException.class)
public void constructorFailsWithNullDEM() {
new ContinuousElevationModel(null);
}
@Test
public void elevationAtReturns0OutsideOfExtent() {
DiscreteElevationModel dDEM = new ConstantElevationDEM(EXT_100_100, 1000);
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
assertEquals(0, cDEM.elevationAt(pointForSampleIndex(101, 0)), 0);
}
@Test
public void elevationAtReturnsCorrectElevationInsideExtent() {
double elevation = 1000;
DiscreteElevationModel dDEM = new ConstantElevationDEM(EXT_100_100, elevation);
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
Random rng = newRandom();
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
double x = rng.nextDouble() * 100d, y = rng.nextDouble() * 100d;
assertEquals(elevation, cDEM.elevationAt(pointForSampleIndex(x, y)), 1e-10);
}
}
@Test
public void elevationAtInterpolatesJustOutsideExtent() {
DiscreteElevationModel dDEM = new ConstantElevationDEM(EXT_100_100, 1000);
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
assertEquals(500, cDEM.elevationAt(pointForSampleIndex(100.5, 10)), 1e-10);
}
@Test
public void elevationAtReturnsCorrectInterpolatedElevation() {
DiscreteElevationModel dDEM = new ConstantSlopeDEM(EXT_100_100);
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
Random rng = new Random();
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
double x = rng.nextDouble() * 100;
double y = rng.nextDouble() * 100;
assertEquals((x + y) * ConstantSlopeDEM.INTER_SAMPLE_DISTANCE, cDEM.elevationAt(pointForSampleIndex(x, y)), 1e-6);
}
}
@Test
public void elevationAtStaysWithinBoundsOnRandomTerrain() {
int maxElevation = 1000;
DiscreteElevationModel dDEM = new RandomElevationDEM(EXT_13_13, maxElevation);
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
Random rng = newRandom();
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
double x = rng.nextDouble() * dDEM.extent().iX().size();
double y = rng.nextDouble() * dDEM.extent().iY().size();
double e = cDEM.elevationAt(pointForSampleIndex(x, y));
assertTrue(0 <= e && e <= maxElevation);
}
}
@Test
public void slopeAtReturnsCorrectInterpolatedSlope() {
DiscreteElevationModel dDEM = new ConstantSlopeDEM(EXT_100_100);
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
Random rng = new Random();
double expectedSlope = Math.acos(1 / Math.sqrt(3));
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
double x = 5 + rng.nextDouble() * 90;
double y = 5 + rng.nextDouble() * 90;
assertEquals(expectedSlope, cDEM.slopeAt(pointForSampleIndex(x, y)), 1e-4);
}
}
@Test
public void slopeAtStaysWithinBoundsOnRandomTerrain() {
int maxElevation = 1000;
DiscreteElevationModel dDEM = new RandomElevationDEM(EXT_13_13, maxElevation);
ContinuousElevationModel cDEM = new ContinuousElevationModel(dDEM);
Random rng = newRandom();
for (int i = 0; i < RANDOM_ITERATIONS; ++i) {
double x = rng.nextDouble() * dDEM.extent().iX().size();
double y = rng.nextDouble() * dDEM.extent().iY().size();
double e = toDegrees(cDEM.slopeAt(pointForSampleIndex(x, y)));
assertTrue(0 <= e && e < 90);
}
}
private static GeoPoint pointForSampleIndex(double x, double y) {
return new GeoPoint(toRadians(x / 3600d), toRadians(y / 3600d));
}
}
class RandomElevationDEM implements DiscreteElevationModel {
private final Interval2D extent;
private final double[][] elevations;
public RandomElevationDEM(Interval2D extent, int maxElevation) {
this.extent = extent;
this.elevations = randomElevations(extent.iX().size(), extent.iY().size(), maxElevation);
}
private static double[][] randomElevations(int width, int height, int maxElevation) {
Random rng = newRandom();
double[][] es = new double[width][height];
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
es[x][y] = rng.nextInt(maxElevation + 1);
}
}
return es;
}
@Override
public Interval2D extent() {
return extent;
}
@Override
public double elevationSample(int x, int y) {
return elevations[x][y];
}
@Override
public void close() throws Exception { }
}
class ConstantSlopeDEM implements DiscreteElevationModel {
public final static double INTER_SAMPLE_DISTANCE =
2d * Math.PI * 6_371_000d / (3600d * 360d);
private final Interval2D extent;
public ConstantSlopeDEM(Interval2D extent) {
this.extent = extent;
}
@Override
public Interval2D extent() { return extent; }
@Override
public double elevationSample(int x, int y) {
return (x + y) * INTER_SAMPLE_DISTANCE;
}
@Override
public void close() throws Exception {}
}

View File

@@ -0,0 +1,70 @@
package ch.epfl.alpano.dem;
import static java.lang.Math.toRadians;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import javax.imageio.ImageIO;
import ch.epfl.alpano.GeoPoint;
final class DrawElevationProfile {
final static File HGT_FILE = new File("HGT"+File.separatorChar+"N46E006.hgt");
final static double MAX_ELEVATION = 1_500;
final static int LENGTH = 111_000;
final static double AZIMUTH = toRadians(27.97);
final static double LONGITUDE = toRadians(6.15432);
final static double LATITUDE = toRadians(46.20562);
final static int WIDTH = 800, HEIGHT = 100;
public static void main(String[] as) throws Exception {
DiscreteElevationModel dDEM =
new HgtDiscreteElevationModel(HGT_FILE);
ContinuousElevationModel cDEM =
new ContinuousElevationModel(dDEM);
GeoPoint o =
new GeoPoint(LONGITUDE, LATITUDE);
ElevationProfile p1 =
new ElevationProfile(cDEM, o, AZIMUTH, (int)(LENGTH/3));
GeoPoint gP1 = p1.positionAt((int)LENGTH/3);
ElevationProfile p2 =
new ElevationProfile(cDEM, p1.positionAt((int)LENGTH/3), AZIMUTH+toRadians(6.0),2*((int)LENGTH/3));
GeoPoint gP2 = p2.positionAt(2*((int)LENGTH/3));
ElevationProfile p3 = new ElevationProfile (cDEM,p2.positionAt(2*((int)LENGTH/3)), AZIMUTH, LENGTH);
ArrayList<GeoPoint> trekkingSpots = new ArrayList<GeoPoint>(Arrays.asList(o,gP1,gP2));
ArrayList<ElevationProfile> profiles= new ArrayList<ElevationProfile>();
for (int index = 0; index < trekkingSpots.size()-1; index++){
GeoPoint current= trekkingSpots.get(index);
GeoPoint next = trekkingSpots.get(index+1);
ElevationProfile evP= new ElevationProfile(cDEM, current,current.azimuthTo(next), current.distanceTo(next));
profiles.add(evP);
}
CompositElevationProfile p = new CompositElevationProfile(profiles);
int BLACK = 0x00_00_00, WHITE = 0xFF_FF_FF;
BufferedImage i =
new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < WIDTH; ++x) {
double pX = x * (double) LENGTH / (WIDTH - 1);
double pY = p.elevationAt(pX);
int yL = (int)((pY / MAX_ELEVATION) * (HEIGHT - 1));
for (int y = 0; y < HEIGHT; ++y) {
int color = y < yL ? BLACK : WHITE;
i.setRGB(x, HEIGHT - 1 - y, color);
}
}
dDEM.close();
ImageIO.write(i, "png", new File("tests/ch/epfl/alpano/dem/profile.png"));
}
}

View File

@@ -0,0 +1,83 @@
package ch.epfl.alpano.dem;
import static java.lang.Math.max;
import static java.lang.Math.min;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import ch.epfl.alpano.GeoPoint;
import static java.lang.Math.toRadians;
final class DrawHgtDEM {
final static File HGT_FILE = new File("HGT"+File.separatorChar+"N46E006.hgt");
final static double ORIGIN_LON = toRadians(6.25);
final static double ORIGIN_LAT = toRadians(46.25);
final static double WIDTH = toRadians(0.5);
final static int IMAGE_SIZE = 300;
final static double MIN_ELEVATION = 200;
final static double MAX_ELEVATION = 1_500;
public static void main(String[] as) throws Exception {
DiscreteElevationModel dDEM =
new HgtDiscreteElevationModel(HGT_FILE);
ContinuousElevationModel cDEM =
new ContinuousElevationModel(dDEM);
double step = WIDTH / (IMAGE_SIZE - 1);
BufferedImage i = new BufferedImage(IMAGE_SIZE,
IMAGE_SIZE,
BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < IMAGE_SIZE; ++x) {
double lon = ORIGIN_LON + x * step;
for (int y = 0; y < IMAGE_SIZE; ++y) {
double lat = ORIGIN_LAT + y * step;
GeoPoint p = new GeoPoint(lon, lat);
double el =
(cDEM.elevationAt(p) - MIN_ELEVATION)
/ (MAX_ELEVATION - MIN_ELEVATION);
i.setRGB(x, IMAGE_SIZE - 1 - y, gray(el));
}
}
dDEM.close();
ImageIO.write(i, "png", new File("tests/ch/epfl/alpano/dem/dem.png"));
}
public static void drawDem(ContinuousElevationModel cDem){
double step = WIDTH / (IMAGE_SIZE - 1);
BufferedImage i = new BufferedImage(IMAGE_SIZE,
IMAGE_SIZE,
BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < IMAGE_SIZE; ++x) {
double lon = ORIGIN_LON + x * step;
for (int y = 0; y < IMAGE_SIZE; ++y) {
double lat = ORIGIN_LAT + y * step;
GeoPoint p = new GeoPoint(lon, lat);
double el =
(cDem.elevationAt(p) - MIN_ELEVATION)
/ (MAX_ELEVATION - MIN_ELEVATION);
i.setRGB(x, IMAGE_SIZE - 1 - y, gray(el));
}
}
try {
ImageIO.write(i, "png", new File("tests/ch/epfl/alpano/dem/dem.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
private static int gray(double v) {
double clampedV = max(0, min(v, 1));
int gray = (int) (255.9999 * clampedV);
return (gray << 16) | (gray << 8) | gray;
}
}

View File

@@ -0,0 +1,50 @@
package ch.epfl.alpano.dem;
import static java.lang.Math.max;
import static java.lang.Math.min;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import ch.epfl.alpano.GeoPoint;
import static java.lang.Math.toRadians;
final class DrawHgtDEM2 {
final static double ORIGIN_LON = toRadians(6.0);
final static double ORIGIN_LAT = toRadians(45.0);
final static double WIDTH = toRadians(0.1);
final static int IMAGE_SIZE = 1200;
final static double MIN_ELEVATION = 00;
final static double MAX_ELEVATION = 500;
public static void main(String[] as) throws Exception {
DiscreteElevationModel dDEM = new HgtDiscreteElevationModel(null);
ContinuousElevationModel cDEM =
new ContinuousElevationModel(dDEM);
double step = WIDTH / (IMAGE_SIZE - 1);
BufferedImage i = new BufferedImage(IMAGE_SIZE,
IMAGE_SIZE, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < IMAGE_SIZE; ++x) {
double lon = ORIGIN_LON + x * step;
for (int y = 0; y < IMAGE_SIZE; ++y) {
double lat = ORIGIN_LAT + y * step;
GeoPoint p = new GeoPoint(lon, lat);
double el =
(cDEM.elevationAt(p) - MIN_ELEVATION)
/ (MAX_ELEVATION - MIN_ELEVATION);
i.setRGB(x, IMAGE_SIZE - 1 - y, gray(el));
}
}
dDEM.close();
ImageIO.write(i, "png", new File("tests/ch/epfl/alpano/dem/dem2.png"));
}
private static int gray(double v) {
double clampedV = max(0, min(v, 1));
int gray = (int) (255.9999 * clampedV);
return (gray << 16) | (gray << 8) | gray;
}
}

View File

@@ -0,0 +1,49 @@
package ch.epfl.alpano.dem;
import static java.lang.Math.toRadians;
import static org.junit.Assert.*;
import java.io.File;
import org.junit.Test;
import ch.epfl.alpano.GeoPoint;
public class ElevationProfileTest {
final static File HGT_FILE = new File("HGT"+File.separatorChar+"N46E006.hgt");
final static double AZIMUTH = toRadians(45.0);
final static double LONGITUDE = toRadians(6.0);
final static double LATITUDE = toRadians(46.0);
final static int LENGTH = 111_000;
@Test
public void testElevationProfile() {
DiscreteElevationModel dDEM =
new HgtDiscreteElevationModel(HGT_FILE);
ContinuousElevationModel cDEM =
new ContinuousElevationModel(dDEM);
GeoPoint o =
new GeoPoint(LONGITUDE, LATITUDE);
ElevationProfile p =
new ElevationProfile(cDEM, o, AZIMUTH, LENGTH);
assertEquals(toRadians(6.09385),p.positionAt(10240).longitude(),0.00001);
assertEquals(toRadians(46.06508),p.positionAt(10240).latitude(),0.00001);
}
/*
@Test
public void testElevationAt() {
fail("Not yet implemented");
}
@Test
public void testPositionAt() {
fail("Not yet implemented");
}
@Test
public void testSlopeAt() {
fail("Not yet implemented");
}
*/
}

View File

@@ -0,0 +1,134 @@
package ch.epfl.alpano.dem;
import static java.lang.Math.PI;
import static java.lang.Math.toRadians;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import ch.epfl.alpano.GeoPoint;
import ch.epfl.alpano.Interval1D;
import ch.epfl.alpano.Interval2D;
public class ElevationProfileTestP {
@Test(expected = NullPointerException.class)
public void constructorFailsWhenElevationModelIsNull() {
new ElevationProfile(null, new GeoPoint(0,0), 0, 100);
}
@Test(expected = NullPointerException.class)
public void constructorFailsWhenOriginIsNull() {
new ElevationProfile(newConstantSlopeDEM(), null, 0, 100);
}
@Test(expected = IllegalArgumentException.class)
public void constructorFailsWhenAzimuthIsNotCanonical() {
new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 6.3, 100);
}
@Test(expected = IllegalArgumentException.class)
public void constructorFailsWhenLengthIsZero() {
new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 0, 0);
}
@Test(expected = IllegalArgumentException.class)
public void elevationAtFailsWhenXIsTooBig() {
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 0, 100);
p.elevationAt(101);
}
@Test
public void elevationAtWorksOnConstantSlopeDEMGoingNorth() {
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 0, 100_000);
for (int i = 0; i < 100; ++i) {
double x = 100d * i;
assertEquals(x, p.elevationAt(x), 1e-5);
}
}
@Test
public void elevationAtWorksOnConstantSlopeDEMGoingSouth() {
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), PI, 100_000);
for (int i = 0; i < 100; ++i) {
double x = 100d * i;
assertEquals(-x, p.elevationAt(x), 1e-5);
}
}
@Test
public void elevationAtWorksOnConstantSlopeDEMGoingEast() {
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), PI/2d, 100_000);
for (int i = 0; i < 100; ++i) {
double x = 100d * i;
assertEquals(x, p.elevationAt(x), 1e-5);
}
}
@Test
public void elevationAtWorksOnConstantSlopeDEMGoingWest() {
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 3d*PI/2d, 100_000);
for (int i = 0; i < 100; ++i) {
double x = 100d * i;
assertEquals(-x, p.elevationAt(x), 1e-5);
}
}
@Test(expected = IllegalArgumentException.class)
public void positionAtFailsWhenXIsTooBig() {
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 0, 100);
p.positionAt(101);
}
@Test
public void positionAtProducesConstantLongitudeWhenGoingNorth() {
double lon = toRadians(3);
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(lon,toRadians(40)), 0, 100_000);
for (int i = 0; i < 100; ++i) {
double x = 500d * i;
assertEquals(lon, p.positionAt(x).longitude(), 1e-5);
}
}
@Test
public void positionAtProducesConstantLongitudeWhenGoingSouth() {
double lon = toRadians(3);
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(lon,toRadians(40)), PI, 100_000);
for (int i = 0; i < 100; ++i) {
double x = 500d * i;
assertEquals(lon, p.positionAt(x).longitude(), 1e-5);
}
}
@Test
public void positionAtProducesConstantLatitudeWhenGoingEast() {
double lat = toRadians(40);
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(toRadians(3),lat), PI/2d, 100_000);
for (int i = 0; i < 100; ++i) {
double x = 500d * i;
assertEquals(lat, p.positionAt(x).latitude(), 1e-4);
}
}
@Test
public void positionAtProducesConstantLatitudeWhenGoingWest() {
double lat = toRadians(40);
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(toRadians(3),lat), 3d*PI/2d, 100_000);
for (int i = 0; i < 100; ++i) {
double x = 500d * i;
assertEquals(lat, p.positionAt(x).latitude(), 1e-4);
}
}
@Test(expected = IllegalArgumentException.class)
public void slopeAtFailsWhenXIsNegative() {
ElevationProfile p = new ElevationProfile(newConstantSlopeDEM(), new GeoPoint(0,0), 0, 100);
p.positionAt(-1);
}
private static ContinuousElevationModel newConstantSlopeDEM() {
Interval2D extent = new Interval2D(
new Interval1D(-10_000, 10_000),
new Interval1D(-10_000, 10_000));
return new ContinuousElevationModel(new ConstantSlopeDEM(extent));
}
}

View File

@@ -0,0 +1,77 @@
package ch.epfl.alpano.dem;
import static org.junit.Assert.*;
import static ch.epfl.alpano.Preconditions.checkArgument;
import java.io.File;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
public class HgtDiscreteElevationModelTest {
@Test
public void testHgtDiscreteElevationModel() {
String[] files = {"N45E006.hgt","N45E007.hgt","N45E008.hgt","N45E009.hgt",
"N45E010.hgt","N45E011.hgt","N46E006.hgt","N46E007.hgt",
"N46E008.hgt","N46E009.hgt","N46E010.hgt","N46E011.hgt",
"N47E006.hgt","N47E007.hgt","N47E008.hgt","N47E009.hgt",
"N47E010.hgt","N47E011.hgt","N00E000.hgt","S89W120"};
File file;
for(String txt: files){
file = new File("HGT"+File.separatorChar+txt);
if(file.exists())
new HgtDiscreteElevationModel(file);
}
assertTrue(true);
}
@Test(expected=IllegalArgumentException.class)
public void testHgtDiscreteElevationModelFails() {
String[] files = {"N45E180.hgt","N45E007.hgt",};
File file;
for(String txt: files){
file = new File("HGT"+File.separatorChar+txt);
new HgtDiscreteElevationModel(file);
}
}
@Test
public void checkFileNameSuccess() {
assertTrue(checkFileName("S00E000.hgt")!=null);
assertTrue(checkFileName("N00E000.hgt")!=null);
assertTrue(checkFileName("S00W129.hgt")!=null);
assertTrue(checkFileName("N00W000.hgt")!=null);
assertTrue(checkFileName("S69E139.hgt")!=null);
assertTrue(checkFileName("S90W180.hgt")!=null);
assertTrue(checkFileName("N90E180.hgt")!=null);
assertTrue(checkFileName("S90W180.hgt")!=null);
}
@Test(expected=IllegalArgumentException.class)
public void checkFileNameFails() {
checkFileName("E46E006.hgt");
checkFileName("N4gE006.hgt");
checkFileName("N46E0g6.hgt");
checkFileName("N46E006lhgt");
checkFileName("N46E006.hGT");
checkFileName("N4gE006.hgt");
checkFileName("N46E0g6.hgt");
checkFileName("N46E006phgt");
checkFileName("Q99E006.hGT");
}
private static final Matcher checkFileName(String txt){
final Pattern P = Pattern.compile("([NS])(\\d{2})([EW])(\\d{3})\\.hgt");
Matcher m = P.matcher(txt);
checkArgument((txt.length()==11 && m.find()));
int lat = Integer.parseInt(m.group(2));
int lon = Integer.parseInt(m.group(4));
checkArgument(!(lat>90 || lon>180 ));
return m;
}
}

View File

@@ -0,0 +1,154 @@
package ch.epfl.alpano.dem;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.nio.file.StandardOpenOption.CREATE_NEW;
import static java.nio.file.StandardOpenOption.READ;
import static java.nio.file.StandardOpenOption.WRITE;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ShortBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import ch.epfl.alpano.Interval1D;
import ch.epfl.alpano.Interval2D;
public class HgtDiscreteElevationModelTestP {
private final static long HGT_FILE_SIZE = 3601L * 3601L * 2L;
private static Path FAKE_HGT_DIR, FAKE_HGT_FILE;
@BeforeClass
public static void createFakeHgtFiles() throws IOException {
Path fakeHgtDir = Files.createTempDirectory("hgt");
Path fakeHgtFile = fakeHgtDir.resolve("empty.hgt");
try (FileChannel c = FileChannel.open(fakeHgtFile, CREATE_NEW, READ, WRITE)) {
// make sure the empty hgt file has the right size
c.map(MapMode.READ_WRITE, 0, HGT_FILE_SIZE).asShortBuffer();
}
FAKE_HGT_FILE = fakeHgtFile;
FAKE_HGT_DIR = fakeHgtDir;
}
@AfterClass
public static void deleteFakeHgtFiles() throws IOException {
Files.walkFileTree(FAKE_HGT_DIR, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
if (exc != null)
throw exc;
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
@Test(expected = IllegalArgumentException.class)
public void constructorFailsWithTooShortName() throws Exception {
createHgtDemWithFileNamed("N47E010.hg");
}
@Test(expected = IllegalArgumentException.class)
public void constructorFailsWithInvalidLatitudeLetter() throws Exception {
createHgtDemWithFileNamed("N4xE010.hgt");
}
@Test(expected = IllegalArgumentException.class)
public void constructorFailsWithInvalidLongitudeLetter() throws Exception {
createHgtDemWithFileNamed("N47x010.hgt");
}
@Test(expected = IllegalArgumentException.class)
public void constructorFailsWithInexistantFile() throws Exception {
Path p = FAKE_HGT_DIR.resolve("N40E010.hgt");
try (DiscreteElevationModel d = new HgtDiscreteElevationModel(p.toFile())) {}
}
@Test(expected = IllegalArgumentException.class)
public void constructorFailsWithEmptyFile() throws Exception {
File f = FAKE_HGT_DIR.resolve("N41E010.hgt").toFile();
try (FileOutputStream s = new FileOutputStream(f)) {
s.write(0);
}
try (DiscreteElevationModel d = new HgtDiscreteElevationModel(f)) {}
}
@Test
public void constructorWorksInEcuador() throws Exception {
createHgtDemWithFileNamed("S03W078.hgt");
}
@Test
public void extentMatchesFileName() throws Exception {
int[] lons = new int[] { 1, 7 };
int[] lats = new int[] { 1, 47 };
for (int lon: lons) {
for (int lat: lats) {
Interval2D expectedExtent = new Interval2D(
new Interval1D(lon * 3600, (lon + 1) * 3600),
new Interval1D(lat * 3600, (lat + 1) * 3600));
String hgtFileName = String.format("N%02dE%03d.hgt", lat, lon);
Path p = copyEmptyHgtFileAs(hgtFileName);
try (HgtDiscreteElevationModel dem = new HgtDiscreteElevationModel(p.toFile())) {
assertEquals(expectedExtent, dem.extent());
}
}
}
}
@Test(expected = IllegalArgumentException.class)
public void elevationSampleFailsForIndexNotInExtent() throws Exception {
String hgtFileName = "N02E002.hgt";
Path p = copyEmptyHgtFileAs(hgtFileName);
try (HgtDiscreteElevationModel dem = new HgtDiscreteElevationModel(p.toFile())) {
dem.elevationSample(10, 10);
}
}
@Test
public void elevationSampleIsCorrectInFourCorners() throws Exception {
Path p = FAKE_HGT_DIR.resolve("N01E001.hgt");
try (FileChannel c = FileChannel.open(p, CREATE_NEW, READ, WRITE)) {
ShortBuffer b = c.map(MapMode.READ_WRITE, 0, HGT_FILE_SIZE).asShortBuffer();
b.put(0, (short)1);
b.put(3600, (short) 2);
b.put(3601 * 3600, (short) 3);
b.put(3601 * 3601 - 1, (short) 4);
}
try (HgtDiscreteElevationModel dem = new HgtDiscreteElevationModel(p.toFile())) {
assertEquals(0, dem.elevationSample(4000, 4000), 1e-10);
assertEquals(1, dem.elevationSample(3600, 7200), 1e-10);
assertEquals(2, dem.elevationSample(7200, 7200), 1e-10);
assertEquals(3, dem.elevationSample(3600, 3600), 1e-10);
assertEquals(4, dem.elevationSample(7200, 3600), 1e-10);
}
}
private static void createHgtDemWithFileNamed(String hgtFileName) throws Exception {
Path p = copyEmptyHgtFileAs(hgtFileName);
try (DiscreteElevationModel d = new HgtDiscreteElevationModel(p.toFile())) {}
}
private static Path copyEmptyHgtFileAs(String hgtFileName) throws IOException {
return Files.copy(FAKE_HGT_FILE, FAKE_HGT_DIR.resolve(hgtFileName), REPLACE_EXISTING);
}
}

View File

@@ -0,0 +1,26 @@
package ch.epfl.alpano.dem;
import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.nio.ShortBuffer;
import java.nio.channels.FileChannel.MapMode;
public class MemMapExample {
public static void main(String[] args)
throws IOException {
File f = new File("HGT"+File.separatorChar+"N46E007.hgt");
long l = f.length();
try (FileInputStream s = new FileInputStream(f)) {
ShortBuffer b = s.getChannel()
.map(MapMode.READ_ONLY, 0, l)
.asShortBuffer();
for (int i = 0; i <= 5; ++i)
System.out.println(b.get(i));
System.out.println("-----------------");
for (int i = 12967195; i < 12967201; ++i)
System.out.println(b.get(i));
}
}
}

View File

@@ -0,0 +1,57 @@
package ch.epfl.alpano.dem;
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
import static java.lang.Math.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import ch.epfl.alpano.*;
import javax.imageio.ImageIO;
public final class TestWavyDEM {
@SuppressWarnings("resource")
public static void main(String[] args)
throws IOException {
DiscreteElevationModel dDEM1 =
new WavyDEM(new Interval2D(new Interval1D(0, 50),
new Interval1D(0, 100)));
DiscreteElevationModel dDEM2 =
new WavyDEM(new Interval2D(new Interval1D(50, 100),
new Interval1D(0, 100)));
DiscreteElevationModel dDEM =
dDEM1.union(dDEM2);
ContinuousElevationModel cDEM =
new ContinuousElevationModel(dDEM);
int size = 300;
double scale = (100d / 3600d) / (size - 1);
BufferedImage elI =
new BufferedImage(size, size, TYPE_INT_RGB);
BufferedImage slI =
new BufferedImage(size, size, TYPE_INT_RGB);
for (int x = 0; x < size; ++x) {
for (int y = 0; y < size; ++y) {
GeoPoint p = new GeoPoint(toRadians(x * scale),
toRadians(y * scale));
double el = cDEM.elevationAt(p);
elI.setRGB(x, y, gray(el / 1000d));
double sl = cDEM.slopeAt(p);
slI.setRGB(x, y, gray(sl / (PI / 2d)));
}
}
ImageIO.write(elI, "png", new File("tests/ch/epfl/alpano/dem/elevation.png"));
ImageIO.write(slI, "png", new File("tests/ch/epfl/alpano/dem/slope.png"));
}
private static int gray(double v) {
double clampedV = max(0, min(v, 1));
int gray = (int) (255.9999 * clampedV);
return (gray << 16) | (gray << 8) | gray;
}
}

View File

@@ -0,0 +1,28 @@
package ch.epfl.alpano.dem;
import ch.epfl.alpano.Interval2D;
import static java.lang.Math.PI;
import static java.lang.Math.sin;
import static java.lang.Math.cos;
final class WavyDEM implements DiscreteElevationModel {
private final static double PERIOD = 100, HEIGHT = 1000;
private final Interval2D extent;
public WavyDEM(Interval2D extent) {
this.extent = extent;
}
@Override
public void close() throws Exception { }
@Override
public Interval2D extent() { return extent; }
@Override
public double elevationSample(int x, int y) {
double x1 = PI * 2d * x / PERIOD;
double y1 = PI * 2d * y / PERIOD;
return (1 + sin(x1) * cos(y1)) / 2d * HEIGHT;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 800 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB