Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
bryanjos committed Jul 15, 2017
0 parents commit 323cd88
Show file tree
Hide file tree
Showing 18 changed files with 1,028 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# The directory Mix will write compiled artifacts to.
/_build

# If you run "mix test --cover", coverage assets end up here.
/cover

# The directory Mix downloads your dependencies sources to.
/deps

# Where 3rd-party dependencies like ExDoc output generated docs.
/doc

# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch

# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump

# Also ignore archive artifacts (built via "mix archive.build").
*.ez
16 changes: 16 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
dist: trusty
sudo: false
language: elixir
elixir:
- 1.4.5
otp_release:
- 18.0
- 19.0
- 20.0
addons:
postgresql: '9.6'
services:
- postgresql
before_script:
- psql -c 'create database geo_postgrex_test;' -U postgres
- psql -c 'create extension postgis;' -U postgres -d geo_postgrex_test
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [1.0.0]
### Added
- PostGIS extension for Postgrex
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2017 Bryan Joseph

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
144 changes: 144 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# GeoPostGIS

[![Build Status](https://travis-ci.org/bryanjos/geo_postgis.svg?branch=master)](https://travis-ci.org/bryanjos/geo_postgis)

Postgrex extension for the PostGIS data types. Uses the [geo](https://github.com/bryanjos/geo) library

[Documentation](http://hexdocs.pm/geo_postgis)

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `geo_postgis` to your list of dependencies in `mix.exs`:

```elixir
def deps do
[{:geo_postgis, "~> 1.0"}]
end
```

## Examples

### Postgrex Extension for the PostGIS data types, Geometry and Geography

```elixir
Postgrex.Types.define(MyApp.PostgresTypes, [Geo.PostGIS.Extension], [])

opts = [hostname: "localhost", username: "postgres", database: "geo_postgrex_test", types: MyApp.PostgresTypes ]
[hostname: "localhost", username: "postgres", database: "geo_postgrex_test", types: MyApp.PostgresTypes]

{:ok, pid} = Postgrex.Connection.start_link(opts)
{:ok, #PID<0.115.0>}

geo = %Geo.Point{coordinates: {30, -90}, srid: 4326}
%Geo.Point{coordinates: {30, -90}, srid: 4326}

{:ok, _} = Postgrex.Connection.query(pid, "CREATE TABLE point_test (id int, geom geometry(Point, 4326))")
{:ok, %Postgrex.Result{columns: nil, command: :create_table, num_rows: 0, rows: nil}}

{:ok, _} = Postgrex.Connection.query(pid, "INSERT INTO point_test VALUES ($1, $2)", [42, geo])
{:ok, %Postgrex.Result{columns: nil, command: :insert, num_rows: 1, rows: nil}}

Postgrex.Connection.query(pid, "SELECT * FROM point_test")
{:ok, %Postgrex.Result{columns: ["id", "geom"], command: :select, num_rows: 1,
rows: [{42, %Geo.Point{coordinates: {30.0, -90.0}, srid: 4326 }}]}}
```

### Use with Ecto Referencing [the documentation](https://hexdocs.pm/ecto/Ecto.Adapters.Postgres.html#module-extensions):

```elixir

#If using with Ecto, you may want something like thing instead
Postgrex.Types.define(MyApp.PostgresTypes,
[Geo.PostGIS.Extension] ++ Ecto.Adapters.Postgres.extensions(),
json: Poison)

#Add extensions to your repo config
config :thanks, Repo,
database: "geo_postgrex_test",
username: "postgres",
password: "postgres",
hostname: "localhost",
adapter: Ecto.Adapters.Postgres,
types: MyApp.PostgresTypes


#Create a model
defmodule Test do
use Ecto.Model

schema "test" do
field :name, :string
field :geom, Geo.Geometry
end
end

#Geometry or Geography columns can be created in migrations too
defmodule Repo.Migrations.Init do
use Ecto.Migration

def up do
create table(:test) do
add :name, :string
add :geom, :geometry
end
end

def down do
drop table(:test)
end
end
```


### Ecto migrations can also use more elaborate [Postgis GIS Objects](http://postgis.net/docs/using_postgis_dbmanagement.html#RefObject). These types are useful for enforcing constraints on {Lng,Lat} (order matters), or ensuring that a particular projection/coordinate system/format is used.

```elixir
defmodule Repo.Migrations.AdvancedInit do
use Ecto.Migration

def up do
create table(:test) do
add :name, :string
end
# Add a field `lng_lat_point` with type `geometry(Point,4326)`.
# This can store a "standard GPS" (epsg4326) coordinate pair {longitude,latitude}.
execute("SELECT AddGeometryColumn ('test','lng_lat_point',4326,'POINT',2);")
end

def down do
drop table(:test)
end
end
```

Be sure to enable the Postgis extension if you haven't already done so:

```elixir

defmodule MyApp.Repo.Migrations.EnablePostgis do
use Ecto.Migration

def up do
execute "CREATE EXTENSION IF NOT EXISTS postgis"
end

def down do
execute "DROP EXTENSION IF EXISTS postgis"
end
end
```

### [Postgis functions](http://postgis.net/docs/manual-1.3/ch06.html) can also be used in ecto queries. Currently only the OpenGIS functions are implemented. Have a look at [lib/geo/postgis.ex](lib/geo/postgis.ex) for the implemented functions. You can use them like:

```elixir
defmodule Example do
import Ecto.Query
import Geo.PostGIS

def example_query(geom) do
from location in Location, limit: 5, select: st_distance(location.geom, ^geom)
end

end
```
5 changes: 5 additions & 0 deletions config/config.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config

import_config "#{Mix.env}.exs"
1 change: 1 addition & 0 deletions config/dev.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use Mix.Config
1 change: 1 addition & 0 deletions config/prod.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use Mix.Config
12 changes: 12 additions & 0 deletions config/test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use Mix.Config

config :geo_postgis, Geo.Ecto.Test.Repo,
database: "geo_postgrex_test",
username: "postgres",
password: "postgres",
hostname: "localhost",
adapter: Ecto.Adapters.Postgres,
types: Geo.PostGIS.PostgrexTypes

# Print only warnings and errors during test
config :logger, level: :warn
Loading

0 comments on commit 323cd88

Please sign in to comment.