コード例 #1
0
ファイル: gridvar.py プロジェクト: axiom-data-science/paegan
    def get_boundingpolygon(self):
        """
            TODO: Implement ncell bbox

            order of lines creation (assumes 0,0 is x)
            -----3-----
            |         |
            4         2
            |         |
            x----1-----
        """

        if self._ndim == 2: # CGRID
            nx,ny = self._xarray.shape
            one = MultiLineString([((self._xarray[i][0],self._yarray[i][0]),(self._xarray[i+1][0],self._yarray[i+1][0])) for i in range(nx-1)])
            two = MultiLineString([((self._xarray[nx-1][j],self._yarray[nx-1][j]),(self._xarray[nx-1][j+1],self._yarray[nx-1][j+1])) for j in range(ny-1)])
            three = MultiLineString([((self._xarray[i][ny-1],self._yarray[i][ny-1]),(self._xarray[i-1][ny-1],self._yarray[i-1][ny-1])) for i in reversed(list(range(1,nx)))])
            four = MultiLineString([((self._xarray[0][j],self._yarray[0][j]),(self._xarray[0][j-1],self._yarray[0][j-1])) for j in reversed(list(range(1,ny)))])
            m = one.union(two).union(three).union(four)
        else: # RGRID
            nx,ny = self._xarray.shape[0], self._yarray.shape[0]
            one = LineString([(self._xarray[i], self._yarray[0]) for i in range(nx)])
            two = LineString([(self._xarray[-1], self._yarray[i]) for i in range(ny)])
            three = LineString([(self._xarray[i], self._yarray[-1]) for i in reversed(list(range(nx)))])
            four = LineString([(self._xarray[0], self._yarray[i]) for i in reversed(list(range(ny)))])
            m = MultiLineString([one,two,three,four])

        polygons = list(polygonize(m))
        # -- polygonize returns a list of polygons, including interior features, the largest in area "should" be the full feature
        assert len(polygons) > 0, "Could not determine a polygon"
        polygon = sorted(polygons, key=lambda x: x.area)[-1]
        return polygon
コード例 #2
0
class LinearReferencingTestCase(unittest.TestCase):
    def setUp(self):
        self.point = Point(1, 1)
        self.line1 = LineString(([0, 0], [2, 0]))
        self.line2 = LineString(([3, 0], [3, 6]))
        self.multiline = MultiLineString([
            list(self.line1.coords), list(self.line2.coords)
        ]) 

    def test_line1_project(self):
        self.assertEqual(self.line1.project(self.point), 1.0)
        self.assertEqual(self.line1.project(self.point, normalized=True), 0.5)

    def test_line2_project(self):
        self.assertEqual(self.line2.project(self.point), 1.0)
        self.assertAlmostEqual(self.line2.project(self.point, normalized=True),
            0.16666666666, 8)

    def test_multiline_project(self):
        self.assertEqual(self.multiline.project(self.point), 1.0)
        self.assertEqual(self.multiline.project(self.point, normalized=True),
            0.125)

    def test_not_supported_project(self):
        self.assertRaises(TypeError, self.point.buffer(1.0).project,
            self.point)

    def test_not_on_line_project(self):
        # Points that aren't on the line project to 0.
        self.assertEqual(self.line1.project(Point(-10,-10)), 0.0)

    def test_line1_interpolate(self):
        self.failUnless(self.line1.interpolate(0.5).equals(Point(0.5, 0.0)))
        self.failUnless(
            self.line1.interpolate(0.5, normalized=True).equals(
                Point(1.0, 0.0)))

    def test_line2_interpolate(self):
        self.failUnless(self.line2.interpolate(0.5).equals(Point(3.0, 0.5)))
        self.failUnless(
            self.line2.interpolate(0.5, normalized=True).equals(
                Point(3.0, 3.0)))

    def test_multiline_interpolate(self):
        self.failUnless(self.multiline.interpolate(0.5).equals(
            Point(0.5, 0.0)))
        self.failUnless(
            self.multiline.interpolate(0.5, normalized=True).equals(
                Point(3.0, 2.0)))

    def test_line_ends_interpolate(self):
        # Distances greater than length of the line or less than
        # zero yield the line's ends.
        self.failUnless(self.line1.interpolate(-1000).equals(Point(0.0, 0.0)))
        self.failUnless(self.line1.interpolate(1000).equals(Point(2.0, 0.0)))
コード例 #3
0
ファイル: Polygonize.py プロジェクト: AnAvidDeveloper/QGIS
 def processAlgorithm(self, progress):
     try:
         from shapely.ops import polygonize
         from shapely.geometry import Point, MultiLineString
     except ImportError:
         raise GeoAlgorithmExecutionException(
                 'Polygonize algorithm requires shapely module!')
     vlayer = dataobjects.getObjectFromUri(
             self.getParameterValue(self.INPUT))
     output = self.getOutputFromName(self.OUTPUT)
     vprovider = vlayer.dataProvider()
     if self.getParameterValue(self.FIELDS):
         fields = vprovider.fields()
     else:
         fields = QgsFields()
     if self.getParameterValue(self.GEOMETRY):
         fieldsCount = fields.count()
         fields.append(QgsField('area', QVariant.Double, 'double', 16, 2))
         fields.append(QgsField('perimeter', QVariant.Double,
                                'double', 16, 2))
     allLinesList = []
     features = vector.features(vlayer)
     current = 0
     total = 40.0 / float(len(features))
     for inFeat in features:
         inGeom = inFeat.geometry()
         if inGeom.isMultipart():
             allLinesList.extend(inGeom.asMultiPolyline())
         else:
             allLinesList.append(inGeom.asPolyline())
         current += 1
         progress.setPercentage(int(current * total))
     progress.setPercentage(40)
     allLines = MultiLineString(allLinesList)
     allLines = allLines.union(Point(0, 0))
     progress.setPercentage(45)
     polygons = list(polygonize([allLines]))
     progress.setPercentage(50)
     writer = output.getVectorWriter(fields, QGis.WKBPolygon, vlayer.crs())
     outFeat = QgsFeature()
     current = 0
     total = 50.0 / float(len(polygons))
     for polygon in polygons:
         outFeat.setGeometry(QgsGeometry.fromWkt(polygon.wkt))
         if self.getParameterValue(self.GEOMETRY):
             outFeat.setAttributes([None] * fieldsCount + [polygon.area,
                                   polygon.length])
         writer.addFeature(outFeat)
         current += 1
         progress.setPercentage(50 + int(current * total))
     del writer
コード例 #4
0
ファイル: precut.py プロジェクト: starshipfactory/precut
 def check_intersections(self):
     checks_done = MultiLineString()
     for subpath, elem in self.get_line_strings():
         line = subpath.as_linestring()
         if not line.is_simple:
             # TODO: find location of self-intersection and introduce some
             # tolerance
             # checks_done = checks_done.union(line)
             yield CheckerResult("self-intersection found", elem)
             # continue
         if checks_done.intersects(line):
             intersection = checks_done.intersection(line)
             yield CheckerResult("intersection found", elem, extra={"intersection": intersection})
         checks_done = checks_done.union(line)
コード例 #5
0
  def union(self):
    '''new method using Union function'''
    global polyCount
    inFeat = QgsFeature()

    progress = 0.

    self.emit(SIGNAL('progress'), 0)

    self.parent.layer = getMapLayerByName(self.ui.cmbLayer.currentText())
    provider = self.parent.layer.dataProvider()
    #user can't toggle edit mode of line layer while polygonizing, plugin automatically turn it off 
    QObject.connect(self.parent.layer,SIGNAL("editingStarted()"), self.parent.startEditing)
    allAttrs = provider.attributeIndexes()
    provider.select(allAttrs)

    provider.select()

    step = 45. / self.parent.layer.featureCount()
    allLinesList = []
    allLinesListExtend = allLinesList.extend
    allLinesListAppend = allLinesList.append

    while provider.nextFeature(inFeat):
      geom = inFeat.geometry()
      if geom.isMultipart():
        allLinesListExtend(geom.asMultiPolyline() )
      else:
        allLinesListAppend(geom.asPolyline())

      progress += step
      self.emit(SIGNAL('progress'), progress)

    allLines = MultiLineString(allLinesList)
    allLines = allLines.union(Point(0,0))

    polygons = list(polygonize([allLines]))

    polyCount = len(polygons)
    #if no polygons where created then exit from thread
    if polyCount == 0:
      QObject.disconnect(self.parent.polygonizeThread,SIGNAL("finished()"), self.parent.threadFinished)
      self.emit(SIGNAL('noPolygons'))
      return
    else:
      if self.ui.cbOutput.isChecked():
        self.saveAsFile(polygons, progress)
      else:
        self.saveInMemory(polygons, progress)
コード例 #6
0
def plot_buff(G_, ax, buff=20, color='yellow', alpha=0.3, 
              title='Proposal Snapping',
              title_fontsize=8, outfile='', 
              dpi=200,
              verbose=False):
    '''plot buffer around graph using shapely buffer'''
        
    # get lines
    line_list = []    
    for u, v, key, data in G_.edges(keys=True, data=True):
        if verbose:
            print("u, v, key:", u, v, key) 
            print("  data:", data)
        geom = data['geometry']
        line_list.append(geom)
    
    mls = MultiLineString(line_list)
    mls_buff = mls.buffer(buff)

    if verbose: 
        print("type(mls_buff) == MultiPolygon:", type(mls_buff) == shapely.geometry.MultiPolygon)
    
    if type(mls_buff) == shapely.geometry.Polygon:
        mls_buff_list = [mls_buff]
    else:
        mls_buff_list = mls_buff
    
    for poly in mls_buff_list:
        x,y = poly.exterior.xy
        coords = np.stack((x,y), axis=1)
        interiors = poly.interiors
        #coords_inner = np.stack((x_inner,y_inner), axis=1)
        
        if len(interiors) == 0:
            #ax.plot(x, y, color='#6699cc', alpha=0.0, linewidth=3, solid_capstyle='round', zorder=2)
            ax.add_patch(matplotlib.patches.Polygon(coords, alpha=alpha, color=color))
        else:
            path = pathify(poly)
            patch = PathPatch(path, facecolor=color, edgecolor=color, alpha=alpha)
            ax.add_patch(patch)
 
    ax.axis('off')
    if len(title) > 0:
        ax.set_title(title, fontsize=title_fontsize)
    #outfile = os.path.join(res_dir, 'gt_raw_buffer.png')
    if outfile:
        plt.savefig(outfile, dpi=dpi)
    return ax
コード例 #7
0
ファイル: map_api.py プロジェクト: SAUSy-Lab/nb-gtfs
	def __init__(self,trip_object):
		# initialize some variables
		self.trip = trip_object					# trip object that this is a match for
		self.geometry = MultiLineString()	# MultiLineString shapely geom
		self.OSRM_response = {}					# python-parsed OSRM response object
		self.confidence = 0						# 	
		# error radius to use for map matching, same for all points
		self.error_radius = conf['error_radius']
		self.default_route_used = False;
		# fire off a query to OSRM with the default parameters
		self.query_OSRM()
		if not self.OSRM_match_is_sufficient:
			# try again with a larger error radius
			self.error_radius *= 1.5
			self.query_OSRM()
		# still no good? 
		if not self.OSRM_match_is_sufficient:
			# Try a default geometry
			if self.get_default_route():
				self.locate_vehicles_on_default_route()
			else: 
				return # bad match, no default
		else: # have a workable OSRM match geometry
			self.parse_OSRM_geometry()
			self.locate_vehicles_on_OSRM_route()
		if len(self.trip.vehicles) > 2:
			self.locate_stops_on_route()
		# report on what happened
		self.print_outcome()
コード例 #8
0
 def setUp(self):
     self.point = Point(1, 1)
     self.line1 = LineString(([0, 0], [2, 0]))
     self.line2 = LineString(([3, 0], [3, 6]))
     self.multiline = MultiLineString([
         list(self.line1.coords), list(self.line2.coords)
     ])
コード例 #9
0
ファイル: map_api.py プロジェクト: SAUSy-Lab/nb-gtfs
	def get_default_route(self):
		"""Check if a default route geometry is available; if so, we'll need to 
			parse things into the same format, just as though this had come from 
			OSRM."""
		# get the default if there is one
		route_geom = db.get_route_geom( self.trip.direction_id, self.trip.last_seen )
		if route_geom: # default available
			self.default_route_used = True
			self.confidence = 1
			self.geometry = MultiLineString([route_geom])
			return True
		else: # no default
			return False
コード例 #10
0
ファイル: simulation.py プロジェクト: m3d/osgar_archive_2020
 def __init__(self, bus, end_condition, world=None):
     bus.register('scan', 'rot', 'orientation', 'sim_time_sec', 'origin',
                  'pose2d', 'acc', 'artf')
     self.bus = bus
     self.end_condition = end_condition
     self.world = world if world is not None else MultiLineString()
     self._handlers = collections.defaultdict(lambda: self.on_default)
     self.set_handler('request_origin', self.on_request_origin)
     self.set_handler('desired_speed', self.on_desired_speed)
     self.set_handler('pose2d', self.on_pose)
     self.set_handler('pose3d', self.on_pose)
     self.origin = [7.0, 3.0, 0.0]
     self.xyz = [0.0, 0.0, 0.0]
     self.orientation = quaternion.identity()
     self.speed_forward = 0.0
     self.speed_angular = 0.0
     self.time = datetime.timedelta()
コード例 #11
0
def round_multilinestring_coords(mls, precision):
    """
    Round the coordinates of a shapely MultiLineString to some decimal precision.

    Parameters
    ----------
    mls : shapely MultiLineString
        the MultiLineString to round the coordinates of
    precision : int
        decimal precision to round coordinates to

    Returns
    -------
    MultiLineString
    """

    return MultiLineString([round_linestring_coords(ls, precision) for ls in mls])
コード例 #12
0
def projected_multigeometry(geom):
    ''' Accept an unprojected geometry and return a projected multigeometry.
    '''
    geoms = getattr(geom, 'geoms', [geom])

    if geom.type in ('LineString', 'MultiLineString'):
        projected = MultiLineString(list(map(_m, geoms)))

    elif geom.type in ('Polygon', 'MultiPolygon'):
        parts = [(_m(poly.exterior), list(map(_m, poly.interiors)))
                 for poly in geoms]
        projected = MultiPolygon(parts)

    else:
        raise ValueError("Can't generalize a %s geometry" % geom.type)

    return projected
コード例 #13
0
def test_rect_grid_multilinestring_in_one_cell_shapely():
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_rect_grid()
    ix = GridIntersect(gr)
    result = ix.intersect_linestring(
        MultiLineString([
            LineString([(1., 1), (9., 1.)]),
            LineString([(1., 9.), (9., 9.)])
        ]))
    assert len(result) == 1
    assert result.lengths == 16.
    assert result.cellids[0] == (1, 0)
    return result
コード例 #14
0
ファイル: parse.py プロジェクト: Ricyteach/msh2shapely
def element_dict(element_list: List[Element],
                 node_dict: Dict[int, Point]) -> Dict[int, MultiLineString]:
    """A dictionary from an element list that turns an element number into a shapely MultiLineString"""

    d: Dict[int, MultiLineString] = dict()

    for e in element_list:
        if len(e) == 2:
            line_strings = (LineString((node_dict[e.i], node_dict[e.j])), )
        else:
            lhs, rhs = e[:-1], e[1:] + e[:1]
            line_strings = tuple(
                LineString((node_dict[n1], node_dict[n2]))
                for n1, n2 in zip(lhs, rhs))
        d[e.num] = MultiLineString(line_strings)

    return d
コード例 #15
0
def test_with_known_mls_error():
    """
    Test branches_and_nodes with known mls error.
    """
    linestrings = samples.mls_from_these_linestrings_list
    target_area = [box(*MultiLineString(linestrings).bounds)]
    branches, nodes = branches_and_nodes.branches_and_nodes(
        gpd.GeoSeries(linestrings), gpd.GeoSeries(target_area),
        Helpers.snap_threshold)
    for branch in branches.geometry:
        assert EE_branch not in str(branches[CONNECTION_COLUMN])
        assert isinstance(branch, LineString)
        assert branch.is_simple
        assert not branch.is_empty
    for node in nodes.geometry:
        assert isinstance(node, Point)
        assert not node.is_empty
コード例 #16
0
    def contours_to_multiline(da_i, z_value, min_vertices=2):
        '''
        Helper function to apply marching squares contour extraction
        to an array and return a data as a shapely MultiLineString.
        The `min_vertices` parameter allows you to drop small contours 
        with less than X vertices.
        '''

        # Extracts contours from array, and converts each discrete
        # contour into a Shapely LineString feature
        line_features = [
            LineString(i[:, [1, 0]]) for i in find_contours(da_i, z_value)
            if i.shape[0] > min_vertices
        ]

        # Output resulting lines into a single combined MultiLineString
        return MultiLineString(line_features)
コード例 #17
0
def rectilinear_optimal(shape, gap, angle):
    hlines, clines, theta, c, x = get_all(shape, gap)
    if not clines:
        return [], None, None, 0, 0, 0, 0
    prob = LpProblem("Problema_Teste",LpMaximize)

    xf = [j for i in x for j in i]
    z = LpVariable.dicts("LC",xf,cat = 'Binary')

    prob += lpSum(z)

    '''restrição de não poder usar uma linha de conexão que não existe'''
    for i in range(len(x)):
        for j in range(len(x[i])-1):
            prob += z[x[i][j]] + z[x[i][j+1]] <= 1
            prob += theta[i][j] + z[x[i][j]] <= 1
        prob += theta[i][-1] + z[x[i][-1]] <= 1

    ''' restrição não poder ir para duas linhas de conexão que possuem uma ligação'''
    for i in range(len(c)):
        for j in range(i+1,len(c[i])):
            for k in range(len(c[i][j])):
                if(c[i][j][k] != 0):
                    prob += c[i][j][k] * (z[x[i][k]] + z[x[j][k]]) <= 1
    prob.solve(PULP_CBC_CMD(msg=0));
    tempo = prob.solutionTime
    num_restr = len(prob.constraints)
    num_var = len(prob._variables)

    vecSol = [v.varValue for v in prob.variables()]

    valor = value(prob.objective)

    selected_lines = []
    for v in prob.variables():
        if v.varValue == 1:
            i = int(v.name[4:].split(".")[0])
            j = int(v.name[4:].split(".")[1])
            selected_lines.append(clines[i][j])

    selected_lines.extend(hlines)
    paths = linemerge(MultiLineString(selected_lines))
    if type(paths) == LineString:
        return [paths]
    else:
        return list(paths)
コード例 #18
0
def get_connections_by_heights(clines, polygon, gap):
    minx, miny, maxx, maxy = get_bounds(polygon)
    num_hlines = int((maxy - miny)/gap) + 1
    edges = linemerge(MultiLineString(clines))

    clines_by_heights = []
    theta = np.ones((len(edges), num_hlines))
    for i, edge in enumerate(edges):
        clines_by_heights.append([])
        for j in range(num_hlines):
            clines_by_heights[i].append(None)
        for line in clines:
            if line.within(edge):
                j = int((line.bounds[1]-miny)/gap)
                clines_by_heights[i][j] = line
                theta[i][j] = 0
    return clines_by_heights, theta
コード例 #19
0
def test_projection():
    given = GeometryCollection([
        MultiPoint([(1, 2), (3, 4), (5, 6), (7, 8)]),
        MultiLineString([[(20, 30), (40, 50), (60, 70)]]),
        MultiPolygon([[[(1.1, 1.2), (1.3, 1.4), (1.5, 1.6), (1.7, 1.8), (1.1, 1.2)], []]]),
    ])
    result = project(given, WGS84, MOLLWEIDE).wkt
    assert 'MULTIPOINT' in result
    assert 'GEOMETRYCOLLECTION' in result

    result = project(given).wkt
    assert 'MULTIPOINT' in result
    assert 'GEOMETRYCOLLECTION' in result


    expected = 'GEOMETRYCOLLECTION (MULTIPOINT (1 2, 3 4, 5 6, 7 8), MULTILINESTRING ((20 30, 40 50, 60 70)), MULTIPOLYGON (((1.1 1.2, 1.3 1.4, 1.5 1.6, 1.7 1.8, 1.1 1.2))))'
    assert project(given, WGS84, WGS84).wkt == expected
コード例 #20
0
def generate_subpanel_bridges(dxf_outline_space, dxf_drill_space, area,
                              cutout_width, count_x, count_y):
    __generate_bridges(dxf_outline_space, area, count_x, count_y)

    frame_lines = MultiLineString(cutout_lines)

    generate_mouse_bites(area, dxf_drill_space, frame_lines)

    for splitter in splitter_rectangles:
        frame_lines = frame_lines.difference(splitter)

    # Merge all lines, so the endpoints are not where lines cross
    frame_lines = ops.linemerge(frame_lines)

    inset_lines = []
    for frame_line in frame_lines:
        line = frame_line.parallel_offset(2, 'left')

        # line2 = frame_line.parallel_offset(2, 'right')
        if frame_line.boundary and line.boundary:
            inset_line = LineString([frame_line.boundary[0], line.boundary[0]])
            inset_lines.append(inset_line)
            inset_line = LineString([frame_line.boundary[1], line.boundary[1]])
            inset_lines.append(inset_line)

        line = frame_line.parallel_offset(2, 'right')
        if frame_line.boundary and line.boundary:
            inset_line = LineString([frame_line.boundary[0], line.boundary[1]])
            inset_lines.append(inset_line)
            inset_line = LineString([frame_line.boundary[1], line.boundary[0]])
            inset_lines.append(inset_line)

        # frame_lines = frame_lines.union(inset_line)

    inset_lines = MultiLineString(inset_lines)
    dilated_insets = inset_lines.buffer(cutout_width / 3, join_style=1)

    # Remove outward bridges TODO: Needs better solution, this one is a quick hack TODO: Check if interior exterior
    #  of polygon would work: https://gis.stackexchange.com/questions/341604/creating-shapely-polygons-with-holes
    # dilated_insets = clean_outer_perimeter(area, dilated_insets)

    # Merge cutouts and insets
    dilated = frame_lines.buffer(cutout_width / 2, cap_style=2, join_style=2)
    dilated = dilated.union(dilated_insets)
    # Round the corners of insets
    dilated = dilated.buffer(0.8, join_style=1).buffer(-0.8, join_style=1)
    for element in dilated:
        dxf_outline_space.add_lwpolyline(element.exterior.coords)
コード例 #21
0
    def generate(self, date, moduleid):
        # 尝试将一个相交线写入到文件
        list = self.db.findAllLineByDateModuleid(date, moduleid)
        if len(list) == 0:
            return

        lineList = []
        for wkt in list:
            lineList.append(loads(wkt[2]))

        lines = MultiLineString(lineList)

        # print(lines.bounds)

        # box = self.boxByModuleidDate(date, moduleid)
        startLon = lines.bounds[0]
        startLat = lines.bounds[1]
        polygonList = []

        for geo in lines:
            # print("id=%d" % (geo[0]))
            box256 = self.createTileBox(startLon, startLat, geo.bounds[0],
                                        geo.bounds[1], geo.bounds[2],
                                        geo.bounds[3])
            lonlat = box256[0]
            tileXy = box256[1]
            key = str(date) + "_" + str(moduleid) + "_" + str(
                tileXy[0]) + "_" + str(tileXy[1])
            imgToPolygon = ImgToPolygon(startLon, startLat)

            if key not in self.keyList:
                filePath = self.getTrainTestImageByFileKey(key)
                if os.path.exists(filePath):
                    self.keyList.append(key)
                    list = imgToPolygon.toPolygon(tileXy, filePath)
                    polygonList = polygonList + list

        # 尝试将一天的地块多边形写入到文件
        polygonList = cascaded_union(polygonList)

        # for p in polygonList:
        #     self.flowcountLine.wirteIntersection(moduleid, str(date), lineList, p)
        # self.flowcountLine.save()

        return polygonList
コード例 #22
0
    def plot(self, geometry, inverse = False):
        geometries = hasattr(geometry, 'geoms') and geometry.geoms or [geometry]
        res = []

        # at first shift polygons
        #shifted = []
        #for geom in geometries:
        #    if isinstance(geom, Polygon):
        #        shifted += self._shift_polygon(geom)
        #    else:
        #        shifted += [geom]

        for geom in geometries:
            if isinstance(geom, Polygon):
                res += self.plot_polygon(geom, inverse = inverse)
            elif isinstance(geom, LineString):
                rings = self.plot_linear_ring(geom, inverse = inverse)
                res += map(LineString, rings)
            elif isinstance(geom, Point):
                if self._visible(geom.x, geom.y) and inverse:
                    x, y = self.project_inverse(geom.x, geom.y)
                    res.append(Point(x, y))
                elif self._visible(geom.x, geom.y):
                    x, y = self.project(geom.x, geom.y)
                    res.append(Point(x, y))
            else:
                pass
                # raise KartographError('proj.plot(): unknown geometry type %s' % geom)

        if len(res) > 0:
            if isinstance(res[0], Polygon):
                if len(res) > 1:
                    return MultiPolygon(res)
                else:
                    return res[0]
            elif isinstance(res[0], LineString):
                if len(res) > 1:
                    return MultiLineString(res)
                else:
                    return LineString(res[0])
            else:
                if len(res) > 1:
                    return MultiPoint(res)
                else:
                    return Point(res[0].x, res[0].y)
コード例 #23
0
ファイル: google.py プロジェクト: kyroskoh/RouteComparison
    def create_multilinestring(self, route_json):
        """Converts original google route data to more suitable format
        for creating shapely and ogr geometry. Creates Shapely and Ogr
        LineString geometries from route coordinates.

        .. note:: Raw Google route data is in proprietary format, so
            GOOGLE_POLYLINE_DECODER is needed to convert it to more suitable
            format. Moreover, Raw google data may contain multiple routes,
            each route contains legs, each leg contains steps and each step
            contains encoded polyline points.

        :arg route_json: dictionary with google route data
        :type route_json: dictionary

        :returns: tuple consisted of route's shapely and ogr geometry
        :rtype: (shapely.geometry.linestring.LineString, osgeo.ogr.Geometry)

        """
        # List of all polylines.
        polyline_list = []
        route_distance = 0
        duration = 0

        for route in route_json['routes']:
            for leg in route['legs']:
                route_distance += leg['distance']['value'] / 1000.0
                duration += leg['duration']['value']

                for step in leg['steps']:  # step is "edge"
                    decoded_polyline = (
                        GOOGLE_POLYLINE_DECODER.decode_google_polyline(
                            point_str=step['polyline']['points']))

                    polyline_list.append(decoded_polyline)

        # Create shapely multilinestring from list of polylines.
        route_multilinestring_shapely = MultiLineString(polyline_list)
        # Create ogr multilinestring
        route_multilinestring_ogr = ogr.CreateGeometryFromWkb(
            route_multilinestring_shapely.wkb)

        driving_time = {'sec': duration, 'hms': DT.timedelta(seconds=duration)}

        return (route_multilinestring_shapely, route_multilinestring_ogr,
                route_distance, driving_time)
コード例 #24
0
ファイル: util.py プロジェクト: zassa/geoviews
def path_to_geom_dicts(path, skip_invalid=True):
    """
    Converts a Path element into a list of geometry dictionaries,
    preserving all value dimensions.
    """
    interface = path.interface.datatype
    if interface == 'geodataframe':
        return [row.to_dict() for _, row in path.data.iterrows()]
    elif interface == 'geom_dictionary':
        return path.data

    geoms = []
    invalid = False
    xdim, ydim = path.kdims
    for i, path in enumerate(path.split(datatype='columns')):
        array = np.column_stack([path.pop(xdim.name), path.pop(ydim.name)])
        splits = np.where(np.isnan(
            array[:, :2].astype('float')).sum(axis=1))[0]
        arrays = np.split(array, splits + 1) if len(splits) else [array]
        subpaths = []
        for j, arr in enumerate(arrays):
            if j != (len(arrays) - 1):
                arr = arr[:-1]  # Drop nan

            if len(arr) == 0:
                continue
            elif len(arr) == 1:
                if skip_invalid:
                    continue
                g = Point(arr[0])
                invalid = True
            else:
                g = LineString(arr)
            subpaths.append(g)

        if invalid:
            geoms += [dict(path, geometry=sp) for sp in subpaths]
            continue
        elif len(subpaths) == 1:
            geom = subpaths[0]
        elif subpaths:
            geom = MultiLineString(subpaths)
        path['geometry'] = geom
        geoms.append(path)
    return geoms
コード例 #25
0
 def route_to_line_string(graph):
     """
     Method converts route representes as Directed Acyclic Graph to LineString
     :param graph: MultiDiGraph, DiGraph
     :return: LineString
     """
     geometries = [e[2]['geometry'] for e in graph.edges(data=True)]
     # Some edges have list as geometry
     geometries = list(flatten(geometries))
     # Form MultiLineString of given LineString geometries
     multi_line = MultiLineString(geometries)
     # Finally merge them
     merged_line = ops.linemerge(multi_line)
     # merged_line = ops.unary_union(geometries)
     if isinstance(merged_line, MultiLineString):
         print("Warning: route can`t be merged", file=sys.stderr)
         # merged_line = connect_lines(merged_line)
     return merged_line
コード例 #26
0
ファイル: test_spatial.py プロジェクト: meracan/mshapely
def test_resample():
    point = Point((0, 0)).resample()
    assert_array_equal(point.np, [[0, 0]])
    assert_array_equal(
        LineString([(0, 0), (10, 0)]).resample(),
        np.column_stack((np.arange(11), np.zeros(11))))
    assert_array_equal(
        LineString([(0, 0), (10, 0)]).resample(2),
        np.column_stack((np.arange(0, 11, 2), np.zeros(6))))

    assert_array_equal(
        MultiLineString([[(0, 0), (10, 0)]]).resample().xy,
        np.column_stack((np.arange(11), np.zeros(11))))

    assert_array_equal(
        Polygon([(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)]).resample().xy,
        np.array([[0., 0.], [0., 1.], [0., 2.], [1., 2.], [2., 2.], [2., 1.],
                  [2., 0.], [1., 0.], [0., 0.]]))
コード例 #27
0
    def simplify_multiline(self, mline, threshold):
        # break MultiLineString into lines
        lineList = mline.geoms
        simpleLineList = []

        # call simplify_line on each
        for line in lineList:
            simpleLine = self.simplify_line(line, threshold)
            #if not none append to list
            if simpleLine:
                simpleLineList.append(simpleLine)

        # check that line count > 0, otherwise return None
        if not simpleLineList:
            return None

        # put back into multilinestring
        return MultiLineString(simpleLineList)
コード例 #28
0
    def restore_geometry(self, lines, minArea=0):
        """
        restores geometry from linear rings
        """
        from shapely.geometry import LineString, MultiLineString
        linestrings = []
        for line in lines:
            kept = []
            for pt in line:
                if not pt.deleted:
                    kept.append((pt[0], pt[1]))
            if len(kept) >= 2:
                linestrings.append(LineString(kept))

        if len(linestrings) > 0:
            self.geometry = MultiLineString(linestrings)
        else:
            self.geometry = None
コード例 #29
0
ファイル: check_roads_geom.py プロジェクト: smartparrot/iem
def main():
    """Go Main, please"""
    pgconn = get_dbconn("postgis")
    cursor = pgconn.cursor()
    req = requests.get(URI, timeout=30)
    jobj = req.json()
    featureset = jobj["layers"][0]["featureSet"]
    for feat in featureset["features"]:
        props = feat["attributes"]
        # Geometry is [[pt]] and we only have single segments
        path = MultiLineString([LineString(feat["geometry"]["paths"][0])])
        # segid is defined by the database insert
        major = props["ROUTE_NAME"]
        (typ, _num) = major.replace("-", " ").split()
        if typ not in ["I", "US", "IA"]:
            print("Totally unknown, abort")
            print(json.dumps(jobj, indent=4))
            sys.exit()
        geom = ("ST_Transform(ST_SetSrid(ST_GeomFromText('%s'), 3857), 26915)"
                ) % (path.wkt)
        idot_id = props["SEGMENT_ID"]
        cursor.execute(
            """
        SELECT st_length(geom),
        st_length(""" + geom + """), archive_begin from roads_base
        where idot_id = %s and archive_begin > '2017-01-01'::date
        ORDER by archive_begin DESC
        """,
            (idot_id, ),
        )
        row = cursor.fetchone()
        if abs(row[1] - row[0]) > 1:
            print("%s, %s" % (str(row), cursor.rowcount))
            cursor.execute(
                """
            UPDATE roads_base SET geom = """ + geom + """
            WHERE idot_id = %s and archive_begin > '2017-01-01'::date
            """,
                (idot_id, ),
            )
            print("updated %s rows" % (cursor.rowcount, ))

    cursor.close()
    pgconn.commit()
コード例 #30
0
    def get(self,apnk,LatLongs):
        # Adding Geolocation
        gmaps = googlemaps.Client(key=apnk)
        val = []
        geolocation = GoogleV3(api_key=apnk)
        RoadInfo = json.loads(LatLongs)
        directions = gmaps.directions(RoadInfo[0],RoadInfo[1],mode="driving",alternatives=True)
        polylines = [i["overview_polyline"]["points"] for i in directions]
        routeLengths = [j["distance"]["value"]  for i in directions for j in i["legs"]]
        routeDurations = [j["duration"]["value"]  for i in directions for j in i["legs"]]
        cur = mysql.connection.cursor()
        AccData = pd.read_sql('select Longitude, Latitude, RadiusInKM, PostcodeNo, AccidentCount,concat(RoadName,\' \', RoadType) as Road from AccidentCluster where AccidentCount > 1 ;',con=mysql.connection)
        LS = [LineString(PolylineCodec().decode(line)[1::2]) for line in polylines]
        MLS = MultiLineString(LS)
        bounds = MLS.bounds
        newData = AccData.loc[(AccData['Latitude'] >= bounds[0]) & (AccData['Latitude'] <= bounds[2]) & (AccData['Longitude'] >= bounds[1]) & (AccData['Longitude'] <= bounds[3])]
        
        def myFun(point,line):
            np = line.interpolate(line.project(point))
            new_point = pnt(longitude=np.y,latitude=np.x)
            old_point = pnt(longitude=point.y,latitude=point.x)
            dist = distance(new_point,old_point).km
            return dist

        geo = geop.GeoDataFrame(newData,geometry=geop.points_from_xy(newData.Latitude,newData.Longitude))
        
        for i in range(len(LS)):
            s=str(i)
            geo[s] = geo.apply(lambda val: myFun(val['geometry'],LS[i]),axis=1)

        for i in range(7,len(geo.columns)):
            j = str(i-7)
            newdf = geo.loc[(geo[j] <= 3.0)]
            dropList = [str(thing-7) for thing in range(7,len(geo.columns))]
            newdf = newdf.drop(columns=dropList)
            newdf = newdf.drop(columns=['geometry'])
            val.append({"RouteNo":int(j),"polyline": polylines[i-7],
            'routeLengthInMeters':routeLengths[i-7],
            'routeDurationInSeconds':routeDurations[i-7],
            'data':newdf.to_dict(orient='records'),
            'totalAccidents': str(newdf['AccidentCount'].sum()),
            'bounds':bounds})
        finalVal = {'routes':val}
        return jsonify(finalVal)
コード例 #31
0
 def load_poly_file(self, poly_file):
     points_basename = os.path.basename(poly_file).replace(
         'POLY_', 'POINTS_', 1).replace('_shp', '_pts')
     print('Running %s...' % points_basename)
     points_path = os.path.join(self.analysis_folder, points_basename)
     if not os.path.isfile(points_path):
         print(points_path)
         print(poly_file)
         print('error: points not found for ', os.path.basename(poly_file))
     else:
         self.poly_path_to_points_dic[poly_file] = points_path
         poly_poly = shp.Reader(poly_file)
         # 2. Load poly file
         #       2.1 check if it is an area or a line
         poly_check = True
         building_poly_coords = None
         building_poly = None
         try:
             building_poly_coords = poly_poly.shapeRecords(
             )[0].shape.__geo_interface__['coordinates']
             building_string = LineString(building_poly_coords[0])
         except ValueError:
             print('linelist')
             line_list = []
             for a in poly_poly.shapeRecords():
                 building_poly_coords = a.shape.__geo_interface__[
                     'coordinates']
                 line_list.append(building_poly_coords)
             building_string = MultiLineString(line_list)
             poly_check = False
         building_buff = building_string.buffer(5)
         building_interior = building_buff.interiors
         # what was this meant to achieve??????
         try:
             building_poly = unary_union(building_string, building_interior)
         except Exception as e:
             # print('e3', e)
             print('unary exception')
             pass
         if poly_check:
             building_poly = Polygon(building_poly_coords[0])
         else:
             building_poly = building_string
         self.poly_shp_dic[poly_file] = (building_poly, building_string)
コード例 #32
0
ファイル: svg_utils.py プロジェクト: Bielorusse/halftone
def path_to_lines(path_str):
    """
    Read SVG path string using svg.path and convert it to a shapely MultiLineString object.

    Parameters
    ----------
    path_str : str

    Returns
    -------
    shapely.geometry.MultiLineString
    """

    # parse svg path
    path = svg.path.parse_path(path_str)

    # initiate lists and coords
    lines = []
    points = []
    x0 = 0
    y0 = 0
    x1 = 0
    y1 = 0

    for element in path:
        if isinstance(element, svg.path.Move) and not (x1 == 0 and y1 == 0):
            # element is a move (pen up): close line with previous element end point
            points.append((x1, y1))
            lines.append(points)
            points = []
        elif isinstance(element, svg.path.Line):
            # element is a line (pen down): add element start point
            x0 = element.start.real
            y0 = element.start.imag
            x1 = element.end.real
            y1 = element.end.imag
            points.append((x0, y0))
    if points != []:
        # close line with previous element end point
        points.append((x1, y1))
        lines.append(points)
        points = []

    return MultiLineString(lines)
コード例 #33
0
ファイル: util.py プロジェクト: marammuabrak/crash-model
def reproject_records(records, inproj='epsg:4326', outproj='epsg:3857'):
    """
    Reprojects a set of records from one projection to another
    Records can either be points, line strings, or multiline strings
    Args:
        records - list of records to reproject
        inproj - defaults to 4326
        outproj - defaults to 3857
    Returns:
        list of reprojected records
    """
    results = []
    inproj = pyproj.Proj(init=inproj)
    outproj = pyproj.Proj(init=outproj)

    for record in records:

        coords = record['geometry']['coordinates']
        if record['geometry']['type'] == 'Point':
            re_point = pyproj.transform(inproj, outproj, coords[0], coords[1])
            point = Point(re_point)
            results.append({'geometry': point,
                            'properties': record['properties']})
        elif record['geometry']['type'] == 'MultiLineString':
            new_coords = []
            for segment in coords:
                new_segment = []
                for coord in segment:
                    new_segment.append(pyproj.transform(
                        inproj, outproj, coord[0], coord[1]))
                new_coords.append(new_segment)

            results.append({'geometry': MultiLineString(new_coords),
                            'properties': record['properties']})
        elif record['geometry']['type'] == 'LineString':
            new_coords = []
            for coord in coords:
                new_coords.append(
                    pyproj.transform(inproj, outproj, coord[0], coord[1])
                )
            results.append({'geometry': LineString(new_coords),
                            'properties': record['properties']})

    return results
コード例 #34
0
def polygonizeFeatures(features, fields=None):
    lineList = []
    for inFeat in features:
        inGeom = inFeat.geometry()
        if inGeom is None:
            pass
        elif inGeom.isMultipart():
            lineList.extend(inGeom.asMultiPolyline())
        else:
            lineList.append(inGeom.asPolyline())
    allLines = MultiLineString(lineList)
    allLines = unary_union(allLines)
    polygons = list(polygonize([allLines]))
    outList = []
    for polygon in polygons:
        outFeat = QgsFeature(fields)
        outFeat.setGeometry(QgsGeometry.fromWkt(polygon.wkt))
        outList.append(outFeat)
    return outList
コード例 #35
0
ファイル: fig2layer.py プロジェクト: motiejus/stud
def sinewave(args):
    INTERVAL = 0.1

    if args.numwaves == 2:
        TAIL_LEN, SINE_LEN = 7, 7
        TAILS = np.zeros(int(TAIL_LEN / INTERVAL))
        sin_range = np.arange(-pi / 4, SINE_LEN, INTERVAL) * pi / 2
        amplitude = (np.sin(sin_range) + 1)
    else:
        TAIL_LEN, SINE_LEN = 3.5, 3.5
        TAILS = np.zeros(int(TAIL_LEN / INTERVAL))
        sin_range = np.arange(-pi / 4, SINE_LEN - pi / 8, INTERVAL) * pi / 2
        amplitude = np.sin(sin_range) + 1

    y = np.concatenate([TAILS, amplitude, TAILS])
    x = np.arange(-TAIL_LEN - pi / 4, SINE_LEN + TAIL_LEN, INTERVAL)
    lines = LineString(zip(x * 10, y * 10))
    geom = MultiLineString([lines])
    write_file(args, geom)
コード例 #36
0
ファイル: fort14.py プロジェクト: JaimeCalzadaNOAA/adcircpy
 def gdf(self):
     if not hasattr(self, '_gdf'):
         data = []
         for i, (id, boundary) in enumerate(self._data.items()):
             front_face, back_face = list(zip(*self.indexes[i]))
             data.append({
                 'geometry':
                 MultiLineString([
                     LineString(
                         self._mesh.coords.iloc[front_face, :].values),
                     LineString(
                         self._mesh.coords.iloc[back_face, :].values),
                 ]),
                 'key':
                 f'{boundary.get("ibtype")}:{id}',
                 **boundary,
             })
         self._gdf = gpd.GeoDataFrame(data, crs=self._mesh.crs)
     return self._gdf
コード例 #37
0
def test_tri_grid_multilinestring_in_one_cell(rtree=True):
    # avoid test fail when shapely not available
    try:
        import shapely
    except:
        return
    gr = get_tri_grid()
    if gr == -1:
        return
    ix = GridIntersect(gr, rtree=rtree)
    result = ix.intersect(
        MultiLineString([
            LineString([(1., 1), (9., 1.)]),
            LineString([(2., 2.), (9., 2.)])
        ]))
    assert len(result) == 1
    assert result.lengths == 15.
    assert result.cellids[0] == 4
    return result
コード例 #38
0
ファイル: server.py プロジェクト: afcarl/hackday
def walkshed(start, dist):
    visited = []
    queued = [start]
    to_visit = [(start, 0)]  # node, dist at node
    lines = []

    while to_visit:
        node, cur_dist = to_visit.pop()
        edges = n.edges(nbunch=[node], data=True)
        for e in edges:
            if e[2]['type'] in ['1', '5', '6', '10']:
                if cur_dist + e[2]['len'] < dist:
                    if e[2]['geo'] not in lines:
                        lines.append(e[2]['geo'])
                    if e[1] not in queued:
                        to_visit.append((e[1], cur_dist + e[2]['len']))
                        queued.append(e[1])

    return mapping(MultiLineString(lines))
コード例 #39
0
	def __init__(self,vehicles):
		# initialize some variables
		self.vehicles = vehicles
		self.confidence = None					# average match confidence
		self.geom = MultiLineString()			# multiline shapely geom
		self.error_radius = conf['error_radius']
		self.use_times = False					# whether times are sent to OSRM
		self.response = {}						# python-parsed formerly-JSON object
		self.is_useable = True					# good enough to be used elsewhere?
		self.num_attempts = 0
		# send the query right away
		self.send()
		# validate the results - can we likely improve on them?
		self.validate()
		# output
		if self.is_useable:
			print '\tconf. is',self.confidence,'on',len(self.response['matchings']),'match(es) after',self.num_attempts,'tries' 
		else:
			print '\tmatching failed'
コード例 #40
0
ファイル: _layer.py プロジェクト: perrygeo/geofu
    def _overlay(self, layer2, method):
        assert method in ['union', 'intersection', 'identity']

        idx1 = index.Index()
        idx2 = index.Index()

        # for fast lookup of geometry and properties after spatial index
        # advantage: don't have to reopen ds and seek on disk
        # disadvantage: have to keep everything in memory
        #  {id: (shapely geom, properties dict) }
        # TODO just use the index as the id and just copy the fiona records?
        features1 = {}
        features2 = {}
        rings1 = []
        rings2 = []

        log.debug("gathering LinearRings")
        log.debug("\tself")
        for rec in self.collection():
            geom = shape(rec['geometry'])
            rid = int(rec['id'])
            features1[rid] = (geom, rec['properties'])
            idx1.insert(rid, geom.bounds)
            if hasattr(geom, 'geoms'):
                for poly in geom.geoms:  # if it's a multipolygon
                    if not poly.is_valid:
                        log.debug("\tgeom from self layer is not valid," +
                                  " attempting fix by buffer 0")
                        poly = poly.buffer(0)
                    rings1.append(poly.exterior)
                    rings1.extend(poly.interiors)
            else:
                if not geom.is_valid:
                    log.debug("\tgeom from self layer is not valid," +
                              " attempting fix by buffer 0")
                    geom = geom.buffer(0)
                rings1.append(geom.exterior)
                rings1.extend(geom.interiors)

        log.debug("\tlayer2")
        for rec in layer2.collection():
            geom = shape(rec['geometry'])

            rid = int(rec['id'])
            features2[rid] = (geom, rec['properties'])
            idx2.insert(rid, geom.bounds)

            if hasattr(geom, 'geoms'):
                for poly in geom.geoms:  # multipolygon
                    if not poly.is_valid:
                        log.debug("\t geom from layer2 is not valid," +
                                  " attempting fix by buffer 0")
                        poly = poly.buffer(0)
                    rings2.append(poly.exterior)
                    rings2.extend(poly.interiors)
            else:
                if not geom.is_valid:
                    log.debug("\t geom from layer2 is not valid," +
                              " attempting fix by buffer 0")
                    geom = geom.buffer(0)
                rings2.append(geom.exterior)
                rings2.extend(geom.interiors)

        #rings = [x for x in rings if x.is_valid]
        mls1 = MultiLineString(rings1)
        mls2 = MultiLineString(rings2)

        try:
            log.debug("calculating union (try the fast unary_union)")
            mm = unary_union([mls1, mls2])
        except:
            log.exception("unary_union FAILED")
            log.debug("calculating union again (using the slow a.union(b))")
            mm = mls1.union(mls2)

        log.debug("polygonize rings")
        newpolys = polygonize(mm)

        log.debug("constructing new schema")
        out_schema = self.collection().schema.copy()
        # TODO polygon geomtype

        layer2_schema_map = {}  # {old: new}
        for key, value in layer2.collection().schema['properties'].items():
            if key not in out_schema['properties']:
                out_schema['properties'][key] = value
                layer2_schema_map[key] = key
            else:
                # try to rename it
                i = 2
                while True:
                    newkey = "%s_%d" % (key, i)
                    if newkey not in out_schema['properties']:
                        out_schema['properties'][newkey] = value
                        layer2_schema_map[key] = newkey 
                        break
                    i += 1 

        tempds = self.tempds(method)
        out_collection = fiona.collection(
            tempds, "w", "ESRI Shapefile", out_schema)

        log.debug("determine spatial relationship")
        for fid, newpoly in enumerate(newpolys):
            cent = newpoly.representative_point()

            # Test intersection with original polys
            layer1_hit = False
            layer2_hit = False
            prop1 = None
            prop2 = None
            candidates1 = list(idx1.intersection(cent.bounds))
            candidates2 = list(idx2.intersection(cent.bounds))

            for cand in candidates1:
                if cent.intersects(features1[cand][0]):
                    layer1_hit = True
                    prop1 = features1[cand][1]  # properties
                    break

            for cand in candidates2:
                if cent.intersects(features2[cand][0]):
                    layer2_hit = True
                    prop2 = features2[cand][1]  # properties
                    break

            # determine whether to output based on type of overlay
            hit = False
            if method == "intersection" and (layer1_hit and layer2_hit):
                hit = True
            elif method == "union" and (layer1_hit or layer2_hit):
                hit = True
            elif method == "identity" and ((layer1_hit and layer2_hit) or
                           (layer1_hit and not layer2_hit)):
                hit = True

            if not hit:
                continue

            log.debug("write newpoly with attrs gathered from prop1 & prop2")
            if not prop1:
                prop1 = dict.fromkeys(
                    self.collection().schema['properties'].keys(), None)

            if not prop2:
                prop2 = dict.fromkeys(layer2_schema_map.keys(), None)

            newprop = prop1
            for key, value in prop2.items():
                newkey = layer2_schema_map[key]
                newprop[newkey] = value

            out_feature = {
                'id': fid,
                'properties': newprop,
                'geometry': mapping(newpoly)}

            out_collection.write(out_feature)

        out_collection.close()
        return Layer(tempds)
コード例 #41
0
from shapely.geometry import LineString, MultiLineString, Polygon, Point
from shapely.ops import polygonize, polygonize_full, transform, linemerge

shapely_line_strings = [LineString(x) for x in snap_lines]

# add bounding lines needed by polygonize (it's easy to do per pixel. TODO refactor to create only necessary lines)
#for i in xrange(sz):
#  pair_lines.append(((0,i),(0,i+1)))
#  pair_lines.append(((sz,i),(sz,i+1)))
#  pair_lines.append(((i,0),(i+1,0)))
#  pair_lines.append(((i,sz),(i+1,sz)))

#ps = list(polygonize(shapely_line_strings))

# simple polygonize doesn't work. it is a trick (see http://gis.stackexchange.com/questions/58245/generate-polygons-from-a-set-of-intersecting-lines)
M = MultiLineString(shapely_line_strings)
MB = M.buffer(0.001)
P = Polygon([(0, 0), (0, sz), (sz, sz), (sz, 0)])
pso = P.difference(MB)

# round vertices coords
ps = []
for p in pso:
  pb = p.buffer(0.001)
  pbt = transform(lambda x, y, z=None: (int(round(x)), int(round(y))), pb)
  ps.append(pbt)

# associate LineString_s with Polygon_s
pt_polygon_index = dict();

for p in ps:
コード例 #42
0
ファイル: map_api.py プロジェクト: SAUSy-Lab/nb-gtfs
class match(object):
	"""This object is responsible for coming up with a more spatially accurate 
	version of the trip. We do this by first trying to map match the GPS 
	track to the street/rail network using OSRM. If that doesn't work well 
	for any reason, we try altering some parameters to improve the match. 
	If it's still not great, we can see if there is a default route_geometry 
	provided. Ultimately, we judge whether the match is sufficent to proceed.

	If we do use this match, this object also provides methods for associating 
	points (vehicles, stops) with points along the route gemetry; these will 
	be used for time interpolation inside the trip object."""

	def __init__(self,trip_object):
		# initialize some variables
		self.trip = trip_object					# trip object that this is a match for
		self.geometry = MultiLineString()	# MultiLineString shapely geom
		self.OSRM_response = {}					# python-parsed OSRM response object
		self.confidence = 0						# 	
		# error radius to use for map matching, same for all points
		self.error_radius = conf['error_radius']
		self.default_route_used = False;
		# fire off a query to OSRM with the default parameters
		self.query_OSRM()
		if not self.OSRM_match_is_sufficient:
			# try again with a larger error radius
			self.error_radius *= 1.5
			self.query_OSRM()
		# still no good? 
		if not self.OSRM_match_is_sufficient:
			# Try a default geometry
			if self.get_default_route():
				self.locate_vehicles_on_default_route()
			else: 
				return # bad match, no default
		else: # have a workable OSRM match geometry
			self.parse_OSRM_geometry()
			self.locate_vehicles_on_OSRM_route()
		if len(self.trip.vehicles) > 2:
			self.locate_stops_on_route()
		# report on what happened
		self.print_outcome()


	@property
	def OSRM_match_is_sufficient(self):
		"""Is this match good enough actually to be used?"""
		return self.confidence >= conf['min_OSRM_match_quality']

	@property
	def is_useable(self):
		"""Do we have everything we need to proceed with the match?"""
		if not (self.OSRM_match_is_sufficient or self.default_route_used):
			return False
		if not len(self.trip.vehicles) > 3:
			return False
		if self.trip.vehicles[0].measure == self.trip.vehicles[-1].measure:
			return False
		if not len(self.trip.timepoints) > 1:
			return False
		# and only if we make it past all those conditions:
		return True
			

	def query_OSRM(self):
		"""Construct the request and send it to OSRM, retrying if necessary."""
		# structure it as API requires, rounding coords to 6 decimals
		coords = ';'.join( [ 
			format(v.lon,'.7g')+','+format(v.lat,'.7g') for v in self.trip.vehicles 
		] )
		radii = ';'.join( [ str(self.error_radius) ] * len(self.trip.vehicles) )
		# construct and send the request
		options = {
			'radiuses':radii,
			'steps':'false',
			'geometries':'geojson',
			'annotations':'false',
			'overview':'full',
			'gaps':'ignore', # don't split based on time gaps - shouldn't be any
			'tidy':'true',
			'generate_hints':'false'
		}
		# open a connection, configured to retry in case of errors
		with requests.Session() as session:
			retries = Retry( total=5, backoff_factor=1 )
			session.mount( 'http://', HTTPAdapter(max_retries=retries) )
			# make the request
			try:
				raw_response = session.get(
					conf['OSRMserver']['url']+'/match/v1/transit/'+coords,
					params=options,
					timeout=conf['OSRMserver']['timeout']
					)
			except:
				return db.ignore_trip(self.trip.trip_id,'connection issue')
		# parse the result to a python object
		self.OSRM_response = json.loads(raw_response.text)
		# how confident should we be in this response?
		if self.OSRM_response['code'] != 'Ok':
			self.confidence = 0
			return 
		else:
			# Get an average confidence value from the match result.
			confidence_values = [ m['confidence'] for m in self.OSRM_response['matchings'] ]
			self.confidence = mean( confidence_values )


	def parse_OSRM_geometry(self):
		"""Parse the OSRM match geometry into a more useable format.
			Specifically a simplified and projected MultiLineString."""
		# get a list of lists of lat-lon coords which need to be reprojected
		lines = [asShape(matching['geometry']) for matching in self.OSRM_response['matchings']]
		multilines = MultiLineString(lines)
		# reproject to local 
		local_multilines = reproject( conf['projection'], multilines )
		# simplify slightly for speed (2 meter simplification)
		simple_local_multilines = local_multilines.simplify(2)
		# if the multi actually just had one line, this simplifies to a 
		# linestring, which can cause problems down the road
		if simple_local_multilines.geom_type == 'LineString':
			simple_local_multilines = MultiLineString([simple_local_multilines])
		self.geometry = simple_local_multilines


	def get_default_route(self):
		"""Check if a default route geometry is available; if so, we'll need to 
			parse things into the same format, just as though this had come from 
			OSRM."""
		# get the default if there is one
		route_geom = db.get_route_geom( self.trip.direction_id, self.trip.last_seen )
		if route_geom: # default available
			self.default_route_used = True
			self.confidence = 1
			self.geometry = MultiLineString([route_geom])
			return True
		else: # no default
			return False


	def print_outcome(self):
		"""Print the outcome of this match to stdout."""
		if self.default_route_used and self.confidence == 1:
			print( '\tdefault route used for direction',self.trip.direction_id )
		elif self.default_route_used and self.confidence == 0:
			print( '\tdefault route not found for',self.trip.direction_id )
		elif not self.default_route_used and self.confidence > conf['min_OSRM_match_quality']:
			print( '\tOSRM match found with',round(self.confidence,3),'confidence' )
		else:
			print( '\tmatching failed for trip',self.trip.trip_id )


	# Below are functions associated with finding the measure of points along
	# the route geometry, either as given by OSRM or provided as the default.
	# These are called from inside the trip if the match is useable.


	def locate_vehicles_on_OSRM_route(self):
		"""Find the measure of vehicles along the OSRM-supplied route. This is 
		easy because OSRM provides the distance of an input coordinate along the 
		match geometry."""
		assert not self.default_route_used
		# these are the matched points of the input cordinates
		# null (None) entries indicate an omitted (outlier) point
		# true where not none
		drop_list = [ point is None for point in self.OSRM_response['tracepoints'] ]
		# drop vehicles that did not contribute to the match,
		# backwards to maintain order
		for i in reversed( range( 0, len(drop_list) ) ):
			if drop_list[i]: self.trip.ignore_vehicle( i )
		# get cumulative distances of each vehicle along the match geom
		# This is based on the leg distances provided by OSRM. Each leg is just 
		# the trip between matched points. Each match has one more vehicle record 
		# associated with it than legs
		cummulative_distance = 0
		v_i = 0
		for matching in self.OSRM_response['matchings']:
			# the first point is at 0 per match
			self.trip.vehicles[v_i].set_measure( cummulative_distance )
			v_i += 1
			for leg in matching['legs']:
				cummulative_distance += leg['distance']
				self.trip.vehicles[v_i].set_measure( cummulative_distance )
				v_i += 1
		# Because the line has been simplified, the distances will be 
		# slightly off and need correcting 
		adjust_factor = self.geometry.length / self.trip.vehicles[-1].measure
		for v in self.trip.vehicles:
			v.measure = v.measure * adjust_factor


	def locate_vehicles_on_default_route(self):
		"""Find the measure of vehicles along the default route. First discard 
		observations too far from the route geometry. Next, find the measure of 
		the remaining vehicles in the order they were observed. If the vehicles 
		progress monotonically down the line then all is good. Otherwise, we 
		start dropping observations that are most severely out of order until we 
		are left with an ordered list moving along the route in the correct 
		direction. Wrong direction travel will generally result in a minimal
		ordered set: 1 remaining observation."""
		assert self.default_route_used
		# match stops within a distance of the route geometry
		vehicles_to_ignore = []
		for vehicle in self.trip.vehicles:
			# if the vehicle is close enough
			distance_from_route = self.geometry.distance( vehicle.geom )
			if distance_from_route <= conf['stop_dist']:
				m = self.geometry.project(vehicle.geom)
				vehicle.set_measure(m)
			else:
				vehicles_to_ignore.append(vehicle)
		for vehicle in vehicles_to_ignore:
			self.trip.ignore_vehicle( vehicle )
		# while the list is not fully sorted
		while self.trip.vehicles != sorted(self.trip.vehicles,key=lambda v: v.measure):
			correct_order = sorted(self.trip.vehicles,key=lambda v: v.measure)
			current_order = self.trip.vehicles
			transpositions = {}
			# compare all vehicles in both lists
			for i,v1 in enumerate(correct_order):
				for j,v2 in enumerate(current_order):
					if v1 == v2:
						if abs(i-j) > 0: # not in the same position
							# add these vehicles to the list with their distances as keys
							if abs(i-j) not in transpositions: transpositions[abs(i-j)] = [v1]
							else: transpositions[abs(i-j)].append(v1)
						else: # are in the same position
							continue
			max_dist = max(transpositions.keys())
			# ignore vehicles associated with the max of the transposition distances
			for vehicle in transpositions[max_dist]:
				self.trip.ignore_vehicle(vehicle)
		# now we either have a sorted list or an essentially empty list if the 
		# match happened to be bad


	def locate_stops_on_route(self):
		"""Find the measure of stops along the route geometry for any arbitrary 
			route. Stops must be within a given distance of the path, but can 
			repeat if the route passes a stop two or more times. To check for this,
			the geometry is sliced up into segments and we check just a portion 
			of the route at a time."""
		assert len(self.trip.stops) > 0
		assert self.geometry.length > 0
		# list of timepoints
		potential_timepoints = []
		# copy the geometry so we can slice it up it
		path = copy(self.geometry)
		traversed = 0
		# while there is more than 750m of path remaining
		while path.length > 0:
			subpath, path = cut(path,750)
			# check for nearby stops
			for stop in self.trip.stops:
				# if the stop is close enough
				stop_dist = subpath.distance(stop.geom)
				if stop_dist <= conf['stop_dist']:
					# measure how far it is along the trip
					m = traversed + subpath.project(stop.geom)
					# add it to the list of measures
					potential_timepoints.append( TimePoint(stop,m,stop_dist) )
			# note what we have already traversed
			traversed += 750
		# Now some of these will be duplicates that are close to the cutpoint
		# and thus are added twice with similar measures
		# such points need to be removed
		final_timepoints = []
		for pt in potential_timepoints:
			skip_this_timepoint = False
			for ft in final_timepoints:
				# if same stop and very close
				if pt.stop_id == ft.stop_id and abs(pt.measure-ft.measure) < 2*conf['stop_dist']:
					#choose the closer of the two to use
					if ft.dist <= pt.dist:
						skip_this_timepoint = True
						break 
					else:
						ft = pt
						skip_this_timepoint = True
						break
			if not skip_this_timepoint:
				# we didn't have anything like that in the final set yet
				final_timepoints.append( pt )
		# add terminal stops if they are anywhere near the GPS data
		# but not used yet
		if not self.default_route_used:
			# for first and last stops
			for terminal_stop in [self.trip.stops[0],self.trip.stops[-1]]:
				if not terminal_stop.id in [ t.stop.id for t in potential_timepoints ]:
					# if the terminal stop is less than 500m away from the route
					dist = self.geometry.distance(terminal_stop.geom)
					if dist < 500:
						m = self.geometry.project(terminal_stop.geom)
						final_timepoints.append( TimePoint(
							terminal_stop,
							m-dist if m < self.geometry.length/2 else m+dist,
							dist
						) )
		# for default geometries on the other hand, remove stops that are nowhere
		# near the actual GPS data
		else:
			final_timepoints = [
				t for t in final_timepoints if 
				t.measure > self.trip.vehicles[0].measure - 500 and 
				t.measure < self.trip.vehicles[-1].measure + 500
			]
		# sort by measure ascending
		final_timepoints = sorted(final_timepoints,key=lambda timepoint: timepoint.measure)
		self.trip.timepoints = final_timepoints
コード例 #43
0
ファイル: test3.py プロジェクト: perrygeo/geofu
                poly = poly.buffer(0)
            rings2.append(poly.exterior)
            rings2.extend(poly.interiors)
    else:
        if not geom.is_valid:
            print "***** Geometry from layer2 is not valid, fixing by buffer 0"
            geom = geom.buffer(0)
        rings2.append(geom.exterior)
        rings2.extend(geom.interiors)

#print "\t", len([x for x in rings if not x.is_valid]), "invalid rings"
#rings = [x for x in rings if x.is_valid]

from shapely.geometry import MultiLineString

mls1 = MultiLineString(rings1)
mls2 = MultiLineString(rings2)

try:
    print "calculating union (try the fast unary_union)"
    mm = unary_union([mls1, mls2])
except:
    print "FAILED"
    print "calculating union again (using the slow a.union(b))"
    mm = mls1.union(mls2)

print "polygonize rings"
newpolys = polygonize(mm)

print "determine spatial relationship and plot new polys"
for newpoly in newpolys:
コード例 #44
0
ファイル: overlay.py プロジェクト: Casyfill/geopandas
def overlay(df1, df2, how, use_sindex=True):
    """Perform spatial overlay between two polygons.

    Currently only supports data GeoDataFrames with polygons.
    Implements several methods that are all effectively subsets of
    the union.

    Parameters
    ----------
    df1 : GeoDataFrame with MultiPolygon or Polygon geometry column
    df2 : GeoDataFrame with MultiPolygon or Polygon geometry column
    how : string
        Method of spatial overlay: 'intersection', 'union',
        'identity', 'symmetric_difference' or 'difference'.
    use_sindex : boolean, default True
        Use the spatial index to speed up operation if available.

    Returns
    -------
    df : GeoDataFrame
        GeoDataFrame with new set of polygons and attributes
        resulting from the overlay

    """
    allowed_hows = [
        'intersection',
        'union',
        'identity',
        'symmetric_difference',
        'difference',  # aka erase
    ]

    if how not in allowed_hows:
        raise ValueError("`how` was \"%s\" but is expected to be in %s" % \
            (how, allowed_hows))

    if isinstance(df1, GeoSeries) or isinstance(df2, GeoSeries):
        raise NotImplementedError("overlay currently only implemented for GeoDataFrames")

    # Collect the interior and exterior rings
    rings1 = _extract_rings(df1)
    rings2 = _extract_rings(df2)
    mls1 = MultiLineString(rings1)
    mls2 = MultiLineString(rings2)

    # Union and polygonize
    try:
        # calculating union (try the fast unary_union)
        mm = unary_union([mls1, mls2])
    except:
        # unary_union FAILED
        # see https://github.com/Toblerity/Shapely/issues/47#issuecomment-18506767
        # calculating union again (using the slow a.union(b))
        mm = mls1.union(mls2)
    newpolys = polygonize(mm)

    # determine spatial relationship
    collection = []
    for fid, newpoly in enumerate(newpolys):
        cent = newpoly.representative_point()

        # Test intersection with original polys
        # FIXME there should be a higher-level abstraction to search by bounds
        # and fall back in the case of no index?
        if use_sindex and df1.sindex is not None:
            candidates1 = [x.object for x in
                           df1.sindex.intersection(newpoly.bounds, objects=True)]
        else:
            candidates1 = [i for i, x in df1.iterrows()]

        if use_sindex and df2.sindex is not None:
            candidates2 = [x.object for x in
                           df2.sindex.intersection(newpoly.bounds, objects=True)]
        else:
            candidates2 = [i for i, x in df2.iterrows()]

        df1_hit = False
        df2_hit = False
        prop1 = None
        prop2 = None
        for cand_id in candidates1:
            cand = df1.ix[cand_id]
            if cent.intersects(cand[df1.geometry.name]):
                df1_hit = True
                prop1 = cand
                break  # Take the first hit
        for cand_id in candidates2:
            cand = df2.ix[cand_id]
            if cent.intersects(cand[df2.geometry.name]):
                df2_hit = True
                prop2 = cand
                break  # Take the first hit

        # determine spatial relationship based on type of overlay
        hit = False
        if how == "intersection" and (df1_hit and df2_hit):
            hit = True
        elif how == "union" and (df1_hit or df2_hit):
            hit = True
        elif how == "identity" and df1_hit:
            hit = True
        elif how == "symmetric_difference" and not (df1_hit and df2_hit):
            hit = True
        elif how == "difference" and (df1_hit and not df2_hit):
            hit = True

        if not hit:
            continue

        # gather properties
        if prop1 is None:
            prop1 = pd.Series(dict.fromkeys(df1.columns, None))
        if prop2 is None:
            prop2 = pd.Series(dict.fromkeys(df2.columns, None))

        # Concat but don't retain the original geometries
        out_series = pd.concat([prop1.drop(df1._geometry_column_name),
                                prop2.drop(df2._geometry_column_name)])

        out_series.index = _uniquify(out_series.index)

        # Create a geoseries and add it to the collection
        out_series['geometry'] = newpoly
        collection.append(out_series)

    # Return geodataframe with new indicies
    return GeoDataFrame(collection, index=range(len(collection)))