Obtendo latitude e longitude do ponto projetado usando o ArcPy? [fechadas]

13

Eu tenho um recurso de ponto em uma classe de recurso que está sendo acessada pelo ArcPy. O ponto é projetado, mas preciso encontrar um meio eficiente de obter a latitude e longitude não projetadas para esse ponto.

Existe um método diferente de reprojetar (desprojetar), obter um cursor de pesquisa na nova classe de recurso, localizar o recurso e remover o lat / lon da forma do recurso?

Kenton W
fonte

Respostas:

6

O SearchCursor suporta a especificação de uma referência espacial; nesse caso, você deseja um sistema de coordenadas geográficas, como o WGS 1984. Em seguida, você percorre o cursor e pega x & y na forma, veja aqui .

James
fonte
6

A maioria das outras respostas foi publicada quando o ArcGIS 10.0 foi o software mais recente. No ArcGIS 10.1, muitas novas funcionalidades do ArcPy se tornaram disponíveis. Esta resposta tira proveito dessa nova funcionalidade. Não será adequado para 10.0, mas oferece desempenho e funcionalidade aprimorados para 10.1 e posterior.

import arcpy

input_feature_class = 'C:\your_feature_class.shp'
wkid = 4326 # wkid code for wgs84
spatial_reference = arcpy.SpatialReference(wkid)

fields_to_work_with = ['SHAPE@']

with arcpy.da.SearchCursor(input_feature_class,
                           fields_to_work_with) as s_cur:
    for row in s_cur:
        point_in_wgs84 = row[0].projectAs(spatial_reference)
        print point_in_wgs84.firstPoint.X, point_in_wgs84.firstPoint.Y

Esse trecho de código usa o wkid para criar um objeto de referência espacial em vez de digitar uma representação de seqüência de caracteres, usa os cursores de acesso a dados mais modernos e projeta os objetos de geometria individuais usando o método projectAs () .

GeoSharp
fonte
boa resposta. Gostaria apenas de sugerir a mudar X e Y na impressão, porque em WGS84 a ordem comum é latitude / longitude
radouxju
ainda mais simples, faça isso. srs = arcpy.SpatialReference (4326) xy_coords = arcpy.da.FeatureClassToNumPyArray (input_feature_class, 'SHAPE @ XY', spatial_reference = srs) print (xy_coords)
dfresh22
5

Para elaborar a sugestão de James, aqui está um exemplo de código mínimo usando Python / arcpy:

import arcpy

def main():
    projectedPointFC = r'c:\point_test.shp'
    desc = arcpy.Describe(projectedPointFC)
    shapefieldname = desc.ShapeFieldName

    rows = arcpy.SearchCursor(projectedPointFC, r'', \
                              r'GEOGCS["GCS_WGS_1984",' + \
                              'DATUM["D_WGS_1984",' + \
                              'SPHEROID["WGS_1984",6378137,298.257223563]],' + \
                              'PRIMEM["Greenwich",0],' + \
                              'UNIT["Degree",0.017453292519943295]]')

    for row in rows:
        feat = row.getValue(shapefieldname)
        pnt = feat.getPart()
        print pnt.X, pnt.Y

if __name__ == '__main__':
    main()
Allan Adair
fonte
4

Quer você chame de projeção ou não, tenho certeza de que, por definição, quando você está traduzindo os valores de coordenadas de um sistema de referência espacial para outro, você está / não está projetando.

Eu não estou tão familiarizado com o ArcPy, mas no arcgisscripting na 9.3, você teria que projetar toda a classe de recursos.

Dependendo da complexidade de um algoritmo de projeção / transormação que você precisa, você sempre pode rolar sua própria projeção para as coordenadas na matemática básica de python. Isso permitiria coordenar a projeção de valor no nível do recurso.

Se você estava aberto para usar as ligações python OGR, é possível projetar no nível do recurso em algo como um 'cursor de pesquisa'.

DavidF
fonte
Infelizmente, não posso usar coisas não ESRI com o script que estou usando. Mesmo que ainda ESRI usa OGR e GDAL (não conte a ninguém, certo?) ...
Kenton W
Na verdade, a melhor rota pode ser descobrir como usar o PROJ4 diretamente nas coordenadas de entrada de alguma forma.
Kenton W
@ Kenton - Isso também inclui seu próprio algoritmo personalizado (com base no código existente)? Se você precisar converter UTM -> WGS84, tenho código para fazer isso em python que eu poderia postar. Como alternativa, você pode extrair o algoritmo necessário do Proj4 e usá-lo. Ou se você estiver realmente constrangido a usar o código ESRI (e não quiser projetar uma classe de recurso inteira, como sugerido), escreva uma biblioteca C simples para projetar usando ArcObjects, depois chame-a de Python usando ctypes. Ou ficar com arcpy e projetar uma classe de feição toda :(
Sasa Ivetic
@Kenton - A pesquisa rápida retorna pyproj ( code.google.com/p/pyproj ). Você pode ver um exemplo de como usar python para chamar a biblioteca do Proj4.
perfil completo de Sasa Ivetic
@Kenton - Se for uma projeção UTM NAD83 => geográfica WGS84 sem transformação de dados, você poderá implementar o algoritmo em python puro. As equações estão no livro de Snyder: onlinepubs.er.usgs.gov/djvu/PP/PP_1395.pdf Eu tenho uma função Oracle PL / SQL que faz isso se você deseja o código. I foram significado para a porta esta função para Python, mas geralmente apenas usar OGR / OSR ...
davidf
4

No ArcPy 10.0, não há capacidade de projetar geometrias individuais. No entanto, você pode criar um conjunto de recursos (ou uma classe de recurso na memória) e projetá-lo em vez de uma classe de recurso completa em uma área de trabalho em disco ou em um banco de dados em algum lugar.

Philip
fonte
que é exatamente o que eu esperava evitar. Faz-me desejar para o poder que você pode entrar em .Net com ArcObjects ...
Kenton W
0

O principal motivo pelo qual vejo não querer criar uma classe de recurso é porque arcpy.CreateFeatureclass_management pode ser lento. Você também pode usar arcpy.da.NumPyArrayTofeatureClass, que é mais ou menos instantâneo para as classes de recurso in_memory:

In [1]: import arcpy

In [2]: import numpy as np

In [3]: geosr = arcpy.SpatialReference('Geographic Coordinate Systems/Spheroid-based/WGS 1984 Major Auxiliary Sphere')

In [4]: tosr = arcpy.SpatialReference('Projected Coordinate Systems/World/WGS 1984 Web Mercator (auxiliary sphere)')

In [5]: npai=list(enumerate(((-115.12799999956881, 36.11419999969922), (-117, 38.1141))))

In [6]: npai
Out[6]: [(0, (-115.12799999956881, 36.11419999969922)), (1, (-117, 38.1141))]

In [7]: npa=np.array(npai, np.dtype(([('idfield', np.int32), ('XY', np.float, 2)])))

In [8]: npa
Out[8]: 
array([(0, [-115.12799999956881, 36.11419999969922]),
       (1, [-117.0, 38.1141])], 
      dtype=[('idfield', '<i4'), ('XY', '<f8', (2,))])

In [9]: fcName = arcpy.CreateScratchName(workspace='in_memory', data_type='FeatureClass')

In [10]: arcpy.da.NumPyArrayToFeatureClass(npa, fcName, ['XY'], geosr)

In [11]: with arcpy.da.SearchCursor(fcName, 'SHAPE@XY', spatial_reference=tosr) as cur:
    ...:     print list(cur)
    ...:     
[((-12815990.336048, 4316346.515041453),), ((-13024380.422813002, 4595556.878958654),)]
cwa
fonte
-1
import arcpy
dsc = arcpy.Describe(FC)
cursor = arcpy.UpdateCursor(FC, "", "Coordinate Systems\Geographic Coordinate   Systems\World\WGS 1984.prj")
for row in cursor:
  shape=row.getValue(dsc.shapeFieldName)
  geom = shape.getPart(0)
  x = geom.X
  y = geom.Y
  row.setValue('LONG_DD', x)
  row.setValue('LAT_DD', y)
  cursor.updateRow(row)

del cursor, row
ThinkSpatially
fonte