Example #1
0
def get_polygon_centline(contours,
                         world_coords=[],
                         segmentize_maxlen=8,
                         max_points=3000,
                         simplification=0.05,
                         smooth_sigma=5):
    if not isinstance(contours, list):
        contours = [contours]
    results = []
    for contour in contours:
        try:
            polygon = Polygon(contour)
            # print(polygon)
            centerlines = get_centerline(polygon,
                                         segmentize_maxlen=segmentize_maxlen,
                                         max_points=max_points,
                                         simplification=simplification,
                                         smooth_sigma=smooth_sigma)
            # print(centerline1)
            results.append(centerlines)
        except Exception as e:
            print("Error in get_polygon_centline():", e)
            results.append(0)
            continue

    if len(world_coords) > 0:
        # coords =
        # centerlines = [np.c_[cont, np.ones((len(cont),))] for cont in contours]
        results = [
            shapely.affinity.affine_transform(cont, world_coords)
            for cont in results
        ]
        print(results)

    return results
def main():
    #-- Read the system arguments listed after the program
    if len(sys.argv) == 1:
        sys.exit('No input file given')
    else:
        input_list = sys.argv[1:]

    for INPUT in input_list:
        #-- read shapefile
        gdf = gpd.read_file(INPUT)
        out_gdf = gdf.copy()
        #-- remove 'err' from ID
        out_gdf['ID'][0] = gdf['ID'][0].replace('err', '')
        #-- check if this is a pinning point
        if gdf['Class'][0] == 'Pinning Contour':
            #-- pinning point. Just get perimeter of polygon
            out_gdf['Class'][0] = 'Pinning Point'
        else:
            #-- convert to polygon
            p = Polygon(gdf['geometry'][0])
            dis = p.length / 10
            mx = p.length / 80
            out_gdf['geometry'][0] = get_centerline(p,
                                                    segmentize_maxlen=dis,
                                                    max_points=mx)
            out_gdf['Class'][0] = 'Grounding Line'

        #-- save centerline to file
        gl_file = INPUT.replace('_ERR', '')
        out_gdf.to_file(gl_file)
Example #3
0
def _feature_worker(feature, segmentize_maxlen, max_points, simplification,
                    smooth):
    try:
        start = time.time()
        centerline = get_centerline(shape(feature["geometry"]),
                                    segmentize_maxlen, max_points,
                                    simplification, smooth)
    except CenterlineError:
        return [(dict(properties=feature["properties"]),
                 round(time.time() - start, 3))]
    finally:
        elapsed = round(time.time() - start, 3)

    if centerline.geom_type == "LineString":
        return [(dict(feature, geometry=mapping(centerline)), elapsed)]
    elif centerline.geom_type == "MultiLineString":
        return [(dict(feature, geometry=mapping(subgeom)), elapsed)
                for subgeom in centerline]
    return result


fig, ax = plt.subplots(1)

for poly in match:
    # try:
    #     line = get_centerline(poly, segmentize_maxlen=0.5, max_points=8000, simplification=5, smooth_sigma=0.5)
    #     x, y = line.xy
    #     ax.plot(x, y, 'y.')
    # except Exception:
    #     pass
    try:
        centerline = get_centerline(poly,
                                    segmentize_maxlen=10,
                                    max_points=8000,
                                    simplification=5,
                                    smooth_sigma=0.5)
        x, y = centerline.xy
        ax.plot(x, y, 'r')
        patch1 = PolygonPatch(centerline.buffer(10),
                              fc='yellow',
                              ec='yellow',
                              alpha=0.5,
                              zorder=2)
        ax.add_patch(patch1)
    except CenterlineError:
        pass

x, y = track1.xy
ax.plot(x, y, 'b')
def main():
	#-- Read the system arguments listed after the program
	long_options=['INPUT=','FILTER=']
	optlist,arglist = getopt.getopt(sys.argv[1:],'I:F',long_options)

	#-- Set default settings
	INPUT = os.path.join(os.path.expanduser('~'),'GL_learning_data','geocoded_v1',\
		'stitched.dir','atrous_32init_drop0.2_customLossR727.dir',\
		'gl_007_180518-180524-180530-180605_021954-011058-022129-011233_T050854_T050855.tif')
	FILTER = 0.
	flt_str = ''
	for opt, arg in optlist:
		if opt in ("-I","--INPUT"):
			INPUT = arg
		elif opt in ("-F","--FILTER"):
			if arg not in ['NONE','none','None','N','n',0]:
				FILTER = float(arg)
				flt_str = '_%.1fkm'%(FILTER/1000)
			
	#-- threshold for getting contours and centerlines
	eps = 0.3

	#-- read file
	raster = rasterio.open(INPUT,'r')
	im = raster.read(1)
	#-- get transformation matrix
	trans = raster.transform

	#-- also read the corresponding mask file
	mask_file = INPUT.replace('.tif','_mask.tif')
	print(mask_file)
	mask_raster = rasterio.open(mask_file,'r')
	mask = mask_raster.read(1)
	mask_raster.close()

	#-- get contours of prediction
	#-- close contour ends to make polygons
	im[np.nonzero(im[:,0] > eps),0] = eps
	im[np.nonzero(im[:,-1] > eps),-1] = eps
	im[0,np.nonzero(im[0,:] > eps)] = eps
	im[-1,np.nonzero(im[-1,:] > eps)] = eps
	contours = find_contours(im, eps)
	#-- make contours into closed polyons to find pinning points
	#-- also apply noise filter and append to noise list
	x = {}
	y = {}
	noise = []
	pols = [None]*len(contours)
	pol_type = [None]*len(contours)
	for n,contour in enumerate(contours):
		#-- convert to coordinates
		x[n],y[n] = rasterio.transform.xy(trans, contour[:,0], contour[:,1])

		pols[n] = Polygon(zip(x[n],y[n]))
		#-- get elements of mask the contour is on
		submask = mask[np.round(contour[:, 0]).astype('int'), np.round(contour[:, 1]).astype('int')]
		#-- if more than half of the elements are from test tile, count contour as test type
		if np.count_nonzero(submask) > submask.size/2.:
			pol_type[n] = 'Test'
		else:
			pol_type[n] = 'Train'
	
	#-- loop through and apply noise filter
	for n in range(len(contours)):
		#-- apply filter
		if (n not in ignore_list) and (len(x[n]) < 2 or LineString(zip(x[n],y[n])).length <= FILTER):
			noise.append(n)

	#-- loop through remaining polygons and determine which ones are 
	#-- pinning points based on the width and length of the bounding box
	pin_list = []
	box_ll = [None]*len(contours)
	box_ww = [None]*len(contours)
	for n in range(len(pols)):
		box_ll[n] = pols[n].length
		box_ww[n] = pols[n].area/box_ll[n]
		if (n not in noise):
			#-- if the with is larger than 1/25 of the length, it's a pinning point
			if box_ww[n] > box_ll[n]/25:
				pin_list.append(n)

	#-- Loop through all the polygons and take any overlapping areas out
	#-- of the enclosing polygon and ignore the inside polygon
	ignore_list = []
	for i in range(len(pols)):
		for j in range(len(pols)):
			if (i != j) and pols[i].contains(pols[j]):
				# pols[i] = pols[i].difference(pols[j])
				if (i in pin_list) and (j in pin_list):
					#-- if it's a pinning point, ignore outer loop
					ignore_list.append(i)
				else:
					#-- if not, add inner loop to ignore list
					ignore_list.append(j)

	#-- find overlap between ignore list nad noise list
	if len(list(set(noise) & set(ignore_list))) != 0:
		sys.exit('Overlap not empty: ', list(set(noise) & set(ignore_list)))

	#-- initialize list of contour linestrings
	er = [None]*len(contours)
	cn = []
	n = 0  # total center line counter
	pc = 1 # pinning point counter
	lc = 1 # line counter
	er_type = [None]*len(er)
	cn_type = []
	er_class = [None]*len(er)
	cn_class = []
	er_lbl = [None]*len(er)
	cn_lbl = []
	#-- loop through polygons, get centerlines, and save
	for idx,p in enumerate(pols):
		er[idx] = [list(a) for a in zip(x[idx],y[idx])]
		er_type[idx] = pol_type[idx]
		if idx in noise:
			er_class[idx] = 'Noise'				
		elif idx in ignore_list:
			er_class[idx] = 'Ignored Contour'
		else:
			if idx in pin_list:
				#-- pinning point. Just get perimeter of polygon
				xc,yc = pols[idx].exterior.coords.xy
				cn.append([list(a) for a in zip(xc,yc)])
				cn_class.append('Pinning Point')
				cn_type.append(pol_type[idx])
				#-- set label
				cn_lbl.append('pin%i'%pc)
				pc += 1 #- incremenet pinning point counter
			else:
				dis = pols[idx].length/10
				mx = pols[idx].length/80
				merged_lines = get_centerline(p,segmentize_maxlen=dis,max_points=mx)
				#-- save coordinates of linestring
				xc,yc = merged_lines.coords.xy
				cn.append([list(a) for a in zip(xc,yc)])
				cn_class.append('Grounding Line')
				cn_lbl.append('line%i'%lc)
				cn_type.append(pol_type[idx])
				er_class[idx] = 'GL Uncertainty'
				#-- set label
				er_lbl[idx] = 'err%i'%lc
				lc += 1 #- incremenet line counter

	#-- save all linestrings to file
	output_dir = os.path.join(os.path.dirname(INPUT),'shapefiles.dir')
	if (not os.path.isdir(output_dir)):
			os.mkdir(output_dir)
	filename = os.path.basename(INPUT)
	#-- make separate files for centerlines and errors
	# 1) GL file
	gl_file = os.path.join(output_dir,filename.replace('.tif','%s.shp'%flt_str))
	w = shapefile.Writer(gl_file)
	w.field('ID', 'C')
	w.field('Type','C')
	w.field('Class','C')
	#-- loop over contour centerlines
	for n in range(len(cn)):
		w.line([cn[n]])
		w.record(cn_lbl[n], cn_type[n], cn_class[n])
	w.close()
	# create the .prj file
	prj = open(gl_file.replace('.shp','.prj'), "w")
	prj.write(raster.crs.to_wkt())
	prj.close()

	# 2) Err File
	er_file = os.path.join(output_dir,filename.replace('.tif','%s_ERR.shp'%flt_str))
	w = shapefile.Writer(er_file)
	w.field('ID', 'C')
	w.field('Type','C')
	w.field('Class','C')
	w.field('Length','C')
	w.field('Width','C')
	#-- loop over contours and write them
	for n in range(len(er)):
		w.line([er[n]])
		w.record(er_lbl[n] , er_type[n], er_class[n], box_ll[n], box_ww[n])
	w.close()
	# create the .prj file
	prj = open(er_file.replace('.shp','.prj'), "w")
	prj.write(raster.crs.to_wkt())
	prj.close()

	#-- close input file
	raster.close()
Example #6
0
    lineThickness = 1

    # for line in centerline1:
    #     # print(list(line.coords)[0])
    #     coords = list(line.coords)
    #     start = (int(coords[0][0]), int(coords[0][1]))
    #     end   = (int(coords[1][0]), int(coords[1][1]))
    #     cv2.line(t, start, end, (0, 0, 255), lineThickness)

    for cont in contours:
        contour = np.squeeze(cont)
        polygon = Polygon(contour)
        print(polygon)
        centerline1 = get_centerline(polygon,
                                     segmentize_maxlen=8,
                                     max_points=3000,
                                     simplification=0.05,
                                     smooth_sigma=5)
        print(centerline1)
        line = centerline1
        # print(list(line.coords)[0])
        coords = list(line.coords)
        print(len(coords), coords)
        for idx, coord in enumerate(coords[:-1]):
            # print(idx, )
            start = (int(coords[idx][0]), int(coords[idx][1]))
            end = (int(coords[idx + 1][0]), int(coords[idx + 1][1]))
            cv2.line(t, start, end, (0, 0, 255), lineThickness)

    cv2.imshow('closed', t)
    if cv2.waitKey(0) == ord('q'):
Example #7
0
def test_centerline(alps_shape):
    cl = get_centerline(alps_shape)
    assert cl.is_valid
    assert cl.geom_type == "LineString"