2014-04-11 38 views
1

我想扭轉的座標的順序從(LAT,LON)到(LON,LAT)此JSON響應:扭轉LON Python化方式,在以GeoJSON響應緯度座標

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'} 

我可以把它分開,蠻力,並把它粘在一起,但我想知道:在保持結構完整的情況下,改變順序的好方法是什麼?

回答

1

解決方案應該針對任何GeoJSON的工作。它會翻轉所有'座標'。

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 
+0

我選擇了這一個,不是因爲它是最短或最優雅的,但它確實似乎適用於迄今爲止所見過的所有geojson響應。其他解決方案雖然很酷 - 我從兩方面都學到了一些東西 –

1

使用列表理解並將結果重新分配給結構。

這裏有涉及到幾個列表,因此需要幾個循環:

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']] 

這並不假定的'coordinates'結構是穩定的;我發現還有一個'type'鍵,如果使用u'MultiPolygon以外的其他類型,則可能需要更改如何更改結構。

>>> 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'} 

到:

>>> 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'} 
+0

嗯..沒錯。理想情況下,我希望這個句柄成爲一般情況,不管JSON響應的結構如何,都會返回返回的任何座標。 –

+0

你必須調查'type'可以使用的值,以及'coordinate'結構在這種情況下的樣子。 –

2

嗯...挖下來到您的座標列表藉此:

d['features'][0]['geometry']['coordinates'][0][0] 

因此,要扭轉這些

這從移動數據你必須這樣做:

d['features'][0]['geometry']['coordinates'][0][0] = [i[::-1] for i in d['features'][0]['geometry']['coordinates'][0][0]] 

或者說,有點清潔IMO:使用numpy

for l in d['features'][0]['geometry']['coordinates'][0][0]: 
    l.reverse() 
+0

這很漂亮。正如Martijn Pieters在他的回答中指出的那樣,如果JSON中返回的任何座標都可以顛倒,那將是非常好的。 –

1

您的「pythonic」代碼不可讀,不起作用。保持簡單,愚蠢!

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'])