-
Notifications
You must be signed in to change notification settings - Fork 2
PROJ
PROJ implements the standard ISO19111 per OSGEO
Full tech paper for PROJ.8.0.1 as of May 8th, 2021
Spatialite documentation of key updates from PROJ.4 to PROJ.6, i.e. change from proj-strings to WKT (ISO19162).
Within the WKT string, each object is comprised of a key word followed by a set of attributes. Delimiters which enclose each object are normally [...]
. The PROJ
library uses the same.
Key words are case insensitive but will be in upper case when human readability is important.
The PROJJSON
format introduced in PROJ.6
follows the WKT format as close as possible.
optional attribute* which includes both scope
and extent
. Extent
may consist of one or more of area textual description, area bounding box, vertical extent and/or temporal extent.
WKT Examples:
- EPSG:9674
USAGE[
SCOPE["Forestry."],
AREA["United States (USA) - Oregon and Washington."],
BBOX[41.98,-124.79,49.05,-116.47]],
- EPSG:4326
USAGE[
SCOPE["Horizontal component of 3D system."],
AREA["World."],
BBOX[-90,-180,90,180]],
PROJJSON Examples:
- EPSG:9674
"scope": "Forestry.",
"area": "United States (USA) - Oregon and Washington.",
"bbox": {
"south_latitude": 41.98,
"west_longitude": -124.79,
"north_latitude": 49.05,
"east_longitude": -116.47
- EPSG:4326
"scope": "Horizontal component of 3D system.",
"area": "World.",
"bbox": {
"south_latitude": -90,
"west_longitude": -180,
"north_latitude": 90,
"east_longitude": 180
Scope describes purpose and uses for which a CRS, datum, etc is applied. Within the WKT scope will be seen by SCOPE["Map usage"]
.
Extent describes spatial applicability of a crs, datum, etc.
Horizontal extent can be described by description and/or geographic bounding box, but not by polygon due to string length considerations.
AREA is an optional attribute which describes a geographic are over which a crs or coordinate operation is applicable. I.e for EPSG:2000
Describes "north up" area. It is an approximate description of location. Precision of two decimal places.
proj.db
has 5 tables corresponding to various coordinate reference systems.
sqlite3 /usr/share/proj/proj.db ".tables" | grep crs
compound_crs
crs_view
geodetic_crs
projected_crs
vertical_crs
In order of importance:
- Projected coordinate systems (
projected_crs
) - Geodetic coordinate systems (
geodetic_crs
) - Vertical coordinate systems (
vertical_crs
) - Compound coordinate systems (
compound_crs
)
"Derived from a CRS with a geodetic reference frame by applying the coordinate conversion known as a map projection." - ISO191111
This table will contain all projections designed to represent a localized region.
Count of all EPSG codes in projected_crs
sqlite3 /usr/share/proj/proj.db "SELECT code FROM projected_crs WHERE auth_name = 'EPSG';" | wc
5120 5120 27068
Contains global coordinate systems
sqlite3 /usr/share/proj/proj.db "SELECT code FROM geodetic_crs WHERE auth_name = 'EPSG';" | wc
1063 1063 5315
e.g. EPSG:4326
sqlite3 /usr/share/proj/proj.db "SELECT code FROM geodetic_crs WHERE auth_name = 'EPSG';" | grep 4326
4326
The sqlite database provided follows the same format as described in ISO 19162 - Geographic information — Well known text representation of coordinate reference systems with each table representative of a main attribute that would be found in a WKT string.
Both the scope (purpose and uses) and usage (area and bbox) attributes have their own tables which can be queried by both authorities and codes.
sqlite> .headers on
sqlite> select * from extent limit 5;
auth_name|code|name|description|south_lat|north_lat|west_lon|east_lon|deprecated
EPSG|1024|Afghanistan|Afghanistan.|29.4|38.48|60.5|74.92|0
EPSG|1025|Albania|Albania - onshore and offshore.|39.63|42.67|18.46|21.06|0
EPSG|1026|Algeria|Algeria - onshore and offshore.|18.97|38.8|-8.67|11.99|0
EPSG|1027|American Samoa|American Samoa - onshore and offshore.|-17.56|-10.02|-173.75|-165.2|0
EPSG|1028|Andorra|Andorra.|42.43|42.66|1.42|1.79|0
sqlite> select * from scope limit 5;
auth_name|code|scope|deprecated
EPSG|1024|Not known.|0
EPSG|1025|?|1
EPSG|1026|Spatial referencing.|0
EPSG|1027|Geodesy.|0
EPSG|1028|Cadastre.|0
The usage table creates a relation which is similar to the structure of the USAGE WKT attribute within which the extent and scope attributes are.
The usage table has the following columns
auth_name|code|object_table_name|object_auth_name|object_code|extent_auth_name|extent_code|scope_auth_name|scope_code
To query extent and scope their respective codes must be obtained from the usage
table.
The EPSG code which is used to identify the CRS will be queried against the object_code
, NOT the code
column.
I.e. if we incorrectly query the EPSG code 9674 against the code
column, we get
sqlite3 /usr/share/proj/proj.db "select * from usage where auth_name = 'EPSG' and code = 9674"
EPSG|9674|conversion|EPSG|6236|EPSG|4156|EPSG|1055
where the scope_code
will be 1055 and the extent_code
will be 4156. Using these we can query both tables
sqlite3 /usr/share/proj/proj.db "select * from scope where auth_name = 'EPSG' and code = 1055"
EPSG|1055|Cadastre, engineering survey, topographic mapping (large scale).|0
sqlite3 /usr/share/proj/proj.db "select * from extent where auth_name = 'EPSG' and code = 4156"
EPSG|4156|Colombia - San Andres city|Colombia - San Andres city.|12.43|12.65|-81.82|-81.6|0
These results are wrong!!
Instead we must query the EPSG code 9674 against the object_code
column which returns
sqlite3 /usr/share/proj/proj.db "select * from usage where auth_name = 'EPSG' and object_code = 9674"
EPSG|14787|projected_crs|EPSG|9674|EPSG|2381|EPSG|1165
where 1165 is the scope_code
and 2381 is the extent_code
. When queried respectively we get
sqlite3 /usr/share/proj/proj.db "select * from scope where auth_name = 'EPSG' and code = 1165"
EPSG|1165|Forestry.|0
sqlite3 /usr/share/proj/proj.db "select * from extent where auth_name = 'EPSG' and code = 2381"
EPSG|2381|USA - Oregon and Washington|United States (USA) - Oregon and Washington.|41.98|49.05|-124.79|-116.47|0
These are correct and we can verify these results directly with both the PROJ WKT and PROJJSON outputs for the same EPSG code
USAGE[
SCOPE["Forestry."],
AREA["United States (USA) - Oregon and Washington."],
BBOX[41.98,-124.79,49.05,-116.47]],
ID["EPSG",9674]]
"scope": "Forestry.",
"area": "United States (USA) - Oregon and Washington.",
"bbox": {
"south_latitude": 41.98,
"west_longitude": -124.79,
"north_latitude": 49.05,
"east_longitude": -116.47
},
"id": {
"authority": "EPSG",
"code": 9674
Is bounding box always "defined in rectangular bboxes in lat/long, not in a projected CS"?
PROJ uses ISO 19115-1 Geographic information — Metadata to dictate metadata standardizations. ISO 19115-1 also dictates essentially every other standard pertaining to Geospatial Data Management. I am not able to get ISO 19115-1 in full without buying it, however using other standards and resources I am able to gather that it dictates that Geographic Bounding boxes are to be in Decimal Degrees lat/lon.
The geographic bounding box is found in class EX_GeographicBoundingBox in all documents and GeographicBoundingBox in all source code. Details about the specification can be seen in
- Spatial Data Standards for Facilities, Infrastructure, and Environment (SDSFIE) Table 90
- ICSM ISO19115-1 Metadata Best Practice Guide
- Earth Science Information Partners (ESIP) Wiki
- ISO 19162 Section 7.3.2.3.3
- EPA Metadata Technical Specification
In addition, per the PROJ source code, the PROJ GeographicBoundingBox Class implements the GeographicBoundingBox from GeoAPI which uses coordinate values expressed in decimal degrees.