diff --git a/readme.md b/readme.md index ad622f0..6817c1c 100644 --- a/readme.md +++ b/readme.md @@ -91,3 +91,21 @@ java -jar target/hgt-map-renderer-0.0.1-SNAPSHOT.jar "contour" "" "44" "16" "48" "22" "47.84907" "20.19078" "500" "47.91870" "19.70804" "500" +``` + +Int the next example the viewpoint is on the lookout tower in Kékes, and the target is the reservoir in Nagyréde. +The point is visible. +``` +java -jar target/hgt-map-renderer-0.0.1-SNAPSHOT.jar "cansee" "" "44" "16" "48" "22" "47.87231" "20.00913" "1050" "47.78333" "19.83700" "200" +``` + +Warning! This method does not yet calculate with the Earth's curve. \ No newline at end of file diff --git a/src/main/java/hu/awm/srtm/data/hgt/Tile.java b/src/main/java/hu/awm/srtm/data/hgt/Tile.java index c73b823..f4564d8 100644 --- a/src/main/java/hu/awm/srtm/data/hgt/Tile.java +++ b/src/main/java/hu/awm/srtm/data/hgt/Tile.java @@ -77,6 +77,20 @@ public double getMaxElevation() { return maxElevation; } + public double elevationByExactCoordinates(final double lat, final double lon) { + if (lat < this.lat || lat >= this.lat + 1 || lon < this.lon || lon >= this.lon + 1) { + throw new IllegalArgumentException("{lat: " + lat + " lon: " + lon + "} is not in tile of {lat: " + + this.lat + " lon: " + this.lon + "}"); + } + double latDelta = lat - this.lat; + double lonDelta = lon - this.lon; + + int row = (int)(RESOLUTION * latDelta); + int col = (int)(RESOLUTION * lonDelta); + + return elevation(row, col); + } + private static String createExceptionMessage(int row, int col) { return "Query: " + row + "/" + col; } diff --git a/src/main/java/hu/awm/srtm/map/contour/ContourCalculator.java b/src/main/java/hu/awm/srtm/map/contour/ContourCalculator.java index c87d19f..2e7b568 100644 --- a/src/main/java/hu/awm/srtm/map/contour/ContourCalculator.java +++ b/src/main/java/hu/awm/srtm/map/contour/ContourCalculator.java @@ -107,7 +107,7 @@ else if (eyeHeight < targetVisibleHeight) { } //Based on https://github.com/dizzib/earthcalc. - static double calculateTargetHiddenHeight(double eyeHeight, int targetDistance) { + public static double calculateTargetHiddenHeight(double eyeHeight, double targetDistance) { final int EARTH_RADIUS_KM = 6371; final double eyeHeightKm = eyeHeight * 0.001; final double targetDistanceKm = targetDistance * 0.001; diff --git a/src/main/java/hu/awm/srtm/tools/cansee/CanSeeCalculator.java b/src/main/java/hu/awm/srtm/tools/cansee/CanSeeCalculator.java index 32843e7..be646a2 100644 --- a/src/main/java/hu/awm/srtm/tools/cansee/CanSeeCalculator.java +++ b/src/main/java/hu/awm/srtm/tools/cansee/CanSeeCalculator.java @@ -1,11 +1,13 @@ package hu.awm.srtm.tools.cansee; +import hu.awm.srtm.data.hgt.Tile; import hu.awm.srtm.data.hgt.TileMap; +import hu.awm.srtm.map.contour.ContourCalculator; public class CanSeeCalculator { - private Xyz from; - private Xyz to; + private Vector3D from; + private Vector3D to; private TileMap tileMap; public CanSeeCalculator() { @@ -13,8 +15,8 @@ public CanSeeCalculator() { } public void setCoordinates(Double fromLat, Double fromLon, Double fromHeight, Double toLat, Double toLon, Double toHeight) { - this.from = new Xyz(fromLat, fromLon, fromHeight); - this.to = new Xyz(toLat, toLon, toHeight); + this.from = new Vector3D(fromLat, fromLon, fromHeight); + this.to = new Vector3D(toLat, toLon, toHeight); } public void setTileMap(TileMap tileMap) { @@ -22,12 +24,36 @@ public void setTileMap(TileMap tileMap) { } public Sight calculateSight() { - // TODO: Replace this with the correct math. - return new Sight(null, null, null); + Vector3D loseSightCoordinate = null; + Vector3D directionVector = to.subtract(from); + double stepCount = Math.max(Math.abs(to.getLat() - from.getLat()) * Tile.RESOLUTION, + Math.abs(to.getLon() - from.getLon()) * Tile.RESOLUTION) * 2; + Vector3D stepVector = directionVector.getInstanceResizedToLength(directionVector.length() / stepCount); + + for (Vector3D i = from.newInstance(); i.lengthTo(to) > stepVector.length(); i = i.add(stepVector)) { + if (!isPointVisible(i)) { + loseSightCoordinate = i.newInstance(); + break; + } + } + if (loseSightCoordinate == null) { + if (!isPointVisible(to)) { + loseSightCoordinate = to.newInstance(); + } + } + return new Sight(from, to, loseSightCoordinate); } public boolean calculateBoolean() { Sight sight = calculateSight(); return !sight.hasBlocker(); } + + private boolean isPointVisible(Vector3D pointToCheck) { + int tileLat = pointToCheck.getLat().intValue(); + int tileLon = pointToCheck.getLon().intValue(); + Tile tile = tileMap.getByLatLon(tileLat, tileLon); + double height = tile.elevationByExactCoordinates(pointToCheck.getLat(), pointToCheck.getLon()); + return height <= pointToCheck.getHeight(); + } } diff --git a/src/main/java/hu/awm/srtm/tools/cansee/Sight.java b/src/main/java/hu/awm/srtm/tools/cansee/Sight.java index 9c02f84..2b7aa44 100644 --- a/src/main/java/hu/awm/srtm/tools/cansee/Sight.java +++ b/src/main/java/hu/awm/srtm/tools/cansee/Sight.java @@ -1,40 +1,40 @@ package hu.awm.srtm.tools.cansee; public class Sight { - private Xyz startCoordinate; - private Xyz endCoordinate; - private Xyz looseSightCoordinate; + private Vector3D startCoordinate; + private Vector3D endCoordinate; + private Vector3D looseSightCoordinate; public Sight() { } - public Sight(Xyz startCoordinate, Xyz endCoordinate, Xyz looseSightCoordinate) { + public Sight(Vector3D startCoordinate, Vector3D endCoordinate, Vector3D looseSightCoordinate) { this.startCoordinate = startCoordinate; this.endCoordinate = endCoordinate; this.looseSightCoordinate = looseSightCoordinate; } - public Xyz getStartCoordinate() { + public Vector3D getStartCoordinate() { return startCoordinate; } - public void setStartCoordinate(Xyz startCoordinate) { + public void setStartCoordinate(Vector3D startCoordinate) { this.startCoordinate = startCoordinate; } - public Xyz getEndCoordinate() { + public Vector3D getEndCoordinate() { return endCoordinate; } - public void setEndCoordinate(Xyz endCoordinate) { + public void setEndCoordinate(Vector3D endCoordinate) { this.endCoordinate = endCoordinate; } - public Xyz getLooseSightCoordinate() { + public Vector3D getLooseSightCoordinate() { return looseSightCoordinate; } - public void setLooseSightCoordinate(Xyz looseSightCoordinate) { + public void setLooseSightCoordinate(Vector3D looseSightCoordinate) { this.looseSightCoordinate = looseSightCoordinate; } diff --git a/src/main/java/hu/awm/srtm/tools/cansee/Vector3D.java b/src/main/java/hu/awm/srtm/tools/cansee/Vector3D.java new file mode 100644 index 0000000..07fce78 --- /dev/null +++ b/src/main/java/hu/awm/srtm/tools/cansee/Vector3D.java @@ -0,0 +1,64 @@ +package hu.awm.srtm.tools.cansee; + +public class Vector3D { + private Double lat; + private Double lon; + private Double height; + + public Vector3D(Double lat, Double lon, Double height) { + this.lat = lat; + this.lon = lon; + this.height = height; + } + + public Vector3D newInstance() { + return new Vector3D(this.lat, this.lon, this.height); + } + + public Double getLat() { + return lat; + } + + public Double getLon() { + return lon; + } + + public Double getHeight() { + return height; + } + + public Vector3D getInstanceResizedToLength(Double newLength) { + Double ratio = newLength / length(); + return new Vector3D(lat * ratio, lon * ratio, height * ratio); + } + + public Double length() { + return Math.sqrt(Math.pow(lat, 2.0) + + Math.pow(lon, 2.0) + + Math.pow(height, 2.0)); + } + + public static Vector3D subtract(Vector3D from, Vector3D what) { + return from.subtract(what); + } + + public Vector3D subtract(Vector3D what) { + return new Vector3D(this.lat - what.getLat(), + this.lon - what.getLon(), + this.height - what.getHeight()); + } + + public static Vector3D add(Vector3D to, Vector3D what) { + return to.add(what); + } + + public Vector3D add(Vector3D what) { + return new Vector3D(this.lat + what.getLat(), + this.lon + what.getLon(), + this.height + what.getHeight()); + } + + public double lengthTo(Vector3D what) { + return what.subtract(this).length(); + } +} diff --git a/src/main/java/hu/awm/srtm/tools/cansee/Xyz.java b/src/main/java/hu/awm/srtm/tools/cansee/Xyz.java deleted file mode 100644 index 63dc391..0000000 --- a/src/main/java/hu/awm/srtm/tools/cansee/Xyz.java +++ /dev/null @@ -1,25 +0,0 @@ -package hu.awm.srtm.tools.cansee; - -public class Xyz { - private Double x; - private Double y; - private Double z; - - public Xyz(Double x, Double y, Double z) { - this.x = x; - this.y = y; - this.z = z; - } - - public Double getX() { - return x; - } - - public Double getY() { - return y; - } - - public Double getZ() { - return z; - } -}