def test_iter_intersects(self): points = self.geom_michigan_point_grid si = SpatialIndex() ids = points.keys() geoms = [points[i] for i in ids] si.add(ids, geoms) intersects_ids = list(si.iter_intersects(self.geom_michigan, points)) self.assertEqual(set(intersects_ids), set([22, 23, 24, 32, 33, 34, 35, 36, 42, 43, 44, 46, 56, 66, 67, 76]))
def test_rtree(self): from ocgis.util.spatial.index import SpatialIndex geom_mapping = {1: Point(1, 2)} si = SpatialIndex() si.add(1, Point(1, 2)) ret = list(si.iter_intersects(Point(1, 2), geom_mapping)) self.assertEqual(ret, [1])
def test_iter_intersects_with_polygon(self): polygon = self.geom_michigan[1] si = SpatialIndex() points = self.geom_michigan_point_grid ids = points.keys() geoms = [points[i] for i in ids] si.add(ids, geoms) intersects_ids = list(si.iter_intersects(polygon, points)) self.assertEqual(intersects_ids, [67])
def test_iter_intersects_with_polygon(self): polygon = self.geom_michigan[1] # print 'michigan',self.write_geom_dict({1:polygon},geometry_type='Polygon') si = SpatialIndex() points = self.geom_michigan_point_grid ids = points.keys() geoms = [points[i] for i in ids] si.add(ids,geoms) intersects_ids = list(si.iter_intersects(polygon,points)) # new_geoms = {i:points[i] for i in intersects_ids} # print 'points',self.write_geom_dict(new_geoms) self.assertEqual(intersects_ids,[67])
def test_keep_touches(self): points = self.geom_michigan_point_grid si = SpatialIndex() ids = points.keys() geoms = [points[i] for i in ids] si.add(ids,geoms) touch_geom = Point(*mapping(self.geom_michigan)['coordinates'][0][0][3]) si.add(1000,touch_geom) points[1000] = touch_geom for keep_touches in [True,False]: intersects_ids = list(si.iter_intersects(self.geom_michigan,points,keep_touches=keep_touches)) if keep_touches: self.assertIn(1000,intersects_ids) else: self.assertNotIn(1000,intersects_ids)
def get_intersects_masked(self,polygon,use_spatial_index=True): ''' :param polygon: The Shapely geometry to use for subsetting. :type polygon: :class:`shapely.geometry.Polygon' or :class:`shapely.geometry.MultiPolygon' :param bool use_spatial_index: If ``False``, do not use the :class:`rtree.index.Index` for spatial subsetting. If the geometric case is simple, it may marginally improve execution times to turn this off. However, turning this off for a complex case will negatively impact (significantly) spatial operation execution times. :raises: NotImplementedError, EmptySubsetError :returns: :class:`ocgis.interface.base.dimension.spatial.SpatialGeometryPointDimension` ''' ## only polygons are acceptable for subsetting. if a point is required, ## buffer it. if type(polygon) not in (Polygon,MultiPolygon): raise(NotImplementedError(type(polygon))) ## return a shallow copy of self ret = copy(self) ## create the fill array and reference the mask. this is the outpout ## geometry value array. fill = np.ma.array(ret.value,mask=True) ref_fill_mask = fill.mask ## this is the path if a spatial index is used. if use_spatial_index: ## keep this as a local import as it is not a required dependency from ocgis.util.spatial.index import SpatialIndex ## create the index object and reference import members si = SpatialIndex() _add = si.add _value = self.value ## add the geometries to the index for (ii,jj),id_value in iter_array(self.uid,return_value=True): _add(id_value,_value[ii,jj]) ## this mapping simulates a dictionary for the item look-ups from ## two-dimensional arrays geom_mapping = GeomMapping(self.uid,self.value) _uid = ret.uid ## return the identifiers of the objects intersecting the target geometry ## and update the mask accordingly for intersect_id in si.iter_intersects(polygon,geom_mapping,keep_touches=False): sel = _uid == intersect_id ref_fill_mask[sel] = False ## this is the slower simpler case else: ## prepare the polygon for faster spatial operations prepared = prep(polygon) ## we are not keeping touches at this point. remember the mask is an ## inverse. for (ii,jj),geom in iter_array(self.value,return_value=True): bool_value = False if prepared.intersects(geom): if polygon.touches(geom): bool_value = True else: bool_value = True ref_fill_mask[ii,jj] = bool_value ## if everything is masked, this is an empty subset if ref_fill_mask.all(): raise(EmptySubsetError(self.name)) ## set the returned value to the fill array ret._value = fill ## also update the unique identifier array ret.uid = np.ma.array(ret.uid,mask=fill.mask.copy()) return(ret)