Opened 3 months ago
Last modified 3 months ago
#22596 new enhancement
[Patch] Elevation at current map location / Automatic download of SRTM HGT files
Reported by: | hhtznr | Owned by: | team |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | Plugin elevationprofile | Version: | |
Keywords: | elevation, SRTM HGT, current map location, automatic download | Cc: | OliverW |
Description (last modified by )
What?
I wrote this patch, which will display the elevation at the current location on the map next to the coordinates in the MapStatus line. Optionally, the necessary SRTM HGT files providing the elevation can automatically be downloaded, if they are missing on disk.
Why?
This is typical functionality in most map applications, but it is missing in JOSM. Elevation at the current map location (mouse pointer) can be useful in determining the proper direction of waterways, the location of summits etc.
How does it work?
It builds on HgtReader from ElevationProfile plugin written by Oliver Wieland. HgtReader checks whether the HGT file covering the current map location is available on disk. If so, it reads it into memory and determines the elevation at the current location.
I extended HgtReader with HgtDownloader, which will download any missing HGT file in a background thread from NASA's Land Processes Distributed Active Archive Center (LP DAAC) at https://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL3.003/2000.02.11/.
I created a preferences tab, where the elevation feature can be enabled and where optional auto-downloading can turned on.
Why not as plugin?
I did not see a way, how to feed the current map location (mouse pointer) into a plugin.
What's the content of the patch?
New files:
- src/org/openstreetmap/josm/data/elevation/ElevationHelper.java (from Oliver Wieland)
- src/org/openstreetmap/josm/data/elevation/HgtDownloader.java
- src/org/openstreetmap/josm/data/elevation/HgtDownloadListener.java
- src/org/openstreetmap/josm/data/elevation/HgtPreferences.java
- src/org/openstreetmap/josm/data/elevation/HgtReader.java (builds on Oliver Wieland)
- src/org/openstreetmap/josm/data/elevation/gpx/GeoidCorrectionKind.java (from Oliver Wieland)
- src/org/openstreetmap/josm/gui/preferences/elevation/HgtPreference.java
- src/org/openstreetmap/josm/gui/preferences/elevation/HgtPreferencesPanel.java
- resources/images/preferences/elevation.svg
- resources/images/statusline/ele.svg
Updated files:
- src/org/openstreetmap/josm/gui/MapStatus.java
- src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java
What next?
I would appreciate it, if the demonstrated functionality could be integrated into mainline JOSM.
Attachments (5)
Change History (17)
Changed 3 months ago by
Attachment: | JOSM_18616_Elevation_git_diff.txt added |
---|
Changed 3 months ago by
Attachment: | JOSM_18616_Elevation_new_updated_src_files.tar.gz added |
---|
Archive with new and updated source files
Changed 3 months ago by
Attachment: | JOSM_with_elevation_in_MapSatus.png added |
---|
Screenshot of elevation information in MapStatus line
Changed 3 months ago by
Attachment: | JOSM_Elevation_Data_Preferences.png added |
---|
Screenshot of elevation data preferences tab
comment:1 Changed 3 months ago by
Description: | modified (diff) |
---|
comment:2 Changed 3 months ago by
Description: | modified (diff) |
---|
comment:3 Changed 3 months ago by
Description: | modified (diff) |
---|
comment:4 follow-up: 5 Changed 3 months ago by
Why not as plugin?
I did not see a way, how to feed the current map location (mouse pointer) into a plugin.
It is possible to do so:
Point mousePosition = MainApplication.getMap().mapView.getMousePosition(); LatLon latLon = MainApplication.getMap().mapView.getLatLon(mousePosition.getX(), mousePosition.getY());
Also, you should have renamed attachment:JOSM_18616_Elevation_git_diff.txt such that it ended with .diff
or .patch
.
Anyway, skimming through your patch:
- Why unzip the HGT file? It takes more space on disk, and there are several methods in Java to get a decompressed input stream. If you profiled it, and it took fewer resources, that would be helpful to know.
- Please don't set the
HttpClient
factory. (HttpClient.setFactory(Http1Client::new);
). This should only be set by JOSM itself or a plugin which provides its own factory (like the http2 plugin). - I'm not a fan of the TODO comments sprinkled throughout the code
- Is there any documentation for the login process for the government server? Does it use OAuth 2.0? If so, does it allow redirects to localhost/127.0.0.1? I've got a WIP patch for OAuth 2.0 support in JOSM, and it takes advantage of the remote control server to receive initial server redirect.
comment:5 follow-up: 6 Changed 3 months ago by
Replying to taylor.smock:
Why not as plugin?
I did not see a way, how to feed the current map location (mouse pointer) into a plugin.
It is possible to do so:
Point mousePosition = MainApplication.getMap().mapView.getMousePosition(); LatLon latLon = MainApplication.getMap().mapView.getLatLon(mousePosition.getX(), mousePosition.getY());
Thank you for pointing this out. It helped me to figure out how to do it outside the scope of MapStatus
. I think, your proposal would not work to get the position as a result of mouse motion. But being pointed to mapView
, I came across that it could be done like this, copying the listener code from MapStatus
into an own plugin class and putting it in Plugin.mapFrameInitialized
:
@Override public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) { super.mapFrameInitialized(oldFrame, newFrame); if (newFrame != null) { newFrame.mapView.addMouseMotionListener(new MouseMotionListener() { @Override public void mouseDragged(MouseEvent e) { mouseMoved(e); } @Override public void mouseMoved(MouseEvent e) { if (newFrame.mapView.getCenter() == null) return; // Do not update the view if ctrl or right button is pressed. if ((e.getModifiersEx() & (MouseEvent.CTRL_DOWN_MASK | MouseEvent.BUTTON3_DOWN_MASK)) == 0) updateEleText(newFrame.mapView.getLatLon(e.getX(), e.getY())); } }); } } }
Also, you should have renamed attachment:JOSM_18616_Elevation_git_diff.txt such that it ended with
.diff
or.patch
.
Anyway, skimming through your patch:
- Why unzip the HGT file? It takes more space on disk, and there are several methods in Java to get a decompressed input stream. If you profiled it, and it took fewer resources, that would be helpful to know.
Modern file systems use compression so it does not take more space when the original file is decompressed. Should I create a config option so the user can decide whether to decompress the downloaded files or to leave them as-is?
- Please don't set the
HttpClient
factory. (HttpClient.setFactory(Http1Client::new);
). This should only be set by JOSM itself or a plugin which provides its own factory (like the http2 plugin).
Is this better?
Http1Client httpClient = new Http1Client(url, "GET");
- I'm not a fan of the TODO comments sprinkled throughout the code
NP, can be deleted.
- Is there any documentation for the login process for the government server? Does it use OAuth 2.0? If so, does it allow redirects to localhost/127.0.0.1? I've got a WIP patch for OAuth 2.0 support in JOSM, and it takes advantage of the remote control server to receive initial server redirect.
They have documentation here: https://urs.earthdata.nasa.gov/documentation
It's not really explained in depth, but it seems they use OAuth2: https://urs.earthdata.nasa.gov/documentation/for_users/oauth2
They also have a Java code example, which uses java.net.HttpURLConnection
: https://urs.earthdata.nasa.gov/documentation/for_users/data_access/java
However, it uses basic authorization with username + password instead of the authorization bearer. Would this be preferred? I thought otherwise.
Sorry, I'm absolutely no expert on this web stuff. So some support on this would be appreciated.
comment:6 Changed 3 months ago by
Replying to hhtznr:
Modern file systems use compression so it does not take more space when the original file is decompressed. Should I create a config option so the user can decide whether to decompress the downloaded files or to leave them as-is?
Many of the common linux filesystems do not enable transparent compression by default. BTRFS requires the user to pick a compression type, ext4 doesn't support transparent compression, and so on.
- Please don't set the
HttpClient
factory. (HttpClient.setFactory(Http1Client::new);
). This should only be set by JOSM itself or a plugin which provides its own factory (like the http2 plugin).Is this better?
Http1Client httpClient = new Http1Client(url, "GET");
Not really. You should be using the factory (HttpClient.create
), and the variable type should just be the base HttpClient
type instead of a specific subclass. All of the methods you called on Http1Client
and Http1Response
are available in the super class/interface (HttpClient
and HttpResponse
respectively).
- Is there any documentation for the login process for the government server? Does it use OAuth 2.0? If so, does it allow redirects to localhost/127.0.0.1? I've got a WIP patch for OAuth 2.0 support in JOSM, and it takes advantage of the remote control server to receive initial server redirect.
They have documentation here: https://urs.earthdata.nasa.gov/documentation
It's not really explained in depth, but it seems they use OAuth2: https://urs.earthdata.nasa.gov/documentation/for_users/oauth2
They also have a Java code example, which uses
java.net.HttpURLConnection
: https://urs.earthdata.nasa.gov/documentation/for_users/data_access/java
However, it uses basic authorization with username + password instead of the authorization bearer. Would this be preferred? I thought otherwise.
Sorry, I'm absolutely no expert on this web stuff. So some support on this would be appreciated.
It does look like they do use OAuth 2, and that would be greatly preferred over username + password. See #20768 for the WIP patch for JOSM OAuth 2 support.
comment:7 follow-up: 8 Changed 3 months ago by
Is a "display local elevation" feature of interest for integration into the main application or should I rather convert my proposal into a plugin?
comment:8 follow-up: 9 Changed 3 months ago by
Replying to hhtznr:
Is a "display local elevation" feature of interest for integration into the main application or should I rather convert my proposal into a plugin?
I'd probably just apply the patch to the ElevationProfile
plugin.
comment:9 Changed 3 months ago by
Replying to taylor.smock:
Replying to hhtznr:
Is a "display local elevation" feature of interest for integration into the main application or should I rather convert my proposal into a plugin?
I'd probably just apply the patch to the
ElevationProfile
plugin.
OK, I'll consider your valued feedback on HttpClient
and decompression, incorporate my code into ElevationProfile
and send a new diff/patch.
Changed 3 months ago by
Attachment: | JOSM_ElevationProfile_18494.diff added |
---|
Git diff of reworked elevation patch against ElevationProfile
comment:10 Changed 3 months ago by
I integrated my code into ElevationProfile
plugin and created this diff: https://josm.openstreetmap.de/attachment/ticket/22596/JOSM_ElevationProfile_18494.diff
An incompatible change is the directory, where the HGT files are saved.
The original code used:
for (String location : Preferences.getAllPossiblePreferenceDirs()) { String fullPath = new File(location + File.separator + "elevation", file).getPath(); [...] }
I use ...
public static final File DEFAULT_HGT_DIRECTORY = Paths.get(Preferences.main().getDirs().getCacheDirectory(true).toString(), "elevation", "SRTM3").toFile();
... to make sure, I have a directory that is writable when downloading and to ensure that SRTM3 HGT files can be distinguished from other elevation data in case that this should be necessary in the future.
What is your opinion on this patch?
comment:11 Changed 3 months ago by
Component: | Core → Plugin elevationprofile |
---|---|
Owner: | changed from team to OliverW |
Version: | latest |
comment:12 Changed 3 months ago by
Cc: | OliverW added |
---|---|
Owner: | changed from OliverW to team |
Git diff of elevation patch