当前位置: 首页 > article >正文

【GIS】本地部署nominatim地理编码服务

参考:https://www.cnblogs.com/nonkicat/p/17222677.html

docker 部署命令

4.5 版本 docker 用不了,需要用 4.0 版本

docker run -it   -e PBF_PATH=/data/你的osm文件.osm.pbf   -e FREEZE=true   -e POSTGRES_MAX_CONNECTIONS=100   -p 6666:8080   --name nominatim   -v /宿主机指向pdf目录:/data   -v /osm-maps/data:/nominatim/data   mediagis/nominatim:4.0

耐心等待建立索引

看到以下输出即成功

2025-02-10 11:17:38.015 UTC [764] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2025-02-10 11:17:38.015 UTC [764] LOG:  listening on IPv6 address "::", port 5432
2025-02-10 11:17:38.027 UTC [764] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2025-02-10 11:17:38.105 UTC [765] LOG:  database system was shut down at 2025-02-10 11:17:37 UTC
2025-02-10 11:17:38.118 UTC [764] LOG:  database system is ready to accept connections

查询

$ keyword="人民大学"
$ curl "http://localhost:6666/search.php?q=${keyword}&polygon_geojson=1&format=jsonv2"

输出

[
    {
        "place_id": 116078,
        "licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
        "osm_type": "node",
        "osm_id": 7861046852,
        "boundingbox": [
            "39.960744",
            "39.970744",
            "116.3107286",
            "116.3207286"
        ],
        "lat": "39.965744",
        "lon": "116.3157286",
        "display_name": "人民大学, 北三环(四通桥), 中关村街道, 海淀区, 北京市, 100872, 中国",
        "place_rank": 30,
        "category": "railway",
        "type": "station",
        "importance": 0.11100000000000002,
        "geojson": {
            "type": "Point",
            "coordinates": [
                116.3157286,
                39.965744
            ]
        }
    },
    ...................
]

配套 python 代码查询

import requests

def get_coordinates(keyword):
    """
    根据关键词查询地点的经纬度。
    
    参数:
        keyword (str): 查询的关键词(如地点名称)。
        
    返回:
        list: 包含地点名称和对应经纬度的字典列表。
              每个字典包含 "place_name", "latitude", "longitude"。
    """
    url = "http://localhost:6666/search.php"
    params = {
        "q": keyword,
        "polygon_geojson": 1,
        "format": "jsonv2"
    }
    
    try:
        # 发送 GET 请求
        response = requests.get(url, params=params)
        
        # 检查响应状态码是否为 200(成功)
        if response.status_code == 200:
            data = response.json()
            results = []
            
            # 遍历结果并提取经纬度
            for item in data:
                place_name = item.get("display_name", "未知地点")
                
                # 尝试从 geojson 提取经纬度
                try:
                    coordinates = item["geojson"]["coordinates"]
                    if item["geojson"]["type"] == "Point":
                        latitude = coordinates[1]
                        longitude = coordinates[0]
                    elif item["geojson"]["type"] == "Polygon":
                        # 如果是 Polygon,取第一个点作为代表
                        latitude = coordinates[0][0][1]
                        longitude = coordinates[0][0][0]
                    else:
                        # 如果类型未知,跳过该条目
                        print(f"未知的 GeoJSON 类型: {item['geojson']['type']},跳过地点: {place_name}")
                        continue
                except (KeyError, IndexError, TypeError):
                    # 如果 geojson 不可用,尝试使用 lat 和 lon 字段
                    try:
                        latitude = float(item["lat"])
                        longitude = float(item["lon"])
                    except KeyError:
                        print(f"无法提取经纬度信息,跳过地点: {place_name}")
                        continue
                
                # 添加到结果列表
                results.append({
                    "place_name": place_name,
                    "latitude": latitude,
                    "longitude": longitude
                })
            
            return results
        else:
            print(f"请求失败,状态码: {response.status_code}")
            return []
    except requests.exceptions.RequestException as e:
        print(f"网络请求出错: {e}")
        return []
    except ValueError as e:
        print(f"JSON 解析出错: {e}")
        return []


# 测试样例
keywords = [
    "北京大学",          # 大学
    "天安门广场",       # 广场
    "故宫博物院",       # 博物馆
    "北京站",           # 火车站
    "颐和园",           # 公园
    "中关村创业大街",   # 街道
    "清华大学",         # 大学
    "国家体育场",       # 体育场馆(鸟巢)
    "首都国际机场",     # 机场
    "人民大会堂"        
]

for keyword in keywords:
    print(f"查询关键词: {keyword}")
    coordinates = get_coordinates(keyword)
    if coordinates:
        for result in coordinates:
            print(f"地点名称: {result['place_name']}")
            print(f"纬度: {result['latitude']}, 经度: {result['longitude']}")
            print("-" * 40)
    else:
        print("未找到任何地点信息。")
    print("\n" + "=" * 80 + "\n")

http://www.kler.cn/a/540294.html

相关文章:

  • 【人工智能】解码语言之谜:使用Python构建神经机器翻译系统
  • 练习题(2.10)
  • 如何使用DeepSeek帮助自己的工作?
  • Left side cannot be assigned to
  • Json-RPC框架项目(一)
  • DeepSeek从入门到精通教程PDF清华大学出版
  • 【人工智能】python之set集合练习
  • 等级保护2.0|网络安全服务
  • pytorch torch.linalg模块介绍
  • pip3命令全解析:Python3包管理工具的详细使用指南
  • 【LeetCode 热题100】74:搜索二维矩阵(二分、线性两种方式 详细解析)(Go 语言实现)
  • 超越 DeepSeek V3 -->【Qwen2.5-Max】
  • 【快应用】原生广告下载状态监听案例
  • 证明: 极限的局部有界性
  • Faiss特征向量搜索
  • ESP-IDF学习记录(6)
  • Django开发入门 – 2.Django的Web应用项目架构
  • flink JobGraph解析
  • leetcode刷题-动态规划04
  • 机器学习:学习记录(二)
  • Kotlin实战经验:将接口回调转换成suspend挂起函数
  • Bigemap Pro如何裁剪矢量数据
  • Ollama系列---【ollama使用gpu运行大模型】
  • 蓝耘智算平台部署deepseek-助力深度学习
  • webpack配置之---output.clean
  • AWS vs Azure vs 阿里云:出海企业全球扩张的技术选型指南(2024深度对比)