Interactive Course · Diátaxis Framework

Become a GIS Analyst

A self-paced journey through spatial databases, SQL, geoprocessing, web mapping, and cartographic visualization — built from training materials at Politeknik Negeri Batam.

Start Learning ↓
10 Modules
30+ Exercises
~3hrs Self-paced
Tutorial
How-To
Reference
Explanation
Explanation 01

What is GIS — and Why Does It Matter?

Geographic Information Systems turn raw location data into decisions that shape cities, protect forests, and save lives.

Maps That Think

Imagine you're the mayor of a growing city. A new hospital needs to be built, but where? It must be close to the most people, reachable by road, and far from flood zones. A GIS can answer that.

🌎

Capture

Collect data from satellites, GPS, surveys, and open data portals like OpenStreetMap.

🗃

Store

Organize it in spatial databases where every row knows its location on Earth.

Analyze

Run operations like buffering, overlay, and network analysis to extract insights.

🗺

Visualize

Present findings as beautiful, readable maps that drive real-world decisions.

Your GIS Toolbox

This course is built around an open-source stack — free, professional-grade tools used worldwide.

Q
QGIS

QGIS is your main workspace — load layers, run analyses, design maps.

P
PostgreSQL + PostGIS

PostGIS stores geometry alongside regular data, so you can ask “which villages touch this district?”

G
GeoServer + MapStore2

GeoServer publishes your data to the web; MapStore2 gives users a browser-based map viewer.

Two Flavors of Spatial Data

Every GIS dataset is either vector or raster.

VECTOR
Points  ●  (hospitals, villages)
Lines   ─  (roads, rivers)
Polygons ■ (districts, forests)

Each feature has a shape
+ an attribute table (name,
population, type, etc.)
RASTER

A grid of cells (pixels), like a photo. Each cell holds one numeric value.

Elevation models: each cell = height in meters.

Population density (WorldPop): each cell = people per km².

Satellite imagery: each cell = reflectance values.

💡
Vector vs. Raster

Vector = drawing with a pen (precise boundaries). Raster = painting with a grid (continuous surfaces). Most GIS projects use both.

Check Your Understanding

You need to map every hospital with its name, bed count, and address. Which data type?

Explanation 02

Designing Spatial Databases

Bad database design leads to data chaos. Good design makes every query fast and every answer trustworthy.

The Rules of Good Tables

A relational database is like a library with a perfect catalog system.

1 subjectEach table represents one thing (customers, roads, hospitals)
1 PKEvery table has a Primary Key
No multi-partSplit “302 Walker Bldg, University Park, PA” into street, city, state
No duplicatesNo Author1, Author2, Author3 — use a separate table
No derivedDon’t store Wage if you have PayRate × Hours

Normalization: Three Cleaning Passes

Normalization is tidying a messy room in three passes — each catches a different kind of mess.

1
First Normal Form (1NF)

Unique entities, no duplicate columns (no Flavor1, Flavor2, Flavor3), and a primary key.

2
Second Normal Form (2NF)

In 1NF + no column depends on only part of a composite key.

3
Third Normal Form (3NF)

In 2NF + no column depends on another non-key column. Remove derived values.

💡
The Trade-Off

Higher normalization = more tables = more joins. Database design balances data integrity against query complexity.

The Ice Cream Shop Example

Jen and Barry sell ice cream and need to track orders. Watch how a messy table gets normalized:

Attempt 1
Flavors crammed in one column

~

Attempt 2
Flavor1, Flavor2, Flavor3 columns

Final
4 tables: Customers, Flavors, Orders, OrderItems

Entity-Relationship Diagrams

Before building tables, you draw an ER diagram.

Entities

Real-world objects: Users, Cars, Ads. Each becomes a table. Strong (exists alone) or weak (depends on another).

Attributes

Simple (color), composite (address), derived (age from birthdate), multi-valued (phone numbers).

Relationships

How entities connect. Cardinality defines how many (1:1, 1:N, M:N).

Check Your Understanding

Scenario

Each health facility can have multiple phone numbers. A colleague suggests Phone1, Phone2, Phone3 columns.

What’s wrong with this approach?

Tutorial 03

SQL Fundamentals: Hands-On

SQL is the language you use to talk to databases. Follow along step by step — every command uses real examples from this training.

Step 1: Creating Tables

SQL is how you talk to a database. Let’s start with the most fundamental operation — creating a new table from existing data.

SQL
CREATE TABLE kelurahan AS
SELECT geom, giskemen_2, giskemen_4,
       giskemen18, giskemen19, giskemen20,
       giskemen21, giskemen27, giskemen28
FROM public.desa_batam
PLAIN ENGLISH

Create a brand new table called “kelurahan” (sub-district)…

Fill it by copying specific columns (geometry + 7 data fields)…

…from the existing “desa_batam” villages table.

Like photocopying certain pages from a binder into a new folder.

💡
CREATE TABLE ... AS SELECT

This pattern is incredibly powerful: create a new table that’s a filtered/transformed copy of another. You control exactly which columns and rows end up in the new table.

Step 2: Renaming Columns

Real-world data arrives with cryptic column names. SQL lets you clean house with ALTER TABLE.

SQL
ALTER TABLE public.kelurahan
  RENAME COLUMN giskemen_2
  TO nama_desa;
PLAIN ENGLISH

Go to the “kelurahan” table…

Find the cryptic column “giskemen_2”…

Rename it to “nama_desa” (village name) — so humans can read it.

Step 3: Managing Primary Keys

Sometimes you need to restructure the identity of a table — change which column serves as the unique identifier.

SQL
-- Step A: Remove old primary key
ALTER TABLE desa_batam
  DROP CONSTRAINT id;

-- Step B: Rename column to something clear
ALTER TABLE desa_batam
  RENAME COLUMN giskemen_4 TO id;

-- Step C: Set new primary key
ALTER TABLE desa_batam
  ADD PRIMARY KEY (id);
PLAIN ENGLISH

A: Remove the old primary key constraint…

B: Rename the cryptic “giskemen_4” column to “id”…

C: Declare this renamed column as the new primary key.

Like relabeling the filing system and assigning a new master index.

Step 4: SELECT — Asking Questions

SELECT is the most-used SQL command. It retrieves data that matches your criteria.

SQL
-- Find all hospitals in the data
SELECT nama, jenis, alamat
FROM fasilitas_kesehatan
WHERE jenis = 'Rumah Sakit';

-- Count facilities per type
SELECT jenis, COUNT(*) AS jumlah
FROM fasilitas_kesehatan
GROUP BY jenis
ORDER BY jumlah DESC;
PLAIN ENGLISH

Query 1: Show me the name, type, and address of every facility that is a hospital (“Rumah Sakit”).

Query 2: Count how many facilities exist for each type…

…group them by type…

…and sort from most to least.

Step 5: JOINs — Combining Tables

JOINs are where relational databases shine — combining data from multiple tables.

SQL
SELECT
  k.nama_desa,
  k.jumlah_penduduk,
  f.nama AS fasilitas_terdekat
FROM kelurahan k
JOIN fasilitas_kesehatan f
  ON ST_DWithin(
    k.geom, f.geom, 5000
  );
PLAIN ENGLISH

Show me village name, population, and nearest health facility…

Combine the kelurahan table with the health facilities table…

…where the village geometry is within 5,000 meters of a facility.

This is a spatial join — connecting tables by location instead of a shared ID.

💡
Spatial JOINs Are the Superpower

Regular JOINs match rows by shared column values (like matching IDs). Spatial JOINs match rows by geographic proximity — “find all facilities within 5km of each village.” This is what makes PostGIS extraordinary.

Step 6: Views — Saved Queries

A View is a query saved as a virtual table. Every time you open it, the database re-runs the query with latest data.

SQL
CREATE VIEW TestView AS
SELECT * FROM kelurahan
WHERE ST_Touches(
  kelurahan.geom,
  (SELECT geom FROM kelurahan
   WHERE nama_desa = 'SADAI')
);
PLAIN ENGLISH

Save this query as a reusable “view” called TestView…

Whenever someone opens it, automatically show all sub-districts adjacent to SADAI…

If boundaries change, the view updates automatically.

Practice: Choose the Right SQL

Task

You imported government data with a column called “kol_23”. You want to rename it to “population”.

Which SQL command?

Why create a VIEW instead of a new table with SELECT...INTO?

Task

You need to know how many villages exist in each district. The table has columns: village_name, district_name.

Which query answers this?

Tutorial Reference 04

Spatial SQL with PostGIS

PostGIS adds geographic superpowers to SQL. Now your queries can answer: “what’s nearby?”, “what borders what?”, and “how far apart?”

Finding Neighbors: ST_Touches

The training’s first spatial query finds all sub-districts adjacent to a specific area — like asking “who lives next door?”

SQL
SELECT * INTO qlayer
FROM kelurahan
WHERE ST_Touches(
  kelurahan.geometry,
  (SELECT geometry
   FROM kelurahan
   WHERE nama_desa = 'SADAI')
)
PLAIN ENGLISH

Create a new layer called “qlayer”…

…with all sub-districts whose boundary physically touches

…the boundary of the sub-district named “SADAI”.

The inner SELECT fetches SADAI’s geometry; the outer query finds everything touching it.

Measuring Distance: ST_Distance & ST_DWithin

Two essential spatial functions for proximity analysis:

SQL
-- How far is each village from the
-- nearest hospital? (in meters)
SELECT
  v.nama_desa,
  MIN(ST_Distance(
    v.geom, h.geom
  )) AS jarak_m
FROM kelurahan v, rumah_sakit h
GROUP BY v.nama_desa
ORDER BY jarak_m DESC;
PLAIN ENGLISH

For each village, calculate the distance to every hospital…

…then keep only the minimum (nearest) distance.

Sort results so the most remote villages appear first.

This reveals underserved areas — villages farthest from healthcare.

SQL
-- Find all schools within 2km of a road
SELECT s.nama, s.jenis
FROM sekolah s, jalan j
WHERE ST_DWithin(
  s.geom, j.geom, 2000
);
PLAIN ENGLISH

Find every school whose geometry is within 2,000 meters of any road…

ST_DWithin is faster than calculating ST_Distance and filtering — it uses a spatial index.

Think of it as: “draw a 2km buffer around the road and check what’s inside.”

Containment: ST_Contains & ST_Within

SQL
-- Count hospitals per district
SELECT
  d.nama_kecamatan,
  COUNT(h.id) AS jumlah_rs
FROM kecamatan d
LEFT JOIN rumah_sakit h
  ON ST_Contains(d.geom, h.geom)
GROUP BY d.nama_kecamatan
ORDER BY jumlah_rs DESC;
PLAIN ENGLISH

For each district polygon, count how many hospital points fall inside it.

LEFT JOIN ensures districts with zero hospitals still appear (with count 0).

ST_Contains checks: “does this polygon completely contain that point?”

Sort from most hospitals to fewest — revealing healthcare distribution.

Creating Buffers: ST_Buffer

SQL
-- Create 500m buffer around rivers
SELECT
  nama_sungai,
  ST_Buffer(geom, 500) AS geom
INTO sempadan_sungai
FROM sungai;

-- Count houses in the flood plain
SELECT COUNT(*) AS rumah_di_sempadan
FROM rumah r, sempadan_sungai s
WHERE ST_Within(r.geom, s.geom);
PLAIN ENGLISH

Query 1: Draw a 500-meter zone around every river. Save these zones as a new table called “sempadan_sungai” (river buffer/floodplain).

Query 2: Count how many houses fall inside those flood zones.

This is from the training’s case study: “counting houses in the river floodplain.”

Real-world use: disaster risk assessment and land-use regulation.

Area & Length Calculations

SQL
-- Calculate area of each district in km²
SELECT
  nama_kecamatan,
  ST_Area(geom) / 1000000 AS area_km2
FROM kecamatan
ORDER BY area_km2 DESC;

-- Calculate road length per type
SELECT
  road_type,
  SUM(ST_Length(geom)) / 1000
    AS total_km
FROM jalan
GROUP BY road_type;
PLAIN ENGLISH

Query 1: Calculate each district’s area in square meters, divide by 1,000,000 to get km².

Sort largest first — useful for density calculations.

Query 2: Sum up all road lengths per type (highway, secondary, etc.), convert to km.

Important: these work correctly only in a projected CRS (like UTM) that uses meters!

PostGIS Function Reference

Here’s your quick-lookup card for the most important PostGIS spatial functions:

FunctionWhat It DoesReturns
ST_Touches(A, B)Do A and B share a boundary?true / false
ST_Intersects(A, B)Do A and B overlap at all?true / false
ST_Contains(A, B)Is B completely inside A?true / false
ST_Within(A, B)Is A completely inside B? (reverse of Contains)true / false
ST_DWithin(A, B, d)Are A and B within distance d? (uses spatial index — fast!)true / false
ST_Distance(A, B)Shortest distance between A and Bnumber (meters in UTM)
ST_Buffer(A, d)Create a zone of distance d around Apolygon geometry
ST_Area(A)Calculate area of polygon Anumber (m² in UTM)
ST_Length(A)Calculate length of line Anumber (meters in UTM)
ST_Centroid(A)Center point of Apoint geometry
ST_Union(A, B)Merge geometries into onegeometry
ST_Intersection(A, B)Area shared by both A and Bgeometry
ST_Difference(A, B)Part of A not overlapping Bgeometry
ST_Transform(A, srid)Reproject geometry to a different CRSgeometry

Practice: Spatial SQL Challenges

Scenario

A flood hit district SADAI. You need to warn all adjacent districts.

Which function finds adjacent districts?

Scenario

A city planner needs all roads within 1km of a school for a “slow zone” regulation.

Which approach works?

Scenario

How many houses are within 200m of a river? You have tables: “rumah” (houses) and “sungai” (rivers).

Write the logic:

How-To 05

How-To: Build a Health Facility Database

Follow this recipe to design, build, and populate a real spatial database for service area analysis — from ER diagram to working PostGIS tables.

The Problem

A health department needs to know: How many people live within reach of each clinic? Which areas are underserved?

HospitalsRumah Sakit, Puskesmas, Posyandu, Rumah Bersalin
Admin boundsDistrict and sub-district polygons
RoadsRoad network for service area calculation
PopulationCensus counts + WorldPop density raster

Step 1: Design the ER Diagram

Before writing any SQL, sketch the relationships using pgModeler:

1
Identify entities

Facilities, Districts, Roads, Population

2
Define attributes

Facility: name, type, beds, phone, geom. District: name, code, geom, population.

3
Draw relationships

Facility → District (many-to-one: many facilities per district). Road → District (many-to-many).

4
Normalize

Check each table against 1NF/2NF/3NF rules. Split multi-valued attributes.

Step 2: Create the PostGIS Database

SQL
-- Connect to PostgreSQL via pgAdmin4
-- Create database with PostGIS extension
CREATE DATABASE health_service_db;

-- Enable spatial support
\c health_service_db
CREATE EXTENSION postgis;

-- Create facilities table
CREATE TABLE fasilitas (
  id SERIAL PRIMARY KEY,
  nama VARCHAR(255),
  jenis VARCHAR(50),
  tempat_tidur INTEGER,
  kecamatan_id INTEGER,
  geom GEOMETRY(Point, 32648)
);
PLAIN ENGLISH

Create a new database and enable PostGIS…

Build a “fasilitas” table with auto-incrementing ID…

Columns for name, type, bed count, and district link…

The geom column stores points in UTM Zone 48N (EPSG:32648).

Step 3: Load Data from OpenStreetMap

Data sources from the training:

O
OpenStreetMap — Geofabrik

Download Indonesia extract from download.geofabrik.de. Contains roads, buildings, POIs as shapefiles.

K
Kemendagri ArcGIS Service

Indonesian Ministry of Interior publishes admin boundaries via REST service.

W
WorldPop

High-resolution population density raster — download for your study area.

📍
CRS Matters!

OSM data arrives in WGS 84 (EPSG:4326 — degrees). For accurate distance and area calculations, reproject to UTM Zone 48N (EPSG:32648) when loading into your database.

Step 4: Run the Service Area Analysis

1

Load
Roads + facilities in UTM

2

Network Analysis
Service Area via QGIS

3

Buffer
Zone around service lines

4

Zonal Stats
Sum population in zones

SQL
-- After service areas are computed,
-- count population per service zone
SELECT
  sa.facility_name,
  SUM(
    ST_SummaryStats(
      ST_Clip(pop.rast, sa.geom)
    )
  ).sum AS pop_served
FROM service_areas sa,
     worldpop pop
WHERE ST_Intersects(
  pop.rast, sa.geom)
GROUP BY sa.facility_name;
PLAIN ENGLISH

For each facility’s service area polygon…

Clip the WorldPop raster to just that polygon…

Sum all the pixel values (each pixel = people/km²)…

Result: estimated population served by each facility.

Practice: Database Design

Scenario

Determine which villages are within 15 minutes of a fire station.

Why use network analysis instead of a simple buffer?

Explanation 06

GIS Modeling: From Data to Decisions

Models chain multiple operations to answer complex questions — like predicting delivery times or identifying underserved populations.

The Regression Model

The training includes a delivery-time prediction model showing how GIS data feeds statistics:

MODEL
LTIME =
  +0.2663 * CARVOLUME
  +0.6984 * LLENGTH
  +0.0203 * LPOP
  +0.0605 * TWOWAY
  +0.1681 * SCHOOL
  +0.0317 * RESIDENTIAL
  -0.5497
PLAIN ENGLISH

Delivery time depends on: traffic volume (0.27), route length (0.70 — strongest), population (0.02), two-way roads (0.06), schools (0.17 — slow zones), residential areas (0.03).

Each variable comes from a GIS layer. GIS turns geographic features into numbers that feed regression models.

Check Your Understanding

How do you calculate population inside a service area polygon?

Tutorial Reference 07

Geoprocessing Operations

The core toolkit of GIS — filter, dissolve, reclassify, analyze terrain, and create density maps.

Feature Selection: Extracting Villages

The training extracts village locations from a massive OpenStreetMap dataset for protected area monitoring.

1
Open osm_points.shp

Thousands of points — restaurants, ATMs, villages, everything.

2
Open Attribute Table

Right-click → Open Attribute Table. Find the “place” column.

3
Select by expression

Type: "place" = 'village'

4
Save selected features

Right-click → Save As. Check “Save only selected features”. Change CRS to UTM Zone 48 (EPSG:32648).

Dissolve: Merging Districts into Provinces

Dissolve merges polygons by attribute. The training uses Laos boundaries (gadm36_LAO_2.shp):

1

Load gadm36_LAO_2.shp
(district boundaries)

2

Vector → Geoprocessing → Dissolve
Field: NAME_1

Province-level polygons
Shared boundaries removed

Terrain Analysis: Slope & Hillshade

The training covers DEM-derived analyses using the Processing Toolbox:

Slope

First derivative of the DEM — rate of elevation change. Shows how steep the terrain is at each pixel. Essential for landslide risk and road planning.

🌅

Hillshade

Simulates sunlight and shadow on terrain. Overlaid semi-transparently on a DEM, it creates a 3D-like effect. Use Multiply blending + 50% transparency.

📈

Reclassify

Group continuous values into classes. E.g., elevation: <1000m (low), 1000-2000m (mid), >2000m (high). Uses r.reclass in the Processing Toolbox.

Square Pixels Required!

Terrain algorithms assume square pixels. If your raster has non-square pixels, re-export it with equal X/Y resolution (e.g., 30m × 30m) before running slope or hillshade. Right-click → Save As → set pixel size.

Density Analysis: Heatmaps

When you have thousands of points (noise complaints, crime locations, facility positions), heatmaps reveal patterns invisible in the raw data.

1
Set search radius

For density per km²: r = √(1,000,000 / π) ≈ 564m. Larger radius = smoother; smaller = more detail.

2
Choose kernel shape

Quartic (default), triangular, Epanechnikov. Quartic is standard for crime/health analysis.

3
Set pixel size

Balance quality vs. speed. Aim for 10-100 cells per unit area (search radius area).

4
Optional: Weight by attribute

Weight schools by student count, or facilities by capacity. Changes from “density of locations” to “density of service.”

Geoprocessing Reference

OperationInputResultUse Case
Select by expressionLayer + expressionSubset of featuresExtract villages from OSM
DissolvePolygons + attributeMerged polygonsDistricts → provinces
BufferFeatures + distanceZone polygons500m zone around rivers
ClipLayer + clip layerCropped to boundaryCut raster to study area
Extract extentLayerBounding box polygonDefine study area limits
SlopeDEM rasterSlope raster (degrees)Landslide risk assessment
HillshadeDEM rasterShadow relief raster3D visualization effect
ReclassifyRaster + rulesClassified rasterElevation into 3 classes
HeatmapPoint layer + radiusDensity rasterCrime or noise hotspots
Zonal statisticsRaster + polygonsStats per polygonPopulation per district

Practice: Geoprocessing

Scenario

500 sub-districts, boss wants 34 provinces. Data has a “province_name” column.

Which operation combines sub-districts into provinces?

What happens when you increase the heatmap search radius?

Explanation How-To 08

Sharing Maps with the World: WebGIS

Desktop GIS is powerful, but the web makes your maps accessible to everyone with a browser.

How WebGIS Works

0 / 6

OGC Standards

🖼

WMS

Web Map Service — returns images. Fast but no attribute queries.

📄

WFS

Web Feature Service — returns actual data. Click-to-query works.

WMTS

Web Map Tile Service — pre-cached tiles. Fastest option.

🌐

WCS

Web Coverage Service — raw raster data for analysis.

Deploying GeoServer

XML
<multipart-config>
  <!-- Increase upload limit -->
  <max-file-size>
    183886080
  </max-file-size>
  <max-request-size>
    183886080
  </max-request-size>
</multipart-config>
PLAIN ENGLISH

In Tomcat’s web.xml, increase the upload limit to ~175MB…

…because the GeoServer WAR file exceeds the default ~80MB limit.

Without this, deployment fails with “file too large” error.

Check Your Understanding

Scenario

Users click hospitals on a web map and see name, bed count, phone.

WMS or WFS for the hospital layer?

Tutorial 09

Making Beautiful Maps with QGIS

Data collection is half the work. The other half is presenting it so clearly that the map speaks for itself.

Layer Organization

Think of layers like transparencies stacked on a projector — order matters.

Top: Points

Hospitals, schools, villages — small features visible above everything.

Middle: Lines

Roads, rivers — the map’s skeleton.

Bottom: Polygons & Rasters

Land use, elevation — the background.

The Seven Renderers

Single Symbol

One uniform style for all features. Simplest renderer.

🎨

Categorized

Different colors per category. Land use: forest=green, water=blue.

📈

Graduated

Colors scale with a numeric value. Creates choropleth maps.

🔧

Rule-Based

Maximum flexibility — custom expressions. “If highway AND lanes>2, thick red.”

Point Displacement

Spreads overlapping points so all are visible.

Inverted Polygons

Styles the outside of polygons — darken everything except your study area.

🔥

Heatmap Renderer

Point density as continuous surface. Dense = hot (red), sparse = cool.

Tutorial: Graduated Renderer

Create a population map where bigger dots = more people:

1
Open Layer Properties → Symbology

Double-click the villages layer.

2
Set renderer to Graduated

Select the “pop” column. Method: Size.

3
Choose classification mode

Natural Breaks (Jenks) for most maps. Equal Interval if data is evenly distributed. 5-7 classes recommended.

4
Click Classify, then OK

QGIS creates size classes automatically. Adjust manually if needed.

💡
Classification Methods Matter

Equal Interval: equal-width ranges (0-20, 20-40). Quantile: equal number of features per class. Natural Breaks: clusters similar values. Std Deviation: shows variation from the mean. Choose based on what story you want to tell.

Tutorial: Heatmap Renderer

The training overlays a heatmap of villages on Hin Nam No National Park:

1
Set renderer to Heatmap

Select the villages_utm layer.

2
Choose color ramp: OrRd

Orange-to-Red preset. Edit or create custom ramps if needed.

3
Set radius

Controls search area. Bigger radius = smoother. Units: pixels, mm, or map units.

4
Optional: Weight by field

Weight by population to show “density of people” instead of “density of villages.”

Labeling: Making Maps Readable

Labels turn data into information. Without them, polygons are just colored shapes.

TextFont, size, color, bold/italic. Use readable fonts at appropriate sizes.
BufferHalo around text for readability. White buffer, 1mm, round joins.
PlacementPoint labels: offset from marker. Line labels: follow the road curve.
Scale rulesShow labels only at certain zoom levels. Max scale 1:10000 = visible only when zoomed in.
ExpressionsCombine fields: “name” || ’\n’ || “Line” creates multi-line labels.

Raster Styling: DEM + Hillshade

The training creates a stunning terrain visualization by combining two techniques:

1
Style the DEM as pseudocolor

Renderer: Singleband pseudocolor. Color ramp: “elevation” from cpt-city topography group. Mode: Continuous.

2
Place hillshade above DEM

Drag hillshade layer above the DEM in the layer panel.

3
Set blending: Multiply + 50% transparency

In hillshade properties: Layer transparency = 50%, Blending mode = Multiply. This creates a semi-3D effect without washing out the DEM colors.

Practice: Visualization

Scenario

Darker colors = higher population density across districts.

Which renderer?

Scenario

Highways = thick red, secondary = thin gray, unpaved = dashed.

Which renderer for this level of control?

Reference 10

SQL & PostGIS Quick Reference

Your cheat sheet — keep this open while working in pgAdmin or QGIS DB Manager.

SQL Command Reference

CommandSyntaxWhat It Does
Create tableCREATE TABLE t AS SELECT ... FROM ...New table from query results
Rename columnALTER TABLE t RENAME COLUMN a TO bChange column name
Add columnALTER TABLE t ADD COLUMN c TYPEAdd new column
Set primary keyALTER TABLE t ADD PRIMARY KEY (id)Declare unique identifier
Drop constraintALTER TABLE t DROP CONSTRAINT nameRemove a constraint
Select + filterSELECT cols FROM t WHERE conditionQuery rows matching criteria
AggregateSELECT col, COUNT(*) FROM t GROUP BY colSummarize per group
SortORDER BY col ASC|DESCSort results
Join tablesSELECT ... FROM a JOIN b ON a.id = b.idCombine related tables
Create viewCREATE VIEW v AS SELECT ...Saved query (auto-updates)

PostGIS Spatial Functions

FunctionReturnsUse Case
ST_Touches(A, B)boolAdjacent districts
ST_Intersects(A, B)boolAny overlap
ST_Contains(A, B)boolPoints inside polygons
ST_Within(A, B)boolReverse of Contains
ST_DWithin(A, B, d)boolFast proximity check
ST_Distance(A, B)metersMeasure distance
ST_Buffer(A, d)geomCreate zone around feature
ST_Area(A)Polygon area
ST_Length(A)metersLine length
ST_Centroid(A)pointCenter of geometry
ST_Union(A, B)geomMerge geometries
ST_Intersection(A, B)geomShared area
ST_Difference(A, B)geomA minus B overlap
ST_Transform(A, srid)geomReproject to different CRS

Common CRS Codes

EPSG CodeNameUnitsWhen to Use
4326WGS 84DegreesGPS coordinates, OpenStreetMap data, web maps
3857Web MercatorMetersGoogle Maps, Bing, web tile services
32648UTM Zone 48NMetersBatam, Indonesia — accurate distances/areas

Congratulations!

You’ve completed the GIS Analyst Training course — from database design through spatial SQL, geoprocessing, web mapping, and cartographic visualization.

What’s Next?

✓ Practice with real OSM datasets
✓ Build a PostGIS database for your study area
✓ Publish a web map with GeoServer
✓ Prepare for the GIS Analyst certification exam

Built from training materials by Firman Hadi
Geomatics Engineering, Politeknik Negeri Batam