common module¶
The common module contains common functions and classes used by the other modules.
check_qgis()
¶
Check if QGIS is available and raise an error if not.
Exceptions:
| Type | Description |
|---|---|
ImportError |
If QGIS libraries are not available. |
Source code in qgis_map/common.py
def check_qgis() -> None:
"""Check if QGIS is available and raise an error if not.
Raises:
ImportError: If QGIS libraries are not available.
"""
if not is_qgis_available():
raise ImportError(
"QGIS libraries are not available. "
"Please run this code within QGIS or install PyQGIS."
)
download_file(url, output_path=None, overwrite=False, **kwargs)
¶
Download a file from a URL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url |
str |
The URL to download from. |
required |
output_path |
Optional[str] |
The output file path. If None, uses a temp file. |
None |
overwrite |
bool |
Whether to overwrite existing files. Defaults to False. |
False |
**kwargs |
Additional keyword arguments for urllib.request.urlretrieve. |
{} |
Returns:
| Type | Description |
|---|---|
str |
The path to the downloaded file. |
Exceptions:
| Type | Description |
|---|---|
Exception |
If the download fails. |
Source code in qgis_map/common.py
def download_file(
url: str,
output_path: Optional[str] = None,
overwrite: bool = False,
**kwargs,
) -> str:
"""Download a file from a URL.
Args:
url: The URL to download from.
output_path: The output file path. If None, uses a temp file.
overwrite: Whether to overwrite existing files. Defaults to False.
**kwargs: Additional keyword arguments for urllib.request.urlretrieve.
Returns:
The path to the downloaded file.
Raises:
Exception: If the download fails.
"""
import urllib.request
import tempfile
if output_path is None:
suffix = os.path.splitext(url.split("?")[0])[1]
with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp:
output_path = tmp.name
if os.path.exists(output_path) and not overwrite:
return output_path
try:
urllib.request.urlretrieve(url, output_path)
return output_path
except Exception as e:
raise Exception(f"Failed to download {url}: {e}")
get_color_ramp(name, n_colors=5, reverse=False)
¶
Get QGIS color ramp by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name |
str |
Color ramp name (e.g., "Spectral", "YlOrRd", "RdYlGn"). |
required |
n_colors |
int |
Number of colors in the ramp. Defaults to 5. |
5 |
reverse |
bool |
Whether to reverse the color ramp. Defaults to False. |
False |
Returns:
| Type | Description |
|---|---|
Any |
QgsColorRamp object, or None if not available. |
Exceptions:
| Type | Description |
|---|---|
ImportError |
If QGIS is not available. |
Source code in qgis_map/common.py
def get_color_ramp(
name: str,
n_colors: int = 5,
reverse: bool = False,
) -> Any:
"""Get QGIS color ramp by name.
Args:
name: Color ramp name (e.g., "Spectral", "YlOrRd", "RdYlGn").
n_colors: Number of colors in the ramp. Defaults to 5.
reverse: Whether to reverse the color ramp. Defaults to False.
Returns:
QgsColorRamp object, or None if not available.
Raises:
ImportError: If QGIS is not available.
"""
try:
from qgis.core import QgsStyle, QgsGradientColorRamp, QgsColorRampShader
except ImportError:
raise ImportError("QGIS libraries required for color ramps")
# Get default style
style = QgsStyle.defaultStyle()
# Try to get color ramp by name
color_ramp = style.colorRamp(name)
if color_ramp is None:
# If not found, try common variations
variations = [
name,
name.lower(),
name.upper(),
name.title(),
]
for variant in variations:
color_ramp = style.colorRamp(variant)
if color_ramp:
break
# If still not found, return a default gradient
if color_ramp is None:
print(f"Color ramp '{name}' not found, using default gradient")
color_ramp = QgsGradientColorRamp()
# Reverse if requested
if reverse and hasattr(color_ramp, "invert"):
color_ramp.invert()
return color_ramp
get_file_extension(filepath)
¶
Get the file extension from a filepath.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath |
str |
The file path. |
required |
Returns:
| Type | Description |
|---|---|
str |
The file extension (lowercase, without the dot). |
Source code in qgis_map/common.py
def get_file_extension(filepath: str) -> str:
"""Get the file extension from a filepath.
Args:
filepath: The file path.
Returns:
The file extension (lowercase, without the dot).
"""
return os.path.splitext(filepath)[1].lower().lstrip(".")
get_sample_data(name='countries')
¶
Get a path to sample data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name |
str |
The name of the sample dataset. Options: - "countries": Natural Earth countries - "cities": Natural Earth populated places - "rivers": Natural Earth rivers |
'countries' |
Returns:
| Type | Description |
|---|---|
str |
The path to the sample data file. |
Source code in qgis_map/common.py
def get_sample_data(name: str = "countries") -> str:
"""Get a path to sample data.
Args:
name: The name of the sample dataset. Options:
- "countries": Natural Earth countries
- "cities": Natural Earth populated places
- "rivers": Natural Earth rivers
Returns:
The path to the sample data file.
"""
samples = {
"countries": "https://raw.githubusercontent.com/nvkelso/natural-earth-vector/master/geojson/ne_110m_admin_0_countries.geojson",
"cities": "https://raw.githubusercontent.com/nvkelso/natural-earth-vector/master/geojson/ne_110m_populated_places.geojson",
"rivers": "https://raw.githubusercontent.com/nvkelso/natural-earth-vector/master/geojson/ne_110m_rivers_lake_centerlines.geojson",
}
if name not in samples:
raise ValueError(
f"Unknown sample data: {name}. Options: {list(samples.keys())}"
)
url = samples[name]
return download_file(url)
hello_world()
¶
Prints "Hello World!" to the console.
Source code in qgis_map/common.py
def hello_world():
"""Prints "Hello World!" to the console."""
print("Hello World!")
hex_to_rgb(hex_color)
¶
Convert a hex color string to RGB tuple.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
hex_color |
str |
A hex color string (e.g., "#ff0000" or "ff0000"). |
required |
Returns:
| Type | Description |
|---|---|
Tuple[int, int, int] |
A tuple of (R, G, B) values. |
Source code in qgis_map/common.py
def hex_to_rgb(hex_color: str) -> Tuple[int, int, int]:
"""Convert a hex color string to RGB tuple.
Args:
hex_color: A hex color string (e.g., "#ff0000" or "ff0000").
Returns:
A tuple of (R, G, B) values.
"""
hex_color = hex_color.lstrip("#")
if len(hex_color) != 6:
raise ValueError(
f"Invalid hex color '{hex_color}': expected 6 hexadecimal characters."
)
if not all(c in "0123456789abcdefABCDEF" for c in hex_color):
raise ValueError(
f"Invalid hex color '{hex_color}': contains non-hexadecimal characters."
)
return tuple(int(hex_color[i : i + 2], 16) for i in (0, 2, 4))
is_qgis_available()
¶
Check if QGIS libraries are available.
Returns:
| Type | Description |
|---|---|
bool |
True if QGIS is available, False otherwise. |
Source code in qgis_map/common.py
def is_qgis_available() -> bool:
"""Check if QGIS libraries are available.
Returns:
True if QGIS is available, False otherwise.
"""
try:
from qgis.core import QgsApplication
return True
except ImportError:
return False
is_raster_file(filepath)
¶
Check if a file is a raster format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath |
str |
The file path. |
required |
Returns:
| Type | Description |
|---|---|
bool |
True if the file is a raster format, False otherwise. |
Source code in qgis_map/common.py
def is_raster_file(filepath: str) -> bool:
"""Check if a file is a raster format.
Args:
filepath: The file path.
Returns:
True if the file is a raster format, False otherwise.
"""
raster_extensions = {
"tif",
"tiff",
"geotiff",
"img",
"jp2",
"png",
"jpg",
"jpeg",
"gif",
"bmp",
"ecw",
"sid",
"nc",
"hdf",
"hdf4",
"hdf5",
"grd",
"asc",
"dem",
"dt0",
"dt1",
"dt2",
"vrt",
}
return get_file_extension(filepath) in raster_extensions
is_vector_file(filepath)
¶
Check if a file is a vector format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath |
str |
The file path. |
required |
Returns:
| Type | Description |
|---|---|
bool |
True if the file is a vector format, False otherwise. |
Source code in qgis_map/common.py
def is_vector_file(filepath: str) -> bool:
"""Check if a file is a vector format.
Args:
filepath: The file path.
Returns:
True if the file is a vector format, False otherwise.
"""
vector_extensions = {
"shp",
"geojson",
"json",
"gpkg",
"kml",
"kmz",
"gml",
"tab",
"mif",
"mid",
"dgn",
"dxf",
"dwg",
"gpx",
"csv",
"xlsx",
"xls",
"ods",
"parquet",
"feather",
"gdb",
}
return get_file_extension(filepath) in vector_extensions
parse_point_data(data, x, y, encoding='utf-8')
¶
Parse CSV file or DataFrame to extract coordinates and attributes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data |
Union[str, Any] |
Path to CSV file or pandas DataFrame. |
required |
x |
str |
Column name for x-coordinate (longitude). |
required |
y |
str |
Column name for y-coordinate (latitude). |
required |
encoding |
str |
Encoding for CSV file. Defaults to "utf-8". |
'utf-8' |
Returns:
| Type | Description |
|---|---|
Tuple[Any, List[str]] |
A tuple of (DataFrame, list of attribute column names). |
Exceptions:
| Type | Description |
|---|---|
ImportError |
If pandas is not available. |
FileNotFoundError |
If CSV file doesn't exist. |
ValueError |
If required columns are not found. |
Source code in qgis_map/common.py
def parse_point_data(
data: Union[str, Any],
x: str,
y: str,
encoding: str = "utf-8",
) -> Tuple[Any, List[str]]:
"""Parse CSV file or DataFrame to extract coordinates and attributes.
Args:
data: Path to CSV file or pandas DataFrame.
x: Column name for x-coordinate (longitude).
y: Column name for y-coordinate (latitude).
encoding: Encoding for CSV file. Defaults to "utf-8".
Returns:
A tuple of (DataFrame, list of attribute column names).
Raises:
ImportError: If pandas is not available.
FileNotFoundError: If CSV file doesn't exist.
ValueError: If required columns are not found.
"""
try:
import pandas as pd
except ImportError:
raise ImportError("pandas is required for parsing point data")
# Load data
if isinstance(data, str):
if not os.path.exists(data):
raise FileNotFoundError(f"File not found: {data}")
df = pd.read_csv(data, encoding=encoding)
else:
df = data
# Validate required columns
if x not in df.columns:
raise ValueError(
f"Column '{x}' not found in data. Available: {list(df.columns)}"
)
if y not in df.columns:
raise ValueError(
f"Column '{y}' not found in data. Available: {list(df.columns)}"
)
# Get attribute columns (all except x and y)
attr_columns = [col for col in df.columns if col not in [x, y]]
return df, attr_columns
random_string(length=8)
¶
Generate a random string of specified length.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
length |
int |
The length of the random string. Defaults to 8. |
8 |
Returns:
| Type | Description |
|---|---|
str |
A random string. |
Source code in qgis_map/common.py
def random_string(length: int = 8) -> str:
"""Generate a random string of specified length.
Args:
length: The length of the random string. Defaults to 8.
Returns:
A random string.
"""
import random
import string
return "".join(random.choices(string.ascii_lowercase + string.digits, k=length))
rgb_to_hex(r, g, b)
¶
Convert RGB values to a hex color string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
r |
int |
Red component (0-255). |
required |
g |
int |
Green component (0-255). |
required |
b |
int |
Blue component (0-255). |
required |
Returns:
| Type | Description |
|---|---|
str |
A hex color string (e.g., "#ff0000"). |
Source code in qgis_map/common.py
def rgb_to_hex(r: int, g: int, b: int) -> str:
"""Convert RGB values to a hex color string.
Args:
r: Red component (0-255).
g: Green component (0-255).
b: Blue component (0-255).
Returns:
A hex color string (e.g., "#ff0000").
"""
return "#{:02x}{:02x}{:02x}".format(r, g, b)