def geometry(obj, tp_arcs, transform=None): """ Converts a topology object to a geometry object. The topology object is a dict with 'type' and 'arcs' items, such as -- {'type': "LineString", 'arcs': [0, 1, 2]} """ if obj["type"] == "GeometryCollection": geometries = [geometry(feat, tp_arcs) for feat in obj["geometries"]] return {"type": obj["type"], "geometries": geometries} if obj["type"] == "MultiPoint": scale = transform["scale"] translate = transform["translate"] coords = obj["coordinates"] point_coords = dequantize(np.array(coords), scale, translate).tolist() return {"type": obj["type"], "coordinates": point_coords} if obj["type"] == "Point": scale = transform["scale"] translate = transform["translate"] coords = [obj["coordinates"]] point_coord = dequantize(np.array(coords), scale, translate).tolist() return {"type": obj["type"], "coordinates": point_coord[0]} else: return {"type": obj["type"], "coordinates": coordinates(obj["arcs"], tp_arcs)}
def get_gridcell_geometry(): """ Calculates the grid cell area and dimensions. The length expressions are derived from the haversine formula: hav(d/r)= hav(lat2-lat1) + cos(lat1) * cos(lat2) * hav(lon2-lon1) See: http://math.stackexchange.com/a/479459 The expression for the area comes from: http://gis.stackexchange.com/a/29743 See also: https://badc.nerc.ac.uk/help/coordinates/cell-surf-area.html """ # FIXME: these 3 lines should be a get_lat_lon() function latnrs, lonnrs = get_latnrs_lonnrs() with netCDF4.MFDataset("%s/*.sp.nc" % wam2layers_config.data_dir) as dataset: latitude = dataset.variables['latitude'][latnrs] geometry = collections.namedtuple( 'geometry', ['area', 'top_length', 'bottom_length', 'side_length']) grid_size = np.abs(latitude[0] - latitude[1]) tops = np.radians(np.minimum(latitude + 0.5 * grid_size, +90)) bottoms = np.radians(np.maximum(latitude - 0.5 * grid_size, -90)) grid_size = np.radians(grid_size) # define the haversine and inverse haversine functions: hav = lambda x: np.sin(x / 2)**2 inv_hav = lambda x: 2 * np.arcsin(np.sqrt(x)) # For the "side" length, lon2 = lon1, then: hav(lon2-lon1) = 0, and the # haversine formula becomes: hav(d/r) = hav(lat2-lat1) # i.e.: d = r * (lat2-lat1) side_length = AUTHALIC_EARTH_RADIUS * grid_size # For the top and bottom lengths, lat2 = lat1, then: # hav(lat2-lat1) = 0 # cos(lat1)*cos(lat2) = cos(lat1)**2 # and the haversine formula becomes: hav(d/r) = cos(lat1)**2 * hav(lon2-lon1) # i.e.: d = r * inv_hav(cos(lat1)**2 * hav(lon2-lon1)) top_length = AUTHALIC_EARTH_RADIUS * inv_hav( np.cos(tops)**2 * hav(grid_size)) bottom_length = AUTHALIC_EARTH_RADIUS * inv_hav( np.cos(bottoms)**2 * hav(grid_size)) area = (AUTHALIC_EARTH_RADIUS**2 * grid_size * np.abs(np.sin(tops) - np.sin(bottoms))) return geometry(area[np.newaxis, :, np.newaxis], top_length[np.newaxis, :, np.newaxis], bottom_length[np.newaxis, :, np.newaxis], side_length)
def serialize_as_geojson( topo_object, fp=None, pretty=False, indent=4, maxlinelength=88, validate=False, objectname="data", ): from shapely.geometry import asShape # prepare arcs from topology object arcs = topo_object["arcs"] transform = None if "transform" in topo_object.keys(): transform = topo_object["transform"] scale = transform["scale"] translate = transform["translate"] if arcs: np_arcs = np_array_from_arcs(arcs) # dequantize if quantization is applied np_arcs = dequantize(np_arcs, scale, translate) else: np_arcs = None # select object member from topology object features = topo_object["objects"][objectname]["geometries"] # prepare geojson featurecollection fc = {"type": "FeatureCollection", "features": []} # fill the featurecollection with geometry object members for index, feature in enumerate(features): f = {"id": index, "type": "Feature"} if "properties" in feature.keys(): f["properties"] = feature["properties"].copy() # the transform is only used in cases of points or multipoints geommap = geometry(feature, np_arcs, transform) if validate: geom = asShape(geommap).buffer(0) assert geom.is_valid f["geometry"] = geom.__geo_interface__ else: f["geometry"] = geommap fc["features"].append(f) return fc