Python el camino a la inversa lon,lat coordenadas en un GeoJSON respuesta
-
21-12-2019 - |
Pregunta
Me gustaría invertir el orden de las coordenadas en este JSON de respuesta de (lat,lon) a (lon,lat):
url='https://www.sciencebase.gov/catalogMaps/mapping/ows/5342c5fce4b0aa151574a8ed?\
service=wfs&version=1.1.0&request=GetFeature&typeNames=sb:Conservation_Zone_WGS84&outputFormat=application/json'
response = requests.get(url).json()
print response
{u'crs': {u'properties': {u'code': u'4326'}, u'type': u'EPSG'},
u'features': [{u'geometry': {u'coordinates': [[[[39.81487959537135,
-74.09688169446223],
[39.81488113835475, -74.09587338924456],
[39.8143317590967, -74.09614209870023],
[39.8137616151959, -74.09633047532941],
[39.812950626580545, -74.09670529470912],
[39.8120075697193, -74.09698124228382],
[39.814255381955064, -74.0973277412355],
[39.81487959537135, -74.09688169446223]]]],
u'type': u'MultiPolygon'},
u'geometry_name': u'the_geom',
u'id': u'Conservation_Zone_WGS84.1',
u'properties': {u'ID': 1,
u'NAME': u'Sedge Island Marine Conservation Zone',
u'OBJECTID': 1,
u'SHAPE_AREA': 70259289.0821,
u'SHAPE_LEN': 40592.8006466,
u'WEB_LINK': u'http://www.state.nj.us/dep/fgw/sedge.htm'},
u'type': u'Feature'}],
u'type': u'FeatureCollection'}
Yo podría tirar de este aparte, la fuerza bruta, y palo de vuelta juntos, pero me pregunto:cuál sería una buena python el camino para cambiar el orden, dejando la estructura intacta?
Solución
Solución utilizando numpy
que debería funcionar para cualquier geojson.Vollará todas las 'coordenadas'.
import json
import requests
import numpy as np
def flip_geojson_coordinates(geo):
if isinstance(geo, dict):
for k, v in geo.iteritems():
if k == "coordinates":
z = np.asarray(geo[k])
f = z.flatten()
geo[k] = np.dstack((f[1::2], f[::2])).reshape(z.shape).tolist()
else:
flip_geojson_coordinates(v)
elif isinstance(geo, list):
for k in geo:
flip_geojson_coordinates(k)
url = "https://www.sciencebase.gov/catalogMaps/mapping/ows/5342c5fce4b0aa151574a8ed?\
service=wfs&version=1.1.0&request=GetFeature&typeNames=sb:Conservation_Zone_WGS84&outputFormat=application/json"
resp = requests.get(url)
gj = json.loads(resp.text)
print gj
flip_geojson_coordinates(gj)
print gj
Otros consejos
Bueno ... excavación a su lista de coordenadas toma esto:
d['features'][0]['geometry']['coordinates'][0][0]
para revertir aquellos que tendrías que hacer esto:
d['features'][0]['geometry']['coordinates'][0][0] = [i[::-1] for i in d['features'][0]['geometry']['coordinates'][0][0]]
o, un poco más limpio imo:
for l in d['features'][0]['geometry']['coordinates'][0][0]:
l.reverse()
El uso de una lista de comprensión y re-asignar el resultado a la estructura.
Hay varias listas que participan aquí, así que un par de bucles son necesarios:
for feature in response['features']:
feature['geometry']['coordinates'] = [[
[[long, lat] for lat, long in coords] for coords in poly]
for poly in feature['geometry']['coordinates']]
Esto hace suponer que la estructura de 'coordinates'
es estable;Veo que hay un 'type'
clave demasiado, puede que tenga que puedes variar la forma de alterar la estructura de los tipos distintos de las u'MultiPolygon
se utilizan.
Esto mueve los datos de:
>>> pprint.pprint(response)
{u'crs': {u'properties': {u'code': u'4326'}, u'type': u'EPSG'},
u'features': [{u'geometry': {u'coordinates': [[[[39.81487959537135,
-74.09688169446223],
[39.81488113835475,
-74.09587338924456],
[39.8143317590967,
-74.09614209870023],
[39.8137616151959,
-74.09633047532941],
....
[39.814255381955064,
-74.0973277412355],
[39.81487959537135,
-74.09688169446223]]]],
u'type': u'MultiPolygon'},
u'geometry_name': u'the_geom',
u'id': u'Conservation_Zone_WGS84.1',
u'properties': {u'ID': 1,
u'NAME': u'Sedge Island Marine Conservation Zone',
u'OBJECTID': 1,
u'SHAPE_AREA': 70259289.0821,
u'SHAPE_LEN': 40592.8006466,
u'WEB_LINK': u'http://www.state.nj.us/dep/fgw/sedge.htm'},
u'type': u'Feature'}],
u'type': u'FeatureCollection'}
a:
>>> pprint.pprint(response)
{u'crs': {u'properties': {u'code': u'4326'}, u'type': u'EPSG'},
u'features': [{u'geometry': {u'coordinates': [[[[-74.09688169446223,
39.81487959537135],
[-74.09587338924456,
39.81488113835475],
[-74.09614209870023,
39.8143317590967],
[-74.09633047532941,
39.8137616151959],
....
[-74.0973277412355,
39.814255381955064],
[-74.09688169446223,
39.81487959537135]]]],
u'type': u'MultiPolygon'},
u'geometry_name': u'the_geom',
u'id': u'Conservation_Zone_WGS84.1',
u'properties': {u'ID': 1,
u'NAME': u'Sedge Island Marine Conservation Zone',
u'OBJECTID': 1,
u'SHAPE_AREA': 70259289.0821,
u'SHAPE_LEN': 40592.8006466,
u'WEB_LINK': u'http://www.state.nj.us/dep/fgw/sedge.htm'},
u'type': u'Feature'}],
u'type': u'FeatureCollection'}
Su código "Pythonic" es ilegible y no funciona.¡Manténlo simple, estúpido!
def swapCoords(x):
out = []
for iter in x:
if isinstance(iter, list):
out.append(swapCoords(iter))
else:
return [x[1], x[0]]
return out
for feature in response['features']:
feature['geometry']['coordinates'] = swapCoords(feature['geometry']['coordinates'])