iOS Swift3-转换坐标 [英] iOS Swift3 - Convert coordinate

查看:71
本文介绍了iOS Swift3-转换坐标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从geoJSON文件在MapKit上创建注释,但是问题是geoJSON文件提供的坐标与MapKit使用的坐标系不匹配.

I'm trying to create annotations on the MapKit from a geoJSON file, but the problem is that the coordinates provided by the geoJSON file don't match the coordinate system that MapKit uses.

问题:如何转换 read geoJSON文件和 convert 来自WGS84S?

Question : How do I convert read the geoJSON file and convert the coordinates from `` to WGS84S?

以下是geoJSON文件的示例:

{"name":"MAPADDRESSPOINT","type":"FeatureCollection"
,"crs":{"type":"name","properties":{"name":"EPSG:3008"}}
,"features":[
{"type":"Feature","geometry":{
    "type":"Point","coordinates": [97973.4655999987,6219081.53249992,0]},
        "properties":{
            "ADDRESSAREA_resolved":"Sadelvägen",
            "multi_reader_id":1,
            "multi_reader_full_id":1,
            "BALSTATUS_resolved":"Gällande",
            "REMARKTYPE_resolved":"",
            "FARMADDRESSAREA_resolved":"",
            "geodb_type":"geodb_point",
            "multi_reader_keyword":"GEODATABASE_SDE_2",
            "DEVIATEFROMSTANDARD_resolved":"",
            "geodb_feature_is_simple":"yes",
            "STATUS_resolved":"Ingen information",
            "ADDRESSEDCONSTRUCTIONTYPE_resolved":"",
            "SUPPLIER_resolved":"",
            "multi_reader_type":"GEODATABASE_SDE",
            "geodb_oid":18396,
            "STAIRCASEIDENTIFIER_resolved":"",
            "LOCATIONADDRESSSTATUS_resolved":"Gällande",
            "POSITIONKIND_resolved":"Byggnad",
            "BALADDRESSTYPE_resolved":"Gatuadressplats",
            "COMMENTARY":"","
            DTYPE":"",
            "EXTERNALID":2,"GID":"{DEEA1685-2FF3-4BEB-823D-B9FA51E09F71}",
            "MODIFICATIONDATE":"20170301173751",
            "MODIFICATIONSIGN":"BAL service",
            "OBJECTID":18396,
            "REGDATE":"20110321151134",
            "REGSIGN":"BAL service",
            "STATUS":0,
            "ADDRESSEDCONSTRUCTIONVALUE":"",
            "LABELROTATIONANGLE":0,
            "POSTCODE":"25483",
            "POSITIONKIND":1,
            "REALPROPERTYKEY":"120320803",
            "BALSTATUS":2,
            "BALADDRESSTYPE":1,
            "BALID":"D5650F0B-EE54-4C4C-9C40-A8162118288C",
            "DESIGNATIONVALUE":"",
            "SYNCDATE":"20170301173751",
            "STREETNAME":"Sadelvägen",
            "ADDRESSAREA":554,
            "YARDSNAME":"",
            "PLACENAMEID":"",
            "ADDRESSLABEL":"Sadelvägen 6",
            "DESIGNATIONNUMBERLETTER":"",
            "LOCATIONADDRESSSTATUS":3,
            "CITY":"Helsingborg",
            "ENUMERATOR":"6",
            "SYMBOLROTATIONANGLE":0,
            "POPULARNAME":"",
            "geodb_feature_dataset":"Adress"
        }
    }
}]
}

推荐答案

https://zh-CN .m.wikipedia.org/wiki/Transverse_Mercator_projection

自然起源的经度0°00'00.000"N 13°30'00.000东

Longitude of natural origin 0° 00' 00.000" N 13° 30' 00.000" E

自然起源的比例因子 1

Scale factor at natural origin 1

虚假东移 150000 米

False easting 150000 meters

虚假北向 0

最终版(游乐场)

//: [Previous](@previous)

import Foundation

extension Double {
    var rad: Double {
        get {
            return .pi * self / 180.0
        }
    }
    var deg: Double {
        get {
            return 180.0 * self / .pi
        }
    }
}

// SWEREF99 13 30 (GRS80)
let φ0 = 0.0
let λ0 = 13.5.rad
let N0 = 0.0
let E0 = 150000.0
let k0 = 1.0

// GRS80
let a = k0 * 6378137.0
let b = k0 * 6356752.31414034
let n = (a - b)/(a + b)

let n2 = n * n
let n3 = n2 * n
let n4 = n3 * n
let a2 = a * a
let b2 = b * b
let e2 = (a2 - b2)/a2
let H0 = 1.0 + 1.0/4.0*n2 + 1.0/64.0*n4
let H2 = -3.0/2.0*n + 3.0/16.0*n3
let H4 = 15.0/16.0*n2 - 15.0/64.0*n4
let H6 = -35.0/48.0*n3
let H8 = 315.0/512.0*n4

let ν:(Double)->Double = { φ in
    return a/(sqrt(1.0 - e2 * sin(φ) * sin(φ)))
}

let ρ:(Double)->Double = { φ in
    return ν(φ) * (1.0 - e2) / (1.0 - e2 * sin(φ) * sin(φ))
}

let η2:(Double)->Double = { φ in
    return ν(φ) / ρ(φ) - 1.0
}
var arcMeridian1:(Double)->Double = { φ in
    let m = (a + b) / 2 * (H0 * φ + H2 * sin(2.0 * φ) + H4 * sin(4.0 * φ) + H6 * sin(6.0 * φ) + H8 * sin(8.0 * φ))
    return m
}

var arcMeridian:(Double, Double)->Double = { φ1, φ2 in
    return arcMeridian1(φ2) - arcMeridian1(φ1)
}

var cartografic:(Double,Double)->(Double,Double) = { φ, λ in
    let νφ = ν(φ)
    let ρφ = ρ(φ)
    let η2φ = νφ / ρφ - 1.0
    let s1 = sin(φ)
    let s2 = s1 * s1
    let c1 = cos(φ)
    let c2 = c1 * c1
    let c3 = c2 * c1
    let c5 = c3 * c2
    let t2 = s2/c2
    let t4 = t2 * t2

    let k1 = νφ * c1
    let k2 = νφ/2.0 * s1 * c1
    let k3 = νφ/6.0 * c3 * (νφ / ρφ - t2)
    let k4 = νφ/24.0 * s1 * c3 * (5.0 - t2 + 9.0 * η2φ)
    let k5 = νφ/120.0 * c5 * (5.0 - 18.0 * t2 + t4 + 14.0 * η2φ - 58.0 * t2 * η2φ)
    let k6 = νφ/720.0 * s1 * c5 * (61.0 - 58.0 * t2 + t4)

    let Δλ = λ - λ0
    let Δλ2 = Δλ * Δλ
    let Δλ3 = Δλ2 * Δλ
    let Δλ4 = Δλ3 * Δλ
    let Δλ5 = Δλ4 * Δλ
    let Δλ6 = Δλ4 * Δλ

    let N = arcMeridian(φ0,φ) + N0 + Δλ2 * k2 + Δλ4 * k4 + Δλ6 * k6
    let E = E0 + Δλ * k1 + Δλ3 * k3 + Δλ5 * k5

    return (N,E)
}

var geodetic:(Double,Double)->(Double,Double) = { N, E in
    var φ = (N - N0) / a + φ0
    var M = arcMeridian(φ0, φ)

    var diff = 1.0
    repeat {
        φ += (N - N0 - M) / a
        M = arcMeridian(φ0, φ)
        diff = N - N0 - M
    } while abs(diff) > 0.0000000001  // max 3 - 4 iterations
    let E1 = E - E0
    let E2 = E1 * E1
    let E3 = E2 * E1
    let E4 = E3 * E1
    let E5 = E4 * E1
    let E6 = E5 * E1
    let E7 = E6 * E1

    let νφ = ν(φ)
    let νφ3 = νφ * νφ * νφ
    let νφ5 = νφ3 * νφ * νφ
    let νφ7 = νφ5 * νφ * νφ
    let ρφ = ρ(φ)
    let η2φ = νφ / ρφ - 1.0
    let s1 = sin(φ)
    let s2 = s1 * s1
    let c1 = cos(φ)
    let t1 = s1 / c1
    let t2 = t1 * t1
    let t4 = t2 * t2
    let t6 = t4 * t2

    let k1 = 1.0 / (c1 * νφ)
    let k2 = t1 / (2.0 * ρφ * νφ)
    let k3 = 1.0 / (6.0 * νφ3) * (νφ / ρφ + 2.0 * t2)
    let k4 = (t1 / (24.0 * ρφ * νφ3)) * (5.0 + 3.0 * t2 + η2φ - 9.0 * t2 * η2φ)
    let k5 = 1.0 / (120.0 * νφ5) * (5.0 + 28.0 * t2 + 24.0 * t4)
    let k6 = (t1 / (720.0 * ρφ * νφ5)) * (61.0 + 90.0 * t2 + 45.0 * t4)
    let k7 = (t1 / (5040.0 * ρφ * νφ7)) * (61.0 + 662.0 * t2 + 1320.0 * t4 + 720.0 * t6)

    φ = φ - E2 * k2 + E4 * k4 - E6 * k6
    let λ = λ0 + E1 * k1 - E3 * k3 + E5 * k5 - E7 * k7
    return (φ, λ)
}

print("pecision check")
let carto0 = cartografic(55.0.rad, 12.75.rad)
print(carto0,"err:", carto0.0 - 6097487.637, carto0.1 - 102004.871)

let carto1 = cartografic(61.0.rad, 14.25.rad)
print(carto1,"err:", carto1.0 - 6765725.847, carto1.1 - 190579.995)
print()
print("given position: N 6219081.53249992, E 97973.4655999987")
let geo = geodetic(6219081.53249992, 97973.4655999987)
print("geodetic: φ =", geo.0.deg,"λ =", geo.1.deg)

//: [Next](@next)

打印

pecision check
(6097487.6372101102, 102004.87085248799) err: 0.00021011009812355 -0.000147512007970363
(6765725.8471242301, 190579.99493182387) err: 0.000124230049550533 -6.81761302985251e-05

given position: N 6219081.53249992, E 97973.4655999987
geodetic: φ = 56.0916410844269 λ = 12.6641326192406

在地图上的位置

这篇关于iOS Swift3-转换坐标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆