def test_is_outside(self):
     point = self.map_box.geometry.representative_point()
     self.assertFalse(np.all(geo.is_outside(self.map_box, point)))
     point = self.map_canyon.geometry.representative_point()
     self.assertFalse(np.all(geo.is_outside(self.map_canyon, point)))
     point_series = gpd.GeoSeries(point.array,crs=self.map_canyon.crs,index=[10,11])
     pdt.assert_series_equal(geo.is_outside(self.map_canyon, point_series),pd.Series([False,False],index=[10,11]),check_names=False)
Пример #2
0
 def test_random_walk(self):
     points = sim.random_walk(self.map_box,100,self.start,self.end,self.polygon)
     self.assertTrue(np.all(geo.is_outside(self.map_box,points.geometry)))
     self.assertTrue(all([self.polygon.contains(p) for p in points.geometry]))
     self.assertTrue(np.all(points["time"]>=np.datetime64('2020-09-01T09:00')))
     self.assertTrue(np.all(points["time"]<=(np.datetime64('2020-09-01T10:00')+np.timedelta64(1,'ms'))))
     self.assertTrue(np.all(s.z>0 for s in points.geometry))
    def test_point_process(self):
        points = sim.point_process(self.map_box, self.polygon.bounds,
                                   self.start, self.end, 100)
        self.assertTrue(
            np.all(points["time"] >= np.datetime64('2020-09-01T09:00')))
        self.assertTrue(
            np.all(points["time"] <= np.datetime64('2020-09-01T10:00')))
        self.assertTrue(np.all(s.z > 0 for s in points.geometry))

        self.assertEqual(self.map_box.crs, points.crs)
        self.assertTrue(np.all(geo.is_outside(self.map_box, points.geometry)))
        self.assertTrue(
            all([self.polygon.contains(p) for p in points.geometry]))
Пример #4
0
def point_process(map_: Map,
                  bounds: np.array,
                  start: pd.Timestamp,
                  end: pd.Timestamp,
                  num_samples: int,
                  cluster: str = 'none',
                  cluster_args: dict = dict(),
                  receiver_offset: float = 1.0) -> ReceiverPoints:
    """Generates a set of receiver locations using a clustered point process.

    Each cluster represents a set of receiver measurements. Child process can vary (none,random or levy walk, or a guided walk)
    Receiver locations are only returned if outside of buildings.

    Parameters
    ----------
    map_ : Map
    bounds : np.array
        spatial bounds with minx,miny,maxx,maxy format
    start : pd.Timestamp
        lower time bound
    end : pd.Timestamp
        upper time bound
    num_samples : int
        number of receivers (parent process) to simulate 
    cluster_args : dict
        passed to clustering (child) process, by default dict().
    cluster : str, optional
        type of child process, by default 'none'
    receiver_offset : float, optional
        The altitude of receiver location above ground level, by default 1.0

    Returns
    -------
    ReceiverPoints
    """
    cm.check.check_type(map_, 'map', raise_errors=True)
    xy, t = _poisson_cluster(bounds, start, end, num_samples, cluster,
                             cluster_args)
    points = gpd.GeoSeries(gpd.points_from_xy(xy[0, :], xy[1, :]),
                           crs=map_.crs)
    outside = is_outside(map_, points, box(*bounds))
    z = ground_level(map_, points[outside]) + receiver_offset

    return gpd.GeoDataFrame({'time': t[outside]},
                            geometry=gpd.points_from_xy(
                                xy[0, outside], xy[1, outside], z),
                            crs=map_.crs)
Пример #5
0
def _xy_point_process(map_: gpd.GeoDataFrame, polygon: Polygon,
                      num_samples: int) -> gpd.GeoSeries:
    """ Generates a geoseries of (2d) points outside map_ buildings and inside polygon"""
    minx, miny, maxx, maxy = polygon.bounds
    xy = np.empty(shape=(0, 2), dtype=float)
    n = num_samples - xy.shape[0]

    while n > 0:
        p = _rng.random(
            (n, 2)) * np.array([[maxx - minx, maxy - miny]]) + np.array(
                [[minx, miny]])
        points = gpd.GeoSeries(gpd.points_from_xy(p[:, 0], p[:, 1]),
                               crs=map_.crs)
        outside = p[is_outside(map_, points, polygon), :]
        xy = np.vstack((xy, outside))
        n = num_samples - xy.shape[0]

    return gpd.GeoSeries(gpd.points_from_xy(xy[:, 0], xy[:, 1]), crs=map_.crs)
Пример #6
0
 def test_xy_process(self):
     points = sim._xy_point_process(self.map_box,self.polygon,1000)
     self.assertEqual(len(points), 1000)
     self.assertEqual(self.map_box.crs,points.crs)
     self.assertTrue(np.all(geo.is_outside(self.map_box,points)))
     self.assertTrue(all([self.polygon.contains(p) for p in points]))
Пример #7
0
def random_walk(map_: gpd.GeoDataFrame,
                num_samples: int,
                start: pd.Timestamp,
                end: pd.Timestamp,
                polygon: Polygon = Polygon(),
                receiver_offset: float = 1.,
                avg_speed: float = .1,
                sampling_rate: int = 5) -> gpd.GeoDataFrame:
    """Generates a set of receiver locations using a random point process.

    Receiver locations are within the map boundaries and outside of buildings.

    Parameters
    ----------
    map_ : gpd.GeoDataFrame
        A gnssmapper map
    num_samples : int
        number of receiver locations to generate
    start : pd.Timestamp
        start boundary for observation time.
    end : pd.Timestamp
        end boundary for observation time.
    polygon : Polygon, optional
        A bounding polygon, by default empty.
    receiver_offset : float, optional
        The altitude of receiver location above ground level, by default 1.0
    avg_speed : float, optional
        speed of random walk per second, by default .1
    sampling_rate : int, optional
        frequency of readings in seconds, by default 5

    Returns
    -------
    gpd.GeoDataFrame
        Receiverpoints
    """

    if num_samples <= 0:
        return gpd.GeoDataFrame()

    if polygon.is_empty:
        polygon = box(*map_.geometry.total_bounds)

    starting_point = _xy_point_process(map_, polygon, 1)
    x, y, s = [starting_point.x[0]], [starting_point.y[0]], [0]
    tempx, tempy, temps = x[-1], y[-1], s[-1]

    while len(x) != num_samples:
        orientation = _rng.uniform(0, 2 * np.pi)
        x_ = avg_speed * np.cos(orientation)
        y_ = avg_speed * np.sin(orientation)
        p = gpd.GeoSeries(Point(tempx + x_, tempy + y_), crs=map_.crs)
        if p.within(polygon)[0]:
            tempx += x_
            tempy += y_
            temps += 1
            if temps % sampling_rate == 0 and is_outside(map_, p)[0]:
                x.append(tempx)
                y.append(tempy)
                s.append(temps)

    xy = gpd.GeoSeries(gpd.points_from_xy(x, y), crs=map_.crs)
    z = ground_level(map_, xy) + receiver_offset

    time_range = (end - start).total_seconds()
    bounded_s = pd.to_timedelta(np.mod(s, time_range), unit='S')
    t = start + bounded_s
    return gpd.GeoDataFrame({'time': t},
                            geometry=gpd.points_from_xy(xy.x, xy.y, z),
                            crs=xy.crs)