在地理空间数据处理的范畴内,大家普遍希望读取地理空间文件的过程能够顺利无阻。然而,现实情况并非总是如此理想。这种理想与现实之间的差距,确实值得我们进行深入研究。
In [9]: df = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres')) In [10]: df.crs Out[10]: Name: WGS 84 Axis Info [ellipsoidal]: - Lat[north]: Geodetic latitude (degree) - Lon[east]: Geodetic longitude (degree) Area of Use: - name: World. - bounds: (-180.0, -90.0, 180.0, 90.0) Datum: World Geodetic System 1984 ensemble - Ellipsoid: WGS 84 - Prime Meridian: Greenwich
旧CRS格式下的CRS对象差异
使用旧CRS格式时,生成的CRS对象有时会与预期不符。这种情况并不少见,处理地理空间数据时,许多人都有可能遇到。以实际项目为例,一些早期的地理数据项目在执行CRS相关操作时,由于旧格式的限制,生成的CRS对象可能与预期有所差异。这种情况会为数据处理和分析带来不少麻烦,比如可能影响数据的精确投影和后续的可视化效果。
## OLD GeoDataFrame(..., crs={'init': 'epsg:4326'}) # or gdf.crs = {'init': 'epsg:4326'} # or gdf.to_crs({'init': 'epsg:4326'})
另一方面,旧格式带来的CRS对象差异可能导致操作间的连锁效应。比如,当数据转换至另一CRS时,这些差异如同潜藏的暗礁,使得操作流程变得繁杂且容易出错,进而可能影响地理信息处理全流程的数据精确度。
手动指定CRS代码的变化
## NEW GeoDataFrame(..., crs="EPSG:4326") # or gdf.crs = "EPSG:4326" # or gdf.to_crs("EPSG:4326")
gdf.crs = "+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs"
以前,众多人包括GeoPandas文档示例都曾用“init”proj4字符串来设定EPSG代码。但现在,这种方法已经不再适用,使用它会导致pyproj发出弃用警告。目前,正确的方法是直接使用EPSG代码。尽管如此,在许多老旧的代码库中,依旧普遍采用这种方法。这些老代码就像沉睡的巨兽,一旦需要维护或更新,就必须对存在问题的代码进行修改。
gdf.crs = "EPSG:2163"
持续采用原有指定方法,观察实际操作效果,可能会对代码执行效率产生负面影响,且与现行地理空间数据处理的规范不符。这就像在一条现代化的高铁上,却用上了陈旧的蒸汽机车,其后果不言而喻,效率和精确度都会显著降低。
查找EPSG代码的方法
>>> import pyproj >>> crs = pyproj.CRS("+proj=laea +lat_0=45 +lon_0=-100 +x_0=0 +y_0=0 +a=6370997 +b=6370997 +units=m +no_defs") >>> crs.to_epsg() 2163
要找到EPSG代码,一种有效的方法是使用pyproj进行操作。对于许多缺乏EPSG代码的地理数据,这种方法可以帮助确定代码。比如,在田野地理调查中收集的原始地理数据,若需进行精确的空间分析,确定EPSG代码至关重要,pyproj在这里能起到关键作用。
此外,诸如spatialreference.org和epsg.io等网站提供了大量CRS描述、EPSG代码和Proj4字符串定义。当研究人员在整理和分析地理数据时,若代码中无法直接找到EPSG代码,便会访问这些网站查找所需信息,从而保证数据处理结果的精确性。
其它指定CRS的方法
>>> pyproj.CRS(3EPSG:4326") ... Axis Info [ellipsoidal]: - Lat[north]: Geodetic latitude (degree) - Lon[east]: Geodetic longitude (degree) ...
除了EPSG代码,还有其他途径来定义坐标参考系统。例如,可以采用实物对象、WKT字符串、项目JSON字符串等,这些都可以在GeoPandas中通过设置crs关键字或属性来实现。EPSG代码如同大多数人熟悉的主要道路,而其他方法则像是较少人知晓的偏僻小径,但它们同样能够引导我们到达目的地。
在某些特定数据情境中,这些手段可能发挥着至关重要的角色。比如,在处理某些特殊类型的地理数据时,或者当数据来源非同寻常,传统的EPSG代码设定方法不再适用时,其他方法便可以发挥作用,确保CRS的正确指定,从而便于后续的数据处理。
GeoPandas中的坐标存储顺序
>>> import pyproj >>> crs = pyproj.CRS("+proj=lcc +lat_1=51.16666723333333 +lat_2=49.8333339 +lat_0=90 +lon_0=4.367486666666666 +x_0=150000.013 +y_0=5400088.438 +ellps=intl +towgs84=106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1 +units=m +no_defs") >>> crs Name: unknown Axis Info [cartesian]: - E[east]: Easting (metre) - N[north]: Northing (metre) Area of Use: - undefined Coordinate Operation: - name: Transformation from unknown to WGS84 - method: Position Vector transformation (geog2D domain) Datum: Unknown based on International 1909 (Hayford) ellipsoid - Ellipsoid: International 1909 (Hayford) - Prime Meridian: Greenwich Source CRS: unknown
在GeoPandas中,坐标数据总是以(x,y)即经纬度的顺序进行保存,不受坐标参考系(CRS)的影响。这种存储方式有点像双刃剑。它有一个好处,那就是无论CRS如何定义,坐标都保持一致,便于管理和稳定。此外,当处理不同CRS定义的数据时,这种方式能有效避免因坐标存储方式不同而引起的混乱。
另一方面,在与遵循特定CRS标准坐标存储方案的交互中,可能会遭遇兼容难题。这就像一个讲通用语言的人与仅懂方言的人对话,可能会出现沟通不畅的情况。
文件源与CRS定义导致的问题
>>> crs.source_crs Name: unknown ...
众多文件来源及CRS的界定与Proj>6的新规定存在出入,涉及Proj4字符串和较旧的WKT格式等。这种不吻合可能造成生成的对象与设想有差异。以许多企业更新数据处理系统为例,他们发现,因文件源未达标新规,许多旧地理数据在新流程中生成的CRS对象与预期的EPSG代码不符,此类问题在业内颇为常见。
在将WKT字符串转换成CRS对象时,可能会出现结果与预期不符的情况。比如,用“EPSG:2953”的WKT字符串构建的CRS对象,其坐标轴顺序是“东,北”,而用EPSG代码构建的CRS对象,其坐标轴顺序则是“北,东”。
>>> crs.to_epsg() >>> crs.source_crs.to_epsg() 31370
各位读者,在你们操作地理空间数据时,是否也遇到过与CRS相关的一些难题?不妨在评论区留下你们的经历,如觉得本文对您有帮助,请点赞并转发。