Verificando se duas classes de recursos têm a mesma referência espacial usando o ArcPy?

9

Usando o arcpy, como você verifica se duas classes de recursos têm a mesma referência espacial?

Apenas verificar se os dois são iguais não funciona:

>>> import arcpy
>>> fc1 = r"C:\Users\e1b8\Desktop\E1B8\GIS_Stackexchange\data.gdb\test"
>>> sr1 = arcpy.Describe (fc1).spatialReference 
>>> sr2 = arcpy.Describe (fc1).spatialReference
>>> sr1 == sr2
False

factoryCode não funciona, porque as projeções personalizadas não as possuem.

>>> fc2 = r"C:\Users\e1b8\Desktop\E1B8\GIS_Stackexchange\data.gdb\customproj"
>>> sr2 = arcpy.Describe (fc2).spatialReference
>>> sr2.factoryCode
0

name, mas os nomes podem ser os mesmos, mas têm unidades diferentes:

>>> sr1 = arcpy.Describe (fc1).spatialReference
>>> sr2 = arcpy.Describe (fc2).spatialReference
>>> sr1.name
u'NAD_1983_UTM_Zone_10N'
>>> sr2.name
u'NAD_1983_UTM_Zone_10N'
>>> sr1.linearUnitCode
9003
>>> sr2.linearUnitCode
9001

Então fica um pouco complicado. O melhor que eu criei é:

>>> def CompareSRs (inFc1, inFc2):
    sr1 = arcpy.Describe (inFc1).spatialReference
    sr2 = arcpy.Describe (inFc2).spatialReference
    if not sr1.name != sr2.name:
        return False
    srType = sr1.type
    if srType != sr2.type:
        return False
    if srType == "Geographic":
        return sr1.angularUnitCode == sr2.angularUnitCode
    return sr1.linearUnitCode == sr2.linearUnitCode

E ainda não tenho certeza de que o código acima é hermético. Existe uma maneira melhor?

Emil Brundage
fonte
1
Isso pode ser útil: gis.stackexchange.com/q/50312/8104
Aaron
Ah, sim, exportToString ()que retorna uma sequência do WKT da referência espacial, pode ser o ticket.
Emil Brundage

Respostas:

13

A julgar pelos comentários, você já deve tê-lo :)

Você pode comparar as descrições de texto conhecido (WKT) das referências espaciais.

sr1 = arcpy.Describe(dataset1).spatialReference
sr2 = arcpy.Describe(dataset2).spatialReference
sr1String = sr1.exportToString()
sr2String = sr2.exportToString()

matching = False

if sr1String == sr2String:
    # Exact string match
    matching = True
else:
    # difference
    pass
Paulo Raposo
fonte
1

Versão do arco: 10.3

Caso alguém ainda encontre isso em 2019 , tive problemas semelhantes e queria ter a maior certeza possível sobre se as projeções correspondiam. Como nas perguntas / respostas acima, você pode obter a referência espacial usando arcpy.Describe(dataset).spatialReference. Em uma biblioteca de funções minha, integro isso a um fluxo de trabalho, configurado para lidar com a comparação de 2 conjuntos de dados.

Os atributos individuais de um objeto de referência espacial de geoprocessamento estão disponíveis aqui .

As seguintes funções devem ajudar - fique à vontade para usar / modificar, é claro. Vale a pena verificar o que é omitido - alguns atributos dos sistemas de referência espacial serão inofensivos se não corresponderem, mas isso depende de você :)

import arcpy


def check_crs(dataset):
    """Return a coordinate reference system string

    Get coordinate reference system of dataset
    """
    crs = arcpy.Describe(dataset).spatialReference
    return(crs)

def assert_crs_attribs(dataset1, dataset2, strict=False): 
    """Returns Nothing

    Asserts equality of all attributes of the provided geoprocessing spatial reference objects.
    These are generated using arcpy.Describe(your_dataset).spatialReference.
    Attributes of spatial reference object: https://pro.arcgis.com/en/pro-app/arcpy/classes/spatialreference.htm

    dataset1 - a spatial dataset with projection info e.g. shp
    dataset2 - a spatial dataset with projection info e.g. shp
    strict - boolean - if True will compare every element (default: False)
    """
    crs1=check_crs(dataset1)
    crs2=check_crs(dataset2)

    try:
        # Consider these
        assert(crs1.name==crs2.name) # The name of the spatial reference.
        assert(crs1.PCSCode==crs2.PCSCode) # The projected coordinate system code.1 
        assert(crs1.PCSName==crs2.PCSName) # The projected coordinate system name.1 
        assert(crs1.azimuth==crs2.azimuth) # The azimuth of a projected coordinate system.1 
        assert(crs1.centralMeridian==crs2.centralMeridian) # The central meridian of a projected coordinate system.1    
        assert(crs1.centralMeridianInDegrees==crs2.centralMeridianInDegrees) # The central meridian (Lambda0) of a projected coordinate system in degrees.1 
        assert(crs1.centralParallel==crs2.centralParallel) # The central parallel of a projected coordinate system.1
        assert(crs1.falseEasting==crs2.falseEasting) # The false easting of a projected coordinate system.1 
        assert(crs1.falseNorthing==crs2.falseNorthing) # The false northing of a projected coordinate system.1  
        assert(crs1.MFalseOriginAndUnits==crs2.MFalseOriginAndUnits) # The measure false origin and units.
        assert(crs1.MResolution==crs2.MResolution) # The measure resolution.
        assert(crs1.MTolerance==crs2.MTolerance) # The measure tolerance.
        assert(crs1.XYTolerance==crs2.XYTolerance) # The xy tolerance.
        assert(crs1.ZDomain==crs2.ZDomain) # The extent of the z domain.
        assert(crs1.ZFalseOriginAndUnits==crs2.ZFalseOriginAndUnits) # The z false origin and units.
        assert(crs1.factoryCode==crs2.factoryCode) # The factory code or well-known ID (WKID) of the spatial reference.
        assert(crs1.isHighPrecision==crs2.isHighPrecision) # Indicates whether the spatial reference has high precision set.
        assert(crs1.latitudeOf1st==crs2.latitudeOf1st) # The latitude of the first point of a projected coordinate system.1
        assert(crs1.latitudeOf2nd==crs2.latitudeOf2nd) # The latitude of the second point of a projected coordinate system.1    
        assert(crs1.latitudeOfOrigin==crs2.latitudeOfOrigin) # The latitude of origin of a projected coordinate system.1    
        assert(crs1.linearUnitCode==crs2.linearUnitCode) # The linear unit code.    
        assert(crs1.linearUnitName==crs2.linearUnitName) # The linear unit name.1
        assert(crs1.longitude==crs2.longitude) # The longitude value of this prime meridian.1
        assert(crs1.longitudeOf1st==crs2.longitudeOf1st) #The longitude of the first point of a projected coordinate system.1
        assert(crs1.longitudeOf2nd==crs2.longitudeOf2nd) # The longitude of the second point of a projected coordinate system.1
        assert(crs1.longitudeOfOrigin==crs2.longitudeOfOrigin) # The longitude of origin of a projected coordinate system.1
        assert(crs1.metersPerUnit==crs2.metersPerUnit) # The meters per linear unit.1
        assert(crs1.projectionCode==crs2.projectionCode) # The projection code.1
        assert(crs1.projectionName==crs2.projectionName) # The projection name.1
        assert(crs1.scaleFactor==crs2.scaleFactor) # The scale factor of a projected coordinate system.1
        assert(crs1.standardParallel1==crs2.standardParallel1) # The first parallel of a projected coordinate system.1
        assert(crs1.standardParallel2==crs2.standardParallel2) # The second parallel of a projected coordinate system.1
        assert(crs1.angularUnitCode==crs2.angularUnitCode) # The angular unit code.2
        assert(crs1.angularUnitName==crs2.angularUnitName) # The angular unit name.2
        assert(crs1.datumCode==crs2.datumCode) # The datum code.2
        assert(crs1.datumName==crs2.datumName) # The datum name.2
        assert(crs1.flattening==crs2.flattening) # The flattening ratio of this spheroid.2
        assert(crs1.longitude==crs2.longitude) # The longitude value of this prime meridian.2
        assert(crs1.primeMeridianCode==crs2.primeMeridianCode) # The prime meridian code.2

        ## Prob can be ignored
        if strict:
            assert(crs1.ZResolution==crs2.ZResolution) # The z resolution property.
            assert(crs1.ZTolerance==crs2.ZTolerance) # The z-tolerance property.
            assert(crs1.hasMPrecision==crs2.hasMPrecision) # Indicates whether m-value precision information has been defined.
            assert(crs1.hasXYPrecision==crs2.hasXYPrecision) # Indicates whether xy precision information has been defined.
            assert(crs1.hasZPrecision==crs2.hasZPrecision) # Indicates whether z-value precision information has been defined.
            assert(crs1.XYResolution==crs2.XYResolution) # The xy resolution.
            assert(crs1.domain==crs2.domain) # The extent of the xy domain.
            assert(crs1.MDomain==crs2.MDomain) # The extent of the measure domain.
            assert(crs1.remarks==crs2.remarks) # The comment string of the spatial reference.
            assert(crs1.type==crs2.type) # The type of the spatial reference. Geographic: A geographic coordinate system. Projected: A projected coordinate system.
            assert(crs1.usage==crs2.usage) # The usage notes.   
            assert(crs1.classification==crs2.classification) # The classification of a map projection.1 
            assert(crs1.GCSCode==crs2.GCSCode) # The geographic coordinate system code.2
            assert(crs1.GCSName==crs2.GCSName) # The geographic coordinate system name.2
            assert(crs1.primeMeridianName==crs2.primeMeridianName) # The prime meridian name.2
            assert(crs1.radiansPerUnit==crs2.radiansPerUnit) # The radians per angular unit.2
            assert(crs1.semiMajorAxis==crs2.semiMajorAxis) # The semi-major axis length of this spheroid.2
            assert(crs1.semiMinorAxis==crs2.semiMinorAxis) # The semi-minor axis length of this spheroid.2
            assert(crs1.spheroidCode==crs2.spheroidCode) # The spheroid code.2
            assert(crs1.spheroidName==crs2.spheroidName) # The spheroid name.2
        return(True)
    except:
        output_message="CRS differs between datasets."#\ncrs1: %s\ncrs2 : %s" %(crs1.exportToString(), crs2.exportToString())
        print(output_message)
        return(False)
    ## Differs to the falseEasting and falseNorthingUnits are odd on occasion but false eastings and northings make sense
    # crs.falseOriginAndUnits # The false origin and units.

    ## Not required
    #crs.GCS # A projected coordinate system returns a SpatialReference object for the geographic coordinate system it is based on. A geographic crs.coordinate system returns the same SpatialReference.
    #crs.SpatialReference
    #crs.VCS # If the coordinate system has a vertical coordinate system, it returns a VCS object for the vertical coordinate system it is based on.
    #crs.abbreviation # The abbreviated name of the spatial reference.
    #crs.alias # The alias of the spatial reference.

Dado o exposto, você pode usá-los como:

dataset1="your_vector_1.shp"
dataset2="your_vector_2.shp"

assert_crs_attribs(dataset1, dataset2)

Dado o seu caso de uso, espero que as declarações não falhem.

Agora integro essas funções em muitos processos, como onde tenho uma variedade de conjuntos de dados espaciais nos quais estou ingressando e quero eliminar qualquer dúvida de que as coisas estavam desalinhadas.

ChrisWills
fonte