Shapely: Penghitungan luas poligon tidak cocok dengan alat lain seperti mesin google earth atau geojson.io

Dibuat pada 5 Jun 2019  ·  8Komentar  ·  Sumber: Toblerity/Shapely

Penghitungan luas poligon tampaknya tidak cocok dengan alat serupa lainnya seperti Geojson.io atau Google Earth Engine. Sebagai contoh:

coords = [(-97.59238135821987, 43.47456565304017),
 (-97.59244690469288, 43.47962399877412),
 (-97.59191951546768, 43.47962728271748),
 (-97.59185396090983, 43.47456565304017),
 (-97.59238135821987, 43.47456565304017)]

projection = partial(pyproj.transform, pyproj.Proj(init='epsg:4326'), pyproj.Proj(init='epsg:3857'))
shapely.ops.transform(projection, shapely.geometry.Polygon(sample_coords)).area

menghasilkan area 45573.993884405005 m^2 sementara Google Earth Engine dan Geojson.io masing-masing melaporkan 23944.14737277293 dan 23997.77 .

Area di shapely dihitung di sini dengan mengutip metode yang tautannya terputus, sedangkan Geojson.io dihitung di sini melalui metode yang dijelaskan mulai dari halaman 3 dokumen ini .

Saya telah mengonversi ini secara singkat ke python dengan argumen yang mengharapkan skema koordinat yang sama seperti di atas (daftar koordinat):

def ringArea(coords):
    #var p1, p2, p3, lowerIndex, middleIndex, upperIndex, i,
    area = 0
    wgs84_radius = 6378137 # earth's equitorial radius in wgs84 = espg 4326
    coordsLength = len(coords)

    if coordsLength > 2:
        for i in range(coordsLength):
            if i == coordsLength - 2:
                lowerIndex = coordsLength - 2
                middleIndex = coordsLength - 1
                upperIndex = 0
            elif i == coordsLength - 1:
                lowerIndex = coordsLength - 1
                middleIndex = 0
                upperIndex = 1
            else:
                lowerIndex = i
                middleIndex = i + 1
                upperIndex = i + 2

            p1 = coords[lowerIndex]
            p2 = coords[middleIndex]
            p3 = coords[upperIndex]
            area += (np.deg2rad(p3[0]) - np.deg2rad(p1[0]) ) * np.sin(np.deg2rad(p2[1]))

        area = area * wgs84_radius * wgs84_radius / 2
    return area

Metode ini mengembalikan area 23997.769250450423 m^2.

Pertanyaan utama saya adalah: Apakah metode saat ini lebih disukai karena alasan tertentu? Jika demikian, dapatkah tautan ke yang dikutip diperbaiki (saya tidak yakin ke mana harus pergi). Jika tidak, apakah mungkin untuk menyesuaikan (atau menambahkan opsi) dengan metode yang dijelaskan dalam dokumen JPL?

Saya akan dengan senang hati berkontribusi untuk ini jika opsi untuk metode lain ini ingin ditambahkan, tetapi saya tidak melihat pedoman kontribusi apa pun.

Komentar yang paling membantu

Sejauh yang saya mengerti, indah mengasumsikan semua titik adalah kartesius, dan menghitung luas dalam koordinat apa pun yang diberikan; pada contoh di atas koordinat wgs diubah menjadi web mercator epsg3857 untuk menghitung luas, tetapi web mercator bukanlah proyeksi luas yang sama.

Jika kita mengganti konversi ke sistem koordinat luas yang sama seperti world mollweide (https://spatialreference.org/ref/esri/54009/), perhitungan luas dilakukan seperti yang diharapkan:

coords = [(-97.59238135821987, 43.47456565304017),
 (-97.59244690469288, 43.47962399877412),
 (-97.59191951546768, 43.47962728271748),
 (-97.59185396090983, 43.47456565304017),
 (-97.59238135821987, 43.47456565304017)]

projection = partial(pyproj.transform, pyproj.Proj(init='epsg:4326'), pyproj.Proj(init='esri:54009'))
shapely.ops.transform(projection, shapely.geometry.Polygon(coords)).area

Yang memberi 23997.775332830173 .

Kami menggunakan ini di https://github.com/mapbox/fio-area. Semoga ini membantu!

Semua 8 komentar

Sejauh yang saya mengerti, indah mengasumsikan semua titik adalah kartesius, dan menghitung luas dalam koordinat apa pun yang diberikan; pada contoh di atas koordinat wgs diubah menjadi web mercator epsg3857 untuk menghitung luas, tetapi web mercator bukanlah proyeksi luas yang sama.

Jika kita mengganti konversi ke sistem koordinat luas yang sama seperti world mollweide (https://spatialreference.org/ref/esri/54009/), perhitungan luas dilakukan seperti yang diharapkan:

coords = [(-97.59238135821987, 43.47456565304017),
 (-97.59244690469288, 43.47962399877412),
 (-97.59191951546768, 43.47962728271748),
 (-97.59185396090983, 43.47456565304017),
 (-97.59238135821987, 43.47456565304017)]

projection = partial(pyproj.transform, pyproj.Proj(init='epsg:4326'), pyproj.Proj(init='esri:54009'))
shapely.ops.transform(projection, shapely.geometry.Polygon(coords)).area

Yang memberi 23997.775332830173 .

Kami menggunakan ini di https://github.com/mapbox/fio-area. Semoga ini membantu!

Shapely hanya melakukan perhitungan Cartesian, jadi masalah ini sebagian besar di luar topik.

Saya baru saja memperbaiki tautan yang rusak di shapely/algorithms/cga.py ke https://web.archive.org/web/20080209143651/http://cgafaq . info:80/wiki/Polygon_Area

Ada beberapa cara berbeda untuk menghitung luas dari koordinat geodetik, dan masing-masing akan memberikan hasil yang sedikit berbeda. Untuk menambahkan metode lain, gunakan Planimeter pada WGS84 sebagai contoh untuk mendapatkan 23988,9 m^2 dengan kesalahan sekitar 0,2 m^2, jadi saya akan menyebutnya "jawaban terbaik". Metode ini juga digunakan di PostGIS pada tipe geografi.

Terima kasih @dnomadb @mwtoews !

Saya menghargai masukan dari semua orang. Saya cukup baru di dunia GIS jadi semuanya membantu, terima kasih!

@dnomadb ketika mencoba metode yang disarankan saya mendapatkan kesalahan berikut:

CRSError: Invalid projection: +init=epsg:54009 +type=crs: (Internal Proj Error: proj_create: crs not found)

Apakah Anda menemukan ini?

@brentonmallen1 sepertinya Anda memiliki epsg:54009 di mana seharusnya esri:54009 (seperti dalam contoh di sini: https://github.com/Toblerity/Shapely/issues/726#issuecomment-499252744 -- itu hal yang mudah untuk mencampuradukkan)

Itu salah ketik di pihak saya mencoba berbagai hal untuk melihat apakah saya bisa membuatnya berfungsi. Saya masih mendapatkan kesalahan dengan esri:54009 :

projection = partial(pyproj.transform, pyproj.Proj(init='epsg:4326'), pyproj.Proj(init='esri:54009'))

``` ------------------------------------------------- ----------------------------
CRSError Traceback (panggilan terakhir terakhir)
di
5 (-97.59238135821987, 43.47456565304017)]
6
----> 7 proyeksi = parsial(pyproj.transform, pyproj.Proj(init='epsg:4326'), pyproj.Proj(init='esri:54009'))
8 shapely.ops.transform(proyeksi, shapely.geometry.Polygon(coords)).area

~/miniconda3/envs/fs-ml/lib/python3.6/site-packages/pyproj/proj.py di __init__(self, projparams, melestarikan_unit, **kwargs)
145 '116,366 39,867'
146 """
-> 147 self.crs = CRS.from_user_input(projparams jika projparams bukan Tidak ada lagi kwargs)
148 # pastikan unit adalah meter jika melestarikan_unit salah.
149 jika tidak melestarikan_unit dan "kaki" di self.crs.axis_info[0].unit_name:

~/miniconda3/envs/fs-ml/lib/python3.6/site-packages/pyproj/crs.py di from_user_input(cls, value)
389 jika isinstance(nilai, _CRS):
390 nilai pengembalian
-> 391 kembali cls(nilai)
392
393 def get_geod(mandiri):

~/miniconda3/envs/fs-ml/lib/python3.6/site-packages/pyproj/crs.py di __init__(self, projparams, **kwargs)
258 raise CRSError("Input CRS tidak valid: {!r}".format(projparams))
259
--> 260 super(CRS, self).__init__(projstring)
261
262 @metodekelas

pyproj/_crs.pyx di pyproj._crs._CRS.__init__()

CRSError: Proyeksi tidak valid: +init= esri:54009 +type=crs: (Kesalahan Proj Internal: proj_create: tidak dapat diperluas +init=esri:54009 +type=crs)```

Jika ada orang lain yang menemukan masalah di atas dengan memproyeksikan ulang ke ESRI:54009 , berikut adalah solusinya https://github.com/pyproj4/pyproj/issues/341

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

jGaboardi picture jGaboardi  ·  5Komentar

chivasblue picture chivasblue  ·  3Komentar

LostFan123 picture LostFan123  ·  5Komentar

LostFan123 picture LostFan123  ·  3Komentar

kannes picture kannes  ·  4Komentar