Obtain the altitude of almost anywhere

This flow uses the free API of opentopodata.org to estimate elevation from latitude & longitude.

I used international airports for test data since Wikipedia has latitude, longitude & elevation data for them
Of course runways are not necessarily level.
The exception is a UK Ordnance Survey trig. point with a reliable published elevation.

These locations are all reasonably free from jungle which might degrade space derived data.
It's interesting to see how much the three datasets vary!

[{"id":"16832a0f88474019","type":"inject","z":"587c179bd119b743","name":"Capel Curig","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"53.10505,-3.91235","payloadType":"str","x":130,"y":340,"wires":[["a42ae083f347c883","c708abe71616c94e","8c5f674dd1edc2c3"]]},{"id":"29f446fc3d755f2a","type":"comment","z":"587c179bd119b743","name":"Capel Curig 197.436m","info":"","x":140,"y":300,"wires":[]},{"id":"40bf5770db7e247b","type":"comment","z":"587c179bd119b743","name":"Agra Airport 167.94m","info":"","x":140,"y":400,"wires":[]},{"id":"7eab32379963907e","type":"inject","z":"587c179bd119b743","name":"Agra","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"27.161831,77.970726","payloadType":"str","x":110,"y":440,"wires":[["a42ae083f347c883","8c5f674dd1edc2c3","c708abe71616c94e"]]},{"id":"87dd72d9688760de","type":"comment","z":"587c179bd119b743","name":"Ushuaia Airport 31m","info":"","x":130,"y":500,"wires":[]},{"id":"bdad0862c640d0fc","type":"inject","z":"587c179bd119b743","name":"Ushuaia","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"-54.843756,-68.313204","payloadType":"str","x":120,"y":540,"wires":[["a42ae083f347c883","8c5f674dd1edc2c3","c708abe71616c94e"]]},{"id":"2db4dfb687c95134","type":"comment","z":"587c179bd119b743","name":"Denver Int. Airport 1656m","info":"","x":150,"y":600,"wires":[]},{"id":"2a0ced9ac38ecb3a","type":"inject","z":"587c179bd119b743","name":"Denver","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"39.861785,-104.696602","payloadType":"str","x":110,"y":640,"wires":[["a42ae083f347c883","8c5f674dd1edc2c3","c708abe71616c94e"]]},{"id":"86bd223b9787ebdc","type":"group","z":"587c179bd119b743","name":"Advanced Spaceborne Thermal Emission and Reflection Radiometer dataset.","style":{"label":true},"nodes":["8c5f674dd1edc2c3","91367e5c9c5d45a6","1bc0340b0f28f2a0","add6ca2ae25aeabe"],"x":314,"y":419,"w":552,"h":122},{"id":"8c5f674dd1edc2c3","type":"change","z":"587c179bd119b743","g":"86bd223b9787ebdc","name":"ASTER","rules":[{"t":"set","p":"url","pt":"msg","to":"\"https://api.opentopodata.org/v1/aster30m?locations=\" & payload","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":460,"wires":[["91367e5c9c5d45a6"]]},{"id":"91367e5c9c5d45a6","type":"http request","z":"587c179bd119b743","g":"86bd223b9787ebdc","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":570,"y":460,"wires":[["1bc0340b0f28f2a0"]]},{"id":"1bc0340b0f28f2a0","type":"debug","z":"587c179bd119b743","g":"86bd223b9787ebdc","name":"debug 99","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":760,"y":460,"wires":[]},{"id":"add6ca2ae25aeabe","type":"comment","z":"587c179bd119b743","g":"86bd223b9787ebdc","name":"Coverage 83S to 83N. 1 arc-second (c30m at equator). Accuracy +/- ?","info":"","x":590,"y":500,"wires":[]},{"id":"c607856ce2e44129","type":"group","z":"587c179bd119b743","name":"EU-DEM derived from ASTER & SRTM. ","style":{"label":true},"nodes":["c708abe71616c94e","56280c54d13e9048","320d6459b82eed0d","3456abd4e71e46f3"],"x":314,"y":559,"w":552,"h":122},{"id":"c708abe71616c94e","type":"change","z":"587c179bd119b743","g":"c607856ce2e44129","name":"EU-DEM","rules":[{"t":"set","p":"url","pt":"msg","to":"\"https://api.opentopodata.org/v1/eudem25m?locations=\" & payload","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":400,"y":640,"wires":[["56280c54d13e9048"]]},{"id":"56280c54d13e9048","type":"http request","z":"587c179bd119b743","g":"c607856ce2e44129","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":570,"y":640,"wires":[["320d6459b82eed0d"]]},{"id":"320d6459b82eed0d","type":"debug","z":"587c179bd119b743","g":"c607856ce2e44129","name":"debug 98","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":760,"y":640,"wires":[]},{"id":"3456abd4e71e46f3","type":"comment","z":"587c179bd119b743","g":"c607856ce2e44129","name":"Coverage Europe. Grid 25m. Accuracy +-7m","info":"","x":510,"y":600,"wires":[]},{"id":"64277e2926fccb88","type":"group","z":"587c179bd119b743","name":"Shuttle Radar Topography Mission ","style":{"label":true},"nodes":["a42ae083f347c883","a36aa6dc2840a99e","afd8f4fee8cd34a8","330e2a8a2f37ee0b"],"x":314,"y":279,"w":592,"h":122},{"id":"a42ae083f347c883","type":"change","z":"587c179bd119b743","g":"64277e2926fccb88","name":"SRTM","rules":[{"t":"set","p":"url","pt":"msg","to":"\"https://api.opentopodata.org/v1/srtm30m?locations=\" & payload","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":360,"wires":[["a36aa6dc2840a99e"]]},{"id":"a36aa6dc2840a99e","type":"http request","z":"587c179bd119b743","g":"64277e2926fccb88","name":"","method":"GET","ret":"obj","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":570,"y":360,"wires":[["afd8f4fee8cd34a8"]]},{"id":"afd8f4fee8cd34a8","type":"debug","z":"587c179bd119b743","g":"64277e2926fccb88","name":"debug 97","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":760,"y":360,"wires":[]},{"id":"330e2a8a2f37ee0b","type":"comment","z":"587c179bd119b743","g":"64277e2926fccb88","name":"Coverage 56S to 60N.Grid 1arc-second (c30m) at equator. Accuracy +/- 8m?","info":"","x":610,"y":320,"wires":[]}]

Results are in JSON format

{
   "results":   [
      {
         "dataset":"eudem25m",
         "elevation":194.2355194091797,
         "location":
         {
            "lat":53.10505,
            "lng":-3.91235
         }
      }   ],
   "status":"OK"
}
5 Likes

There is also TessaDEM which isn't free but isn't expensive either and has a claimed vertical resolution of around 2m and removes tree height errors. Horizontal resolution is 30m.

€12 per 12,000 requests (€0.001 per request).

For €12 you can get:

  • Up to 6,144,000 elevation data in points mode.
  • Up to 24,576,000 elevation data in path mode.
  • Up to 196,608,000 elevation data in area mode.

For England there is a free dataset offering +/- 15cm on a 1m grid!
I'm not aware of an API and the data itself is too cryptic for me.
https://www.data.gov.uk/dataset/cf3f1137-c12b-44a1-a835-e80fe4a60b92/lidar-composite-digital-surface-model-dsm-1m

I saw that but didn't mention it because it doesn't have an API and I couldn't see an easy way to query the data in the way required.

@jbudd,
For some reason my brain likes your project, although my creativity fails to find use cases for it. Unless of course in some professional applications...
Do you have some examples?
Bart

I think this came out of a side conversation we had about standardising a schema for weather data. One of the things you need to know if you want to include your own sensor data for pressure is your altitude. Also useful to know your altitude to compare against what some weather API's return since generally, the location you request weather for is rarely the location the API returns data for. Here in Sheffield for example, this is quite critical since even just 10m away can be quite a different altitude. :slight_smile:

1 Like

We keep hearing about the alpine nature of Sheffield! :mountain_snow: :mountain:

Most weather APIs give the air pressure at sea level, likely in hectoPascals, (1hPa = 100Pa) but the barometer on your wall displays absolute pressure, probably as inches of water or mercury.
So my BME280 currently reports 991.7 hPa while sea level pressure from an API is 1009 hPa.
My elevation is somewhere around 140 m. Grandfather's much-tapped aneroid barometer says 29.7 "Hg (It's pointer can be adjusted with a screw)

If I knew the elevation correction formulae I could use these to calibrate my BME and aneroid.

Another possibility: hot air ballooning in thick fog? :upside_down_face: That would highlight the difference between elevation and altitude!

2 Likes

I'll see if I can dig it out, I know I have it somewhere, possibly buried in some Arduino code. :slight_smile:

Which is why pilots have to pick up a current weather forecast for their starting and ending airports before flying. Aircraft have to adjust their old-school altimeters to the current barometric pressure so that they show the correct starting and ending altitude.

In the UK and similar island locations, barometric pressure changes quite rapidly, on a large mainland like continental Europe or North America, less so. Before the days of GPS and before the days of having many GPS satellites in the sky (which makes GPS altitude readings a bit more accurate), those of us into the mountains sometimes relied on barometric-based altimeters to help cross reference against map reading in bad weather. This was more useful in the Alps than on British mountains though. Even today, from the ground, especially at higher latitudes, GPS altitudes are rarely very accurate.

1 Like

Indeed, it seems to be Arduino code:

Sealevel

	double SFE_BMP180::sealevel(double P, double A)
	// Given a pressure P (mb) taken at a specific altitude (meters),
	// return the equivalent pressure (mb) at sea level.
	// This produces pressure readings that can be used for weather measurements.
	{
		return( P/pow( 1-(A/44330.0),5.255 ) );
	}

Altitude

	double SFE_BMP180::altitude(double P, double P0)
	// Given a pressure measurement P (mb) and the pressure at a baseline P0 (mb),
	// return altitude (meters) above baseline.
	{
		return(44330.0*(1-pow(P/P0,1/5.255)));
	}

Convert from mb to inHg

	Serial.print(bmpPress*0.0295333727,2); Serial.println(" inHg");

From the BME280 docs:

Calculating Altitude / Elevation

The BME280 does not measure altitude directly, but it can be calculated using the pressure reading. Most libraries for this device include altitude calculation routines.

Since the device does a very good job of measuring pressure, it can do a very good job of calculating relative altitude. If you have an altitude reading with the device sitting on a table and then move it to the floor, it will show a 2 foot decrease in altitude.

If on the other hand you are trying to measure absolute altitude, such as the altitude of your table relative to sea level, things get more complicated. Since altitude is relative to sea level the device needs to know the current air pressure corrected to sea level so that it has a reference by which to calculate the altitude given the air pressure that it is currently reading.

You can get somewhat close by finding the reported air pressure from a local airport or weather service on-line which are corrected for sea level. In our example program down below, you would enter this value in the SEA_LEVEL_PRESSURE constant. In our example, we have 1013.25 loaded which is a typical reading.

Since the air pressure is constantly changing based on time, location and weather conditions, unless you have an accurate barometer corrected to sea level with you to reference, it will be difficult to get closer than 20-30 feet.

If you know the altitude that the sensor is at, you can also back into a reading by modifying the SEA_LEVEL_PRESSURE constant to give you the correct altitude reading. This might be useful if you want to make absolute measurements based on your current elevation, such as sending a rocket up into the air.

I think that is a simplification because it doesn't take into account the change of temperature with elevation (lapse rate).

Wikipedia explains it like this
image

Simple enough I think? :crazy_face:

Mind you it doesn't explain where you obtain the value for temperature lapse rate in the International Standard Atmosphere.
I wonder if the heating effect of urban areas (air conditioning, convection from sunlit concrete) results in an anomalous low pressure over the city.

Well as Julian says, this was a sideline and I think I'll get back to the main topic!

1 Like

Ah, you've triggered my memory now. I remember going through that when I started on my sensors years ago and rejecting the the full calc as "impossible" to comprehend! :rofl:

The simplified calculations seemed accurate enough for most use. Probably not for landing an aircraft in the fog though!

1 Like

... or helicopters...

Another example:
Some APIs, eg Norwegian Met. Office met.no allow you to pass the altitude of a place with your http request..

Presumably they correct for the difference in altitude between your chosen location and the point[s] on their worldwide forecast grid used to construct their response.

From https://api.met.no/weatherapi/locationforecast/2.0/documentation#!/data/get_compact

altitude
Ground surface height above (or sometimes below) sea level in whole meters (integers).
Optional but recommended for precise temperature values.
When missing the internal topography model is used for temperature correction, which is rather course and may be incorrect in hilly terrain.

**Note** that this is the altitude of the **ground surface**! 
You cannot use this to ask for atmospheric predictions, e.g. for aviation purposes.
2 Likes