【问题标题】:Import mssql spatial fields into geopandas/shapely geometry将 mssql 空间字段导入 geopandas/shapely 几何
【发布时间】:2021-04-12 21:48:41
【问题描述】:

我似乎无法将 mssql 空间字段直接导入 geopandas。我可以使用 Pymssql 将普通的 mssql 表导入到 pandas 中而不会出现问题,但我无法找到一种将空间字段导入形状几何的方法。我知道 mssql 的 OGR 驱动程序应该能够处理它,但我对 sql 的熟练程度不足以解决这个问题。 这对于线和多边形来说更成问题,因为点可以从 mssql 字段转换为 x 和 y 坐标。 谢谢!

【问题讨论】:

    标签: python sql-server shapely geopandas


    【解决方案1】:

    我通过正确查询 sql 数据库表并通过 shapely.wkt 中的加载函数将 wkt 字符串转换为 shapely 几何来解决这个问题。

    我不是程序员,所以请记住函数的组织。该函数可以导入带或不带 GIS 几何的 mssql 表。

    from pymssql import connect
    from pandas import read_sql
    from shapely.wkt import loads
    from geopandas import GeoDataFrame
    
    def rd_sql(server, database, table, col_names=None, where_col=None, where_val=None, geo_col=False, epsg=2193, export=False, path='save.csv'):
        """
        Imports data from MSSQL database, returns GeoDataFrame. Specific columns can be selected and specific queries within columns can be selected. Requires the pymssql package, which must be separately installed.
        Arguments:
        server -- The server name (str). e.g.: 'SQL2012PROD03'
        database -- The specific database within the server (str). e.g.: 'LowFlows'
        table -- The specific table within the database (str). e.g.: 'LowFlowSiteRestrictionDaily'
        col_names -- The column names that should be retrieved (list). e.g.: ['SiteID', 'BandNo', 'RecordNo']
        where_col -- The sql statement related to a specific column for selection (must be formated according to the example). e.g.: 'SnapshotType'
        where_val -- The WHERE query values for the where_col (list). e.g. ['value1', 'value2']
        geo_col -- Is there a geometry column in the table?
        epsg -- The coordinate system (int)
        export -- Should the data be exported
        path -- The path and csv name for the export if 'export' is True (str)
        """
        if col_names is None and where_col is None:
            stmt1 = 'SELECT * FROM ' + table
        elif where_col is None:
            stmt1 = 'SELECT ' + str(col_names).replace('\'', '"')[1:-1] + ' FROM ' + table
        else:
            stmt1 = 'SELECT ' + str(col_names).replace('\'', '"')[1:-1] + ' FROM ' + table + ' WHERE ' + str([where_col]).replace('\'', '"')[1:-1] + ' IN (' + str(where_val)[1:-1] + ')'
        conn = connect(server, database=database)
        df = read_sql(stmt1, conn)
    
        ## Read in geometry if required
        if geo_col:
            geo_col_stmt = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=" + "\'" + table + "\'" + " AND DATA_TYPE='geometry'"
            geo_col = str(read_sql(geo_col_stmt, conn).iloc[0,0])
            if where_col is None:
                stmt2 = 'SELECT ' + geo_col + '.STGeometryN(1).ToString()' + ' FROM ' + table
            else:
                stmt2 = 'SELECT ' + geo_col + '.STGeometryN(1).ToString()' + ' FROM ' + table + ' WHERE ' + str([where_col]).replace('\'', '"')[1:-1] + ' IN (' + str(where_val)[1:-1] + ')'
            df2 = read_sql(stmt2, conn)
            df2.columns = ['geometry']
            geometry = [loads(x) for x in df2.geometry]
            df = GeoDataFrame(df, geometry=geometry, crs={'init' :'epsg:' + str(epsg)})
    
        if export:
            df.to_csv(path, index=False)
    
        conn.close()
        return(df)
    

    编辑:使函数自动查找几何字段(如果存在)。

    【讨论】:

    • SQL Server does not guarantee row order 在结果集中,因此您传递给 GeoDataFrame 的几何图形可能与现有数据框行不匹配。您应该明确控制 df 和 df2 的查询顺序以保证正确的结果。
    【解决方案2】:

    喜欢这个函数,感谢 Dryden,但提取几何的代码存在多多边形字段的问题。如果其中一个记录的几何形状是多面体,并且您使用 .STGeometryN(1) 代码,那么您只会获得记录中可能存在的多个多边形中的第一个。地理数据框不会以该记录的总几何图形结束。您调整代码并删除它应该处理多面体的 .STGeometryN(1)。

    我用它来提取我存储在 SQL Server 中的人口普查块组,并进行了一些调整(应该包括数据库架构参数)我让它工作但我会警告其他使用它的人以确保你知道首先在 SQL 中使用此查询,您的数据中是否有多面体。

    select geometrycolumn.STGeometryType(), 
    ,geometrycolumn.STNumGeometries() 
     from yourtable
     order by 1
    

    这将告诉您是否有多个多边形以及每条记录有多少个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-04
      • 1970-01-01
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 2020-07-22
      • 1970-01-01
      相关资源
      最近更新 更多