In letzter Zeit habe ich die OGR-Projektionsklassen verwendet, die mit ogr / gdal geliefert werden, aber pyproj wurde mir empfohlen, also dachte ich, ich würde es versuchen. Um zu entscheiden, ob ich wechseln soll, habe ich einen Geschwindigkeitstest durchgeführt. Das Folgende ist ein kleines (fast) reproduzierbares Beispiel, das ich mir ausgedacht habe, um die beiden zu testen. Ich bin mir nicht sicher, ob dieser Test völlig fair ist, daher sind Kommentare und Empfehlungen willkommen!
Importiert zuerst, um sicherzustellen, dass wir mit gleichen Wettbewerbsbedingungen beginnen:
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
Da ich die formschönen Geometrien in einer Pandas-Serie speichere, müssen die Funktionen funktionieren Series.apply()
. Hier definiere ich zwei Funktionen (eine mit 'ogr.osr' und eine mit 'pyproj'), um Koordinatentransformationen innerhalb eines Aufrufs von durchzuführen 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)
Jede dieser Funktionen verwendet einen EPSG-Code als Eingabe für die Referenzsysteme für Ursprungs- und Zielkoordinaten. Beide Bibliotheken bieten alternative Möglichkeiten zum Definieren von Projektionsinformationen, aber EPSG-Codes halten den Code vorerst recht einfach.
Hier sind die Ergebnisse unter Verwendung der %timeit
magischen Funktion in ipython:
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
Natürlich ist die 'ogr.osr'-Version schneller, aber ist es ein fairer Vergleich? Die 'pyproj'-Version wird an einzelnen Punkten erstellt und meistens in Python ausgeführt, während die' ogr.osr'-Version direkt auf das OGR-Geometrieobjekt angewendet wird. Gibt es eine bessere Möglichkeit, diese zu vergleichen?
projected_coords = numpy.vstack(pyproj.transform(origin, target, *numpy.array(geom).T)).T