diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index 3767d726b..6b8956b3a 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -26,6 +26,10 @@ from Esri's [projection-engine-db-doc](https://github.com/Esri/projection-engine PROJ definitions by PROJ 9.7.1. The WKT2 test corpus (`crates/data/src/raster/wkt2_corpus.tsv`) is 60 of those EPSG and Esri coordinate systems written as WKT2 by PROJ 9.7.1, through pyproj 3.7.2. +The ESRI datum test corpus (`crates/data/src/raster/esri_datum_corpus.tsv`) contains 13 EPSG +coordinate systems written as ESRI WKT1 through pyproj 3.7.2; reference coordinates use PROJ +with the bundled `crs-definitions` Helmert definitions. The OSGB36, Amersfoort and GGRS87 WKT2 +reference coordinates use those same transformations. The GeoLibre tool suite ([geolibre-rust](https://github.com/opengeos/geolibre-rust), MIT, built on [whitebox-wasm](https://github.com/opengeos/whitebox-wasm), MIT) is not part of RustGIS: the diff --git a/crates/data/src/io.rs b/crates/data/src/io.rs index b541a193b..f49f9fd8d 100644 --- a/crates/data/src/io.rs +++ b/crates/data/src/io.rs @@ -2397,6 +2397,27 @@ mod tests { assert!(rep.messages.iter().any(|m| m.contains("not longitude/latitude")), "{:?}", rep.messages); std::fs::remove_dir_all(&dir).ok(); } + /// An ESRI .prj without an authority retains the national datum shift (issue #807). + #[cfg(not(target_arch = "wasm32"))] + #[test] + fn shapefile_esri_national_datum() { + use shapefile::dbase::{Record, TableWriterBuilder}; + let dir = tempfile::tempdir().unwrap(); + let shp = dir.path().join("milan.shp"); + { + let mut writer = shapefile::Writer::from_path(&shp, TableWriterBuilder::new()).unwrap(); + writer + .write_shape_and_record(&shapefile::Point::new(1_514_881.490_594_152, 5_034_556.812_441_661), &Record::default()) + .unwrap(); + } + let row = include_str!("raster/esri_datum_corpus.tsv").lines().find(|l| l.starts_with("3003\t")).unwrap(); + std::fs::write(shp.with_extension("prj"), row.split('\t').nth(5).unwrap()).unwrap(); + let (ds, report) = read_path(&shp).unwrap(); + let c = ds.features[0].geometry.as_ref().and_then(Geometry::label_point).unwrap(); + assert!((c.x - 9.19).abs() < 1e-7 && (c.y - 45.4642).abs() < 1e-7, "{c:?}"); + assert!(report.messages.is_empty(), "{:?}", report.messages); + } + /// Zipped Shapefiles are read from memory (the web app's way to open them), with their `.prj`, /// from folders inside the archive, beside other vector files; truncations are errors. #[test] diff --git a/crates/data/src/raster/esri_datum_corpus.tsv b/crates/data/src/raster/esri_datum_corpus.tsv new file mode 100644 index 000000000..2c8bc85d5 --- /dev/null +++ b/crates/data/src/raster/esri_datum_corpus.tsv @@ -0,0 +1,14 @@ +# EPSG x y longitude latitude ESRI WKT1; reference: PROJ with the bundled EPSG Helmert definition +3003 1514881.490594152 5034556.812441661 9.19000000788174 45.464200001031124 PROJCS["Monte_Mario_Italy_1",GEOGCS["GCS_Monte_Mario",DATUM["D_Monte_Mario",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",1500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] +3004 2520007.813943255 4649786.031858027 15.000000005146543 42.000000001033825 PROJCS["Monte_Mario_Italy_2",GEOGCS["GCS_Monte_Mario",DATUM["D_Monte_Mario",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",2520000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",15.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] +23032 500083.1509016752 5538832.534343051 9.000000007202905 50.000000005050765 PROJCS["ED_1950_UTM_Zone_32N",GEOGCS["GCS_European_1950",DATUM["D_European_1950",SPHEROID["International_1924",6378388.0,297.0]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] +27700 434423.01017492707 233624.37495991692 -1.4999999879048393 51.99999999577776 PROJCS["British_National_Grid",GEOGCS["GCS_OSGB_1936",DATUM["D_OSGB_1936",SPHEROID["Airy_1830",6377563.396,299.3249646]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",400000.0],PARAMETER["False_Northing",-100000.0],PARAMETER["Central_Meridian",-2.0],PARAMETER["Scale_Factor",0.9996012717],PARAMETER["Latitude_Of_Origin",49.0],UNIT["Meter",1.0]] +31467 3571769.722625813 5540887.027504178 10.000000003372906 50.000000004665104 PROJCS["DHDN_3_Degree_Gauss_Zone_3",GEOGCS["GCS_Deutsches_Hauptdreiecksnetz",DATUM["D_Deutsches_Hauptdreiecksnetz",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",3500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] +28992 149038.2794319498 467991.1354606445 5.300000001687074 52.200000004047254 PROJCS["RD_New",GEOGCS["GCS_Amersfoort",DATUM["D_Amersfoort",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Double_Stereographic"],PARAMETER["False_Easting",155000.0],PARAMETER["False_Northing",463000.0],PARAMETER["Central_Meridian",5.38763888888889],PARAMETER["Scale_Factor",0.9999079],PARAMETER["Latitude_Of_Origin",52.1561605555556],UNIT["Meter",1.0]] +2100 499850.44058235415 4205527.108977563 23.999999991487297 37.99999998697819 PROJCS["Greek_Grid",GEOGCS["GCS_GGRS_1987",DATUM["D_GGRS_1987",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",24.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] +25832 500000.0 5538630.702744345 9.0 50.00000000000001 PROJCS["ETRS_1989_UTM_Zone_32N",GEOGCS["GCS_ETRS_1989",DATUM["D_ETRS_1989",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] +6707 500000.0 4982950.400106853 9.0 45.0 PROJCS["RDN2008_TM32",GEOGCS["GCS_RDN2008",DATUM["D_Rete_Dinamica_Nazionale_2008",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] +3064 500000.0 4982950.400226552 9.0 45.0 PROJCS["IGM_1995_UTM_Zone_32N",GEOGCS["GCS_IGM_1995",DATUM["D_IGM_1995",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",9.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]] +21781 642695.4201549252 205590.52228722392 8.000000007959498 47.00000001018142 PROJCS["CH1903_LV03",GEOGCS["GCS_CH1903",DATUM["D_CH1903",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],PARAMETER["False_Easting",600000.0],PARAMETER["False_Northing",200000.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Azimuth",90.0],PARAMETER["Longitude_Of_Center",7.43958333333333],PARAMETER["Latitude_Of_Center",46.9524055555556],UNIT["Meter",1.0]] +2056 2642695.4201549254 1205590.522287224 8.0000000079595 47.00000001018142 PROJCS["CH1903+_LV95",GEOGCS["GCS_CH1903+",DATUM["D_CH1903+",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Hotine_Oblique_Mercator_Azimuth_Center"],PARAMETER["False_Easting",2600000.0],PARAMETER["False_Northing",1200000.0],PARAMETER["Scale_Factor",1.0],PARAMETER["Azimuth",90.0],PARAMETER["Longitude_Of_Center",7.43958333333333],PARAMETER["Latitude_Of_Center",46.9524055555556],UNIT["Meter",1.0]] +5514 -703017.4359071456 -1058153.5759874587 15.000000007792027 50.00000000489641 PROJCS["S-JTSK_Krovak_East_North",GEOGCS["GCS_S_JTSK",DATUM["D_S_JTSK",SPHEROID["Bessel_1841",6377397.155,299.1528128]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Krovak"],PARAMETER["False_Easting",0.0],PARAMETER["False_Northing",0.0],PARAMETER["Pseudo_Standard_Parallel_1",78.5],PARAMETER["Scale_Factor",0.9999],PARAMETER["Azimuth",30.28813975277778],PARAMETER["Longitude_Of_Center",24.83333333333333],PARAMETER["Latitude_Of_Center",49.5],PARAMETER["X_Scale",-1.0],PARAMETER["Y_Scale",1.0],PARAMETER["XY_Plane_Rotation",90.0],UNIT["Meter",1.0]] diff --git a/crates/data/src/raster/wkt.rs b/crates/data/src/raster/wkt.rs index e639cf28c..923ddd755 100644 --- a/crates/data/src/raster/wkt.rs +++ b/crates/data/src/raster/wkt.rs @@ -7,7 +7,8 @@ //! //! An EPSG authority is used when the text names one. The `.prj` files ArcGIS and GDAL write have //! none (`PROJCS["WGS_1984_UTM_Zone_31N",…]`), so Web Mercator and UTM are also known by name, and -//! any other projection is turned into a PROJ definition from its parameters. +//! any other projection is turned into a PROJ definition from its parameters. Known national +//! datums recover the same Helmert transformation as their bundled EPSG definition. use super::crs::{Crs, CustomCrs, epsg_proj4}; @@ -234,7 +235,7 @@ pub fn crs_from_wkt(text: &str) -> Result { } /// The coordinate system a WKT text describes, with a note when its datum has no conversion to -/// WGS 84 given (NAD 27, OSGB 36…), so positions may be off by up to a few hundred metres. +/// WGS 84 available (for example, NAD 27), so positions may be off by up to a few hundred metres. pub fn read_wkt(text: &str) -> Result<(Crs, Option), String> { let root = wkt1(parse(text)?, 0)?; if let Some(a) = root.child("AUTHORITY") @@ -404,6 +405,14 @@ fn lookup<'a, T>(n: &Node, table: &'a [T], key: impl Fn(&T) -> (u32, &str)) -> O code.and_then(|c| table.iter().find(|r| key(r).0 == c)).or_else(|| table.iter().find(|r| key(r).1 == name)) } +/// Axes whose signs differ from the East/North convention used by the WKT reader. +/// Polar axes follow their own meridians and are handled by the projection itself. +fn reversed_axes(p: &Node) -> bool { + p.nodes() + .filter(|a| a.name.eq_ignore_ascii_case("AXIS") && a.child("MERIDIAN").is_none()) + .any(|a| a.items.iter().any(|i| matches!(i, Item::Word(w) if w.eq_ignore_ascii_case("west") || w.eq_ignore_ascii_case("south")))) +} + /// A WKT2 projected system as a `PROJCS`, its parameters in degrees and the system's linear unit. fn projected2(p: &Node) -> Result { // Axes pointing west or south (South Africa's Lo grids) would be read with the wrong sign, as @@ -411,10 +420,7 @@ fn projected2(p: &Node) -> Result { // their axes to a meridian, which is how WKT1 reads them.) // Axis order isn't read: as with WKT1, coordinates are easting then northing (GIS order), // whatever order the system declares. - let flipped = p - .nodes() - .filter(|a| a.name.eq_ignore_ascii_case("AXIS") && a.child("MERIDIAN").is_none()) - .any(|a| a.items.iter().any(|i| matches!(i, Item::Word(w) if w.eq_ignore_ascii_case("west") || w.eq_ignore_ascii_case("south")))); + let flipped = reversed_axes(p); if flipped && epsg_id(p).and_then(Crs::from_epsg).is_none() { return Err("axes pointing west or south aren't supported".into()); } @@ -628,6 +634,9 @@ pub fn utm_of_code(code: u32) -> Option<(&'static str, u32, bool)> { /// A projection's PROJ definition built from its WKT parameters. fn custom(p: &Node, method: &str) -> Result { + if method == "KROVAK" && reversed_axes(p) { + return Err("axes pointing west or south aren't supported".into()); + } let params: Vec<(String, f64)> = p .items .iter() @@ -650,6 +659,27 @@ fn custom(p: &Node, method: &str) -> Result { let at = format!("+lon_0={lon0} +x_0={x0} +y_0={y0}"); let proj = match method { "TRANSVERSE_MERCATOR" | "GAUSS_KRUGER" => format!("+proj=tmerc +lat_0={lat0} +k_0={k0} {at}"), + // proj4rs supports the Swiss special case, not arbitrary Hotine projections. + "HOTINE_OBLIQUE_MERCATOR_AZIMUTH_CENTER" + if national_datum(p.child("GEOGCS").and_then(|g| g.child("DATUM"))) + .is_some_and(|d| Some(d) == epsg_proj4(4149) || Some(d) == epsg_proj4(4150)) + && get(&["AZIMUTH"]).is_some_and(|v| (v - 90.0).abs() < 1e-10) + && get(&["RECTIFIED_GRID_ANGLE"]).is_none_or(|v| (v - 90.0).abs() < 1e-10) => + { + format!("+proj=somerc +lat_0={lat0} +k_0={k0} {at}") + } + // The implementation fixes the cone axis and pseudo standard parallel. Refuse other + // variants and axis conventions instead of treating their coordinates as East/North. + "KROVAK" + if national_datum(p.child("GEOGCS").and_then(|g| g.child("DATUM"))) == epsg_proj4(4156) + && get(&["AZIMUTH"]).is_some_and(|v| (v - 30.28813975277778).abs() < 1e-6) + && get(&["PSEUDO_STANDARD_PARALLEL_1"]).is_some_and(|v| (v - 78.5).abs() < 1e-10) + && get(&["X_SCALE"]).is_none_or(|v| v == -1.0) + && get(&["Y_SCALE"]).is_none_or(|v| v == 1.0) + && get(&["XY_PLANE_ROTATION"]).is_none_or(|v| v == 90.0) => + { + format!("+proj=krovak +lat_0={lat0} +k_0={k0} {at}") + } "MERCATOR" | "MERCATOR_1SP" | "MERCATOR_2SP" => match lat1 { Some(ts) => format!("+proj=merc +lat_ts={ts} {at}"), None => format!("+proj=merc +k_0={k0} {at}"), @@ -708,6 +738,13 @@ fn wgs84_like(datum: Option<&Node>) -> Option<&'static str> { // (WKT2 names a datum ensemble: `World Geodetic System 1984 ensemble`.) match norm(datum.map_or("", Node::title)).trim_start_matches("D_").trim_end_matches("_ENSEMBLE") { "WGS_1984" | "WGS84" | "WORLD_GEODETIC_SYSTEM_1984" => Some("+datum=WGS84"), + // New Italian aliases require the published ellipsoid. GRS80 and the WGS84 + // ellipsoid in older IGM95 definitions differ by less than a millimetre. + // MILITAIRE is the legacy spelling in crs-definitions 0.6's EPSG:3064/4670 WKT. + "RETE_DINAMICA_NAZIONALE_2008" | "RDN2008" | "IGM_1995" | "IGM95" + | "ISTITUTO_GEOGRAFICO_MILITARE_1995" | "ISTITUTO_GEOGRAFICO_MILITAIRE_1995" => datum + .filter(|d| ellipsoid_matches(d, "+proj=longlat +ellps=GRS80")) + .map(|_| "+ellps=GRS80 +towgs84=0,0,0"), "NORTH_AMERICAN_1983" | "NORTH_AMERICAN_DATUM_1983" | "NAD_1983" @@ -732,6 +769,44 @@ fn wgs84_like(datum: Option<&Node>) -> Option<&'static str> { } } +/// A national datum's bundled EPSG definition. Match the datum, never just the projected +/// system's title, and require the published ellipsoid so a locally modified grid is not +/// silently assigned a different datum. These are the same Helmert approximations used when +/// the file supplies an EPSG code; regional grid transformations are not inferred. +fn national_datum(datum: Option<&Node>) -> Option<&'static str> { + let datum = datum?; + let name = norm(datum.title()); + let code = match name.strip_prefix("D_").unwrap_or(&name) { + "MONTE_MARIO" => 4265, + "EUROPEAN_1950" | "EUROPEAN_DATUM_1950" | "ED50" => 4230, + "OSGB_1936" | "OSGB36" | "ORDNANCE_SURVEY_OF_GREAT_BRITAIN_1936" => 4277, + "DEUTSCHES_HAUPTDREIECKSNETZ" | "DHDN" => 4314, + "AMERSFOORT" => 4289, + "GGRS_1987" | "GGRS87" | "GREEK_GEODETIC_REFERENCE_SYSTEM_1987" => 4121, + "CH1903" => { + if datum.title().contains('+') { + 4150 + } else { + 4149 + } + } + "S_JTSK" | "SYSTEM_JEDNOTNE_TRIGONOMETRICKE_SITE_KATASTRALNI" | "SYSTEM_OF_THE_UNIFIED_TRIGONOMETRICAL_CADASTRAL_NETWORK" => 4156, + _ => return None, + }; + let def = epsg_proj4(code)?; + ellipsoid_matches(datum, def).then_some(def) +} + +/// Whether the file's ellipsoid axes agree with a known definition within a centimetre. +fn ellipsoid_matches(datum: &Node, def: &str) -> bool { + let Ok(proj) = proj4rs::Proj::from_proj_string(def) else { return false }; + let Some(sph) = datum.child_of(&["SPHEROID", "ELLIPSOID"]) else { return false }; + let (Some(actual_a), Some(rf)) = (sph.num(0), sph.num(1)) else { return false }; + let (a, b) = proj.ellipse_parameters(); + let actual_b = if rf > 0.0 { actual_a * (1.0 - 1.0 / rf) } else { actual_a }; + (actual_a - a).abs() < 0.01 && (actual_b - b).abs() < 0.01 +} + /// Whether the file gives the datum a `TOWGS84` shift other than none, which then wins over the /// null shift a WGS 84-like datum would get by its name: the file says what it was made with. fn shifted(datum: Option<&Node>) -> bool { @@ -746,7 +821,7 @@ fn towgs84(datum: Option<&Node>) -> Option> { /// A note when the datum (of a `GEOGCS`) is neither WGS 84-like nor shifted to it by `TOWGS84`. fn datum_note(geog: Option<&Node>) -> Option { let datum = geog?.child("DATUM")?; - if wgs84_like(Some(datum)).is_some() || towgs84(Some(datum)).is_some() { + if wgs84_like(Some(datum)).is_some() || towgs84(Some(datum)).is_some() || national_datum(Some(datum)).is_some() { return None; } Some(format!( @@ -759,7 +834,17 @@ fn datum_note(geog: Option<&Node>) -> Option { /// prime meridian. fn earth(geog: Option<&Node>) -> String { let datum = geog.and_then(|g| g.child("DATUM")); - let mut out = match wgs84_like(datum).filter(|_| !shifted(datum)) { + let known = wgs84_like(datum).map(str::to_string).or_else(|| { + national_datum(datum).map(|def| { + def.split_whitespace() + .filter(|p| p.starts_with("+ellps=") || p.starts_with("+datum=") || p.starts_with("+towgs84=")) + .collect::>() + .join(" ") + }) + }); + // A national datum yields to any explicit TOWGS84, including a zero shift. + // WGS 84-like datums can keep their equivalent named definition for a zero shift. + let mut out = match known.filter(|_| towgs84(datum).is_none() || (wgs84_like(datum).is_some() && !shifted(datum))) { Some(d) => d.to_string(), None => { let sph = datum.and_then(|d| d.child("SPHEROID").or_else(|| d.child("ELLIPSOID"))); @@ -1183,6 +1268,98 @@ mod tests { assert_eq!(read_wkt(&ogc), Ok((Crs::LonLat, None))); } + #[test] + fn esri_national_datums_match_epsg() { + for line in include_str!("esri_datum_corpus.tsv").lines().filter(|l| !l.starts_with('#')) { + let fields: Vec<_> = line.split('\t').collect(); + let code: u32 = fields[0].parse().unwrap(); + let number = |i: usize| fields[i].parse::().unwrap(); + let xy = Coord::new(number(1), number(2)); + let (crs, note) = read_wkt(fields[5]).unwrap_or_else(|e| panic!("EPSG:{code}: {e}")); + assert!(note.is_none(), "EPSG:{code}: {note:?}"); + let actual = crs.transformer().unwrap().to_lonlat(xy).unwrap(); + let expected = Crs::from_epsg(code).unwrap().transformer().unwrap().to_lonlat(xy).unwrap(); + let distance = |a: Coord, b: Coord| ((a.x - b.x) * b.y.to_radians().cos()).hypot(a.y - b.y) * 111_195.0; + assert!(distance(actual, expected) < 0.01, "EPSG:{code}: {actual:?} vs {expected:?}"); + assert!(distance(actual, Coord::new(number(3), number(4))) < 0.1, "EPSG:{code}: {actual:?}"); + } + } + + #[test] + fn national_datum_fallback_respects_file_definition() { + let line = include_str!("esri_datum_corpus.tsv").lines().find(|l| l.starts_with("3003\t")).unwrap(); + let wkt = line.split('\t').nth(5).unwrap(); + for shift in ["0,0,0", "1,2,3", "1,2,3,4,5,6,7"] { + let explicit = wkt.replace(r#"DATUM["D_Monte_Mario","#, &format!(r#"DATUM["D_Monte_Mario",TOWGS84[{shift}],"#)); + let (crs, note) = read_wkt(&explicit).unwrap(); + let def = crs.custom_def().unwrap(); + assert!(def.proj4.contains(&format!("+towgs84={shift} ")), "{}", def.proj4); + assert!(note.is_none()); + } + // Neither the CRS title nor the ellipsoid alone identifies a datum. An altered + // ellipsoid must not inherit a national datum's transformation either. + for changed in + [wkt.replace("D_Monte_Mario", "D_Local"), wkt.replace("D_Monte_Mario", "D_Roma_1940"), wkt.replace("6378388.0", "6378300.0")] + { + let (crs, note) = read_wkt(&changed).unwrap(); + assert!(note.is_some()); + assert!(!crs.custom_def().unwrap().proj4.contains("+towgs84=")); + } + // A locally named projection with different false easting retains its parameters. + let local = wkt.replace("Monte_Mario_Italy_1", "Local grid").replace("1500000.0", "1500100.0"); + let def = crs_from_wkt(&local).unwrap().custom_def().unwrap(); + assert!(def.proj4.contains("+x_0=1500100") && def.proj4.contains("+towgs84=")); + // Geographic WKT uses the same fallback; explicit shifts still take precedence. + let geog = parse(wkt).unwrap().child("GEOGCS").unwrap().clone(); + assert!(earth(Some(&geog)).contains("+towgs84=-104.1,-49.1,-9.9")); + assert!(datum_note(Some(&geog)).is_none()); + for (code, from, to) in [("21781", "90.0", "45.0"), ("5514", "78.5", "77.5"), ("5514", r#""X_Scale",-1.0"#, r#""X_Scale",1.0"#)] { + let row = include_str!("esri_datum_corpus.tsv").lines().find(|l| l.starts_with(&format!("{code}\t"))).unwrap(); + let changed = row.split('\t').nth(5).unwrap().replace(from, to); + assert!(crs_from_wkt(&changed).is_err(), "{changed}"); + } + } + + #[test] + fn italian_datums_require_their_ellipsoid() { + for datum in ["D_Rete_Dinamica_Nazionale_2008", "D_IGM_1995", "Istituto_Geografico_Militaire_1995"] { + let geographic = GEOG_4326.replace("D_WGS_1984", datum).replace("6378137.0", "6378000.0"); + let (crs, note) = read_wkt(&geographic).unwrap(); + assert!(note.is_some(), "{datum}"); + let def = crs.custom_def().unwrap(); + assert!(def.proj4.contains("+a=6378000") && !def.proj4.contains("+towgs84="), "{}", def.proj4); + } + for code in ["6707", "3064"] { + let row = include_str!("esri_datum_corpus.tsv").lines().find(|l| l.starts_with(&format!("{code}\t"))).unwrap(); + let projected = row.split('\t').nth(5).unwrap().replace("6378137.0", "6378000.0"); + let (crs, note) = read_wkt(&projected).unwrap(); + assert!(note.is_some(), "{code}"); + let def = crs.custom_def().unwrap(); + assert!(def.proj4.contains("+a=6378000") && !def.proj4.contains("+towgs84="), "{}", def.proj4); + } + } + + #[test] + fn swiss_projection_requires_a_swiss_datum() { + let row = include_str!("esri_datum_corpus.tsv").lines().find(|l| l.starts_with("21781\t")).unwrap(); + let wkt = row.split('\t').nth(5).unwrap(); + for datum in ["D_Local", "D_OSGB_1936"] { + assert!(crs_from_wkt(&wkt.replace("D_CH1903", datum)).is_err()); + } + for datum in ["Istituto_Geografico_Militare_1995", "Istituto_Geografico_Militaire_1995"] { + assert_eq!(read_wkt(&GEOG_4326.replace("D_WGS_1984", datum)), Ok((Crs::LonLat, None))); + } + } + + #[test] + fn krovak_south_west_axes_are_refused() { + let row = include_str!("esri_datum_corpus.tsv").lines().find(|l| l.starts_with("5514\t")).unwrap(); + let wkt = row.split('\t').nth(5).unwrap(); + let changed = wkt.replace(r#",PARAMETER["X_Scale",-1.0],PARAMETER["Y_Scale",1.0],PARAMETER["XY_Plane_Rotation",90.0]"#, ""); + let changed = format!(r#"{},AXIS["Southing",SOUTH],AXIS["Westing",WEST]]"#, changed.strip_suffix(']').unwrap()); + assert_eq!(crs_from_wkt(&changed), Err("axes pointing west or south aren't supported".into())); + } + #[test] fn polar_stereographic() { // GDAL's WKT for EPSG:3031 (true scale at 71°S) and EPSG:32761 (UPS South, scale 0.994 at @@ -1252,8 +1429,8 @@ mod tests { assert_eq!(read_wkt(row("EPSG:32631")), Ok((Crs::Epsg(32631), None))); assert_eq!(read_wkt(row("EPSG:3857")), Ok((Crs::WebMercator, None))); assert_eq!(read_wkt(row("EPSG:4283")), Ok((Crs::LonLat, None))); - // OSGB 36 without a shift gets the note, as in WKT1. - assert!(read_wkt(row("EPSG:27700")).unwrap().1.is_some_and(|n| n.contains("Ordnance Survey of Great Britain 1936"))); + // OSGB 36 gets the same bundled Helmert shift as its EPSG definition. + assert!(read_wkt(row("EPSG:27700")).unwrap().1.is_none()); // A geocentric system isn't a map's. let geocentric = r#"GEODCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563]],CS[Cartesian,3],AXIS["(X)",geocentricX],AXIS["(Y)",geocentricY],AXIS["(Z)",geocentricZ],LENGTHUNIT["metre",1]]"#; assert_eq!(crs_from_wkt(geocentric), Err("Cartesian coordinate systems aren't supported".into())); diff --git a/crates/data/src/raster/wkt2_corpus.tsv b/crates/data/src/raster/wkt2_corpus.tsv index fd88a3254..b07796f25 100644 --- a/crates/data/src/raster/wkt2_corpus.tsv +++ b/crates/data/src/raster/wkt2_corpus.tsv @@ -1,11 +1,11 @@ # WKT2 2019 of 60 coordinate systems, written by pyproj 3.7.2 (PROJ 9.7.1) without # their top-level ID and usage. Columns: code, x, y, and the longitude and latitude of x, y on the -# system's own datum (no datum shift). +# system's own datum, except OSGB36, Amersfoort and GGRS87, which use WGS 84 and the bundled Helmert shift. EPSG:4326 0.0 0.0 0.0 0.0 GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)",ID["EPSG",1166]],MEMBER["World Geodetic System 1984 (G730)",ID["EPSG",1152]],MEMBER["World Geodetic System 1984 (G873)",ID["EPSG",1153]],MEMBER["World Geodetic System 1984 (G1150)",ID["EPSG",1154]],MEMBER["World Geodetic System 1984 (G1674)",ID["EPSG",1155]],MEMBER["World Geodetic System 1984 (G1762)",ID["EPSG",1156]],MEMBER["World Geodetic System 1984 (G2139)",ID["EPSG",1309]],MEMBER["World Geodetic System 1984 (G2296)",ID["EPSG",1383]],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1],ID["EPSG",7030]],ENSEMBLEACCURACY[2.0],ID["EPSG",6326]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8901]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]]] EPSG:4269 180.0 50.685 180.0 50.685 GEOGCRS["NAD83",DATUM["North American Datum 1983",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1,ID["EPSG",9001]]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8901]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]]] EPSG:4258 10.954999999999998 58.995000000000005 10.954999999999998 58.995000000000005 GEOGCRS["ETRS89",ENSEMBLE["European Terrestrial Reference System 1989 ensemble",MEMBER["European Terrestrial Reference Frame 1989",ID["EPSG",1178]],MEMBER["European Terrestrial Reference Frame 1990",ID["EPSG",1179]],MEMBER["European Terrestrial Reference Frame 1991",ID["EPSG",1180]],MEMBER["European Terrestrial Reference Frame 1992",ID["EPSG",1181]],MEMBER["European Terrestrial Reference Frame 1993",ID["EPSG",1182]],MEMBER["European Terrestrial Reference Frame 1994",ID["EPSG",1183]],MEMBER["European Terrestrial Reference Frame 1996",ID["EPSG",1184]],MEMBER["European Terrestrial Reference Frame 1997",ID["EPSG",1185]],MEMBER["European Terrestrial Reference Frame 2000",ID["EPSG",1186]],MEMBER["European Terrestrial Reference Frame 2005",ID["EPSG",1204]],MEMBER["European Terrestrial Reference Frame 2014",ID["EPSG",1206]],MEMBER["European Terrestrial Reference Frame 2020",ID["EPSG",1382]],ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1],ID["EPSG",7019]],ENSEMBLEACCURACY[0.1],ID["EPSG",6258]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8901]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]]] EPSG:4283 133.375 -34.51 133.375 -34.51 GEOGCRS["GDA94",DATUM["Geocentric Datum of Australia 1994",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1,ID["EPSG",9001]]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8901]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]]] -EPSG:4277 -3.5 55.379999999999995 -3.5 55.379999999999995 GEOGCRS["OSGB36",DATUM["Ordnance Survey of Great Britain 1936",ELLIPSOID["Airy 1830",6377563.396,299.3249646,LENGTHUNIT["metre",1,ID["EPSG",9001]]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8901]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]]] +EPSG:4277 -3.4986390218735695 55.37999381533582 -3.5 55.379999999999995 GEOGCRS["OSGB36",DATUM["Ordnance Survey of Great Britain 1936",ELLIPSOID["Airy 1830",6377563.396,299.3249646,LENGTHUNIT["metre",1,ID["EPSG",9001]]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8901]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]]] EPSG:4674 -73.735 -13.575 -73.735 -13.575 GEOGCRS["SIRGAS 2000",DATUM["Sistema de Referencia Geocentrico para las AmericaS 2000",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1,ID["EPSG",9001]]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8901]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]]] EPSG:4267 180.0 45.160000000000004 180.0 45.160000000000004 GEOGCRS["NAD27",DATUM["North American Datum 1927",ELLIPSOID["Clarke 1866",6378206.4,294.978698213898,LENGTHUNIT["metre",1,ID["EPSG",9001]]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8901]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]]] EPSG:4979 0.0 0.0 0.0 0.0 GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)",ID["EPSG",1166]],MEMBER["World Geodetic System 1984 (G730)",ID["EPSG",1152]],MEMBER["World Geodetic System 1984 (G873)",ID["EPSG",1153]],MEMBER["World Geodetic System 1984 (G1150)",ID["EPSG",1154]],MEMBER["World Geodetic System 1984 (G1674)",ID["EPSG",1155]],MEMBER["World Geodetic System 1984 (G1762)",ID["EPSG",1156]],MEMBER["World Geodetic System 1984 (G2139)",ID["EPSG",1309]],MEMBER["World Geodetic System 1984 (G2296)",ID["EPSG",1383]],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1],ID["EPSG",7030]],ENSEMBLEACCURACY[2.0],ID["EPSG",6326]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8901]],CS[ellipsoidal,3],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],AXIS["ellipsoidal height (h)",up,ORDER[3],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] @@ -14,7 +14,7 @@ EPSG:32631 500000.0000000007 4649776.224819178 3.0 42.0 PROJCRS["WGS 84 / UTM zo EPSG:32717 500000.0 5572242.781261626 -81.0 -40.0 PROJCRS["WGS 84 / UTM zone 17S",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["UTM zone 17S",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",-81,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",10000000,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:26917 500000.0 5972952.000352257 -81.0 53.905 PROJCRS["NAD83 / UTM zone 17N",BASEGEOGCRS["NAD83",DATUM["North American Datum 1983",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4269]],CONVERSION["UTM zone 17N",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",-81,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:25832 500276.6127925036 6681481.103924277 9.004999999999999 60.27 PROJCRS["ETRS89 / UTM zone 32N",BASEGEOGCRS["ETRS89",ENSEMBLE["European Terrestrial Reference System 1989 ensemble",MEMBER["European Terrestrial Reference Frame 1989"],MEMBER["European Terrestrial Reference Frame 1990"],MEMBER["European Terrestrial Reference Frame 1991"],MEMBER["European Terrestrial Reference Frame 1992"],MEMBER["European Terrestrial Reference Frame 1993"],MEMBER["European Terrestrial Reference Frame 1994"],MEMBER["European Terrestrial Reference Frame 1996"],MEMBER["European Terrestrial Reference Frame 1997"],MEMBER["European Terrestrial Reference Frame 2000"],MEMBER["European Terrestrial Reference Frame 2005"],MEMBER["European Terrestrial Reference Frame 2014"],MEMBER["European Terrestrial Reference Frame 2020"],ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[0.1]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4258]],CONVERSION["UTM zone 32N",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",9,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] -EPSG:27700 304969.207370822 610584.9936767236 -3.5 55.379999999999995 PROJCRS["OSGB36 / British National Grid",BASEGEOGCRS["OSGB36",DATUM["Ordnance Survey of Great Britain 1936",ELLIPSOID["Airy 1830",6377563.396,299.3249646,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4277]],CONVERSION["British National Grid",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",49,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",-2,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996012717,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",400000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",-100000,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] +EPSG:27700 305055.40881237545 610582.4484892632 -3.5 55.379999999999995 PROJCRS["OSGB36 / British National Grid",BASEGEOGCRS["OSGB36",DATUM["Ordnance Survey of Great Britain 1936",ELLIPSOID["Airy 1830",6377563.396,299.3249646,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4277]],CONVERSION["British National Grid",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",49,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",-2,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996012717,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",400000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",-100000,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:2263 1252460.5525610321 263192.27554016607 -73.03 40.885 PROJCRS["NAD83 / New York Long Island (ftUS)",BASEGEOGCRS["NAD83",DATUM["North American Datum 1983",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4269]],CONVERSION["SPCS83 New York Long Island zone (US survey foot)",METHOD["Lambert Conic Conformal (2SP)",ID["EPSG",9802]],PARAMETER["Latitude of false origin",40.1666666666667,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8821]],PARAMETER["Longitude of false origin",-74,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8822]],PARAMETER["Latitude of 1st standard parallel",41.0333333333333,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8823]],PARAMETER["Latitude of 2nd standard parallel",40.6666666666667,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8824]],PARAMETER["Easting at false origin",984250,LENGTHUNIT["US survey foot",0.304800609601219],ID["EPSG",8826]],PARAMETER["Northing at false origin",0,LENGTHUNIT["US survey foot",0.304800609601219],ID["EPSG",8827]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["US survey foot",0.304800609601219]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["US survey foot",0.304800609601219]]] EPSG:2229 6631142.589076225 1926178.4665179423 -117.77000000000001 34.285 PROJCRS["NAD83 / California zone 5 (ftUS)",BASEGEOGCRS["NAD83",DATUM["North American Datum 1983",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4269]],CONVERSION["SPCS83 California zone 5 (US survey foot)",METHOD["Lambert Conic Conformal (2SP)",ID["EPSG",9802]],PARAMETER["Latitude of false origin",33.5,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8821]],PARAMETER["Longitude of false origin",-118,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8822]],PARAMETER["Latitude of 1st standard parallel",35.4666666666667,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8823]],PARAMETER["Latitude of 2nd standard parallel",34.0333333333333,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8824]],PARAMETER["Easting at false origin",6561666.667,LENGTHUNIT["US survey foot",0.304800609601219],ID["EPSG",8826]],PARAMETER["Northing at false origin",1640416.667,LENGTHUNIT["US survey foot",0.304800609601219],ID["EPSG",8827]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["US survey foot",0.304800609601219]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["US survey foot",0.304800609601219]]] EPSG:2272 2003290.567014627 404990.81174634997 -77.625 40.445 PROJCRS["NAD83 / Pennsylvania South (ftUS)",BASEGEOGCRS["NAD83",DATUM["North American Datum 1983",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4269]],CONVERSION["SPCS83 Pennsylvania South zone (US survey foot)",METHOD["Lambert Conic Conformal (2SP)",ID["EPSG",9802]],PARAMETER["Latitude of false origin",39.3333333333333,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8821]],PARAMETER["Longitude of false origin",-77.75,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8822]],PARAMETER["Latitude of 1st standard parallel",40.9666666666667,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8823]],PARAMETER["Latitude of 2nd standard parallel",39.9333333333333,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8824]],PARAMETER["Easting at false origin",1968500,LENGTHUNIT["US survey foot",0.304800609601219],ID["EPSG",8826]],PARAMETER["Northing at false origin",0,LENGTHUNIT["US survey foot",0.304800609601219],ID["EPSG",8827]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["US survey foot",0.304800609601219]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["US survey foot",0.304800609601219]]] @@ -31,7 +31,7 @@ EPSG:3413 1155327.2723032606 -1155327.2723032609 0.0 75.0 PROJCRS["WGS 84 / NSID EPSG:3976 0.0 1633879.4974707854 0.0 -75.0 PROJCRS["WGS 84 / NSIDC Sea Ice Polar Stereographic South",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["US NSIDC Sea Ice polar stereographic south",METHOD["Polar Stereographic (variant B)",ID["EPSG",9829]],PARAMETER["Latitude of standard parallel",-70,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8832]],PARAMETER["Longitude of origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8833]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",north,MERIDIAN[90,ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["northing (Y)",north,MERIDIAN[0,ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:32761 2000000.0 3674550.193713854 0.0 -75.0 PROJCRS["WGS 84 / UPS South (N,E)",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Universal Polar Stereographic South",METHOD["Polar Stereographic (variant A)",ID["EPSG",9810]],PARAMETER["Latitude of natural origin",-90,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.994,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",2000000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",2000000,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["northing (N)",north,MERIDIAN[0,ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["easting (E)",north,MERIDIAN[90,ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:5041 2000000.0 325449.80628614617 0.0 75.0 PROJCRS["WGS 84 / UPS North (E,N)",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Universal Polar Stereographic North",METHOD["Polar Stereographic (variant A)",ID["EPSG",9810]],PARAMETER["Latitude of natural origin",90,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.994,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",2000000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",2000000,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",south,MERIDIAN[90,ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",south,MERIDIAN[180,ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] -EPSG:28992 142863.97881339837 470673.11249190365 5.21 52.225 PROJCRS["Amersfoort / RD New",BASEGEOGCRS["Amersfoort",DATUM["Amersfoort",ELLIPSOID["Bessel 1841",6377397.155,299.1528128,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4289]],CONVERSION["RD New",METHOD["Oblique Stereographic",ID["EPSG",9809]],PARAMETER["Latitude of natural origin",52.1561605555556,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",5.38763888888889,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9999079,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",155000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",463000,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] +EPSG:28992 142892.18777137925 470783.86707942653 5.21 52.225 PROJCRS["Amersfoort / RD New",BASEGEOGCRS["Amersfoort",DATUM["Amersfoort",ELLIPSOID["Bessel 1841",6377397.155,299.1528128,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4289]],CONVERSION["RD New",METHOD["Oblique Stereographic",ID["EPSG",9809]],PARAMETER["Latitude of natural origin",52.1561605555556,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",5.38763888888889,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9999079,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",155000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",463000,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:2154 489353.58775158133 6587552.204045072 0.2600000000000007 46.355000000000004 PROJCRS["RGF93 v1 / Lambert-93",BASEGEOGCRS["RGF93 v1",DATUM["Reseau Geodesique Francais 1993 v1",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4171]],CONVERSION["Lambert-93",METHOD["Lambert Conic Conformal (2SP)",ID["EPSG",9802]],PARAMETER["Latitude of false origin",46.5,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8821]],PARAMETER["Longitude of false origin",3,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8822]],PARAMETER["Latitude of 1st standard parallel",49,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8823]],PARAMETER["Latitude of 2nd standard parallel",44,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8824]],PARAMETER["Easting at false origin",700000,LENGTHUNIT["metre",1],ID["EPSG",8826]],PARAMETER["Northing at false origin",6600000,LENGTHUNIT["metre",1],ID["EPSG",8827]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:3034 3664622.8977630353 3098904.2726719077 4.625 54.665000000000006 PROJCRS["ETRS89-extended / LCC Europe",BASEGEOGCRS["ETRS89",ENSEMBLE["European Terrestrial Reference System 1989 ensemble",MEMBER["European Terrestrial Reference Frame 1989"],MEMBER["European Terrestrial Reference Frame 1990"],MEMBER["European Terrestrial Reference Frame 1991"],MEMBER["European Terrestrial Reference Frame 1992"],MEMBER["European Terrestrial Reference Frame 1993"],MEMBER["European Terrestrial Reference Frame 1994"],MEMBER["European Terrestrial Reference Frame 1996"],MEMBER["European Terrestrial Reference Frame 1997"],MEMBER["European Terrestrial Reference Frame 2000"],MEMBER["European Terrestrial Reference Frame 2005"],MEMBER["European Terrestrial Reference Frame 2014"],MEMBER["European Terrestrial Reference Frame 2020"],ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[0.1]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4258]],CONVERSION["Europe Conformal 2001",METHOD["Lambert Conic Conformal (2SP)",ID["EPSG",9802]],PARAMETER["Latitude of false origin",52,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8821]],PARAMETER["Longitude of false origin",10,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8822]],PARAMETER["Latitude of 1st standard parallel",35,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8823]],PARAMETER["Latitude of 2nd standard parallel",65,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8824]],PARAMETER["Easting at false origin",4000000,LENGTHUNIT["metre",1],ID["EPSG",8826]],PARAMETER["Northing at false origin",2800000,LENGTHUNIT["metre",1],ID["EPSG",8827]]],CS[Cartesian,2],AXIS["northing (N)",north,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["easting (E)",east,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:3978 207455.49567399794 1463644.068639633 -90.86999999999999 62.334999999999994 PROJCRS["NAD83 / Canada Atlas Lambert",BASEGEOGCRS["NAD83",DATUM["North American Datum 1983",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4269]],CONVERSION["Canada Atlas Lambert",METHOD["Lambert Conic Conformal (2SP)",ID["EPSG",9802]],PARAMETER["Latitude of false origin",49,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8821]],PARAMETER["Longitude of false origin",-95,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8822]],PARAMETER["Latitude of 1st standard parallel",49,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8823]],PARAMETER["Latitude of 2nd standard parallel",77,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8824]],PARAMETER["Easting at false origin",0,LENGTHUNIT["metre",1],ID["EPSG",8826]],PARAMETER["Northing at false origin",0,LENGTHUNIT["metre",1],ID["EPSG",8827]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] @@ -43,7 +43,7 @@ EPSG:3994 6730814.809125746 -3935671.9712001598 180.0 -42.5 PROJCRS["WGS 84 / Me EPSG:2193 1557768.5448432215 5492759.65743377 172.5 -40.715 PROJCRS["NZGD2000 / New Zealand Transverse Mercator 2000",BASEGEOGCRS["NZGD2000",DATUM["New Zealand Geodetic Datum 2000",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4167]],CONVERSION["New Zealand Transverse Mercator 2000",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",173,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",1600000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",10000000,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["northing (N)",north,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["easting (E)",east,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:3067 419924.39978573413 7149882.0006198855 25.335 64.465 PROJCRS["EUREF-FIN / TM35FIN(E,N)",BASEGEOGCRS["EUREF-FIN",DATUM["EUREF-FIN",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]],ANCHOREPOCH[1997]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",10690]],CONVERSION["TM35FIN",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",27,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:3006 609924.4489727435 6877630.37144294 17.1 62.015 PROJCRS["SWEREF99 TM",BASEGEOGCRS["SWEREF99",DATUM["SWEREF99",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4619]],CONVERSION["SWEREF99 TM",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",15,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["northing (N)",north,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["easting (E)",east,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] -EPSG:2100 494317.67042823415 4240767.862084222 23.935000000000002 38.315 PROJCRS["GGRS87 / Greek Grid",BASEGEOGCRS["GGRS87",DATUM["Greek Geodetic Reference System 1987",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4121]],CONVERSION["Greek Grid",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",24,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] +EPSG:2100 494168.08116862935 4240480.130834421 23.935000000000002 38.315 PROJCRS["GGRS87 / Greek Grid",BASEGEOGCRS["GGRS87",DATUM["Greek Geodetic Reference System 1987",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4121]],CONVERSION["Greek Grid",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",24,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",0.9996,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",500000,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:2039 193412.21592306579 585981.7010273987 34.93 31.365000000000002 PROJCRS["Israel 1993 / Israeli TM Grid",BASEGEOGCRS["Israel 1993",DATUM["Israel 1993",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4141]],CONVERSION["Israeli TM",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",31.7343936111111,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",35.2045169444444,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",1.0000067,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",219529.584,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",626907.39,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["(E)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["(N)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:3414 27630.671900054072 31372.9137690611 103.83 1.2999999999999998 PROJCRS["SVY21 / Singapore TM",BASEGEOGCRS["SVY21",DATUM["SVY21",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4757]],CONVERSION["Singapore Transverse Mercator",METHOD["Transverse Mercator",ID["EPSG",9807]],PARAMETER["Latitude of natural origin",1.36666666666667,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",103.833333333333,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["Scale factor at natural origin",1,SCALEUNIT["unity",1],ID["EPSG",8805]],PARAMETER["False easting",28001.642,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",38744.572,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["northing (N)",north,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["easting (E)",east,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] EPSG:6933 0.0 0.0 0.0 0.0 PROJCRS["WGS 84 / NSIDC EASE-Grid 2.0 Global",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],MEMBER["World Geodetic System 1984 (G2296)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["US NSIDC EASE-Grid 2.0 Global",METHOD["Lambert Cylindrical Equal Area",ID["EPSG",9835]],PARAMETER["Latitude of 1st standard parallel",30,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8823]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]] diff --git a/docs/user-guide/data.md b/docs/user-guide/data.md index 05de8723a..11965849e 100644 --- a/docs/user-guide/data.md +++ b/docs/user-guide/data.md @@ -57,6 +57,14 @@ GeoParquet and FlatGeobuf carry their coordinate system in the file. Rasters kee coordinate system and are reprojected as they draw. The map uses Web Mercator by default, but **View › Projection** can change it; see [Maps](maps.md). +ESRI `.prj` files without an EPSG code use their projection parameters and, for ED50, +Monte Mario, OSGB36, DHDN, Amersfoort, GGRS87, CH1903/CH1903+ and S-JTSK, the same built-in +Helmert datum transformation as the EPSG definition. A `TOWGS84` transformation in the file +takes precedence. RDN2008 and IGM95 are treated as WGS 84-like datums. These transformations +do not replace regional grid corrections for survey accuracy. An unrecognized datum keeps +its ellipsoid and produces a notice when no transformation is available. Swiss oblique +Mercator and the standard Krovak East/North variant are supported from their parameters. + Shapefile text uses a supported `.cpg` encoding, otherwise the `.dbf` code page, with UTF-8 as the fallback. Keep the sidecar files together.