Exemplo n.º 1
0
 def delaunay_triangulation(self):
     import voronoi
     from sets import Set
     vprovider = self.vlayer.dataProvider()
     allAttrs = vprovider.attributeIndexes()
     vprovider.select(allAttrs)
     fields = {
         0: QgsField("POINTA", QVariant.Double),
         1: QgsField("POINTB", QVariant.Double),
         2: QgsField("POINTC", QVariant.Double)
     }
     writer = QgsVectorFileWriter(self.myName, self.myEncoding, fields,
                                  QGis.WKBPolygon, vprovider.crs())
     inFeat = QgsFeature()
     c = voronoi.Context()
     pts = []
     ptDict = {}
     ptNdx = -1
     while vprovider.nextFeature(inFeat):
         geom = QgsGeometry(inFeat.geometry())
         point = geom.asPoint()
         x = point.x()
         y = point.y()
         pts.append((x, y))
         ptNdx += 1
         ptDict[ptNdx] = inFeat.id()
     if len(pts) < 3:
         return False
     uniqueSet = Set(item for item in pts)
     ids = [pts.index(item) for item in uniqueSet]
     sl = voronoi.SiteList([voronoi.Site(*i) for i in uniqueSet])
     c.triangulate = True
     voronoi.voronoi(sl, c)
     triangles = c.triangles
     feat = QgsFeature()
     nFeat = len(triangles)
     nElement = 0
     self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
     self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat))
     for triangle in triangles:
         indicies = list(triangle)
         indicies.append(indicies[0])
         polygon = []
         step = 0
         for index in indicies:
             vprovider.featureAtId(ptDict[ids[index]], inFeat, True,
                                   allAttrs)
             geom = QgsGeometry(inFeat.geometry())
             point = QgsPoint(geom.asPoint())
             polygon.append(point)
             if step <= 3: feat.addAttribute(step, QVariant(ids[index]))
             step += 1
         geometry = QgsGeometry().fromPolygon([polygon])
         feat.setGeometry(geometry)
         writer.addFeature(feat)
         nElement += 1
         self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement)
     del writer
     return True
Exemplo n.º 2
0
 def processAlgorithm(self, progress):
     vlayer = QGisLayers.getObjectFromUri(
         self.getParameterValue(Delaunay.INPUT))
     vprovider = vlayer.dataProvider()
     allAttrs = vprovider.attributeIndexes()
     vprovider.select(allAttrs)
     fields = {
         0: QgsField("POINTA", QVariant.Double),
         1: QgsField("POINTB", QVariant.Double),
         2: QgsField("POINTC", QVariant.Double)
     }
     writer = self.getOutputFromName(Delaunay.OUTPUT).getVectorWriter(
         fields, QGis.WKBPolygon, vprovider.crs())
     inFeat = QgsFeature()
     c = voronoi.Context()
     pts = []
     ptDict = {}
     ptNdx = -1
     while vprovider.nextFeature(inFeat):
         geom = QgsGeometry(inFeat.geometry())
         point = geom.asPoint()
         x = point.x()
         y = point.y()
         pts.append((x, y))
         ptNdx += 1
         ptDict[ptNdx] = inFeat.id()
     if len(pts) < 3:
         return False
     uniqueSet = Set(item for item in pts)
     ids = [pts.index(item) for item in uniqueSet]
     sl = voronoi.SiteList([voronoi.Site(*i) for i in uniqueSet])
     c.triangulate = True
     voronoi.voronoi(sl, c)
     triangles = c.triangles
     feat = QgsFeature()
     nFeat = len(triangles)
     nElement = 0
     for triangle in triangles:
         indicies = list(triangle)
         indicies.append(indicies[0])
         polygon = []
         step = 0
         for index in indicies:
             vprovider.featureAtId(ptDict[ids[index]], inFeat, True,
                                   allAttrs)
             geom = QgsGeometry(inFeat.geometry())
             point = QgsPoint(geom.asPoint())
             polygon.append(point)
             if step <= 3: feat.addAttribute(step, QVariant(ids[index]))
             step += 1
         geometry = QgsGeometry().fromPolygon([polygon])
         feat.setGeometry(geometry)
         writer.addFeature(feat)
         nElement += 1
         progress.setPercentage(nElement / nFeat * 100)
     del writer
Exemplo n.º 3
0
 def voronoi_polygons(self):
     vprovider = self.vlayer.dataProvider()
     writer = QgsVectorFileWriter(self.myName, self.myEncoding,
                                  vprovider.fields(), QGis.WKBPolygon,
                                  vprovider.crs())
     inFeat = QgsFeature()
     outFeat = QgsFeature()
     extent = self.vlayer.extent()
     extraX = extent.height() * (self.myParam / 100.00)
     extraY = extent.width() * (self.myParam / 100.00)
     height = extent.height()
     width = extent.width()
     c = voronoi.Context()
     pts = []
     ptDict = {}
     ptNdx = -1
     fit = vprovider.getFeatures()
     while fit.nextFeature(inFeat):
         geom = QgsGeometry(inFeat.geometry())
         point = geom.asPoint()
         x = point.x() - extent.xMinimum()
         y = point.y() - extent.yMinimum()
         pts.append((x, y))
         ptNdx += 1
         ptDict[ptNdx] = inFeat.id()
     self.vlayer = None
     if len(pts) < 3:
         return False
     uniqueSet = Set(item for item in pts)
     ids = [pts.index(item) for item in uniqueSet]
     sl = voronoi.SiteList([
         voronoi.Site(i[0], i[1], sitenum=j)
         for j, i in enumerate(uniqueSet)
     ])
     voronoi.voronoi(sl, c)
     inFeat = QgsFeature()
     nFeat = len(c.polygons)
     nElement = 0
     self.emit(SIGNAL("runStatus( PyQt_PyObject )"), 0)
     self.emit(SIGNAL("runRange( PyQt_PyObject )"), (0, nFeat))
     for site, edges in c.polygons.iteritems():
         vprovider.getFeatures(QgsFeatureRequest().setFilterFid(
             ptDict[ids[site]])).nextFeature(inFeat)
         lines = self.clip_voronoi(edges, c, width, height, extent, extraX,
                                   extraY)
         geom = QgsGeometry.fromMultiPoint(lines)
         geom = QgsGeometry(geom.convexHull())
         outFeat.setGeometry(geom)
         outFeat.setAttributes(inFeat.attributes())
         writer.addFeature(outFeat)
         nElement += 1
         self.emit(SIGNAL("runStatus( PyQt_PyObject )"), nElement)
     del writer
     return True
Exemplo n.º 4
0
 def processAlgorithm(self, progress):
     vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(VoronoiPolygons.INPUT))
     vprovider = vlayer.dataProvider()
     allAttrs = vprovider.attributeIndexes()
     vprovider.select( allAttrs )
     writer = self.getOutputFromName(VoronoiPolygons.OUTPUT).getVectorWriter(vprovider.fields(), QGis.WKBPolygon, vprovider.crs() )
     inFeat = QgsFeature()
     outFeat = QgsFeature()
     extent = vlayer.extent()
     height = extent.height()
     width = extent.width()
     c = voronoi.Context()
     pts = []
     ptDict = {}
     ptNdx = -1
     while vprovider.nextFeature(inFeat):
       geom = QgsGeometry(inFeat.geometry())
       point = geom.asPoint()
       x = point.x()-extent.xMinimum()
       y = point.y()-extent.yMinimum()
       pts.append((x, y))
       ptNdx +=1
       ptDict[ptNdx] = inFeat.id()
     #self.vlayer = None
     if len(pts) < 3:
       return False
     uniqueSet = Set(item for item in pts)
     ids = [pts.index(item) for item in uniqueSet]
     sl = voronoi.SiteList([voronoi.Site(i[0], i[1], sitenum=j) for j, i in enumerate(uniqueSet)])
     voronoi.voronoi(sl, c)
     inFeat = QgsFeature()
     nFeat = len(c.polygons)
     nElement = 0
     for site, edges in c.polygons.iteritems():
       vprovider.featureAtId(ptDict[ids[site]], inFeat, True,  allAttrs)
       lines = self.clip_voronoi(edges, c, width, height, extent, 0, 0)
       geom = QgsGeometry.fromMultiPoint(lines)
       geom = QgsGeometry(geom.convexHull())
       outFeat.setGeometry(geom)
       outFeat.setAttributeMap(inFeat.attributeMap())
       writer.addFeature(outFeat)
       nElement += 1
       progress.setPercentage(nElement/nFeat * 100)
     del writer
     return True
Exemplo n.º 5
0
def VoronoiLineEdges(PointsMap):
  Sitepts = []
  pts = {}

  #print CurrentDate, PointsMap[PointsMap.keys()[0]]
  for grid, stn in PointsMap.items():

    x=float(stn[0])
    y=float(stn[1])
    station=grid
    #station.extend( stn[3:])
    #print x,y,station

    pts[ (x,y) ]=station
  
  stncounts=len(pts.keys())
  #print stncounts, "points"
  
  site_points=[]
  for pt in pts.keys():
    Sitepts.append(voronoi.Site(pt[0],pt[1]))
    site_points.append( (pt[0],pt[1]) )
      

  #print "Calculating Voronoi Lattice",
  
  siteList = voronoi.SiteList(Sitepts)
  context  = voronoi.Context()
  voronoi.Edge.EDGE_NUM=0  
  voronoi.voronoi(siteList,context)

  vertices=context.vertices
  lines=context.lines
  edges=context.edges
  triangles=context.triangles
  has_edge=context.has_edge

  return vertices, lines, edges, has_edge
Exemplo n.º 6
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(self.getParameterValue(
            self.INPUT))

        buf = self.getParameterValue(self.BUFFER)

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            layer.pendingFields().toList(), QGis.WKBPolygon, layer.crs())

        inFeat = QgsFeature()
        outFeat = QgsFeature()
        extent = layer.extent()
        extraX = extent.height() * (buf / 100.0)
        extraY = extent.width() * (buf / 100.0)
        height = extent.height()
        width = extent.width()
        c = voronoi.Context()
        pts = []
        ptDict = {}
        ptNdx = -1

        features = vector.features(layer)
        for inFeat in features:
            geom = QgsGeometry(inFeat.geometry())
            point = geom.asPoint()
            x = point.x() - extent.xMinimum()
            y = point.y() - extent.yMinimum()
            pts.append((x, y))
            ptNdx += 1
            ptDict[ptNdx] = inFeat.id()

        if len(pts) < 3:
            raise GeoAlgorithmExecutionException(
                'Input file should contain at least 3 points. Choose \
                    another file and try again.')

        uniqueSet = Set(item for item in pts)
        ids = [pts.index(item) for item in uniqueSet]
        sl = voronoi.SiteList([
            voronoi.Site(i[0], i[1], sitenum=j)
            for (j, i) in enumerate(uniqueSet)
        ])
        voronoi.voronoi(sl, c)
        inFeat = QgsFeature()

        current = 0
        total = 100.0 / float(len(c.polygons))

        for (site, edges) in c.polygons.iteritems():
            request = QgsFeatureRequest().setFilterFid(ptDict[ids[site]])
            inFeat = layer.getFeatures(request).next()
            lines = self.clip_voronoi(edges, c, width, height, extent, extraX,
                                      extraY)

            geom = QgsGeometry.fromMultiPoint(lines)
            geom = QgsGeometry(geom.convexHull())
            outFeat.setGeometry(geom)
            outFeat.setAttributes(inFeat.attributes())
            writer.addFeature(outFeat)

            current += 1
            progress.setPercentage(int(current * total))

        del writer
Exemplo n.º 7
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(self.getParameterValue(
            self.INPUT))

        fields = [
            QgsField('POINTA', QVariant.Double, '', 24, 15),
            QgsField('POINTB', QVariant.Double, '', 24, 15),
            QgsField('POINTC', QVariant.Double, '', 24, 15)
        ]

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields, QGis.WKBPolygon, layer.crs())

        pts = []
        ptDict = {}
        ptNdx = -1
        c = voronoi.Context()
        features = vector.features(layer)
        for inFeat in features:
            geom = QgsGeometry(inFeat.geometry())
            point = geom.asPoint()
            x = point.x()
            y = point.y()
            pts.append((x, y))
            ptNdx += 1
            ptDict[ptNdx] = inFeat.id()

        if len(pts) < 3:
            raise GeoAlgorithmExecutionException(
                'Input file should contain at least 3 points. Choose \
                    another file and try again.')

        uniqueSet = Set(item for item in pts)
        ids = [pts.index(item) for item in uniqueSet]
        sl = voronoi.SiteList([voronoi.Site(*i) for i in uniqueSet])
        c.triangulate = True
        voronoi.voronoi(sl, c)
        triangles = c.triangles
        feat = QgsFeature()

        current = 0
        total = 100.0 / float(len(triangles))

        for triangle in triangles:
            indicies = list(triangle)
            indicies.append(indicies[0])
            polygon = []
            attrs = []
            step = 0
            for index in indicies:
                request = QgsFeatureRequest().setFilterFid(ptDict[ids[index]])
                inFeat = layer.getFeatures(request).next()
                geom = QgsGeometry(inFeat.geometry())
                point = QgsPoint(geom.asPoint())
                polygon.append(point)
                if step <= 3:
                    attrs.append(ids[index])
                step += 1
            feat.setAttributes(attrs)
            geometry = QgsGeometry().fromPolygon([polygon])
            feat.setGeometry(geometry)
            writer.addFeature(feat)
            current += 1
            progress.setPercentage(int(current * total))

        del writer
Exemplo n.º 8
0
    def effect(self):
        if not self.options.ids:
            inkex.errormsg(_("Please select an object"))
            exit()
        scale = self.unittouu('1px')            # convert to document units
        self.options.size *= scale
        self.options.border *= scale
        q = {'x':0,'y':0,'width':0,'height':0}  # query the bounding box of ids[0]
        for query in q.keys():
            p = Popen('inkscape --query-%s --query-id=%s "%s"' % (query, self.options.ids[0], self.args[-1]), shell=True, stdout=PIPE, stderr=PIPE)
            rc = p.wait()
            q[query] = scale*float(p.stdout.read())
        mat = simpletransform.composeParents(self.selected[self.options.ids[0]], [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
        defs = self.xpathSingle('/svg:svg//svg:defs')
        pattern = inkex.etree.SubElement(defs ,inkex.addNS('pattern','svg'))
        pattern.set('id', 'Voronoi' + str(random.randint(1, 9999)))
        pattern.set('width', str(q['width']))
        pattern.set('height', str(q['height']))
        pattern.set('patternTransform', 'translate(%s,%s)' % (q['x'] - mat[0][2], q['y'] - mat[1][2]))
        pattern.set('patternUnits', 'userSpaceOnUse')

        # generate random pattern of points
        c = voronoi.Context()
        pts = []
        b = float(self.options.border)          # width of border
        for i in range(int(q['width']*q['height']/self.options.size/self.options.size)):
            x = random.random()*q['width']
            y = random.random()*q['height']
            if b > 0:                           # duplicate border area
                pts.append(voronoi.Site(x, y))
                if x < b:
                    pts.append(voronoi.Site(x + q['width'], y))
                    if y < b:
                        pts.append(voronoi.Site(x + q['width'], y + q['height']))
                    if y > q['height'] - b:
                        pts.append(voronoi.Site(x + q['width'], y - q['height']))
                if x > q['width'] - b:
                    pts.append(voronoi.Site(x - q['width'], y))
                    if y < b:
                        pts.append(voronoi.Site(x - q['width'], y + q['height']))
                    if y > q['height'] - b:
                        pts.append(voronoi.Site(x - q['width'], y - q['height']))
                if y < b:
                    pts.append(voronoi.Site(x, y + q['height']))
                if y > q['height'] - b:
                    pts.append(voronoi.Site(x, y - q['height']))
            elif x > -b and y > -b and x < q['width'] + b and y < q['height'] + b:
                pts.append(voronoi.Site(x, y))  # leave border area blank
            # dot = inkex.etree.SubElement(pattern, inkex.addNS('rect','svg'))
            # dot.set('x', str(x-1))
            # dot.set('y', str(y-1))
            # dot.set('width', '2')
            # dot.set('height', '2')
        if len(pts) < 3:
            inkex.errormsg("Please choose a larger object, or smaller cell size")
            exit()

        # plot Voronoi diagram
        sl = voronoi.SiteList(pts)
        voronoi.voronoi(sl, c)
        path = ""
        for edge in c.edges:
            if edge[1] >= 0 and edge[2] >= 0:       # two vertices
                [x1, y1, x2, y2] = clip_line(c.vertices[edge[1]][0], c.vertices[edge[1]][1], c.vertices[edge[2]][0], c.vertices[edge[2]][1], q['width'], q['height'])
            elif edge[1] >= 0:                      # only one vertex
                if c.lines[edge[0]][1] == 0:        # vertical line
                    xtemp = c.lines[edge[0]][2]/c.lines[edge[0]][0]
                    if c.vertices[edge[1]][1] > q['height']/2:
                        ytemp = q['height']
                    else:
                        ytemp = 0
                else:
                    xtemp = q['width']
                    ytemp = (c.lines[edge[0]][2] - q['width']*c.lines[edge[0]][0])/c.lines[edge[0]][1]
                [x1, y1, x2, y2] = clip_line(c.vertices[edge[1]][0], c.vertices[edge[1]][1], xtemp, ytemp, q['width'], q['height'])
            elif edge[2] >= 0:                      # only one vertex
                if c.lines[edge[0]][1] == 0:        # vertical line
                    xtemp = c.lines[edge[0]][2]/c.lines[edge[0]][0]
                    if c.vertices[edge[2]][1] > q['height']/2:
                        ytemp = q['height']
                    else:
                        ytemp = 0
                else:
                    xtemp = 0
                    ytemp = c.lines[edge[0]][2]/c.lines[edge[0]][1]
                [x1, y1, x2, y2] = clip_line(xtemp, ytemp, c.vertices[edge[2]][0], c.vertices[edge[2]][1], q['width'], q['height'])
            if x1 or x2 or y1 or y2:
                path += 'M %.3f,%.3f %.3f,%.3f ' % (x1, y1, x2, y2)

        patternstyle = {'stroke': '#000000', 'stroke-width': str(scale)}
        attribs = {'d': path, 'style': simplestyle.formatStyle(patternstyle)}
        inkex.etree.SubElement(pattern, inkex.addNS('path', 'svg'), attribs)

        # link selected object to pattern
        obj = self.selected[self.options.ids[0]]
        style = {}
        if obj.attrib.has_key('style'):
            style = simplestyle.parseStyle(obj.attrib['style'])
        style['fill'] = 'url(#%s)' % pattern.get('id')
        obj.attrib['style'] = simplestyle.formatStyle(style)
        if obj.tag == inkex.addNS('g', 'svg'):
            for node in obj:
                style = {}
                if node.attrib.has_key('style'):
                    style = simplestyle.parseStyle(node.attrib['style'])
                style['fill'] = 'url(#%s)' % pattern.get('id')
                node.attrib['style'] = simplestyle.formatStyle(style)
    def effect(self):
        if not self.options.ids:
            inkex.errormsg(_("Please select an object"))
            exit()
        scale = self.unittouu('1px')  # convert to document units
        self.options.size *= scale
        self.options.border *= scale
        q = {
            'x': 0,
            'y': 0,
            'width': 0,
            'height': 0
        }  # query the bounding box of ids[0]

        for query in q.keys():
            p = Popen('inkscape --query-%s --query-id=%s "%s"' %
                      (query, self.options.ids[0], self.args[-1]),
                      shell=True,
                      stdout=PIPE,
                      stderr=PIPE)
            rc = p.wait()
            q[query] = scale * float(p.stdout.read())

        # generate random pattern of points
        node = self.selected.values()[0]
        path_string = node.attrib[u'd']
        svg_path = simplepath.parsePath(path_string)

        pts = self.generatePoints(svg_path, self.options.size)
        self.display_pts(pts)

        c = voronoi.Context()
        pts_to_trig = []
        for point in pts:
            pts_to_trig.append(voronoi.Site(point.loc[0], point.loc[1]))

        # triangulate with library
        sl = voronoi.SiteList(pts_to_trig)
        c.triangulate = True
        voronoi.voronoi(sl, c)

        edge_to_triangle = {}
        triangle_timestamps = [0] * len(c.triangles)
        triangle_used = [False] * len(c.triangles)
        quads = []

        def getTriangularMidPoint(pt1, pt2, pt3):
            mid_2_3 = pt2.loc + 0.5 * (pt3.loc - pt2.loc)
            mid_1_3 = pt1.loc + 0.5 * (pt3.loc - pt1.loc)
            return curve_utils.intersect_line_line([pt1.loc, mid_2_3],
                                                   [pt2.loc, mid_1_3])[0]

        def rejectOutofRangeTringl():
            for trngl_indx in range(len(c.triangles)):
                triangle = c.triangles[trngl_indx]
                if pts[triangle[0]].type != 3 and pts[
                        triangle[1]].type != 3 and pts[triangle[2]].type != 3:
                    triangle_midpt = getTriangularMidPoint(
                        pts[triangle[0]], pts[triangle[1]], pts[triangle[2]])
                    if not pointInPath(self.paths, triangle_midpt):
                        triangle_used[trngl_indx] = True

        rejectOutofRangeTringl()

        for trngl_indx in range(len(c.triangles)):
            triangle = c.triangles[trngl_indx]
            # compute timestamp for each triangle
            verts = [pts[triangle[i]] for i in range(3)]
            min_tstmp = min([vert.timestamp for vert in verts])
            triangle_timestamps[trngl_indx] = min_tstmp
            # build edge_to_triangle
            for j in range(0, 3):
                id1 = triangle[j]
                id2 = triangle[(j + 1) % 3]
                if id1 < id2:
                    edge = (id1, id2)
                else:
                    edge = (id2, id1)
                if edge in edge_to_triangle:
                    edge_to_triangle[edge].append(trngl_indx)
                else:
                    edge_to_triangle[edge] = [trngl_indx]

        def getThirdInkex(triangle, edge):
            for id in triangle:
                if id not in edge:
                    return id

        def getEdgeLen(pt1, pt2):
            return np.linalg.norm(pt1.loc - pt2.loc)

        def getAngle(pt1, pt2, pt3):
            vec1 = pt1.loc - pt2.loc
            vec2 = pt3.loc - pt2.loc
            angle = np.dot(
                vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
            return math.acos(angle)

        def matchLongestEdge(matchTimestamp):
            # process triangles
            for edge in edge_to_triangle:
                if len(edge_to_triangle[edge]) == 2:
                    tringl1, tringl2 = edge_to_triangle[edge]
                    # skip if either triangle used
                    if triangle_used[tringl1] or triangle_used[tringl2]:
                        continue
                    if matchTimestamp and triangle_timestamps[
                            tringl1] != triangle_timestamps[tringl2]:
                        continue

                    # get third index of triangle
                    third_id1 = getThirdInkex(c.triangles[tringl1], edge)
                    third_id2 = getThirdInkex(c.triangles[tringl2], edge)
                    # get edge length
                    edge_len = getEdgeLen(pts[edge[0]], pts[edge[1]])
                    # get other edges length
                    trigl1_edge_len = [
                        getEdgeLen(pts[edge[0]], pts[third_id1]),
                        getEdgeLen(pts[edge[1]], pts[third_id1])
                    ]
                    trigl2_edge_len = [
                        getEdgeLen(pts[edge[0]], pts[third_id2]),
                        getEdgeLen(pts[edge[1]], pts[third_id2])
                    ]
                    # check if the connecting edge is longest edge of both triangles
                    if all(edge_len >= el for el in trigl1_edge_len) and all(
                            edge_len >= el for el in trigl2_edge_len):
                        # if yes, create quadrilateral
                        quads.append([edge[0], third_id1, edge[1], third_id2])
                        triangle_used[tringl1] = True
                        triangle_used[tringl2] = True

        def createNiceQuads(matchTimestamp):
            # process triangles
            for edge in edge_to_triangle:
                if len(edge_to_triangle[edge]) == 2:
                    tringl1, tringl2 = edge_to_triangle[edge]
                    # skip if either triangle used
                    if triangle_used[tringl1] or triangle_used[tringl2]:
                        continue
                    if matchTimestamp and triangle_timestamps[
                            tringl1] != triangle_timestamps[tringl2]:
                        continue

                    # get third index of triangle
                    third_id1 = getThirdInkex(c.triangles[tringl1], edge)
                    third_id2 = getThirdInkex(c.triangles[tringl2], edge)
                    # get edge length
                    quad_lens = []
                    edge_len = getEdgeLen(pts[edge[0]], pts[edge[1]])
                    # get other edges length
                    quad_lens.extend([
                        getEdgeLen(pts[edge[0]], pts[third_id1]),
                        getEdgeLen(pts[edge[1]], pts[third_id1])
                    ])
                    quad_lens.extend([
                        getEdgeLen(pts[edge[0]], pts[third_id2]),
                        getEdgeLen(pts[edge[1]], pts[third_id2])
                    ])
                    avg_quad_len = sum(quad_lens) / len(quad_lens)
                    len_diff = 0
                    for quad_len in quad_lens:
                        len_diff += abs(quad_len - avg_quad_len) / avg_quad_len

                    angles = []
                    angles.append(
                        getAngle(pts[edge[0]], pts[third_id1], pts[edge[1]]))
                    angles.append(
                        getAngle(pts[third_id1], pts[edge[1]], pts[third_id2]))
                    angles.append(
                        getAngle(pts[edge[1]], pts[third_id2], pts[edge[0]]))
                    angles.append(
                        getAngle(pts[third_id2], pts[edge[0]], pts[third_id1]))

                    angle_diff = 0
                    for angle in angles:
                        angle_diff += abs(angle - 3.14159 / 2.0) / (3.14159 /
                                                                    2)

                    # check if the connecting edge is longest edge of both triangles
                    if len_diff + angle_diff <= threshold:
                        # if yes, create quadrilateral
                        quads.append([edge[0], third_id1, edge[1], third_id2])
                        triangle_used[tringl1] = True
                        triangle_used[tringl2] = True

        matchLongestEdge(True)
        matchLongestEdge(False)
        createNiceQuads(True)
        createNiceQuads(False)

        self.display_triangles(pts, triangle_used, c.triangles)
        self.display_quads(pts, quads)
Exemplo n.º 10
0
def VoronoiPolygons(PointsMap, BoundingBox="W", PlotMap=False):
    global PlotIt
    global WorldRange
    global WorldRanges

    if type(BoundingBox) == type([]):
        if len(BoundingBox) == 4:
            WorldRange = BoundingBox
        else:
            return "Error in Bounding Box"
    else:
        WorldRange = WorldRanges[BoundingBox]

    PlotIt = PlotMap

    currenttime = time.time()
    Sitepts = []
    pts = {}

    #print CurrentDate, PointsMap[PointsMap.keys()[0]]
    for grid, stn in PointsMap.items():

        x = float(stn[0])
        y = float(stn[1])
        station = grid
        #station.extend( stn[3:])
        #print x,y,station

        pts[(x, y)] = station

    stncounts = len(pts.keys())
    #print stncounts, "points"

    site_points = []
    for pt in pts.keys():
        Sitepts.append(voronoi.Site(pt[0], pt[1]))
        site_points.append((pt[0], pt[1]))

    #print "Calculating Voronoi Lattice",

    siteList = voronoi.SiteList(Sitepts)
    context = voronoi.Context()
    voronoi.Edge.EDGE_NUM = 0
    voronoi.voronoi(siteList, context)

    vertices = context.vertices
    lines = context.lines
    edges = context.edges

    #print edges

    #For Faster Access
    edge_dic = {}
    for edge in edges:
        edge_dic[edge[0]] = edge[1:]

    triangles = context.triangles
    has_edge = context.has_edge

    voronoi_lattice = {}

    m_range = {}
    m_range["max_x"] = -9999999999
    m_range["max_y"] = -9999999999
    m_range["min_x"] = 9999999999
    m_range["min_y"] = 9999999999

    #Get the range!!
    for pnt in site_points:
        m_range = update_maxmin(m_range, pnt[0], pnt[1])

    #print "Getting the Polygons"

    prev_percent = 0
    for station, ls in has_edge.items():

        voronoi_lattice[station] = {}
        voronoi_lattice[station]["coordinate"] = site_points[station]
        voronoi_lattice[station]["info"] = pts[site_points[station]]

        polygon = []

        prev_extreme = []
        Verbose = True
        if Verbose:
            current_percent = int(station / float(stncounts) * 100)
            if current_percent != prev_percent:
                #print station,"/", stncounts, current_percent, "% Done"
                timeelapse = time.time() - currenttime
                #print station, timeelapse
                currenttime = time.time()

            prev_percent = current_percent

        #For every lines that the station owns
        for l in ls:
            e = edge_dic[l]

            v1 = vertices[e[0]]
            v2 = vertices[e[1]]

            if e[0] < 0 and checkInRange(WorldRange, v2[0], v2[1]) == False:
                continue
            if e[1] < 0 and checkInRange(WorldRange, v1[0], v1[1]) == False:
                continue

            if e[0] > -1 and e[1] > -1 and checkInRange(
                    WorldRange, v1[0], v1[1]) == False and checkInRange(
                        WorldRange, v2[0], v2[1]) == False:
                continue

            if e[0] < 0 or checkInRange(WorldRange, v1[0], v1[1]) == False:
                v1 = getExtreme(lines[l], v2, LR=0)

                if len(prev_extreme) == 0:
                    prev_extreme = v1
                else:
                    extreme_points = linkExtremes(prev_extreme, v1, m_range)
                    for extreme_pair in extreme_points:
                        polygon.append(extreme_pair)

            if e[1] < 0 or checkInRange(WorldRange, v2[0], v2[1]) == False:
                v2 = getExtreme(lines[l], v1, LR=1)

                if len(prev_extreme) == 0:
                    prev_extreme = v2
                else:
                    extreme_points = linkExtremes(prev_extreme, v2, m_range)
                    for extreme_pair in extreme_points:
                        polygon.append(extreme_pair)

            if v1 != v2:
                polygon.append((v1, v2))

        if len(polygon) == 0:
            sys.stderr.write(
                "\nThis station does not have meaningful polygon:")
            sys.stderr.write(
                str(pts[site_points[station]]) + " at " +
                str(site_points[station]) + "\n")
            for l in ls:
                e = edge_dic[l]

                v1 = vertices[e[0]]
                v2 = vertices[e[1]]

                sys.stderr.write(str(e[0]) + "," + str(e[1]) + "\n")
                sys.stderr.write(str(v1) + "," + str(v2) + "\n")

            voronoi_lattice.pop(station)
            continue

        #print polygon
        try:
            result = list(polygonize(polygon))
        except ValueError:
            #print "Wrong:", polygon

            #Delete invisible short lines
            point_to_replace = []
            for line in polygon:
                d = math.hypot(line[0][0] - line[1][0],
                               line[0][1] - line[1][1])
                if d < 1:
                    polygon.remove(line)
                    point_to_replace = line
            i = 0
            New_Lines = []
            for line in polygon:
                New_Lines.append(list(line))
                j = 0
                for point in line:
                    if point == point_to_replace[0]:
                        #print line, point_to_replace
                        New_Lines[i][j] = point_to_replace[1]
                    j += 1
                i += 1

            polygon = tuple(New_Lines)

            #I could not figure out why sometimes it fails to draw a polygon.
            try:
                result = list(polygonize(polygon))
            except:
                voronoi_lattice.pop(station)
                continue

        finalpoly = result[0]
        #print list(finalpoly.exterior.coords)
        #voronoi_lattice[station]["polygon"]=list(finalpoly.exterior.coords)
        voronoi_lattice[station]["obj_polygon"] = finalpoly

        #print polygon

    if (PlotIt):
        for station, data in voronoi_lattice.items():

            x = []
            y = []
            #print data
            try:
                polygon_data = data["obj_polygon"]
                #print polygon_data
                for point in list(polygon_data.exterior.coords):
                    x.append(point[0])
                    y.append(point[1])

            except:
                print "Error", data["name"]
            #if station == 8 :
            #plot(x,y)

            fill(x, y, alpha=0.6)

            plot(data["coordinate"][0], data["coordinate"][1])
            #text(data["coordinate"][0],data["coordinate"][1],data["info"])

        show()

    return voronoi_lattice
Exemplo n.º 11
0
for plz, (long, lat, name) in geoitems:
    x.append(long)
    y.append(lat)
ctx.init_geoscale(min(x), max(x) - min(x), min(y), max(y) - min(y))
ctx.set_antialias(cairo.ANTIALIAS_SUBPIXEL)
ctx.set_line_width(0.3 * c.ctxscale)

# see http://lists.cairographics.org/archives/cairo/2009-June/017459.html for drawing points
for plz, (long, lat, name) in geoitems:
    ctx.move_to(*ctx.geoscale(long, lat))
    ctx.close_path()
ctx.stroke()

pts = []
for plz, (long, lat, name) in geoitems:
    pts.append(voronoi.Site(long, lat))

points, lines, edges = voronoi.computeVoronoiDiagram(pts)

pprint(points)
pprint(lines)
pprint(edges)

ctx.set_line_width(0.1 * c.ctxscale)

for (l, p1, p2) in edges:
    x1 = y1 = x2 = y2 = None
    if p1 > -1:
        x1, y1 = points[p1]
    if p2 > -1:
        x2, y2 = points[p2]
Exemplo n.º 12
0
    def effect(self):
        if not self.options.ids:
            return inkex.errormsg(_("Please select an object"))
        scale = self.svg.unittouu('1px')  # convert to document units
        self.options.size *= scale
        self.options.border *= scale
        obj = self.svg.selection.first()
        bbox = obj.bounding_box()
        mat = obj.composed_transform().matrix
        pattern = self.svg.defs.add(Pattern())
        pattern.set_random_id('Voronoi')
        pattern.set('width', str(bbox.width))
        pattern.set('height', str(bbox.height))
        pattern.set('patternUnits', 'userSpaceOnUse')
        pattern.patternTransform.add_translate(bbox.left - mat[0][2], bbox.top - mat[1][2])

        # generate random pattern of points
        c = voronoi.Context()
        pts = []
        b = float(self.options.border)  # width of border
        for i in range(int(bbox.width * bbox.height / self.options.size / self.options.size)):
            x = random.random() * bbox.width
            y = random.random() * bbox.height
            if b > 0:  # duplicate border area
                pts.append(voronoi.Site(x, y))
                if x < b:
                    pts.append(voronoi.Site(x + bbox.width, y))
                    if y < b:
                        pts.append(voronoi.Site(x + bbox.width, y + bbox.height))
                    if y > bbox.height - b:
                        pts.append(voronoi.Site(x + bbox.width, y - bbox.height))
                if x > bbox.width - b:
                    pts.append(voronoi.Site(x - bbox.width, y))
                    if y < b:
                        pts.append(voronoi.Site(x - bbox.width, y + bbox.height))
                    if y > bbox.height - b:
                        pts.append(voronoi.Site(x - bbox.width, y - bbox.height))
                if y < b:
                    pts.append(voronoi.Site(x, y + bbox.height))
                if y > bbox.height - b:
                    pts.append(voronoi.Site(x, y - bbox.height))
            elif x > -b and y > -b and x < bbox.width + b and y < bbox.height + b:
                pts.append(voronoi.Site(x, y))  # leave border area blank
            # dot = pattern.add(inkex.Rectangle())
            # dot.set('x', str(x-1))
            # dot.set('y', str(y-1))
            # dot.set('width', '2')
            # dot.set('height', '2')
        if len(pts) < 3:
            return inkex.errormsg("Please choose a larger object, or smaller cell size")

        # plot Voronoi diagram
        sl = voronoi.SiteList(pts)
        voronoi.voronoi(sl, c)
        path = ""
        for edge in c.edges:
            if edge[1] >= 0 and edge[2] >= 0:  # two vertices
                [x1, y1, x2, y2] = clip_line(c.vertices[edge[1]][0], c.vertices[edge[1]][1], c.vertices[edge[2]][0], c.vertices[edge[2]][1], bbox.width, bbox.height)
            elif edge[1] >= 0:  # only one vertex
                if c.lines[edge[0]][1] == 0:  # vertical line
                    xtemp = c.lines[edge[0]][2] / c.lines[edge[0]][0]
                    if c.vertices[edge[1]][1] > bbox.height / 2:
                        ytemp = bbox.height
                    else:
                        ytemp = 0
                else:
                    xtemp = bbox.width
                    ytemp = (c.lines[edge[0]][2] - bbox.width * c.lines[edge[0]][0]) / c.lines[edge[0]][1]
                [x1, y1, x2, y2] = clip_line(c.vertices[edge[1]][0], c.vertices[edge[1]][1], xtemp, ytemp, bbox.width, bbox.height)
            elif edge[2] >= 0:  # only one vertex
                if edge[0] >= len(c.lines):
                    xtemp = 0
                    ytemp = 0
                elif c.lines[edge[0]][1] == 0:  # vertical line
                    xtemp = c.lines[edge[0]][2] / c.lines[edge[0]][0]
                    if c.vertices[edge[2]][1] > bbox.height / 2:
                        ytemp = bbox.height
                    else:
                        ytemp = 0
                else:
                    xtemp = 0
                    ytemp = c.lines[edge[0]][2] / c.lines[edge[0]][1]
                [x1, y1, x2, y2] = clip_line(xtemp, ytemp, c.vertices[edge[2]][0], c.vertices[edge[2]][1], bbox.width, bbox.height)
            if x1 or x2 or y1 or y2:
                path += 'M %.3f,%.3f %.3f,%.3f ' % (x1, y1, x2, y2)

        patternstyle = {'stroke': '#000000', 'stroke-width': str(scale)}
        attribs = {'d': path, 'style': str(inkex.Style(patternstyle))}
        pattern.append(PathElement(**attribs))

        # link selected object to pattern
        style = {}
        if 'style' in obj.attrib:
            style = dict(inkex.Style.parse_str(obj.attrib['style']))
        style['fill'] = 'url(#%s)' % pattern.get('id')
        obj.attrib['style'] = str(inkex.Style(style))
        if isinstance(obj, inkex.Group):
            for node in obj:
                style = {}
                if 'style' in node.attrib:
                    style = dict(inkex.Style.parse_str(node.attrib['style']))
                style['fill'] = 'url(#%s)' % pattern.get('id')
                node.attrib['style'] = str(inkex.Style(style))
def GenerateVoronoi(CurrentDate, PointsMap):

  currenttime=time.time()
  Sitepts = []
  pts = {}

  #print CurrentDate, PointsMap[PointsMap.keys()[0]]
  for grid, stations in PointsMap.items():
    for stn in stations:
      x=int(stn[2])
      y=int(stn[1])
      station=[stn[0]]
      station.extend( stn[3:])
      #print x,y,station

    if checkInRange(WorldRange,x,y)==False:
      #print x,y
      continue
    pts[ (x,y) ]=station
  
  stncounts=len(pts.keys())
  #print stncounts, "points"
  
  site_points=[]
  for pt in pts.keys():
    Sitepts.append(voronoi.Site(pt[0],pt[1]))
    site_points.append( (pt[0],pt[1]) )
      

  #print "Calculating Voronoi Lattice",
  
  siteList = voronoi.SiteList(Sitepts)
  context  = voronoi.Context()
  voronoi.Edge.EDGE_NUM=0   #what the hell why should I initialize it?
  voronoi.voronoi(siteList,context)

  vertices=context.vertices
  lines=context.lines
  edges=context.edges
  
  #print edges

  #For Faster Access
  edge_dic={}
  for edge in edges:
    edge_dic[edge[0]]=edge[1:]
  
  triangles=context.triangles
  has_edge=context.has_edge

  voronoi_lattice={}

  m_range={}
  m_range["max_x"]=-9999999999
  m_range["max_y"]=-9999999999
  m_range["min_x"]=9999999999
  m_range["min_y"]=9999999999

  #Get the range!!
  for pnt in site_points:
    m_range=update_maxmin(m_range, pnt[0], pnt[1])

  #print "Getting the Polygons"

  prev_percent=0
  for station, ls in has_edge.items():
    voronoi_lattice[station]={}
    voronoi_lattice[station]["coordinate"]=site_points[station]
    voronoi_lattice[station]["info"]=pts[ site_points[station] ]

    polygon=[]
 
    prev_extreme=[]
    Verbose=True
    if Verbose: 
      current_percent=int(station/float(stncounts)*100)
      if current_percent!=prev_percent:
        #print station,"/", stncounts, current_percent, "% Done" 
        timeelapse=time.time()-currenttime
        #print station, timeelapse
        currenttime=time.time()

      prev_percent=current_percent

    #For every lines that the station owns
    for l in ls:
      e=edge_dic[l]

      v1=vertices[e[0]]
      v2=vertices[e[1]]
    
      if e[0] < 0 and checkInRange(WorldRange,v2[0],v2[1])==False: continue
      if e[1] < 0 and checkInRange(WorldRange,v1[0],v1[1])==False: continue

      if e[0] > -1 and e[1] > -1 and checkInRange(WorldRange,v1[0],v1[1])==False and checkInRange(WorldRange,v2[0],v2[1])==False:
        continue 

      if e[0] < 0 or checkInRange(WorldRange,v1[0],v1[1])==False:
        v1=getExtreme(lines[l],v2, LR=0)

        if len(prev_extreme)==0:
          prev_extreme=v1
        else:
          extreme_points=linkExtremes(prev_extreme, v1, m_range)
          for extreme_pair in extreme_points:
            polygon.append(extreme_pair)

      if e[1] < 0 or checkInRange(WorldRange,v2[0],v2[1])==False :
        v2=getExtreme(lines[l],v1, LR=1)

        if len(prev_extreme)==0:
          prev_extreme=v2
        else:
          extreme_points=linkExtremes(prev_extreme, v2, m_range)
          for extreme_pair in extreme_points:
            polygon.append(extreme_pair)

      if v1!=v2:
        polygon.append( (v1,v2) )

    #This happened only once for 195612: ['999999-68601', 'BEARDMORE CAMP', 'AY', 'AY'] at (-164667, -85033)      
    if len(polygon)==0:
      voronoi_lattice.pop(station)
      continue
    #print polygon
    try:
      result = list(polygonize( polygon ))
    except ValueError:
      #print "Wrong:", polygon

      #Delete invisible short lines
      point_to_replace=[]
      for line in polygon:
        d=math.hypot( line[0][0]-line[1][0], line[0][1]-line[1][1])
        if d<1:
          polygon.remove(line)
          point_to_replace=line
      i=0
      New_Lines=[]
      for line in polygon:
        New_Lines.append(list(line))
        j=0
        for point in line:
          if point==point_to_replace[0]:
            #print line, point_to_replace
            New_Lines[i][j]=point_to_replace[1]
          j+=1
        i+=1

      sys.stderr.write(str(polygon))
      polygon=tuple(New_Lines)
      sys.stderr.write(str(polygon))
      result = list(polygonize( polygon ))





    finalpoly=result[0]
    #print list(finalpoly.exterior.coords)
    #voronoi_lattice[station]["polygon"]=list(finalpoly.exterior.coords)
    voronoi_lattice[station]["obj_polygon"]=finalpoly
    
    #print polygon
  
  return voronoi_lattice