def get_coastline(bbox): """ Get coastline GeoJSON within bounding box """ cmask = bfmask.open_vector(os.path.join(os.path.dirname(bfalg_ndwi.__file__), 'coastmask.shp')) lons = [c[0] for c in bbox['features'][0]['geometry']['coordinates'][0]] lats = [c[1] for c in bbox['features'][0]['geometry']['coordinates'][0]] bbox = [min(lons), min(lats), max(lons), max(lats)] gj = bfmask.get_features_as_geojson(cmask[1], bbox=bbox, union=True) fname = 'tmpfile.geojson' with open(fname, 'w') as f: f.write(json.dumps(gj)) bfvec.simplify(fname, 0.025) with open(fname) as f: gj = json.load(f) os.remove(fname) return gj
def test_simplify(self): """ Simplify GeoJSON geometries """ geoimg = download_image(self.test_url) geoimg.set_nodata(0) lines = vectorize.potrace(geoimg[0] > 9500, close=0) fout = os.path.join(os.path.dirname(__file__), 'test.geojson') vectorize.save_geojson(lines, fout) # check file df = ogr.Open(fout) layer = df.GetLayer() self.assertEqual(layer.GetFeatureCount(), len(lines)) geom = json.loads(layer.GetNextFeature().ExportToJson()) self.assertEqual(len(geom['geometry']['coordinates']), len(lines[0])) df = None # simplify and check file vectorize.simplify(fout, tolerance=0.001) df = ogr.Open(fout) layer = df.GetLayer() geom = json.loads(layer.GetNextFeature().ExportToJson()) self.assertEqual(len(geom['geometry']['coordinates']), 22)
def process(geoimg, coastmask=defaults['coastmask'], minsize=defaults['minsize'], close=defaults['close'], simple=defaults['simple'], smooth=defaults['smooth'], outdir='', bname=None): """ Process data from indir to outdir """ if bname is None: bname = geoimg.basename() if outdir is None: outdir = tempfile.mkdtemp() prefix = os.path.join(outdir, bname) # calculate NWDI fout = prefix + '_ndwi.tif' logger.info('Saving NDWI to file %s' % fout, action='Save file', actee=fout, actor=__name__) imgout = alg.indices(geoimg, ['ndwi'], filename=fout) # mask with coastline if coastmask: # open coastline vector fname = os.path.join(os.path.dirname(__file__), 'coastmask.shp') fout_coast = prefix + '_coastmask.tif' try: imgout = bfmask.mask_with_vector(imgout, (fname, ''), filename=fout_coast) except Exception as e: if str(e) == 'No features after masking': logger.warning( 'Image does not intersect coastal mask. Generating empty geojson file. Error: %s/' % str(e)) geojson = {'type': 'FeatureCollection', 'features': []} fout = prefix + '.geojson' logger.info('Saving GeoJSON to file %s' % fout, action='Save file', actee=fout, actor=__name__) with open(fout, 'w') as f: f.write(json.dumps(geojson)) return geojson if str(e) == "'NoneType' object has no attribute 'ExportToJson'": logger.warning( 'Image does not intersect coastal mask. Generating empty geojson file. Error: %s/' % str(e)) geojson = {'type': 'FeatureCollection', 'features': []} fout = prefix + '.geojson' logger.info('Saving GeoJSON to file %s' % fout, action='Save file', actee=fout, actor=__name__) with open(fout, 'w') as f: f.write(json.dumps(geojson)) return geojson else: logger.warning('Error encountered during masking. Error : %s' % str(e)) raise RuntimeError(e) # calculate optimal threshold threshold = bfproc.otsu_threshold(imgout[0]) logger.debug("Otsu's threshold = %s" % threshold) #import pdb; pdb.set_trace() # save thresholded image #if False: #logger.level <= logging.DEBUG: fout = prefix + '_thresh.tif' logger.debug('Saving thresholded image as %s' % fout) logger.info('Saving threshold image to file %s' % fout, action='Save file', actee=fout, actor=__name__) imgout2 = gippy.GeoImage.create_from(imgout, filename=fout, dtype='byte') imgout2.set_nodata(255) #pdb.set_trace() (imgout[0] > threshold).save(imgout2[0]) imgout = imgout2 # vectorize threshdolded (ie now binary) image coastline = bfvec.potrace(imgout[0], minsize=minsize, close=close, alphamax=smooth) # convert coordinates to GeoJSON geojson = bfvec.to_geojson(coastline, source=geoimg.basename()) # write geojson output file fout = prefix + '.geojson' logger.info('Saving GeoJSON to file %s' % fout, action='Save file', actee=fout, actor=__name__) with open(fout, 'w') as f: f.write(json.dumps(geojson)) if simple is not None: fout = bfvec.simplify(fout, tolerance=simple) return geojson