GEOHASH

GeoHash Ueno

Geohashは階層的なデータ構造になっていて、任意の桁数で区画の範囲を表現する事が出来ます。Open SourceのMySQLやPostgreSQL等でも実装されていると同時に、Rails等でもgemが提供されていたりします。これらのデータを利用して、色々なサービスを作成する事も可能ですので、是非試してみて頂ければと思います。

MySQLの場合 (In case of MySQL)

テーブル定義(こちらにOpen Street Mapのデータを流し込んで検証)

root@localhost [GIS]> select @@version;
+-----------+
| @@version |
+-----------+
| 8.0.11    |
+-----------+

root@localhost [GIS]> show create table nodes\G
*************************** 1. row ***************************
       Table: nodes
Create Table: CREATE TABLE `nodes` (
  `id` bigint(20) DEFAULT NULL,
  `geom` geometry NOT NULL,
  `user` varchar(50) DEFAULT NULL,
  `version` int(11) DEFAULT NULL,
  `timestamp` varchar(20) DEFAULT NULL,
  `uid` int(11) DEFAULT NULL,
  `changeset` int(11) DEFAULT NULL,
  `tags` text,
  `GeoHash5` varchar(8) GENERATED ALWAYS AS (st_geohash(`geom`,5)) VIRTUAL,
  UNIQUE KEY `i_nodeids` (`id`),
  SPATIAL KEY `i_geomidx` (`geom`),
  KEY `idx_hash` (`GeoHash5`),
  FULLTEXT KEY `tags` (`tags`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

root@localhost [GIS]> show create table nodetags\G
*************************** 1. row ***************************
       Table: nodetags
Create Table: CREATE TABLE `nodetags` (
  `id` bigint(20) DEFAULT NULL,
  `k` varchar(50) DEFAULT NULL,
  `v` varchar(256) DEFAULT NULL,
  KEY `i_nodeids2` (`id`),
  KEY `i_nodekeys` (`k`(12)),
  KEY `i_nodevalues` (`v`(12))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

サンプルデータ

※ GeoHashの列は生成列を利用しているので,geomertyデータ型のgeom列からデータを読み込んで動的にデータを生成しています。

root@localhost [GIS]> select * from nodes limit 1\G
*************************** 1. row ***************************
       id: 31236601
     geom:        xa@teA@
     user: damember
  version: 3
timestamp: 2013-01-25T13:34:14Z
      uid: 336948
changeset: 14780749
     tags: ref=1101,name=台場,highway=motorway_junction
 GeoHash5: xn76s
1 row in set (0.00 sec)

root@localhost [GIS]> select * from nodetags where k = 'name'  limit 1\G
*************************** 1. row ***************************
id: 31236601
 k: name
 v: 台場
1 row in set (0.00 sec)

root@localhost [GIS]> 

特定GeoHashデータの確認(半径2.4Km以内)

select nodes.id,st_astext(nodes.geom),
st_latfromgeohash(st_geohash((nodes.geom),8)), 
st_longfromgeohash(st_geohash((nodes.geom),8)), 
nodes.GeoHash5,nodetags.v FROM nodes,nodetags
WHERE nodes.id = nodetags.id 
and nodetags.k = 'name' 
and nodes.GeoHash5 = 'xn76g' limit 20;
geohash
geohash

GeoHashに関して

Hash値の長さによって範囲が決まってきます。上記の例では、 st_geohash(`geom`,5))としているので±2.4kmの範囲にある施設が同じHash値を持つ事になります。同じHash値を持つデータは2.4km圏内にある事を意味します。もし自分のいる位置から±0.61kmの範囲にある施設を表示したい場合は、Geohashの値を6にしてデータを取得すればOKという事になります。

GeoHash
Reference: Wiki

Webにて変換: Geohashes

https://www.movable-type.co.uk/scripts/geohash.html

生成列に関しては以下の資料P.27にて紹介しています。

PostgreSQLの場合(In case of PostgreSQL)

PostgreSQLにはGIS用のExtensionが必要ですので、先ずはPostGISをインストールします。

[root@ec2-rails-za home]# yum list | grep postgis

postgis.x86_64                         2.0.7-2.el7                   epel       
postgis-docs.x86_64                    2.0.7-2.el7                   epel       
postgis-utils.x86_64                   2.0.7-2.el7                   epel       
[root@ec2-rails-za home]# yum install postgis*
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                                                                                     | 3.7 kB  00:00:00     
218 packages excluded due to repository priority protections
Resolving Dependencies
--> Running transaction check
---> Package postgis.x86_64 0:2.0.7-2.el7 will be installed
--> Processing Dependency: gdal >= 1.9.0 for package: postgis-2.0.7-2.el7.x86_64
--> Processing Dependency: geos >= 3.1.1 for package: postgis-2.0.7-2.el7.x86_64

インストール完了後に、GIS機能を利用したいデータベースにてExtentionを作成します。

[ec2-user@ec2-rails-za ~]$ sudo su - postgres

Last login: Sat Oct 30 04:07:17 UTC 2021 on pts/0
-bash-4.2$ psql app
psql (9.2.24)
Type "help" for help.

app=# CREATE EXTENSION postgis;
CREATE EXTENSION
app=# SELECT PostGIS_full_version();

                                                    postgis_full_version                                                                
--------------------------------------------------------------------------------------------------------------------
 POSTGIS="2.0.7 r13406" GEOS="3.4.2-CAPI-1.8.2 r3921" PROJ="Rel. 4.8.0, 6 March 2012" GDAL="GDAL 1.11.4, released 2016/01/25" LIBXML="2.9.1" RASTER
(1 row)

app=# 

データを作成していないので、直接緯度経度を指定してGeoHash値を確認してみます。

上野駅

app=# SELECT ST_GeoHash(ST_SetSRID(ST_MakePoint(139.777254,35.713768),4326));
      st_geohash      
----------------------
 xn77htqxy0fu2t0y69sv
(1 row)

app=# SELECT ST_GeoHash(ST_SetSRID(ST_MakePoint(139.777254,35.713768),4326),5);
 st_geohash 
------------
 xn77h

確認:http://geohash.org/xn77htqxy0fu

東京駅

app=# SELECT ST_GeoHash(ST_SetSRID(ST_MakePoint(139.7673068,35.6809591),4326));
      st_geohash      
----------------------
 xn76urx2wkceen6v7h2m
(1 row)

app=# SELECT ST_GeoHash(ST_SetSRID(ST_MakePoint(139.7673068,35.6809591),4326),5);
 st_geohash 
------------
 xn76u
(1 row)

app=# 

確認:http://geohash.org/xn76urx2wkce

その他参考:

Global Map Japan

カテゴリー:

最近のコメント

表示できるコメントはありません。