13

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?

kz_sergey
  • 677
  • 5
  • 19

2 Answers2

7

As of Shapely 1.6b2 this is possible using the exact commands you are using!

Jens de Bruijn
  • 939
  • 9
  • 25
0

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]
jdmcbr
  • 5,964
  • 6
  • 28
  • 38