问题
I want to calculate areas of geometries and some of these geometries can be geometry collections. But I can't do this because shapely doesn't create geometry collection from geojson.
Here is the sample code:
import sys
import shapely
from shapely.geometry import shape
print sys.version
print shapely.__version__
shp = shape({ "type" : "GeometryCollection", "geometries" : [ { "type" : "MultiPolygon", "coordinates" : [ [ [ [ -176.392059198913, -44.2871679740063 ], [ -176.392051742896, -44.287151383102 ], [ -176.392031530803, -44.2871344706636 ], [ -176.39200961191, -44.2871265610425 ], [ -176.391981764136, -44.2871247604782 ], [ -176.391958318107, -44.2871296477241 ], [ -176.391938555171, -44.2871399366613 ], [ -176.391926697409, -44.2871518332429 ], [ -176.391919510887, -44.2871685527587 ], [ -176.391919510887, -44.2871809637809 ], [ -176.391926697409, -44.2871977475943 ], [ -176.39194142978, -44.2872117662547 ], [ -176.391952299394, -44.2872176823855 ], [ -176.391975026771, -44.2872241772677 ], [ -176.392002874545, -44.287224370185 ], [ -176.392025601922, -44.2872180682202 ], [ -176.392043837722, -44.2872068790156 ], [ -176.392055875147, -44.2871915742382 ], [ -176.392059198913, -44.2871679740063 ] ] ], [ [ [ -176.395054990554, -44.2866718524961 ], [ -176.394985011794, -44.2865985431944 ], [ -176.394870296932, -44.2865318573729 ], [ -176.39471973929, -44.2864943666608 ], [ -176.394478451805, -44.2864536605947 ], [ -176.394252974669, -44.2864997684115 ], [ -176.39423896095, -44.2864981607477 ], [ -176.394288098796, -44.2862575894326 ], [ -176.394110412033, -44.2860409393617 ], [ -176.393535220757, -44.2860305859249 ], [ -176.393376668109, -44.2861752766473 ], [ -176.393372446027, -44.2862439563855 ], [ -176.39308166137, -44.2869353793885 ], [ -176.39289184735, -44.2873133692894 ], [ -176.39283543315, -44.2873595407371 ], [ -176.392827258481, -44.2874577353246 ], [ -176.393011952104, -44.2875944486682 ], [ -176.393422751683, -44.2876439637706 ], [ -176.393631699818, -44.2875120734508 ], [ -176.393639694824, -44.2875105944256 ], [ -176.393681556316, -44.2875372811799 ], [ -176.39377641841, -44.287580044267 ], [ -176.393856817628, -44.2876262798103 ], [ -176.393945122021, -44.2877477524342 ], [ -176.393972790132, -44.2878800923601 ], [ -176.394000817568, -44.2880426552818 ], [ -176.394041062093, -44.2881004653263 ], [ -176.394137451323, -44.2881293381748 ], [ -176.39437882864, -44.2881469576789 ], [ -176.39444934639, -44.288034231344 ], [ -176.394488512936, -44.2878805424954 ], [ -176.39452749982, -44.2877896794012 ], [ -176.394566756197, -44.2876918712001 ], [ -176.394586429302, -44.2875450621349 ], [ -176.394533159206, -44.2873842340869 ], [ -176.394460844825, -44.2872859750708 ], [ -176.394428864801, -44.2872049498422 ], [ -176.394396705114, -44.2871413513901 ], [ -176.39438879994, -44.2870604545739 ], [ -176.394445393803, -44.2869391734468 ], [ -176.394558042539, -44.2869161518684 ], [ -176.394670691276, -44.2869161518684 ], [ -176.394839754212, -44.286887471342 ], [ -176.394996330566, -44.2868534533899 ], [ -176.39503531745, -44.2868046449896 ], [ -176.395045109086, -44.2867417534732 ], [ -176.395054990554, -44.2866718524961 ] ] ] ] }, { "type" : "MultiLineString", "coordinates" : [ [ [ -176.394252974669, -44.2864997684115 ], [ -176.394075737063, -44.2866440721399 ] ], [ [ -176.394075737063, -44.2866440721399 ], [ -176.39390685379, -44.2866785403577 ] ], [ [ -176.39390685379, -44.2866785403577 ], [ -176.393761955534, -44.286695774459 ] ], [ [ -176.393761955534, -44.286695774459 ], [ -176.393633137123, -44.2867187318175 ] ], [ [ -176.393633137123, -44.2867187318175 ], [ -176.393624872622, -44.2868689511739 ] ], [ [ -176.393624872622, -44.2868689511739 ], [ -176.393624962454, -44.286990361058 ] ], [ [ -176.393624962454, -44.286990361058 ], [ -176.393624513296, -44.2870655347429 ] ], [ [ -176.393624513296, -44.2870655347429 ], [ -176.393624423464, -44.2871117706912 ] ], [ [ -176.393624423464, -44.2871117706912 ], [ -176.393615889469, -44.2873486730876 ] ], [ [ -176.393615889469, -44.2873486730876 ], [ -176.393639694824, -44.2875105944256 ] ] ] } ] })
print shp.area
Here is the output:
2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2]
1.5.13
Traceback (most recent call last):
...
File "/usr/local/lib/python2.7/dist-packages/Shapely-1.5.13-py2.7.egg/shapely/geometry/geo.py", line 42, in shape
raise ValueError("Unknown geometry type: %s" % geom_type)
ValueError: Unknown geometry type: geometrycollection
Maybe latest version of shapely can do this? If it does, what version can I install under ubuntu? If doesn't, what is the alternative way of calculating geometry collection area?
回答1:
As of Shapely 1.6b2 this is possible using the exact commands you are using!
回答2:
I'm not aware of shapely
handling mixed types like this (though I could be wrong). I think you'll need to use your understanding of the structure of the geojson to correctly extract the information you're looking for. For instance, you might select the coordinates that correspond to polygons in your geometry collection, and then convert them to shapely
polygons, as follows:
geo_dict = { "type" : "GeometryCollection", "geometries" : [ { "type" : "MultiPolygon", "coordinates" : [ [ [ [ -176.392059198913, -44.2871679740063 ], [ -176.392051742896, -44.287151383102 ], [ -176.392031530803, -44.2871344706636 ], [ -176.39200961191, -44.2871265610425 ], [ -176.391981764136, -44.2871247604782 ], [ -176.391958318107, -44.2871296477241 ], [ -176.391938555171, -44.2871399366613 ], [ -176.391926697409, -44.2871518332429 ], [ -176.391919510887, -44.2871685527587 ], [ -176.391919510887, -44.2871809637809 ], [ -176.391926697409, -44.2871977475943 ], [ -176.39194142978, -44.2872117662547 ], [ -176.391952299394, -44.2872176823855 ], [ -176.391975026771, -44.2872241772677 ], [ -176.392002874545, -44.287224370185 ], [ -176.392025601922, -44.2872180682202 ], [ -176.392043837722, -44.2872068790156 ], [ -176.392055875147, -44.2871915742382 ], [ -176.392059198913, -44.2871679740063 ] ] ], [ [ [ -176.395054990554, -44.2866718524961 ], [ -176.394985011794, -44.2865985431944 ], [ -176.394870296932, -44.2865318573729 ], [ -176.39471973929, -44.2864943666608 ], [ -176.394478451805, -44.2864536605947 ], [ -176.394252974669, -44.2864997684115 ], [ -176.39423896095, -44.2864981607477 ], [ -176.394288098796, -44.2862575894326 ], [ -176.394110412033, -44.2860409393617 ], [ -176.393535220757, -44.2860305859249 ], [ -176.393376668109, -44.2861752766473 ], [ -176.393372446027, -44.2862439563855 ], [ -176.39308166137, -44.2869353793885 ], [ -176.39289184735, -44.2873133692894 ], [ -176.39283543315, -44.2873595407371 ], [ -176.392827258481, -44.2874577353246 ], [ -176.393011952104, -44.2875944486682 ], [ -176.393422751683, -44.2876439637706 ], [ -176.393631699818, -44.2875120734508 ], [ -176.393639694824, -44.2875105944256 ], [ -176.393681556316, -44.2875372811799 ], [ -176.39377641841, -44.287580044267 ], [ -176.393856817628, -44.2876262798103 ], [ -176.393945122021, -44.2877477524342 ], [ -176.393972790132, -44.2878800923601 ], [ -176.394000817568, -44.2880426552818 ], [ -176.394041062093, -44.2881004653263 ], [ -176.394137451323, -44.2881293381748 ], [ -176.39437882864, -44.2881469576789 ], [ -176.39444934639, -44.288034231344 ], [ -176.394488512936, -44.2878805424954 ], [ -176.39452749982, -44.2877896794012 ], [ -176.394566756197, -44.2876918712001 ], [ -176.394586429302, -44.2875450621349 ], [ -176.394533159206, -44.2873842340869 ], [ -176.394460844825, -44.2872859750708 ], [ -176.394428864801, -44.2872049498422 ], [ -176.394396705114, -44.2871413513901 ], [ -176.39438879994, -44.2870604545739 ], [ -176.394445393803, -44.2869391734468 ], [ -176.394558042539, -44.2869161518684 ], [ -176.394670691276, -44.2869161518684 ], [ -176.394839754212, -44.286887471342 ], [ -176.394996330566, -44.2868534533899 ], [ -176.39503531745, -44.2868046449896 ], [ -176.395045109086, -44.2867417534732 ], [ -176.395054990554, -44.2866718524961 ] ] ] ] }, { "type" : "MultiLineString", "coordinates" : [ [ [ -176.394252974669, -44.2864997684115 ], [ -176.394075737063, -44.2866440721399 ] ], [ [ -176.394075737063, -44.2866440721399 ], [ -176.39390685379, -44.2866785403577 ] ], [ [ -176.39390685379, -44.2866785403577 ], [ -176.393761955534, -44.286695774459 ] ], [ [ -176.393761955534, -44.286695774459 ], [ -176.393633137123, -44.2867187318175 ] ], [ [ -176.393633137123, -44.2867187318175 ], [ -176.393624872622, -44.2868689511739 ] ], [ [ -176.393624872622, -44.2868689511739 ], [ -176.393624962454, -44.286990361058 ] ], [ [ -176.393624962454, -44.286990361058 ], [ -176.393624513296, -44.2870655347429 ] ], [ [ -176.393624513296, -44.2870655347429 ], [ -176.393624423464, -44.2871117706912 ] ], [ [ -176.393624423464, -44.2871117706912 ], [ -176.393615889469, -44.2873486730876 ] ], [ [ -176.393615889469, -44.2873486730876 ], [ -176.393639694824, -44.2875105944256 ] ] ] } ] } # the contents of your geojson, as above
geometries = geo_dict["geometries"]
polygon_bounds = [geom['coordinates'] for geom in geometries if "Polygon" in geom["type"]]
polygons = [shapely.geometry.Polygon(b[0]) for b in polygon_bounds[0]]
areas = [p.area for p in polygons]
来源:https://stackoverflow.com/questions/40655863/how-to-create-geometrycollection-from-geojson-with-python-shapely