mirror of
https://github.com/K-Dense-AI/claude-scientific-skills.git
synced 2026-03-27 07:09:27 +08:00
Add GeoMaster: Comprehensive Geospatial Science Skill
- Added SKILL.md with installation, quick start, core concepts, workflows - Added 12 reference documentation files covering 70+ topics - Includes 500+ code examples across 7 programming languages - Covers remote sensing, GIS, ML/AI, 30+ scientific domains - MIT License Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Co-Authored-By: Dr. Umair Rabbani <umairrs@gmail.com>
This commit is contained in:
369
scientific-skills/geomaster/references/gis-software.md
Normal file
369
scientific-skills/geomaster/references/gis-software.md
Normal file
@@ -0,0 +1,369 @@
|
||||
# GIS Software Integration
|
||||
|
||||
Guide to integrating with major GIS platforms: QGIS, ArcGIS, GRASS GIS, and SAGA GIS.
|
||||
|
||||
## QGIS / PyQGIS
|
||||
|
||||
### Running Python Scripts in QGIS
|
||||
|
||||
```python
|
||||
# Processing framework script
|
||||
from qgis.core import (QgsProject, QgsVectorLayer, QgsRasterLayer,
|
||||
QgsProcessingAlgorithm, QgsProcessingParameterRasterLayer)
|
||||
|
||||
# Load layers
|
||||
vector_layer = QgsVectorLayer("path/to/shapefile.shp", "layer_name", "ogr")
|
||||
raster_layer = QgsRasterLayer("path/to/raster.tif", "raster_name", "gdal")
|
||||
|
||||
# Add to project
|
||||
QgsProject.instance().addMapLayer(vector_layer)
|
||||
QgsProject.instance().addMapLayer(raster_layer)
|
||||
|
||||
# Access features
|
||||
for feature in vector_layer.getFeatures():
|
||||
geom = feature.geometry()
|
||||
attrs = feature.attributes()
|
||||
```
|
||||
|
||||
### Creating QGIS Processing Scripts
|
||||
|
||||
```python
|
||||
from qgis.PyQt.QtCore import QCoreApplication
|
||||
from qgis.core import (QgsProcessingAlgorithm, QgsProcessingParameterRasterDestination,
|
||||
QgsProcessingParameterRasterLayer)
|
||||
|
||||
class NDVIAlgorithm(QgsProcessingAlgorithm):
|
||||
INPUT = 'INPUT'
|
||||
OUTPUT = 'OUTPUT'
|
||||
|
||||
def tr(self, string):
|
||||
return QCoreApplication.translate('Processing', string)
|
||||
|
||||
def createInstance(self):
|
||||
return NDVIAlgorithm()
|
||||
|
||||
def name(self):
|
||||
return 'ndvi_calculation'
|
||||
|
||||
def displayName(self):
|
||||
return self.tr('Calculate NDVI')
|
||||
|
||||
def group(self):
|
||||
return self.tr('Raster')
|
||||
|
||||
def groupId(self):
|
||||
return 'raster'
|
||||
|
||||
def shortHelpString(self):
|
||||
return self.tr("Calculate NDVI from Sentinel-2 imagery")
|
||||
|
||||
def initAlgorithm(self, config=None):
|
||||
self.addParameter(QgsProcessingParameterRasterLayer(
|
||||
self.INPUT, self.tr('Input Sentinel-2 Raster')))
|
||||
|
||||
self.addParameter(QgsProcessingParameterRasterDestination(
|
||||
self.OUTPUT, self.tr('Output NDVI')))
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
raster = self.parameterAsRasterLayer(parameters, self.INPUT, context)
|
||||
|
||||
# NDVI calculation
|
||||
# ... implementation ...
|
||||
|
||||
return {self.OUTPUT: destination}
|
||||
```
|
||||
|
||||
### Plugin Development
|
||||
|
||||
```python
|
||||
# __init__.py
|
||||
def classFactory(iface):
|
||||
from .my_plugin import MyPlugin
|
||||
return MyPlugin(iface)
|
||||
|
||||
# my_plugin.py
|
||||
from qgis.PyQt.QtCore import QSettings
|
||||
from qgis.PyQt.QtWidgets import QAction
|
||||
from qgis.core import QgsProject
|
||||
|
||||
class MyPlugin:
|
||||
def __init__(self, iface):
|
||||
self.iface = iface
|
||||
|
||||
def initGui(self):
|
||||
self.action = QAction("My Plugin", self.iface.mainWindow())
|
||||
self.action.triggered.connect(self.run)
|
||||
self.iface.addPluginToMenu("My Plugin", self.action)
|
||||
|
||||
def run(self):
|
||||
# Plugin logic here
|
||||
pass
|
||||
|
||||
def unload(self):
|
||||
self.iface.removePluginMenu("My Plugin", self.action)
|
||||
```
|
||||
|
||||
## ArcGIS / ArcPy
|
||||
|
||||
### Basic ArcPy Operations
|
||||
|
||||
```python
|
||||
import arcpy
|
||||
|
||||
# Set workspace
|
||||
arcpy.env.workspace = "C:/data"
|
||||
|
||||
# Set output overwrite
|
||||
arcpy.env.overwriteOutput = True
|
||||
|
||||
# Set scratch workspace
|
||||
arcpy.env.scratchWorkspace = "C:/data/scratch"
|
||||
|
||||
# List features
|
||||
feature_classes = arcpy.ListFeatureClasses()
|
||||
rasters = arcpy.ListRasters()
|
||||
```
|
||||
|
||||
### Geoprocessing Workflows
|
||||
|
||||
```python
|
||||
import arcpy
|
||||
from arcpy.sa import *
|
||||
|
||||
# Check out Spatial Analyst extension
|
||||
arcpy.CheckOutExtension("Spatial")
|
||||
|
||||
# Set environment
|
||||
arcpy.env.workspace = "C:/data"
|
||||
arcpy.env.cellSize = 10
|
||||
arcpy.env.extent = "study_area"
|
||||
|
||||
# Slope analysis
|
||||
out_slope = Slope("dem.tif")
|
||||
out_slope.save("slope.tif")
|
||||
|
||||
# Aspect
|
||||
out_aspect = Aspect("dem.tif")
|
||||
out_aspect.save("aspect.tif")
|
||||
|
||||
# Hillshade
|
||||
out_hillshade = Hillshade("dem.tif", azimuth=315, altitude=45)
|
||||
out_hillshade.save("hillshade.tif")
|
||||
|
||||
# Viewshed analysis
|
||||
out_viewshed = Viewshed("observer_points.shp", "dem.tif", obs_elevation_field="HEIGHT")
|
||||
out_viewshed.save("viewshed.tif")
|
||||
|
||||
# Cost distance
|
||||
cost_raster = CostDistance("source.shp", "cost.tif")
|
||||
cost_raster.save("cost_distance.tif")
|
||||
|
||||
# Hydrology: Flow direction
|
||||
flow_dir = FlowDirection("dem.tif")
|
||||
flow_dir.save("flowdir.tif")
|
||||
|
||||
# Flow accumulation
|
||||
flow_acc = FlowAccumulation(flow_dir)
|
||||
flow_acc.save("flowacc.tif")
|
||||
|
||||
# Stream delineation
|
||||
stream = Con(flow_acc > 1000, 1)
|
||||
stream_raster = StreamOrder(stream, flow_dir)
|
||||
```
|
||||
|
||||
### Vector Analysis
|
||||
|
||||
```python
|
||||
# Buffer analysis
|
||||
arcpy.Buffer_analysis("roads.shp", "roads_buffer.shp", "100 meters")
|
||||
|
||||
# Spatial join
|
||||
arcpy.SpatialJoin_analysis("points.shp", "zones.shp", "points_joined.shp",
|
||||
join_operation="JOIN_ONE_TO_ONE",
|
||||
match_option="HAVE_THEIR_CENTER_IN")
|
||||
|
||||
# Dissolve
|
||||
arcpy.Dissolve_management("parcels.shp", "parcels_dissolved.shp",
|
||||
dissolve_field="OWNER_ID")
|
||||
|
||||
# Intersect
|
||||
arcpy.Intersect_analysis(["layer1.shp", "layer2.shp"], "intersection.shp")
|
||||
|
||||
# Clip
|
||||
arcpy.Clip_analysis("input.shp", "clip_boundary.shp", "output.shp")
|
||||
|
||||
# Select by location
|
||||
arcpy.SelectLayerByLocation_management("points_layer", "HAVE_THEIR_CENTER_IN",
|
||||
"polygon_layer")
|
||||
|
||||
# Feature to raster
|
||||
arcpy.FeatureToRaster_conversion("landuse.shp", "LU_CODE", "landuse.tif", 10)
|
||||
```
|
||||
|
||||
### ArcGIS Pro Notebooks
|
||||
|
||||
```python
|
||||
# ArcGIS Pro Jupyter Notebook
|
||||
import arcpy
|
||||
import pandas as pd
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
# Use current project's map
|
||||
aprx = arcpy.mp.ArcGISProject("CURRENT")
|
||||
m = aprx.listMaps()[0]
|
||||
|
||||
# Get layer
|
||||
layer = m.listLayers("Parcels")[0]
|
||||
|
||||
# Export to spatial dataframe
|
||||
sdf = pd.DataFrame.spatial.from_layer(layer)
|
||||
|
||||
# Plot
|
||||
sdf.plot(column='VALUE', cmap='YlOrRd', legend=True)
|
||||
plt.show()
|
||||
|
||||
# Geocode addresses
|
||||
locator = "C:/data/locators/composite.locator"
|
||||
results = arcpy.geocoding.GeocodeAddresses(
|
||||
"addresses.csv", locator, "Address Address",
|
||||
None, "geocoded_results.gdb"
|
||||
)
|
||||
```
|
||||
|
||||
## GRASS GIS
|
||||
|
||||
### Python API for GRASS
|
||||
|
||||
```python
|
||||
import grass.script as gscript
|
||||
import grass.script.array as garray
|
||||
|
||||
# Initialize GRASS session
|
||||
gscript.run_command('g.gisenv', set='GISDBASE=/grassdata')
|
||||
gscript.run_command('g.gisenv', set='LOCATION_NAME=nc_spm_08')
|
||||
gscript.run_command('g.gisenv', set='MAPSET=user1')
|
||||
|
||||
# Import raster
|
||||
gscript.run_command('r.in.gdal', input='elevation.tif', output='elevation')
|
||||
|
||||
# Import vector
|
||||
gscript.run_command('v.in.ogr', input='roads.shp', output='roads')
|
||||
|
||||
# Get raster info
|
||||
info = gscript.raster_info('elevation')
|
||||
print(info)
|
||||
|
||||
# Slope analysis
|
||||
gscript.run_command('r.slope.aspect', elevation='elevation',
|
||||
slope='slope', aspect='aspect')
|
||||
|
||||
# Buffer
|
||||
gscript.run_command('v.buffer', input='roads', output='roads_buffer',
|
||||
distance=100)
|
||||
|
||||
# Overlay
|
||||
gscript.run_command('v.overlay', ainput='zones', binput='roads',
|
||||
operator='and', output='zones_roads')
|
||||
|
||||
# Calculate statistics
|
||||
stats = gscript.parse_command('r.univar', map='elevation', flags='g')
|
||||
```
|
||||
|
||||
## SAGA GIS
|
||||
|
||||
### Using SAGA via Command Line
|
||||
|
||||
```python
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
# SAGA path
|
||||
saga_cmd = "/usr/local/saga/saga_cmd"
|
||||
|
||||
# Grid Calculus
|
||||
def saga_grid_calculus(input1, input2, output, formula):
|
||||
cmd = [
|
||||
saga_cmd, "grid_calculus", "GridCalculator",
|
||||
f"-GRIDS={input1};{input2}",
|
||||
f"-RESULT={output}",
|
||||
f"-FORMULA={formula}"
|
||||
]
|
||||
subprocess.run(cmd)
|
||||
|
||||
# Slope analysis
|
||||
def saga_slope(dem, output_slope):
|
||||
cmd = [
|
||||
saga_cmd, "ta_morphometry", "SlopeAspectCurvature",
|
||||
f"-ELEVATION={dem}",
|
||||
f"-SLOPE={output_slope}"
|
||||
]
|
||||
subprocess.run(cmd)
|
||||
|
||||
# Morphometric features
|
||||
def saga_morphometry(dem):
|
||||
cmd = [
|
||||
saga_cmd, "ta_morphometry", "MorphometricFeatures",
|
||||
f"-DEM={dem}",
|
||||
f"-SLOPE=slope.sgrd",
|
||||
f"-ASPECT=aspect.sgrd",
|
||||
f"-CURVATURE=curvature.sgrd"
|
||||
]
|
||||
subprocess.run(cmd)
|
||||
|
||||
# Channel network
|
||||
def saga_channels(dem, threshold=1000):
|
||||
cmd = [
|
||||
saga_cmd, "ta_channels", "ChannelNetworkAndDrainageBasins",
|
||||
f"-ELEVATION={dem}",
|
||||
f"-CHANNELS=channels.shp",
|
||||
f"-BASINS=basins.shp",
|
||||
f"-THRESHOLD={threshold}"
|
||||
]
|
||||
subprocess.run(cmd)
|
||||
```
|
||||
|
||||
## Cross-Platform Workflows
|
||||
|
||||
### Export QGIS to ArcGIS
|
||||
|
||||
```python
|
||||
import geopandas as gpd
|
||||
|
||||
# Read data processed in QGIS
|
||||
gdf = gpd.read_file('qgis_output.geojson')
|
||||
|
||||
# Ensure CRS
|
||||
gdf = gdf.to_crs('EPSG:32633')
|
||||
|
||||
# Export for ArcGIS (File Geodatabase)
|
||||
gdf.to_file('arcgis_input.gpkg', driver='GPKG')
|
||||
# ArcGIS can read GPKG directly
|
||||
|
||||
# Or export to shapefile
|
||||
gdf.to_file('arcgis_input.shp')
|
||||
```
|
||||
|
||||
### Batch Processing
|
||||
|
||||
```python
|
||||
import geopandas as gpd
|
||||
from pathlib import Path
|
||||
|
||||
# Process multiple files
|
||||
input_dir = Path('input')
|
||||
output_dir = Path('output')
|
||||
|
||||
for shp in input_dir.glob('*.shp'):
|
||||
gdf = gpd.read_file(shp)
|
||||
|
||||
# Process
|
||||
gdf['area'] = gdf.geometry.area
|
||||
gdf['buffered'] = gdf.geometry.buffer(100)
|
||||
|
||||
# Export for various platforms
|
||||
basename = shp.stem
|
||||
gdf.to_file(output_dir / f'{basename}_qgis.geojson')
|
||||
gdf.to_file(output_dir / f'{basename}_arcgis.shp')
|
||||
```
|
||||
|
||||
For more GIS-specific examples, see [code-examples.md](code-examples.md).
|
||||
Reference in New Issue
Block a user