Source code for ibmdbpy.geoFrame

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#-----------------------------------------------------------------------------
# Copyright (c) 2015, IBM Corp.
# All rights reserved.
#
# Distributed under the terms of the BSD Simplified License.
#
# The full license is in the LICENSE file, distributed with this software.
#-----------------------------------------------------------------------------

"""
IdaGeoDataFrame
"""

# Ensure Python 2 compatibility
from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals
from __future__ import absolute_import
from builtins import super
from builtins import zip
from builtins import str
from builtins import int
from future import standard_library
standard_library.install_aliases()

import ibmdbpy
from ibmdbpy.frame import IdaDataFrame
from ibmdbpy.geoSeries import IdaGeoSeries

from copy import deepcopy

import six


[docs]class IdaGeoDataFrame(IdaDataFrame): """ An IdaGeoDataFrame container inherits from IdaDataFrame. It has a property called "geometry" which refers to a column with geometry type. It is set as a string with a column name, either at instantiation time or with the set_geometry() method. If the "geometry" property is set, when calling a geospatial method from IdaDataFrame the method will be carried on the column this property refers to. The property "geometry" returns an IdaGeoSeries. See IdaDataFrame. See IdaGeoSeries. Examples -------- >>> idageodf = IdaGeoDataFrame(idadb, 'SAMPLES.GEO_COUNTY', indexer='OBJECTID') >>> idageodf.dtypes TYPENAME OBJECTID INTEGER SHAPE ST_MULTIPOLYGON STATEFP VARCHAR COUNTYFP VARCHAR COUNTYNS VARCHAR NAME VARCHAR GEOID VARCHAR NAMELSAD VARCHAR LSAD VARCHAR CLASSFP VARCHAR MTFCC VARCHAR CSAFP VARCHAR CBSAFP VARCHAR METDIVFP VARCHAR FUNCSTAT VARCHAR ALAND DECIMAL AWATER DECIMAL INTPTLAT VARCHAR INTPTLON VARCHAR >>> idageodf[['NAME', 'SHAPE']].head() NAME SHAPE 0 Becker MULTIPOLYGON (((-95.1637185512 46.7176480983, ... 1 Jim Hogg MULTIPOLYGON (((-98.9542377853 26.7856984795, ... 2 Henry MULTIPOLYGON (((-88.0532984194 36.4970648458, ... 3 Keith MULTIPOLYGON (((-102.0517705602 41.0038968011,... 4 Clinton MULTIPOLYGON (((-94.2059683962 39.7458481141, ... >>> idageodf.geometry AttributeError: Geometry property has not been set yet. Use set_geometry method to set it. >>> idageodf.set_geometry('SHAPE') >>> idageodf.geometry.column 'SHAPE' >>> type(idageodf.geometry) <class 'ibmdbpy.geoSeries.IdaGeoSeries'> >>> idageoseries = idageodf.geometry >>> idageoseries.head() 0 MULTIPOLYGON (((-95.1637185512 46.7176480983, ... 1 MULTIPOLYGON (((-98.9542377853 26.7856984795, ... 2 MULTIPOLYGON (((-88.0532984194 36.4970648458, ... 3 MULTIPOLYGON (((-102.0517705602 41.0038968011,... 4 MULTIPOLYGON (((-94.2059683962 39.7458481141, ... Name: SHAPE, dtype: object >>> idageodf['County area'] = idageodf.area(unit='mile') >>> counties_with_areas = idageodf[['NAME', 'SHAPE', 'County area']] >>> counties_with_areas.dtypes TYPENAME NAME VARCHAR SHAPE ST_MULTIPOLYGON County area DOUBLE >>> counties_with_areas.head() NAME SHAPE County area 0 Menard MULTIPOLYGON (((-99.4847630885 30.940610279, ... 902.281540 1 Boone MULTIPOLYGON (((-88.7764991497 42.491919892, ... 282.045087 2 Ochiltree MULTIPOLYGON (((-100.5467326897 36.056542135,... 918.188142 3 Sharkey MULTIPOLYGON (((-90.9143429922 33.007703026, ... 435.548518 4 Audubon MULTIPOLYGON (((-94.7006367168 41.504155369, ... 444.827726 """
[docs] def __init__(self, idadb, tablename, indexer = None, geometry = None): """ Constructor for IdaGeoDataFrame objects. See IdaDataFrame.__init__ documentation. Parameters ---------- geometry : str, optional Column name to set the "geometry" property of the IdaGeoDataFrame. The column must have geometry type. Attributes ---------- _geometry_colname : str Name of the column that "geometry" property refers to. This attribute must be set through the set_geometry() method. geometry : IdaGeoSeries The column referenced by _geometry_colname attribute. """ # TODO: Add support for receiving either a string or an IdaGeoSeries as # geometry parameter. if geometry is not None and not isinstance(geometry, six.string_types): raise TypeError("geometry must be a string") super(IdaGeoDataFrame, self).__init__(idadb, tablename, indexer) self._geometry_colname = None if geometry is not None: self.set_geometry(geometry)
def __getitem__(self, item): """ Returns an IdaDataFrame, IdaSeries, IdaGeoDataFrame or IdaGeoSeries as appropriate. Returns -------- IdaGeoSeries When the projection has only one column and it has geometry type. IdaGeoDataFrame When the projection has more than one column, and the "geometry" column of the IdaGeoDataFrame is included in them. IdaDataFrame When the projection has more than one column, and the "geometry" column of the IdaGeoDataFrame is not included in them. IdaSeries When the projection has only one column and it doesn't have geometry type. """ ida = super(IdaGeoDataFrame, self).__getitem__(item) if isinstance(ida, ibmdbpy.IdaSeries): if ida.dtypes['TYPENAME'][ida.column].find('ST_') == 0: idageoseries = IdaGeoSeries.from_IdaSeries(ida) # Return IdaGeoSeries return idageoseries else: # Return IdaSeries return ida elif isinstance(ida, ibmdbpy.IdaDataFrame): if self._geometry_colname in ida.dtypes.index: # Return IdaGeoDataFrame idageodf = IdaGeoDataFrame.from_IdaDataFrame(ida) idageodf._geometry_colname = self._geometry_colname return idageodf else: # Return IdaDataFrame return ida def __delitem__(self, item): """ Erases the "geometry" property if the column it refers to is deleted. """ super(IdaGeoDataFrame, self).__delitem__(item) if item == self._geometry_colname: self._geometry_colname = None def __getattr__(self, name): """ Carry geospatial method calls on the "geometry" column of the IdaGeoDataFrame, if it was set. Notes ----- This method gets called only when an attribute lookup on IdaGeoDataFrame is not resolved, i.e. it is not an instance attribute and it's not found in the class tree. """ if name == 'geometry': # When .geometry is accessed and _geometry_colname is None return self.__getattribute__('geometry') if hasattr(IdaGeoSeries, name): # Geospatial method call if self._geometry_colname is None: raise AttributeError("Geometry column has not been set yet.") else: # Get a IdaGeoSeries and carry the operation on it idageoseries = self.__getitem__(item = self._geometry_colname) return idageoseries.__getattribute__(name) else: raise AttributeError @property def geometry(self): """ Returns an IdaGeoSeries with the column whose name is stored in _geometry_colname attribute. The setter calls the set_geometry() method. Returns ------- IdaGeoSeries Raises ------ AttributeError If the property has not been set yet. """ if self._geometry_colname is None: raise AttributeError( "Geometry property has not been set yet. " "Use set_geometry method to set it.") else: return self.__getitem__(self._geometry_colname) @geometry.setter def geometry(self, value): """ See set_geometry() method. """ self.set_geometry(value) @classmethod
[docs] def from_IdaDataFrame(cls, idadf, geometry = None): """ Creates an IdaGeoDataFrame from an IdaDataFrame. Parameters ---------- geometry : str, optional Column name to set the "geometry" property of the IdaGeoDataFrame. The column must have geometry type. Raises ------ TypeError If idadf is not an IdaDataFrame. """ if not isinstance(idadf, IdaDataFrame): raise TypeError("Expected IdaDataFrame") else: # TODO: check if it's better to only change the .__base__ attribute #behavior based on _clone() method of IdaDataFrame newida = IdaGeoDataFrame( idadf._idadb, idadf._name, idadf.indexer, geometry) newida.columns = idadf.columns newida.dtypes = idadf.dtypes newida.internal_state.name = deepcopy(idadf.internal_state.name) newida.internal_state.ascending = deepcopy(idadf.internal_state.ascending) #newida.internal_state.views = deepcopy(idadf.internal_state.views) newida.internal_state._views = deepcopy(idadf.internal_state._views) newida.internal_state._cumulative = deepcopy(idadf.internal_state._cumulative) newida.internal_state.order = deepcopy(idadf.internal_state.order) newida.internal_state.columndict = deepcopy(idadf.internal_state.columndict) return newida
[docs] def set_geometry(self, column_name): """ Receives a column name to set as the "geometry" column of the IdaDataFrame. Parameters: ----------- column_name : str Name of the column to be set as geometry column of the IdaDataFrame. It must have geometry type. Raises ------ KeyError If the column is not present in the IdaGeoDataFrame. TypeError If the column doesn't have geometry type. """ if not isinstance(column_name, six.string_types): raise TypeError("column_name must be a string") if column_name not in self.columns: raise KeyError( "'" + column_name + "' cannot be set as geometry column: " "not a column in the IdaGeoDataFrame." ) elif self.dtypes.TYPENAME[column_name].find('ST_') != 0: raise TypeError( "'" + column_name + "' cannot be set as geometry column: " "column doesn't have geometry type." ) else: self._geometry_colname = column_name # ============================================================================== ### Binary geospatial methods # ==============================================================================
[docs] def equals(self, ida2): """ Valid types for the column in the calling IdaGeoDataFrame: ST_Geometry or one of its subtypes. Returns an IdaGeoDataFrame of indices of the two input IdaGeoDataFrames and a result column with 1 or 0 depending upon whether the geometry of the first IdaGeoDataFrame crosses the second. For None geometries the output is None. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. References ---------- DB2 Spatial Extender ST_CROSSES() function. Examples -------- >>> counties = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> counties.set_geometry('SHAPE') >>> ida1 = counties[counties['NAME'] == 'Austin'] >>> ida2 = counties[counties['NAME'] == 'Kent'] >>> result = ida1.equals(ida2) >>> result.head() INDEXERIDA1 INDEXERIDA2 RESULT 2 163 0 2 1840 0 2 109 0 """ return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_EQUALS', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
[docs] def distance(self, ida2, unit=None): """ Valid types for the column in the calling IdaGeoDataFrame: ST_Geometry or one of its subtypes. Returns an IdaGeoDataFrame of indices of the two input IdaGeoDataFrames and a result column with a numeric value which is the geographic distance measured between the geometries of the input IdaGeoDataFrames. For None geometries the output is None. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. unit : str, optional Name of the unit, it is case-insensitive. If omitted, the following rules are used: * If geometry is in a projected or geocentric coordinate system, the linear unit associated with this coordinate system is used. * If geometry is in a geographic coordinate system, the angular unit associated with this coordinate system is used. References ---------- DB2 Spatial Extender ST_DISTANCE() function. Examples -------- >>> counties = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> counties.set_geometry('SHAPE') >>> ida1 = counties[counties['NAME'] == 'Austin'] >>> ida2 = counties[counties['NAME'] == 'Kent'] >>> result = ida1.distance(ida2,unit = 'KILOMETER') >>> result.head() INDEXERIDA1 INDEXERIDA2 RESULT 2 163 26.918942 2 1840 4.868971 2 109 16.387094 """ additional_args = [] if unit is not None: unit = self._check_linear_unit(unit) # Can raise exceptions additional_args.append(unit) return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_DISTANCE', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
[docs] def crosses(self, ida2): """ Valid types for the column in the calling IdaGeoDataFrame: ST_Geometry or one of its subtypes. Returns an IdaGeoDataFrame of indices of the two input IdaGeoDataFrames and a result column with 1 or 0 depending upon whether the geometry of the first IdaGeoDataFrame crosses the second. For None geometries the output is None. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. References ---------- DB2 Spatial Extender ST_CROSSES() function. See also -------- linear_units : list of valid units. Examples -------- >>> counties = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> counties.set_geometry('SHAPE') >>> ida1 = counties[counties['NAME'] == 'Austin'] >>> ida2 = counties[counties['NAME'] == 'Kent'] >>> result = ida1.crosses(ida2) >>> result.head() INDEXERIDA1 INDEXERIDA2 RESULT 2 163 0 2 1840 0 2 109 0 """ return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_CROSSES', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
[docs] def intersects(self, ida2): """ Valid types for the column in the calling IdaGeoDataFrame: ST_Geometry or one of its subtypes. Returns an IdaGeoDataFrame of indices of the two input IdaGeoDataFrames and a result column with 1 or 0 depending upon whether the geometries of the input IdaGeoDataFrames intersect each other. For None geometries the output is None. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. References ---------- DB2 Spatial Extender ST_INTERSECTS() function. Examples -------- >>> counties = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> counties.set_geometry('SHAPE') >>> ida1 = counties[counties['NAME'] == 'Austin'] >>> ida2 = counties[counties['NAME'] == 'Kent'] >>> result = ida1.intersects(ida2) >>> result.head() INDEXERIDA1 INDEXERIDA2 RESULT 2 163 0 2 1840 0 2 109 0 """ return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_INTERSECTS', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
[docs] def overlaps(self, ida2): """ Valid types for the column in the calling IdaGeoDataFrame: ST_Geometry or one of its subtypes. Returns an IdaGeoDataFrame of indices of the two input IdaGeoDataFrames and a result column with 1 or 0 depending upon whether the geometries of the input IdaGeoDataFrames overlap each other. For None geometries the output is None. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. References ---------- DB2 Spatial Extender ST_OVERLAPS() function. Examples -------- >>> counties = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> counties.set_geometry('SHAPE') >>> ida1 = counties[counties['NAME'] == 'Austin'] >>> ida2 = counties[counties['NAME'] == 'Kent'] >>> result = ida1.overlaps(ida2) >>> result.head() INDEXERIDA1 INDEXERIDA2 RESULT 2 163 0 2 1840 0 2 109 0 """ return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_OVERLAPS', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
[docs] def touches(self, ida2): """ Valid types for the column in the calling IdaGeoDataFrame: ST_Geometry or one of its subtypes. Returns an IdaGeoDataFrame of indices of the two input IdaGeoDataFrames and a result column with 1 or 0 depending upon whether the boundary of the first geometry touches the second. For None geometries the output is None. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. References ---------- DB2 Spatial Extender ST_TOUCHES() function. Examples -------- >>> counties = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> counties.set_geometry('SHAPE') >>> ida1 = counties[counties['NAME'] == 'Austin'] >>> ida2 = counties[counties['NAME'] == 'Kent'] >>> result = ida1.touches(ida2) >>> result.head() INDEXERIDA1 INDEXERIDA2 RESULT 2 163 0 2 1840 0 2 109 0 """ return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_TOUCHES', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
[docs] def disjoint(self, ida2): """ Valid types for the column in the calling IdaGeoDataFrame: ST_Geometry or one of its subtypes. Returns an IdaGeoDataFrame of indices of the two input IdaGeoDataFrames and a result column with 1 or 0 depending upon whether the geometries in the input dataframes are disjoint. For None geometries the output is None. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. References ---------- DB2 Spatial Extender ST_DISJOINT() function. Examples -------- >>> counties = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> counties.set_geometry('SHAPE') >>> ida1 = counties[counties['NAME'] == 'Austin'] >>> ida2 = counties[counties['NAME'] == 'Kent'] >>> result = ida1.disjoint(ida2) >>> result.head() INDEXERIDA1 INDEXERIDA2 RESULT 2 163 1 2 1840 1 2 109 1 """ return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_DISJOINT', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
[docs] def contains(self, ida2): """ Valid types for the column in the calling IdaGeoDataFrame: ST_Geometry or one of its subtypes. Returns an IdaGeoDataFrame of indices of the two input IdaGeoDataFrames and a result column with 1 or 0 depending upon whether the second geometry contains the first. For None geometries the output is None. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. References ---------- DB2 Spatial Extender ST_CONTAINS() function. Examples -------- >>> idageodf_customer = IdaGeoDataFrame(idadb,'SAMPLES.GEO_CUSTOMER',indexer='OBJECTID') >>> idageodf_customer.set_geometry('SHAPE') >>> idageodf_county = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> idageodf_county.set_geometry('SHAPE') >>> ida1 = idageodf_customer[idageodf_customer['INSURANCE_VALUE']>250000] >>> ida2 = idageodf_county[idageodf_county['NAME']=='Madison'] >>> result = ida2.contains(ida1) >>> result[result['RESULT']==1].head() INDEXERIDA1 INDEXERIDA2 RESULT 21473 134 1 21413 134 1 21414 134 1 21417 134 1 21419 134 1 """ return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_CONTAINS', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
[docs] def within(self, ida2): """ Valid types for the column in the calling IdaGeoDataFrame: ST_Geometry or one of its subtypes. Returns an IdaGeoDataFrame of indices of the two input IdaGeoDataFrames and a result column with 1 or 0 depending upon whether the first geometry is inside the second. For None geometries the output is None. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. References ---------- DB2 Spatial Extender ST_WITHIN() function. Examples -------- >>> idageodf_customer = IdaGeoDataFrame(idadb,'SAMPLES.GEO_CUSTOMER',indexer='OBJECTID') >>> idageodf_customer.set_geometry('SHAPE') >>> idageodf_county = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> idageodf_county.set_geometry('SHAPE') >>> ida1 = idageodf_customer[idageodf_customer['INSURANCE_VALUE']>250000] >>> ida2 = idageodf_county[idageodf_county['NAME']=='Madison'] >>> result = ida1.within(ida2) >>> result[result['RESULT']==1].head() INDEXERIDA1 INDEXERIDA2 RESULT 134 21473 1 134 21413 1 134 21414 1 134 21417 1 134 21419 1 """ return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_WITHIN', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
[docs] def mbr_intersects(self, ida2): """ This method takes a second IdaGeoDataFrame an an input and checks if the Minimum Bounding rectangles of the geometries from both IdaGeoDataFrames intersect and stores the result as 0 or 1 in the RESULT column of the resulting IdaGeoDataFrame. For None geometries the output is None. For empty geometries the output is None. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. References ---------- DB2 Spatial Extender ST_MBRIntersects() function. Examples -------- >>> counties = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> counties.set_geometry('SHAPE') >>> ida1 = counties[counties['NAME'] == 'Austin'] >>> ida2 = counties[counties['NAME'] == 'Kent'] >>> result = ida1.difference(ida2) >>> result.head() INDEXERIDA1 INDEXERIDA2 RESULT 2 163 0 2 1840 0 2 109 0 """ return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_MBRINTERSECTS', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
[docs] def difference(self, ida2): """ This method takes a second IdaGeoDataFrame an an input and returns the difference of the geometries from both IdaGeoDataFrames as a new geometry stored in the RESULT column of the resulting IdaGeoDataFrame. For None geometries the output is None. For empty geometries the output is None. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. References ---------- DB2 Spatial Extender ST_Difference() function. Examples -------- >>> counties = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> counties.set_geometry('SHAPE') >>> ida1 = counties[counties['NAME'] == 'Austin'] >>> ida2 = counties[counties['NAME'] == 'Kent'] >>> result = ida1.difference(ida2) >>> result.head() INDEXERIDA1 INDEXERIDA2 RESULT 2 163 POLYGON ((-96.6219873342 30.0442882117, -96.61... 2 1840 POLYGON ((-96.6219873342 30.0442882117, -96.61... 2 109 POLYGON ((-96.6219873342 30.0442882117, -96.61... """ return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_DIFFERENCE', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
[docs] def intersection(self, ida2): """ This method takes a second IdaGeoDataFrame an an input and returns the intersection of the geometries from both IdaGeoDataFrames as a new geometry stored in the RESULT column of the resulting IdaGeoDataFrame. For None geometries the output is None. For empty geometries the output is POINT EMPTY. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. References ---------- DB2 Spatial Extender ST_Intersection() function. Examples -------- >>> counties = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> counties.set_geometry('SHAPE') >>> ida1 = counties[counties['NAME'] == 'Austin'] >>> ida2 = counties[counties['NAME'] == 'Kent'] >>> result = ida1.intersection(ida2) >>> result.head() INDEXERIDA1 INDEXERIDA2 RESULT 2 163 POINT EMPTY 2 1840 POINT EMPTY 2 109 POINT EMPTY """ return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_INTERSECTION', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
[docs] def union(self, ida2): """ This method takes a second IdaGeoDataFrame an an input and returns the union of the geometries from both IdaGeoDataFrames as a new geometry stored in the RESULT column of the resulting IdaGeoDataFrame. For None geometries the output is None. For empty geometries the output is None. Returns ------- Returns an IdaGeoDataFrame with three columns: INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation Parameters ---------- ida2 : IdaGeoDataFrame Name of the second IdaGeoDataFrame on which the function ST_EQUALS() will be invoked. References ---------- DB2 Spatial Extender ST_Union() function. Examples -------- >>> counties = IdaGeoDataFrame(idadb,'SAMPLES.GEO_COUNTY',indexer='OBJECTID') >>> counties.set_geometry('SHAPE') >>> ida1 = counties[counties['NAME'] == 'Austin'] >>> ida2 = counties[counties['NAME'] == 'Kent'] >>> result = ida1.union(ida2) >>> result.head() INDEXERIDA1 INDEXERIDA2 RESULT 2 163 MULTIPOLYGON (((-96.6219873342 30.0442882117, ... 2 1840 MULTIPOLYGON (((-96.6219873342 30.0442882117, ... 2 109 MULTIPOLYGON (((-96.6219873342 30.0442882117, .. """ return self._binary_operation_handler( ida2, db2gse_function='DB2GSE.ST_UNION', valid_types_ida1=['ST_GEOMETRY'], valid_types_ida2=['ST_GEOMETRY'])
def _binary_operation_handler(self, ida2, db2gse_function, valid_types_ida1, valid_types_ida2, additional_args=None): """ Returns an IdaGeoDataFrame with three columns: [ INDEXERIDA1 : indexer of the first IdaGeoSeries (None if not set), INDEXERIDA2 : indexer of the second IdaGeoSeries (None if not set), RESULT : the result of the operation ] Parameters ---------- db2gse_function : str Name of the corresponding DB2GSE function. valid_types_ida1 : list of str Valid input typenames for the first IdaGeoSeries. valid_types_ida2 : list of str Valid input typenames for the second IdaGeoSeries. additional_args : list of str, optional Additional arguments for the DB2GSE function. Returns ------- IdaGeoDataFrame """ ida1 = self # For code clearness if not (ida1.dtypes.TYPENAME[0] in valid_types_ida1 or valid_types_ida1[0] == 'ST_GEOMETRY'): raise TypeError("Column " + ida1.column + " has incompatible type.") if not (ida2.dtypes.TYPENAME[0] in valid_types_ida2 or valid_types_ida2[0] == 'ST_GEOMETRY'): raise TypeError("Column " + ida1.column + " has incompatible type.") # Get the definitions of the columns, which will be the arguments for # the DB2GSE function column1_for_db2gse = ida1.internal_state.columndict[self.geometry.column] if column1_for_db2gse[0] == '\"' and column1_for_db2gse[-1] == '\"': column1_for_db2gse = column1_for_db2gse[1:-1] column2_for_db2gse = ida2.internal_state.columndict[self.geometry.column] if column2_for_db2gse[0] == '\"' and column2_for_db2gse[-1] == '\"': column2_for_db2gse = column2_for_db2gse[1:-1] arguments_for_db2gse_function = [] arguments_for_db2gse_function.append('IDA1.' + column1_for_db2gse) arguments_for_db2gse_function.append('IDA2.' + column1_for_db2gse) if additional_args is not None: for arg in additional_args: arguments_for_db2gse_function.append(arg) # SELECT statement select_columns = [] if hasattr(ida1, '_indexer') and ida1._indexer is not None: select_columns.append('IDA1.\"%s\" AS \"INDEXERIDA1\"' % (ida1.indexer)) else: message = (ida1 + "has no indexer defined. Please assign index column with set_indexer and retry.") raise IdaGeoDataFrameError(message) if hasattr(ida2, '_indexer') and ida2._indexer is not None: select_columns.append('IDA2.\"%s\" AS \"INDEXERIDA2\"' % (ida1.indexer)) else: message = (ida2 + "has no indexer defined. Please assign index column with set_indexer and retry.") raise IdaGeoDataFrameError(message) result_column = ( db2gse_function + '(' + ','.join(map(str, arguments_for_db2gse_function)) + ')' ) select_columns.append('%s AS \"RESULT\"' % (result_column)) select_statement = 'SELECT ' + ','.join(select_columns) + ' ' # FROM clause from_clause = ( 'FROM ' + ida1.name + ' AS IDA1, ' + ida2.name + ' AS IDA2 ' ) # Create a view view_creation_query = '(' + select_statement + from_clause + ')' viewname = self._idadb._create_view_from_expression( view_creation_query) idageodf = ibmdbpy.IdaGeoDataFrame(self._idadb, viewname,indexer= 'INDEXERIDA1') return idageodf