Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
    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