GeoMaster
Comprehensive geospatial science skill covering GIS, remote sensing, spatial analysis, and ML for Earth observation across 70+ topics with 500+ code examples in 8 programming languages.
Installation
# Core Python stack (conda recommended)
conda install -c conda-forge gdal rasterio fiona shapely pyproj geopandas
# Remote sensing & ML
uv pip install rsgislib torchgeo earthengine-api
uv pip install scikit-learn xgboost torch-geometric
# Network & visualization
uv pip install osmnx networkx folium keplergl
uv pip install cartopy contextily mapclassify
# Big data & cloud
uv pip install xarray rioxarray dask-geopandas
uv pip install pystac-client planetary-computer
# Point clouds
uv pip install laspy pylas open3d pdal
# Databases
conda install -c conda-forge postgis spatialite
Quick Start
NDVI from Sentinel-2
import rasterio
import numpy as np
with rasterio.open('sentinel2.tif') as src:
red = src.read(4).astype(float) # B04
nir = src.read(8).astype(float) # B08
ndvi = (nir - red) / (nir + red + 1e-8)
ndvi = np.nan_to_num(ndvi, nan=0)
profile = src.profile
profile.update(count=1, dtype=rasterio.float32)
with rasterio.open('ndvi.tif', 'w', **profile) as dst:
dst.write(ndvi.astype(rasterio.float32), 1)
Spatial Analysis with GeoPandas
import geopandas as gpd
# Load and ensure same CRS
zones = gpd.read_file('zones.geojson')
points = gpd.read_file('points.geojson')
if zones.crs != points.crs:
points = points.to_crs(zones.crs)
# Spatial join and statistics
joined = gpd.sjoin(points, zones, how='inner', predicate='within')
stats = joined.groupby('zone_id').agg({
'value': ['count', 'mean', 'std', 'min', 'max']
}).round(2)
Google Earth Engine Time Series
import ee
import pandas as pd
ee.Initialize(project='your-project')
roi = ee.Geometry.Point([-122.4, 37.7]).buffer(10000)
s2 = (ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
.filterBounds(roi)
.filterDate('2020-01-01', '2023-12-31')
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)))
def add_ndvi(img):
return img.addBands(img.normalizedDifference(['B8', 'B4']).rename('NDVI'))
s2_ndvi = s2.map(add_ndvi)
def extract_series(image):
stats = image.reduceRegion(ee.Reducer.mean(), roi.centroid(), scale=10, maxPixels=1e9)
return ee.Feature(None, {'date': image.date().format('YYYY-MM-dd'), 'ndvi': stats.get('NDVI')})
series = s2_ndvi.map(extract_series).getInfo()
df = pd.DataFrame([f['properties'] for f in series['features']])
df['date'] = pd.to_datetime(df['date'])
Core Concepts
Data Types
| Type |
Examples |
Libraries |
| Vector |
Shapefile, GeoJSON, GeoPackage |
GeoPandas, Fiona, GDAL |
| Raster |
GeoTIFF, NetCDF, COG |
Rasterio, Xarray, GDAL |
| Point Cloud |
LAS, LAZ |
Laspy, PDAL, Open3D |
Coordinate Systems
- EPSG:4326 (WGS 84) - Geographic, lat/lon, use for storage
- EPSG:3857 (Web Mercator) - Web maps only (don't use for area/distance!)
- EPSG:326xx/327xx (UTM) - Metric calculations, <1% distortion per zone
- Use
gdf.estimate_utm_crs() for automatic UTM detection
# Always check CRS before operations
assert gdf1.crs == gdf2.crs, "CRS mismatch!"
# For area/distance calculations, use projected CRS
gdf_metric = gdf.to_crs(gdf.estimate_utm_crs())
area_sqm = gdf_metric.geometry.area
OGC Standards
- WMS: Web Map Service - raster maps
- WFS: Web Feature Service - vector data
- WCS: Web Coverage Service - raster coverage
- STAC: Spatiotemporal Asset Catalog - modern metadata
Common Operations
Spectral Indices
def calculate_indices(image_path):
"""NDVI, EVI, SAVI, NDWI from Sentinel-2."""
with rasterio.open(image_path) as src:
B02, B03, B04, B08, B11 = [src.read(i).astype(float) for i in [1,2,3,4,5]]
ndvi = (B08 - B04) / (B08 + B04 + 1e-8)
evi = 2.5 * (B08 - B04) / (B08 + 6*B04 - 7.5*B02 + 1)
savi = ((B08 - B04) / (B08 + B04 + 0.5)) * 1.5
ndwi = (B03 - B08) / (B03 + B08 + 1e-8)
return {'NDVI': ndvi, 'EVI': evi, 'SAVI': savi, 'NDWI': ndwi}
Vector Operations
# Buffer (use projected CRS!)
gdf_proj = gdf.to_crs(gdf.estimate_utm_crs())
gdf['buffer_1km'] = gdf_proj.geometry.buffer(1000)
# Spatial relationships
intersects = gdf[gdf.geometry.intersects(other_geometry)]
contains = gdf[gdf.geometry.contains(point_geometry)]
# Geometric operations
gdf['centroid'] = gdf.geometry.centroid
gdf['simplified'] = gdf.geometry.simplify(tolerance=0.001)
# Overlay operations
intersection = gpd.overlay(gdf1, gdf2, how='intersection')
union = gpd.overlay(gdf1, gdf2, how='union')
Terrain Analysis
def terrain_metrics(dem_path):
"""Calculate slope, aspect, hillshade from DEM."""
with rasterio.open(dem_path) as src:
dem = src.read(1)
dy, dx = np.gradient(dem)
slope = np.arctan(np.sqrt(dx**2 + dy**2)) * 180 / np.pi
aspect = (90 - np.arctan2(-dy, dx) * 180 / np.pi) % 360
# Hillshade
az_rad, alt_rad = np.radians(315), np.radians(45)
hillshade = (np.sin(alt_rad) * np.sin(np.radians(slope)) +
np.cos(alt_rad) * np.cos(np.radians(slope)) *
np.cos(np.radians(aspect) - az_rad))
return slope, aspect, hillshade
Network Analysis
import osmnx as ox
import networkx as nx
# Download and analyze street network
G = ox.graph_from_place('San Francisco, CA', network_type='drive')
G = ox.add_edge_speeds(G).add_edge_travel_times(G)
# Shortest path
orig = ox.distance.nearest_nodes(G, -122.4, 37.7)
dest = ox.distance.nearest_nodes(G, -122.3, 37.8)
route = nx.shortest_path(G, orig, dest, weight='travel_time')
Image Classification
from sklearn.ensemble import RandomForestClassifier
import rasterio
from rasterio.features import rasterize
def classify_imagery(raster_path, training_gdf, output_path):
"""Train RF and classify imagery."""
with rasterio.open(raster_path) as src:
image = src.read()
profile = src.profile
transform = src.transform
# Extract training data
X_train, y_train = [], []
for _, row in training_gdf.iterrows():
mask = rasterize([(row.geometry, 1)],
out_shape=(profile['height'], profile['width']),
transform=transform, fill=0, dtype=np.uint8)
pixels = image[:, mask > 0].T
X_train.extend(pixels)
y_train.extend([row['class_id']] * len(pixels))
# Train and predict
rf = RandomForestClassifier(n_estimators=100, max_depth=20, n_jobs=-1)
rf.fit(X_train, y_train)
prediction = rf.predict(image.reshape(image.shape[0], -1).T)
prediction = prediction.reshape(profile['height'], profile['width'])
profile.update(dtype=rasterio.uint8, count=1)
with rasterio.open(output_path, 'w', **profile) as dst:
dst.write(prediction.astype(rasterio.uint8), 1)
return rf
Modern Cloud-Native Workflows
STAC + Planetary Computer
import pystac_client
import planetary_computer
import odc.stac
# Search Sentinel-2 via STAC
catalog = pystac_client.Client.open(
"https://planetarycomputer.microsoft.com/api/stac/v1",
modifier=planetary_computer.sign_inplace,
)
search = catalog.search(
collections=["sentinel-2-l2a"],
bbox=[-122.5, 37.7, -122.3, 37.9],
datetime="2023-01-01/2023-12-31",
query={"eo:cloud_cover": {"lt": 20}},
)
# Load as xarray (cloud-native!)
data = odc.stac.load(
list(search.get_items())[:5],
bands=["B02", "B03", "B04", "B08"],
crs="EPSG:32610",
resolution=10,
)
# Calculate NDVI on xarray
ndvi = (data.B08 - data.B04) / (data.B08 + data.B04)
Cloud-Optimized GeoTIFF (COG)
import rasterio
from rasterio.session import AWSSession
# Read COG directly from cloud (partial reads)
session = AWSSession(aws_access_key_id=..., aws_secret_access_key=...)
with rasterio.open('s3://bucket/path.tif', session=session) as src:
# Read only window of interest
window = ((1000, 2000), (1000, 2000))
subset = src.read(1, window=window)
# Write COG
with rasterio.open('output.tif', 'w', **profile,
tiled=True, blockxsize=256, blockysize=256,
compress='DEFLATE', predictor=2) as dst:
dst.write(data)
# Validate COG
from rio_cogeo.cogeo import cog_validate
cog_validate('output.tif')
Performance Tips
# 1. Spatial indexing (10-100x faster queries)
gdf.sindex # Auto-created by GeoPandas
# 2. Chunk large rasters
with rasterio.open('large.tif') as src:
for i, window in src.block_windows(1):
block = src.read(1, window=window)
# 3. Dask for big data
import dask.array as da
dask_array = da.from_rasterio('large.tif', chunks=(1, 1024, 1024))
# 4. Use Arrow for I/O
gdf.to_file('output.gpkg', use_arrow=True)
# 5. GDAL caching
from osgeo import gdal
gdal.SetCacheMax(2**30) # 1GB cache
# 6. Parallel processing
rf = RandomForestClassifier(n_jobs=-1) # All cores
Best Practices
- Always check CRS before spatial operations
- Use projected CRS for area/distance calculations
- Validate geometries:
gdf = gdf[gdf.is_valid]
- Handle missing data:
gdf['geometry'] = gdf['geometry'].fillna(None)
- Use efficient formats: GeoPackage > Shapefile, Parquet for large data
- Apply cloud masking to optical imagery
- Preserve lineage for reproducible research
- Use appropriate resolution for your analysis scale
Detailed Documentation
- Coordinate Systems - CRS fundamentals, UTM, transformations
- Core Libraries - GDAL, Rasterio, GeoPandas, Shapely
- Remote Sensing - Satellite missions, spectral indices, SAR
- Machine Learning - Deep learning, CNNs, GNNs for RS
- GIS Software - QGIS, ArcGIS, GRASS integration
- Scientific Domains - Marine, hydrology, agriculture, forestry
- Advanced GIS - 3D GIS, spatiotemporal, topology
- Big Data - Distributed processing, GPU acceleration
- Industry Applications - Urban planning, disaster management
- Programming Languages - Python, R, Julia, JS, C++, Java, Go, Rust
- Data Sources - Satellite catalogs, APIs
- Troubleshooting - Common issues, debugging, error reference
- Code Examples - 500+ examples
GeoMaster covers everything from basic GIS operations to advanced remote sensing and machine learning.
Source: K-Dense-AI/scientific-agent-skills → skills/geomaster/SKILL.md
1---2name: geomaster3description: Comprehensive geospatial science skill covering remote sensing, GIS, spatial analysis, machine learning for earth observation, and 30+ scientific domains. Supports satellite imagery processing (Sentinel, Landsat, MODIS, SAR, hyperspectral), vector and raster data operations, spatial statistics, point cloud processing, network analysis, cloud-native workflows (STAC, COG, Planetary Computer), and 8 programming languages (Python, R, Julia, JavaScript, C++, Java, Go, Rust) with 500+ code examples. Use for remote sensing workflows, GIS analysis, spatial ML, Earth observation data processing, terrain analysis, hydrological modeling, marine spatial analysis, atmospheric science, and any geospatial computation task.4---5
6
7# GeoMaster
8
9Comprehensive geospatial science skill covering GIS, remote sensing, spatial analysis, and ML for Earth observation across 70+ topics with 500+ code examples in 8 programming languages.
10
11## Installation
12
13```bash
14# Core Python stack (conda recommended)
15conda install -c conda-forge gdal rasterio fiona shapely pyproj geopandas
16
17# Remote sensing & ML
18uv pip install rsgislib torchgeo earthengine-api
19uv pip install scikit-learn xgboost torch-geometric
20
21# Network & visualization
22uv pip install osmnx networkx folium keplergl
23uv pip install cartopy contextily mapclassify
24
25# Big data & cloud
26uv pip install xarray rioxarray dask-geopandas
27uv pip install pystac-client planetary-computer
28
29# Point clouds
30uv pip install laspy pylas open3d pdal
31
32# Databases
33conda install -c conda-forge postgis spatialite
34```
35
36## Quick Start
37
38### NDVI from Sentinel-2
39
40```python
41import rasterio
42import numpy as np
43
44with rasterio.open('sentinel2.tif') as src:
45 red = src.read(4).astype(float) # B04
46 nir = src.read(8).astype(float) # B08
47 ndvi = (nir - red) / (nir + red + 1e-8)
48 ndvi = np.nan_to_num(ndvi, nan=0)
49
50 profile = src.profile
51 profile.update(count=1, dtype=rasterio.float32)
52
53 with rasterio.open('ndvi.tif', 'w', **profile) as dst:
54 dst.write(ndvi.astype(rasterio.float32), 1)
55```
56
57### Spatial Analysis with GeoPandas
58
59```python
60import geopandas as gpd
61
62# Load and ensure same CRS
63zones = gpd.read_file('zones.geojson')
64points = gpd.read_file('points.geojson')
65
66if zones.crs != points.crs:
67 points = points.to_crs(zones.crs)
68
69# Spatial join and statistics
70joined = gpd.sjoin(points, zones, how='inner', predicate='within')
71stats = joined.groupby('zone_id').agg({
72 'value': ['count', 'mean', 'std', 'min', 'max']
73}).round(2)
74```
75
76### Google Earth Engine Time Series
77
78```python
79import ee
80import pandas as pd
81
82ee.Initialize(project='your-project')
83roi = ee.Geometry.Point([-122.4, 37.7]).buffer(10000)
84
85s2 = (ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
86 .filterBounds(roi)
87 .filterDate('2020-01-01', '2023-12-31')
88 .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)))
89
90def add_ndvi(img):
91 return img.addBands(img.normalizedDifference(['B8', 'B4']).rename('NDVI'))
92
93s2_ndvi = s2.map(add_ndvi)
94
95def extract_series(image):
96 stats = image.reduceRegion(ee.Reducer.mean(), roi.centroid(), scale=10, maxPixels=1e9)
97 return ee.Feature(None, {'date': image.date().format('YYYY-MM-dd'), 'ndvi': stats.get('NDVI')})
98
99series = s2_ndvi.map(extract_series).getInfo()
100df = pd.DataFrame([f['properties'] for f in series['features']])
101df['date'] = pd.to_datetime(df['date'])
102```
103
104## Core Concepts
105
106### Data Types
107
108| Type | Examples | Libraries |
109|------|----------|-----------|
110| Vector | Shapefile, GeoJSON, GeoPackage | GeoPandas, Fiona, GDAL |
111| Raster | GeoTIFF, NetCDF, COG | Rasterio, Xarray, GDAL |
112| Point Cloud | LAS, LAZ | Laspy, PDAL, Open3D |
113
114### Coordinate Systems
115
116- **EPSG:4326** (WGS 84) - Geographic, lat/lon, use for storage
117- **EPSG:3857** (Web Mercator) - Web maps only (don't use for area/distance!)
118- **EPSG:326xx/327xx** (UTM) - Metric calculations, <1% distortion per zone
119- Use `gdf.estimate_utm_crs()` for automatic UTM detection
120
121```python
122# Always check CRS before operations
123assert gdf1.crs == gdf2.crs, "CRS mismatch!"
124
125# For area/distance calculations, use projected CRS
126gdf_metric = gdf.to_crs(gdf.estimate_utm_crs())
127area_sqm = gdf_metric.geometry.area
128```
129
130### OGC Standards
131
132- **WMS**: Web Map Service - raster maps
133- **WFS**: Web Feature Service - vector data
134- **WCS**: Web Coverage Service - raster coverage
135- **STAC**: Spatiotemporal Asset Catalog - modern metadata
136
137## Common Operations
138
139### Spectral Indices
140
141```python
142def calculate_indices(image_path):
143 """NDVI, EVI, SAVI, NDWI from Sentinel-2."""
144 with rasterio.open(image_path) as src:
145 B02, B03, B04, B08, B11 = [src.read(i).astype(float) for i in [1,2,3,4,5]]
146
147 ndvi = (B08 - B04) / (B08 + B04 + 1e-8)
148 evi = 2.5 * (B08 - B04) / (B08 + 6*B04 - 7.5*B02 + 1)
149 savi = ((B08 - B04) / (B08 + B04 + 0.5)) * 1.5
150 ndwi = (B03 - B08) / (B03 + B08 + 1e-8)
151
152 return {'NDVI': ndvi, 'EVI': evi, 'SAVI': savi, 'NDWI': ndwi}
153```
154
155### Vector Operations
156
157```python
158# Buffer (use projected CRS!)
159gdf_proj = gdf.to_crs(gdf.estimate_utm_crs())
160gdf['buffer_1km'] = gdf_proj.geometry.buffer(1000)
161
162# Spatial relationships
163intersects = gdf[gdf.geometry.intersects(other_geometry)]
164contains = gdf[gdf.geometry.contains(point_geometry)]
165
166# Geometric operations
167gdf['centroid'] = gdf.geometry.centroid
168gdf['simplified'] = gdf.geometry.simplify(tolerance=0.001)
169
170# Overlay operations
171intersection = gpd.overlay(gdf1, gdf2, how='intersection')
172union = gpd.overlay(gdf1, gdf2, how='union')
173```
174
175### Terrain Analysis
176
177```python
178def terrain_metrics(dem_path):
179 """Calculate slope, aspect, hillshade from DEM."""
180 with rasterio.open(dem_path) as src:
181 dem = src.read(1)
182
183 dy, dx = np.gradient(dem)
184 slope = np.arctan(np.sqrt(dx**2 + dy**2)) * 180 / np.pi
185 aspect = (90 - np.arctan2(-dy, dx) * 180 / np.pi) % 360
186
187 # Hillshade
188 az_rad, alt_rad = np.radians(315), np.radians(45)
189 hillshade = (np.sin(alt_rad) * np.sin(np.radians(slope)) +
190 np.cos(alt_rad) * np.cos(np.radians(slope)) *
191 np.cos(np.radians(aspect) - az_rad))
192
193 return slope, aspect, hillshade
194```
195
196### Network Analysis
197
198```python
199import osmnx as ox
200import networkx as nx
201
202# Download and analyze street network
203G = ox.graph_from_place('San Francisco, CA', network_type='drive')
204G = ox.add_edge_speeds(G).add_edge_travel_times(G)
205
206# Shortest path
207orig = ox.distance.nearest_nodes(G, -122.4, 37.7)
208dest = ox.distance.nearest_nodes(G, -122.3, 37.8)
209route = nx.shortest_path(G, orig, dest, weight='travel_time')
210```
211
212## Image Classification
213
214```python
215from sklearn.ensemble import RandomForestClassifier
216import rasterio
217from rasterio.features import rasterize
218
219def classify_imagery(raster_path, training_gdf, output_path):
220 """Train RF and classify imagery."""
221 with rasterio.open(raster_path) as src:
222 image = src.read()
223 profile = src.profile
224 transform = src.transform
225
226 # Extract training data
227 X_train, y_train = [], []
228 for _, row in training_gdf.iterrows():
229 mask = rasterize([(row.geometry, 1)],
230 out_shape=(profile['height'], profile['width']),
231 transform=transform, fill=0, dtype=np.uint8)
232 pixels = image[:, mask > 0].T
233 X_train.extend(pixels)
234 y_train.extend([row['class_id']] * len(pixels))
235
236 # Train and predict
237 rf = RandomForestClassifier(n_estimators=100, max_depth=20, n_jobs=-1)
238 rf.fit(X_train, y_train)
239
240 prediction = rf.predict(image.reshape(image.shape[0], -1).T)
241 prediction = prediction.reshape(profile['height'], profile['width'])
242
243 profile.update(dtype=rasterio.uint8, count=1)
244 with rasterio.open(output_path, 'w', **profile) as dst:
245 dst.write(prediction.astype(rasterio.uint8), 1)
246
247 return rf
248```
249
250## Modern Cloud-Native Workflows
251
252### STAC + Planetary Computer
253
254```python
255import pystac_client
256import planetary_computer
257import odc.stac
258
259# Search Sentinel-2 via STAC
260catalog = pystac_client.Client.open(
261 "https://planetarycomputer.microsoft.com/api/stac/v1",
262 modifier=planetary_computer.sign_inplace,
263)
264
265search = catalog.search(
266 collections=["sentinel-2-l2a"],
267 bbox=[-122.5, 37.7, -122.3, 37.9],
268 datetime="2023-01-01/2023-12-31",
269 query={"eo:cloud_cover": {"lt": 20}},
270)
271
272# Load as xarray (cloud-native!)
273data = odc.stac.load(
274 list(search.get_items())[:5],
275 bands=["B02", "B03", "B04", "B08"],
276 crs="EPSG:32610",
277 resolution=10,
278)
279
280# Calculate NDVI on xarray
281ndvi = (data.B08 - data.B04) / (data.B08 + data.B04)
282```
283
284### Cloud-Optimized GeoTIFF (COG)
285
286```python
287import rasterio
288from rasterio.session import AWSSession
289
290# Read COG directly from cloud (partial reads)
291session = AWSSession(aws_access_key_id=..., aws_secret_access_key=...)
292with rasterio.open('s3://bucket/path.tif', session=session) as src:
293 # Read only window of interest
294 window = ((1000, 2000), (1000, 2000))
295 subset = src.read(1, window=window)
296
297# Write COG
298with rasterio.open('output.tif', 'w', **profile,
299 tiled=True, blockxsize=256, blockysize=256,
300 compress='DEFLATE', predictor=2) as dst:
301 dst.write(data)
302
303# Validate COG
304from rio_cogeo.cogeo import cog_validate
305cog_validate('output.tif')
306```
307
308## Performance Tips
309
310```python
311# 1. Spatial indexing (10-100x faster queries)
312gdf.sindex # Auto-created by GeoPandas
313
314# 2. Chunk large rasters
315with rasterio.open('large.tif') as src:
316 for i, window in src.block_windows(1):
317 block = src.read(1, window=window)
318
319# 3. Dask for big data
320import dask.array as da
321dask_array = da.from_rasterio('large.tif', chunks=(1, 1024, 1024))
322
323# 4. Use Arrow for I/O
324gdf.to_file('output.gpkg', use_arrow=True)
325
326# 5. GDAL caching
327from osgeo import gdal
328gdal.SetCacheMax(2**30) # 1GB cache
329
330# 6. Parallel processing
331rf = RandomForestClassifier(n_jobs=-1) # All cores
332```
333
334## Best Practices
335
3361. **Always check CRS** before spatial operations
3372. **Use projected CRS** for area/distance calculations
3383. **Validate geometries**: `gdf = gdf[gdf.is_valid]`
3394. **Handle missing data**: `gdf['geometry'] = gdf['geometry'].fillna(None)`
3405. **Use efficient formats**: GeoPackage > Shapefile, Parquet for large data
3416. **Apply cloud masking** to optical imagery
3427. **Preserve lineage** for reproducible research
3438. **Use appropriate resolution** for your analysis scale
344
345## Detailed Documentation
346
347- **[Coordinate Systems](references/coordinate-systems.md)** - CRS fundamentals, UTM, transformations
348- **[Core Libraries](references/core-libraries.md)** - GDAL, Rasterio, GeoPandas, Shapely
349- **[Remote Sensing](references/remote-sensing.md)** - Satellite missions, spectral indices, SAR
350- **[Machine Learning](references/machine-learning.md)** - Deep learning, CNNs, GNNs for RS
351- **[GIS Software](references/gis-software.md)** - QGIS, ArcGIS, GRASS integration
352- **[Scientific Domains](references/scientific-domains.md)** - Marine, hydrology, agriculture, forestry
353- **[Advanced GIS](references/advanced-gis.md)** - 3D GIS, spatiotemporal, topology
354- **[Big Data](references/big-data.md)** - Distributed processing, GPU acceleration
355- **[Industry Applications](references/industry-applications.md)** - Urban planning, disaster management
356- **[Programming Languages](references/programming-languages.md)** - Python, R, Julia, JS, C++, Java, Go, Rust
357- **[Data Sources](references/data-sources.md)** - Satellite catalogs, APIs
358- **[Troubleshooting](references/troubleshooting.md)** - Common issues, debugging, error reference
359- **[Code Examples](references/code-examples.md)** - 500+ examples
360
361---
362
363**GeoMaster covers everything from basic GIS operations to advanced remote sensing and machine learning.**
364
365---
366
367**Source:** [`K-Dense-AI/scientific-agent-skills`](https://github.com/K-Dense-AI/scientific-agent-skills) → `skills/geomaster/SKILL.md`