Beispiel #1
0
def test_recurse_geometry_collection():
    mp = MultiPoint([(0.5, 0.5), (0.5, 1), (1, 1), (1.5, 1.5)])
    gc = GeometryCollection([mp])
    assert recursive_geom_finder(gc, 'point').wkt == mp.wkt

    mp = MultiPoint([(0.5, 0.5), (0.5, 1), (1, 1), (1.5, 1.5)])
    gc = GeometryCollection([mp])
    assert recursive_geom_finder(gc, 'line') is None
Beispiel #2
0
def test_collection():
    g = GeometryCollection([Point(1, 2), LineString([(1, 2), (3, 4)])])
    assert hash(g) == hash(
        GeometryCollection([Point(1, 2), LineString([(1, 2), (3, 4)])])
    )
    assert hash(g) != hash(
        GeometryCollection([Point(1, 2), LineString([(1, 2), (3, 3)])])
    )
Beispiel #3
0
def projection(point, vector, linestring, must_contain=True):
    """Projection of point along vector onto a linestring.
    Define equations of two lines:
    - one defined by point and vector: a*x + b*y + c = 0
    - one defined by linestring: d*x + e*y + f = 0

    then if the lines are not parallel, the interesction is defined by:
    X = - W^(-1) . B, where X = [x, y], W = [[a, b], [c, d]], B = [c, f]

    Do not use if the two lines are parallel (determinant is 0, W not
    invertible)
    """
    # Define equation a*x + b*y + c = 0
    a, b = -vector[1], vector[0]
    c = -(a * point.x + b * point.y)
    # Define equation d*x + e*y +f = 0
    b1, b2 = linestring.boundary
    d, e = -(b2.y - b1.y), b2.x - b1.x
    f = -(d * b1.x + e * b1.y)
    # TODO: check that two lines are not parallel
    n1 = [a, b]
    n2 = [d, e]
    if are_2d_vecs_collinear(n1, n2):
        return GeometryCollection()
    else:
        W = [[a, b], [d, e]]
        B = [c, f]
        x, y = -np.linalg.inv(W).dot(B)
        pt_intersection = Point(x, y)
        length_linestring = linestring.length
        # For the following, using linestring.contains(pt_intersection) leads
        # to wrong assessments sometimes, probably because of round off errors
        distance_to_b1 = b1.distance(pt_intersection)
        distance_to_b2 = b2.distance(pt_intersection)
        contained_by_linestring = (
            (linestring.distance(pt_intersection) < DISTANCE_TOLERANCE)
            and (distance_to_b1 <= length_linestring)
            and (distance_to_b2 <= length_linestring))
        if not must_contain:
            # No need for the geometry to contain it
            return pt_intersection
        elif contained_by_linestring:
            # Check that the intersection is not too close to a boundary: if it
            # is it can create a "memory access error" it seems
            too_close_to_b1 = distance_to_b1 < DISTANCE_TOLERANCE
            too_close_to_b2 = distance_to_b2 < DISTANCE_TOLERANCE
            if too_close_to_b1:
                return b1
            elif too_close_to_b2:
                return b2
            else:
                return pt_intersection
        else:
            return GeometryCollection()
    def setup_method(self):
        coll1 = GeometryCollection([
            Polygon([(1, 0), (2, 0), (2, 1)]),
            MultiLineString([((0.5, 0.5), (1, 1)), ((1, 0.5), (1.5, 1))]),
        ])
        coll2 = GeometryCollection(
            [Point(0.75, 0.25),
             Polygon([(2, 2), (3, 2), (2, 3)])])

        self.series = GeoSeries([coll1, coll2])
        self.df = GeoDataFrame({"geometry": self.series, "values": [1, 2]})
Beispiel #5
0
    def split(geom, splitter):
        """
        Splits a geometry by another geometry and returns a collection of geometries. This function is the theoretical
        opposite of the union of the split geometry parts. If the splitter does not split the geometry, a collection
        with a single geometry equal to the input geometry is returned.
        The function supports:
          - Splitting a (Multi)LineString by a (Multi)Point or (Multi)LineString or (Multi)Polygon
          - Splitting a (Multi)Polygon by a LineString

        It may be convenient to snap the splitter with low tolerance to the geometry. For example in the case
        of splitting a line by a point, the point must be exactly on the line, for the line to be correctly split.
        When splitting a line by a polygon, the boundary of the polygon is used for the operation.
        When splitting a line by another line, a ValueError is raised if the two overlap at some segment.

        Parameters
        ----------
        geom : geometry
            The geometry to be split
        splitter : geometry
            The geometry that will split the input geom

        Example
        -------
        >>> pt = Point((1, 1))
        >>> line = LineString([(0,0), (2,2)])
        >>> result = split(line, pt)
        >>> result.wkt
        'GEOMETRYCOLLECTION (LINESTRING (0 0, 1 1), LINESTRING (1 1, 2 2))'
        """

        if geom.type in ('MultiLineString', 'MultiPolygon'):
             return GeometryCollection([i for part in geom.geoms for i in SplitOp.split(part, splitter).geoms])

        elif geom.type == 'LineString':
            if splitter.type in ('LineString', 'MultiLineString', 'Polygon', 'MultiPolygon'):
                split_func = SplitOp._split_line_with_line
            elif splitter.type in ('Point'):
                split_func = SplitOp._split_line_with_point
            elif splitter.type in ('MultiPoint'):
                split_func =  SplitOp._split_line_with_multipoint
            else:
                raise ValueError("Splitting a LineString with a %s is not supported" % splitter.type)

        elif geom.type == 'Polygon':
            if splitter.type == 'LineString':
                split_func = SplitOp._split_polygon_with_line
            else:
                raise ValueError("Splitting a Polygon with a %s is not supported" % splitter.type)

        else:
            raise ValueError("Splitting %s geometry is not supported" % geom.type)

        return GeometryCollection(split_func(geom, splitter))
Beispiel #6
0
def shape_function_wrapper(x):
    if isinstance(x, dict):
        return shape(x)
    elif x not in ["", None, " "]:
        try:
            return shape(json.loads(x))
        except:
            return GeometryCollection()
    else:
        print("Issue dealing with geometry: " + str(x) +
              " Returning empty GeometryCollection()")
        return GeometryCollection()
Beispiel #7
0
 def test_geometrycollection(self):
     polygon = Polygon([(0, 0), (0, 1), (1, 0)])
     polygon_reversed = Polygon(
         polygon.exterior.coords[::-1]
     )
     collection = GeometryCollection([polygon])
     assert orient(collection, 1) == GeometryCollection(
         [polygon_reversed]
     )
     assert orient(collection, -1) == GeometryCollection(
         [polygon]
     )
Beispiel #8
0
    def test_is_similar(self):
        geom1 = box(0, 0, 1, 1)
        geom2 = Polygon([(1, 1), (1, 0), (0, 0), (0, 1)])
        self.assertTrue(is_similar(geom1, geom2))
        self.assertTrue(is_similar(geom2, geom1))

        multi_geom2 = MultiPolygon([geom2])
        self.assertFalse(is_similar(geom1, multi_geom2))
        self.assertFalse(is_similar(multi_geom2, geom1))

        geom_col1 = GeometryCollection([geom1, geom2, Point(0, 1)])
        geom_col2 = GeometryCollection([geom1, geom2])
        self.assertFalse(is_similar(geom_col1, geom_col2))
        self.assertFalse(is_similar(geom_col2, geom_col1))
Beispiel #9
0
def split_flowline(intersectionPoint, flowlines):

    # Convert the flowline to a geometry colelction to be exported
    nhdGeom = flowlines['features'][0]['geometry']
    nhdFlowline = GeometryCollection([shape(nhdGeom)])[0]
    nhdFlowline = LineString([xy[0:2] for xy in list(nhdFlowline[0].coords)
                              ])  # Convert xyz to xy

    # If the intersectionPoint is on the NHD Flowline, split the flowline at the point
    if nhdFlowline.intersects(intersectionPoint) is True:
        NHDFlowlinesCut = split(nhdFlowline, intersectionPoint)

    # If they don't intersect (weird right?), buffer the intersectionPoint and then split the flowline
    if nhdFlowline.intersects(intersectionPoint) is False:
        buffDist = intersectionPoint.distance(nhdFlowline) * 1.01
        buffIntersectionPoint = intersectionPoint.buffer(buffDist)
        NHDFlowlinesCut = split(nhdFlowline, buffIntersectionPoint)
        # print('NHDFlowlinesCut: ', len(NHDFlowlinesCut), NHDFlowlinesCut)

    # If the NHD Flowline was split, then calculate measure
    try:
        NHDFlowlinesCut[1]
    except AssertionError as error:  # If NHDFlowline was not split, then the intersectionPoint is either the first or last point on the NHDFlowline
        startPoint = Point(nhdFlowline[0].coords[0][0],
                           nhdFlowline[0].coords[0][1])
        lastPointID = len(nhdFlowline[0].coords) - 1
        lastPoint = Point(nhdFlowline[0].coords[lastPointID][0],
                          nhdFlowline[0].coords[lastPointID][1])
        if (intersectionPoint == startPoint):
            upstreamFlowline = GeometryCollection()
            downstreamFlowline = NHDFlowlinesCut
            error = 'The point of intersection is the first point on the NHD Flowline.'
        if (intersectionPoint == lastPoint):
            downstreamFlowline = GeometryCollection()
            upstreamFlowline = NHDFlowlinesCut
            error = 'The point of intersection is the last point on the NHD Flowline.'
        if (intersectionPoint != startPoint
                and intersectionPoint != lastPoint):
            error = 'Error: NHD Flowline measure not calculated'
            downstreamFlowline = GeometryCollection()
            upstreamFlowline = GeometryCollection()
        print(error)
    else:
        lastLineID = len(NHDFlowlinesCut) - 1
        upstreamFlowline = NHDFlowlinesCut[0]
        downstreamFlowline = NHDFlowlinesCut[lastLineID]
    print('split NHD Flowline')

    return upstreamFlowline, downstreamFlowline
Beispiel #10
0
def get_total_basin(catchmentIdentifier, catchment):
    """Use local catchment identifier to get local upstream basin geometry from NLDI"""

    print('getting upstream basin...')

    # request upstream basin
    payload = {'f': 'json', 'simplified': 'false'}

    # request upstream basin from NLDI using comid of catchment point is in
    r = requests.get(NLDI_URL + catchmentIdentifier + '/basin', params=payload)

    # print('upstream basin', r.text)
    resp = r.json()

    # convert geojson to ogr geom
    features = resp['features']
    totalBasinGeom = GeometryCollection(
        [shape(feature["geometry"]).buffer(0) for feature in features])

    # d = 0.00045
    # cf = 1.3  # cofactor

    # upstreamBasinGeom = totalBasinGeom.symmetric_difference(catchment).buffer(-d).buffer(d*cf).simplify(d)

    print('finished getting upstream basin')
    return totalBasinGeom
Beispiel #11
0
def get_flowgrid(catchment_geom, transformToRaster, transformToWGS84):
    """Use a 90 meter buffer of the local catchment to clip NHD Plus v2 flow direction raster"""

    print('start clip raster')
    with rasterio.open(IN_FDR_COG, 'r') as ds:

        # get raster crs
        dest_crs = ds.crs

        # create wgs84 crs
        wgs84 = pyproj.CRS('EPSG:4326')

        # check to see if raster is already wgs84
        latlon = dest_crs == wgs84

        # transform catchment geometry to use for clip
        projected_catchment_geom = transform_geom(transformToRaster,
                                                  catchment_geom)

        # buffer catchment geometry by 90m before clipping flow direction raster
        buffer_projected_catchment_geom = GeometryCollection(
            [projected_catchment_geom.buffer(90)])

        # clip input fd
        flwdir, flwdir_transform = rasterio.mask.mask(
            ds, buffer_projected_catchment_geom, crop=True)
        print('finish clip raster')

    # import clipped fdr into pyflwdir
    flw = pyflwdir.from_array(flwdir[0],
                              ftype='d8',
                              transform=flwdir_transform,
                              latlon=latlon)

    return flw, flwdir_transform
Beispiel #12
0
    def at(self, idx):
        """Generate a PV segment geometry for the desired index.

        Parameters
        ----------
        idx : int
            Index to use to generate PV segment geometry

        Returns
        -------
        segment : :py:class:`~pvfactors.geometry.base.PVSurface` \
        or :py:class:`~shapely.geometry.GeometryCollection`
            The returned object will be an empty geometry if its length is
            really small, otherwise it will be a PV surface geometry
        """
        if self.length[idx] < DISTANCE_TOLERANCE:
            # return an empty geometry
            return GeometryCollection()
        else:
            # Get normal vector at idx
            n_vector = (self.n_vector[:, idx]
                        if self.n_vector is not None else None)
            # Get params at idx
            # TODO: should find faster solution
            params = _get_params_at_idx(idx, self.params)
            # Return a pv surface geometry with given params
            return PVSurface(self.coords.at(idx),
                             shaded=self.shaded,
                             index=self.index,
                             normal_vector=n_vector,
                             param_names=self.param_names,
                             params=params)
Beispiel #13
0
def geomcol_gdf():
    """Create a Mixed Polygon and LineString For Testing"""
    point = Point([(2, 3), (11, 4), (7, 2), (8, 9), (1, 13)])
    poly = Polygon([(3, 4), (5, 2), (12, 2), (10, 5), (9, 7.5)])
    coll = GeometryCollection([point, poly])
    gdf = GeoDataFrame([1], geometry=[coll], crs="EPSG:3857")
    return gdf
 def deserialize_geometry_collection(self,
                                     gpbGeometry) -> GeometryCollection:
     geometries = [
         self.deserialize_geometry(geometry)
         for geometry in gpbGeometry.geometries
     ]
     return GeometryCollection(geometries)
    def test_geoms_to_multi_polygon(self):
        polygon_a = Polygon([(0, 0), (1, 0), (0, 1), (0, 0)])
        polygon_b = Polygon([(2, 2), (2, 1), (1, 2), (2, 2)])
        polygon_c = Polygon([(3, 3), (3, 4), (4, 4), (4, 3), (3, 3)])
        multi_polygon = MultiPolygon([polygon_a, polygon_b])
        line_string = LineString([(0, 0), (1, 0)])
        geometry_collection = GeometryCollection([
            multi_polygon, polygon_c, line_string
        ])

        self.assertEqual(
            MultiPolygon([polygon_a]),
            geoms_to_multi_polygon(polygon_a)
        )

        self.assertEqual(
            multi_polygon,
            geoms_to_multi_polygon(multi_polygon)
        )

        self.assertEqual(
            MultiPolygon([polygon_a, polygon_b, polygon_c]),
            geoms_to_multi_polygon(geometry_collection)
        )
        pass
Beispiel #16
0
    def _normalize_geometry(
        self, geometries
    ) -> Tuple[Union[DriverVectorCube, DelayedVector, BaseGeometry], dict]:
        """
        Helper to preprocess geometries (as used in aggregate_spatial and mask_polygon)
        and extract bbox (e.g. for filter_bbox)
        """
        # TODO #71 #114 EP-3981 normalize to vector cube instead of GeometryCollection
        if isinstance(geometries, DriverVectorCube):
            bbox = geometries.get_bounding_box()
        elif isinstance(geometries, dict):
            return self._normalize_geometry(geojson_to_geometry(geometries))
        elif isinstance(geometries, str):
            return self._normalize_geometry(DelayedVector(geometries))
        elif isinstance(geometries, DelayedVector):
            bbox = geometries.bounds
        elif isinstance(geometries, shapely.geometry.base.BaseGeometry):
            if isinstance(geometries, Point):
                geometries = buffer_point_approx(geometries, "EPSG:4326")
            elif isinstance(geometries, GeometryCollection):
                geometries = GeometryCollection([
                    buffer_point_approx(geom, "EPSG:4326") if isinstance(
                        geom, Point) else geom for geom in geometries.geoms
                ])

            bbox = geometries.bounds
        else:
            raise ValueError(geometries)
        bbox = dict(west=bbox[0],
                    south=bbox[1],
                    east=bbox[2],
                    north=bbox[3],
                    crs="EPSG:4326")
        return geometries, bbox
Beispiel #17
0
def shp2raster(shape, scale, margin=0.05, style='lab', bounds=None):
    shapes = shape['shape'].values
    kmargin = margin/(1-2*margin)
    geoms = list(shape['shape'].values)
    bounds = bounds or GeometryCollection(geoms).bounds
    l,t,r,b = bounds
    w,h = r-l, b-t
    if isinstance(scale, tuple):
        W, H = np.array(scale) * (1-margin*2)
        scale = max(w/W, h/H)
    offsetx, offsety = l-w*kmargin, b+h*kmargin
    shp = np.array((h,w))*(1+(kmargin*2))/scale
    rst = np.zeros(shp.astype(np.int), dtype=np.int16)
    m = [1/scale, 0, 0, -1/scale, -offsetx/scale, offsety/scale]
    img = Image.fromarray(rst)
    draw = ImageDraw.Draw(img)
    for i in range(len(shapes)):
        gs = affine_transform(shapes[i], m)
        for g in gs:
            pts = np.array(g.exterior.xy).T.astype(np.int).ravel()
            if style=='lab': draw.polygon(list(pts), i+1)
            else: draw.line(list(pts), 255, style)
        
        #pgs = [np.array(g.exterior.xy).T.astype(np.int) for g in gs]
        #if style=='lab':cv2.fillPoly(rst, pgs, i+1)
        #else: cv2.drawContours(rst, pgs, -1, 255, style)
    rst = np.array(img)
    m = np.array([offsetx, scale, 0, offsety, 0, -scale]).reshape((2,3))
    return Raster([rst], shape.prj, m)
Beispiel #18
0
def test_keep_geom_type_geomcoll_different_types():
    polys1 = [box(0, 1, 1, 3), box(10, 10, 12, 12)]
    polys2 = [
        Polygon([(1, 0), (3, 0), (3, 3), (1, 3), (1, 2), (2, 2), (2, 1),
                 (1, 1)]),
        box(11, 11, 13, 13),
    ]
    df1 = GeoDataFrame({"left": [0, 1], "geometry": polys1})
    df2 = GeoDataFrame({"right": [0, 1], "geometry": polys2})
    result1 = overlay(df1, df2, keep_geom_type=True)
    expected1 = GeoDataFrame({
        "left": [1],
        "right": [1],
        "geometry": [box(11, 11, 12, 12)],
    })
    assert_geodataframe_equal(result1, expected1)

    result2 = overlay(df1, df2, keep_geom_type=False)
    expected2 = GeoDataFrame({
        "left": [0, 1],
        "right": [0, 1],
        "geometry": [
            GeometryCollection([LineString([(1, 2), (1, 3)]),
                                Point(1, 1)]),
            box(11, 11, 12, 12),
        ],
    })
    assert_geodataframe_equal(result2, expected2)
Beispiel #19
0
 def _parse_geom(self, geometry):
     geom_type = self._geometry_type.upper()
     for element in geometry:
         tag = get_tag(element)
         geom = None
         if tag == self.TAG_POINT_LV03:
             geom = self._parse_point(element, 21781)
         elif tag == self.TAG_POINT_LV95:
             geom = self._parse_point(element, 2056)
         elif tag == self.TAG_LINE_LV03:
             geom = self._parse_line(element, 21781)
         elif tag == self.TAG_LINE_LV95:
             geom = self._parse_line(element, 2056)
         elif tag == self.TAG_AREA_LV03:
             geom = self._parse_area(element, 21781)
         elif tag == self.TAG_AREA_LV95:
             geom = self._parse_area(element, 2056)
         if geom is not None:
             if geom_type == 'MULTIPOINT':
                 geom = MultiPoint([geom])
             elif geom_type == 'MULTILINESTRING':
                 geom = MultiLineString([geom])
             elif geom_type == 'MULTIPOLYGON':
                 geom = MultiPolygon([geom])
             elif geom_type == 'GEOMETRYCOLLECTION':
                 geom = GeometryCollection([geom])
             return from_shape(geom, srid=2056)
     return None
Beispiel #20
0
def _clip_bounds(bbox, filename):
    """Clip input fiona-compatible vector file to input bounding box.

    :param bbox:
      Tuple of (xmin,ymin,xmax,ymax) desired clipping bounds.
    :param filename:
      Input name of file containing vector data in a format compatible
      with fiona.
    :returns:
      Shapely Geometry object (Polygon or MultiPolygon).
    """
    f = fiona.open(filename, 'r')
    shapes = list(f.items(bbox=bbox))
    xmin, ymin, xmax, ymax = bbox
    newshapes = []
    bboxpoly = sPolygon([(xmin, ymax), (xmax, ymax), (xmax, ymin),
                         (xmin, ymin), (xmin, ymax)])
    for tshape in shapes:
        myshape = sShape(tshape[1]['geometry'])
        intshape = myshape.intersection(bboxpoly)
        newshapes.append(intshape)
        newshapes.append(myshape)
    gc = GeometryCollection(newshapes)
    f.close()
    return gc
Beispiel #21
0
def test_inearest_dresample():
    polygon = Point((0, 0)).buffer(100)

    hole1 = Point((-50, 0)).buffer(20)
    hole2 = Point((50, 0)).buffer(20)
    polygon = Polygon(
        polygon.exterior,
        [hole1.exterior.coords[::-1], hole2.exterior.coords[::-1]])
    density = polygon.fetch(maxDistance=100, angle=90)
    density[:, 2] = density[:, 2] * 0.1
    mp = GeometryCollection(list(map(Point, density[:, :2])))
    # mp.write("test/data/test_fetch.geojson",properties=map(lambda x:{"density":x},density[:,2]))
    np.testing.assert_almost_equal(
        density[:, 2],
        list(
            map(lambda x: x['density'],
                readGeometry("test/data/test_fetch.geojson")['properties'])),
        decimal=6)

    polygon = polygon.resampleDensity(density,
                                      minDensity=1,
                                      maxDensity=100,
                                      growth=1.2)
    # polygon.write("test/data/test_inearest.geojson")
    np.testing.assert_almost_equal(
        polygon.xy,
        readGeometry("test/data/test_inearest.geojson")['geometry'].xy,
        decimal=6)
Beispiel #22
0
def test_collection():
    g = GeometryCollection([Point(0, 0)])
    try:
        assert hash(g)
        return False
    except TypeError:
        return True
Beispiel #23
0
def get_local_flowlines(catchmentIdentifier):
    """Request NDH Flowline from NLDI with Catchment ID"""

    cql_filter = "comid=%s" % (catchmentIdentifier)

    payload = {
        'service': 'wfs',
        'version': '1.0.0',
        'request': 'GetFeature',
        'typeName': 'wmadata:nhdflowline_network',
        'maxFeatures': '500',
        'outputFormat': 'application/json',
        'srsName': 'EPSG:4326',
        'CQL_FILTER': cql_filter
    }

    # request  flowline geometry from point in polygon query from NLDI geoserver
    r = requests.get(NLDI_GEOSERVER_URL, params=payload)

    # print('request url: ', r.url)
    flowlines = r.json()

    print('got local flowlines')

    # Convert the flowline to a geometry colelction to be exported
    nhdGeom = flowlines['features'][0]['geometry']
    nhdFlowline = GeometryCollection([shape(nhdGeom)])[0]
    nhdFlowline = LineString([xy[0:2] for xy in list(nhdFlowline[0].coords)
                              ])  # Convert xyz to xy
    # print('nhdFlowline: ', nhdFlowline)

    return flowlines, nhdFlowline
Beispiel #24
0
    def at(self, idx, shaded=None):
        """Generate a PV segment geometry for the desired index.

        Parameters
        ----------
        idx : int
            Index to use to generate PV segment geometry

        Returns
        -------
        segment : :py:class:`~pvfactors.geometry.base.PVSurface` or :py:class:`~shapely.geometry.GeometryCollection`
            The returned object will be an empty geometry if its length is
            really small, otherwise it will be a PV surface geometry
        """
        if self.length[idx] < DISTANCE_TOLERANCE:
            # return an empty geometry
            return GeometryCollection()
        else:
            # Get normal vector at idx
            n_vector = (self.n_vector[:, idx] if self.n_vector is not None
                        else None)
            # Get params at idx
            # TODO: should find faster solution
            params = {k: (val if (val is None) or np.isscalar(val)
                          or isinstance(val, dict) else val[idx])
                      for k, val in self.params.items()}
            # Return a pv surface geometry with given params
            return PVSurface(self.coords.at(idx), shaded=shaded,
                             normal_vector=n_vector,
                             param_names=self.param_names,
                             params=params)
Beispiel #25
0
 def test_sjoin_empty_geometries(self):
     # https://github.com/geopandas/geopandas/issues/944
     empty = GeoDataFrame(geometry=[GeometryCollection()] * 3)
     df = sjoin(self.pointdf.append(empty), self.polydf, how="left")
     assert df.shape == (24, 8)
     df2 = sjoin(self.pointdf, self.polydf.append(empty), how="left")
     assert df2.shape == (21, 8)
Beispiel #26
0
def test_point_geometry_collection():
    mp = GeometryCollection(
        [MultiPoint([(0.5, 0.5), (0.5, 1), (1, 1), (1.5, 1.5)])])
    expected = {
        0: {
            'geom': {
                'coordinates': ((0.5, 0.5), (0.5, 1.0), (1.0, 1.0)),
                'type': 'MultiPoint'
            },
            'measure': 3
        },
        1: {
            'geom': {
                'coordinates': ((0.5, 1.0), (1.0, 1.0)),
                'type': 'MultiPoint'
            },
            'measure': 2
        },
        2: {
            'geom': {
                'coordinates': ((1.0, 1.0), ),
                'type': 'MultiPoint'
            },
            'measure': 1
        },
        3: {
            'geom': {
                'coordinates': ((1.0, 1.0), (1.5, 1.5)),
                'type': 'MultiPoint'
            },
            'measure': 2
        }
    }
    assert get_intersection(mp, 'point', Map(grid, 'name'),
                            (0, 1, 2, 3)) == expected
Beispiel #27
0
def test_keep_geom_type_geometry_collection2():
    polys1 = [
        box(0, 0, 1, 1),
        box(1, 1, 3, 3).union(box(1, 3, 5, 5)),
    ]

    polys2 = [
        box(0, 0, 1, 1),
        box(3, 1, 4, 2).union(box(4, 1, 5, 4)),
    ]
    df1 = GeoDataFrame({"left": [0, 1], "geometry": polys1})
    df2 = GeoDataFrame({"right": [0, 1], "geometry": polys2})

    result1 = overlay(df1, df2, keep_geom_type=True)
    expected1 = GeoDataFrame({
        "left": [0, 1],
        "right": [0, 1],
        "geometry": [box(0, 0, 1, 1), box(4, 3, 5, 4)],
    })
    assert_geodataframe_equal(result1, expected1)

    result1 = overlay(df1, df2, keep_geom_type=False)
    expected1 = GeoDataFrame({
        "left": [0, 1, 1],
        "right": [0, 0, 1],
        "geometry": [
            box(0, 0, 1, 1),
            Point(1, 1),
            GeometryCollection([box(4, 3, 5, 4),
                                LineString([(3, 1), (3, 2)])]),
        ],
    })
    assert_geodataframe_equal(result1, expected1)
Beispiel #28
0
def transform_crs(shape, crs_in=crs_geographic, crs_out=crs_geographic):
    proj_in = pyproj.Proj(crs_in)
    proj_out = pyproj.Proj(crs_out)
    try:
        # pyproj >= 2.1
        project = pyproj.Transformer.from_proj(proj_in,
                                               proj_out,
                                               always_xy=True).transform
    except:
        logger.warning("old pyproj<2.1 will be deprecated")
        project = partial(pyproj.transform, proj_in, proj_out)

    transform_shape = transform(project, shape)
    if is_geographic(crs_out):
        transform_shape = transform_shape.smallest_dlon()
    if not transform_shape.is_valid:
        logger.warn('transform_crs is trying to correct invalid shape')

        if is_geographic(crs_out):
            # try lon_wrap
            transform_shape = GeometryCollection(
                split_east_west(
                    transform(
                        lambda x, y: pyproj.transform(
                            pyproj.Proj(crs_in),
                            pyproj.Proj(crs_out, lon_wrap=180), x, y), shape)))
            for sub_shape in transform_shape:
                dlon = sub_shape.bounds[2] - sub_shape.bounds[0]
                if dlon > 180:
                    raise RuntimeError('dlon > 180 after split_east_west')
        if not transform_shape.is_valid:
            raise ValueError('transform_crs produced an invalid shape')

    return transform_shape
Beispiel #29
0
 def load_utm_proj4(Class, source_path):
     geotable = Class.load(source_path,
                           target_proj4=LONGITUDE_LATITUDE_PROJ4)
     lonlat_point = GeometryCollection(geotable.geometries).centroid
     longitude, latitude = lonlat_point.x, lonlat_point.y
     zone_number, zone_letter = utm.from_latlon(latitude, longitude)[-2:]
     return get_utm_proj4(zone_number, zone_letter)
Beispiel #30
0
def getPolygon(fileName):

    # create a parser.
    parser = ConfigParser()
    # read config file.
    parser.read(fileName)

    try:
        # Check parser for section of name 'geojson'.
        if parser.has_section('geojson'):
            shapeBounds = parser.items('geojson')
            # Store items in section 'geojson' in shapeBounds list of tuples.
        else:
            print("No [geojson] in .ini file.\nClosed.")
            exit()
        # Store value of geojson name in geojsonName
        geojsonName = (shapeBounds[0][1])

        # Load in GeoJSON file from .ini file as f and obtain "features" object.
        with open(geojsonName) as f:
            features = json.load(f)["features"]

        # Define shape as "geometry" from GeoJSON file and buffer(0) removes overlapping coordinates.
        poly = (GeometryCollection(
            [shape(feature["geometry"]).buffer(0) for feature in features]))
        return poly

    except FileNotFoundError:
        # If file not found, end program.
        print("GeoJSON file not found.")
        exit()