Skip to content

seniverse/ex_fast_rgc

Repository files navigation

FastRGC

Fast reverse geocoding at city level. it's inspired by reversegeocode, we implement same policy in elixir only for china region.

Usage

To prepare lookup by latitude and longitude, you need parse database first and hold the parsed object for later usage:

    iex(1)> {:ok, database} = FastRGC.load()

then lookup by latitude and longitude pair:

    iex(2)> FastRGC.lookup(database, %{lat: 39, lng: 116})
    %{
      "adcode" => "130632",
      "center" => "115.931979,38.929912",
      "name" => "安新县",
      "path" => "中华人民共和国,河北省,保定市,安新县"
    }

if coordinate is outside of china, nil will be returned by lookup/2 function.

    iex(3)> FastRGC.lookup(database, %{lat: 39, lng: 200})
    nil

Installation

If available in Hex, the package can be installed by adding ex_fast_rgc to your list of dependencies in mix.exs:

def deps do
  [
    {:ex_fast_rgc, "~> 0.1.0"}
  ]
end

Format of Database

The file format is designed to support reading read every bits directly without any decompress or query, and this binary decrease final file size from 44MB to ~1MB.

Orignal data is splited to 12 * 12 block, and only have four types of blocks:

Type 0, only one id in this block Type 1, only two ids in this block Type 2, three or four ids in this block Type 3, four above ids in this block

<HEADER>
 4 Bytes - SDB\01 <0x53444201>
 2 Bytes - width of the map in pixel
 2 Bytes - height of the map in pixel
 4 Bytes - width of the map in degree
 4 Bytes - height of the map in degree
 4 Bytes - longitude offset of the map in degree
 4 Bytes - latitude offset of the map in degree
 2 Bytes - tile size
 2 Bytes - y, div(height, tile_size)
 2 Bytes - x, div(width, tile_size)
 2 Bytes - delta, offset of id number
 2 Bytes - c0, count of type 0 block
 2 Bytes - c1, count of type 1 block
 2 Bytes - c2, count of type 2 block
 2 Bytes - c3, count of type 3 block

<INDEX>
  x * y * 2 Bytes - query map for every tiled block

<BODY>
  c1 * (2 * 2 + n * n / 8) Bytes - Type1 Block Data
  c2 * (2 * 4 + 2 * n * n / 8) Bytes - Type2 Block Data
  c3 * (2 * n * n) Bytes - Type3 Block Data
<BODY>
 x bytes for each row (run-length ecoding)

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/ex_fast_rgc.