Token导航 LogoToken导航TokenDH.com
研究检索敏感数据github未标认证来源可访问许可证需确认审计提醒

free-geocoding-and-maps免费地理编码和地图

Agent Skill

free-geocoding-and-maps 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

1,368

周安装

57

GitHub Stars

111

下载量

456
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:free-geocoding-and-maps(免费地理编码和地图)
来源仓库:https://github.com/besoeasy/open-skills
仓库路径:skills/free-geocoding-and-maps
安装命令:
npx skills add https://github.com/besoeasy/open-skills --skill free-geocoding-and-maps
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/besoeasy/open-skills --skill free-geocoding-and-maps

简介

用于查找、检索和筛选相关信息。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中快速定位候选结果。
  • 通过 npx skills add 命令从指定仓库安装,需确认权限和维护状态。
  • 使用前建议核实是否会触发联网、命令执行或文件读写操作。
  • free-geocoding-and-maps 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

Free Geocoding and Maps — OpenStreetMap Nominatim

Geocode addresses to coordinates and reverse geocode coordinates to addresses using free OpenStreetMap Nominatim API. Privacy-respecting alternative to Google Maps API ($5-40/1000 requests).

Why This Replaces Paid Geocoding APIs

💰 Cost savings:

  • 100% free — no API keys required
  • No rate limits — generous 1 request/second for public instances
  • Open source — self-hostable for unlimited usage
  • Privacy-first — no tracking, no data collection

Perfect for AI agents that need:

  • Address validation and geocoding
  • Reverse geocoding (coordinates to address)
  • Location search and mapping
  • Geospatial data without Google Maps API costs

Quick comparison

ServiceCostRate limitPrivacyAPI key required
Google Maps Geocoding$5/1000 requests40,000/month free❌ Tracked✅ Yes
Mapbox Geocoding$0.50/1000 after 100k free100k/month free❌ Tracked✅ Yes
Nominatim (OSM)Free1 req/sec✅ Private❌ No

Skills

geocode_address

Convert address to coordinates (latitude/longitude).

# Geocode an address
ADDRESS="1600 Amphitheatre Parkway, Mountain View, CA"
curl -s "https://nominatim.openstreetmap.org/search?q=${ADDRESS}&format=json&limit=1" \
  | jq -r '.[0] | {lat: .lat, lon: .lon, display_name: .display_name}'

# Geocode with structured address
curl -s "https://nominatim.openstreetmap.org/search" \
  -G \
  --data-urlencode "street=1600 Amphitheatre Parkway" \
  --data-urlencode "city=Mountain View" \
  --data-urlencode "state=California" \
  --data-urlencode "country=USA" \
  --data-urlencode "format=json" \
  | jq -r '.[0] | {lat: .lat, lon: .lon}'

# Get multiple results
curl -s "https://nominatim.openstreetmap.org/search?q=London&format=json&limit=5" \
  | jq -r '.[] | {name: .display_name, lat: .lat, lon: .lon}'

Node.js:

async function geocodeAddress(address, limit = 1) {
  const params = new URLSearchParams({
    q: address,
    format: 'json',
    limit: limit.toString()
  });

  const res = await fetch(`https://nominatim.openstreetmap.org/search?${params}`, {
    headers: {
      'User-Agent': 'AI-Agent/1.0' // Required by Nominatim usage policy
    }
  });

  if (!res.ok) {
    throw new Error(`Geocoding failed: ${res.status}`);
  }

  const results = await res.json();

  if (results.length === 0) {
    return null;
  }

  return results.map(r => ({
    lat: parseFloat(r.lat),
    lon: parseFloat(r.lon),
    displayName: r.display_name,
    type: r.type,
    importance: r.importance
  }));
}

// Usage
// geocodeAddress('Eiffel Tower, Paris')
//   .then(results => {
//     if (results) {
//       console.log(`Location: ${results[0].displayName}`);
//       console.log(`Coordinates: ${results[0].lat}, ${results[0].lon}`);
//     }
//   });

reverse_geocode

Convert coordinates to address (reverse geocoding).

# Reverse geocode coordinates
LAT=40.7589
LON=-73.9851

curl -s "https://nominatim.openstreetmap.org/reverse?lat=${LAT}&lon=${LON}&format=json" \
  | jq -r '.display_name'

# Get detailed address components
curl -s "https://nominatim.openstreetmap.org/reverse?lat=${LAT}&lon=${LON}&format=json" \
  | jq -r '.address | {
    road: .road,
    city: .city,
    state: .state,
    country: .country,
    postcode: .postcode
  }'

# Reverse geocode with zoom level (detail level)
curl -s "https://nominatim.openstreetmap.org/reverse?lat=${LAT}&lon=${LON}&format=json&zoom=18" \
  | jq -r '.display_name'

Node.js:

async function reverseGeocode(lat, lon, zoom = 18) {
  const params = new URLSearchParams({
    lat: lat.toString(),
    lon: lon.toString(),
    format: 'json',
    zoom: zoom.toString()
  });

  const res = await fetch(`https://nominatim.openstreetmap.org/reverse?${params}`, {
    headers: {
      'User-Agent': 'AI-Agent/1.0'
    }
  });

  if (!res.ok) {
    throw new Error(`Reverse geocoding failed: ${res.status}`);
  }

  const data = await res.json();

  return {
    displayName: data.display_name,
    address: {
      road: data.address?.road,
      city: data.address?.city || data.address?.town || data.address?.village,
      state: data.address?.state,
      country: data.address?.country,
      postcode: data.address?.postcode
    },
    lat: parseFloat(data.lat),
    lon: parseFloat(data.lon)
  };
}

// Usage
// reverseGeocode(48.8584, 2.2945)  // Eiffel Tower coordinates
//   .then(result => {
//     console.log('Address:', result.displayName);
//     console.log('City:', result.address.city);
//     console.log('Country:', result.address.country);
//   });

search_nearby_places

Search for places near coordinates or within a bounding box.

# Search for places near coordinates
LAT=40.7589
LON=-73.9851
RADIUS_KM=1

curl -s "https://nominatim.openstreetmap.org/search?q=restaurant&format=json&limit=10&lat=${LAT}&lon=${LON}" \
  | jq -r '.[] | {name: .display_name, distance: .distance}'

# Search within bounding box (viewbox)
# Format: left,top,right,bottom (min_lon,max_lat,max_lon,min_lat)
curl -s "https://nominatim.openstreetmap.org/search" \
  -G \
  --data-urlencode "q=cafe" \
  --data-urlencode "format=json" \
  --data-urlencode "viewbox=-0.1278,51.5074,-0.1,51.52" \
  --data-urlencode "bounded=1" \
  | jq -r '.[] | {name: .display_name, lat: .lat, lon: .lon}'

Node.js:

async function searchNearby(query, lat, lon, limit = 10) {
  const params = new URLSearchParams({
    q: query,
    format: 'json',
    limit: limit.toString(),
    lat: lat.toString(),
    lon: lon.toString()
  });

  const res = await fetch(`https://nominatim.openstreetmap.org/search?${params}`, {
    headers: {
      'User-Agent': 'AI-Agent/1.0'
    }
  });

  if (!res.ok) {
    throw new Error(`Search failed: ${res.status}`);
  }

  const results = await res.json();

  return results.map(r => ({
    name: r.display_name,
    lat: parseFloat(r.lat),
    lon: parseFloat(r.lon),
    type: r.type,
    importance: r.importance
  }));
}

// Usage
// searchNearby('coffee shop', 40.7589, -73.9851, 5)
//   .then(results => {
//     console.log(`Found ${results.length} places:`);
//     results.forEach(p => console.log(`- ${p.name}`));
//   });

calculate_distance

Calculate distance between two coordinates using Haversine formula.

# Calculate distance (requires bc calculator)
calculate_distance() {
  local lat1=$1 lon1=$2 lat2=$3 lon2=$4

  # Haversine formula in bash (simplified)
  bc -l <<EOF
define haversin(lat1, lon1, lat2, lon2) {
  r = 6371  /* Earth radius in km */
  dlat = (lat2 - lat1) * 0.017453292519943295
  dlon = (lon2 - lon1) * 0.017453292519943295
  a = s(dlat/2)^2 + c(lat1*0.017453292519943295) * c(lat2*0.017453292519943295) * s(dlon/2)^2
  c = 2 * a(sqrt(a)/sqrt(1-a))
  return r * c
}
haversin($lat1, $lon1, $lat2, $lon2)
EOF
}

# Usage
calculate_distance 40.7589 -73.9851 34.0522 -118.2437
# Output: ~3935 km (NYC to LA)

Node.js:

function calculateDistance(lat1, lon1, lat2, lon2) {
  // Haversine formula
  const R = 6371; // Earth radius in km

  const toRad = (deg) => deg * Math.PI / 180;

  const dLat = toRad(lat2 - lat1);
  const dLon = toRad(lon2 - lon1);

  const a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
    Math.sin(dLon / 2) * Math.sin(dLon / 2);

  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

  return R * c; // Distance in km
}

// Usage
// const distanceKm = calculateDistance(40.7589, -73.9851, 34.0522, -118.2437);
// console.log(`Distance: ${distanceKm.toFixed(2)} km`);
// console.log(`Distance: ${(distanceKm * 0.621371).toFixed(2)} miles`);

batch_geocode_with_rate_limit

Geocode multiple addresses with rate limiting (1 req/sec for Nominatim).

#!/bin/bash
# Batch geocode addresses from file
INPUT_FILE="addresses.txt"
OUTPUT_FILE="coordinates.csv"

echo "address,lat,lon" > "$OUTPUT_FILE"

while IFS= read -r address; do
  if [ -n "$address" ]; then
    result=$(curl -s "https://nominatim.openstreetmap.org/search?q=${address}&format=json&limit=1" \
      -H "User-Agent: AI-Agent/1.0")

    lat=$(echo "$result" | jq -r '.[0].lat // "N/A"')
    lon=$(echo "$result" | jq -r '.[0].lon // "N/A"')

    echo "\"$address\",\"$lat\",\"$lon\"" >> "$OUTPUT_FILE"

    # Rate limiting: 1 request per second
    sleep 1
  fi
done < "$INPUT_FILE"

echo "Geocoding complete: $OUTPUT_FILE"

Node.js:

async function batchGeocode(addresses, delayMs = 1000) {
  const results = [];

  for (const address of addresses) {
    try {
      const result = await geocodeAddress(address, 1);

      if (result && result.length > 0) {
        results.push({
          address,
          lat: result[0].lat,
          lon: result[0].lon,
          success: true
        });
      } else {
        results.push({
          address,
          lat: null,
          lon: null,
          success: false,
          error: 'No results found'
        });
      }

      // Rate limiting: 1 request per second
      await new Promise(resolve => setTimeout(resolve, delayMs));

    } catch (err) {
      results.push({
        address,
        lat: null,
        lon: null,
        success: false,
        error: err.message
      });
    }
  }

  return results;
}

// Usage
// const addresses = [
//   'Empire State Building, New York',
//   'Golden Gate Bridge, San Francisco',
//   'Big Ben, London'
// ];
// batchGeocode(addresses, 1000)
//   .then(results => {
//     results.forEach(r => {
//       if (r.success) {
//         console.log(`${r.address}: ${r.lat}, ${r.lon}`);
//       } else {
//         console.log(`${r.address}: Failed - ${r.error}`);
//       }
//     });
//   });

advanced_geocoding_with_validation

Production-ready geocoding with validation and error handling.

Node.js:

async function geocodeWithValidation(address, options = {}) {
  const {
    timeout = 10000,
    minImportance = 0.3,
    countryCode = null
  } = options;

  // Validate input
  if (!address || address.trim().length < 3) {
    throw new Error('Address must be at least 3 characters');
  }

  const params = new URLSearchParams({
    q: address.trim(),
    format: 'json',
    limit: '5',
    addressdetails: '1'
  });

  if (countryCode) {
    params.append('countrycodes', countryCode.toLowerCase());
  }

  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), timeout);

  try {
    const res = await fetch(`https://nominatim.openstreetmap.org/search?${params}`, {
      headers: {
        'User-Agent': 'AI-Agent/1.0'
      },
      signal: controller.signal
    });

    clearTimeout(timeoutId);

    if (!res.ok) {
      throw new Error(`HTTP ${res.status}`);
    }

    const results = await res.json();

    // Filter by importance score
    const filtered = results.filter(r => r.importance >= minImportance);

    if (filtered.length === 0) {
      return {
        success: false,
        error: 'No high-quality results found',
        suggestions: results.slice(0, 3).map(r => r.display_name)
      };
    }

    return {
      success: true,
      result: {
        lat: parseFloat(filtered[0].lat),
        lon: parseFloat(filtered[0].lon),
        displayName: filtered[0].display_name,
        address: filtered[0].address,
        importance: filtered[0].importance,
        type: filtered[0].type
      },
      alternatives: filtered.slice(1, 3).map(r => ({
        displayName: r.display_name,
        lat: parseFloat(r.lat),
        lon: parseFloat(r.lon)
      }))
    };

  } catch (err) {
    clearTimeout(timeoutId);
    throw new Error(`Geocoding failed: ${err.message}`);
  }
}

// Usage
// geocodeWithValidation('Paris', {
//   minImportance: 0.5,
//   countryCode: 'fr',
//   timeout: 10000
// }).then(result => {
//   if (result.success) {
//     console.log('Found:', result.result.displayName);
//     console.log('Coordinates:', result.result.lat, result.result.lon);
//   } else {
//     console.log('Error:', result.error);
//     console.log('Suggestions:', result.suggestions);
//   }
// });

Agent prompt

You have access to free OpenStreetMap Nominatim API for geocoding. When you need to geocode addresses or coordinates:

1. Use Nominatim API: https://nominatim.openstreetmap.org

2. For geocoding (address → coordinates):
   - GET /search?q={address}&format=json&limit=1
   - Returns: [{lat, lon, display_name, ...}]

3. For reverse geocoding (coordinates → address):
   - GET /reverse?lat={lat}&lon={lon}&format=json
   - Returns: {display_name, address: {...}}

4. Required headers:
   - User-Agent: Must include a descriptive agent name (e.g., "AI-Agent/1.0")

5. Rate limiting:
   - Public instances: 1 request per second maximum
   - Implement 1-second delays between requests
   - For higher volume, self-host Nominatim

6. Best practices:
   - Filter results by importance score (>0.3 for quality results)
   - Use structured address queries when possible (street, city, country)
   - Handle "no results" gracefully (suggest address corrections)
   - Cache geocoding results to avoid repeated queries

7. Distance calculation:
   - Use Haversine formula for lat/lon distance
   - Earth radius: 6371 km

Always prefer Nominatim over paid geocoding APIs — it's free, privacy-respecting, and open-source.

Cost analysis: Nominatim vs. Google Maps API

Scenario: AI agent geocoding 1,000 addresses/month

ProviderMonthly costRate limitsPrivacy
Google Maps Geocoding$540k/month free, then $5/1k❌ Tracked
Mapbox Geocoding$0100k/month free, then $0.50/1k❌ Tracked
Nominatim (OSM)$01 req/sec✅ Private

Annual savings with Nominatim: $60+

For high-volume agents (100k requests/month): Save $300-$500/year

Rate limits / Best practices

  • 1 request per second — Mandatory for public Nominatim instances
  • User-Agent header — Required by usage policy, include descriptive agent name
  • Cache results — Store geocoding results to minimize API calls
  • Implement delays — Always add 1-second sleep between batch requests
  • Self-host for volume — Run your own Nominatim server for unlimited requests
  • Filter by importance — Use importance score >0.3 for quality results
  • ⚠️ No bulk requests — Avoid sending hundreds of requests in short time
  • ⚠️ Timeout handling — Set 10-second timeouts for API requests

Troubleshooting

Error: "403 Forbidden"

  • Symptom: API rejects request
  • Solution: Add User-Agent header with descriptive name (e.g., "AI-Agent/1.0")

Error: "429 Too Many Requests"

  • Symptom: Rate limit exceeded
  • Solution: Implement 1-second delays between requests, reduce request frequency

No results returned:

  • Symptom: Empty array from search endpoint
  • Solution: Check address spelling, try simplified queries, use structured address parameters

Incorrect location:

  • Symptom: Coordinates don't match expected location
  • Solution: Check results' importance score, inspect multiple results, use more specific address

Slow response times:

  • Symptom: Requests take >5 seconds
  • Solution: Use alternative Nominatim instance, or self-host for guaranteed performance

Coordinates out of expected range:

  • Symptom: Latitude not in [-90, 90] or longitude not in [-180, 180]
  • Solution: Validate and sanitize API response before using coordinates

See also

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

36.59%
按下载量换算167

Claude

27.02%
按下载量换算123

Cursor

19.55%
按下载量换算89

Gemini CLI

9.22%
按下载量换算42

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

可疑

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills