golang坐标转换与坐标系变换插件库WGS84的使用

Golang坐标转换与坐标系变换插件库WGS84的使用

安装

go get github.com/wroge/wgs84/v2@v2.0.0-alpha.13

目前该包正在重写中,部分功能将会变更,同时会添加新特性,如NTv2网格变换和Krovak等其他投影支持。如果您有任何建议或意见,请在issues中反馈。

Web Mercator投影转换示例

package main

import (
	"fmt"

	"github.com/wroge/wgs84/v2"
)

func main() {
	// 创建从EPSG:4326(WGS84)到EPSG:3857(Web Mercator)的转换器,结果保留3位小数
	transform := wgs84.Transform(wgs84.EPSG(4326), wgs84.EPSG(3857)).Round(3)

	// 将经度10°,纬度50°转换为Web Mercator坐标
	east, north, _ := transform(10, 50, 0)

	fmt.Println(east, north)
	// 输出: 1.113194908e+06 6.446275841e+06

	// 等同于命令行: echo 10 50 | cs2cs +init=epsg:4326 +to +init=epsg:3857 -d 3
	// 输出: 1113194.908     6446275.841
}

OSGB(英国国家网格)转换示例

package main

import (
	"fmt"

	"github.com/wroge/wgs84/v2"
)

func main() {
	// 创建从EPSG:4326(WGS84)到EPSG:27700(OSGB)的转换器,结果保留3位小数
	transform := wgs84.Transform(wgs84.EPSG(4326), wgs84.EPSG(27700)).Round(3)

	// 将经度-2.25°,纬度52.25°转换为OSGB坐标
	east, north, h := transform(-2.25, 52.25, 0)

	fmt.Println(east, north, h)
	// 输出: 383029.296 261341.615 0

	// 等同于命令行: echo -2.25 52.25 | cs2cs +init=epsg:4326 +to +init=epsg:27700 -d 3
	// 输出: 383029.296 261341.615 0.000
}

更多关于golang坐标转换与坐标系变换插件库WGS84的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang坐标转换与坐标系变换插件库WGS84的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang坐标转换与坐标系变换插件库WGS84使用指南

WGS84是地理信息系统中最常用的坐标参考系统之一,下面我将介绍如何在Golang中进行WGS84坐标转换与坐标系变换。

常用库推荐

在Golang中,有几个优秀的库可以处理WGS84坐标转换:

  1. proj - Go的PROJ库绑定
  2. go-geom - 几何对象处理
  3. orb - 地理空间数据处理

安装依赖

go get github.com/go-spatial/proj
go get github.com/twpayne/go-geom
go get github.com/paulmach/orb

基本坐标转换示例

1. WGS84转Web墨卡托(EPSG:3857)

package main

import (
	"fmt"
	"github.com/go-spatial/proj"
)

func main() {
	// 初始化转换器
	transformer, err := proj.NewTransformer(
		"+proj=longlat +datum=WGS84 +no_defs",  // WGS84
		"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs",  // Web墨卡托
	)
	if err != nil {
		panic(err)
	}
	defer transformer.Close()

	// 经纬度坐标(北京)
	longitude := 116.404
	latitude := 39.915

	// 执行转换
	x, y, err := transformer.Transform(longitude, latitude)
	if err != nil {
		panic(err)
	}

	fmt.Printf("WGS84坐标: (%f, %f)\n", longitude, latitude)
	fmt.Printf("Web墨卡托坐标: (%f, %f)\n", x, y)
}

2. 使用orb库进行坐标转换

package main

import (
	"fmt"
	"github.com/paulmach/orb"
	"github.com/paulmach/orb/project"
)

func main() {
	// 定义WGS84点(北京)
	point := orb.Point{116.404, 39.915}
	
	// 转换为Web墨卡托
	projected := project.Point(point, project.WGS84.ToMercator)
	
	fmt.Printf("原始坐标: %v\n", point)
	fmt.Printf("投影坐标: %v\n", projected)
	
	// 反向转换
	unprojected := project.Point(projected, project.Mercator.ToWGS84)
	fmt.Printf("还原坐标: %v\n", unprojected)
}

坐标系统转换

1. WGS84转GCJ-02(火星坐标)

package main

import (
	"fmt"
	"github.com/wroge/wgs84"
)

func main() {
	// 北京坐标
	lat, lon := 39.915, 116.404
	
	// WGS84转GCJ-02
	gcjLat, gcjLon := wgs84.ToGCJ(lat, lon)
	
	fmt.Printf("WGS84: (%f, %f)\n", lat, lon)
	fmt.Printf("GCJ-02: (%f, %f)\n", gcjLat, gcjLon)
	
	// GCJ-02转WGS84
	wgsLat, wgsLon := wgs84.FromGCJ(gcjLat, gcjLon)
	fmt.Printf("还原WGS84: (%f, %f)\n", wgsLat, wgsLon)
}

2. WGS84转BD-09(百度坐标)

package main

import (
	"fmt"
	"github.com/wroge/wgs84"
)

func main() {
	// 北京坐标
	lat, lon := 39.915, 116.404
	
	// WGS84转BD-09
	bdLat, bdLon := wgs84.ToBD(lat, lon)
	
	fmt.Printf("WGS84: (%f, %f)\n", lat, lon)
	fmt.Printf("BD-09: (%f, %f)\n", bdLat, bdLon)
	
	// BD-09转WGS84
	wgsLat, wgsLon := wgs84.FromBD(bdLat, bdLon)
	fmt.Printf("还原WGS84: (%f, %f)\n", wgsLat, wgsLon)
}

距离计算

package main

import (
	"fmt"
	"github.com/paulmach/orb"
	"github.com/paulmach/orb/dist"
)

func main() {
	// 北京和上海坐标
	beijing := orb.Point{116.404, 39.915}
	shanghai := orb.Point{121.474, 31.230}
	
	// 计算两点间距离(米)
	distance := dist.Haversine(beijing, shanghai)
	
	fmt.Printf("北京到上海的距离: %.2f 米\n", distance)
	fmt.Printf("北京到上海的距离: %.2f 公里\n", distance/1000)
}

注意事项

  1. 不同坐标系统转换会有精度损失
  2. GCJ-02和BD-09转换是非线性的,不能简单逆向
  3. 高精度应用应考虑使用专业GIS软件
  4. 中国境内地图服务通常使用GCJ-02或BD-09坐标系

以上代码示例涵盖了常见的WGS84坐标转换场景,可以根据实际需求选择合适的库和方法。

回到顶部