Skill: 279458179/gaodemapskill (version 1.0.0)

--- name: gaode_map description: A skill to interact with Gaode Map (AMap) for location search and route planning. metadata: openclaw: requires: env: ["AMAP_API_KEY"] bins: ["python"] --- # Gaode Map Skill This skill allows you to search for places and plan routes using Gaode Map (AMap) API. ## Usage You can use the `amap_tool.py` script to perform actions. The API Key is expected to be in the `AMAP_API_KEY` environment variable. ### Place Search Search for POIs (Points of Interest). **Command:** ```bash python amap_tool.py search --keywords "<keywords>" [--city "<city>"] ``` **Parameters:** - `keywords`: The search query (e.g., "restaurants", "gas station"). - `city`: (Optional) The city to search in. ### Route Planning Plan a route between two locations. **Command:** ```bash python amap_tool.py route --origin "<origin>" --destination "<destination>" [--mode "<mode>"] [--city "<city>"] ``` **Parameters:** - `origin`: Start location (address or coordinates "lon,lat"). - `destination`: End location (address or coordinates "lon,lat"). - `mode`: (Optional) Route mode: `driving` (default), `walking`, `bicycling`, `transit`. - `city`: (Optional) City name (required for `transit` mode, or to help geocoding). ## Examples **User:** "Find coffee shops in Shanghai." **Action:** ```bash python amap_tool.py search --keywords "coffee shop" --city "Shanghai" ``` **User:** "Show me the driving route from Beijing West Station to the Forbidden City." **Action:** ```bash python amap_tool.py route --origin "Beijing West Station" --destination "Forbidden City" --mode "driving" --city "Beijing" ```

path: .gitignore
content: __pycache__/
*.pyc
.env
.DS_Store


path: amap_tool.py
content: import os
import sys
import json
import requests
import argparse

class AMapClient:
    def __init__(self, api_key):
        self.[REDACTED_SECRET]
        self.base_url = "https://restapi.amap.com/v3"

    def place_search(self, keywords, city=None):
        """
        Search for places based on keywords.
        """
        url = f"{self.base_url}/place/text"
        params = {
            "key": self.api_key,
            "keywords": keywords,
            "output": "json"
        }
        if city:
            params["city"] = city
        
        try:
            response = requests.get(url, params=params)
            response.raise_for_status()
            data = response.json()
            if data.get("status") == "1":
                return data.get("pois", [])
            else:
                return {"error": data.get("info", "Unknown error")}
        except Exception as e:
            return {"error": str(e)}

    def geocode(self, address, city=None):
        """
        Convert address to coordinates.
        """
        url = f"{self.base_url}/geocode/geo"
        params = {
            "key": self.api_key,
            "address": address,
            "output": "json"
        }
        if city:
            params["city"] = city
            
        try:
            response = requests.get(url, params=params)
            response.raise_for_status()
            data = response.json()
            if data.get("status") == "1" and data.get("geocodes"):
                return data["geocodes"][0]["location"]
            else:
                return None
        except:
            return None

    def route_planning(self, origin, destination, mode="driving", city=None):
        """
        Plan a route between origin and destination.
        Origin and destination can be coordinates (lon,lat) or names.
        If names are provided, geocoding will be attempted.
        """
        # If origin/destination don't look like coordinates, try to geocode them
        if "," not in origin:
            loc = self.geocode(origin, city)
            if loc:
                origin = loc
            else:
                return {"error": f"Could not geocode origin: {origin}"}
        
        if "," not in destination:
            loc = self.geocode(destination, city)
            if loc:
                destination = loc
            else:
                return {"error": f"Could not geocode destination: {destination}"}

        if mode == "driving":
            url = f"{self.base_url}/direction/driving"
        elif mode == "walking":
            url = f"{self.base_url}/direction/walking"
        elif mode == "bicycling":
            url = f"{self.base_url}/direction/bicycling"
        elif mode == "transit":
            url = f"{self.base_url}/direction/transit/integrated"
            if not city:
                 return {"error": "City is required for transit route planning"}
        else:
            return {"error": f"Unsupported mode: {mode}"}

        params = {
            "key": self.api_key,
            "origin": origin,
            "destination": destination,
            "output": "json"
        }
        
        if mode == "transit" and city:
             params["city"] = city

        try:
            response = requests.get(url, params=params)
            response.raise_for_status()
            data = response.json()
            if data.get("status") == "1":
                return data.get("route", {})
            else:
                return {"error": data.get("info", "Unknown error")}
        except Exception as e:
            return {"error": str(e)}

def main():
    parser = argparse.ArgumentParser(description="AMap (Gaode Map) Skill Tool")
    parser.add_argument("action", choices=["search", "route"], help="Action to perform")
    parser.add_argument("--key", help="AMap API Key (can also be set via AMAP_API_KEY env var)")
    parser.add_argument("--keywords", help="Keywords for place search")
    parser.add_argument("--city", help="City for search or route planning")
    parser.add_argument("--origin", help="Origin for route planning")
    parser.add_argument("--destination", help="Destination for route planning")
    parser.add_argument("--mode", default="driving", choices=["driving", "walking", "bicycling", "transit"], help="Route planning mode")

    args = parser.parse_args()

    [REDACTED_SECRET] or os.environ.get("AMAP_API_KEY")
    if not [REDACTED_SECRET]"error": "AMap API Key is required. Set AMAP_API_KEY env var or pass --key."}))
        sys.exit(1)

    client = AMapClient(api_key)
    result = {}

    if args.action == "search":
        if not args.keywords:
            result = {"error": "--keywords is required for search"}
        else:
            result = client.place_search(args.keywords, args.city)
    elif args.action == "route":
        if not args.origin or not args.destination:
            result = {"error": "--origin and --destination are required for route"}
        else:
            result = client.route_planning(args.origin, args.destination, args.mode, args.city)

    print(json.dumps(result, ensure_ascii=False, indent=2))

if __name__ == "__main__":
    main()


path: README.md
content: # Gaode Map (AMap) Skill for OpenClaw

This is an OpenClaw skill that integrates with the Gaode Map (AMap) API to provide location services.

## Features

- **Place Search**: Search for places/POIs by keywords.
- **Route Planning**: Plan routes for driving, walking, bicycling, and public transit.
- **Geocoding**: Automatically converts addresses to coordinates.

## Installation

1. Clone this repository into your OpenClaw skills directory (e.g., `~/.openclaw/skills/gaode_map`).
2. Install dependencies:
   ```bash
   pip install -r requirements.txt
   ```

## Configuration

You need a Gaode Map API Key. Get one from [AMap Console](https://console.amap.com/).

Set the environment variable `AMAP_API_KEY` in your OpenClaw configuration or environment.

## Usage

This skill exposes a Python script `amap_tool.py` that the agent can use.

### Commands

- **Search**: `python amap_tool.py search --keywords "..." --city "..."`
- **Route**: `python amap_tool.py route --origin "..." --destination "..." --mode "..."`

## Structure

- `SKILL.md`: The skill definition and instructions for OpenClaw.
- `amap_tool.py`: The implementation of the API client.
- `requirements.txt`: Python dependencies.


path: requirements.txt
content: requests


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)