Est-il possible d'obtenir la valeur EPSG à partir d'une classe OSR SpatialReference à l'aide de l'API OGR Python?

21

Lors de la lecture d'une couche à partir d'une connexion OGR PostGIS, je peux obtenir la référence spatiale de la couche, mais est-il possible d'obtenir la valeur EPSG? Existe-t-il une documentation à ce sujet?

Par exemple:

lyr = conn.GetLayerByName(tbl) # Where conn is OGR PG connection
srs = ly.GetSpatialRef()
print srs

Retour:

PROJCS["OSGB 1936 / British National Grid",
GEOGCS["OSGB 1936",
    DATUM["OSGB_1936",
        SPHEROID["Airy 1830",6377563.396,299.3249646,
            AUTHORITY["EPSG","7001"]],
        AUTHORITY["EPSG","6277"]],
    PRIMEM["Greenwich",0,
        AUTHORITY["EPSG","8901"]],
    UNIT["degree",0.01745329251994328,
        AUTHORITY["EPSG","9122"]],
    AUTHORITY["EPSG","4277"]],
UNIT["metre",1,
    AUTHORITY["EPSG","9001"]],
PROJECTION["Transverse_Mercator"],
PARAMETER["latitude_of_origin",49],
PARAMETER["central_meridian",-2],
PARAMETER["scale_factor",0.9996012717],
PARAMETER["false_easting",400000],
PARAMETER["false_northing",-100000],
AUTHORITY["EPSG","27700"],
AXIS["Easting",EAST],
AXIS["Northing",NORTH]]

Alors, comment puis-je obtenir la valeur EPSG pour la projection? Par exemple:

srs.GetEPSG()
print srs
27700

J'ai essayé srs.GetAttrValue('AUTHORITY'), mais cela revient juste 'EPSG'.

Tomas
la source
I've tried srs.GetAttrValue('AUTHORITY'), but this just returns 'EPSG'qui est correct. EPSG est l'autorité
nmtoken

Réponses:

30

C'est un peu enterré, mais il y a un deuxième paramètre à GetAttrValue () qui renvoie la valeur à cet ordinal. Je peux donc faire:

In [1]: import osgeo.osr as osr

In [2]: srs = osr.SpatialReference()

In [3]: srs.SetFromUserInput("EPSG:27700")
Out[3]: 0

In [4]: print srs
PROJCS["OSGB 1936 / British National Grid",
    GEOGCS["OSGB 1936",
        DATUM["OSGB_1936",
            SPHEROID["Airy 1830",6377563.396,299.3249646,
                AUTHORITY["EPSG","7001"]],
            TOWGS84[375,-111,431,0,0,0,0],
            AUTHORITY["EPSG","6277"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4277"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",49],
    PARAMETER["central_meridian",-2],
    PARAMETER["scale_factor",0.9996012717],
    PARAMETER["false_easting",400000],
    PARAMETER["false_northing",-100000],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    AXIS["Easting",EAST],
    AXIS["Northing",NORTH],
    AUTHORITY["EPSG","27700"]]

In [5]: srs.GetAttrValue("AUTHORITY", 0)
Out[5]: 'EPSG'

In [6]: srs.GetAttrValue("AUTHORITY", 1)
Out[6]: '27700'

Après un peu de jeu, j'ai trouvé que vous pouvez obtenir la valeur de n'importe quel paramètre en utilisant un tuyau |comme séparateur de chemin:

In [12]: srs.GetAttrValue("PRIMEM|AUTHORITY", 1)
Out[12]: '8901'

Qui peut être utile pour trouver le système de coordonnées géographiques d'un CS projeté:

In [13]: srs.GetAttrValue("PROJCS|GEOGCS|AUTHORITY", 1)
Out[13]: '4277'
MerseyViking
la source
1
Merci, c'est super. Je vais le mettre en œuvre. J'avais manqué de temps pour continuer à «jouer» - le développement rapide des applications étant freiné par le manque de documentation GDAL / OGR encore une fois!
Tomas
J'ai essayé la fonction GetAttrValue avec les arguments "AUTHORITY" et "1" et j'ai remarqué qu'elle ne renvoyait pas toujours le code EPSG car le code EPSG n'est pas toujours inclus dans le WKT. Je suis encore un peu flou sur la raison pour laquelle c'est le cas. J'ai trouvé que la solution suivante fonctionnait bien pour mes besoins: gis.stackexchange.com/questions/7608/…
Burrow
5

Voici un extrait de code qui a fonctionné pour moi:

def wkt2epsg(wkt, epsg='/usr/local/share/proj/epsg', forceProj4=False):
''' Transform a WKT string to an EPSG code

Arguments
---------

wkt: WKT definition
epsg: the proj.4 epsg file (defaults to '/usr/local/share/proj/epsg')
forceProj4: whether to perform brute force proj4 epsg file check (last resort)

Returns: EPSG code

'''
code = None
p_in = osr.SpatialReference()
s = p_in.ImportFromWkt(wkt)
if s == 5:  # invalid WKT
    return None
if p_in.IsLocal() == 1:  # this is a local definition
    return p_in.ExportToWkt()
if p_in.IsGeographic() == 1:  # this is a geographic srs
    cstype = 'GEOGCS'
else:  # this is a projected srs
    cstype = 'PROJCS'
an = p_in.GetAuthorityName(cstype)
ac = p_in.GetAuthorityCode(cstype)
if an is not None and ac is not None:  # return the EPSG code
    return '%s:%s' % \
        (p_in.GetAuthorityName(cstype), p_in.GetAuthorityCode(cstype))
else:  # try brute force approach by grokking proj epsg definition file
    p_out = p_in.ExportToProj4()
    if p_out:
        if forceProj4 is True:
            return p_out
        f = open(epsg)
        for line in f:
            if line.find(p_out) != -1:
                m = re.search('<(\\d+)>', line)
                if m:
                    code = m.group(1)
                    break
        if code:  # match
            return 'EPSG:%s' % code
        else:  # no match
            return None
    else:
        return None
tomkralidis
la source
0

SpatialReference.GetAuthorityCode() prend None comme paramètre, qui trouve un nœud d'autorité sur l'élément racine (c'est-à-dire projeté / géographique selon le cas). Il en va de même pour GetAuthorityName():

In [1]: import osgeo.osr as osr

In [2]: srs = osr.SpatialReference()

In [3]: srs.SetFromUserInput("EPSG:27700")
Out[3]: 0

In [4]: srs.GetAuthorityCode(None)
Out[4]: '27700'

In [5]: srs.GetAuthorityCode(None)
Out[5]: 'EPSG'
rcoup
la source