Пример #1
0
// Transform a Swiss coordinate value to a GRS80 based latitude and longitude coordinate. Function returns
// cartconvert.ErrRange, if the swiss coordinate type is not one of LV03 or LV95
func SwissCoordToGRS80LatLong(coord *SwissCoord) (*cartconvert.PolarCoord, error) {

	var fn, fe float64

	switch coord.CoordType {
	case LV03:
		fe = 600000
		fn = 200000
	case LV95:
		fe = -2600000
		fn = -1200000
	default:
		return nil, cartconvert.ErrRange
	}

	gc := cartconvert.InverseTransverseMercator(
		&cartconvert.GeoPoint{Y: coord.Northing, X: coord.Easting, El: coord.El},
		46.952406, // lat0
		7.439583,  // long0
		1,
		fe, // fe
		fn) // fn

	cart := cartconvert.PolarToCartesian(gc)
	// According to literature, the Granit87 parameters shall not be used in favour of
	// higher accuracy of the following shift values

	// pt := cartconvert.HelmertLV03ToWGS84Granit87.Transform(&cartconvert.Point3D{X: cart.X, Y: cart.Y, Z: cart.Z})
	pt := &cartconvert.Point3D{X: cart.X + 674.374, Y: cart.Y + 15.056, Z: cart.Z + 405.346}

	return cartconvert.CartesianToPolar(&cartconvert.CartPoint{X: pt.X, Y: pt.Y, Z: pt.Z, El: cartconvert.GRS80Ellipsoid}), nil
}
Пример #2
0
// Transform a BMN coordinate value to a WGS84 based latitude and longitude coordinate. Function returns
// cartconvert.ErrRange, if the meridian stripe of the bmn-coordinate is not set
func BMNToWGS84LatLong(bmncoord *BMNCoord) (*cartconvert.PolarCoord, error) {

	var long0, fe float64

	switch bmncoord.Meridian {
	case BMNM28:
		long0 = 10.0 + 20.0/60.0
		fe = 150000
	case BMNM31:
		long0 = 13.0 + 20.0/60.0
		fe = 450000
	case BMNM34:
		long0 = 16.0 + 20.0/60.0
		fe = 750000
	default:
		return nil, cartconvert.ErrRange
	}

	gc := cartconvert.InverseTransverseMercator(
		&cartconvert.GeoPoint{Y: bmncoord.Height, X: bmncoord.Right, El: bmncoord.El},
		0,
		long0,
		1,
		fe,
		-5000000)

	cart := cartconvert.PolarToCartesian(gc)
	pt := cartconvert.HelmertWGS84ToMGI.InverseTransform(&cartconvert.Point3D{X: cart.X, Y: cart.Y, Z: cart.Z})

	return cartconvert.CartesianToPolar(&cartconvert.CartPoint{X: pt.X, Y: pt.Y, Z: pt.Z, El: cartconvert.WGS84Ellipsoid}), nil
}
Пример #3
0
// Transform a latitude / longitude coordinate datum into a BMN coordinate. Function returns
// cartconvert.ErrRange, if the meridian stripe of the bmn-coordinate is not set.
//
// Important: The reference ellipsoid of the originating coordinate system will be assumed
// to be the WGS84Ellipsoid and will be set thereupon, regardless of the actually set reference ellipsoid.
func WGS84LatLongToBMN(gc *cartconvert.PolarCoord, meridian BMNMeridian) (*BMNCoord, error) {

	var long0, fe float64

	// This sets the Ellipsoid to WGS84, regardless of the actual value set
	gc.El = cartconvert.WGS84Ellipsoid

	cart := cartconvert.PolarToCartesian(gc)
	pt := cartconvert.HelmertWGS84ToMGI.Transform(&cartconvert.Point3D{X: cart.X, Y: cart.Y, Z: cart.Z})
	polar := cartconvert.CartesianToPolar(&cartconvert.CartPoint{X: pt.X, Y: pt.Y, Z: pt.Z, El: cartconvert.Bessel1841MGIEllipsoid})

	// Determine meridian stripe based on longitude
	if meridian == BMNZoneDet {
		switch {
		case 11.0+0.5/6*10 >= polar.Longitude && polar.Longitude >= 8.0+0.5/6*10:
			meridian = BMNM28
		case 14.0+0.5/6*10 >= polar.Longitude && polar.Longitude >= 11.0+0.5/6*10:
			meridian = BMNM31
		case 17.0+0.5/6*10 >= polar.Longitude && polar.Longitude >= 14.0+0.5/6*10:
			meridian = BMNM34
		}
	}

	switch meridian {
	case BMNM28:
		long0 = 10.0 + 20.0/60.0
		fe = 150000
	case BMNM31:
		long0 = 13.0 + 20.0/60.0
		fe = 450000
	case BMNM34:
		long0 = 16.0 + 20.0/60.0
		fe = 750000
	default:
		return nil, cartconvert.ErrRange
	}

	gp := cartconvert.DirectTransverseMercator(
		polar,
		0,
		long0,
		1,
		fe,
		-5000000)

	return &BMNCoord{Meridian: meridian, Height: gp.Y, Right: gp.X, El: gp.El}, nil
}
Пример #4
0
// Convert an OSGB36 coordinate value to a WGS84 based latitude and longitude coordinate.
//
// Important: A OSGB36 datum like NN11 will be internally expanded to NN1500015000 to point to the middle of the zone.
// For the point at NN1000010000 it is necessary to fully qualify northing and easting.
//
// Plain grid zone specifiers will NOT be shifted towards the middle of the square.
func OSGB36ToWGS84LatLong(coord *OSGB36Coord) *cartconvert.PolarCoord {

	easting, northing := OSGB36ZoneToRefCoords(coord)

	gc := cartconvert.InverseTransverseMercator(
		&cartconvert.GeoPoint{Y: float64(northing), X: float64(easting), El: coord.El},
		49,
		-2,
		0.9996012717,
		400000,
		-100000)

	cart := cartconvert.PolarToCartesian(gc)
	pt := cartconvert.HelmertWGS84ToOSGB36.InverseTransform(&cartconvert.Point3D{X: cart.X, Y: cart.Y, Z: cart.Z})

	return cartconvert.CartesianToPolar(&cartconvert.CartPoint{X: pt.X, Y: pt.Y, Z: pt.Z, El: cartconvert.WGS84Ellipsoid})
}
Пример #5
0
// Transform a latitude / longitude coordinate datum into a OSGB36 coordinate.
//
// Important: The reference ellipsoid of the originating coordinate system will be assumed
// to be the WGS84Ellipsoid and will be set thereupon, regardless of the actually set reference ellipsoid.
func WGS84LatLongToOSGB36(gc *cartconvert.PolarCoord) (*OSGB36Coord, error) {
	// This sets the Ellipsoid to WGS84, regardless of the actual value set
	gc.El = cartconvert.WGS84Ellipsoid

	cart := cartconvert.PolarToCartesian(gc)
	pt := cartconvert.HelmertWGS84ToOSGB36.Transform(&cartconvert.Point3D{X: cart.X, Y: cart.Y, Z: cart.Z})
	polar := cartconvert.CartesianToPolar(&cartconvert.CartPoint{X: pt.X, Y: pt.Y, Z: pt.Z, El: cartconvert.Airy1830Ellipsoid})

	gp := cartconvert.DirectTransverseMercator(
		polar,
		49,
		-2,
		0.9996012717,
		400000,
		-100000)

	return GridRefNumToLet(uint(gp.X+0.5), uint(gp.Y+0.5), 0, OSGB36_Max)
}
Пример #6
0
// Transform a latitude / longitude coordinate datum into a Swiss coordinate. Function returns
// cartconvert.ErrRange, if the coordinate type is not set.
//
// Important: The reference ellipsoid of the originating coordinate system will be assumed
// to be the GRS80Ellipsoid and will be set thereupon, regardless of the actually set reference ellipsoid.
func GRS80LatLongToSwissCoord(gc *cartconvert.PolarCoord, coordType SwissCoordType) (*SwissCoord, error) {

	var fn, fe float64

	// This sets the Ellipsoid to GRS80, regardless of the actual value set
	gc.El = cartconvert.GRS80Ellipsoid

	cart := cartconvert.PolarToCartesian(gc)
	// According to literature, the Granit87 parameters shall not be used in favour of
	// higher accuracy of the following shift values

	// pt := cartconvert.HelmertWGS84ToMGI.Transform(&cartconvert.Point3D{X: cart.X, Y: cart.Y, Z: cart.Z})
	pt := &cartconvert.Point3D{X: cart.X - 674.374, Y: cart.Y - 15.056, Z: cart.Z - 405.346}
	polar := cartconvert.CartesianToPolar(&cartconvert.CartPoint{X: pt.X, Y: pt.Y, Z: pt.Z, El: cartconvert.Bessel1841Ellipsoid})

	switch coordType {
	case LV03:
		fe = 600000
		fn = 200000
	case LV95:
		fe = -2600000
		fn = -1200000
	default:
		return nil, cartconvert.ErrRange
	}

	gp := cartconvert.DirectTransverseMercator(
		polar,
		46.952406, // lat0
		7.439583,  // long0
		1,
		fe, // fe
		fn) // fn

	return &SwissCoord{CoordType: coordType, Northing: gp.Y, Easting: gp.X, El: gp.El}, nil
}