More

QGIS Polygon edge style based on adjoining feature?

QGIS Polygon edge style based on adjoining feature?


Is there a way to change the style of only PART of a polygon's border in QGIS? I would like one or two edges of certain polygons to render a different color, or not at all, depending on the type of feature that is adjacent. (For example, a political division that adjoins a waterbody would show that one edge as blue.)

The obvious way seems to be changing the style of the adjoining feature, then using symbol levels to have it render on top of the first feature, but this doesn't work; there is always a little bit of the other border showing through underneath:

I can increase the line thickness of the adjoining feature so that it fully covers the feature underneath (in the example image it's already twice as thick), but then it also begins to cover the interior of that polygon. I can also convert to polylines and just clip off the shoreline, but then I lose the geometry. I think what I really need is a way to suppress rendering of the border on the one side, and just covering it with something else isn't working.


As user30184 points out you need the boundary geometry of polygons to render one polygons outline in a different way. To create such a planar graph you can downgrade polygons to polylines, and keep only one instance of these segments being shared by two polygons.

The following script might help. It mimics kind of topology building process. It takes into account, that neighboring polygon may not be digitized in the same direction. In the result each segment has attributes with the feature ids of the left and right polygon. These values can be used, to establish a join to the attribute table of the polygons. If you want to dissolve the segments to continous lines, use the dissolve tool from processing toolset. For this to create useful results you should consider to combine attributeslpolyandrpolyinto a composite attribute, and use this for the dissolve process.

from PyQt4.QtCore import QVariant layer = iface.activeLayer() segments = {} j = 0 for feat in layer.getFeatures(): # polylines line = feat.geometry().asPolygon()[0] for i in xrange(len(line)-1): lsegment = ((line[i][0], line[i][1]), (line[i+1][0], line[i+1][1])) rsegment = ((line[i+1][0], line[i+1][1]), (line[i][0], line[i][1])) if lsegment in segments: if segments[lsegment]['lpoly'] == -9999: segments[lsegment]['lpoly'] = feat.id() elif segments[lsegment]['rpoly'] == -9999: segments[lsegment]['rpoly'] = feat.id() elif rsegment in segments: if segments[rsegment]['lpoly'] == -9999: segments[rsegment]['lpoly'] = feat.id() elif segments[rsegment]['rpoly'] == -9999: segments[rsegment]['rpoly'] = feat.id() else: segments[lsegment] = {'lpoly': feat.id(), 'rpoly': -9999, 'fid': j} j += 1 layer = QgsVectorLayer('LineString?crs=EPSG:4326', 'Result', 'memory') prov = layer.dataProvider() attributes = [QgsField('fid', QVariant.Int), QgsField('lpoly', QVariant.Int), QgsField('rpoly', QVariant.Int), QgsField('length', QVariant.Double)] prov.addAttributes(attributes) QgsMapLayerRegistry.instance().addMapLayer(layer) # create features feats = [] layer.startEditing() for segment in segments: feat = QgsFeature() vertices = [QgsPoint(segment[0][0], segment[0][1]), QgsPoint(segment[1][0], segment[1][1])] attributes = [segments[segment]['fid'], segments[segment]['lpoly'], segments[segment]['rpoly']] feat.setGeometry(QgsGeometry.fromPolyline(vertices)) attributes.append(feat.geometry().length()) feat.setAttributes(attributes) feats.append(feat) prov.addFeatures(feats) layer.updateExtents() layer.commitChanges()

Example: Polygons, labeled with id()

Boundary of polygons, labeled with lpoly above rpoly


Watch the video: A Complete Beginners Guide to ArcGIS Desktop Part 1