def test_bounds(self): from next.model.models import Scenario, Node from next.views import show_phases request = testing.DummyRequest() sc1 = self.session.query(Scenario).filter(Scenario.name == "Test").first() nodes = self.session.query(Node).filter(Node.scenario_id == sc1.id).all() bounds = Polygon([(-2, -2), (1, -2), (1, 1), (-2, 1), (-2, -2)]) actual_bounds = sc1.get_bounds(srid=4326) self.assertTrue(bounds.equals(actual_bounds)) phase1 = sc1.phases[0] bounds = Polygon([(-1, -1), (1, -1), (1, 1), (-1, 1), (-1, -1)]) actual_bounds = phase1.get_bounds(srid=4326) self.assertTrue(bounds.equals(actual_bounds))
def test_polygonSplit_cutThroughHole(self): P = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)], [[(0.2, 0.2), (0.2, 0.8), (0.8, 0.8), (0.8, 0.2)]]) e = LineString([(0.2, 0), (0.2, 1)]) result = polygon_split(P, e) R1 = Polygon([(0.2, 0), (0, 0), (0, 1), (0.2, 1), (0.2, 0.8), (0.2, 0.2), (0.2, 0)]) R2 = Polygon([(0.2, 1), (1, 1), (1, 0), (0.2, 0), (0.2, 0.2), (0.8, 0.2), (0.8, 0.8), (0.2, 0.8), (0.2, 1)]) self.assertTrue(R1.equals(result[0]) and R2.equals(result[1]))
def checkExtent(self, metaExtent, checkExtent, operation): """ @summary: checks polygons against operation @param metaExtent: list in the format [minx,miny,maxx,maxy] @param checkExtent: list in the format [minx,miny,maxx,maxy] """ metaExtent = [float(x) for x in metaExtent] checkExtent = [float(x) for x in checkExtent] metaPoly = Polygon( ((metaExtent[0], metaExtent[1]), (metaExtent[0], metaExtent[3]), (metaExtent[2], metaExtent[3]), (metaExtent[2], metaExtent[1]))) checkPoly = Polygon( ((checkExtent[0], checkExtent[1]), (checkExtent[0], checkExtent[3]), (checkExtent[2], checkExtent[3]), (checkExtent[2], checkExtent[1]))) if operation == "Contains": return checkPoly.contains(metaPoly) if operation == "Intersects": return checkPoly.intersects(metaPoly) if operation == "Equals": return checkPoly.equals(metaPoly) if operation == "Touches": return checkPoly.touches(metaPoly) if operation == "Within": return checkPoly.within(metaPoly) if operation == "Outside": return checkPoly.disjoint(metaPoly)
def get_baseline(self, image_bytes): ggl = self.get_ggl_ocr_data(image_bytes) tes = self.get_tes_ocr_data(image_bytes)[['text', 'poly']].copy() should_restart = True while should_restart: should_restart = False for i, trow in tes.iterrows(): for j, grow in ggl.iterrows(): tpoly = Polygon(trow['poly']) gpoly = Polygon(grow['poly']) if (self.has_intersection(tpoly, gpoly) and not tpoly.equals(gpoly)): points = np.array(trow['poly'] + grow['poly']) min_x, min_y, max_x, max_y = ( self.get_bbox_values(points)) bbox = [(min_x, min_y), (max_x, min_y), (max_x, max_y), (min_x, max_y)] tes['poly'].iloc[i] = bbox ggl['poly'].iloc[j] = bbox should_restart = True break collated = self.collate_data(ggl, tes, col_poly='poly') baseline = collated.apply(self.compare_text, axis=1) baseline = baseline[(baseline['res'] == 'matched') & (baseline['text_g'].str.len() >= 2)] baseline['init_scale'] = baseline.apply(self.get_scale_ratio, axis=1) self.baseline = baseline return baseline
def frame(input_path, correct_path): ''' Input is a 3 x 3 grid. The bounding frame should be created around the extents of the input shapefile that is contiguous input_path: path to shapefile that we will be created a bounding frame around correct_path: path to correct bounding frame shapefile ''' # load in correct bounding frame shapefile correct = fm.load_shapefile(correct_path) correct = gpd.read_file(correct_path) # load testing shapefile and create bounding frame shapefile df = fm.load_shapefile(input_path) created = sm.generate_bounding_frame(df) # Check if polygon created by correct_frame's and created_frame's interior # are equal # Get polygon created by the frame's interior ix = correct.index.values[0] correct_frame = correct.at[ix, 'geometry'] correct_interior = Polygon(correct_frame.interiors[0]) # Get polygon created by the bounds of the input ix = correct.index.values[0] created_frame = created.at[ix, 'geometry'] created_interior = Polygon(created_frame.interiors[0]) # Check equality between the two interiors assert correct_interior.equals(created_interior)
def testLocator(self): image = mk_img(400, 600) # draw a rectangle A = (5, 5) B = (5, 300) C = (250, 5) D = (250, 300) ABCD = Polygon([A, B, D, C, A]) image = draw_poly(image, ABCD) # locate it locator = BinaryLocator() located = locator.locate(image) polygons, labels = zip(*located) self.assertEqual(1, len(located), "One polygon found") self.assertTrue(ABCD.equals(polygons[0]), "Found polygon has the same shape") # test locate with an offset locator2 = BinaryLocator() located2 = locator2.locate(image, offset=(50, 40)) polygons2, labels2 = zip(*located2) self.assertEqual(1, len(located2), "One polygon found") self.assertTrue( translate(ABCD, 50, 40).equals(polygons2[0]), "Found translated polygon")
def processPastDetection (bbox, label, conf,mid): mon_file = g.config['image_path'] + '/monitor-'+mid +'-data.pkl' g.logger.debug ('trying to load '+mon_file) try: fh = open(mon_file, "rb") saved_bs = pickle.load(fh) saved_ls = pickle.load(fh) saved_cs = pickle.load(fh) except FileNotFoundError: g.logger.debug ('No history data file found for monitor {}'.format(mid)) return bbox, label, conf # load past detection #g.logger.debug ('loaded past: bbox={}, labels={}'.format(saved_bs, saved_ls)); new_label = [] new_bbox = [] new_conf = [] for idx, b in enumerate(bbox): # iterate list of detections old_b = b it = iter(b) b = list(zip(it,it)) b.insert(1, (b[1][0], b[0][1])) b.insert(3, (b[0][0], b[1][1])) #g.logger.debug ("Past detection: {}@{}".format(saved_ls[idx],b)) #g.logger.debug ('BOBK={}'.format(b)) obj = Polygon(b) foundMatch = False for saved_idx, saved_b in enumerate(saved_bs): # compare current detection element with saved list from file if saved_ls[saved_idx] != label[idx]: continue it = iter(saved_b) saved_b = list(zip(it,it)) saved_b.insert(1, (saved_b[1][0], saved_b[0][1])) saved_b.insert(3, (saved_b[0][0], saved_b[1][1])) saved_obj = Polygon(saved_b) if obj.equals(saved_obj): g.logger.debug ('past detection {}@{} exactly matches {}@{} removing'.format(saved_ls[saved_idx],saved_b, label[idx],b)) foundMatch = True break if obj.almost_equals(saved_obj): g.logger.debug ('past detection {}@{} approximately matches {}@{} removing'.format(saved_ls[saved_idx],saved_b, label[idx],b)) foundMatch = True break if not foundMatch: new_bbox.append(old_b) new_label.append(label[idx]) new_conf.append(conf[idx]) return new_bbox, new_label, new_conf
def SpatialToplogy (Spatial_A,Spatial_B): if Spatial_A[4] == 'Point' and Spatial_B[4]== 'Point': Point_0=Point(Spatial_A[0],Spatial_A[1]) Point_1=Point(Spatial_B[0],Spatial_B[1]) #Point to point relationships if Point_0.equals(Point_1): return 'Point1 equals Point2' if Point_0.within(Point_1.buffer(2)): return 'Point1 lies within a buffer of 2 m from Point2' if Point_0.overlaps(Point_1): return 'Point1 overlaps Point2' #if Point_0.disjoint(Point_1): return 'Point1 disjoint Point2' #Point to line relationships if Spatial_A[4] == 'Point' and Spatial_B[4]== 'Line': Point_0=Point(Spatial_A[0],Spatial_A[1]) Line_0=LineString([(Spatial_B[0],Spatial_B[1]),(Spatial_B[2],Spatial_B[3])]) if Point_0.touches(Line_0):return 'Point1 touches Line1' if Point_0.within(Line_0.buffer(2)):return 'Point1 lies within a buffer of 2 m from L1' #Point to polygon relationships if Spatial_A[4] == 'Point' and Spatial_B[4]== 'Polygon': Point_0=Point(Spatial_A[0],Spatial_A[1]) Polygon_0=Polygon([(Spatial_B[0],Spatial_B[1]),(Spatial_B[2],Spatial_B[1]),(Spatial_B[2],Spatial_B[3]),(Spatial_B[0],Spatial_B[3])]) if Point_0.touches(Polygon_0):return 'Point1 touches Polygon1' if Point_0.within(Polygon_0):return'Point1 lies within Polygon1' if Point_0.overlaps(Polygon_0):return 'Point1 lies overlaps Polygon1' #Line to line relationships if Spatial_A[4]=='Line' and Spatial_B[4]=='Line': Line_0=LineString([(Spatial_A[0],Spatial_A[1]),(Spatial_A[2],Spatial_A[3])]) Line_1=LineString([(Spatial_B[0],Spatial_B[1]),(Spatial_B[2],Spatial_B[3])]) if Line_0.equals(Line_1):return 'Line0 equals Line1' if Line_0.touches(Line_1):return 'Line0 touches Line1' if Line_0.crosses(Line_1):return 'Line0 crosses Line1' if Line_0.within(Line_1.buffer(2)):return 'Line0 lies within a buffer of 2 m Line1' if Line_0.overlaps(Line_1):return 'Line0 overlaps Line1' #Line to polygon relationships if Spatial_A[4]=='Line' and Spatial_B[4]=='Polygon': Line_0=LineString([(Spatial_A[0],Spatial_A[1]),(Spatial_A[2],Spatial_A[3])]) Polygon_0=Polygon([(Spatial_B[0],Spatial_B[1]),(Spatial_B[2],Spatial_B[1]),(Spatial_B[2],Spatial_B[3]),(Spatial_B[0],Spatial_B[3])]) if Line_0.touches(Polygon_0):return 'Line0 touches Polygon1' if Line_0.crosses(Polygon_0):return 'Line0 crosses Polygon1' if Line_0.within(Polygon_0):return 'Line0 lies within Polygon1' #Polygon to Polygon relationships if Spatial_A[4]=='Polygon' and Spatial_B[4]=='Polygon': Polygon_0=Polygon([(Spatial_A[0],Spatial_A[1]),(Spatial_A[2],Spatial_A[1]),(Spatial_A[2],Spatial_A[3]),(Spatial_A[0],Spatial_A[3])]) Polygon_1=Polygon([(Spatial_B[0],Spatial_B[1]),(Spatial_B[2],Spatial_B[1]),(Spatial_B[2],Spatial_B[3]),(Spatial_B[0],Spatial_B[3])]) if Polygon_0.touches(Polygon_1):return 'Polygon touches Polygon1' if Polygon_0.equals(Polygon_1):return 'Polygon0 equals Polygon1' if Polygon_0.within(Polygon_1):return 'Polygon lies within Polygon1' if Polygon_0.within(Polygon_1.buffer(2)):return 'Polygon lies within a buffer of 2m Polygon1'
def testLocator(self): image = mk_img(400, 600) # draw a rectangle A = (5, 80) B = (5, 300) C = (250, 80) D = (250, 300) ABCD = Polygon([A, B, D, C, A]) image = draw_poly(image, ABCD) image, circle = draw_circle(image, 85, (500, 300), return_circle=True) # test locator locator = BinaryLocator() located = locator.locate(image) polygons, labels = zip(*located) self.assertEqual(2, len(polygons), "Two polygons found") self.assertTrue(ABCD.equals(polygons[1]), "Rectangle polygon is found") self.assertLessEqual(relative_error(polygons[0].area, np.pi * 85 * 85), 0.025)
def testLocate(self): image = mk_img(200, 300) # draw a rectangle A = (3, 40) B = (3, 150) C = (125, 40) D = (125, 150) ABCD = Polygon([A, B, D, C, A]) image = draw_poly(image, ABCD, color=1) image = draw_circle(image, 40, (250, 150), color=2) # test locator locator = SemanticLocator(background=0) located = locator.locate(image) located = sorted(located, key=lambda o: (o[0].centroid.x, o[0].centroid.y)) polygons, labels = zip(*located) self.assertEqual(2, len(polygons), "Two polygons found") self.assertTrue(ABCD.equals(polygons[0]), "Rectangle polygon is found") self.assertLessEqual(relative_error(polygons[1].area, np.pi * 40 * 40), 0.025)
def test_imgaug(): args = [dict(cls='Affine', translate_px=dict(x=-10, y=-10))] imgaug_transform = transforms.ImgAug(args, clip_invalid_ploys=False) img = np.random.rand(100, 200, 3) poly = np.array([[[0, 0, 50, 0, 50, 50, 0, 50]], [[20, 20, 50, 20, 50, 50, 20, 50]]]) box = np.array([[0, 0, 50, 50], [20, 20, 50, 50]]) results = dict(img=img, masks=poly, bboxes=box) results['mask_fields'] = ['masks'] results['bbox_fields'] = ['bboxes'] results = imgaug_transform(results) for i in range(2): mask = results['masks'].masks[i][0] poly = imgaug.augmentables.polys.Polygon(mask.reshape(-1, 2)) box = poly.to_bounding_box().clip_out_of_image(results['img_shape']) assert box.coords_almost_equals(results['bboxes'][i].reshape(-1, 2)) args = [dict(cls='Affine', translate_px=dict(x=-10, y=-10))] imgaug_transform = transforms.ImgAug(args, clip_invalid_ploys=True) img = np.random.rand(100, 200, 3) poly = np.array([[[0, 0, 50, 0, 50, 50, 0, 50]], [[20, 20, 50, 20, 50, 50, 20, 50]]]) box = np.array([[0, 0, 50, 50], [20, 20, 50, 50]]) poly_target = np.array([[[0, 0, 40, 0, 40, 40, 0, 40]], [[10, 10, 40, 10, 40, 40, 10, 40]]]) box_target = np.array([[0, 0, 40, 40], [10, 10, 40, 40]]) results = dict(img=img, masks=poly, bboxes=box) results['mask_fields'] = ['masks'] results['bbox_fields'] = ['bboxes'] results = imgaug_transform(results) assert np.allclose(results['bboxes'], box_target) for i in range(2): poly1 = Polygon(results['masks'].masks[i][0].reshape(-1, 2)) poly2 = Polygon(poly_target[i].reshape(-1, 2)) assert poly1.equals(poly2) assert np.allclose(results['bboxes'][i], box_target[i])
def checkExtent(self, metaExtent, checkExtent, operation): """ @summary: checks polygons against operation @param metaExtent: list in the format [minx,miny,maxx,maxy] @param checkExtent: list in the format [minx,miny,maxx,maxy] """ metaExtent = [float(x) for x in metaExtent] checkExtent = [float(x) for x in checkExtent] metaPoly = Polygon(((metaExtent[0],metaExtent[1]), (metaExtent[0],metaExtent[3]), (metaExtent[2],metaExtent[3]), (metaExtent[2],metaExtent[1]))) checkPoly = Polygon(((checkExtent[0],checkExtent[1]), (checkExtent[0],checkExtent[3]), (checkExtent[2],checkExtent[3]), (checkExtent[2],checkExtent[1]))) if operation == "Contains": return checkPoly.contains(metaPoly) if operation == "Intersects": return checkPoly.intersects(metaPoly) if operation == "Equals": return checkPoly.equals(metaPoly) if operation == "Touches": return checkPoly.touches(metaPoly) if operation == "Within": return checkPoly.within(metaPoly) if operation == "Outside": return checkPoly.disjoint(metaPoly)
def subset_spatial_impl(ds: xr.Dataset, region: Polygon, mask: bool = True) -> xr.Dataset: """ Do a spatial subset of the dataset :param ds: Dataset to subset :param region: Spatial region to subset :param mask: Should values falling in the bounding box of the polygon but not the polygon itself be masked with NaN. :return: Subset dataset """ # Get the bounding box lon_min, lat_min, lon_max, lat_max = region.bounds # Validate the bounding box if (not (-90 <= lat_min <= 90)) or \ (not (-90 <= lat_max <= 90)) or \ (not (-180 <= lon_min <= 180)) or \ (not (-180 <= lon_max <= 180)): raise ValueError('Provided polygon extent outside of geospatial' ' bounds: latitude [-90;90], longitude [-180;180]') simple_polygon = False if region.equals(box(lon_min, lat_min, lon_max, lat_max)): # Don't do the computationally intensive masking if the provided # region is a simple box-polygon, for which there will be nothing to # mask. simple_polygon = True crosses_antimeridian = _crosses_antimeridian(region) lat_inverted = _lat_inverted(ds.lat) if lat_inverted: lat_index = slice(lat_max, lat_min) else: lat_index = slice(lat_min, lat_max) if crosses_antimeridian and not simple_polygon: # Unlikely but plausible raise NotImplementedError('Spatial subsets crossing the anti-meridian' ' are currently implemented for simple,' ' rectangular polygons only.') if crosses_antimeridian: # Shapely messes up longitudes if the polygon crosses the antimeridian lon_min, lon_max = lon_max, lon_min # Can't perform a simple selection with slice, hence we have to # construct an appropriate longitude indexer for selection lon_left_of_idl = slice(lon_min, 180) lon_right_of_idl = slice(-180, lon_max) lon_index = xr.concat((ds.lon.sel(lon=lon_right_of_idl), ds.lon.sel(lon=lon_left_of_idl)), dim='lon') indexers = {'lon': lon_index, 'lat': lat_index} retset = ds.sel(**indexers) if mask: # Preserve the original longitude dimension, masking elements that # do not belong to the polygon with NaN. return retset.reindex_like(ds.lon) else: # Return the dataset with no NaNs and with a disjoint longitude # dimension return retset if not mask or simple_polygon: # The polygon doesn't cross the IDL, it is a simple box -> Use a simple slice lon_slice = slice(lon_min, lon_max) indexers = {'lat': lat_index, 'lon': lon_slice} return ds.sel(**indexers) # Create the mask array. The result of this is a lon/lat DataArray where # all values falling in the region or on its boundary are denoted with True # and all the rest with False lonm, latm = np.meshgrid(ds.lon.values, ds.lat.values) mask = np.array([ Point(lon, lat).intersects(region) for lon, lat in zip(lonm.ravel(), latm.ravel()) ], dtype=bool) mask = xr.DataArray(mask.reshape(lonm.shape), coords={ 'lon': ds.lon, 'lat': ds.lat }, dims=['lat', 'lon']) # Mask values outside the polygon with NaN, crop the dataset return ds.where(mask, drop=True)
plt.imshow(demo1.draw_rects(ggl_data, img_bytes, (55, 126, 184))) # %% tes_data = demo1.get_tes_ocr_data(img_bytes) ggl_data_orig, tes_data_orig = ggl_data.copy(), tes_data.copy() SHOULD_RESTART = True while SHOULD_RESTART: SHOULD_RESTART = False for i, trow in tes_data.iterrows(): for j, grow in ggl_data.iterrows(): tpoly = Polygon(trow['poly']) gpoly = Polygon(grow['poly']) if (demo1.has_intersection(tpoly, gpoly) and not tpoly.equals(gpoly)): points = np.array(trow['poly'] + grow['poly']) min_x, min_y, max_x, max_y = demo1.get_bbox_values(points) bbox = [(min_x, min_y), (max_x, min_y), (max_x, max_y), (min_x, max_y)] tes_data.at[i, 'poly'] = bbox ggl_data.at[j, 'poly'] = bbox SHOULD_RESTART = True break collated = demo1.collate_data(ggl_data, tes_data, col_poly='poly') baseline = collated.apply(demo1.compare_text, axis=1) baseline = baseline[(baseline['res'] == 'matched') & (baseline['text_g'].str.len() >= 2)] baseline['init_scale'] = baseline.apply(demo1.get_scale_ratio, axis=1)