예제 #1
0
파일: bmn.go 프로젝트: hailocab/cartconvert
// 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
}
예제 #2
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)
}
예제 #3
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
}
예제 #4
0
func main() {

	var ofcmdlinespec, ifcmdlinespec string
	var of displayformat
	var ifm inputformat
	var lines uint
	var instring, outstring, ofparamvalues, ifparamvalues string
	var pc *cartconvert.PolarCoord

	for key, _ := range ofOptions {
		ofparamvalues += fmt.Sprintf(" %s ", key)
	}

	for key, _ := range ifOptions {
		ifparamvalues += fmt.Sprintf(" %s ", key)
	}

	flag.StringVar(&ofcmdlinespec, "of", "deg", "specify output format. Possible values are: "+ofparamvalues)
	flag.StringVar(&ifcmdlinespec, "if", "osgb36", "specify input format. Possible values are: "+ifparamvalues)
	flag.Parse()

	of = ofOptions[strings.ToLower(ofcmdlinespec)]
	ifm = ifOptions[strings.ToLower(ifcmdlinespec)]

	reader := bufio.NewReaderSize(os.Stdin, 100)
	longline := false

	for data, prefix, err := reader.ReadLine(); err != io.EOF; data, prefix, err = reader.ReadLine() {
		if err != nil {
			fmt.Fprintf(os.Stderr, "conv %d: %s\n", lines, err)
			continue
		}

		if prefix {
			longline = true
			continue
		}

		if longline {
			longline = false
			continue
		}

		lines++

		instring = strings.TrimSpace(string(data))

		if len(instring) == 0 {
			continue
		}

		switch ifm {
		case ifbmn:

			bmncoord, err := bmn.ABMNToStruct(instring)

			if err != nil {
				fmt.Fprintf(os.Stderr, "BMN: error on line %d: %s\n", lines, err)
				continue
			}
			pc, err = bmn.BMNToWGS84LatLong(bmncoord)

			if err != nil {
				fmt.Fprintf(os.Stderr, "BMN: error on line %d: %s (BMN does not return a lat/long bearing)\n", lines, err)
				continue
			}
		case ifosgb36:
			osgb36coord, err := osgb36.AOSGB36ToStruct(instring, osgb36.OSGB36Auto)

			if err != nil {
				fmt.Fprintf(os.Stderr, "OSGB36: error on line %d: %s\n", lines, err)
				continue
			}
			pc = osgb36.OSGB36ToWGS84LatLong(osgb36coord)
		}

		switch of {
		case ofdeg:
			lat, long := cartconvert.LatLongToString(pc, cartconvert.LLFdeg)
			outstring = lat + ", " + long
		case ofdms:
			outstring = pc.String()
		case ofutm:
			outstring = cartconvert.LatLongToUTM(pc).String()
		case ofgeohash:
			outstring = cartconvert.LatLongToGeoHash(pc)
		default:
			fmt.Fprintln(os.Stderr, "Unrecognized output specifier")
			flag.Usage()
			fmt.Fprintf(os.Stderr, "possible values are: [%s]\n", ofparamvalues)
			fmt.Fprintln(os.Stderr, "]")
			os.Exit(2)
		}
		fmt.Fprintf(os.Stdout, "%s\n", outstring)
	}
}
예제 #5
0
// serialize gets called by the respective handler methods to perform the serialization in the requested output representation
func serialize(latlong *cartconvert.PolarCoord, oformat string) (interface{}, error) {
	var serializestruct interface{}
	var err error

	switch oformat {
	case OFlatlongdeg:
		lat, long := cartconvert.LatLongToString(latlong, cartconvert.LLFdms)
		serializestruct = &LatLong{Lat: lat, Long: long, Fmt: cartconvert.LLFdms.String(), LatLongString: latlong.String()}
	case OFlatlongcomma:
		lat, long := cartconvert.LatLongToString(latlong, cartconvert.LLFdeg)
		serializestruct = &LatLong{Lat: lat, Long: long, Fmt: cartconvert.LLFdeg.String(), LatLongString: latlong.String()}
	case OFgeohash:
		serializestruct = &GeoHash{GeoHash: cartconvert.LatLongToGeoHash(latlong)}
	case OFUTM:
		utm := cartconvert.LatLongToUTM(latlong)
		serializestruct = &UTMCoord{UTMCoord: utm, UTMString: utm.String()}
	case OFBMN:
		var bmnval *bmn.BMNCoord
		bmnval, err = bmn.WGS84LatLongToBMN(latlong, bmn.BMNZoneDet)
		if err == nil {
			serializestruct = &BMN{BMNCoord: bmnval, BMNString: bmnval.String()}
		}
	case OFOSGB:
		var osgb36val *osgb36.OSGB36Coord
		osgb36val, err = osgb36.WGS84LatLongToOSGB36(latlong)
		if err == nil {
			serializestruct = &OSGB36{OSGB36Coord: osgb36val, OSGB36String: osgb36val.String()}
		}
	default:
		err = fmt.Errorf("Unsupported output format: '%s'", oformat)
	}
	return serializestruct, err
}