<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nominatim &#8211; wqh博客</title>
	<atom:link href="https://wangqianhong.com/tag/nominatim/feed/" rel="self" type="application/rss+xml" />
	<link>https://wangqianhong.com</link>
	<description>和而不同</description>
	<lastBuildDate>Mon, 26 Aug 2024 01:58:12 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://wangqianhong.com/wp-content/uploads/2020/09/cropped-1-1-1-32x32.png</url>
	<title>Nominatim &#8211; wqh博客</title>
	<link>https://wangqianhong.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Nominatim 地址编码</title>
		<link>https://wangqianhong.com/2022/08/nominatim-%e5%9c%b0%e5%9d%80%e7%bc%96%e7%a0%81/</link>
					<comments>https://wangqianhong.com/2022/08/nominatim-%e5%9c%b0%e5%9d%80%e7%bc%96%e7%a0%81/#respond</comments>
		
		<dc:creator><![CDATA[wqh_work]]></dc:creator>
		<pubDate>Sun, 21 Aug 2022 01:40:00 +0000</pubDate>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[Nominatim]]></category>
		<guid isPermaLink="false">https://wangqianhong.com/?p=3686</guid>

					<description><![CDATA[<p>在平时开发应用中，经常会有通过经纬度获取地址信息的需求，这种需要可以通过高德等地图软件提供的收费AP&#8230; <a href="https://wangqianhong.com/2022/08/nominatim-%e5%9c%b0%e5%9d%80%e7%bc%96%e7%a0%81/" class="more-link read-more" rel="bookmark">继续阅读 <span class="screen-reader-text">Nominatim 地址编码</span><i class="fa fa-arrow-right"></i></a></p>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/08/nominatim-%e5%9c%b0%e5%9d%80%e7%bc%96%e7%a0%81/">Nominatim 地址编码</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>在平时开发应用中，经常会有通过经纬度获取地址信息的需求，这种需要可以通过高德等地图软件提供的收费API处理，也可以自己搭建地址编码服务器。</p>



<h3>Nominatim</h3>



<p>Nominatim（<a href="https://github.com/osm-search/Nominatim" target="_blank" rel="noreferrer noopener">https://github.com/osm-search/Nominatim</a>）是一个可以按名称和地址来搜索OSM中的数据，并生成OSM点的合成地址的工具（反向地理编码）。可用在http://nominatim.openstreetmap.org找到这个工具。Nominatim也用在<a href="http://www.openstreetmap.org/" target="_blank" rel="noreferrer noopener">OpenStreetMap首页</a>的<a href="http://wiki.openstreetmap.org/wiki/Search" target="_blank" rel="noreferrer noopener">搜索</a>工具栏中，同时也为<a href="http://wiki.openstreetmap.org/wiki/MapQuest" target="_blank" rel="noreferrer noopener">MapQuest Open Initiative</a>提供搜索支持。</p>



<p><strong>数据导入阶段</strong></p>



<p>读取原始OSM数据，并提取对地理编码有用的所有信息。这部分由osm2pgsql完成，该工具也可用于导入渲染数据库。它使用osm2pgsql/src/output-gatetter中的特殊地名词典输出插件。[ch]pp.导入的结果可以在数据库表中找到。</p>



<p><strong>地址计算或索引阶段</strong></p>



<p>从位置获取数据，并添加地理编码所需的其他信息。它按重要性对地点进行排名，将属于一起的对象链接在一起，并计算地址和搜索索引。大部分工作是通过数据库触发器在PL/pgSQL中完成的，可以在sql/functions/目录中的文件中找到。</p>



<p><strong>搜索前端</strong></p>



<p>实现了实际的API。它接受用户的搜索和反向地理编码查询，查找数据并以请求的格式返回结果。这部分是用PHP编写的，可以在lib/和website/目录中找到。使用apache。</p>



<h3>Docker compose安装</h3>



<pre class="wp-block-code"><code>services:
    nominatim:
        container_name: nominatim
        image: mediagis/nominatim:4.4
        ports:
            - "5432:5432"
            - "8080:8080"
        environment:
            TZ: Asia/Shanghai
            PBF_URL: https://download.geofabrik.de/asia/china-latest.osm.pbf
            REPLICATION_URL: https://download.geofabrik.de/asia/china-updates/
            NOMINATIM_PASSWORD: 123456
            IMPORT_WIKIPEDIA: "true"
            IMPORT_US_POSTCODES: "true"
            IMPORT_GB_POSTCODES: "true"
            REPLICATION_UPDATE_INTVAL: 86400
            THREADS: 16
        volumes:
            - type: bind
              source: /home/test/nominatim/data/db
              target: /var/lib/postgresql/14/main
            - type: bind
              source: /home/test/nominatim/data/flatnode
              target: /nominatim/flatnode
        shm_size: 1gb
</code></pre>



<p>5432是PostgreSQL数据库的端口，8080是服务启动之后提供的web接口端口</p>



<p>PBF_URL：数据包地址</p>



<p>REPLICATION_URL：更新包地址</p>



<p>NOMINATIM_PASSWORD：数据库密码</p>



<p>IMPORT_WIKIPEDIA：导入wiki数据</p>



<p>IMPORT_US_POSTCODES：导入美国邮编</p>



<p>IMPORT_GB_POSTCODES：导入邮编</p>



<p>REPLICATION_UPDATE_INTVAL：更新间隔，单位秒</p>



<p>THREADS：解析地址的线程</p>



<p>如果docker下载osm.pbf很慢，也可以用下载工具下完之后，映射到docker里面：</p>



<pre class="wp-block-code"><code>#PBF_URL: https://download.geofabrik.de/asia/china-latest.osm.pbf
PBF_PATH: /nominatim/data/osm/planet-latest.osm.pbf

volumes:
  - /home/test/nominatim/data/osm:/nominatim/data/osm</code></pre>



<p>这里使用中国的pbf，安装解析过程比较长（可能需要2、3天的时间），具体时间由服务器配置决定。</p>



<p>看到日志出现下面的内容表示服务启动成功：</p>



<pre class="wp-block-preformatted">LOG: database system was shut down at 2022-08-16 05:33:06 UTC
LOG: database system is ready to accept connections</pre>



<h3>全球地址数据</h3>



<p>如果使用全量pbf数据，替换PBF_URL和REPLICATION_URL 的链接：<a href="https://ftp5.gwdg.de/pub/misc/openstreetmap/planet.openstreetmap.org/pbf/planet-latest.osm.pbf">https://ftp5.gwdg.de/pub/misc/openstreetmap/planet.openstreetmap.org/pbf/planet-latest.osm.pbf</a></p>



<p><a href="https://ftp5.gwdg.de/pub/misc/openstreetmap/planet.openstreetmap.org/replication/day/">https://ftp5.gwdg.de/pub/misc/openstreetmap/planet.openstreetmap.org/replication/day/</a></p>



<p>全量数据对硬件要求比较高，而且解析时间更长，可能需要一周的时间：</p>



<pre class="wp-block-preformatted">- 16 core CPU (set THREADS variable to number of cores/threads available)
- 64GB RAM
- 1.5TB (NVMe) SSD storage</pre>



<h3>接口API</h3>



<p><a href="https://nominatim.org/release-docs/develop/api/Overview/">https://nominatim.org/release-docs/develop/api/Overview/</a></p>



<p>这里主要介绍其中的3个</p>



<h4>健康检查（/search?q=avenue%20pasteur）</h4>



<pre class="wp-block-preformatted">[]</pre>



<h4>逆地址编码（/reverse?lat=28.259719364765736&amp;lon=112.91566526653007&amp;format=jsonv2&amp;accept-language=zh）</h4>



<pre class="wp-block-preformatted">{
&nbsp; &nbsp; "place_id": 52339186,
&nbsp; &nbsp; "licence": "Data © OpenStreetMap contributors, ODbL 1.0. http://osm.org/copyright",
&nbsp; &nbsp; "osm_type": "node",
&nbsp; &nbsp; "osm_id": 3569911293,
&nbsp; &nbsp; "lat": "-41.2903464",
&nbsp; &nbsp; "lon": "174.7779487",
&nbsp; &nbsp; "category": "place",
&nbsp; &nbsp; "type": "house",
&nbsp; &nbsp; "place_rank": 30,
&nbsp; &nbsp; "importance": 0.00000999999999995449,
&nbsp; &nbsp; "addresstype": "place",
&nbsp; &nbsp; "name": "",
&nbsp; &nbsp; "display_name": "138, Wakefield Street, Te Aro, 惠灵顿 / 惠靈頓 / 威靈頓, 6011, 紐西蘭/新西兰",
&nbsp; &nbsp; "address": {
&nbsp; &nbsp; &nbsp; &nbsp; "house_number": "138",
&nbsp; &nbsp; &nbsp; &nbsp; "road": "Wakefield Street",
&nbsp; &nbsp; &nbsp; &nbsp; "suburb": "Te Aro",
&nbsp; &nbsp; &nbsp; &nbsp; "city": "惠灵顿 / 惠靈頓 / 威靈頓",
&nbsp; &nbsp; &nbsp; &nbsp; "county": "惠灵顿 / 惠靈頓 / 威靈頓",
&nbsp; &nbsp; &nbsp; &nbsp; "state": "惠灵顿 / 惠靈頓 / 威靈頓",
&nbsp; &nbsp; &nbsp; &nbsp; "ISO3166-2-lvl4": "NZ-WGN",
&nbsp; &nbsp; &nbsp; &nbsp; "postcode": "6011",
&nbsp; &nbsp; &nbsp; &nbsp; "country": "紐西蘭/新西兰",
&nbsp; &nbsp; &nbsp; &nbsp; "country_code": "nz"
&nbsp; &nbsp; },
&nbsp; &nbsp; "boundingbox": [
&nbsp; &nbsp; &nbsp; &nbsp; "-41.2903964",
&nbsp; &nbsp; &nbsp; &nbsp; "-41.2902964",
&nbsp; &nbsp; &nbsp; &nbsp; "174.7778987",
&nbsp; &nbsp; &nbsp; &nbsp; "174.7779987"
&nbsp; &nbsp; ]
}</pre>



<h4>ID详情（/details?osmtype=W&amp;osmid=1274999787&amp;format=json&amp;accept-language=zh）</h4>



<pre class="wp-block-preformatted">{
&nbsp; &nbsp; "place_id": 73967428,
&nbsp; &nbsp; "parent_place_id": 74020996,
&nbsp; &nbsp; "osm_type": "N",
&nbsp; &nbsp; "osm_id": 3569911293,
&nbsp; &nbsp; "category": "place",
&nbsp; &nbsp; "type": "house",
&nbsp; &nbsp; "admin_level": 15,
&nbsp; &nbsp; "localname": "138",
&nbsp; &nbsp; "names": [],
&nbsp; &nbsp; "addresstags": {
&nbsp; &nbsp; &nbsp; &nbsp; "city": "Wellington",
&nbsp; &nbsp; &nbsp; &nbsp; "housenumber": "138",
&nbsp; &nbsp; &nbsp; &nbsp; "postcode": "6011",
&nbsp; &nbsp; &nbsp; &nbsp; "street": "Wakefield Street",
&nbsp; &nbsp; &nbsp; &nbsp; "suburb": "Te Aro"
&nbsp; &nbsp; },
&nbsp; &nbsp; "housenumber": "138",
&nbsp; &nbsp; "calculated_postcode": "6011",
&nbsp; &nbsp; "country_code": "nz",
&nbsp; &nbsp; "indexed_date": "2024-08-13T00:20:54+00:00",
&nbsp; &nbsp; "importance": 9.99999999995449e-6,
&nbsp; &nbsp; "calculated_importance": 9.99999999995449e-6,
&nbsp; &nbsp; "extratags": [],
&nbsp; &nbsp; "calculated_wikipedia": null,
&nbsp; &nbsp; "rank_address": 30,
&nbsp; &nbsp; "rank_search": 30,
&nbsp; &nbsp; "isarea": false,
&nbsp; &nbsp; "centroid": {
&nbsp; &nbsp; &nbsp; &nbsp; "type": "Point",
&nbsp; &nbsp; &nbsp; &nbsp; "coordinates": [
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 174.7779487,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -41.2903464
&nbsp; &nbsp; &nbsp; &nbsp; ]
&nbsp; &nbsp; },
&nbsp; &nbsp; "geometry": {
&nbsp; &nbsp; &nbsp; &nbsp; "type": "Point",
&nbsp; &nbsp; &nbsp; &nbsp; "coordinates": [
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 174.7779487,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -41.2903464
&nbsp; &nbsp; &nbsp; &nbsp; ]
&nbsp; &nbsp; }
}</pre>



<h3>压力测试</h3>



<p>使用lua脚本进行压力测试</p>



<pre class="wp-block-code"><code>-- 设置随机数种子
math.randomseed(os.time())

-- 随机生成经度和纬度的函数
function generate_random_coordinates()
        local longitude = math.random() * 360 - 180 -- &#91;-180, 180]
        local latitude = math.random() * 180 - 90 -- &#91;-90, 90]
        return longitude, latitude
end

-- 定义请求的函数，wrk会在每次请求之前调用这个函数
request = function()
        -- 生成随机的经纬度
        local longitude, latitude = generate_random_coordinates()

    -- 构建带有随机经纬度的请求URL
    local url = "/reverse?lon=" .. string.format("%.6f", longitude) .. "&amp;lat=" .. string.format("%.6f", latitude).."&amp;format=jsonv2&amp;accept-language=zh"

    -- 返回 GET 请求，包含自定义的 URL
    --print(url)
    return wrk.format("GET", url)
end

-- 定义返回的函数
response = function(status, headers, body)
        if status ~= 200 then
                print(body)
        return
      </code></pre>



<p>测试命令</p>



<pre class="wp-block-preformatted"><code>wrk -t100 -c10000 -d600s -s request.lua --latency http://localhost:8080</code>

开启100个线程，模拟10000个连接，持续600秒，结果如下：
Running 10m test @ http://localhost:8080
100 threads and 10000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 32.97ms 38.66ms 1.99s 92.99%
Req/Sec 70.11 61.57 2.96k 89.25%
Latency Distribution
50% 24.34ms
75% 42.52ms
90% 64.47ms
99% 116.16ms
2609713 requests in 10.00m, 1.22GB read
Socket errors: connect 0, read 17012, write 50793, timeout 26407
Requests/sec: 4349.02
Transfer/sec: 2.08MB</pre>
<p><a rel="nofollow" href="https://wangqianhong.com/2022/08/nominatim-%e5%9c%b0%e5%9d%80%e7%bc%96%e7%a0%81/">Nominatim 地址编码</a>最先出现在<a rel="nofollow" href="https://wangqianhong.com">wqh博客</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://wangqianhong.com/2022/08/nominatim-%e5%9c%b0%e5%9d%80%e7%bc%96%e7%a0%81/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
