示例#1
0
 def test_linestring(self):
     a = numpy.array([[1.0, 1.0, 2.0, 2.0, 1.0], [3.0, 4.0, 4.0, 3.0, 3.0]])
     t = a.T
     s = geometry.asLineString(t)
     self.failUnlessEqual(
         list(s.coords),
         [(1.0, 3.0), (1.0, 4.0), (2.0, 4.0), (2.0, 3.0), (1.0, 3.0)] )
示例#2
0
文件: map.py 项目: csdms/pymt
    def __init__(self, *args, **kwargs):
        super(UnstructuredMap, self).__init__(*args, **kwargs)

        self._point = {}
        last_offset = 0
        for (cell_id, offset) in enumerate(self._offset):
            cell = self._connectivity[last_offset:offset]
            last_offset = offset

            for point_id in cell:
                try:
                    self._point[point_id].append(cell_id)
                except KeyError:
                    self._point[point_id] = [cell_id]

        (point_x, point_y) = (self.get_x(), self.get_y())
        self._polys = []
        last_offset = 0
        for (cell_id, offset) in enumerate(self._offset):
            cell = self._connectivity[last_offset:offset]
            last_offset = offset

            (x, y) = (point_x.take(cell), point_y.take(cell))
            if len(x) > 2:
                self._polys.append(asPolygon(zip(x, y)))
            elif len(x) == 2:
                self._polys.append(asLineString(zip(x, y)))
            else:
                self._polys.append(asPoint(zip(x, y)))
示例#3
0
文件: geom.py 项目: miaomaocat/chirp
def rasterize(poly,F,T):
    """
    Create binary array on an arbitrary grid that's True only for
    points inside poly.  Uses a scanline algorithm.

    poly    a shapely Polygon
    F       an array of scalars defining the grid for frequency (row) coordinates
    T       an array of scalars defining the grid for time (column) coordinates

    Returns a boolean len(F) by len(T) array
    """
    imask = nx.zeros((F.size,T.size,),dtype='bool')
    # use a single numpy array for the scanline to avoid creating a lot of objects
    scanline = nx.array([[T[0],0.0],[T[-1],0.0]])
    sl = geometry.asLineString(scanline)
    for i,f in enumerate(F):
        scanline[:,1] = f
        ml = poly.intersection(sl)
        # several different types of objects may be returned from this
        if ml.geom_type == 'LineString': ml = [ml]
        for el in ml:
            # single points are tangents, drop them
            if el.geom_type != 'LineString': continue
            idx = slice(*T.searchsorted(el.xy[0]))
            imask[i,idx] = True
    return imask
示例#4
0
文件: ops.py 项目: gepcel/Shapely
 def shapeup(self, ob):
     if isinstance(ob, BaseGeometry):
         return ob
     else:
         try:
             return asShape(ob)
         except ValueError:
             return asLineString(ob)
示例#5
0
    def test_linestring(self):

        # From coordinate tuples
        line = LineString(((1.0, 2.0), (3.0, 4.0)))
        self.assertEqual(len(line.coords), 2)
        self.assertEqual(line.coords[:], [(1.0, 2.0), (3.0, 4.0)])

        # From Points
        line2 = LineString((Point(1.0, 2.0), Point(3.0, 4.0)))
        self.assertEqual(len(line2.coords), 2)
        self.assertEqual(line2.coords[:], [(1.0, 2.0), (3.0, 4.0)])

        # From mix of tuples and Points
        line3 = LineString((Point(1.0, 2.0), (2.0, 3.0), Point(3.0, 4.0)))
        self.assertEqual(len(line3.coords), 3)
        self.assertEqual(line3.coords[:], [(1.0, 2.0), (2.0, 3.0), (3.0, 4.0)])

        # Bounds
        self.assertEqual(line.bounds, (1.0, 2.0, 3.0, 4.0))

        # Coordinate access
        self.assertEqual(tuple(line.coords), ((1.0, 2.0), (3.0, 4.0)))
        self.assertEqual(line.coords[0], (1.0, 2.0))
        self.assertEqual(line.coords[1], (3.0, 4.0))
        with self.assertRaises(IndexError):
            line.coords[2]  # index out of range

        # Geo interface
        self.assertEqual(line.__geo_interface__,
                         {'type': 'LineString',
                          'coordinates': ((1.0, 2.0), (3.0, 4.0))})

        # Coordinate modification
        line.coords = ((-1.0, -1.0), (1.0, 1.0))
        self.assertEqual(line.__geo_interface__,
                         {'type': 'LineString',
                          'coordinates': ((-1.0, -1.0), (1.0, 1.0))})

        # Adapt a coordinate list to a line string
        coords = [[5.0, 6.0], [7.0, 8.0]]
        la = asLineString(coords)
        self.assertEqual(la.coords[:], [(5.0, 6.0), (7.0, 8.0)])

        # Test Non-operability of Null geometry
        l_null = LineString()
        self.assertEqual(l_null.wkt, 'GEOMETRYCOLLECTION EMPTY')
        self.assertEqual(l_null.length, 0.0)

        # Check that we can set coordinates of a null geometry
        l_null.coords = [(0, 0), (1, 1)]
        self.assertAlmostEqual(l_null.length, 1.4142135623730951)
示例#6
0
def loadDistanceData():
	# Load if possible, but calculate if not possible
	try:
		distances = np.load(os.path.join(DATA_DIR, "distance_matrix.npy"))
		locations = np.load(os.path.join(DATA_DIR, "baltimore_grid.npy"))
	except IOError:
		# TODO: Replace this with a call to refine_baltimore_distance_matrix
		baltimore_grid = gb.getBaltimoreGrid(5, 5)
		baltimore_grid.long, baltimore_grid.lat = sg.asLineString(baltimore_grid).xy
		locations = np.array([baltimore_grid.lat, baltimore_grid.long]).T
		distances = dr.distance_matrix(locations)
		distances = np.save(os.path.join(DATA_DIR, "distance_matrix.npy"), distances, False)
		locations = np.save(os.path.join(DATA_DIR, "baltimore_grid.npy"), locations, False)
	return distances, locations
示例#7
0
文件: sundepths.py 项目: mrayson/soda
def adjust_channel_depth(grd,shpfile,lcmax=500.):
    """
    Adjusts the depths of a suntans grid object using a line shapefile.

    The shapefile must have an attribute called "contour"
    """
    from shapely import geometry, speedups
    from maptools import readShpPointLine

    if speedups.available:
        speedups.enable()

    print 'Adjusting depths in channel regions with a shapefile...'
        
    # Load the shapefile
    xyline,contour = readShpPointLine(shpfile,FIELDNAME='contour')
    
    # Load all of the points into shapely type geometry
    
    # Distance method won't work with numpy array
    #P = geometry.asPoint(xy)
    
    P = [geometry.Point(grd.xv[i],grd.yv[i]) for i in range(grd.Nc)]
    
    L=[]
    for ll in xyline:
        L.append(geometry.asLineString(ll))
     
    nlines = len(L)
    weight_all = np.zeros((grd.Nc,nlines))
    for n in range(nlines):
        print 'Calculating distance from line %d...'%n
        
        dist = [L[n].distance(P[i]) for i in range(grd.Nc)]
        dist = np.array(dist)

        # Calculate the weight from the distance
        weight = -dist/lcmax+1.
        weight[dist>=lcmax]=0.
        
        weight_all[:,n] = weight

    # Now go through and re-calculate the depths
    dv =  grd.dv*(1-weight_all.sum(axis=-1))
    for n in range(nlines):
        dv += weight_all[:,n]*contour[n]
        
    grd.dv=dv   
    return grd
示例#8
0
    def test_numpy(self):

        from numpy import array, asarray
        from numpy.testing import assert_array_equal

        # Construct from a numpy array
        line = LineString(array([[0.0, 0.0], [1.0, 2.0]]))
        self.assertEqual(len(line.coords), 2)
        self.assertEqual(line.coords[:], [(0.0, 0.0), (1.0, 2.0)])

        line = LineString(((1.0, 2.0), (3.0, 4.0)))
        la = asarray(line)
        expected = array([[1.0, 2.0], [3.0, 4.0]])
        assert_array_equal(la, expected)

        # Coordinate sequences can be adapted as well
        la = asarray(line.coords)
        assert_array_equal(la, expected)

        # Adapt a Numpy array to a line string
        a = array([[1.0, 2.0], [3.0, 4.0]])
        la = asLineString(a)
        assert_array_equal(la.context, a)
        self.assertEqual(la.coords[:], [(1.0, 2.0), (3.0, 4.0)])

        # Now, the inverse
        self.assertEqual(la.__array_interface__,
                         la.context.__array_interface__)

        pas = asarray(la)
        assert_array_equal(pas, array([[1.0, 2.0], [3.0, 4.0]]))

        # From Array.txt
        a = asarray([[0.0, 0.0], [2.0, 2.0], [1.0, 1.0]])
        line = LineString(a)
        self.assertEqual(line.coords[:], [(0.0, 0.0), (2.0, 2.0), (1.0, 1.0)])

        data = line.ctypes
        self.assertEqual(data[0], 0.0)
        self.assertEqual(data[5], 1.0)

        b = asarray(line)
        assert_array_equal(b, array([[0., 0.], [2., 2.], [1., 1.]]))

        # Test array interface of empty linestring
        le = LineString()
        a = asarray(le)
        self.assertEqual(a.shape[0], 0)
示例#9
0
    def __init__(self, data, p1, p2, reverse=False, z_adjustment=None):
        self.data = data
        self.p1, self.p2 = p1, p2

        self.projection = None
        self.line = None
        self.date = None

        if reverse == True:
            self.data.sort_index(ascending=False, inplace=True) # flip sections shot right to left
        if z_adjustment != None:
            self.data['z'] = self.data['z'] + z_adjustment

        self.projection = og.project_points(self.data, self.p1, self.p2)
        self.line = asLineString(list(zip(self.projection['d'],self.projection['z'])))
        self.date = (self.data.iloc[0]['t']).split('T')[0]
示例#10
0
    def parse_trajectory_geometry(self, variable, coord_names):
        xvar = self.cd.nc.variables[coord_names['xname']]
        yvar = self.cd.nc.variables[coord_names['yname']]

        # one less order of magnitude eg 390000 -> 10000
        slice_factor = 10 ** (int(math.log10(xvar.size)) - 1)
        if slice_factor < 1:
            slice_factor = 1

        # TODO: don't split x/y as separate arrays.  Refactor to
        # use single numpy array instead with both lon/lat

        # tabledap datasets must be treated differently than
        # standard DAP endpoints.  Retrieve geojson instead of
        # trying to access as a DAP endpoint
        if 'erddap/tabledap' in self.service.get('url'):
            # take off 's.' from erddap
            gj = self.erddap_geojson_url(coord_names)
            # type defaults to MultiPoint, change to LineString
            coords = np.array(gj['coordinates'][::slice_factor] +
                              gj['coordinates'][-1:])
            xs = coords[:, 0]
            ys = coords[:, 1]
        else:
            xs = np.concatenate((xvar[::slice_factor], xvar[-1:]))
            ys = np.concatenate((yvar[::slice_factor], yvar[-1:]))
        # both coords must be valid to have a valid vertex
        # get rid of any nans and unreasonable lon/lats
        valid_idx = ((~np.isnan(xs)) & (np.absolute(xs) <= 180) &
                     (~np.isnan(ys)) & (np.absolute(ys) <= 90))

        xs = xs[valid_idx]
        ys = ys[valid_idx]
        # Shapely seems to require float64 values or incorrect
        # values will propagate for the generated lineString
        # if the array is not numpy's float64 dtype
        lineCoords = np.array([xs, ys]).T.astype('float64')

        gj = mapping(asLineString(lineCoords))

        self.messages.append(u"Variable %s was used to calculate "
                             u"trajectory geometry, and is a "
                             u"naive sampling." % variable)
        return gj
示例#11
0
    def __init__(self, data, p1, p2, backsight=0.0, datum=0.0, reverse=False, z_adjustment=None):
        self.data = data
        self.datum = datum
        self.backsight = backsight

        self.location = None # this will assign x,y values to the data based on p1, p2 coordinates
        self.line = None

        if {'f'}.isin(self.data.columns):
            logger.info('calculate elevations')

        if reverse == True:
            self.data.sort(ascending=False, inplace=True) # flip sections shot right to left
        if z_adjustment != None:
            self.data['z'] = self.data['z'] + z_adjustment

        if p1 != None and p2 != None:
            # calculate locations, but instead of dou, calculate xyz
            # xyzdou
            self.location = og.locate_points(self.data, self.p1, self.p2)

        self.line = asLineString(list(zip(self.data['d'],self.data['z'])))
示例#12
0
def linestring_shpfromdf(df, shpname, IDname, Xname, Yname, Zname, prj, aggregate=None):
    '''
    creates point shape file from pandas dataframe
    shp: name of shapefile to write
    Xname: name of column containing Xcoordinates
    Yname: name of column containing Ycoordinates
    Zname: name of column containing Zcoordinates
    IDname: column with unique integers for each line
    aggregate = dict of column names (keys) and operations (entries)
    '''

    # setup properties for schema
    # if including other properties besides line identifier,
    # aggregate those to single value for line, using supplied aggregate dictionary
    if aggregate:
        cols = [IDname] + list(aggregate.keys())
        aggregated = df[cols].groupby(IDname).agg(aggregate)
        aggregated[IDname] = aggregated.index
        properties = shp_properties(aggregated)
    # otherwise setup properties to just include line identifier
    else:
        properties = {IDname: 'int'}
        aggregated = pd.DataFrame(df[IDname].astype('int32'))

    schema = {'geometry': '3D LineString', 'properties': properties}
    lines = list(np.unique(df[IDname].astype('int32')))

    with fiona.collection(shpname, "w", "ESRI Shapefile", schema) as output:
        for line in lines:

            lineinfo = df[df[IDname] == line]
            vertices = lineinfo[[Xname, Yname, Zname]].values
            linestring = asLineString(vertices)
            props = dict(list(zip(aggregated.columns, aggregated.ix[line, :])))
            output.write({'properties': props,
                          'geometry': mapping(linestring)})
    shutil.copyfile(prj, "{}.prj".format(shpname[:-4]))
示例#13
0
def mask_segments(segments: np.array,
                  mask: np.array,
                  diff: bool = True) -> np.array:
    """
    Take a array of 3D segments and masks them with a 2D polygon. The polygon is assumed to be
    perpendicular to the Z axis and the masking is done along the Z axis
    :param segments: Nx2x3 array of segments
    :param mask: Mx2 polygon to be used for masking
    :param diff: if True, the mask area is removed from segment, otherwise the intersection is
    kept
    :return: Lx2x3 array of segments whose length might differ from input
    """

    _validate_segments(segments)

    if len(mask.shape) != 2 or mask.shape[1] != 2:
        raise ValueError(
            f"mask array must be of dimension (Nx2) instead of {mask.shape}")

    if len(segments) == 0:
        return np.array(segments)

    poly = Polygon(mask)

    # The following is the parallel implementation, which passes the tests but generates
    # a lot of lines (https://github.com/Toblerity/Shapely/issues/779)

    # mls = asMultiLineString(segments)
    # if diff:
    #     mls2 = mls.difference(poly)
    # else:
    #     mls2 = mls.intersection(poly)
    #
    # if mls2.geom_type == "LineString":
    #     return np.array([mls2.coords])
    # elif mls2.geom_type == "MultiLineString":
    #     return np.array([np.array(ls.coords) for ls in mls2])
    # elif mls2.geom_type == "MultiPoint":
    #     return np.empty((0, 2, 3))
    # else:
    #     raise ValueError(f"Unexpected geometry: {mls2.geom_type}")

    # The following is a slower (?), segment-by-segment implementation that does not exhibit
    # the line multiplication issue

    op = "difference" if diff else "intersection"

    output = []
    for i in range(len(segments)):
        ls = asLineString(segments[i, :, :])
        res = getattr(ls, op)(poly)

        # segments with identical start/stop location are sometime returned
        if np.isclose(res.length, 0, atol=ATOL, rtol=RTOL):
            continue

        if res.geom_type == "LineString":
            output.append(np.array([res.coords]))
        elif res.geom_type == "MultiLineString":
            output.append(np.array([np.array(l.coords) for l in res]))

    if output:
        res = np.vstack(output)

        # https://github.com/Toblerity/Shapely/issues/780
        # Some z-coordinate are being erroneously affected by the difference. This ugly
        # hack attempts to restore them.
        for s in segments:
            idx, = np.where(
                np.all(np.all(s[:, 0:2] == res[:, :, 0:2], axis=2), axis=1))
            res[idx, :, 2] = s[:, 2]

        return res
    else:
        return np.empty((0, 2, 3))
示例#14
0
                        ])
                        start = pntCounter
                        bezCurve = bezier.bezier(xList, yList)
                        # add interpolated points to newpoints list
                        newPointList = np.concatenate((newPointList, bezCurve),
                                                      0)
                        disTot = 0
                        del bezCurve, xList, yList, bezMidPoint
                    pntCounter += 1

                else:
                    newPointList = np.concatenate(
                        (newPointList, [points[pntCounter - 1]]), 0
                    )  # for lines consider removing this as it always closes it?

            newLinestring = asLineString(
                newPointList)  # could also use linear rings

            newMultiLine.append(newLinestring)

        bendedLines.append(MultiLineString(newMultiLine[0:]))

    elif lines.geom_type == "LineString":
        try:
            xList = [point[0] for point in linemerge(lines).coords]
            yList = [point[1] for point in linemerge(lines).coords]
            bezCurve = bezier.bezier(xList, yList)
            bendedLines.append(asLineString(bezCurve))
        except:
            pointReduce = lines.simplify(
                minHalfCircleBend)  # just reduce the points
            bendedLines.append(pointReduce)
pt_buf = point.buffer(5)
print(pt_buf.wkt)

# Numpy
from numpy import asarray

a = asarray(point)
a.size
a.shape

from numpy import array

from shapely.geometry import asLineString

a = array([[1.0, 2.0], [3.0, 4.0]])
line = asLineString(a)
print(line.wkt)

# Geo jiekou
d = {"type": "point", "coordinates": (0.0, 0.0)}
from shapely.geometry import asShape

shape = asShape(d)
print(shape.geom_type)
tuple(shape.coords)


class GeoThing(object):
    def __init__(self, d):
        self.__geo_interface__ = d
示例#16
0
 def test_linestring_adapter(self):
     # Adapt a coordinate list to a line string
     coords = [[5.0, 6.0], [7.0, 8.0]]
     la = asLineString(coords)
     self.assertEqual(la.coords[:], [(5.0, 6.0), (7.0, 8.0)])
示例#17
0
def test_linestring_adapter_deprecated():
    coords = [[5.0, 6.0], [7.0, 8.0]]
    with pytest.warns(ShapelyDeprecationWarning, match="proxy geometries"):
        asLineString(coords)
示例#18
0
                # self.bng.step(50)
                sleep(2)

        except Exception:
            # When we brutally kill this process there's no need to log an exception
            l.error("Fatal Error", exc_info=True)
        finally:
            self.bng.close()


if __name__ == '__test__':
    # if __name__ == '__main__':
    from numpy import array, load
    from shapely.geometry import asLineString

    driving_path = asLineString(load('driving.npy'))
    mu = 0.8
    speed_limit_meter_per_sec = 90.0 / 3.6
    road_profiler = RoadProfiler(mu, speed_limit_meter_per_sec)
    car_model = dict()
    # Is this m/s**2
    car_model['max_acc'] = 3.0
    car_model['max_dec'] = -6.3
    ai_script = road_profiler.compute_ai_script(driving_path, car_model)

if __name__ == '__main__':
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--max-speed',
                        type=int,
                        default=90,
示例#19
0
    def harvest(self):
        """
        Identify the type of CF dataset this is:
          * UGRID
          * CGRID
          * RGRID
          * DSG
        """

        try:
            cd = CommonDataset.open(self.service.get('url'))
        except Exception as e:
            app.logger.error("Could not open DAP dataset from '%s'\n"
                             "Exception %s: %s" % (self.service.get('url'),
                                                   type(e).__name__, e))
            return 'Not harvested'


        # For DAP, the unique ID is the URL
        unique_id = self.service.get('url')

        with app.app_context():
            dataset = db.Dataset.find_one( { 'uid' : unicode(unique_id) } )
            if dataset is None:
                dataset = db.Dataset()
                dataset.uid = unicode(unique_id)
                dataset['active'] = True

        # Find service reference in Dataset.services and remove (to replace it)
        tmp = dataset.services[:]
        for d in tmp:
            if d['service_id'] == self.service.get('_id'):
                dataset.services.remove(d)

        # Parsing messages
        messages = []

        # NAME
        name = None
        try:
            name = unicode_or_none(cd.nc.getncattr('title'))
        except AttributeError:
            messages.append(u"Could not get dataset name.  No global attribute named 'title'.")

        # DESCRIPTION
        description = None
        try:
            description = unicode_or_none(cd.nc.getncattr('summary'))
        except AttributeError:
            messages.append(u"Could not get dataset description.  No global attribute named 'summary'.")

        # KEYWORDS
        keywords = []
        try:
            keywords = sorted(map(lambda x: unicode(x.strip()), cd.nc.getncattr('keywords').split(",")))
        except AttributeError:
            messages.append(u"Could not get dataset keywords.  No global attribute named 'keywords' or was not comma seperated list.")

        # VARIABLES
        prefix    = ""
        # Add additonal prefix mappings as they become available.
        try:
            standard_name_vocabulary = unicode(cd.nc.getncattr("standard_name_vocabulary"))

            cf_regex = [re.compile("CF-"), re.compile('http://www.cgd.ucar.edu/cms/eaton/cf-metadata/standard_name.html')]

            for reg in cf_regex:
                if reg.match(standard_name_vocabulary) is not None:
                    prefix = "http://mmisw.org/ont/cf/parameter/"
                    break
        except AttributeError:
            pass

        # Get variables with a standard_name
        std_variables = [cd.get_varname_from_stdname(x)[0] for x in self.get_standard_variables(cd.nc) if x not in self.STD_AXIS_NAMES and len(cd.nc.variables[cd.get_varname_from_stdname(x)[0]].shape) > 0]

        # Get variables that are not axis variables or metadata variables and are not already in the 'std_variables' variable
        non_std_variables = list(set([x for x in cd.nc.variables if x not in itertools.chain(_possibley, _possiblex, _possiblez, _possiblet, self.METADATA_VAR_NAMES, self.COMMON_AXIS_NAMES) and len(cd.nc.variables[x].shape) > 0 and x not in std_variables]))

        axis_names = DapHarvest.get_axis_variables(cd.nc)
        """
        var_to_get_geo_from = None
        if len(std_names) > 0:
            var_to_get_geo_from = cd.get_varname_from_stdname(std_names[-1])[0]
            messages.append(u"Variable '%s' with standard name '%s' was used to calculate geometry." % (var_to_get_geo_from, std_names[-1]))
        else:
            # No idea which variable to generate geometry from... try to factor variables with a shape > 1.
            try:
                var_to_get_geo_from = [x for x in variables if len(cd.nc.variables[x].shape) > 1][-1]
            except IndexError:
                messages.append(u"Could not find any non-axis variables to compute geometry from.")
            else:
                messages.append(u"No 'standard_name' attributes were found on non-axis variables.  Variable '%s' was used to calculate geometry." % var_to_get_geo_from)
        """

        # LOCATION (from Paegan)
        # Try POLYGON and fall back to BBOX

        # paegan does not support ugrid, so try to detect this condition and skip
        is_ugrid = False
        is_trajectory = False
        for vname, v in cd.nc.variables.iteritems():
            if 'cf_role' in v.ncattrs():
                if v.getncattr('cf_role') == 'mesh_topology':
                    is_ugrid = True
                    break
                elif v.getncattr('cf_role') == 'trajectory_id':
                    is_trajectory = True
                    break

        gj = None

        if is_ugrid:
            messages.append(u"The underlying 'Paegan' data access library does not support UGRID and cannot parse geometry.")
        elif is_trajectory:
            coord_names = {}
            # try to get info for x, y, z, t axes
            for v in itertools.chain(std_variables, non_std_variables):
                try:
                    coord_names = cd.get_coord_names(v, **axis_names)

                    if coord_names['xname'] is not None and \
                       coord_names['yname'] is not None:
                        break
                except (AssertionError, AttributeError, ValueError, KeyError):
                    pass
            else:
                messages.append(u"Trajectory discovered but could not detect coordinate variables using the underlying 'Paegan' data access library.")

            if 'xname' in coord_names:
                try:
                    xvar = cd.nc.variables[coord_names['xname']]
                    yvar = cd.nc.variables[coord_names['yname']]

                    # one less order of magnitude eg 390000 -> 10000
                    slice_factor = 10 ** (int(math.log10(xvar.size)) - 1)

                    xs = np.concatenate((xvar[::slice_factor], xvar[-1:]))
                    ys = np.concatenate((yvar[::slice_factor], yvar[-1:]))
                    # both coords must be valid to have a valid vertex
                    # get rid of any nans and unreasonable lon/lats
                    valid_idx = ((~np.isnan(xs)) & (np.absolute(xs) <= 180) &
                                 (~np.isnan(ys)) & (np.absolute(ys) <= 90))

                    xs = xs[valid_idx]
                    ys = ys[valid_idx]
                    # Shapely seems to require float64 values or incorrect
                    # values will propagate for the generated lineString
                    # if the array is not numpy's float64 dtype
                    lineCoords = np.array([xs, ys]).T.astype('float64')

                    gj = mapping(asLineString(lineCoords))

                    messages.append(u"Variable %s was used to calculate "
                                    u"trajectory geometry, and is a "
                                    u"naive sampling." % v)

                except (AssertionError, AttributeError,
                        ValueError, KeyError, IndexError) as e:
                    app.logger.warn("Trajectory error occured: %s", e)
                    messages.append(u"Trajectory discovered but could not create a geometry.")

        else:
            for v in itertools.chain(std_variables, non_std_variables):
                try:
                    gj = mapping(cd.getboundingpolygon(var=v, **axis_names
                                                       ).simplify(0.5))
                except (AttributeError, AssertionError, ValueError,
                        KeyError, IndexError):
                    try:
                        # Returns a tuple of four coordinates, but box takes in four seperate positional argouments
                        # Asterik magic to expland the tuple into positional arguments
                        app.logger.exception("Error calculating bounding box")

                        # handles "points" aka single position NCELLs
                        bbox = cd.getbbox(var=v, **axis_names)
                        gj = self.get_bbox_or_point(bbox)

                    except (AttributeError, AssertionError, ValueError,
                            KeyError, IndexError):
                        pass

                if gj is not None:
                    # We computed something, break out of loop.
                    messages.append(u"Variable %s was used to calculate geometry." % v)
                    break

            if gj is None: # Try the globals
                gj = self.global_bounding_box(cd.nc)
                messages.append(u"Bounding Box calculated using global attributes")
            if gj is None:
                messages.append(u"The underlying 'Paegan' data access library could not determine a bounding BOX for this dataset.")
                messages.append(u"The underlying 'Paegan' data access library could not determine a bounding POLYGON for this dataset.")
                messages.append(u"Failed to calculate geometry using all of the following variables: %s" % ", ".join(itertools.chain(std_variables, non_std_variables)))





        # TODO: compute bounding box using global attributes


        final_var_names = []
        if prefix == "":
            messages.append(u"Could not find a standard name vocabulary.  No global attribute named 'standard_name_vocabulary'.  Variable list may be incorrect or contain non-measured quantities.")
            final_var_names = non_std_variables + std_variables
        else:
            final_var_names = non_std_variables + list(map(unicode, ["%s%s" % (prefix, cd.nc.variables[x].getncattr("standard_name")) for x in std_variables]))

        service = {
            'name':           name,
            'description':    description,
            'service_type':   self.service.get('service_type'),
            'service_id':     ObjectId(self.service.get('_id')),
            'data_provider':  self.service.get('data_provider'),
            'metadata_type':  u'ncml',
            'metadata_value': unicode(dataset2ncml(cd.nc, url=self.service.get('url'))),
            'messages':       map(unicode, messages),
            'keywords':       keywords,
            'variables':      map(unicode, final_var_names),
            'asset_type':     get_common_name(DapHarvest.get_asset_type(cd)),
            'geojson':        gj,
            'updated':        datetime.utcnow()
        }

        with app.app_context():
            dataset.services.append(service)
            dataset.updated = datetime.utcnow()
            dataset.save()

        ncdataset = Dataset(self.service.get('url'))
        scores = self.ccheck_dataset(ncdataset)
        metamap = self.metamap_dataset(ncdataset)

        try:
            metadata_rec = self.save_ccheck_dataset('ioos', dataset._id, scores, metamap)
        except Exception as e:
            metadata_rec = None
            app.logger.error("could not save compliancecheck/metamap information", exc_info=True)

        return "Harvested"
示例#20
0
    if args.startpoint:
        args.skip = coords.index(args.startpoint)
        print(
            f'Moving starting point of tour forward to {args.startpoint} (polygon point #{args.skip})'
        )

    if args.skip > 0:
        print(
            f'Moving tour starting point forward to {args.skip} point(s) into the original polygon'
        )
        coords = coords[args.skip:] + coords[:args.skip]

    if args.simplify != None:
        origcount = len(coords)
        # TODO make simplify dynamic based on distance
        coords = asLineString(coords).simplify(args.simplify, False).coords
        print(f'Smoothed tour from {origcount} down to {len(coords)} points')

    # calculate total runtime before trimming anything
    distanceoffsets = cumulativedistances(coords)
    totaldistance = distanceoffsets[-1]
    totalframes = distancetoframe(
        totaldistance) + 1  # plus one because distance 0 frame was not counted

    totalseconds = totalframes / args.framerate
    # these should be the same
    totaltotalseconds = totaltotalseconds + totalseconds
    print()
    print(
        f'Total runtime of the COMPLETE {round(totaldistance)}km tour at {args.kmh} km/h would be {formatruntime(totalseconds)} ({totalframes} video frames)'
    )
示例#21
0
    def get_and_save_edges(self):
        """Identifies and saves the left, top, right, and bottom (LTRB) edges.

        This method saves the LTRB edges as attributes within the layer object.

        self.left : np.array, coords for left edge
        self.top : np.array, coords for top edge
        self.right : np.array, coords for right edge
        self.bottom : np.array, coords for bottom edge

        """
        edges = self.get_edges()
        # get centroids
        centroids = []
        triangular_region = False
        for edge in edges:
            try:
                centroids.append(asLineString(edge).centroid)
            except ValueError:
                # if the region is triangular, one of its "edges" will be a
                #   point, not a line string.
                triangular_region = True
        # determine which edges are top, bottom, left, and right
        if not triangular_region:
            l = range(4)  # list of indices, one for each edge
            c = np.array([[centroids[0].x, centroids[0].y],
                          [centroids[1].x, centroids[1].y],
                          [centroids[2].x, centroids[2].y],
                          [centroids[3].x, centroids[3].y]])
            cx = c[:,0]
            cy = c[:,1]
            x_max_ind = np.nonzero(cx==cx.max())[0][0]
            x_min_ind = np.nonzero(cx==cx.min())[0][0]
            y_max_ind = np.nonzero(cy==cy.max())[0][0]
            y_min_ind = np.nonzero(cy==cy.min())[0][0]
        else:
            l = range(3)
            c = np.array([[centroids[0].x, centroids[0].y],
                          [centroids[1].x, centroids[1].y],
                          [centroids[2].x, centroids[2].y]])
            cx = c[:,0]
            cy = c[:,1]
            x_min_ind = np.nonzero(cx==cx.min())[0][0]
            y_max_ind = np.nonzero(cy==cy.max())[0][0]
            y_min_ind = np.nonzero(cy==cy.min())[0][0]
        if self.parent_part.__class__.__name__ == 'RootBuildup':
            # find centroid at x=0
            ind_x = np.nonzero(cx==0.0)[0][0]
            l.remove(ind_x)  # remove the index for the right edge
            # find centroid at y=0
            ind_y = np.nonzero(cy==0.0)[0][0]
            l.remove(ind_y)  # remove the index for the left edge
            if self.name == 'triax, lower left':
                self.right = edges[ind_x]  # right edge saved!
                self.left = edges[ind_y]  # left edge saved!
            elif self.name == 'triax, lower right':
                self.left = edges[ind_x]  # left edge saved!
                self.right = edges[ind_y]  # right edge saved!
            elif self.name == 'triax, upper right':
                self.left = edges[ind_x]  # left edge saved!
                self.right = edges[ind_y]  # right edge saved!
            elif self.name == 'triax, upper left':
                self.right = edges[ind_x]  # right edge saved!
                self.left = edges[ind_y]  # left edge saved!
            # find top and bottom edges
            if centroids[l[0]].y > centroids[l[1]].y:
                self.top = edges[l[0]]     # top edge saved!
                self.bottom = edges[l[1]]  # bottom edge saved!
            else:
                self.top = edges[l[1]]     # top edge saved!
                self.bottom = edges[l[0]]  # bottom edge saved!
        elif self.parent_part.__class__.__name__ == 'LE_Panel':
            l.remove(x_min_ind)  # remove the index for the left edge
            self.left = edges[x_min_ind]  # left edge saved!
            l.remove(y_max_ind)  # remove the index for the top edge
            self.top = edges[y_max_ind]  # top edge saved!
            l.remove(y_min_ind)  # remove the index for the bottom edge
            self.bottom = edges[y_min_ind]  # bottom edge saved!
            self.right = edges[l[0]]  # right edge saved!
        elif self.parent_part.__class__.__name__ == 'SparCap':
            l.remove(x_min_ind)  # remove the index for the left edge
            self.left = edges[x_min_ind]  # left edge saved!
            l.remove(x_max_ind)  # remove the index for the right edge
            self.right = edges[x_max_ind]  # right edge saved!
            if centroids[l[0]].y > centroids[l[1]].y:
                self.top = edges[l[0]]     # top edge saved!
                self.bottom = edges[l[1]]  # bottom edge saved!
            else:
                self.top = edges[l[1]]     # top edge saved!
                self.bottom = edges[l[0]]  # bottom edge saved!
        elif self.parent_part.__class__.__name__ == 'AftPanel':
            l.remove(x_min_ind)  # remove the index for the left edge
            self.left = edges[x_min_ind]  # left edge saved!
            l.remove(x_max_ind)  # remove the index for the right edge
            self.right = edges[x_max_ind]  # right edge saved!
            if centroids[l[0]].y > centroids[l[1]].y:
                self.top = edges[l[0]]     # top edge saved!
                self.bottom = edges[l[1]]  # bottom edge saved!
            else:
                self.top = edges[l[1]]     # top edge saved!
                self.bottom = edges[l[0]]  # bottom edge saved!
        elif self.parent_part.__class__.__name__ == 'TE_Reinforcement':
            if self.name == 'uniax' or self.name == 'foam':
                l.remove(x_max_ind)  # remove the index for the right edge
                self.right = edges[x_max_ind]  # right edge saved!
                l.remove(y_max_ind)  # remove the index for the top edge
                self.top = edges[y_max_ind]  # top edge saved!
                l.remove(y_min_ind)  # remove the index for the bottom edge
                self.bottom = edges[y_min_ind]  # bottom edge saved!
                self.left = edges[l[0]]  # left edge saved!
            else:
                # this is an alternate layer
                l.remove(x_min_ind)  # remove the index for the left edge
                self.left = edges[x_min_ind]  # left edge saved!
                if not triangular_region:
                    # if this region is rectangular, assign the right edge
                    l.remove(x_max_ind)  # remove the index for the right edge
                    self.right = edges[x_max_ind]  # right edge saved!
                else:
                    self.right = None
                if centroids[l[0]].y > centroids[l[1]].y:
                    self.top = edges[l[0]]     # top edge saved!
                    self.bottom = edges[l[1]]  # bottom edge saved!
                else:
                    self.top = edges[l[1]]     # top edge saved!
                    self.bottom = edges[l[0]]  # bottom edge saved!
        elif self.parent_part.__class__.__name__ == 'ShearWeb':
            l.remove(x_min_ind)  # remove the index for the left edge
            self.left = edges[x_min_ind]  # left edge saved!
            l.remove(x_max_ind)  # remove the index for the right edge
            self.right = edges[x_max_ind]  # right edge saved!
            if centroids[l[0]].y > centroids[l[1]].y:
                self.top = edges[l[0]]     # top edge saved!
                self.bottom = edges[l[1]]  # bottom edge saved!
            else:
                self.top = edges[l[1]]     # top edge saved!
                self.bottom = edges[l[0]]  # bottom edge saved!
示例#22
0
        driver = ogr.GetDriverByName('ESRI Shapefile')
        outds = driver.CreateDataSource(outfile)
        outlayer = CloneLayer( outds, lyr )

    for i in range(lyr.GetFeatureCount()):
        feat = lyr.GetFeature(i)
        geom = loads(feat.GetGeometryRef().ExportToWkb())
        line = asarray(geom)

        smooth_line = calcBezierFromLine( line, num_bezpts, beztype, t)

        if show_only is True:
            pylab.plot( line[:,0] - 2., line[:,1] )
            pylab.plot( smooth_line[:,0], smooth_line[:,1] )
        else:
            sl = asLineString( smooth_line )
              
            # Loop thru fields and clone attributes
            field_count = lyr.GetLayerDefn().GetFieldCount()
            outfeature = ogr.Feature(feature_def=outlayer.GetLayerDefn())
            for i in range(field_count):
                 outfeature.SetField( i, feat.GetField(i) )
 
            new_geom = ogr.CreateGeometryFromWkt(sl.wkt)
            outfeature.SetGeometry( new_geom )
            outlayer.CreateFeature( outfeature )
        
    if show_only is True:
        pylab.show()
    else:
        ds.Destroy()
示例#23
0
def mask_segment(segment: np.ndarray, faces: np.ndarray) -> np.ndarray:
    """
    Compute the visibility of the segment given the provided faces.
    Segments are hidden when the are on the opposite side of the normal
    :param segment: (2x3) the segment to process
    :param faces: (Nx3x3) the faces to consider
    :return: (Mx2x3) list of visible sub-segments
    """

    if not _validate_shape(segment, 2, 3):
        raise ValueError(
            f"segment has shape {segment.shape} instead of (2, 3)")

    if not _validate_shape(faces, None, 3, 3):
        raise ValueError(f"faces has shape {faces.shape} instead of (M, 3, 3)")

    # Check 2D overlap, all non-overlapping faces can be ignored
    active = triangles_overlap_segment_2d(faces, segment)
    if not np.any(active):
        return segment.reshape((1, 2, 3))

    # Iterate over every triangle and run the intersection function
    mask = []
    for i, face in enumerate(faces[active]):
        res, r, s, t, itrsct, b = segment_triangle_intersection(segment, face)

        if res in (
                DEGENERATE,
                NO_INT_SHORT_SEGMENT_FRONT,
                NO_INT_PARALLEL_FRONT,
                INT_COPLANAR,
        ):
            # this face is not masking the segment
            continue
        elif res in (NO_INT_PARALLEL_BEHIND, NO_INT_SHORT_SEGMENT_BEHIND):
            # this face is masking the segment
            mask.append(face)
        elif res == NO_INT_OUTSIDE_FACE:
            # segment crosses the face's plane, but not the face itself
            # masking occurs if the rear half-segment 2D-overlaps the face
            if b > 0:
                test_seg = np.array([segment[0], itrsct])
            else:
                test_seg = np.array([itrsct, segment[1]])

            overlap = triangles_overlap_segment_2d(np.array([face]),
                                                   np.array(test_seg),
                                                   accept_vertex_only=False)
            if overlap[0]:
                mask.append(face)
        elif res == INT_INSIDE:
            # lets consider the 3 sub-faces with itrsct as vertex, at least one should 2D-
            # intersect with the rear half-segment and should be added to the mask

            if b > 0:
                test_seg = np.array([segment[0], itrsct])
            elif b < 0:
                test_seg = np.array([itrsct, segment[1]])
            else:
                continue

            subfaces = np.array([
                (face[0], face[1], itrsct),
                (face[1], face[2], itrsct),
                (face[2], face[0], itrsct),
            ])
            overlap = triangles_overlap_segment_2d(subfaces,
                                                   test_seg,
                                                   accept_vertex_only=False)
            if np.any(overlap):
                mask.append(subfaces[np.argmax(overlap)])
            else:
                logging.warning(
                    f"inconsistent INTERSECTION_INSIDE with segment {segment} and "
                    f"face {face}: no overlapping sub-face")
        elif res == INT_EDGE:
            # in this case, itrsct defines two sub-faces, at least one should 2D-intersect with
            # the rear half-segment and should be added to the mask
            if b > 0:
                test_seg = np.array([segment[0], itrsct])
            elif b < 0:
                test_seg = np.array([itrsct, segment[1]])
            else:
                continue

            if ~np.isclose(np.linalg.norm(test_seg[1] - test_seg[0]),
                           0,
                           atol=ATOL,
                           rtol=RTOL):
                if s == 0:
                    subfaces = np.array([(face[0], face[1], itrsct),
                                         (itrsct, face[1], face[2])])
                elif t == 0:
                    subfaces = np.array([(face[0], itrsct, face[2]),
                                         (itrsct, face[1], face[2])])
                else:
                    subfaces = np.array([(face[0], itrsct, face[2]),
                                         (face[0], face[1], itrsct)])
                overlap = triangles_overlap_segment_2d(
                    subfaces, test_seg, accept_vertex_only=False)

                mask.extend(subfaces[overlap])
        elif res == INT_VERTEX:
            # in that case we add the face to the mask if the rear half-segment 2D intersects
            # with the face
            if b > 0:
                test_seg = np.array([segment[0], itrsct])
            elif b < 0:
                test_seg = np.array([itrsct, segment[1]])
            else:
                continue

            if ~np.isclose(np.linalg.norm(test_seg[1] - test_seg[0]),
                           0,
                           atol=ATOL,
                           rtol=RTOL):
                overlap = triangles_overlap_segment_2d(
                    np.array([face]), test_seg, accept_vertex_only=False)
                if overlap[0]:
                    mask.append(face)
        else:
            logging.warning(
                f"inconsistent result code {res} from segment_triangle_intersection with "
                f"segment {segment} and face {face}")

    # apply mask on segment
    polys = []
    for f in mask:
        p = Polygon(f[:, 0:2].round(decimals=14))
        if p.is_valid:
            polys.append(p)
    msk_seg = asLineString(segment).difference(shapely.ops.unary_union(polys))
    # TODO: cases where we might want to keep a point
    # - seg parallel to camera axis
    # - others?
    if np.isclose(msk_seg.length, 0, atol=ATOL, rtol=RTOL):
        # segments with identical start/stop location are sometime returned
        return np.empty(shape=(0, 2, 3))
    elif msk_seg.geom_type == "LineString":
        return np.array([msk_seg.coords])
    elif msk_seg.geom_type == "MultiLineString":
        output = np.array(
            [np.array(l.coords) for l in msk_seg if l.length > 1e-14])
        return np.empty(shape=(0, 2, 3)) if len(output) == 0 else output
示例#24
0
def mask_segment_parallel(segment: np.ndarray,
                          faces: np.ndarray) -> np.ndarray:
    """
    Compute the visibility of the segment given the provided faces.
    Segments are hidden when the are on the opposite side of the normal
    :param segment: (2x3) the segment to process
    :param faces: (Nx3x3) the faces to consider
    :return: (Mx2x3) list of visible sub-segments
    """

    if not _validate_shape(segment, 2, 3):
        raise ValueError(
            f"segment has shape {segment.shape} instead of (2, 3)")

    if not _validate_shape(faces, None, 3, 3):
        raise ValueError(f"faces has shape {faces.shape} instead of (M, 3, 3)")

    # Check 2D overlap, all non-overlapping faces can be ignored
    active = triangles_overlap_segment_2d(faces, segment)
    if not np.any(active):
        return segment.reshape((1, 2, 3))

    mask = []

    # noinspection PyShadowingNames,PyUnusedLocal
    def callback(segment, triangles, res, r, s, t, b, itrsct):
        nonlocal mask

        if res in (NO_INT_PARALLEL_BEHIND, NO_INT_SHORT_SEGMENT_BEHIND):
            # this face is masking the segment
            mask.extend(triangles)
            return
        elif res in [
                DEGENERATE,
                NO_INT_SHORT_SEGMENT_FRONT,
                NO_INT_PARALLEL_FRONT,
                INT_COPLANAR,
        ]:
            return

        # build an array of rear half-segments
        half_segments = np.repeat(segment.reshape(1, 2, 3),
                                  len(triangles),
                                  axis=0)
        idx = b > 0
        half_segments[idx, 1, :] = itrsct[idx, :]
        half_segments[~idx, 0, :] = itrsct[~idx, :]

        if res == NO_INT_OUTSIDE_FACE:
            # segment crosses the face's plane, but not the face itself
            # masking occurs if the rear half-segment 2D-overlaps the face
            overlap = triangles_overlap_segment_2d(triangles,
                                                   half_segments,
                                                   accept_vertex_only=False)
            mask.extend(triangles[overlap])
        elif res == INT_INSIDE:
            # lets consider the 3 sub-faces with itrsct as vertex, at least one should 2D-
            # intersect with the rear half-segment and should be added to the mask

            # TODO: this case is not vectorized but is rather rare anyway

            for i in range(len(triangles)):
                subfaces = np.array([
                    (triangles[i, 0], triangles[i, 1], itrsct[i]),
                    (triangles[i, 1], triangles[i, 2], itrsct[i]),
                    (triangles[i, 2], triangles[i, 0], itrsct[i]),
                ])
                overlap = triangles_overlap_segment_2d(
                    subfaces, half_segments[i], accept_vertex_only=False)
                if np.any(overlap):
                    mask.append(subfaces[np.argmax(overlap)])
                else:
                    logging.warning(
                        f"inconsistent INTERSECTION_INSIDE with segment {segment} and "
                        f"face {triangles[i]}: no overlapping sub-face")
        elif res == INT_EDGE:
            # in this case, itrsct defines two sub-faces, at least one should 2D-intersect with
            # the rear half-segment and should be added to the mask

            idx, = np.nonzero(~np.isclose(
                np.linalg.norm(half_segments[:, 1] - half_segments[:, 0],
                               axis=1),
                0,
                atol=ATOL,
                rtol=RTOL,
            ))

            for i in idx:
                if s[i] == 0:
                    subfaces = np.array([
                        (triangles[i, 0], triangles[i, 1], itrsct[i]),
                        (itrsct[i], triangles[i, 1], triangles[i, 2]),
                    ])
                elif t[i] == 0:
                    subfaces = np.array([
                        (triangles[i, 0], itrsct[i], triangles[i, 2]),
                        (itrsct[i], triangles[i, 1], triangles[i, 2]),
                    ])
                else:
                    subfaces = np.array([
                        (triangles[i, 0], itrsct[i], triangles[i, 2]),
                        (triangles[i, 0], triangles[i, 1], itrsct[i]),
                    ])
                overlap = triangles_overlap_segment_2d(
                    subfaces, half_segments[i], accept_vertex_only=False)

                mask.extend(subfaces[overlap])
        elif res == INT_VERTEX:
            # in that case we add the face to the mask if the rear half-segment 2D intersects
            # with the face

            idx = ~np.isclose(
                np.linalg.norm(half_segments[:, 1] - half_segments[:, 0],
                               axis=1),
                0,
                atol=ATOL,
                rtol=RTOL,
            )

            overlap = triangles_overlap_segment_2d(triangles[idx],
                                                   half_segments[idx],
                                                   accept_vertex_only=False)
            mask.extend(triangles[idx][overlap])

    segment_triangles_intersection(segment, faces[active], callback)

    # apply mask on segment
    polys = []
    for f in mask:
        p = Polygon(f[:, 0:2].round(decimals=14))
        if p.is_valid:
            polys.append(p)
    msk_seg = asLineString(segment).difference(shapely.ops.unary_union(polys))

    geom_type = msk_seg.geom_type
    length = msk_seg.length

    # TODO: cases where we might want to keep a point
    # - seg parallel to camera axis
    # - others?
    if np.isclose(length, 0, atol=ATOL, rtol=RTOL):
        # segments with identical start/stop location are sometime returned
        output = np.empty(shape=(0, 2, 3))
    elif geom_type == "LineString":
        output = np.array([msk_seg.coords])
    elif geom_type == "MultiLineString":
        output = np.array(
            [np.array(l.coords) for l in msk_seg if l.length > 1e-14])
        if len(output) == 0:
            output.shape = (0, 2, 3)
    else:
        output = np.empty(shape=(0, 2, 3))

    return output
示例#25
0
def Place_Electrodes(l,
                     phi_0,
                     lambda_approx,
                     electrodes_angle,
                     electrodes_thickness,
                     removal_thickness,
                     IDT_data,
                     electrode_type,
                     electrode_rotate_angle=0):
    plot = False
    Rlist = IDT_data['R']
    Thetalist = IDT_data['Theta']
    Rmin = []
    Rmax = []
    Rline = [[], []]
    for polarity in range(len(Rlist)):
        for i in range(len(Rlist[polarity])):
            R = Rlist[polarity][i]
            Theta = Thetalist[polarity][i]
            Rmin = min([R.min(), Rmin])
            Rmax = max([R.max(), Rmax])
            xy = pol2cart(Theta, R)
            if l == 0:
                #Rline[polarity].append(shapely_geom.LinearRing(shapely_geom.asLineString(xy)))
                Rline[polarity].append(shapely_geom.asLinearRing(xy))
            else:
                Rline[polarity].append(shapely_geom.asLineString(xy))
    Rmax = 1.5 * Rmax
    xyelect0 = pol2cart([electrodes_angle[0], electrodes_angle[0]],
                        [Rmin, Rmax])
    xyelect1 = pol2cart([electrodes_angle[1], electrodes_angle[1]],
                        [Rmin, Rmax])
    elect0 = shapely_geom.LineString([(xyelect0[0, 0], xyelect0[0, 1]),
                                      (xyelect0[1, 0], xyelect0[1, 1])])
    elect1 = shapely_geom.LineString([(xyelect1[0, 0], xyelect1[0, 1]),
                                      (xyelect1[1, 0], xyelect1[1, 1])])
    elect0 = shapely_affinity.rotate(elect0,
                                     electrode_rotate_angle,
                                     origin=(xyelect0[0, 0], xyelect0[0, 1]),
                                     use_radians=False)
    elect1 = shapely_affinity.rotate(elect1,
                                     electrode_rotate_angle,
                                     origin=(xyelect1[0, 0], xyelect1[0, 1]),
                                     use_radians=False)
    removal0 = deepcopy(elect0)
    removal1 = deepcopy(elect1)

    removal_center = shapely_geom.Point(
        0.,
        0.).buffer(Rmin -
                   electrodes_thickness * thickness_factor(electrode_type) / 2)

    Elect0_polyg = elect0.buffer(electrodes_thickness / 2)
    Elect1_polyg = elect1.buffer(electrodes_thickness / 2)

    IDT_data['removal'] = {
        'removal0': removal0.buffer(removal_thickness / 2),
        'removal1': removal1.buffer(removal_thickness / 2),
        'removal_center': removal_center
    }

    if False:  #electrode_rotate_angle != 0. : #draw hollow electrode to avoid forcing opposite voltage to the wave
        Hole_elect0 = elect0.buffer(
            electrodes_thickness /
            4)  #up to 50% of the power branch can be hollow
        Hole_elect1 = elect1.buffer(electrodes_thickness / 4)
        Phi_0 = Electrode_pattern(electrode_type, phi_0)
        N = Phi_0[0].size + Phi_0[1].size  #number of electrodes over lambda
        Hole_elect0 = Hole_elect0.intersection(
            shapely_geom.MultiLineString(Rline[1]).buffer(lambda_approx /
                                                          (4 * N)))
        Hole_elect1 = Hole_elect1.intersection(
            shapely_geom.MultiLineString(Rline[0]).buffer(lambda_approx /
                                                          (4 * N)))
        IDT_data['removal']['Hole_elect0'] = Hole_elect0
        IDT_data['removal']['Hole_elect1'] = Hole_elect1
        #Elect0_polyg  = Elect0_polyg.difference(Hole_elect0)
        #Elect1_polyg  = Elect1_polyg.difference(Hole_elect1)

    Rline = clean_edges(Rline, elect0, elect1)

    IDT_data['electrodes'] = {'elect0': Elect0_polyg, 'elect1': Elect1_polyg}
    IDT_data['Rline'] = Rline

    if plot:
        ax = plt.subplot(111)
        patch1 = PolygonPatch(elect0.buffer(electrodes_thickness / 2),
                              fc=RED,
                              ec=RED,
                              alpha=0.5,
                              zorder=2)
        ax.add_patch(patch1)
        patch2 = PolygonPatch(elect1.buffer(electrodes_thickness / 2),
                              fc=BLUE,
                              ec=BLUE,
                              alpha=0.5,
                              zorder=2)
        ax.add_patch(patch2)
        ax.set_title('a) dilation, cap_style=3')
        xrange = [-0.005, +0.005]
        yrange = [-0.005, +0.005]
        ax.axis([xrange[0], xrange[1], yrange[0], yrange[1]])
        ax.set_aspect(1)
        plt.show()
def calcElev(linestring):

    # Holds coordinates where we check for elevation
    pointArrayX = []
    pointArrayY = []
    # Holds distance according to above coordinates
    distArray = []
    
    
    #
    # Convert line to spherical mercator
    #
    #print "Starter transformering..."
    # Convert to numpy array
    ag = np.asarray(linestring)
    # Extract one array for lon and one for lat
    lon, lat = zip(*ag)
    # Define projections
    #fromProj = pyproj.Proj(init='epsg:3785')
    fromProj = pyproj.Proj(init='epsg:4326')
    toProj = pyproj.Proj(init='epsg:32633')
    # Reproject the line
    x2, y2 = pyproj.transform(fromProj, toProj, lon, lat)
    # Create new numpy array
    a = np.array(zip(x2,y2))
    # Recreate linestring
    projectedLinestrings = asLineString(a)
    #print projectedLinestrings.length
    #print "Slutt transformering..."
    #
    # Set distance for interpolation on line according to length of route
    # - projectedLinestrings.length defines length of route in meter 
    # - stepDist defines how often we want to extract a height value
    #   i.e. stepDist=50 defines that we should extract an elevation value for 
    #   every 50 meter along the route
    stepDist = 0
    if projectedLinestrings.length < 2000: 
        stepDist = 20
    elif projectedLinestrings.length >1999 and projectedLinestrings.length < 4000:
        stepDist = 100
    elif projectedLinestrings.length >3999 and projectedLinestrings.length < 10000:
        stepDist = 100
    else:
        stepDist = 200
        
    
    
    #
    # Make interpolation point along line with stepDist form above.
    # Add these point to arrays.
    #
    step = 0    
    # Trur ikke multilinestringer kommer inn her lenger
    # så koden kan sannsynligvis fjernes
    
    #print "Starter interpolering..."
    if(projectedLinestrings.geom_type == "LineString"):
        #linestring = projectedLinestrings
        while step<projectedLinestrings.length+stepDist:
            point =  projectedLinestrings.interpolate(step)
            # Project back to spherical mercator coordinates
            x, y = pyproj.transform(toProj, pyproj.Proj(init='epsg:3785'), point.x, point.y)
            #x, y = point.x, point.y
            pointArrayX.append(x)
            pointArrayY.append(y)
            distArray.append(step)
            step = step + stepDist
    #print "Slutt interpolering..."
    
    """    
    for coords in projectedLinestrings.coords:
        point  = Point(coords)
        x, y = pyproj.transform(toProj, fromProj, point.x, point.y)    
        pointArrayX.append(x)
        pointArrayY.append(y)
        distArray.append(projectedLinestrings.project(point))
    """
    
    #
    # Convert line to spherical mercator
    #
    #print "Starter transformering..."
    # Convert to numpy array
    ag = np.asarray(linestring)
    # Extract one array for lon and one for lat
    lon, lat = zip(*ag)
    # Define projections
    #fromProj = pyproj.Proj(init='epsg:3785')
    fromProj = pyproj.Proj(init='epsg:4326')
    toProj = pyproj.Proj(init='epsg:3785')
    # Reproject the line
    x2, y2 = pyproj.transform(fromProj, toProj, lon, lat)
    # Create new numpy array
    a = np.array(zip(x2,y2))
    # Recreate linestring
    projectedLinestrings = asLineString(a)
    #print "Slutt transformering..."
    
            
    # Calculate area in image to get
    # Get bounding box of area
    bbox = projectedLinestrings.bounds 
    # Expand the bounding box with 200 meter on each side
    ulx = bbox[0]-200 
    uly = bbox[3]+200
    lrx = bbox[2]+200
    lry = bbox[1]-200
  
    gt, band_array = createRasterArray(ulx, uly, lrx, lry)
    
    
    nx = len(band_array[0])
    ny = len(band_array)

    # Compute mid-point grid spacings
    ax = np.array([ulx + ix*gt[1] + gt[1]/2.0 for ix in range(nx)])
    ay = np.array([uly + iy*gt[5] + gt[5]/2.0 for iy in range(ny)])

    # Create numpy array
    z = np.array(band_array)

    # Set min/max values of image
    ny, nx = z.shape
    xmin, xmax = ax[0], ax[nx-1] #ax[5136] 
    ymin, ymax = ay[ny-1], ay[0] #ay[5144], ay[0]

    
    # Turn these into arrays of x & y coords
    xi = np.array(pointArrayX, dtype=np.float)
    yi = np.array(pointArrayY, dtype=np.float)

    # Now, we'll set points outside the boundaries to lie along an edge
    xi[xi > xmax] = xmax
    xi[xi < xmin] = xmin
    yi[yi > ymax] = ymax
    yi[yi < ymin] = ymin

    # We need to convert these to (float) indicies
    #   (xi should range from 0 to (nx - 1), etc)
    xi = (nx - 1) * (xi - xmin) / (xmax - xmin)
    yi = -(ny - 1) * (yi - ymax) / (ymax - ymin)

    # Interpolate elevation values
    # map_coordinates does cubic interpolation by default, 
    # use "order=1" to preform bilinear interpolation
    elev = map_coordinates(z, [yi, xi], order=1)

    return (distArray, elev, pointArrayX, pointArrayY)
示例#27
0
 def test_linestring_adapter(self):
     a = numpy.array([[1.0, 1.0, 2.0, 2.0, 1.0], [3.0, 4.0, 4.0, 3.0, 3.0]])
     t = a.T
     s = geometry.asLineString(t)
     self.assertEqual(list(s.coords), [(1.0, 3.0), (1.0, 4.0), (2.0, 4.0),
                                       (2.0, 3.0), (1.0, 3.0)])
示例#28
0
def create_pos_file(posfile,scalefile, xlims,ylims,dx,\
    geofile=None,ndmin=5, lcmax=2000.,r=1.05, scalefac=1.0):
    """
    Generates a gmsh background scale file (*.pos)
    
    If a geofile is specified the mesh is embedded
    """
    from shapely import geometry, speedups

    if speedups.available:
        speedups.enable()
        
    X,Y = np.meshgrid(np.arange(xlims[0],xlims[1],dx),np.arange(ylims[0],ylims[1],dx))
    xy = np.vstack((X.ravel(),Y.ravel())).T
    Np = xy.shape[0]
    nj,ni=X.shape
    # Load the scalefile
    xyscale,gridscale = readShpPointLine(scalefile,FIELDNAME='scale')
    
    # Load all of the points into shapely type geometry
    
    # Distance method won't work with numpy array
    #P = geometry.asPoint(xy)
    
    P = [geometry.Point(xy[i,0],xy[i,1]) for i in range(Np)]
    
    L=[]
    for ll in xyscale:
        L.append(geometry.asLineString(ll))
     
    nlines = len(L)
    scale_all = np.zeros((nj,ni,nlines))
    for n in range(nlines):
        print 'Calculating distance from line %d...'%n
        ss = gridscale[n] * scalefac
        lmin = ndmin * ss
        
        # Find the maximum distance
        Nk =  np.log(lcmax/ss)/np.log(r)
        print ss,Nk
        lmax = lmin + Nk * ss
        
        dist = [L[n].distance(P[i]) for i in range(Np)]
        dist = np.array(dist).reshape((nj,ni))
        
        # Calculate the scale
        N = (dist-lmin)/ss
        scale = ss*r**N
        
        ind = dist<=lmin
        if ind.any():
            scale[ind] = ss
            
        ind = scale>lcmax
        if ind.any():
            scale[ind] = lcmax
        
        scale_all[:,:,n] = scale
        
    scale_min = scale_all.min(axis=-1)
    
    write_pos_file(posfile,X,Y,scale_min)  
    
    if not geofile == None:
        fgeo = open(geofile,'a')
        fgeo.write("// Merge a post-processing view containing the target mesh sizes\n")
        fgeo.write('Merge "%s";'%posfile)
        fgeo.write("// Apply the view as the current background mesh\n")
        fgeo.write("Background Mesh View[0];\n")
        fgeo.close()
示例#29
0
 def init_mesh_point(self, x, y):
     # ищем точку в созданных или создаём
     f = list(filter(lambda p: (p.xy == [x, y]).all(), self.points))
     if len(f) == 0:
         point = MeshPoint(x, y, self.mean_z, index=len(self.points))
         self.points.append(point)
     else:
         point = f[0]
     # точка сверху
     if point.up is None:
         # если соседняя точка лежит вне области
         if not self.geom.contains(asPoint([x, y + self.dy])):
             # перессекаем boundary с вертикальной прямой
             xyz = np.array(self.geom.boundary.intersection(
                     asLineString([[x, y], [x, self.max_y]])))
             # если xyz содержит несколько точек, берём ближнюю
             if xyz.shape != (3,):
                 xyz = sorted(xyz, key=lambda v: v[1])[0]
             # создаём точку
             up = MeshPoint(*xyz, index=len(self.points), is_boundary=True)
             self.points.append(up)
         else:
             up = self.init_mesh_point(x, y + self.dy)
         point.set_up(up)
     # точка справа
     if point.right is None:
         # если соседняя точка лежит вне области
         if not self.geom.contains(asPoint([x + self.dx, y])):
             # перессекаем boundary с горизонтальной прямой
             xyz = np.array(self.geom.boundary.intersection(
                     asLineString([[x, y], [self.max_x, y]])))
             # если xyz содержит несколько точек, берём ближнюю
             if xyz.shape != (3,):
                 xyz = sorted(xyz, key=lambda v: v[0])[0]
             # создаём точку
             right = MeshPoint(*xyz, index=len(self.points), is_boundary=True)
             self.points.append(right)
         else:
             right = self.init_mesh_point(x + self.dx, y)
         point.set_right(right)
     # точка снизу
     if point.down is None:
         # если соседняя точка лежит вне области
         if not self.geom.contains(asPoint([x, y - self.dy])):
             # перессекаем boundary с вертикальной прямой
             xyz = np.array(self.geom.boundary.intersection(
                     asLineString([[x, self.min_y], [x, y]])))
             # если xyz содержит несколько точек, берём ближнюю
             if xyz.shape != (3,):
                 xyz = sorted(xyz, key=lambda v: v[1], reversed=True)[0]
             # создаём точку
             down = MeshPoint(*xyz, index=len(self.points), is_boundary=True)
             self.points.append(down)
         else:
             down = self.init_mesh_point(x, y - self.dy)
         point.set_down(down)
     # точка слева
     if point.left is None:
         # если соседняя точка лежит вне области
         if not self.geom.contains(asPoint([x - self.dx, y])):
             # перессекаем boundary с горизонтальной прямой
             xyz = np.array(self.geom.boundary.intersection(
                     asLineString([[self.min_x, y], [x, y]])))
             # если xyz содержит несколько точек, берём ближнюю
             if xyz.shape != (3,):
                 xyz = sorted(xyz, key=lambda v: v[0], reversed=True)[0]
             # создаём точку
             left = MeshPoint(*xyz, index=len(self.points), is_boundary=True)
             self.points.append(left)
         else:
             left = self.init_mesh_point(x - self.dx, y)
         point.set_left(left)
     return point
示例#30
0
def create_pos_file(posfile,scalefile, xlims,ylims,dx,\
    geofile=None,ndmin=5, lcmax=2000.,r=1.05, scalefac=1.0):
    """
    Generates a gmsh background scale file (*.pos)
    
    If a geofile is specified the mesh is embedded
    """
    from shapely import geometry, speedups
    import pandas as pd

    if speedups.available:
        speedups.enable()

    X, Y = np.meshgrid(np.arange(xlims[0], xlims[1], dx),
                       np.arange(ylims[0], ylims[1], dx))
    xy = np.vstack((X.ravel(), Y.ravel())).T
    Np = xy.shape[0]
    nj, ni = X.shape
    # Load the scalefile
    xyscale, gridscale = readShpPointLine(scalefile, FIELDNAME='scale')

    # Load all of the points into shapely type geometry

    # Distance method won't work with numpy array
    #P = geometry.asPoint(xy)

    P = [geometry.Point(xy[i, 0], xy[i, 1]) for i in range(Np)]

    L = []
    for ll in xyscale:
        L.append(geometry.asLineString(ll))

    # Vectorize operations using pandas
    geo_points = pd.DataFrame({'single_column':xy.tolist()}).single_column.\
        apply(lambda x: geometry.Point(x[0],x[1])).values

    geo_lines = pd.DataFrame({'single_column':xyscale}).single_column.\
        apply(lambda x: geometry.LineString(x)).values

    def distance(a_point, a_line):
        return a_point.distance(a_line)

    distance_vec = np.vectorize(distance)

    dist_all = distance_vec(geo_points[..., np.newaxis], geo_lines)

    nlines = len(L)
    scale_all = np.zeros((nj, ni, nlines))
    for n in range(nlines):
        print('Calculating distance from line %d...' % n)
        ss = gridscale[n] * scalefac
        lmin = ndmin * ss

        # Find the maximum distance
        Nk = np.log(lcmax / ss) / np.log(r)
        print(ss, Nk)
        lmax = lmin + Nk * ss

        #dist = [L[n].distance(P[i]) for i in range(Np)]
        #dist = np.array(dist).reshape((nj,ni))
        dist = dist_all[:, n].reshape((nj, ni))

        # Calculate the scale
        N = (dist - lmin) / ss
        scale = ss * r**N

        ind = dist <= lmin
        if ind.any():
            scale[ind] = ss

        ind = scale > lcmax
        if ind.any():
            scale[ind] = lcmax

        scale_all[:, :, n] = scale

    scale_min = scale_all.min(axis=-1)

    write_pos_file(posfile, X, Y, scale_min)

    if not geofile is None:
        fgeo = open(geofile, 'a')
        fgeo.write(
            "// Merge a post-processing view containing the target mesh sizes\n"
        )
        fgeo.write('Merge "%s";' % posfile)
        fgeo.write("// Apply the view as the current background mesh\n")
        fgeo.write("Background Mesh View[0];\n")
        fgeo.close()
示例#31
0
def write_line_string(hull):
    with open("data/line_{0}.csv".format(hull.shape[0]), "w") as file:
        file.write('\"line\"\n')
        text = asLineString(hull).wkt
        file.write('\"' + text + '\"\n')
def get_path(n0, n1):
    """If n0 and n1 are connected nodes in the graph, this function
    return an array of point coordinates along the line linking
    these two nodes."""
    return np.array(json.loads(nx_list_subgraph[n0][n1]['Json'])['coordinates'])

def get_full_path(path):
    """
    Create numpy array line result
    :param path: results of nx.shortest_path function
    :return: coordinate pairs along a path
    """
    p_list = []
    curp = None
    for i in range(len(path)-1):
        p = get_path(path[i], path[i+1])
        if curp is None:
            curp = p
        if np.sum((p[0]-curp)**2) > np.sum((p[-1]-curp)**2):
            p = p[::-1, :]
        p_list.append(p)
        curp = p[-1]
    return np.vstack(p_list)

# create numpy array of coordinates representing result path
nx_array_path = get_full_path(nx_short_path)

# convert numpy array to Shapely Linestring
out_shortest_path = asLineString(nx_array_path)

write_geojson("../geodata/ch08_final_netx_sh_path.geojson", out_shortest_path.__geo_interface__ )
示例#33
0
    def calculate(self, k=3):
        """
        Calculates the convex hull of the data set as an array of points
        :param k: Number of nearest neighbors
        :return: Array of points (N, 2) with the concave hull of the data set
        """
        if self.data_set.shape[0] < 3:
            return None

        if self.data_set.shape[0] == 3:
            return self.data_set

        # Make sure that k neighbors can be found
        kk = min(k, self.data_set.shape[0])

        first_point = self.get_lowest_latitude_index(self.data_set)
        current_point = first_point

        # Note that hull and test_hull are matrices (N, 2)
        hull = np.reshape(np.array(self.data_set[first_point, :]), (1, 2))
        test_hull = hull

        # Remove the first point
        self.indices[first_point] = False

        prev_angle = 270  # Initial reference id due west. North is zero, measured clockwise.
        step = 2
        stop = 2 + kk

        while ((current_point != first_point) or
               (step == 2)) and len(self.indices[self.indices]) > 0:
            if step == stop:
                self.indices[first_point] = True

            knn = self.get_k_nearest(current_point, kk)

            # Calculates the headings between first_point and the knn points
            # Returns angles in the same indexing sequence as in knn
            angles = self.calculate_headings(current_point, knn, prev_angle)

            # Calculate the candidate indexes (largest angles first)
            candidates = np.argsort(-angles)

            i = 0
            invalid_hull = True

            while invalid_hull and i < len(candidates):
                candidate = candidates[i]

                # Create a test hull to check if there are any self-intersections
                next_point = np.reshape(self.data_set[knn[candidate]], (1, 2))
                test_hull = np.append(hull, next_point, axis=0)

                line = asLineString(test_hull)
                invalid_hull = not line.is_simple
                i += 1

            if invalid_hull:
                return self.recurse_calculate()

            # prev_angle = self.calculate_headings(current_point, np.array([knn[candidate]]))
            prev_angle = self.calculate_headings(knn[candidate],
                                                 np.array([current_point]))
            current_point = knn[candidate]
            hull = test_hull

            # write_line_string(hull)

            self.indices[current_point] = False
            step += 1

        poly = asPolygon(hull)

        count = 0
        total = self.data_set.shape[0]
        for ix in range(total):
            pt = asPoint(self.data_set[ix, :])
            if poly.intersects(pt) or pt.within(poly):
                count += 1
            else:
                d = poly.distance(pt)
                if d < 1e-5:
                    count += 1

        if count == total:
            return hull
        else:
            return self.recurse_calculate()
    points = []
    prev_x = 0
    prev_y = 0
    for i in range(0, len(coords) - 1, 2):
        if coords[i] == 0 and coords[i + 1] == 0:
            continue

        prev_x += coords[i + 1]
        prev_y += coords[i]
        # A round to 6 digits ensures that the floats are the same as when they were encoded
        points.append((round(prev_x, 6), round(prev_y, 6)))

    return points


# Go through each row of the data file and decode the encoded polyline into an SRID:3857 WKT LineString
output, count = [], 0
file_name = "gps_routes_sample.tsv"
with open(file_name, "rU") as f:
    reader = csv.reader(f, delimiter="\t")
    for i, row in enumerate(reader):
        decoded_polyline = decode(row[0])  # decode the polyline into an [x,y] coordinate array of arrays
        linestring = asLineString(decoded_polyline)  # create a WKT LineString from the coordinate array
        output.append([count, "SRID=3857;" + transform(project, linestring).wkt])  # project to SRID: 3857
        count += 1

# Write the transformed LineString data to a tab delimited file - easy to COPY into PostgreSQL database
with open("gps_routes_sample_parsed.tab", "a") as tab:
    writer = csv.writer(tab, delimiter="\t")
    writer.writerows(output)
示例#35
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
###############################################################################
from shapely.geometry import Point
from numpy import array

array(Point(0, 0))
from shapely.geometry import LineString

array(LineString([(0, 0), (1, 1)]))
###############################################################################
Point(0, 0).xy
LineString([(0, 0), (1, 1)]).xy
###############################################################################
from shapely.geometry import asPoint

pa = asPoint(array([0.0, 0.0]))
pa.wkt
###############################################################################
from shapely.geometry import asLineString

la = asLineString(array([[1.0, 2.0], [3.0, 4.0]]))
la.wkt