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

【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")

相关文章:

  • TOML介绍
  • 范畴论与AGI知识表示:构建认知世界的数学基础
  • 尚硅谷爬虫note001
  • 《只狼》运行时提示“mfc140u.dll文件缺失”是什么原因?要怎么解决?
  • Xcode证书密钥导入
  • VS Code 通知中一直显示“Reactivating terminals...”的问题解决
  • 论文概览 |《Cities》2024.12 Vol.155(上)
  • 线上HBase client返回超时异常分析 HBase callTimeout=60000
  • Java中的设计模式应用与最佳实践
  • Android车机DIY开发之软件篇(十四)编译i.mx8mplus官方kernel
  • 硬件电路基础
  • CSRF攻击XSS攻击
  • GRN前沿:DeepMCL:通过深度多视图对比学习从单细胞基因表达数据推断基因调控网络
  • 工厂方法模式详解(Java)
  • 【C语言】指针的练习题
  • 【Linux】修改语言编码
  • Vript-Hard——一个基于高分辨率和详细字幕的视频理解算法
  • PHP在线题库小程序
  • Qt 控件整理 —— 按钮类
  • 【油猴脚本/Tampermonkey】DeepSeek 服务器繁忙无限重试(20250214优化)
  • 苏州设置网站建设/百度广告联盟收益
  • 苹果给第三方网站做图标/百度信息流广告平台
  • 上海专业做网站公司/百度网站首页提交入口
  • 制作网站需要什么知识/站长工具seo综合查询降级
  • 太仓住房城乡建设网站/百度数据研究中心官网
  • 做任务赚钱的正规网站/营销中存在的问题及对策