Преобразование координат из EPSG 3857 в 4326 DotSpatial
У меня в БД есть список координат в формате EPSG 3857. Мне нужно конвертировать их в EPSG 4326. Я пытаюсь использовать DotSpatial, но мой код всегда повторяет двойной массив бесконечности.
public double[] ConvertCoodinates()
{
double[] xy = new double[2];
xy[0] = 5085240.8300000000;
xy[1] = 1530088.9600000000;
//An array for the z coordinate
double[] z = new double[1];
z[0] = 0;
ProjectionInfo pStart = KnownCoordinateSystems.Geographic.World.WGS1984;
pStart.AuthorityCode = 3857;
ProjectionInfo pEnd = KnownCoordinateSystems.Geographic.World.WGS1984;
pEnd.AuthorityCode = 4326;
Reproject.ReprojectPoints(xy, z, pStart, pEnd, 0, 1);
return xy;
}
Массив xy всегда совпадает с бесконечностью; Кто-нибудь может мне помочь?
4 ответа
В конце я нахожу математическую формулу для преобразования координат.
Я реализовал это в хранимой процедуре, потому что у меня есть список точек, и эта хранимая процедура вычисляет расстояние.
DECLARE @e FLOAT=2.7182818284
DECLARE @X DECIMAL(18,2) =20037508.34
SET @StartLat3857 =(SELECT TOP 1 Latitude FROM Coordinates WHERE IdCoord=@IdCoord ORDER By IdTDFPath ASC)
SET @StartLng3857=(SELECT TOP 1 Longitude FROM Coordinates WHERE IdCoord=@IdCoord ORDER By IdTDFPath ASC)
--converting the logitute from epsg 3857 to 4326
SET @StartLng=(@StartLng3857*180)/@X
--converting the latitude from epsg 3857 to 4326
SET @StartLat = @StartLat3857/(@X/180)
SET @StartLat = ((ATAN(POWER(@e,((PI()/180)*@StartLat))))/(PI()/360))-90
Ошибка в версии Javascript выбранного ответа.
Вот рабочий код:
coord3857To4326(coord) {
const e_value = 2.7182818284;
const X = 20037508.34;
const lat3857 = coord.lat
const long3857 = coord.lng;
//converting the longitute from epsg 3857 to 4326
const long4326 = (long3857*180)/X;
//converting the latitude from epsg 3857 to 4326 split in multiple lines for readability
let lat4326 = lat3857/(X / 180);
const exponent = (Math.PI / 180) * lat4326;
lat4326 = Math.atan(Math.pow(e_value, exponent));
lat4326 = lat4326 / (Math.PI / 360); // Here is the fixed line
lat4326 = lat4326 - 90;
return {lat:lat4326, lng:long4326};
}
Надеюсь, это поможет другим!
Немного сложно спроецировать EPSG 3857
координаты к EPSG 4326
система координат. Microsoft рекомендует использоватьProjNet4GeoAPI
поэтому я решил использовать это.
https://docs.microsoft.com/en-us/ef/core/modeling/spatial
Я убедился, что здесь это работает:
http://epsg.io/transform#s_srs=3857&t_srs=4326&x=1530088.9600000&y=5085240.8300000
Пример преобразования:
var x = 1530088.96d;
var y = 5085240.83d;
var epsg3857ProjectedCoordinateSystem = ProjNet.CoordinateSystems.ProjectedCoordinateSystem.WebMercator;
var epsg4326GeographicCoordinateSystem = ProjNet.CoordinateSystems.GeographicCoordinateSystem.WGS84;
var coordinateTransformationFactory = new ProjNet.CoordinateSystems.Transformations.CoordinateTransformationFactory();
var coordinateTransformation = coordinateTransformationFactory.CreateFromCoordinateSystems(epsg3857ProjectedCoordinateSystem, epsg4326GeographicCoordinateSystem);
var epsg3857Coordinate = new GeoAPI.Geometries.Coordinate(x, y);
var epsg4326Coordinate = coordinateTransformation.MathTransform.Transform(epsg3857Coordinate);
Я заставил это работать в Rust, используя следующий код:
use std::f64::consts::{E, PI};
fn convert_coordinates(pos: &Vec<f64>) -> Vec<f64> {
// Longitude <-> X
// Latitude <-> Y
// Output Decimal degree (WGS84)
// X:-7920923.8631988168, Y: 5197114.9130207254
// 0 1
// Longitude: -71.1548697°, Latitude: 42.2407752°
//
let long3857: f64 = pos[0];
let lat3857: f64 = pos[1];
let long4326: f64 = (long3857 * 180.0) / 20037508.34;
let lat4326: f64 = (lat3857 * 180.0) / 20037508.34;
let lat_rad: f64 = (lat4326 / 180.0) * PI;
let lat4326_final: f64 = (2.0 * lat_rad.exp().atan() - PI / 2.0).to_degrees();
vec![long4326, lat4326_final]
}
assert_eq!(-71.1548697_f64.round(), convert_coordinates(&vec![-7920923.8631988168, 5197114.9130207254])[0].round());
println!("Longitude Passed");
assert_eq!(42.2407752_f64.round(), convert_coordinates(&vec![-7920923.8631988168, 5197114.9130207254])[1].round());
println!("Latitude Passed");