Thursday, November 28, 2019

A convenient API for retrieving accurate elevation values

The elevation values for the sites in this atlas were recently updated from Google Earth values to values from the Digital Elevation Model (DEM) called ASTER_DGEMV3 which samples 1 arc second squares (30 m).

I've been wanting to do this for a long time but wasn't able to understand all the gyrations involved.  Happily I stumbled across the site called which was created by Xavier Fischer.

This site is an interface to any one of several DEMs including my ASTER_DGEMV3.  It eliminates an enormous amount of work for those of us who aren't quite up to speed on Digital Elevation Models or map projections but really need a source of accurate elevation data.

I began by using this interface in a very simple and naive way.  This page  provides a simple web call that returns the elevation of the Eiffel Tower in Paris (you should experiment with this.  Copy and paste it into your browser URL window and hit 'return'.): 


As you see it requires three arguments, lat, lon, and DEM name.  For DEM name I used: ASTER_GDEMV3 instead of SRTM_GL3/

This call returns a JSON string with the elevation embedded (it's in the first line):

{"message":"OK","geoPoints"[{"latitude":48.854624,"longitude":2.3436793,"elevation":28.353599548339844}],"resultCount":1,"dataSet":{"name":"ASTER_GDEMV3","description":"ASTER Global Digital Elevation Model 1 arc second (30m)","publicUrl":"",
"resolutionMeters":30,"noDataValue":-9999,"fileFormat":{"name":"GeoTiff file","fileExtension":".tif","type":1,"registration":0},"attribution":
{"text":"NASA/METI/AIST/Japan Spacesystems, and U.S./Japan ASTER Science Team. ASTER Global Digital Elevation Model V003. 2018,
distributed by NASA EOSDIS Land Processes DAAC,"},"dataSource":{"indexFilePath":"ASTGTM.003.json",

So ASTER_GDEMV3 returns an elevation of 28.35 m. where Google Earth returns either 33 or 34 m. depending on exactly where you put the cursor.

How do we handle the JSON?  All you really want is the elevation value.  But since we've been given a URL we're home free.  We can capture the return string using cURL and then use json_decode on the string.  I quickly wrote a program in PHP using cURL that incorporated the URL from    Here's the nucleus of it:

$URL = "$lat&lon=$lon&dataSet=ASTER_GDEMV3";       

// This ^ is the URL I want to send.  You will have had to have already filled in $lat and $lon with the desired values.

$ch1= curl_init();                                        // All of this is just  cURL stuff.  I changed nothing.
curl_setopt ($ch1, CURLOPT_URL, $URL );
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch1, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; Media Center PC 4.0)');
curl_setopt ($ch1, CURLOPT_REFERER,'');  //just a fake referer
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_FOLLOWLOCATION, 20);

$htmlContent= curl_exec($ch1);        // this puts the entire returned string into a variable named $htmlContent

$ar = json_decode($htmlContent);                           // JSON decode

$newElev = $ar->geoPoints[0]->elevation;   // Fetch the elevation field

$newElev = round($newElev);                // Round the value (if you like)


That's all you need to do.  You can put this section in a loop which retrieves the lat/lon pairs from each DB.  You can follow it up with an insert back into the DB of the new elevation value.
I simply generate a sql statement and write it to a .sql file for execution later.  That code looks like this:


$diff = $newElev - $oelev;     // I subtracted the old elevation from the newly returned one.  This is the 'error'.

if ($diff != 0)
echo "update site set ALT = $newElev where pk = '".$pk."' limit 1;";          // this generates a SQL update statement that I pipe to an external .sql file.    $pk ('place key') identifies the specific site


In this section $oelev is the old elevation value from the DB which I'm now going to replace with $newElev.

It looked to me as though the average error was on the order of 10 m.  And by looking at my own old data for elevation I discovered a few gross errors caused by me and not Google Earth.  Those are now corrected.

It always helps to review your data.

I'm very grateful to Mr. Fischer for building this site and then promptly and helpfully following up my questions on Twitter (@ElevationApi).  There is much more on this site including the ability to create 3D models of various terrains.

I know that I'm going to learn a great deal by scrutinizing this site carefully along with Mr. Fischer's helpful links.

Thursday, May 30, 2019

Monday, May 6, 2019

The Archaeological Atlas of Mycenae (Iakovidis [2003]) and how to overcome its limitations

I've received the Archaeological Atlas of Mycenae (Iakovidis et al. [2003]) and there's much to say about it.[1]

One of the first things I've done is to plot the chamber tombs and I wanted to describe how that was done on the chance that it might help others.  Conceptually this work is divided into two parts; one part deals just with the Citadel and the other part describes the surrounding countryside.  When I talk about the chamber tombs here I mean those outside the Citadel and in the country.  The maps for the outside regions are very good (1:2500).  There are 14 of these maps and each is divided into lettered squares that are 500 m. in length and width.  Individual sites are identified by their grid square designator plus a unique sequence number for each site in that square.  Their zero point is at UTM 673439.00 m E, 4179619.00 m N, 3  (37.747448 N, 22.968617 E)

The authors felt that their job was done at this point and they failed to supply a lat/lon pair for each feature and site.   Paradoxically they decided to show us where things are on a map.  But it's much more useful to be unambiguously told.  This is something which is crucial for any kind of Atlas and which they could easily have done.[2]

I wanted a precise lat/long pair for every site of significance before I added it to the Mycenaean Atlas Project.  I began this process by deriving lat/lon pairs for the upper left-hand corner for each indexed square.    I made this easier by setting Google Earth to UTM and worked entirely in meters (Tools>Options>Show lat/long and checking 'Universal Transverse Mercator').   I will supply the easting and northing for each index point later on in this post.  Once I had the index markers set up I needed a way to measure accurately from the edges of the squares to each site in turn. 

1. The vertices from the Archaeological Atlas of Mycenae. 
I have darkened the map to make the vertices more visible.
Ancient Mycenae is the blob outlined in orange in the center.

It was done like this:

a. Notice that the vertical distance between grid lines is ~ 103.3 mm.  The horizontal distance is 101 mm.   In order to convert vertical distances into meters requires multiplying the measured vertical distance in mm. by 4.84.  To convert measured horizontal distances in meters requires multiplying the measured horizontal distance in mm. by 4.95.

b. Measure the vertical and horizontal distances to your site

c. Enter these distances into a text file,  mysite.txt,  with this format:

pk, Upper Corner Vertex label, Item no, Name, VDist (mm), HDist (mm)
C8000, A3, 1, Vythisma S, 82, 74

Here the  pk can be anything - the program will ignore it.  In this example the Vythisma Chamber Tomb Complex is at square A3:1.  The explains the next two items.  They are not modified during execution but are used to label the output.  As is the next item which is the text string for the name - 'Vythisma S'.  The final two arguments are the offset in mm measured vertically from the horizontal square border and horizontally from the vertical square border.

You can add as many of these lines as you like to the input file.

d.  Run the program MSites.php (Listing 1).  This program opens mysite.txt,  reads it in, and converts each line to an easting/northing pair.  The output for 'Vythisma S' looks like this:

C8000, A3,  1,  Vythisma S, 654305.3, 4178721.3

This indicates that 'Vythisma S' (which I arbitrarily called 'C8000') which is item A3:1 in the Archaeological Atlas of Mycenae (Iakovidis et al. [2003]) is located at easting: 654305.3 and northing: 4178721.3.  The UTM zone for all of Greece is '34 S'.   

e. Now you can plot this point in Google Earth by creating a new point and entering the northing/easting/zone triple (set GE to UTM first).  Or you can go on to convert this triple into a regular (WGS84) lat/lon pair using one of the many UTM/WGS84 converters that you  can find on the web and then plotting your new point with this lat/lon  pair.   The lat/lon pair for Vythisma S (after conversion) is this: 37.74278838 N, 22.75134851 E

That's the sequence.  The text for the PHP program Msites.php is in Listing One.  It takes an input file of the measured distances to your sites of interest and returns a UTM easting/northing pair for each line in the input.

Also included in Listing 1 are all the UTM coordinates for the vertices in Iakovidis et al. [2003] that I've found necessary so far.

Listing 2  provides the file mysite.txt for the chamber tombs in the Mycenae region.

When you run this program against mysite.txt  you get the output in Listing 3  the lat/lon pairs (WGS84) for all the converted chamber tomb complexes

The result of plotting all the chamber tombs was, I thought, startling.  Here they are in Google Earth:

2. Chamber tomb complexes plotted.  Mycenae is the blue blob in the center.

3. The chamber tombs plotted in a low-angle which emphasizes how they surround the town of ancient Mycenae (M).

I plotted them in Topoguide also:

4. The Chamber Tombs show up as blue push-pins.  Ancient Mycenae is in the center.

Status: I am about to deliver version 1.015 of the database.  This will include some of the sites around Mycenae although there will be more to do after that.

When the Mycenae work is done the Mycenaean Atlas Project will go into maintenance mode.  I will always accept additions, corrections, and updates but the aggressive phase of coverage expansion has pretty much run its course.  I will respond immediately to anyone who suggests corrections and/or additions and I will be very grateful to receive them.

Remember: Friends don't let friends use Facebook.


[1] Younger [2010].

[2] The authors make a  point of telling us that all the data for the maps was digitized. From the Preface, ix.: "Some 703 various remains of all periods of antiquity (tombs, buildings, roads, quarries) were located and plotted.  Their particulars (kind of monument, form, dimensions, construction, orientation, preservation, excavation data, bibliography etc.) were recorded and entered in an electronic data bank."


Iakovidis et al. [2003]:  Spyros Iakovidis, Elizabeth B. French, Kim Shelton, Charalambos Ioannides, Anton Jansen, John Lavery, Archaeological Atlas of Mycenae.   The Archaeological Society at Athens Library, no. 229.  2003, ISBN: 960-8145-40-6.

Younger [2010]:  Younger, John, 'Archaeological Atlas of Mycenae; A Review', GNOMON, Vol. 82, 623-633.  2010.    Online here.

LISTING 1: MSites.php


// Each small array ($A3 etc.) holds the easting and northing for one vertex point in the Atlas.

$A3 = array("easting"=> 653939, "northing"=> 4179119);
$A4 = array("easting"=> 654439, "northing"=> 4179119);
$B2 = array("easting"=> 653439, "northing"=> 4178619);
$B3 = array("easting"=> 653939, "northing"=> 4178619);
$B4 = array("easting"=> 654439, "northing"=> 4178619);
$B5 = array("easting"=> 654939, "northing"=> 4178619);
$C2 = array("easting"=> 653439, "northing"=> 4178119);
$C3 = array("easting"=> 653939, "northing"=> 4178119);
$C4 = array("easting"=> 654439, "northing"=> 4178119);
$C5 = array("easting"=> 654939, "northing"=> 4178119);
$C7 = array("easting"=> 655939, "northing"=> 4178119);
$D2 = array("easting"=> 653439, "northing"=> 4177619);
$D3 = array("easting"=> 653939, "northing"=> 4177619);
$D4 = array("easting"=> 654439, "northing"=> 4177619);
$D5 = array("easting"=> 654939, "northing"=> 4177619);
$D6 = array("easting"=> 655439, "northing"=> 4177619);
$E2 = array("easting"=> 653439, "northing"=> 4177119);
$E3 = array("easting"=> 653939, "northing"=> 4177119);
$E4 = array("easting"=> 654439, "northing"=> 4177119);
$E5 = array("easting"=> 654939, "northing"=> 4177119);
$E6 = array("easting"=> 655439, "northing"=> 4177119);
$F2 = array("easting"=> 653439, "northing"=> 4176619);
$F3 = array("easting"=> 653939, "northing"=> 4176619);
$F4 = array("easting"=> 654439, "northing"=> 4176619);
$F5 = array("easting"=> 654939, "northing"=> 4176619);
$F6 = array("easting"=> 655439, "northing"=> 4176619);
$G4 = array("easting"=> 654439, "northing"=> 4176119);
$G5 = array("easting"=> 654939, "northing"=> 4176119);
$H3 = array("easting"=> 653939, "northing"=> 4175619);
$H5 = array("easting"=> 654939, "northing"=> 4175619);
$H6 = array("easting"=> 655439, "northing"=> 4175619);
$J1 = array("easting"=> 652939, "northing"=> 4175119);
$J5 = array("easting"=> 654939, "northing"=> 4175119);

// This array ($idx) hold the coordinates for each labelled corner in the maps of Archaeological Atlas of Mycenae, Iakovidis et al. [2003].

$idx = array("A3"=>$A3, "A4"=>$A4,
"B2"=>$B2, "B3"=>$B3, "B4"=>$B4, "B5"=>$B5,
"C2"=>$C2, "C3"=>$C3, "C4"=>$C4, "C5"=>$C5, "C7"=>$C7,
"D2"=>$D2, "D3"=>$D3, "D4"=>$D4, "D5"=>$D5, "D6"=>$D6,
"E2"=>$E2, "E3"=>$E3, "E4"=>$E4, "E5"=>$E5, "E6"=>$E6,
"F2"=>$F2, "F3"=>$F3, "F4"=>$F4, "F5"=>$F5, "F6"=>$F6,
"G4"=>$G4, "G5"=>$G5,
"H3"=>$H3, "H5"=>$H5, "H6"=>$H6,
"J1"=>$J1, "J5"=>$J5

// Input file line looks like PK, DQID, iten number in quadrant, name, Vdist, Hdist.  Input file will be called 'mysite.txt'

// open the input file and read it in
$myfile = file('...\mysite.txt');   // open input file.  File is called mysite.txt.  Supply your own path to it.

// for each line in the input file do this ...

foreach ($myfile as $line_num => $line)

$larr = explode(',',$line);  // break up input line on commas

$pk = $larr[0];            // Place key.  Only used on output line as a convenience?
$DQID = $larr[1];          // Quadrant identifier, A4, C5, J1, etc.
$ItemInQuad = $larr[2];    // sequence number of this item in the quadrant
$pname = $larr[3];         // text string = name label
$Vdist = $larr[4];        // vertical distance in mm.
$Hdist = $larr[5];        // horizontal distance in mm.

// Convert vertical and horizontal distance in mm. to meters

$VdistC = 4.84 * $Vdist;  //  $Vdist is mm.  Convert to meters by multiplying by 4.84
$HdistC = 4.9505 * $Hdist;  // $Hdist is mm.  Convert to meters by multiplying by 4.9505

// Get the name of the quadrant and trim it

$DQID = substr($DQID, 1);    // There's a leading space in $DQID before the trim here.

// compute new easting and northing

$newEast  =    $idx[$DQID]["easting"] + $HdistC;
$newNorth =    $idx[$DQID]["northing"] - $VdistC;

// output the result

echo PHP_EOL."$pk, $DQID, $ItemInQuad, $pname, $newEast, $newNorth";

}        // loop over whole file


LISTING  2: The input file, mysite.txt, which lists the distances (in mm.) from nearest grid lines to all the chamber tombs in the Mycenae region.

C8000, A3, 1, Vythisma S, 82, 74
C8001, A4, 1, Vythisma N, 29, 1.5
C8002, B2, 1, Batsourorachi, 80, 96.5
C8003, B3, 1, Loupouno, 51.5, 77.75
C8004, B3, 3, Asprokhoma W, 93.25, 78
C8005, B4, 2, Asprokhoma E (A/A), 87, 10
C8006, B4, 3, Asprokhoma E, 95.5, 19
C8007, B4, 14, Souleimani, 45, 76
C8008, B4, 18, Kapsala S, 93, 90
C8009, B5, 1, Kapsala N/Vlakhostrata, 48.5, 10
C8010, C2, 2, Batsourorachi SW, 72.5, 58
C8011, C3, 4, Koutsoumbela, 41.1, 49.5
C8012, C3, 8, Asprokhoma SW, 51, 89
C8013, C4, 1, Asprokhoma/Agriosykia, 8.25, 6
C8014, C4, 16, Paleogalaro, Lower, 92.5, 97
C8015, C5, 4, Paleogalaro E/Kapsala, 36.5, 47
C8016, C5, 8, Paleogalaro W, 29.8, 3
C8017, C7, 1, Gortsoula, 96, 4
C8018, D3, 5, Kato Fournos, 27, 32.5
C8019, D3, 9, Pezoulia, 33, 89
C8020, D3, 17, Ep. Pigadi/Fournodiaselo, 80.25, 56
C8022, E2, 1, Sfalakhtra, 61.5, 89.8
C8023, E3, 1, Ep. Pigadi/Fournodiaselo, 14, 58.5
C8024, E3, 3, Bouziati (Kalkani N Bank), 26.5, 34
C8025, E3, 4, Kalkani S Bank, 38, 24
C8026, E3, 7, Kalkani SW, 89, 20
C8027, E3, 13, Panagia, 30, 94.5
C8028, E3, 14, Ag. Georgios, 99, 91
C8029, E4, 4, Panagia, 11.5, 1
C8030, E4, 14, Third Km, 72.5, 25.7
C8031, F3, 1, Alepotrypa, 23.5, 32
C8032, F3, 1, Alepotrypa-Aspria, 23.5, 32
C8033, F3, 5, Ag. Georgios, 18, 99.5
C8034, F4, 1, Third Km, 2, 22.5
C8035, F4, 20, Sarra, 59, 40
C8036, G4, 7, Sarra, 87, 92
C8037, G4, 11, Tserania, 19.5, 47
C8038, G5, 2, Sarra, 24.5, 16
C8039, G5, 9, Gouves Cem?, 100, 42
C8040, H3, 2a, Priftiani, 61, 89.5
C8041, H5, 9, Plesia, 97.5, 83
C8042, H6, 4, Koufourachi, 60.5, 43
C8044, J5, 3, Plesia Rema, 20, 26.5
C8045, J5, 7, Plesia, 11, 88.5

LISTING 3: The result of running MSites.php. The outputs are UTM  pairs.

C8000, A3,  1,  Vythisma S, 654305.337, 4178721.3
C8001, A4,  1,  Vythisma N, 654446.42575, 4178978.35
C8002, B2,  1,  Batsourorachi, 653916.72325, 4178231
C8003, B3,  1,  Loupouno, 654323.901375, 4178369.225
C8004, B3,  3,  Asprokhoma W, 654325.139, 4178166.7375
C8005, B4,  2,  Asprokhoma E (A/A), 654488.505, 4178197.05
C8006, B4,  3,  Asprokhoma E, 654533.0595, 4178155.825
C8007, B4,  14,  Souleimani, 654815.238, 4178400.75
C8008, B4,  18,  Kapsala S, 654884.545, 4178167.95
C8009, B5,  1,  Kapsala N/Vlakhostrata, 654988.505, 4178383.775
C8010, C2,  2,  Batsourorachi SW, 653726.129, 4177767.375
C8011, C3,  4,  Koutsoumbela, 654184.04975, 4177919.665
C8012, C3,  8,  Asprokhoma SW, 654379.5945, 4177871.65
C8013, C4,  1,  Asprokhoma/Agriosykia, 654468.703, 4178078.9875
C8014, C4,  16,  Paleogalaro, 654896.92125, 4178119
C8015, C5,  4,  Paleogalaro E/Kapsala, 655171.6735, 4177941.975
C8016, C5,  8,  Paleogalaro W, 654953.8515, 4177974.47
C8017, C7,  1,  Gortsoula, 655958.802, 4177653.4
C8018, D3,  5,  Kato Fournos, 654099.89125, 4177488.05
C8019, D3,  9,  Pezoulia, 654379.5945, 4177458.95
C8020, D3,  17,  Ep. Pigadi/Fournodiaselo, 654216.228, 4177229.7875
C8022, E2,  1,  Sfalakhtra, 653883.5549, 4176820.725
C8023, E3,  1,  Ep. Pigadi/Fournodiaselo, 654228.60425, 4177051.1
C8024, E3,  3,  Bouziati (Kalkani N Bank), 654107.317, 4176990.475
C8025, E3,  4,  Kalkani S Bank, 654057.812, 4176934.7
C8026, E3,  7,  Kalkani SW, 654038.01, 4176687.35
C8027, E3,  13,  Panagia, 654406.82225, 4176973.5
C8028, E3,  14,  Ag. Georgios, 654389.4955, 4176638.85
C8029, E4,  4,  Panagia, 654443.9505, 4177063.225
C8030, E4,  14,  Third Km, 654566.22785, 4176767.375
C8031, F3,  1,  Alepotrypa, 654097.416, 4176505.025
C8032, F3,  1,  Alepotrypa-Aspria, 654097.416, 4176505.025
C8033, F3,  5,  Ag. Georgios, 654431.57475, 4176531.7
C8034, F4,  1,  Third Km, 654550.38625, 4176609.3
C8035, F4,  20,  Sarra, 654637.02, 4176332.85
C8036, G4,  7,  Sarra, 654894.446, 4175697.05
C8037, G4,  11,  Tserania, 654671.6735, 4176024.425
C8038, G5,  2,  Sarra, 655018.208, 4176000.175
C8039, G5,  9,  Gouves Cem?, 655146.921, 4175634
C8040, H3,  2a,  Priftiani, 654382.06975, 4175323.15
C8041, H5,  9,  Plesia, 655349.8915, 4175146.125
C8042, H6,  4,  Koufourachi, 655651.8715, 4175325.575
C8044, J5,  3,  Plesia Rema, 655070.18825, 4175022
C8045, J5,  7,  Plesia, 655377.11925, 4175065.65

LISTING 4: The Chamber Tomb Complexes around Mycenae with lat/lon pairs in WGS84 after conversion from UTM.

Name, ID,  latitude,  longitude
Vythisma S, A3:1, 37.74278838, 22.75134851
Vythisma N, A4:1, 37.74508036, 22.75300421
Batsourorachi, B2:1, 37.73843667, 22.74683571
Loupouno, B3:1, 37.73961338, 22.75148434
Asprokhoma W, B3:3, 37.73778895, 22.75145539
Asprokhoma E (A/A), B4:2, 37.73803447, 22.75331548
Asprokhoma E, B4:3, 37.73765555, 22.7538121
Souleimani, B4:14, 37.73981441, 22.75706504
Kapsala S, B4:18, 37.73770538, 22.75780161
Kapsala N/Vlakhostrata, B5:1, 37.73963215, 22.75902743
Batsourorachi SW, C2:2, 37.73429185, 22.7445757
Koutsoumbela, C3:4, 37.73558683, 22.74980259
Asprokhoma SW, C3:8, 37.7351213, 22.75201041
Asprokhoma/Agriosykia, C4:1, 37.73697418, 22.75306577
Paleogalaro - Lower, C4:16, 37.7372623, 22.75793156
Paleogalaro E/Kapsala, C5:4, 37.73562093, 22.76101086
Paleogalaro W, C5:8, 37.73595057, 22.75854709
Gortsoula, C7:1, 37.73288738, 22.76987825
Kato Fournos, D3:5, 37.73171253, 22.74875651
Pezoulia, D3:9, 37.73140325, 22.75192278
Ep. Pigadi/Fournodiaselo, D3:17, 37.72936624, 22.75002125
Sfalakhtra, E2:1, 37.72573692, 22.74616099
Ep. Pigadi/Fournodiaselo, E3:1, 37.72775434, 22.75012372
Bouziati (Kalkani N Bank), E3:3, 37.72722858, 22.74873529
Kalkani S Bank, E3:4, 37.72673442, 22.74816201
Kalkani SW, E3:7, 37.72450935, 22.74788504
Panagia, E3:13, 37.7270252, 22.75212852
Ag. Georgios, E3:14, 37.72401322, 22.75186098
Panagia, E4:4, 37.72782727, 22.75256924
Third Km, E4:14, 37.7251413, 22.75389318
Alepotrypa, F3:1, 37.72285677, 22.74852014
Alepotrypa-Aspria, F3:1, 37.72285677, 22.74852014
Ag. Georgios, F3:5, 37.7230408, 22.75231545
Third Km, F4:1, 37.72371986, 22.75367993
Sarra, F4:20, 37.72121467, 22.75460367
Sarra, G4:7, 37.7154432, 22.75738767
Tserania, G4:11, 37.71843019, 22.75493109
Sarra, G5:2, 37.71815314, 22.75885624
Gouves Cem?, G5:9, 37.71483245, 22.76023778
Priftiani, H3:2a, 37.71216119, 22.75149759
Plesia, H5:9, 37.71040275, 22.76243524