Skip to content

Commit

Permalink
Added ability to Query if SRID is available
Browse files Browse the repository at this point in the history
Cleaned up a bit
Added Availableconversions and IsKnownConversionSRID
to enable ability to check if an SRID is usable with
proj for conversion.
  • Loading branch information
gdey committed Dec 31, 2024
1 parent 03c4dd9 commit 9b3b9b3
Show file tree
Hide file tree
Showing 9 changed files with 261 additions and 144 deletions.
44 changes: 36 additions & 8 deletions Convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ const (
WGS84 = EPSG4326
)

// ensure only one person is updating our cache of converters at a time
var cacheLock = sync.Mutex{}

// Convert performs a conversion from a 4326 coordinate system (lon/lat
// degrees, 2D) to the given projected system (x/y meters, 2D).
//
Expand Down Expand Up @@ -80,7 +77,9 @@ func Inverse(src EPSGCode, input []float64) ([]float64, error) {
// CustomProjection provides write-only access to the internal projection list
// so that projections may be added without having to modify the library code.
func CustomProjection(code EPSGCode, str string) {
projStringLock.Lock()
projStrings[code] = str
projStringLock.Unlock()
}

//---------------------------------------------------------------------------
Expand All @@ -94,19 +93,48 @@ type conversion struct {
converter core.IConvertLPToXY
}

var conversions = map[EPSGCode]*conversion{}
var (
// cacheLock ensure only one person is updating our cache of converters at a time
cacheLock = sync.Mutex{}
conversions = map[EPSGCode]*conversion{}

projStringLock = sync.RWMutex{}
projStrings = map[EPSGCode]string{
EPSG3395: "+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84", // TODO: support +units=m +no_defs
EPSG3857: "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0", // TODO: support +units=m +nadgrids=@null +wktext +no_defs
EPSG4087: "+proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84", // TODO: support +units=m +no_defs
}
)

// AvailableConversions returns a list of conversion that the system knows about
func AvailableConversions() (ret []EPSGCode) {
projStringLock.RLock()
defer projStringLock.RUnlock()
if len(projStrings) == 0 {
return nil
}
ret = make([]EPSGCode, 0, len(projStrings))
for k := range projStrings {
ret = append(ret, k)
}
return ret
}

var projStrings = map[EPSGCode]string{
EPSG3395: "+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84", // TODO: support +units=m +no_defs
EPSG3857: "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0", // TODO: support +units=m +nadgrids=@null +wktext +no_defs
EPSG4087: "+proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84", // TODO: support +units=m +no_defs
// IsKnownConversionSRID returns if we know about the conversion
func IsKnownConversionSRID(srid EPSGCode) bool {
projStringLock.RLock()
defer projStringLock.RUnlock()
_, ok := projStrings[srid]
return ok
}

// newConversion creates a conversion object for the destination systems. If
// such a conversion already exists in the cache, use that.
func newConversion(dest EPSGCode) (*conversion, error) {

projStringLock.RLock()
str, ok := projStrings[dest]
projStringLock.RUnlock()
if !ok {
return nil, fmt.Errorf("epsg code is not a supported projection")
}
Expand Down
12 changes: 6 additions & 6 deletions cmd/proj/proj.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ func Main(inS io.Reader, outS io.Writer, args []string) error {

// unverbosify all the things
merror.ShowSource = false
mlog.DebugEnabled = false
mlog.InfoEnabled = false
mlog.ErrorEnabled = false
mlog.DisableDebug()
mlog.DisableInfo()
mlog.DisableError()

cli := flag.NewFlagSet(args[0], flag.ContinueOnError)
cli.SetOutput(outS)
Expand Down Expand Up @@ -67,9 +67,9 @@ func Main(inS io.Reader, outS io.Writer, args []string) error {
}

merror.ShowSource = true
mlog.DebugEnabled = true
mlog.InfoEnabled = true
mlog.ErrorEnabled = true
mlog.EnableDebug()
mlog.EnableInfo()
mlog.EnableError()
}

// handle "-epsg" usage, using the Convert API
Expand Down
32 changes: 17 additions & 15 deletions core/ConvertLPToXY.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,27 +243,29 @@ func (op *ConvertLPToXY) inverseFinalize(coo *CoordLP) (*CoordLP, error) {

sys := op.System

if sys.Left == IOUnitsAngular {

if sys.Right != IOUnitsAngular {
/* Distance from central meridian, taking system zero meridian into account */
coo.Lam = coo.Lam + sys.FromGreenwich + sys.Lam0
// if left is not in radians return the value as is.
if sys.Left != IOUnitsAngular {
return coo, nil
}

/* adjust longitude to central meridian */
if !sys.Over {
coo.Lam = support.Adjlon(coo.Lam)
}
if sys.Right != IOUnitsAngular {
/* Distance from central meridian, taking system zero meridian into account */
coo.Lam = coo.Lam + sys.FromGreenwich + sys.Lam0

if coo.Lam == math.MaxFloat64 {
return coo, nil
}
/* adjust longitude to central meridian */
if !sys.Over {
coo.Lam = support.Adjlon(coo.Lam)
}

/* If input latitude was geocentrical, convert back to geocentrical */
if sys.Geoc {
coo = GeocentricLatitude(sys, DirectionForward, coo)
if coo.Lam == math.MaxFloat64 {
return coo, nil
}
}

/* If input latitude was geocentrical, convert back to geocentrical */
if sys.Geoc {
coo = GeocentricLatitude(sys, DirectionForward, coo)
}

return coo, nil
}
6 changes: 4 additions & 2 deletions core/OperationDescription.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
package core

import (
"fmt"

"github.com/go-spatial/proj/merror"
)

Expand Down Expand Up @@ -58,7 +60,7 @@ func RegisterConvertLPToXY(

_, ok := OperationDescriptionTable[id]
if ok {
panic(99)
panic(fmt.Sprintf("duplicate operation description id '%s' : %s", id, description))
}
OperationDescriptionTable[id] = pi
}
Expand All @@ -73,7 +75,7 @@ func (desc *OperationDescription) CreateOperation(sys *System) (IOperation, erro
return nil, merror.New(merror.NotYetSupported)
}

// IsConvertLPToXY returns true iff the operation can be casted to an IConvertLPToXY
// IsConvertLPToXY returns true iff the operation can be cast to an IConvertLPToXY
func (desc *OperationDescription) IsConvertLPToXY() bool {
return desc.OperationType == OperationTypeConversion &&
desc.InputType == CoordTypeLP &&
Expand Down
7 changes: 3 additions & 4 deletions core/OperationDescription_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ import (
"testing"

"github.com/go-spatial/proj/core"

"github.com/stretchr/testify/assert"
)

func TestOperationDescription(t *testing.T) {
assert := assert.New(t)

opDesc := core.OperationDescriptionTable["utm"]
assert.NotNil(opDesc)
if opDesc == nil {
t.Errorf("operaton description table for utm is nil")
}
}
20 changes: 10 additions & 10 deletions core/System.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ type DatumType int
// All the DatumType constants (taken directly from the C)
const (
DatumTypeUnknown DatumType = 0
DatumType3Param = 1
DatumType7Param = 2
DatumTypeGridShift = 3
DatumTypeWGS84 = 4 /* WGS84 (or anything considered equivalent) */
DatumType3Param DatumType = 1
DatumType7Param DatumType = 2
DatumTypeGridShift DatumType = 3
DatumTypeWGS84 DatumType = 4 /* WGS84 (or anything considered equivalent) */
)

// IOUnitsType is the enum for the types of input/output units we support
Expand All @@ -35,10 +35,10 @@ type IOUnitsType int
// All the IOUnitsType constants
const (
IOUnitsWhatever IOUnitsType = 0 /* Doesn't matter (or depends on pipeline neighbours) */
IOUnitsClassic = 1 /* Scaled meters (right), projected system */
IOUnitsProjected = 2 /* Meters, projected system */
IOUnitsCartesian = 3 /* Meters, 3D cartesian system */
IOUnitsAngular = 4 /* Radians */
IOUnitsClassic IOUnitsType = 1 /* Scaled meters (right), projected system */
IOUnitsProjected IOUnitsType = 2 /* Meters, projected system */
IOUnitsCartesian IOUnitsType = 3 /* Meters, 3D cartesian system */
IOUnitsAngular IOUnitsType = 4 /* Radians */
)

// DirectionType is the enum for the operation's direction
Expand All @@ -47,8 +47,8 @@ type DirectionType int
// All the DirectionType constants
const (
DirectionForward DirectionType = 1 /* Forward */
DirectionIdentity = 0 /* Do nothing */
DirectionInverse = -1 /* Inverse */
DirectionIdentity DirectionType = 0 /* Do nothing */
DirectionInverse DirectionType = -1 /* Inverse */
)

const epsLat = 1.0e-12
Expand Down
Loading

0 comments on commit 9b3b9b3

Please sign in to comment.