def bbox_polygon(bbox: list, properties: dict = {}) -> Feature: """ To generate a Polygon Feature for the bounding box generated using bbox. :param bbox: bounding box generated for a geojson. :param properties: properties to be added to the returned feature. :return: polygon for the given bounding box coordinates. Example : >>> from turfpy.measurement import bbox_polygon, bbox >>> from geojson import Polygon >>> p = Polygon([((2.38, 57.322), (23.194, -20.28), (-120.43, 19.15), ... (2.38, 57.322))]) >>> bb = bbox(p) >>> feature = bbox_polygon(bb) """ west = float(bbox[0]) south = float(bbox[1]) east = float(bbox[2]) north = float(bbox[3]) if len(bbox) == 6: raise Exception("bbox-polygon does not support BBox with 6 positions") low_left = (west, south) top_left = (west, north) top_right = (east, north) low_right = (east, south) bbox_polygon = Polygon([(low_left, low_right, top_right, top_left, low_left)]) feature_bbox = Feature(geometry=bbox_polygon) if "properties" in properties: feature_bbox.properties = properties["properties"] elif "properties" not in properties: feature_bbox.properties = {} if "id" in properties: feature_bbox.id = properties["id"] if "bbox" in properties: feature_bbox.bbox = properties["bbox"] return feature_bbox
def center(geojson, properties: Optional[dict] = None) -> Feature: """ Takes a Feature or FeatureCollection and returns the absolute center point of all features. :param geojson: GeoJSON for which centered to be calculated. :param properties: Optional parameters to be set to the generated feature. :return: Point feature for the center. Example : >>> from turfpy.measurement import center >>> from geojson import Feature, FeatureCollection, Point >>> f1 = Feature(geometry=Point((-97.522259, 35.4691))) >>> f2 = Feature(geometry=Point((-97.502754, 35.463455))) >>> f3 = Feature(geometry=Point((-97.508269, 35.463245))) >>> feature_collection = FeatureCollection([f1, f2, f3]) >>> feature = center(feature_collection) """ bounding_box = bbox(geojson) x = (bounding_box[0] + bounding_box[2]) / 2 y = (bounding_box[1] + bounding_box[3]) / 2 point = Point((x, y)) center_feature = Feature(geometry=point) if properties is None: properties = dict() if "properties" in properties: center_feature.properties = properties["properties"] elif "properties" not in properties: center_feature.properties = {} if "id" in properties: center_feature.id = properties["id"] if "bbox" in properties: center_feature.bbox = properties["bbox"] return center_feature
def add_geojson(self, json_ld): """ adds geospatial and event data that links time and space information """ uuid = self.manifest.uuid item_type = self.manifest.item_type geo_meta = self.geo_meta event_meta = self.event_meta features_dict = False # dict of all features to be added feature_events = False # mappings between features and time periods if geo_meta is not False: # print('here!' + str(geo_meta)) features_dict = LastUpdatedOrderedDict() feature_events = LastUpdatedOrderedDict() for geo in geo_meta: geo_id = geo.feature_id geo_node = '#geo-' + str( geo_id) # the node id for database rec of the feature geo_node_geom = '#geo-geom-' + str(geo_id) geo_node_props = '#geo-props-' + str(geo_id) geo_node_derived = '#geo-derived-' + str( geo_id) # node id for a derived feature geo_node_derived_geom = '#geo-derived-geom-' + str(geo_id) geo_node_derived_props = '#geo-derived-props-' + str(geo_id) feature_events[geo_node] = [] geo_props = LastUpdatedOrderedDict() geo_props['href'] = URImanagement.make_oc_uri( uuid, item_type, self.cannonical_uris) geo_props['type'] = geo.meta_type if len(geo.note) > 0: geo_props['note'] = geo.note if uuid != geo.uuid: geo_props['reference-type'] = 'inferred' geo_props['reference-uri'] = URImanagement.make_oc_uri( geo.uuid, 'subjects', self.cannonical_uris) rel_meta = self.item_gen_cache.get_entity(geo.uuid) if rel_meta is not False: geo_props['reference-label'] = rel_meta.label geo_props['reference-slug'] = rel_meta.slug else: geo_props['reference-label'] = self.manifest.label geo_props['reference-type'] = 'specified' if self.assertion_hashes: geo_props['hash_id'] = geo.hash_id geo_props['feature_id'] = geo.feature_id if geo.specificity < 0 and self.manifest.item_type != 'projects': # case where we've got reduced precision geospatial data # geotile = quadtree.encode(geo.latitude, geo.longitude, abs(geo.specificity)) geo_props['location-precision'] = abs(geo.specificity) geo_props[ 'location-precision-note'] = 'Location data approximated as a security precaution.' gmt = GlobalMercator() geotile = gmt.lat_lon_to_quadtree(geo.latitude, geo.longitude, abs(geo.specificity)) tile_bounds = gmt.quadtree_to_lat_lon(geotile) item_polygon = Polygon([[(tile_bounds[1], tile_bounds[0]), (tile_bounds[1], tile_bounds[2]), (tile_bounds[3], tile_bounds[2]), (tile_bounds[3], tile_bounds[0]), (tile_bounds[1], tile_bounds[0])] ]) item_f_poly = Feature(geometry=item_polygon) item_f_poly.id = geo_node_derived item_f_poly.geometry.id = geo_node_derived_geom item_f_poly.properties.update(geo_props) item_f_poly.properties['location-note'] = 'This region defines the '\ 'approximate location for this item.' item_f_poly.properties['id'] = geo_node_derived_props features_dict[geo_node_derived] = item_f_poly item_point = Point( (float(geo.longitude), float(geo.latitude))) item_f_point = Feature(geometry=item_point) item_f_point.id = geo_node item_f_point.geometry.id = geo_node_geom item_f_point.properties.update(geo_props) item_f_point.properties['location-note'] = 'This point defines the center of the '\ 'region approximating the location for this item.' item_f_point.properties['id'] = geo_node_props features_dict[geo_node] = item_f_point elif len(geo.coordinates) > 1: # here we have geo_json expressed features and geometries to use if geo.specificity < 0: geo_props[ 'location-precision-note'] = 'Location data approximated as a security precaution.' elif geo.specificity > 0: geo_props[ 'location-precision-note'] = 'Location data has uncertainty.' else: geo_props['location-precision-note'] = 'Location data available with no '\ 'intentional reduction in precision.' item_point = Point( (float(geo.longitude), float(geo.latitude))) item_f_point = Feature(geometry=item_point) item_f_point.properties.update(geo_props) if uuid == geo.uuid: #the item itself has the polygon as it's feature item_db = Point( (float(geo.longitude), float(geo.latitude))) if geo.ftype == 'Polygon': coord_obj = json.loads(geo.coordinates) item_db = Polygon(coord_obj) elif (geo.ftype == 'MultiPolygon'): coord_obj = json.loads(geo.coordinates) item_db = MultiPolygon(coord_obj) elif (geo.ftype == 'MultiLineString'): coord_obj = json.loads(geo.coordinates) item_db = MultiLineString(coord_obj) item_f_db = Feature(geometry=item_db) item_f_db.id = geo_node item_f_db.geometry.id = geo_node_geom item_f_db.properties.update(geo_props) item_f_db.properties['id'] = geo_node_props features_dict[geo_node] = item_f_db item_f_point.id = geo_node_derived item_f_point.geometry.id = geo_node_derived_geom item_f_point.properties['location-region-note'] = 'This point represents the center of the '\ 'region defining the location of this item.' item_f_point.properties['id'] = geo_node_derived_props features_dict[geo_node_derived] = item_f_point else: #the item is contained within another item with a polygon or multipolygon feature item_f_point.id = geo_node item_f_point.geometry.id = geo_node_geom item_f_point.properties['id'] = geo_node_props item_f_point.properties['contained-in-region'] = True item_f_point.properties['location-region-note'] = 'This point represents the center of the '\ 'region containing this item.' features_dict[geo_node] = item_f_point else: # case where the item only has a point for geo-spatial reference geo_props[ 'location-note'] = 'Location data available with no intentional reduction in precision.' item_point = Point( (float(geo.longitude), float(geo.latitude))) item_f_point = Feature(geometry=item_point) item_f_point.id = geo_node item_f_point.geometry.id = geo_node_geom item_f_point.properties.update(geo_props) item_f_point.properties['id'] = geo_node_props features_dict[geo_node] = item_f_point if event_meta is not False: # events provide chrological information, tied to geo features # sometimes there are more than 1 time period for each geo feature # in such cases, we duplicate geo features and add the different time event # information to the new features for event in event_meta: rel_feature_num = 1 # default to the first geospatial feature for where the event happened rel_feature_node = False if event.feature_id > 0: rel_feature_num = event.feature_id if rel_feature_num >= 1: rel_feature_node = '#geo-' + str(rel_feature_num) act_event_obj = LastUpdatedOrderedDict() act_event_obj = self.add_when_json(act_event_obj, uuid, item_type, event) if rel_feature_node is not False and feature_events is not False: feature_events[rel_feature_node].append(act_event_obj) if features_dict is not False: if feature_events is not False: for node_key, event_list in feature_events.items(): # update the feature with the first event "when" information if len(event_list) > 0: features_dict[node_key].update(event_list[0]) event_i = 1 for event in event_list: if event_i <= 1: # add the time info to the feature old_feature = features_dict[node_key] old_geo_id = old_feature.geometry['id'] old_prop_id = old_feature.properties['id'] features_dict[node_key].update(event) else: act_feature = copy.deepcopy(old_feature) # now add new node ids for the new features created to for the event new_node = node_key + '-event-' + str( event_i) act_feature.id = new_node act_feature.geometry[ 'id'] = old_geo_id + '-event-' + str( event_i) act_feature.properties[ 'id'] = old_prop_id + '-event-' + str( event_i) act_feature.update( event ) # add the time info to the new feature features_dict[new_node] = act_feature del (act_feature) event_i += 1 feature_keys = list(features_dict.keys()) if len(feature_keys) < 1: del features_dict[feature_keys[0]][ 'id'] # remove the conflicting id # only 1 feature, so item is not a feature collection json_ld.update(features_dict[feature_keys[0]]) else: feature_list = [ ] # multiple features, so item has a feature collection for node_key, feature in features_dict.items(): feature_list.append(feature) item_fc = FeatureCollection(feature_list) json_ld.update(item_fc) return json_ld