forked from dmahr1/ihatecoordinatesystems
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
617 lines (592 loc) · 38.4 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
<!DOCTYPE html>
<html lang="en-US">
<head>
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-2029009-3"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'UA-2029009-3');
</script>
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>I Hate Coordinate Systems!</title>
<link rel="icon" href="favicon16.svg" sizes="16x16" />
<link rel="icon" href="favicon32.svg" sizes="32x32" />
<link rel="stylesheet" type="text/css" media="screen" href="styles.css">
<script>
function lookupProjections() {
var lng = document.getElementById("lookup_lng").value;
var lat = document.getElementById("lookup_lat").value;
var x = document.getElementById("lookup_x").value;
var y = document.getElementById("lookup_y").value;
document.getElementById("projectionLoookupLoading").style.display = 'inherit';
if (![lng, lat, x, y].every((str) => { return !isNaN(str) && !isNaN(parseFloat(str)) })) {
document.getElementById("projectionLoookupLoadingText").innerHTML = "Please provide all four parameters.";
return false;
}
document.getElementById("projectionLookupButton").disabled = true;
document.getElementById("projectionLoookupLoadingText").innerHTML = "Searching for projections... (this can take up to 30 seconds)";
var url = `https://us-east1-ihatecoordinatesystems.cloudfunctions.net/projection_lookup_1?lng=${lng}&lat=${lat}&x=${x}&y=${y}`;
fetch(url)
.then(response => response.json())
.then(data => {
document.getElementById("projectionLookupButton").disabled = false;
if (data.error || data.projections.length == 0) {
document.getElementById("projectionLoookupLoadingText").innerHTML = "No results found!";
return;
}
document.getElementById("projectionLoookupLoading").style.display = 'none';
var table = document.getElementById("projectionLookupResults");
while (table.childElementCount > 1) {
table.removeChild(table.lastChild);
}
data.projections.forEach(element => {
var tr = document.createElement('tr');
tr.innerHTML = '<td style="padding-right:0.5em;">' + element.projection + '</td>' +
'<td style="padding-right:0.5em;">' + element.name + '</td>' +
'<td style="text-align:right;">' + element.distance.toFixed(2) + '</td>';
table.appendChild(tr);
});
table.style.display = 'inherit';
});
return false;
}
</script>
</head>
<body>
<div class="max-width">
<div id="header">
<h2 id="title" class="center"><a href="#">🤬 I Hate Coordinate Systems! 🤬</a></h2>
<p>
Coordinate reference systems (CRSs) are a thorn in the side of many geospatial professionals. It's easy
to get by when things are working, but if there's a problem it's hard to even know what to search for.
</p>
<p>
This is a <span class="bold">problem-based guide</span class="bold"> of common CRS issues, root
causes, and solutions.
</p>
</div>
<div id="contents">
<ul style="padding: 0;">
<li><a href="#mental-model">How do I wrap my head around these things?</a></li>
<li><a href="#null-island">My dataset is off the coast of Africa!</a></li>
<li><a href="#incorrectly-gcs">My dataset looks like it's bigger than the Earth!</a></li>
<li><a href="#wrong-crs">My dataset is not located where it should be!</a></li>
<li><a href="#correct-crs">What coordinate system should my dataset be in?</a></li>
<li><a href="#wrong-gcs">My dataset is slightly offset from where it should be!</a></li>
<li><a href="#redefine">How do I redefine a dataset's coordinate system?</a></li>
<li><a href="#not-equidistant">My measurements are bigger or smaller than they should be!</a></li>
<li><a href="#why-mercator">Why is Mercator used if it's so distorted?</a></li>
<li><a href="#why-project">Why don't we always use longitude/latitude?</a></li>
<li><a href="#ellipsoidal-vs-orthometric">My X- and Y-values are OK, but my Z-values (heights,
elevations) are off!</a></li>
<li><a href="#glossary">What do all these terms mean?</a></li>
</ul>
</div>
<div id="mental-model">
<h2><a href="#mental-model">I hate coordinate systems! How do I wrap my head around these things?</a></h2>
<p><span class="bold">Apply this three-part mental model of geospatial datasets.</span> Many common problems
happen when one of these parts is missing or out of sync.</p>
<div class="partlist">
<p>
<span class="part1"><span class="bold">Attributes</span>: the meanings or labels of a data
point.</span>
</p>
<p>
<span class="part2"><span class="bold">Coordinates</span>: numbers describing the data
point's position in space.</span>
</p>
<p>
<span class="part3"><span class="bold">Coordinate (reference) system</span>: metadata
describing the space itself: origin, axes, units, etc.</span>
</p>
</div>
<p>For example:</p>
<div class="partlist">
<p>
<span class="part1"><span class="bold">Attributes</span>: "The White House" or "1600
Pennsylvania Avenue"</span>
</p>
<p>
<span class="part2"><span class="bold">Coordinates</span>: (-77.0367, 38.8976)</span>
</p>
<p>
<span class="part3"><span class="bold">Coordinate (reference) system</span>: WGS84
longitude,latitude</span>
</p>
</div>
</div>
<div id="null-island">
<h2><a href="#null-island">I hate coordinate systems! My dataset is off the coast of Africa!</a>
</h2>
<p>
<span class="bold">
Your dataset probably has some junk <span class="part2">coordinates</span>.
</span>
Many data formats store "null" as zeroes. If your software is assuming a longitude/latitude geographic
<span class="part3">coordinate system</span> (GCS), then the point with <span
class="part2">coordinates</span> (0, 0) is where the equator crosses the prime meridian off the
coast of Africa (humorously known as <a href="https://en.wikipedia.org/wiki/Null_Island"
target="_blank">Null Island</a>). This can sometimes happen when importing from Excel and empty rows
are not trimmed off.
</p>
<img src="images/null_island.png" width="100%">
<p>
<span class="bold">Solution:</span> Remove the data points from your dataset whose <span
class="part2">coordinates</span> are null.
</p>
</div>
<div id="incorrectly-gcs">
<h2><a href="#incorrectly-gcs">I hate coordinate systems! My dataset looks like it's bigger than
the Earth!</a></h2>
<p>
<span class="bold">
Your dataset probably has its <span class="part3">coordinate system</span> wrongly defined as a
longitude/latitude geographic coordinate system (GCS).
</span>
This can happen if the coordinate system is missing altogether, in which case GIS software often assumes
a GCS without telling you. A GCS only ranges from -180° west to +180° east in the X-axis and
-90° south to +90 north in the Y-axis. If the <span class="part2">coordinates</span> in your dataset are
out of this range then your dataset will look like it's off of the Earth.
</p>
<p>
<span class="bold">Solution:</span> <a href="#redefine">Redefine the coordinate system</a>, i.e. change
the <span class="part3">coordinate system</span> but not the <span class="part2">coordinates</span>,
from the GCS to the <a href="#correct-crs">correct coordinate system</a>.
</p>
</div>
<div id="wrong-crs">
<h2><a href="#wrong-crs">I hate coordinate systems! My dataset is not located where it should
be!</a>
</h2>
<p>
<span class="bold">
Your dataset probably has the wrong <span class="part3">coordinate system</span>.
</span> This is the more general case of the previous problem. This can happen if the coordinate system
is missing altogether, in which case GIS software often assumes that it is the same coordinate system as
a previously loaded dataset, or the coordinate system set in the "project" or "map document".
</p>
<p>
<span class="bold">Solution:</span> <a href="#redefine">Redefine the coordinate system</a>, i.e. change
the <span class="part3">coordinate system</span> but not the <span class="part2">coordinates</span>,
to the <a href="#correct-crs">correct coordinate system</a>.
</p>
</div>
<div id="correct-crs">
<h2><a href="#correct-crs">I hate coordinate systems! What coordinate system should my dataset be in?</a>
</h2>
<p>
<span class="bold">
Look at the two things you do know: the <span class="part1">attributes</span> and the <span
class="part2">coordinates</span>.
</span>
A data point's <span class="part1">attributes</span> gives context to where on the Earth it is located.
Most GIS software will display the minimum and maximum <span class="part2">coordinates</span> in the
layer's properties as "extent" or "bounding box". From these, do some detective work on the <span
class="part3">coordinate system</span> which you should use when <a href="#redefine">redefining</a>
your dataset.
</p>
<p class="solutions"><span class="bold">Solutions:</span></p>
<ul class="solutions">
<li>
If the <span class="part1">attributes</span> indicate the approximate longitude,latitude where the
<span class="part2">coordinates</span> <span class="italic">should</span> be located, try doing a
reverse lookup. This iterates over every well-defined <span class="part3">coordinate system</span>,
unprojects the X,Y <span class="part2">coordinates</span> to WGS84, and measures the error to the
known longitude,latitude. Errors less than a few hundred meters denote a reasonable projection,
though this isn't precise enough to <a href="#wrong-gcs">determine the GCS</a>. You can run
<a href="https://github.com/dmahr1/ihatecoordinatesystems/blob/master/lookup.py">this sample
code</a> yourself, or use this form:
</li>
<form onsubmit="return lookupProjections()" action="javascript:void(0);">
<table style="padding: 0.5em;width:100%;font-size:90%;">
<colgroup>
<col span="1" style="width: 18%;">
<col span="1" style="width: 20%;">
<col span="1" style="width: 18%;">
<col span="1" style="width: 20%;">
<col span="1" style="width: 20%;">
</colgroup>
<tbody>
<tr>
<td style="text-align:right;"><label for="lookup_lng">Longitude:</label></td>
<td><input style="width:90%;" type="number" step="any" id="lookup_lng"
name="lookup_lng"></td>
<td style="text-align:right;"><label for="lookup_lat">Latitude:</label></td>
<td><input style="width:90%;" type="number" step="any" id="lookup_lat"
name="lookup_lat"><br></td>
<td></td>
</tr>
<tr>
<td style="text-align:right;"><label for="lookup_x">X-coordinate:</label></td>
<td><input style="width:90%;" type="number" step="any" id="lookup_x" name="lookup_x">
</td>
<td style="text-align:right;"><label for="lookup_y">Y-coordinate:</label></td>
<td><input style="width:90%;" type="number" step="any" id="lookup_y" name="lookup_y">
</td>
<td><input style="width:70%;" id="projectionLookupButton" type="submit" value="Submit">
</td>
</tr>
</tbody>
</table>
</form>
<p id="projectionLoookupLoading" style="display:none;text-align:center;">
<span id="projectionLoookupLoadingText" class="bold italic"></span>
</p>
<table id="projectionLookupResults" style="display:none;padding:0.5em;font-size:80%;">
<tr>
<td><span class="bold">Code</span></td>
<td><span class="bold">Name</span></td>
<td style="text-align:right;"><span class="bold">Error (meters)</span></td>
</tr>
</table>
<li>
If the <span class="part2">coordinates</span> have X-values between -180 and 180, and Y-values
between -90 and 90, then you probably want to <a href="#redefine">redefine</a> to a
longitude,latitude geographic <span class="part3">coordinate system</span> (GCS) like WGS84.
</li>
<li>
If the <span class="part2">coordinates</span> have large absolute values, try <a
href="#redefine">redefining</a> to a local <span class="part3">coordinate system</span> like
UTM, Gauss-Krüger, State Plane, or a national grid. Also consider trying neighboring zones, e.g. if
UTM Zone 19N is wrong, try UTM Zone 18N.
</li>
<li>
If the <span class="part1">attributes</span> suggest the dataset is in the USA, then there might a
problem converting to/from <img src="images/flag-usa.png" class="flag"> Freedom Units <img
src="images/flag-usa.png" class="flag">. Try multiplying/dividing a data point's <span
class="part2">coordinates</span> by 3.28084 to convert feet to meters/meters to feet and see if
that places it in the proper location.
</li>
<li>
If the minimum X/Y <span class="part2">coordinates</span> are both zero and the maxmimum X/Y <span
class="part2">coordinates</span> are both positive, then the dataset may have been exported from
non-geospatial software like Photoshop or Illustrator or Inkscape. This is especially likely if the
dataset is flipped vertically since those editors typically have the Y-axis increasing going down.
You will need to manually georeference the dataset to use it, which changes both the <span
class="part2">coordinates</span> and the <span class="part3">coordinate system</span>.
</li>
</ul>
</div>
<div id="wrong-gcs">
<h2><a href="#wrong-gcs">I hate coordinate systems! My dataset is slightly offset from where it
should be!</a></h2>
<p>
<span class="bold">Your dataset probably has the wrong longitude/latitude geographic <span
class="part3">coordinate system</span> (GCS)</span>. Different GCSs define slightly different
sizes/shapes of the Earth (their ellipsoids) and different positionings on the Earth (their
datums). As a result, the same longitude/latitude <span class="part2">coordinates</span> in two
different GCSs can appear offset, although typically within tens of meters of each other. This can
happen even if you are using a projected coordinate system (PCS) whose units are not degrees of
longitude/latitude since PCSs have a GCS embedded within them. <img src="images/wrong-gcs.png"
width="100%">
<p class="solutions"><span class="bold">Solution:</span><a href="#redefine"> Redefine the coordinate
system</a>, i.e. change the <span class="part3">coordinate system</span> but not the <span
class="part2">coordinates</span>, to one of the following
</p>
<ul class="solutions">
<li>Try redefining to the WGS84 GCS.</li>
<li>If your dataset was collected with GPS <img src="images/flag-usa.png" class="flag">, try redefining
to WGS84.</li>
<li>If your dataset was collected with GLONASS <img src="images/flag-ru.png" class="flag">, try
redefining to PZ-90.</li>
<li>If your dataset was collected with Galileo <img src="images/flag-eu.png" class="flag">, try
redefining to ITRF.</li>
<li>If your dataset is in the USA <img src="images/flag-usa.png" class="flag">, try redefining to NAD27,
NAD83, or WGS84.</li>
<li>If your dataset is in Europe <img src="images/flag-eu.png" class="flag">, try redefining to ED50,
ETRS89, or WGS84.</li>
<li>If your dataset is in Australia <img src="images/flag-au.png" class="flag">, try redefining to GDA94
or GDA2020.</li>
<li>If your dataset is in China <img src="images/flag-cn.png" class="flag"> and/or collected with
BeiDou, <a
href="https://en.wikipedia.org/wiki/Restrictions_on_geographic_data_in_China#Coordinate_systems"
target="_blank">good
luck</a>.</li>
</ul>
</div>
<div id="redefine">
<h2><a href="#redefine">I hate coordinate systems! How do I redefine a dataset's coordinate system?</a></h2>
<p>
<span class="bold">
It depends on your software.
</span>
Remember, redefining means the metadata about the <span class="part3">coordinate system</span> is
modified but the
<span class="part2">coordinates</span> are not. This contrasts with reprojections and transformations,
which modify both the <span class="part3">coordinate system</span> and the <span
class="part2">coordinates</span>.
</p>
<p class="solutions"><span class="bold">Solutions:</span></p>
<ul class="solutions">
<li>In ArcGIS Pro, use the <a
href="https://pro.arcgis.com/en/pro-app/tool-reference/data-management/define-projection.htm"
target="_blank">Define
Projection tool</a>, <span class="italic">not</span> the Project tool.</li>
<li>In ArcMap, use the <a
href="https://desktop.arcgis.com/en/arcmap/latest/tools/data-management-toolbox/define-projection.htm"
target="_blank">Define
Projection tool</a>, <span class="italic">not</span> the Project tool.</li>
<li>In QGIS, for vector datasets, use the <a
href="https://docs.qgis.org/latest/en/docs/user_manual/processing_algs/qgis/vectorgeneral.html#assign-projection"
target="_blank">Assign
Projection tool</a> in the Vector General toolset, <span class="italic">not</span> the
Reproject Layer tool.</li>
<li>In QGIS, for raster datasets, use the <a
href="https://docs.qgis.org/latest/en/docs/user_manual/processing_algs/gdal/rasterprojections.html#assign-projection"
target="_blank">Assign
Projection</a> tool in the "GDAL" toolset, <span class="italic">not</span> the Warp (Reproject)
tool.</li>
<li>From the command line, for vector datasets, use <a
href="https://gdal.org/programs/ogr2ogr.html#cmdoption-ogr2ogr-a_srs" target="_blank"><span
class="mono">ogr2ogr</span> with the <span class="mono">-a_srs</span>
parameter</a>, <span class="italic">not</span> the <span class="mono">-t_srs</span> parameter.
</li>
<li>From the command line, for raster datasets, use <a
href="https://gdal.org/programs/gdal_edit.html#cmdoption-a_srs" target="_blank"><span
class="mono">gdal_edit.py</span> with the <span class="mono">-a_srs</span>
parameter</a>.
</li>
</ul>
</div>
<div id="not-equidistant">
<h2><a href="#not-equidistant">I hate coordinate systems! My measurements are bigger or smaller than they
should be!</a></h2>
<p>
<span class="bold">
Your dataset is probably in a non-equidistant <span class="part3">coordinate system</span>.
</span> Most GIS software stupidly calculates distances, areas, and volumes using Euclidean math in
the dataset's or data frame's <span class="part3">coordinate system</span>, <span
class="italic">regardless</span> of whether it is
equidistant. Depending on the amount of distortion associated with the projection, this can lead to
(wildly) incorrect measurements without you realizing. In the common case of the Mercator projection,
distances are enlarged by about <span class="mono">1/cos(latitude)</span>.
</p>
<p class="solutions"><span class="bold">Solutions:</span></p>
<ul class="solutions">
<li>Reproject your dataset (changing both the <span class="part2">coordinates</span> and <span
class="part3">coordinate system</span>) to an appropriate "local" <span class="part3">coordinate
system</span>. A local coordinate system is tuned to offer very accurate Euclidean measurements
for a constrained region of the Earth. Examples include UTM, Gauss-Krüger, State Plane, and
equidistant national grids like the Equidistant Conic.</li>
<li>Perform geodesic measurements. This unprojects the <span class="part2">coordinates</span> to
longitude/latitude (if projected) and then calculates precise distance along the GCS's ellipsoid.
But beware: each calculation is slower than the Euclidean version, and the improvement in accuracy
is marginal versus a local <span class="part3">coordinate </span> (the previous solution) unless you
require sub-centimeter accuracy. This is done by default in <a
href="https://docs.qgis.org/latest/en/docs/user_manual/introduction/general_tools.html#measuring"
target="_blank">QGIS</a>, can be enabled in <a
href="https://pro.arcgis.com/en/pro-app/help/mapping/navigation/measure.htm"
target="_blank">ArcGIS Pro</a> and <a
href="https://desktop.arcgis.com/en/arcmap/latest/map/working-with-layers/measuring-distances-and-areas.htm"
target="_blank">ArcMap</a>, and can be performed programmatically with open-source libraries
like <a href="https://geographiclib.sourceforge.io/" target="_blank">GeographicLib</a>.
</li>
</ul>
</div>
<div id="why-mercator">
<h2><a href="#why-mercator">I hate coordinate systems! Why is Mercator ever used if it's so distorted?</a>
</h2>
<p>
<span class="bold">Mercator is the only <span class="italic">conformal</span> cylindrical map
projection.</span> Cylindrical map projections mean the whole Earth fits into a rectangle,
which is very convenient for data processing algorithms that are used to working with rectangular
images. Conformal means that angles and shapes are always preserved: north is always up, squares are
always square, etc. Using a non-conformal projection would make things look stretched, squashed, and/or
rotated when zooming in.
</p>
<img src="images/mercator.jpg" width="100%" style="border: 0; display: block; opacity: 0.9;">
<table
style="width: 100%; text-align: center; border: 2px solid #4e4e4e;margin: 0; border-top: 0; padding: 0; border-spacing: 0;">
<colgroup>
<col style="width: 33%">
<col style="width: 34%">
<col style="width: 33%">
</colgroup>
<tbody>
<tr>
<td><span class="bold">Mercator (cylindrical)</span></td>
<td style="border-left: 2px solid #4e4e4e; border-right: 2px solid #4e4e4e"><span
class="bold">Lambert Cylindrical</span></td>
<td><span class="bold">Albers Conic</span></td>
</tr>
<tr>
<td>✅ Shape</td>
<td style="border-left: 2px solid #4e4e4e; border-right: 2px solid #4e4e4e">❌ Shape</td>
<td>✅ Shape</td>
</tr>
<tr>
<td>✅ Rotation</td>
<td style="border-left: 2px solid #4e4e4e; border-right: 2px solid #4e4e4e">✅ Rotation</td>
<td>❌ Rotation</td>
</tr>
<tr>
<td>❌ Area</td>
<td style="border-left: 2px solid #4e4e4e; border-right: 2px solid #4e4e4e">✅ Area</td>
<td>✅ Area</td>
</tr>
</tbody>
</table>
<p>
Mercator does enlarge <span class="italic">areas</span> farther from the equator, but at least this
distortion is the same horizontally and vertically. And it's trivial to calculate a <a
href="https://en.wikipedia.org/wiki/Mercator_projection#Scale_factor" target="_blank">scale
factor</a> to correct measurements. The only time the distortion is problematic is when viewing a
global-scale map with a range of different scale factors, but most maps are not global-scale and there
are plenty of better projections to use for this case.
</p>
</div>
<div id="why-project">
<h2><a href="#why-project">I hate coordinate systems! Why don't we always use longitude/latitude?</a></h2>
<p class="solutions">Good question. There are a bunch of reasons we use planar projected <span
class="part3">coordinate systems</span> rather than just sticking with latitude,longitude geographic
<span class="part3">coordinate systems</span> all the time:</p>
<ul class="solutions">
<li><span class="bold">Planar measurements are ubiquitous.</span> Common GIS features like
property boundaries, road centerlines, forests, lakes, etc. are all reckoned in
Euclidean distances, areas, and volumes - not in terms of angles.</li>
<li><span class="bold">Planar measurements are easier to calculate.</span> Measuring distances on a
plane with the Pythagorean theorem is easier than along a sphere with the <a
href="https://en.wikipedia.org/wiki/Haversine_formula" target="_blank">Haversine formula</a> and
<span class="italic">way</span> easier than along an ellipsoid with the <a
href="https://en.wikipedia.org/wiki/Vincenty%27s_formulae" target="_blank">Vincenty's
formulae</a>, to say nothing of areas or volumes.</li>
<li><span class="bold">Planar measurements can be more accurate.</span> Tectonic drift is not
negligible; Australia is drifting around 7 cm per year. Referencing locations in terms of meters
from a fixed monument on the same tectonic plate can avoid errors that accumulate over time when
referencing against a global datum. Temporal datums try to solve this, but they have limited
software support.</li>
<li><span class="bold">Longitude was hard to figure out before GNSS.</span> Reliable means of
determining longitude are <a href="https://en.wikipedia.org/wiki/History_of_longitude"
target="_blank">only a couple hundred years old</a>, and GPS only a couple decades old. There
is a lot of inertia in surveying and geodesy using Cartesian distances from fixed monuments.</li>
</ul>
</div>
<div id="ellipsoidal-vs-orthometric">
<h2><a href="#ellipsoidal-vs-orthometric">I hate coordinate systems! My X- and Y-values are OK, but my
Z-values (heights, elevations) are off!</a></h2>
<p>
<span class="bold">
Your dataset is probably measuring height above the ellipsoid instead of above sea level (geoid), or
vice-versa.
</span>
Sea level follows the geoid, a surface which is lumpy because of minute regional variations in gravity.
GNSS like GPS do not measure the height above the geoid but rather the idealized mathematical
representation called the ellipsoid. Some GPS devices automatically convert ellipsoidal height to height
above sea level (aka orthometric height aka geoidal height), but many do not.
</p>
<img src="images/ellipsoid-vs-geoid.png" width="100%">
<p>
<span class="bold">Solution:</span> Use <a href="https://proj.org/apps/cs2cs.html" target="_blank"><span
class="mono">cs2cs</span> in PROJ</a>, or alternatively an older tool like <a
href="https://vdatum.noaa.gov/" target="_blank">VDatum</a>, to convert between ellipsoidal and
orthometric (above sea level) heights. For a reasonably small dataset, a constant offset can be applied
to all Z-coordinates.
</p>
</div>
<div id="glossary">
<h2><a href="#glossary">I hate coordinate systems! What do all these terms mean?</a></h2>
<p class="solutions"><span class="bold">Here's a glossary:</span></p>
<ul class="solutions">
<li><span class="part1"><span class="bold">Attributes</span>:
the meanings or labels of a data point</li></span>
<li><span class="part3"><span class="bold">Coordinate (reference) system (CRS)</span>:
metadata describing the space in which coordinates exist, e.g. origin, axes, units, etc.</span>
</li>
<li><span class="part2"><span class="bold">Coordinates</span>:
numbers describing a data point's position within a CRS.</span>
</li>
<li><span class="bold">Datum</span>:
a precise reference frame calculated from a collection of known reference points; one part of a GCS.
</li>
<li><span class="bold">Ellipsoid</span>:
a mathematical approximation of the size and shape of the earth; one part of a GCS.
</li>
<li><span class="bold">Extent</span>:
the minimum and maximum values of the <span class="part2">coordinates</span>.
</li>
<li><span class="bold">Geographic <span class="part3">coordinate system</span> (GCS)</span>:
a <span class="part3">coordinate system</span> with angular longitude,latitude units in degrees;
composed of a datum and an ellipsoid.
</li>
<li><span class="bold">Geoid</span>:
an imaginary surface similar to sea level if landmasses were "cut away"; unlike the smooth
ellipsoid, the geoid is lumpy due to regional variations in gravity.
</li>
<li><span class="bold">GNSS</span>:
global navigation satellite system for precisely global positioning; the most common are GPS <img
src="images/flag-usa.png" class="flag">, GLONASS <img src="images/flag-ru.png" class="flag">,
BeiDou <img src="images/flag-cn.png" class="flag">, and Galileo <img src="images/flag-eu.png"
class="flag">.
</li>
<li><span class="bold">Project</span>:
the act of converting <span class="part2">coordinates</span> from a ellipsoidal longitude,latitude
<span class="part3">GCS</span> to a planar x,y <span class="part3">PCS</span> using a projection.
</li>
<li><span class="bold">Projected <span class="part3">coordinate system</span> (PCS)</span>:
a planar <span class="part3">coordinate system</span> with Euclidean x,y units (not angles);
composed of a GCS and a projection.
</li>
<li><span class="bold">Projection</span>:
an algorithm for converting angular longitude,latitude <span class="part2">coordinates</span> in a
<span class="part3">GCS</span> to a plane (a <span class="part3">PCS</span>) on/near the Earth's
surface, e.g. Mercator, Equidistant Conic, Stereographic, Dymaxion. Different zones (e.g. UTM) are
the same fundamental projection with different parameters.
</li>
<li><span class="bold">Redefine projection</span>:
the act of changing the <span class="part3">coordinate system</span> <span
class="italic">without</span> changing the <span class="part2">coordinates</span>.
</li>
<li><span class="bold">Reproject</span>:
the act of changing the <span class="part3">coordinate system</span> <span class="italic">and</span>
changing the <span class="part2">coordinates</span>. Typically done by unprojecting from the PCS to
the old GCS, transforming to new GCS (if different), and projecting to the new PCS.
</li>
<li><span class="bold">Transform</span>:
the act of changing between two <span class="part3">GCSs</span>. There are often multiple
transformation algorithms for a given pair of <span class="part3">GCSs</span>; the best choice
depends on the location of your data within the GCS.
</li>
<li><span class="bold">Unproject</span>:
the act of converting <span class="part2">coordinates</span> from a planar x,y <span
class="part3">PCS</span> to an ellipsoidal longitude,latitude <span class="part3">GCS</span>;
the inverse of project.
</li>
</ul>
</div>
<!--
<div id="desc">
<h2><a href="#desc">I hate coordinate systems! [PROBLEM]</a></h2>
<p>
<span class="bold">
[ROOT CAUSE]
</span>
[EXPLANATION]
</p>
<p>
<span class="bold">Solution:</span> [SINGLE SOLUTION].
</p>
<p class="solutions"><span class="bold">Solutions:</span></p>
<ul class="solutions">
<li>MULTIPLE</li>
<li>SOLUTIONS</li>
</ul>
</div>
-->
<div id="footer">
<footer>
<p class="center">
© 2020, made with ❤️ by <a href="https://github.com/dmahr1" target="_blank">Dan Mahr</a> at <a
href="https://www.dronedeploy.com" target="_blank">DroneDeploy</a>, inspired by
<a href="https://ohshitgit.com" target="_blank">ohshitgit</a>.
</p>
<p class="center">
See a problem? <a href="https://github.com/dmahr1/ihatecoordinatesystems/issues" target="_blank">Let
me know</a>.
</p>
</footer>
</div>
</div>
</body>
</html>