Wednesday, September 16, 2026

Axonometric Drawing - SSR (Scale, Shear/Skew, Rotate) technique

 The SSR (Scale, Shear, Rotate) technique is a highly efficient mathematical workflow used in vector graphic programs like Adobe Illustrator and Inkscape to precisely transform flat 2D orthographic drawings into a 3D isometric axonometric projection. Instead of tracing flat blueprints onto an isometric grid by hand, the SSR method automates the deformation using exact numerical inputs.

The technique relies on mathematically shifting the 2D plane so that a standard square conforms perfectly to the true 30-degree / 120-degree orientation of an isometric drawing.


The Three Pillars of SSR

To project a flat 2D face onto one of the three visible planes of a 3D cube (Top, Left, or Right), you apply three sequential operations to your vector object:

  1.  Scale: This accounts for the foreshortening effect of looking at an object from an isometric angle. You scale the vertical height of the object down to 86.602% while leaving the width at 100%.
  2.  Shear (or Skew): This slants the vertical edges of the object to mimic a parallel projection angle, tilting them by 30° or -30°.
  3.  Rotate: This turns the entire asset into the final orientation required for that specific plane, shifting it by 30° or -30°.

The Standard Transformation Values

Depending on which side of the axonometric drawing you are generating, apply these specific transformations in order:

Isometric Plane

1. Scale (Vertical)

2. Shear (Skew)

3. Rotate

Top Plane 🪵

86.602%

30°

-30°

Left Plane 🧱

86.602%

-30°

-30°

Right Plane 🧱

86.602%

30°

30°

(Note: Some software packages require a 30° Shear and a 30° Rotation for the Left Plane, or flipped symbols depending on how the software measures clockwise vs. counter-clockwise angles).

The 86.602% vertical scale factor in the SSR technique is not an arbitrary number—it is the exact trigonometric value of 

It acts as a mathematical pre-compensation filter. When you skew (shear) an object in a vector program by 30°, the software stretches the geometry. Scaling the vertical axis down to 86.602% beforehand ensures that after it stretches, the final lines return to exactly 100% of their original true length, maintaining a perfect 1:1:1 aspect ratio across all 3D axes.

Here is the exact geometric breakdown of why this happens.

1. The Trigonometry of the Shear Step

When you apply a 30° Shear to a flat square, the horizontal lines of your drawing tilt upward by 30°.

In vector graphics, a shear shifts points along one axis proportional to their distance from the other axis. This distorts the right angles of your flat square into an isometric diamond (rhombus). During this distortion:

  • The width (horizontal boundary) of the bounding box remains fixed.
  • The horizontal lines tilt up at a 30° angle, turning into the hypotenuse of a right-angled triangle.

According to right-triangle trigonometry:

Rearranging this formula to find the new length:


This means that shearing a flat object by 30° automatically stretches its line segments by roughly 115.47%.

2. Eliminating the Distortion (Why we Scale First)

If you don't scale the graphic before shearing it, your final 3D object will look elongated and structurally warped because the lines on the isometric plane are longer than they should be.

To counteract this 115.47% expansion, you must shrink the asset by the exact reciprocal amount before the shear takes place:

By scaling the vertical size to 86.602%, you intentionally compress the object. When the 30° shear step elongates the lines by 115.47%, the two operations cancel each other out perfectly:


3. Isometric Drawing vs. Isometric Projection

There is a subtle but important distinction in technical drawing that explains why this scale factor is so highly regarded:

  • True Isometric Projection: When an actual 3D cube is rotated in physical space (45° horizontally, then 35.264° downward toward the camera), all axes shrink uniformly to 81.65% of their real-world size due to perspective foreshortening.
  • Isometric Drawing (The SSR Approach): Graphic designers prefer a 1:1 scale so that a 100px line on a flat blueprint remains exactly 100px long on the 3D isometric axis. The SSR technique achieves this "true measurement" standard. By scaling vertically to 86.602% before shearing, the final 3D drawing retains an un-foreshortened, easily measurable 100% scale on all visible faces.


To calculate alternative scale values for other axonometric projections, you must determine how much the shear (skew) angle stretches the artwork and use trigonometry to cancel out that distortion.

The universal formula to find the required vertical scale factor for any parallel projection using the Shear-Rotate method is:

(Where Ï´ is the shear angle you intend to use).


Thank you for reading.

Monday, September 7, 2026

Creating REM from DEM in QGIS

 REMs are best produced from LiDAR data, however my region of interest has no publicly available LiDAR dataset. So, I will use high-resolution DEM from "Copernicus Global Digital Elevation Models" distributed by OpenTopography because it offers superior horizontal and vertical accuracy compared to SRTM DEM data. To cite this data, use:-

European Space Agency (2024). Copernicus Global Digital Elevation Model. Distributed by OpenTopography. https://doi.org/10.5069/G9028PQB. Accessed 2026-09-05


This study area is the Uke river (approximately Latitude 8°35'N to 9°05'N and Longitude 7°35'E to 7°55'E) that streches from Karu LGA into Nasarawa LGA all within Nasarawa state. The Uke river is a dynamic, seasonal river system that feeds into the larger Uke-Antau-Mada drainage basin, just east of Abuja.



What is Relative Elevation Model

A Relative Elevation Model (REM), also called a detrended digital elevation model or height-above-river raster, is a specialized 3D map that shows land height relative to a nearby river channel rather than above sea level.
Traditional Digital Elevation Models show absolute height above sea level. Because rivers naturally slope downward from their source to their mouth, this overall slope can hide small, local changes in the landscape.
An REM "flattens" the river's downward slope by setting the riverbed elevation to zero everywhere.
Software takes a standard elevation grid, estimates the water level along the river's center line, and subtracts that predicted river height from the original elevation data.
A value of zero means the ground is level with the nearest river channel, while positive numbers show how high a specific spot sits above that river.






Steps for Creating a Relative Elevation Model

Step A: Reproject and Clip

  • Open your downloaded GeoTIFF in QGIS.
  • Reproject the layer from WGS 84 (Geographic) to a projected coordinate system for accurate distance measurements. For Nasarawa State, use WGS 84 / UTM Zone 32N (EPSG:32632).

Step B: Extract River Vector and Elevation

  1. Manually digitize the centerline of the Uke River as a line vector layer, or extract it automatically using the SAGA Channel Network tool.
  2. Use the Extract Vertices tool to convert the Uke River line into a series of dense point features along the channel.
  3. Open the Sample Raster Values tool. Use your reprojected DEM to add the exact elevation (Z-value) to every point along the river channel.


Step C: Create the Arbitrary River Plane

  1. Open the Inverse Distance Weighting (IDW) Interpolation tool under the QGIS Processing Toolbox.
  2. Set the input layer as your sampled river points and select the sampled elevation attribute as your vector interpolation field.
  3. Set the extent to match your clipped study area and run the tool. This creates a smooth, continuous "water level baseline surface raster" that mimics the downhill slope of the river.

Step D: Calculate the Relative Elevation Model

  1. Open the Raster Calculator.
  2. Enter the formula: [Projected_DEM] - [IDW_Interpolation_Surface]
  3. Run the calculation.

The resulting layer is your REM. All values of 0 will represent the exact channel bed of the Uke River, while higher values represent the exact height of the surrounding terrain relative to the closest point of the riverbed, perfectly highlighting paleochannels, floodplains, and terrace heights.


Thank you

Wednesday, September 2, 2026

How to Download RADAR Image using Google Earth Engine

 RADAR stands for 'RAdio Detection And Ranging'. It is a system that uses radio waves to determine the distance (ranging), direction (azimuth and elevation angles), and radial velocity of objects relative to the site. Radar remote sensing is a type of active remote Sensing which uses electromagnetic energy backscattered from ground targets to extract physical and dielectric behavior.

A free common source of RADAR image is the Sentinel-1 satellite that uses the C-band SAR (Synthetic Aperture Radar) sensor to acquire Radar imaging.

So, in this post I will guide to on how to download Sentinel-1 image (which is a Radar image) using JavaScript code in Google Earth Engine. Lets get our hands dirty!

To download a RADAR (SAR) image using Google Earth Engine (GEE), you must filter a SAR collection—typically Sentinel-1 Ground Range Detected (GRD)—create a single-image composite, and export it directly to your Google Drive.

Here is the complete workflow and JavaScript code to achieve this.

Step 1: Write the GEE Script

Open the Google Earth Engine Code Editor and paste the following script into the central console:

// 1. Define your Area of Interest (AOI)
// You can also draw a polygon manually using the map geometry tools
var aoi = ee.Geometry.Rectangle([8.05, 8.25, 8.55, 7.50]); // Example: Okokolo, Benue state, Nigeria
Map.centerObject(aoi, 12);

// 2. Load the Sentinel-1 RADAR (SAR) Image Collection
var SAR_collection = ee.ImageCollection('COPERNICUS/S1_GRD')
  .filterBounds(aoi)
  .filterDate('2026-01-01', '2026-06-30') // Filter by date
  // Filter for Interferometric Wide (IW) swath mode
  .filter(ee.Filter.eq('instrumentMode', 'IW')) 
  // Filter for dual-polarization (VV and VH)
  .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
  .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'));

// 3. Create a single median composite image and clip it to your AOI
var raw_image = SAR_collection.median().clip(aoi);

// 4. Select the desired RADAR bands (VV, VH, or an added ratio)
var download_image = raw_image.select(['VV', 'VH']);

// 5. Add the processed image to the map view for a visual check
Map.addLayer(download_image, {min: -25, max: 0}, 'Filtered SAR Image');

// 6. Set up the export command to Google Drive
Export.image.toDrive({
  image: download_image,
  description: 'Sentinel1_RADAR_Download',
  folder: 'GEE_Downloads', // Subfolder name in your Google Drive
  scale: 10,               // Spatial resolution of Sentinel-1 is 10 meters
  region: aoi,             // Target boundary
  fileFormat: 'GeoTIFF',
  maxPixels: 1e13
});


Step 2: Execute the Script

  1. Click the Run button at the top of the Code Editor.
  2. Look at the right-hand panel and click on the Tasks tab. You will see your export task (Sentinel1_RADAR_Download) highlighted in orange/yellow.

Step 3: Run the Task & Download From Google Drive
  1. Click the Run button next to the task name in the Tasks tab.
  2. A pop-up configuration window will appear. Confirm the parameters (leave them at defaults) and click Run again.
  3. The spinning gear icon indicates the processing stage. This can take anywhere from a few minutes to an hour depending on the size of your AOI.
  4. Once the icon turns into a blue checkmark, open your Google Drive.
  5. Navigate to the GEE_Downloads folder and download the GeoTIFF file directly to your computer. You can now import and analyze the raw RADAR image inside external desktop GIS software like QGIS or ArcGIS.




RADAR (SAR) imagery is uniquely powerful because it uses microwave signals. Unlike optical satellites (like Landsat or Sentinel-2), SAR penetrates clouds, smoke, and darkness, allowing it to capture data 24/7 in any weather conditions. SAR sensors do not capture colors; instead, they measure surface roughness, structure, moisture content, and dielectric properties.



Happy mapping!

Tuesday, August 18, 2026

Customizing the Grid/Graticle Labels in QGIS

 To customize your grid/graticle coordinate labels to display with custom text and a unit suffix, you need to use a custom expression in the QGIS Print Layout.

For example, to achieve label format like this “10,000mE”, you will make use of this expression:

format_number(@grid_number, 0) || 'm' || if(@grid_axis = 'x', 'E', 'N')

How This Formula Works

a)    format_number(@grid_number, 0): Automatically adds thousands-separator commas to your coordinate number and removes decimal places.

b)    || 'm': Appends the letter "m" for meters directly to the number.

c)    if(@grid_axis = 'x', 'E', 'N'): Checks if the label belongs to the X-axis (Easting) or Y-axis (Northing) and dynamically attaches the correct E or N directional suffix.


Steps to Use a Custom Expression

a)    Open your Print Layout and select your map frame.

b)    Go to the Item Properties panel on the right.

c)    Scroll down to Grids, select your UTM grid, and click Modify Grid...

d)    Scroll down to Draw Coordinates and ensure the box is checked.

e)    Change the Format dropdown menu from Decimal to Custom.

f)     Click the Expression button (ε) right next to the format dropdown.

 Enter the Custom Formatting Formula

Delete any existing text in the expression box and paste the following formula: format_number(@grid_number, 0) || 'm' || if(@grid_axis = 'x', 'E', 'N')


Common Custom Label Formats

Here are the most common custom label formats used for map grids in QGIS, along with the exact expressions you can paste into the expression editor (ε).

 1. Stripped UTM Grid (Standard Topographic Format)

This format drops the last three trailing zeros (thousands) to keep the map border clean and uncluttered (e.g., 450 instead of 450,000).

  • Example Output: 450
  • Expression: 
substr(to_string(@grid_number), 1, length(to_string(@grid_number)) - 3)

2. Full Kilometers with Suffix

This format converts meter values into kilometers and adds a directional suffix (e.g., 450 km E).

  • Example Output: 450 km E
  • Expression:
(@grid_number / 1000) || ' km ' || if(@grid_axis = 'x', 'E', 'N')

3. Abbreviated Geographic Degrees (Decimal Degrees)

This format rounds standard decimal degrees to a clean precision and adds traditional cardinal directions instead of negative numbers.

  • Example Output: 12.35° N or 74.10° W
  • Expression:
format_number(abs(@grid_number), 2) || '° ' || 
if(@grid_axis = 'x', if(@grid_number < 0, 'W', 'E'), if(@grid_number < 0, 'S', 'N'))

4. Hybrid Meter/Kilometer Topo Style

This mimics military or official survey maps by showing the full value but making the key thousands digits stand out (e.g., showing just the km value with the remainder as a superscript, formatted here as text).

  • Example Output: 450km (000)
  • Expression:
floor(@grid_number / 1000) || 'km (' || right(to_string(@grid_number), 3) || ')'

5. Clear Text Hemispheres for Lat/Long

This provides a highly readable, non-abbreviated text layout for geographic coordinates.

  • Example Output: Latitude 45.5° North
  • Expression:
if(@grid_axis = 'x', 'Longitude ', 'Latitude ') || 
format_number(abs(@grid_number), 1) || '° ' || 
if(@grid_axis = 'x', if(@grid_number < 0, 'West', 'East'), if(@grid_number < 0, 'South', 'North'))



6. Padding Leading Zeros

Useful for local grid systems where all labels must match a fixed character length for visual alignment.

  • Example Output: 004500
  • Expression:
lpad(to_string(@grid_number), 6, '0')

7. Standard DMS with Directional Suffix (available by default)

This clean, universal format splits the coordinate into degrees (°), minutes ('), and seconds ("), adding a cardinal direction indicator instead of negative math symbols. This format is available by default as "Degree, Minute, Second with Suffix" when you set 'Coordinate Precision' to one decimal place.

  • Example Output: 45° 30' 15" N or 122° 15' 45" W
  • Expression:
with_variable('abs_val', abs(@grid_number),
  floor(@abs_val) || '° ' || 
  floor((@abs_val - floor(@abs_val)) * 60) || char(39) || ' ' || 
  format_number((((@abs_val - floor(@abs_val)) * 60) - floor((@abs_val - floor(@abs_val)) * 60)) * 60, 1) || '" ' || 
  if(@grid_axis = 'x', if(@grid_number < 0, 'W', 'E'), if(@grid_number < 0, 'S', 'N'))
)



8. Compact DMS (No Spaces)

Ideal for tight margins or crowded map borders, this removes inner spaces and rounds seconds to the nearest whole integer.

  • Example Output: 45°30'15"N
  • Expression:
with_variable('abs_val', abs(@grid_number),
  floor(@abs_val) || '°' || 
  floor((@abs_val - floor(@abs_val)) * 60) || char(39) || 
  format_number((((@abs_val - floor(@abs_val)) * 60) - floor((@abs_val - floor(@abs_val)) * 60)) * 60, 0) || '"' || 
  if(@grid_axis = 'x', if(@grid_number < 0, 'W', 'E'), if(@grid_number < 0, 'S', 'N'))
)




9. Padded DMS (Consistent Character Width)

This expression adds a leading zero to single-digit minutes and seconds. It ensures all labels are exactly the same physical width, preventing jagged alignments along your map frame.

  • Example Output: 05°09'02" S
  • Expression:
with_variable('abs_val', abs(@grid_number),
  lpad(to_string(floor(@abs_val)), 2, '0') || '°' || 
  lpad(to_string(floor((@abs_val - floor(@abs_val)) * 60)), 2, '0') || char(39) || 
  lpad(to_string(format_number((((@abs_val - floor(@abs_val)) * 60) - floor((@abs_val - floor(@abs_val)) * 60)) * 60, 0)), 2, '0') || '" ' || 
  if(@grid_axis = 'x', if(@grid_number < 0, 'W', 'E'), if(@grid_number < 0, 'S', 'N'))
)



Happy Mapping

Saturday, August 15, 2026

Adding Multiple Grids/Graticles Labels on a Map in QGIS

 Most likely you have come accross a map (similar to the two below) that has more that one Grids/Graticles labelled lines and you are wondering what they are and why they have to include multiple Grids/Graticles labels.

The first map has Grids (UTM) labels inside the frame and Graticles (WGS 84) labels outside the frame. While the second map has Grids (UTM) labels on top and right-hand sides of the frame, and Graticles (WGS 84) labels on the bottom and left-hand side of the frame.




Before we learn how to add multiple Grids/Graticles to a map in QGIS, let understand the difference between Grids/Graticles and why it is necessary to sometime have multiple Grids/Graticles labels on a map.

The fundamental difference between a grid and a graticule is the shape of the surface they represent: a graticule maps a curved, 3D spherical surface (the Earth), while a grid maps a flat, 2D projected surface (a piece of paper or computer screen).

Summary Comparison Table



Maps display two or more different grids (a projected grid and a geographic graticule) simultaneously to serve different navigation, measurement, and reference needs on a single sheet.

1. Cross-Agency and Multi-User Compatibility

Different organizations, military branches, and emergency services use different reference systems.

a)    Search and Rescue: Ground teams might use local UTM meters for precise land navigation, while helicopter pilots require WGS84 Latitude/Longitude degrees for aviation GPS.

b)    Civilian vs. Military: Civilian map users generally rely on standard national grids, while international or defense groups require the Military Grid Reference System (MGRS).

 

2. Balancing Local Distance with Global Position

No single coordinate system does everything perfectly on a flat piece of paper.

a)    The Projected Grid (UTM/State Plane): Uses a flat XY grid measured in meters or feet. It allows users to quickly calculate real-world distances, areas, and angles using simple math.

b)    The Geographic Graticule (Lat/Long): Uses a curved grid measured in degrees. It tells the user exactly where they are on the global sphere, making it easy to cross-reference with international maps or global tracking systems.

 

3. Historical Data and Map Archiving

When updating older maps or combining historical surveys with modern data, dual grids preserve accuracy.

a)    Legacy Systems: Older physical maps often retain their original historical grid system (like the UK OSGB36) on the boundary.

b)    Modern Overlays: Cartographers print a modern global grid (WGS84) over the old map so modern GPS coordinates can still be used accurately.

 

4. Transition Zones and Border Mapping

When a mapped region sits right on the edge of a coordinate boundary, a secondary grid maintains continuity.

a)    UTM Zone Boundaries: If a park sits on the border of UTM Zone 15 and UTM Zone 16, using one zone distorts the other half. Adding both grids lets users work seamlessly across the border.


How to add a Grid and Graticles to a map in QGIS

To add two separate grids to a map in QGIS, open your Print Layout, select your map item, and navigate to the Item Properties panel. Scroll down to the Grids section, click the green plus (+) button twice to create two individual grid entries, and configure each one with its own distinct styling, interval, or coordinate system (CRS).

 

Setting Up the First Grid

a)    Select your map item in the layout canvas.

b)    Find the Grids dropdown in Item Properties and click the + button.

c)    Double-click the newly created grid (e.g., Grid 1) to rename it (e.g., UTM Grid or Projected).

d)    Click Modify Grid... to set your preferred CRS (such as your project's local projected coordinate system), line style (solid, cross, or markers), and X/Y intervals.

e)    Enable Draw Coordinates if you want annotations displayed for this primary grid.

 

Adding and Configuring the Second Grid

a)    Click the green plus (+) button again in the Grids menu to create Grid 2.

b)    Rename it to avoid confusion (e.g., Geographic Grid or Lat-Long).

c)    Click Modify Grid... to adjust its properties independently.

d)    Change the CRS to a different system if needed (e.g., EPSG:4326 for latitude/longitude degrees).

e)    Adjust the interval values, select a different appearance (like using subtle crosses instead of solid lines), or disable line rendering entirely while keeping frame ticks and coordinates active to prevent visual clutter.


Thank you for reading.