Showing antenna symbols on the map: point symbols or features (polygons)
If you want to use symbology only, I propose a solution inspired by my answer from a similar question: Creating sector lights in QGIS?.
Following a similar approach, and assuming you are working on a Projected CRS (instead, if you are using a Geographic Coordinate System, see the note at the end of the answer), I want to underline that I will focus the attention on the explanation of the minimal things to do for reproducing the desired result: this means that some other minor parameters (like sizes, widths and so on) should be easily adjusted by you for better fitting your needs.
Furthermore, I assume that "AZIMUTH"
is the field which stores the azimuth values and "BEAMWIDTH"
is the field which stores the antenna beam widths.
Solution
We will render the points with a Single symbol
and by recurring to one Simple Marker
and two Geometry generator
symbol layers:
In the further explanation, I will follow the same order of the symbols in the image above.
1) Simple Marker
I chose a default symbol of a red circle (this is the easier part of this tutorial), having a size of 3 mm and a width of 0.4 mm.
2) Geometry Generator No. 1
Add a new symbol layer and select the Geometry generator
and the LineString / MultiLineString
types:
Insert this expression in the Expression
field:
make_line(
$geometry,
make_point($x + 300*cos(radians(90 - "AZIMUTH" )), $y + 300*sin(radians((90 - "AZIMUTH" ))))
)
We have just defined the arrow which points towards the azimuth set (for creating the arrow, remember to select the Arrow
symbol layer type under the Line
option from the main symbol Menu). Please note that 300
represents a distance in meters and it's an arbitrary value, so feel free to change it according to your needs.
3) Geometry Generator No. 2
Add a new symbol layer and select the Geometry generator
type and the Polygon / MultiPolygon
types:
Insert this expression in the Expression
field:
CASE
WHEN ("BEAMWIDTH") <= 180
THEN
intersection(
buffer(
$geometry, 200),
make_polygon(
geom_from_wkt(
geom_to_wkt(
make_line(
$geometry,
make_point($x + 2000*cos(radians(90 - "AZIMUTH" - "BEAMWIDTH"/2 )), $y + 2000*sin(radians((90 - "AZIMUTH" - "BEAMWIDTH"/2 )))),
make_point($x + 2000*cos(radians(90 - "AZIMUTH" )), $y + 2000*sin(radians((90 - "AZIMUTH" )))),
make_point($x + 2000*cos(radians(90 - "AZIMUTH" + "BEAMWIDTH" /2)), $y + 2000*sin(radians((90 - "AZIMUTH" + "BEAMWIDTH"/2)))),
$geometry)
)
)
)
)
WHEN ("BEAMWIDTH") > 180
THEN
difference(
buffer(
$geometry, 200),
make_polygon(
geom_from_wkt(
geom_to_wkt(
make_line(
$geometry,
make_point($x + 2000*cos(radians(90 - "AZIMUTH" - "BEAMWIDTH"/2 )), $y + 2000*sin(radians((90 - "AZIMUTH" - "BEAMWIDTH"/2 )))),
make_point($x - 2000*cos(radians(90 - "AZIMUTH" )), $y - 2000*sin(radians((90 - "AZIMUTH" )))),
make_point($x + 2000*cos(radians(90 - "AZIMUTH" + "BEAMWIDTH" /2)), $y + 2000*sin(radians((90 - "AZIMUTH" + "BEAMWIDTH"/2)))),
$geometry)
)
)
)
)
END
We have just defined the sector. Please note that 200
and 2000
represent distances in meters and they are arbitrary values because I'm trying to create a polygon to intersect with the circle having a radius of 200 m, so feel free to change them according to your needs.
Final result
If you correctly perform the previous tasks, you should be able to get results like these ones (the labels are added apart from this solution and they should only explain better the context):
Note
If you are using a Geographic Coordinate System, i.e. if you are dealing with degrees and not with distances, it should be enough using the proper values when I used a distance in the previous formulas. The distances I used are:
- 300 m (see Geometry Generator No. 1);
- 200 m (see Geometry Generator No. 2);
- 2000 m (see Geometry Generator No. 2);
so you may replace it with other arbitrary values expressed in degrees (for example, 0.0002
, 0.002
and so on).
Bonus
I have attached the style here: you may open this code with any text editor and save it as a QGIS Layer Style file (i.e. with a .qml
extension).
The above style was created using QGIS 2.18.4 (it must have the same name of the shapefile you are using).
A few days ago a new plugin was added to QGIS called Wedge Buffer Processing Algorithm. This looks as if it might be of interest.
As the name suggests it's a processing algorithm, so you'll need to run it from the processing toolbox. Not had a chance to try it yet though.
It creates sectors of circles - like a normal circular buffer, but the wedge angle and radius can be set using field values.
Documentation and screenshots can be seen on the github page
Big kudos to mgri.
In our test layer, everything worked smoothly. In a production layer, after two/three hours, I managed to track down an issue with $geometry. Had been exporting a point layer from a platform, didn't take notice, but it was MultiPoint. This seemed to cause issues: the arrow wasn't drawn; and strangely enough only the calculated points made the polygon of the circles.
Another thing is I'm using a variable radius. (not sure if it's the right word in this case, you could also name it 'beam length' or whatever).
Here's what I'm using now, with a MultiPoints geometry type layer (while in fact all features are a single point), and it works for me in QGis 2.18.3
Arrow expression No arrow if 360°.
CASE
WHEN ("BEAMWIDTH") = 360
THEN
make_line(
make_point($x, $y),
make_point($x + "RADIUS"*cos(radians(90 - "AZIMUTH" )), $y + "RADIUS"*sin(radians((90 - "AZIMUTH" ))))
)
END
Polygon expression
CASE
WHEN ("BEAMWIDTH") <= 180
THEN
intersection(
buffer(
make_point($x,$y), "RADIUS"),
make_polygon(
geom_from_wkt(
geom_to_wkt(
make_line(
make_point($x,$y),
make_point($x + "RADIUS"*2*cos(radians(90 - "AZIMUTH" - "BEAMWIDTH"/2 )), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" - "BEAMWIDTH"/2 )))),
make_point($x + "RADIUS"*2*cos(radians(90 - "AZIMUTH" )), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" )))),
make_point($x + "RADIUS"*2*cos(radians(90 - "AZIMUTH" + "BEAMWIDTH" /2)), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" + "BEAMWIDTH"/2)))),
make_point($x,$y))
)
)
)
)
WHEN ("BEAMWIDTH") > 180
THEN
difference(
buffer(
make_point($x,$y), "RADIUS"),
make_polygon(
geom_from_wkt(
geom_to_wkt(
make_line(
make_point($x,$y),
make_point($x + "RADIUS"*2*cos(radians(90 - "AZIMUTH" - "BEAMWIDTH"/2 )), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" - "BEAMWIDTH"/2 )))),
make_point($x - "RADIUS"*2*cos(radians(90 - "AZIMUTH" )), $y - "RADIUS"*2*sin(radians((90 - "AZIMUTH" )))),
make_point($x + "RADIUS"*2*cos(radians(90 - "AZIMUTH" + "BEAMWIDTH" /2)), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" + "BEAMWIDTH"/2)))),
make_point($x,$y))
)
)
)
)
END