[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EC7C2W9KX6J4VWDQGWK3BV":3,"skill-same:01M6EC7C2W9KX6J4VWDQGWK3BV":45},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":20,"frontMatter":21,"refName":22,"commitSha":23,"skillDirectory":24,"forksCount":25,"repositoryHtmlUrl":26,"repositoryHomepageUrl":27,"ownerHtmlUrl":28,"ownerBlogUrl":6,"ownerDescription":29,"updatedAt":30,"install":31,"resources":44},"01M6EC7C2W9KX6J4VWDQGWK3BV","geomaster",null,"ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FK-Dense-AI\u002Fclaude-scientific-skills\u002Fgeomaster\u002FSKILL.md",[],[5],"2026-11-10 10:12:30",false,"# GeoMaster\r\n\r\nComprehensive 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.\r\n\r\n## Installation\r\n\r\n```bash\r\n# Core Python stack (conda recommended)\r\nconda install -c conda-forge gdal rasterio fiona shapely pyproj geopandas\r\n\r\n# Remote sensing & ML\r\nuv pip install rsgislib torchgeo earthengine-api\r\nuv pip install scikit-learn xgboost torch-geometric\r\n\r\n# Network & visualization\r\nuv pip install osmnx networkx folium keplergl\r\nuv pip install cartopy contextily mapclassify\r\n\r\n# Big data & cloud\r\nuv pip install xarray rioxarray dask-geopandas\r\nuv pip install pystac-client planetary-computer\r\n\r\n# Point clouds\r\nuv pip install laspy pylas open3d pdal\r\n\r\n# Databases\r\nconda install -c conda-forge postgis spatialite\r\n```\r\n\r\n## Quick Start\r\n\r\n### NDVI from Sentinel-2\r\n\r\n```python\r\nimport rasterio\r\nimport numpy as np\r\n\r\nwith rasterio.open('sentinel2.tif') as src:\r\n    red = src.read(4).astype(float)   # B04\r\n    nir = src.read(8).astype(float)   # B08\r\n    ndvi = (nir - red) \u002F (nir + red + 1e-8)\r\n    ndvi = np.nan_to_num(ndvi, nan=0)\r\n\r\n    profile = src.profile\r\n    profile.update(count=1, dtype=rasterio.float32)\r\n\r\n    with rasterio.open('ndvi.tif', 'w', **profile) as dst:\r\n        dst.write(ndvi.astype(rasterio.float32), 1)\r\n```\r\n\r\n### Spatial Analysis with GeoPandas\r\n\r\n```python\r\nimport geopandas as gpd\r\n\r\n# Load and ensure same CRS\r\nzones = gpd.read_file('zones.geojson')\r\npoints = gpd.read_file('points.geojson')\r\n\r\nif zones.crs != points.crs:\r\n    points = points.to_crs(zones.crs)\r\n\r\n# Spatial join and statistics\r\njoined = gpd.sjoin(points, zones, how='inner', predicate='within')\r\nstats = joined.groupby('zone_id').agg({\r\n    'value': ['count', 'mean', 'std', 'min', 'max']\r\n}).round(2)\r\n```\r\n\r\n### Google Earth Engine Time Series\r\n\r\n```python\r\nimport ee\r\nimport pandas as pd\r\n\r\nee.Initialize(project='your-project')\r\nroi = ee.Geometry.Point([-122.4, 37.7]).buffer(10000)\r\n\r\ns2 = (ee.ImageCollection('COPERNICUS\u002FS2_SR_HARMONIZED')\r\n      .filterBounds(roi)\r\n      .filterDate('2020-01-01', '2023-12-31')\r\n      .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)))\r\n\r\ndef add_ndvi(img):\r\n    return img.addBands(img.normalizedDifference(['B8', 'B4']).rename('NDVI'))\r\n\r\ns2_ndvi = s2.map(add_ndvi)\r\n\r\ndef extract_series(image):\r\n    stats = image.reduceRegion(ee.Reducer.mean(), roi.centroid(), scale=10, maxPixels=1e9)\r\n    return ee.Feature(None, {'date': image.date().format('YYYY-MM-dd'), 'ndvi': stats.get('NDVI')})\r\n\r\nseries = s2_ndvi.map(extract_series).getInfo()\r\ndf = pd.DataFrame([f['properties'] for f in series['features']])\r\ndf['date'] = pd.to_datetime(df['date'])\r\n```\r\n\r\n## Core Concepts\r\n\r\n### Data Types\r\n\r\n| Type | Examples | Libraries |\r\n|------|----------|-----------|\r\n| Vector | Shapefile, GeoJSON, GeoPackage | GeoPandas, Fiona, GDAL |\r\n| Raster | GeoTIFF, NetCDF, COG | Rasterio, Xarray, GDAL |\r\n| Point Cloud | LAS, LAZ | Laspy, PDAL, Open3D |\r\n\r\n### Coordinate Systems\r\n\r\n- **EPSG:4326** (WGS 84) - Geographic, lat\u002Flon, use for storage\r\n- **EPSG:3857** (Web Mercator) - Web maps only (don't use for area\u002Fdistance!)\r\n- **EPSG:326xx\u002F327xx** (UTM) - Metric calculations, \u003C1% distortion per zone\r\n- Use `gdf.estimate_utm_crs()` for automatic UTM detection\r\n\r\n```python\r\n# Always check CRS before operations\r\nassert gdf1.crs == gdf2.crs, \"CRS mismatch!\"\r\n\r\n# For area\u002Fdistance calculations, use projected CRS\r\ngdf_metric = gdf.to_crs(gdf.estimate_utm_crs())\r\narea_sqm = gdf_metric.geometry.area\r\n```\r\n\r\n### OGC Standards\r\n\r\n- **WMS**: Web Map Service - raster maps\r\n- **WFS**: Web Feature Service - vector data\r\n- **WCS**: Web Coverage Service - raster coverage\r\n- **STAC**: Spatiotemporal Asset Catalog - modern metadata\r\n\r\n## Common Operations\r\n\r\n### Spectral Indices\r\n\r\n```python\r\ndef calculate_indices(image_path):\r\n    \"\"\"NDVI, EVI, SAVI, NDWI from Sentinel-2.\"\"\"\r\n    with rasterio.open(image_path) as src:\r\n        B02, B03, B04, B08, B11 = [src.read(i).astype(float) for i in [1,2,3,4,5]]\r\n\r\n    ndvi = (B08 - B04) \u002F (B08 + B04 + 1e-8)\r\n    evi = 2.5 * (B08 - B04) \u002F (B08 + 6*B04 - 7.5*B02 + 1)\r\n    savi = ((B08 - B04) \u002F (B08 + B04 + 0.5)) * 1.5\r\n    ndwi = (B03 - B08) \u002F (B03 + B08 + 1e-8)\r\n\r\n    return {'NDVI': ndvi, 'EVI': evi, 'SAVI': savi, 'NDWI': ndwi}\r\n```\r\n\r\n### Vector Operations\r\n\r\n```python\r\n# Buffer (use projected CRS!)\r\ngdf_proj = gdf.to_crs(gdf.estimate_utm_crs())\r\ngdf['buffer_1km'] = gdf_proj.geometry.buffer(1000)\r\n\r\n# Spatial relationships\r\nintersects = gdf[gdf.geometry.intersects(other_geometry)]\r\ncontains = gdf[gdf.geometry.contains(point_geometry)]\r\n\r\n# Geometric operations\r\ngdf['centroid'] = gdf.geometry.centroid\r\ngdf['simplified'] = gdf.geometry.simplify(tolerance=0.001)\r\n\r\n# Overlay operations\r\nintersection = gpd.overlay(gdf1, gdf2, how='intersection')\r\nunion = gpd.overlay(gdf1, gdf2, how='union')\r\n```\r\n\r\n### Terrain Analysis\r\n\r\n```python\r\ndef terrain_metrics(dem_path):\r\n    \"\"\"Calculate slope, aspect, hillshade from DEM.\"\"\"\r\n    with rasterio.open(dem_path) as src:\r\n        dem = src.read(1)\r\n\r\n    dy, dx = np.gradient(dem)\r\n    slope = np.arctan(np.sqrt(dx**2 + dy**2)) * 180 \u002F np.pi\r\n    aspect = (90 - np.arctan2(-dy, dx) * 180 \u002F np.pi) % 360\r\n\r\n    # Hillshade\r\n    az_rad, alt_rad = np.radians(315), np.radians(45)\r\n    hillshade = (np.sin(alt_rad) * np.sin(np.radians(slope)) +\r\n                 np.cos(alt_rad) * np.cos(np.radians(slope)) *\r\n                 np.cos(np.radians(aspect) - az_rad))\r\n\r\n    return slope, aspect, hillshade\r\n```\r\n\r\n### Network Analysis\r\n\r\n```python\r\nimport osmnx as ox\r\nimport networkx as nx\r\n\r\n# Download and analyze street network\r\nG = ox.graph_from_place('San Francisco, CA', network_type='drive')\r\nG = ox.add_edge_speeds(G).add_edge_travel_times(G)\r\n\r\n# Shortest path\r\norig = ox.distance.nearest_nodes(G, -122.4, 37.7)\r\ndest = ox.distance.nearest_nodes(G, -122.3, 37.8)\r\nroute = nx.shortest_path(G, orig, dest, weight='travel_time')\r\n```\r\n\r\n## Image Classification\r\n\r\n```python\r\nfrom sklearn.ensemble import RandomForestClassifier\r\nimport rasterio\r\nfrom rasterio.features import rasterize\r\n\r\ndef classify_imagery(raster_path, training_gdf, output_path):\r\n    \"\"\"Train RF and classify imagery.\"\"\"\r\n    with rasterio.open(raster_path) as src:\r\n        image = src.read()\r\n        profile = src.profile\r\n        transform = src.transform\r\n\r\n    # Extract training data\r\n    X_train, y_train = [], []\r\n    for _, row in training_gdf.iterrows():\r\n        mask = rasterize([(row.geometry, 1)],\r\n                        out_shape=(profile['height'], profile['width']),\r\n                        transform=transform, fill=0, dtype=np.uint8)\r\n        pixels = image[:, mask > 0].T\r\n        X_train.extend(pixels)\r\n        y_train.extend([row['class_id']] * len(pixels))\r\n\r\n    # Train and predict\r\n    rf = RandomForestClassifier(n_estimators=100, max_depth=20, n_jobs=-1)\r\n    rf.fit(X_train, y_train)\r\n\r\n    prediction = rf.predict(image.reshape(image.shape[0], -1).T)\r\n    prediction = prediction.reshape(profile['height'], profile['width'])\r\n\r\n    profile.update(dtype=rasterio.uint8, count=1)\r\n    with rasterio.open(output_path, 'w', **profile) as dst:\r\n        dst.write(prediction.astype(rasterio.uint8), 1)\r\n\r\n    return rf\r\n```\r\n\r\n## Modern Cloud-Native Workflows\r\n\r\n### STAC + Planetary Computer\r\n\r\n```python\r\nimport pystac_client\r\nimport planetary_computer\r\nimport odc.stac\r\n\r\n# Search Sentinel-2 via STAC\r\ncatalog = pystac_client.Client.open(\r\n    \"https:\u002F\u002Fplanetarycomputer.microsoft.com\u002Fapi\u002Fstac\u002Fv1\",\r\n    modifier=planetary_computer.sign_inplace,\r\n)\r\n\r\nsearch = catalog.search(\r\n    collections=[\"sentinel-2-l2a\"],\r\n    bbox=[-122.5, 37.7, -122.3, 37.9],\r\n    datetime=\"2023-01-01\u002F2023-12-31\",\r\n    query={\"eo:cloud_cover\": {\"lt\": 20}},\r\n)\r\n\r\n# Load as xarray (cloud-native!)\r\ndata = odc.stac.load(\r\n    list(search.get_items())[:5],\r\n    bands=[\"B02\", \"B03\", \"B04\", \"B08\"],\r\n    crs=\"EPSG:32610\",\r\n    resolution=10,\r\n)\r\n\r\n# Calculate NDVI on xarray\r\nndvi = (data.B08 - data.B04) \u002F (data.B08 + data.B04)\r\n```\r\n\r\n### Cloud-Optimized GeoTIFF (COG)\r\n\r\n```python\r\nimport rasterio\r\nfrom rasterio.session import AWSSession\r\n\r\n# Read COG directly from cloud (partial reads)\r\nsession = AWSSession(aws_access_key_id=..., aws_secret_access_key=...)\r\nwith rasterio.open('s3:\u002F\u002Fbucket\u002Fpath.tif', session=session) as src:\r\n    # Read only window of interest\r\n    window = ((1000, 2000), (1000, 2000))\r\n    subset = src.read(1, window=window)\r\n\r\n# Write COG\r\nwith rasterio.open('output.tif', 'w', **profile,\r\n                   tiled=True, blockxsize=256, blockysize=256,\r\n                   compress='DEFLATE', predictor=2) as dst:\r\n    dst.write(data)\r\n\r\n# Validate COG\r\nfrom rio_cogeo.cogeo import cog_validate\r\ncog_validate('output.tif')\r\n```\r\n\r\n## Performance Tips\r\n\r\n```python\r\n# 1. Spatial indexing (10-100x faster queries)\r\ngdf.sindex  # Auto-created by GeoPandas\r\n\r\n# 2. Chunk large rasters\r\nwith rasterio.open('large.tif') as src:\r\n    for i, window in src.block_windows(1):\r\n        block = src.read(1, window=window)\r\n\r\n# 3. Dask for big data\r\nimport dask.array as da\r\ndask_array = da.from_rasterio('large.tif', chunks=(1, 1024, 1024))\r\n\r\n# 4. Use Arrow for I\u002FO\r\ngdf.to_file('output.gpkg', use_arrow=True)\r\n\r\n# 5. GDAL caching\r\nfrom osgeo import gdal\r\ngdal.SetCacheMax(2**30)  # 1GB cache\r\n\r\n# 6. Parallel processing\r\nrf = RandomForestClassifier(n_jobs=-1)  # All cores\r\n```\r\n\r\n## Best Practices\r\n\r\n1. **Always check CRS** before spatial operations\r\n2. **Use projected CRS** for area\u002Fdistance calculations\r\n3. **Validate geometries**: `gdf = gdf[gdf.is_valid]`\r\n4. **Handle missing data**: `gdf['geometry'] = gdf['geometry'].fillna(None)`\r\n5. **Use efficient formats**: GeoPackage > Shapefile, Parquet for large data\r\n6. **Apply cloud masking** to optical imagery\r\n7. **Preserve lineage** for reproducible research\r\n8. **Use appropriate resolution** for your analysis scale\r\n\r\n## Detailed Documentation\r\n\r\n- **[Coordinate Systems](references\u002Fcoordinate-systems.md)** - CRS fundamentals, UTM, transformations\r\n- **[Core Libraries](references\u002Fcore-libraries.md)** - GDAL, Rasterio, GeoPandas, Shapely\r\n- **[Remote Sensing](references\u002Fremote-sensing.md)** - Satellite missions, spectral indices, SAR\r\n- **[Machine Learning](references\u002Fmachine-learning.md)** - Deep learning, CNNs, GNNs for RS\r\n- **[GIS Software](references\u002Fgis-software.md)** - QGIS, ArcGIS, GRASS integration\r\n- **[Scientific Domains](references\u002Fscientific-domains.md)** - Marine, hydrology, agriculture, forestry\r\n- **[Advanced GIS](references\u002Fadvanced-gis.md)** - 3D GIS, spatiotemporal, topology\r\n- **[Big Data](references\u002Fbig-data.md)** - Distributed processing, GPU acceleration\r\n- **[Industry Applications](references\u002Findustry-applications.md)** - Urban planning, disaster management\r\n- **[Programming Languages](references\u002Fprogramming-languages.md)** - Python, R, Julia, JS, C++, Java, Go, Rust\r\n- **[Data Sources](references\u002Fdata-sources.md)** - Satellite catalogs, APIs\r\n- **[Troubleshooting](references\u002Ftroubleshooting.md)** - Common issues, debugging, error reference\r\n- **[Code Examples](references\u002Fcode-examples.md)** - 500+ examples\r\n\r\n---\r\n\r\n**GeoMaster covers everything from basic GIS operations to advanced remote sensing and machine learning.**\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002FK-Dense-AI\u002Fclaude-scientific-skills\u002Fgeomaster",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":7,"skillName":5,"commands":32,"prompt":42,"zipAvailable":43},[33,36,39],{"tool":34,"command":35},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill geomaster",{"tool":37,"command":38},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill geomaster",{"tool":40,"command":41},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill geomaster","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FK-Dense-AI\u002Fclaude-scientific-skills\u002Fgeomaster\u002FSKILL.md",true,[],[46,60,70,79,85,92],{"skillNo":47,"name":48,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":49,"categories":50,"keywords":56,"publishedAt":18},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[51],{"categoryNo":52,"categoryName":53,"taxonomyType":54,"taxonomyTypeDesc":55},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[57,58,59],"model","model hierarchy","model hierarchy skill",{"skillNo":61,"name":62,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":66,"publishedAt":18},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[65],{"categoryNo":52,"categoryName":53,"taxonomyType":54,"taxonomyTypeDesc":55},[67,68,69],"MCP","zoom","zoom mcp",{"skillNo":71,"name":72,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":73,"categories":74,"keywords":75,"publishedAt":18},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[76,77,78,68],"sdk","zoom apps sdk","apps",{"skillNo":80,"name":81,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":18},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[81],{"skillNo":86,"name":87,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":91,"publishedAt":18},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[90],{"categoryNo":52,"categoryName":53,"taxonomyType":54,"taxonomyTypeDesc":55},[87],{"skillNo":93,"name":94,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":97,"publishedAt":18},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[94]]