ジオメトリ投影速度テスト


8

最近、ogr / gdalに付属するOGRプロジェクションクラスを使用していますが、pyprojが推奨されたので、試してみようと思いました。切り替えるかどうかを判断するために、速度テストを行いました。以下は、2つをテストするために思いついた小さな(ほとんど)再現可能な例です。このテストが完全に公正であるかどうかはわかりませんので、コメントや推奨事項を歓迎します!

最初にインポートして、平等なプレイフィールドから始めることを確認します。

from pandas import Series # This is what our geometries are stored in
from shapely import wkb
import functools
from shapely.geometry import shape
from osgeo import ogr
# The following two imports are the important ones
from pyproj import Proj, transform
from osgeo.osr import SpatialReference, CoordinateTransformation

私はパンダの「シリーズ」に形の良い形状を保存しているので、関数はで動作する必要がありSeries.apply()ます。ここでは、2つの関数(1つは 'ogr.osr'を使用し、もう1つは 'pyproj'を使用)を定義して、への呼び出し内で座標変換を実行しますSeries.apply()

def transform_osr(geoms, origin, target):
    target_crs = SpatialReference()
    target_crs.ImportFromEPSG(origin)
    origin_crs = SpatialReference()
    origin_crs.ImportFromEPSG(origin)
    transformer = CoordinateTransformation(origin_crs, target_crs)
    def trans(geom):
        g = ogr.CreateGeometryFromWkb(geom.wkb)
        if g.Transform(transformer):
            raise Exception("Ahhhh!")
        g = wkb.loads(g.ExportToWkb())
        return g
    return geoms.apply(trans)

def transform_pyproj(geoms, origin, target):
    target = Proj(init="epsg:%s" % target)
    origin = Proj(init="epsg:%s" % origin)
    transformer = functools.partial(transform, origin, target)
    def trans(geom):
        interface = geom.__geo_interface__
        geom_type = interface['type']
        coords = interface['coordinates']
        result = apply_to_coord_pairs(transformer, coords)
        return shape({'coordinates':result, 'type':geom_type})
    def apply_to_coord_pairs(fun, geom):
        return [not all([hasattr(y, "__iter__") for y in x]) and \
                fun(*x) or apply_to_coord_pairs(fun, x) for x in geom]
    return geoms.apply(trans)

これらの各関数は、起点と終点の座標参照系の入力としてEPSGコードを受け取ります。どちらのライブラリも、投影情報を定義する別の方法を提供しますが、EPSGコードは今のところコードをかなり単純なものにしています。

%timeitipythonでmagic関数を使用した結果は次のとおりです。

In [1]: %timeit transform_pyproj(l, 29903, 4326)
1 loops, best of 3: 641 ms per loop

In [2]: %timeit transform_osr(l, 29903, 4326)
10 loops, best of 3: 27.4 ms per loop

明らかに「ogr.osr」バージョンの方が高速ですが、それは公平な比較ですか?「pyproj」バージョンは個々のポイントで実行され、ほとんどがPythonで実行されますが、「ogr.osr」バージョンはOGRジオメトリオブジェクトを直接操作します。これらを比較するより良い方法はありますか?

回答:


7

Pyprojは、PROJ4ライブラリを使用するPython C拡張であり、osgeo.ogrは、PROJ4ライブラリを使用するPython C拡張です。座標投影のみを考慮している場合、最も公正なテストでは、それらはほぼ等しくなります。

Pyprojの変換は座標値の配列を操作できるため、すべてのペアではなく、ラインまたはリングごとに1回だけ呼び出す必要があります。これはかなりスピードアップするはずです。例:https : //gist.github.com/sgillies/3642564#file-2-py-L10

(更新)また、Shapelyは、1.2.16でジオメトリを変換する関数を提供します。

Help on function transform in module shapely.ops:

transform(func, geom)
    Applies `func` to all coordinates of `geom` and returns a new
    geometry of the same type from the transformed coordinates.

    `func` maps x, y, and optionally z to output xp, yp, zp. The input
    parameters may iterable types like lists or arrays or single values.
    The output shall be of the same type. Scalars in, scalars out.
    Lists in, lists out.

    For example, here is an identity function applicable to both types
    of input.

      def id_func(x, y, z=None):
          return tuple(filter(None, [x, y, z]))

      g2 = transform(id_func, g1)

    A partially applied transform function from pyproj satisfies the
    requirements for `func`.

      from functools import partial
      import pyproj

      project = partial(
          pyproj.transform,
          pyproj.Proj(init='espg:4326'),
          pyproj.Proj(init='epsg:26913'))

      g2 = transform(project, g1)

    Lambda expressions such as the one in

      g2 = transform(lambda x, y, z=None: (x+1.0, y+1.0), g1)

    also satisfy the requirements for `func`.

+1。Shapely Points、LinearRingsおよびLineStringsにもnumpy配列インターフェイスがあるため、次のようなことができますprojected_coords = numpy.vstack(pyproj.transform(origin, target, *numpy.array(geom).T)).T
om_henners

これは素晴らしい@sgilliesです。何らかの理由で、私のバージョンのshapelyに変換がありませんか?shapely .__ version__: '1.2.17'。ソースを直接取得してみます。
Carson Farmer

おっと、ごめんなさい。バージョン1.2.18で(おそらく今週末)登場します。
sgillies 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.