def test_convert_to_geometry_coordinates_multipolygon(self): p1 = 'Polygon ((-116.94238466549290933 52.12861711455555991, -82.00526805089285176 61.59075286434307372, -59.92695130138864101 31.0207758265680269, -107.72286778108455962 22.0438778075388484, -122.76523743459291893 37.08624746104720771, -116.94238466549290933 52.12861711455555991))' p2 = 'Polygon ((-63.08099655131782413 21.31602121140134898, -42.70101185946779765 9.42769680782217279, -65.99242293586783603 9.912934538580501, -63.08099655131782413 21.31602121140134898))' p1 = wkt.loads(p1) p2 = wkt.loads(p2) mp1 = MultiPolygon([p1, p2]) mp2 = mp1.buffer(0.1) geoms = [mp1, mp2] gvar = GeometryVariable(name='gc', value=geoms, dimensions='gd') # Test the element node connectivity arrays. results = [] for pack in [False, True]: gc = gvar.convert_to(pack=pack) self.assertEqual(gc.dimension_map.get_driver(), DriverKey.NETCDF_UGRID) self.assertTrue(gc.has_multi) self.assertIn(OcgisConvention.Name.MULTI_BREAK_VALUE, gc.cindex.attrs) # Test multi-break values are part of the element node connectivity arrays. actual = gc.cindex.get_value() for idx, ii in enumerate(actual.flat): self.assertGreater( np.sum(ii == OcgisConvention.Value.MULTI_BREAK_VALUE), 0) results.append(actual) self.assertIsNotNone(gc.x.get_value()) self.assertIsNotNone(gc.y.get_value()) maxes = [] for ii in actual.flat: maxes.append(ii.max()) actual_max = max(maxes) for c in [gc.x, gc.y]: self.assertEqual(c.size - 1, actual_max) geoms = list(gc.iter_geometries()) for ctr, g in enumerate(geoms): self.assertIsInstance(g[1], BaseMultipartGeometry) self.assertEqual(ctr, 1) self.assertPolygonSimilar(geoms[0][1], mp1) self.assertPolygonSimilar(geoms[1][1], mp2) for idx in range(len(results[0])): self.assertNumpyAll(results[0][idx], results[1][idx])
def test_convert_to_geometry_coordinates_multipolygon(self): p1 = 'Polygon ((-116.94238466549290933 52.12861711455555991, -82.00526805089285176 61.59075286434307372, -59.92695130138864101 31.0207758265680269, -107.72286778108455962 22.0438778075388484, -122.76523743459291893 37.08624746104720771, -116.94238466549290933 52.12861711455555991))' p2 = 'Polygon ((-63.08099655131782413 21.31602121140134898, -42.70101185946779765 9.42769680782217279, -65.99242293586783603 9.912934538580501, -63.08099655131782413 21.31602121140134898))' p1 = wkt.loads(p1) p2 = wkt.loads(p2) mp1 = MultiPolygon([p1, p2]) mp2 = mp1.buffer(0.1) geoms = [mp1, mp2] gvar = GeometryVariable(name='gc', value=geoms, dimensions='gd') # Test the element node connectivity arrays. results = [] for pack in [False, True]: gc = gvar.convert_to(pack=pack) self.assertEqual(gc.dimension_map.get_driver(), DriverKey.NETCDF_UGRID) self.assertTrue(gc.has_multi) self.assertIn(OcgisConvention.Name.MULTI_BREAK_VALUE, gc.cindex.attrs) # Test multi-break values are part of the element node connectivity arrays. actual = gc.cindex.get_value() for idx, ii in enumerate(actual.flat): self.assertGreater(np.sum(ii == OcgisConvention.Value.MULTI_BREAK_VALUE), 0) results.append(actual) self.assertIsNotNone(gc.x.get_value()) self.assertIsNotNone(gc.y.get_value()) maxes = [] for ii in actual.flat: maxes.append(ii.max()) actual_max = max(maxes) for c in [gc.x, gc.y]: self.assertEqual(c.size - 1, actual_max) geoms = list(gc.iter_geometries()) for ctr, g in enumerate(geoms): self.assertIsInstance(g[1], BaseMultipartGeometry) self.assertEqual(ctr, 1) self.assertPolygonSimilar(geoms[0][1], mp1) self.assertPolygonSimilar(geoms[1][1], mp2) for idx in range(len(results[0])): self.assertNumpyAll(results[0][idx], results[1][idx])
def cmr(polygon=None, time_start=None, time_end=None, version='004', short_name='ATL03'): """ polygon: list of longitude,latitude in counter-clockwise order with first and last point matching; - e.g. [ {"lon": -115.43, "lat": 37.40}, {"lon": -109.55, "lat": 37.58}, {"lon": -109.38, "lat": 43.28}, {"lon": -115.29, "lat": 43.05}, {"lon": -115.43, "lat": 37.40} ] time_*: UTC time (i.e. "zulu" or "gmt"); expressed in the following format: <year>-<month>-<day>T<hour>:<minute>:<second>Z """ url_list = [] # set default start time to start of ICESat-2 mission if not time_start: time_start = '2018-10-13T00:00:00Z' # set default stop time to current time if not time_end: now = datetime.datetime.utcnow() time_end = now.strftime("%Y-%m-%dT%H:%M:%SZ") # issue CMR request for tolerance in [0.0001, 0.001, 0.01, 0.1, 1.0, None]: # convert polygon list into string polystr = None if polygon: flatpoly = [] for p in polygon: flatpoly.append(p["lon"]) flatpoly.append(p["lat"]) polystr = str(flatpoly)[1:-1] polystr = polystr.replace( " ", "") # remove all spaces as this will be embedded in a url # call into NSIDC routines to make CMR request try: url_list = __cmr_search(short_name, version, time_start, time_end, polystr) break # exit loop because cmr search was successful except urllib.error.HTTPError as e: logger.error('HTTP Request Error: {}'.format(e.reason)) except RuntimeError as e: logger.error("Runtime Error:", e) # simplify polygon if polygon and tolerance: raw_multi_polygon = [[(tuple([(c['lon'], c['lat']) for c in polygon]), [])]] shape = MultiPolygon(*raw_multi_polygon) buffered_shape = shape.buffer(tolerance) simplified_shape = buffered_shape.simplify(tolerance) simplified_coords = list(simplified_shape.exterior.coords) logger.warning( 'Using simplified polygon (for CMR request only!), {} points using tolerance of {}' .format(len(simplified_coords), tolerance)) region = [] for coord in simplified_coords: point = {"lon": coord[0], "lat": coord[1]} region.insert(0, point) polygon = region else: break # exit here because nothing can be done return url_list
class Geometry: def __init__(self): """The constructoris just an empty container.""" def GeomFromFeature(self, feature): self.ogrGeom = feature.GetGeometryRef() self.OgrGeomToShapely() def SetShapelyGeom(self, geom): self.shapelyGeom = geom self.ShapelyToOgrGeom() def LoadWKTGeom(self, geom): import shapely.wkt self.shapelyGeom = shapely.wkt.loads(geom) self.ShapelyToOgrGeom() def BoundsToPoly(self): from shapely.geometry import Polygon minx, miny, maxx, maxy = self.shapelyGeom.bounds ptLT = ((minx, maxy), (maxx, maxy), (maxx, miny), (minx, miny), (minx, maxy)) return Polygon(ptLT) def PointsToMultiPointGeom(self, ptL): from shapely.geometry import Point, MultiPoint ptgeomL = [] for pt in ptL: ptgeomL.append(Point(pt)) self.shapelyGeom = MultiPoint(ptgeomL) self.ShapelyToOgrGeom() def PointsToPolygonGeom(self, ptL): from shapely.geometry import Polygon #ptgeomL = [] #for pt in ptL: # ptgeomL.append(Point(pt)) self.shapelyGeom = Polygon(ptL) #self.shapelyGeom = Polygon(ptgeomL) self.ShapelyToOgrGeom() def CascadeUnion(self, shapelyGeomL): from shapely.ops import cascaded_union self.SetShapelyGeom(cascaded_union(shapelyGeomL)) #return cascaded_union(shapelyGeomL) def MultPolyToSinglePoly(self, multipoly): from shapely.ops import cascaded_union from shapely.geometry import Polygon ''' self.shapelyGeom = cascaded_union([ Polygon(component.exterior) for component in multipoly ]) ''' polyL = [item for item in multipoly] self.shapelyGeom = polyL[0] for item in polyL: self.shapelyGeom.union(item) self.ShapelyToOgrGeom() def OgrGeomToShapely(self): from shapely.wkb import loads self.shapelyGeom = loads(self.ogrGeom.ExportToWkb()) def ShapelyToOgrGeom(self): self.ogrGeom = ogr.CreateGeometryFromWkb(self.shapelyGeom.wkb) def ShapelyBuffer(self, buff): if not self.shapelyGeom.is_valid: print(' mending invalid geometry by buffer = 0') self.shapelyGeom = self.shapelyGeom.buffer(0) if not self.shapelyGeom.is_valid: exitstr = 'Can not fix invalid geometry in ShapelyBuffer' sys.exit(exitstr) def ShapelyPolysToMultiPoly(self, multiPolyL): from shapely.geometry.multipolygon import MultiPolygon self.shapelyGeom = MultiPolygon(multiPolyL) def ShapelyIntersection(self, otherGeom): return self.shapelyGeom.intersection(otherGeom.shapelyGeom) def MultiPolyGeomFromGeomL(self, geomL): singlegeomL = [] for testgeom in geomL: if testgeom.geom_type == 'MultiPolygon': for polygeom in [polygeom for polygeom in testgeom]: if len(list(polygeom.exterior.coords)) > 2: singlegeomL.append(polygeom) else: if len(list(testgeom.exterior.coords)) > 2: singlegeomL.append(testgeom) self.ShapelyPolysToMultiPoly(self, singlegeomL) def SplitPolygonsToSingleGeomL(self): singlegeomL = [] if self.shapelyGeom.geom_type == 'MultiPolygon': for polygeom in [polygeom for polygeom in self.shapelyGeom]: if len(list(polygeom.exterior.coords)) > 2: singlegeomL.append(polygeom) else: if len(list(self.shapelyGeom.exterior.coords)) > 2: singlegeomL.append(self.shapelyGeom) return singlegeomL def ShapelyRemoveSlivers(self): eps = 0.000001 from shapely.geometry import JOIN_STYLE self.ShapelyBuffer(0) #remove slivers self.shapelyGeom = self.shapelyGeom.buffer( eps, 1, join_style=JOIN_STYLE.mitre).buffer(-eps, 1, join_style=JOIN_STYLE.mitre) def ShapelyContainCut(self, cut): if cut.shapelyGeom.contains(self.shapelyGeom): pass #geom remains intact elif cut.shapelyGeom.intersects(self.shapelyGeom): self.shapelyGeom = cut.shapelyGeom.intersection(self.shapelyGeom) else: self.shapelyGeom = False def ShapelyOutsideCut(self, cut): if cut.shapelyGeom.contains(self.shapelyGeom): self.shapelyGeom = False elif cut.shapelyGeom.intersects(self.shapelyGeom): self.shapelyGeom = self.shapelyGeom.difference(cut.shapelyGeom) else: pass #geom remains intact def ShapelyWithin(self, cut): if self.shapelyGeom.within(cut.shapelyGeom): return True else: return False def GeoTransform(self, srcProj, tarProj): self.geoTransform = osr.CoordinateTransformation( srcProj.proj_cs, tarProj.proj_cs) res = self.ogrGeom.Transform(self.geoTransform) if res != 0: sys.exit('Geotransformation failed') #set shapley to reproejcted self.OgrGeomToShapely() def GeoTransformCoordsFIX(self, srcProj, tarProj, ptL): #Special version that allows geotransformation outised lat lon boundaries (i.e. for SIN outised erait sphere transform = osr.CoordinateTransformation(srcProj.proj_cs, tarProj.proj_cs) xyL = [] for pt in ptL: xyL.append(transform.TransformPoint(pt[0], pt[1])) return xyL