我正在将ArcGIS .NET SDK
与WPF
一起使用,并且我的代码基于this project。
我正在尝试从数据库加载多边形以显示在地图上。我还希望能够编辑这些多边形并在数据库上更新它们。我使用SpatialReferences.WebMercator属性保存多边形时,一切工作正常。
但是现在我有了一个将多边形另存为Wgs84(纬度和经度)的数据库。现在,我可以将这些多边形加载到地图上,但是我无法对其进行编辑,因为地图是WebMercator,而多边形是Wgs84。尝试编辑后,出现异常:
输入的空间参考与所属空间不匹配参考...
在进一步介绍之前,创建地图时是否只能将地图设置为SpatialReferences.Wgs84
?这就是我创建地图的方式:
Map myMap = new Map(BasemapType.Streets, -33.9249, 18.4241, 11);
空间参考默认为SpatialReferences.WebMercator
。
我尝试过类似的操作,但是我的地图只是空白:
Map myMap = new Map(SpatialReferences.Wgs84);
myMap.Basemap = Basemap.CreateOpenStreetMap();
好的,假设没有办法将地图更改为Wgs84,我需要在从数据库中加载多边形后立即将其转换(将Wgs84转换为WebMercator),并在保存到数据库之前立即将其转换回( WebMercator转换为Wgs84)。
所以我能够进行第一次转换,我从数据库中加载了Wgs84多边形并将每个点转换为WebMercator。我可以显示这些多边形,也可以对其进行编辑。
但是在尝试保存多边形时,我正在努力进行第二次转换。我确实找到了可以将这些WebMercator点转换回Wgs84以保存在数据库中的公式,但是除了经纬度之外,它还需要一个区域。所以我的观点:
String geomStr = MyMapView.SketchEditor.Geometry.ToJson();
从那里我可以得到所有纬度对进行转换,但是我需要每个点的区域。有什么方法可以从图形或几何对象中检索区域?还是仅通过了解纬度或经度来找出区域呢?这是我所需的全部,然后我才能尝试将Wgs84转换为WebMercator的公式。
This tool具有我需要的功能。
我不知道ArcGIS如何实际存储或处理以WebMercator作为空间参考的数据。
[官方]规范由EPSG:3857给出。
另请参见https://epsg.io/3857和https://spatialreference.org/ref/sr-org/epsg3857-wgs84-web-mercator-auxiliary-sphere/
这里解释了地图投影:https://en.wikipedia.org/wiki/Web_Mercator_projection
[如果您想自己进行计算,请使用如下所示的方法,其中Location是一个类,以度数形式保存WGS 84的纬度和经度值,Point是System.Windows.Point
,并以米为单位保存X和Y值,从纬度= 0和经度= 0的坐标原点开始测量。
public class Location
{
public double Latitude { get; set; } // degrees from -90 to 90
public double Longitude { get; set; } // degrees from -180 to 180
}
public const double Wgs84EquatorialRadius = 6378137d;
public const double Wgs84MetersPerDegree = Wgs84EquatorialRadius * Math.PI / 180d;
public override Point LocationToPoint(Location location)
{
return new Point(
Wgs84MetersPerDegree * location.Longitude,
Wgs84MetersPerDegree * LatitudeToY(location.Latitude));
}
public override Location PointToLocation(Point point)
{
return new Location(
YToLatitude(point.Y / Wgs84MetersPerDegree),
point.X / Wgs84MetersPerDegree);
}
public static double LatitudeToY(double latitude)
{
if (latitude <= -90d)
{
return double.NegativeInfinity;
}
if (latitude >= 90d)
{
return double.PositiveInfinity;
}
return Math.Log(Math.Tan((latitude + 90d) * Math.PI / 360d)) * 180d / Math.PI;
}
public static double YToLatitude(double y)
{
return 90d - Math.Atan(Math.Exp(-y * Math.PI / 180d)) * 360d / Math.PI;
}