gpt4 book ai didi

ios - 如何从数据库在 map 上绘制图 block ?

转载 作者:行者123 更新时间:2023-11-28 21:19:08 26 4
gpt4 key购买 nike

我正在使用 Swift 3.0 开发基于 GIS 的 iOS 应用程序。我想在 map 上绘制瓦片,瓦片图像存储在 SQLite 数据库中。

我的问题是如何从数据库中检索平铺图像并在 map 上绘制这些图像,因为数据库包含列 zoom(值为 12、13 等)、tile_row(值为 4122、3413 等) 、tile_column(值为 4122、3413 等)和数据,但我得到的缩放级别值以千为单位,我在 iOS 应用程序中得到纬度和经度值,所以我需要转换这些值以匹配数据库中的值。我找到了一种将缩放级别转换为 1 到 18 比例的方法,但我不知道我能否使用纬度和经度来匹配 tile_row 和 tile_column 值。

另请验证我将缩放级别转换为 1 到 18(类似于谷歌地图缩放级别)的代码是否正确:

let zoomLevel = Int(log2(360 / MKCoordinateRegionForMapRect(mapRect).span.longitudeDelta))

谢谢。

最佳答案

在 IOS(和大多数 map 系统)中,平铺图像存储在目录结构中,其中每个缩放级别都是一个以缩放级别编号命名的父目录。在该目录下,有一个或多个目录以下面瓷砖的纵向瓷砖编号命名 - 例如,在缩放级别 10 有 1024 个瓷砖,您的目录可能是 750、751、752 和 753,如果这是他们的图像相对下跌。在每个经度(x 坐标)目录下是该 y 坐标的图像(256 X 256 像素),每个图像都以 x 平铺坐标命名,在缩放级别 10 时也是 1024 张。

要找到您在这些范围内的位置,请使用 MKMapPointForCoordinate(CLLocationCoordinate2D),它会在完全缩小时为您提供某个位置的纬度 (y) 和经度 (x) map 点。要获取经度 (y) 瓦片编号,请使用:

Int((pow(2.0, Double(z)) as Double) * point.y / 268435456.0) 

...其中大数字是缩放级别 0 时 x 轴上的点总数(2^20 tiles * 256 pixels/tile)。这样,如果 point.x 是大数字的 1/3,则图像是通过 1024 的 1/3 瓦片,代表该数字落入的 256 像素间隔(即瓦片)的整数就是名称目录。

纬度(y) map 点和图 block 编号的计算方法类似,该编号是图像文件的名称。因此,在缩放级别 10 时,沿 x 轴的 1024 个中的第 752 个图像和沿 y 轴的 1024 个中的 486 个图像将在文件中:

...Documents/Maps/yourDirectory/10/752/486.png

...前提是您将整个 map 目录命名为 Maps,并将这组图 block 的特定目录命名为 yourDirectory。当您使用覆盖时,您将使用此目录信息以及其余设置来实例化 MKTileOverlay 对象。请注意,偏移量是从左下角开始的,除非您指定它们是相反的,因为它们考虑的是 x 轴和 y 轴(提醒您对 UIImage 使用 CoreGraphics?)。

最后,这里是我如何计算给定区域的两个角点的缩放级别,我想为其捕获快照:

    let position1 = MKMapPointForCoordinate(bottomRight)
let position2 = MKMapPointForCoordinate(topLeft)
let xPosition1 = position1.x / Setting.shared.mapScale
let xPosition2 = position2.x / Setting.shared.mapScale
let yPosition1 = position1.y / Setting.shared.mapScale
let yPosition2 = position2.y / Setting.shared.mapScale

let relativeSpanX = xPosition1 - xPosition2 // X distance between points relative to size of full map
let relativeSpanY = yPosition1 - yPosition2 // Y distance between points relative to size of full map
let spanForZoom = max(relativeSpanX, relativeSpanY)

startingZoom = max(10, Int(log2(1.0 / spanForZoom)) - 1)

这会让您获得适合包含这两个点的区域大小的图 block 的缩放级别,但请注意,该尺寸(或小于完整 map 的任何尺寸)的任何标准图 block 都可能包含这两个点,具体取决于它们相对于网格的位置。例如,如果它们跨越本初子午线,则缩放级别为 1 的 4 个图 block 的第一步会将它们分开,因此您可能需要 2 - 4 个起始缩放大小的图 block 才能获得两者。理想情况下,编写一个函数来告诉您包含 CLLocationCoordinate2D 的图 block 编号(x 和 y),因为这在您选择、下载和收集图 block 时非常方便。

虽然您可以像展示的那样使用几何方法来计算纵轴/y 轴值,但 MKMapPointForCoordinate() 对于纬度/y 轴计算是必不可少的,因为墨卡托 map 在您向北移动时是非线性的或向南,该功能会为您处理。

这应该让您开始,但这是一个挑剔的过程 - 需要关注的一件事是布局始终从左下角开始;收集和标记瓷砖时很容易混淆。

我使用以下函数计算给定缩放级别下某个点​​所在的图 block 的 x 和 y 坐标:

func getTileCoordinates(location: CLLocationCoordinate2D, z: Int) -> (x: Int, y: Int)
{
let point = MKMapPointForCoordinate(location)
let locationX = Int((pow(2.0, Double(z)) as Double) * point.x / 268435456.0)
let locationY = Int((pow(2.0, Double(z)) as Double) * point.y / 268435456.0)

return (locationX, locationY)
}

...同样,其中 268435456.0 是缩放级别 20 map 中沿 x 或 y 轴的像素总数。请注意,所有这些都是针对 Apple 的 MapKit map 和显示它们的函数。

关于ios - 如何从数据库在 map 上绘制图 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40538181/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com