或者如何将Yandex地图图块拟合到OpenStreetMaps投影?
参赛作品
每次打开某种在线地图时,都不会完整下载它。 为了加快地图的加载速度,将地图分成小块(平铺),以便仅下载所需区域。 问题是您可以通过几种方式切入这些正方形。

大多数在线卡片都“认为”地球呈球形。 其中,例如Google地图和OpenStreetMaps。 有些人更加细致地考虑到了行星不是正确的球这一事实:至少,它在两极是扁平的。 例如,在Yandex地图中使用了这样的椭圆投影。

结果,在不同投影中具有相同编号的单元将显示完全不同的位置。 例如,这是一个图块,其X轴编号为10427,Y轴编号为5119。比例级别14。左侧-OSM,右侧Yandex。 而不是城市-某种森林。

尽管大多数地图引擎可以自动将图块调整为所需的投影,但有时您可能需要手动执行此操作。 但是如何? 最简单的方法是将图块简单地移动一定数量的像素。 结果,我们将在地图上看到所需的区域。 当然,如果仔细观察,会发现一些变形。 但我认为,同样的准确性,日常工作将绰绰有余。 因此,是时候完成介绍并开始制造转换器了。

方法论
要工作,我们需要一个转换公式。 据我了解,在当时仍然有可能这样做的时候,它是直接从Yandex Maps页面代码中提取的。 我现在找不到指向源的链接,但是此公式
已在中心上
发布 。 我几乎没有碰过它:我只是在Swift上重写了它,并给难以理解的单字母变量赋予了更多“说话”名称。 至少那些能够识别的人。 (感谢Erelen的帮助)
好吧,任务如下。 我们需要做一个转换器,将标准投影中的图块编号作为输入,并将椭圆投影中的图块编号以及需要将其移位到输出的像素数。
这样啊 例如,以编号X 10427,Y 5119,Z 14的
瓷砖为例。
我们将采取两个步骤。 首先,您需要找到此图块的坐标(纬度和经度)。 例如,其左上角的坐标。
func tileNumberToCoordinates(tileX: Int, tileY: Int, mapZoom: Int) -> (lat_deg: Double, lon_deg: Double) { let n : Double = pow(2.0, Double(mapZoom)) let lon = (Double(tileX) / n) * 360.0 - 180.0 let lat = atan( sinh (.pi - (Double(tileY) / n) * 2 * Double.pi)) * (180.0 / .pi) return (lat, lon) }
我们得到输出(55.7889 49.1088)。 现在,将获得的值替换为公式。 缩放级别仍然相同:第14。
func getWGS84Position(latitude: Double, longitude: Double, zoom: Int) -> (x:Int, y:Int, offsetX:Int, offsetY:Int) {
我们得到(10427,5133,0,117)。 这意味着我们需要一个Yandex贴图,其编号为X 10427,Y 5133,Z14。如果将其向左移动0像素,向上移动117像素,则它将占据正确的位置。

怎么办呢?
如果您编写了导航器,并且有机会影响地图的显示,那么一切都会相对简单。 计算屏幕上任何图块的偏移量。 并以任何方便的方式将带有地图的元素移动此像素数。
但是,如果您无权访问该代码,则必须在地图服务器和导航器之间输入一个中间链接。 例如,为此我制作了一个简单的服务器。 它输入所需的图块编号,然后计算椭圆投影中的图块编号。 它还下载了三个相邻的磁贴。 将这四个图块粘合成一个大的图块,然后从中切出所需的片段,并将其返回给用户导航器。

结果和原始:

当然,所有这些操作都需要额外的时间成本。 使用这些链接,您可以实时评估服务器“ photoshop”卡的速度:
https://anygis.ru/api/v1/Yandex_map/{xasket/{y}/{z}https://anygis.ru/api/v1/Yandex_sat_clean/{xasket/{y}/{z}好吧,我希望这里提供的信息对某人有用。 祝您实验顺利。