chore: import upstream snapshot with attribution
CI / compile_and_lint (push) Failing after 0s
CI / docker_build (linux/amd64, -linux-amd64-duckdb, duckdb) (push) Failing after 0s
CI / docker_build (linux/arm64, -linux-arm64, minimal) (push) Failing after 2s
CI / docker_build (linux/arm64, -linux-arm64-duckdb, duckdb) (push) Failing after 1s
CI / docker_build (linux/amd64, minimal) (push) Failing after 1s
CI / test (, sqlite, sqlite::memory:) (push) Has been skipped
CI / test (mssql, mssql, mssql://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / test (mysql, mysql, mysql://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / test (oracle, oracle, Driver=Oracle 21 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!) (push) Has been skipped
CI / test (postgres, odbc, Driver=PostgreSQL Unicode;Server=127.0.0.1;Port=5432;Database=sqlpage;UID=root;PWD=Password123!, true) (push) Has been skipped
CI / test (postgres, postgres, postgres://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / playwright (push) Has been skipped
CI / docker_build (linux/arm/v7, -linux-arm-v7, minimal) (push) Failing after 0s
CI / hurl_examples (push) Failing after 8s
deploy website / deploy_official_site (push) Failing after 1s
CI / hurl (${{ matrix.example }}) (push) Has been skipped
CI / docker_push (duckdb) (push) Has been cancelled
CI / docker_push (minimal) (push) Has been cancelled
CI / windows_test (push) Has been cancelled
CI / compile_and_lint (push) Failing after 0s
CI / docker_build (linux/amd64, -linux-amd64-duckdb, duckdb) (push) Failing after 0s
CI / docker_build (linux/arm64, -linux-arm64, minimal) (push) Failing after 2s
CI / docker_build (linux/arm64, -linux-arm64-duckdb, duckdb) (push) Failing after 1s
CI / docker_build (linux/amd64, minimal) (push) Failing after 1s
CI / test (, sqlite, sqlite::memory:) (push) Has been skipped
CI / test (mssql, mssql, mssql://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / test (mysql, mysql, mysql://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / test (oracle, oracle, Driver=Oracle 21 ODBC driver;Dbq=//127.0.0.1:1521/FREEPDB1;Uid=root;Pwd=Password123!) (push) Has been skipped
CI / test (postgres, odbc, Driver=PostgreSQL Unicode;Server=127.0.0.1;Port=5432;Database=sqlpage;UID=root;PWD=Password123!, true) (push) Has been skipped
CI / test (postgres, postgres, postgres://root:Password123!@127.0.0.1/sqlpage) (push) Has been skipped
CI / playwright (push) Has been skipped
CI / docker_build (linux/arm/v7, -linux-arm-v7, minimal) (push) Failing after 0s
CI / hurl_examples (push) Failing after 8s
deploy website / deploy_official_site (push) Failing after 1s
CI / hurl (${{ matrix.example }}) (push) Has been skipped
CI / docker_push (duckdb) (push) Has been cancelled
CI / docker_push (minimal) (push) Has been cancelled
CI / windows_test (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
# Using PostGIS to build a geographic data application
|
||||
|
||||
## Introduction
|
||||
|
||||
This is a small application that uses [PostGIS](https://postgis.net/)
|
||||
to save data associated with geographic coordinates.
|
||||
|
||||
If you are using a SQLite database, see [this other example instead](../make%20a%20geographic%20data%20application%20using%20sqlite%20extensions/),
|
||||
which implements the same application using the `spatialite` extension for SQLite.
|
||||
|
||||
### Installation
|
||||
|
||||
You need to install the `postgis` extension for postgres. Follow [the official instructions](https://postgis.net/documentation/getting_started/).
|
||||
|
||||
Then you can instruct SQLPage to connect to your database by editing the [`sqlpage/sqlpage.json`](./sqlpage/sqlpage.json) file.
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
@@ -0,0 +1,11 @@
|
||||
INSERT INTO spatial_data (title, geom, description)
|
||||
VALUES (
|
||||
:Title,
|
||||
ST_MakePoint(
|
||||
CAST(:Longitude AS REAL),
|
||||
CAST(:Latitude AS REAL
|
||||
), 4326),
|
||||
:Text
|
||||
) RETURNING
|
||||
'redirect' AS component,
|
||||
'index.sql' AS link;
|
||||
@@ -0,0 +1,17 @@
|
||||
services:
|
||||
web:
|
||||
image: lovasoa/sqlpage:main
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- .:/var/www
|
||||
- ./sqlpage:/etc/sqlpage
|
||||
depends_on:
|
||||
- db
|
||||
environment:
|
||||
DATABASE_URL: postgres://postgres:postgres@db/postgres
|
||||
db:
|
||||
image: postgis/postgis:latest
|
||||
platform: linux/amd64
|
||||
environment:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
@@ -0,0 +1,24 @@
|
||||
SELECT 'shell' as component,
|
||||
'Point edition' AS title,
|
||||
'/' as link,
|
||||
'book' as icon;
|
||||
|
||||
UPDATE spatial_data
|
||||
SET description = :Text
|
||||
WHERE id = $id::int AND :Text IS NOT NULL;
|
||||
|
||||
SELECT 'form' AS component, title
|
||||
FROM spatial_data WHERE id = $id::int;
|
||||
|
||||
SELECT
|
||||
'Text' AS name,
|
||||
'Description for the point: ' || title AS description,
|
||||
'textarea' AS type,
|
||||
description AS value
|
||||
FROM spatial_data
|
||||
WHERE id = $id::int;
|
||||
|
||||
SELECT 'text' as component,
|
||||
description as contents_md
|
||||
FROM spatial_data
|
||||
WHERE id = $id::int;
|
||||
@@ -0,0 +1,38 @@
|
||||
SELECT 'shell' as component,
|
||||
'Map' AS title,
|
||||
'/' as link,
|
||||
'book' as icon;
|
||||
|
||||
SELECT 'map' AS component,
|
||||
ST_Y(geom) AS latitude,
|
||||
ST_X(geom) AS longitude
|
||||
FROM spatial_data
|
||||
WHERE id = $id::int;
|
||||
|
||||
SELECT 'map' as component,
|
||||
'Points of interest' as title,
|
||||
2 as zoom,
|
||||
700 as height;
|
||||
SELECT title,
|
||||
ST_Y(geom) AS latitude,
|
||||
ST_X(geom) AS longitude,
|
||||
format('[View](point.sql?id=%s) [Edit](edition_form.sql?id=%s)', id, id) as description_md
|
||||
FROM spatial_data;
|
||||
|
||||
|
||||
SELECT 'list' as component,
|
||||
'My points' as title;
|
||||
SELECT title,
|
||||
'point.sql?id=' || id as link,
|
||||
'red' as color,
|
||||
'world-pin' as icon
|
||||
FROM spatial_data;
|
||||
|
||||
SELECT 'form' AS component,
|
||||
'Add a point' AS title,
|
||||
'add_point.sql' AS action;
|
||||
|
||||
SELECT 'Title' AS name;
|
||||
SELECT 'Latitude' AS name, 'number' AS type, 0.00000001 AS step;
|
||||
SELECT 'Longitude' AS name, 'number' AS type, 0.00000001 AS step;
|
||||
SELECT 'Text' AS name, 'textarea' AS type;
|
||||
@@ -0,0 +1,58 @@
|
||||
SELECT 'shell' as component,
|
||||
title,
|
||||
'/' as link,
|
||||
'index' as menu_item,
|
||||
'book' as icon
|
||||
FROM spatial_data
|
||||
WHERE id = $id::int;
|
||||
|
||||
SELECT 'datagrid' as component, title FROM spatial_data WHERE id = $id::int;
|
||||
|
||||
SELECT 'Latitude' as title,
|
||||
ST_Y(geom) as description,
|
||||
'purple' as color,
|
||||
'world-latitude' as icon
|
||||
FROM spatial_data WHERE id = $id::int;
|
||||
|
||||
SELECT 'Longitude' as title,
|
||||
ST_X(geom) as description,
|
||||
'purple' as color,
|
||||
'world-longitude' as icon
|
||||
FROM spatial_data WHERE id = $id::int;
|
||||
|
||||
SELECT 'Created at' as title,
|
||||
created_at as description,
|
||||
'calendar' as icon,
|
||||
'Date and time of creation' as footer
|
||||
FROM spatial_data WHERE id = $id::int;
|
||||
|
||||
SELECT 'Label' as title,
|
||||
title as description,
|
||||
'geo:' || ST_Y(geom) || ',' || ST_X(geom) || '?z=16' AS link,
|
||||
'blue' as color,
|
||||
'world' as icon,
|
||||
'User-generated point name' as footer
|
||||
FROM spatial_data
|
||||
WHERE id = $id::int;
|
||||
|
||||
SELECT 'text' as component,
|
||||
description ||
|
||||
format(E'\n\n [Edit description](edition_form.sql?id=%s)', id)
|
||||
as contents_md
|
||||
FROM spatial_data
|
||||
WHERE id = $id::int;
|
||||
|
||||
SELECT 'list' as component, 'Closest points' as title;
|
||||
SELECT to_label as title,
|
||||
ROUND(distance::decimal, 3) || ' km' as description,
|
||||
'point.sql?id=' || to_id as link,
|
||||
'red' as color,
|
||||
'world-pin' as icon
|
||||
FROM distances
|
||||
WHERE from_id = $id::int
|
||||
ORDER BY distance
|
||||
LIMIT 5;
|
||||
|
||||
SELECT 'map' AS component,
|
||||
ST_Y(geom) AS latitude, ST_X(geom) AS longitude
|
||||
FROM spatial_data WHERE id = $id::int;
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 846 KiB |
+24
@@ -0,0 +1,24 @@
|
||||
CREATE EXTENSION IF NOT EXISTS postgis;
|
||||
|
||||
-- Create a table with a postgis geometry column
|
||||
CREATE TABLE IF NOT EXISTS spatial_data (
|
||||
id serial primary key NOT NULL,
|
||||
title text NOT NULL,
|
||||
geom geometry NULL,
|
||||
description text NOT NULL,
|
||||
created_at timestamp without time zone NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
|
||||
CREATE OR REPLACE VIEW distances AS
|
||||
SELECT from_point.id AS from_id,
|
||||
from_point.title AS from_label,
|
||||
to_point.id AS to_id,
|
||||
to_point.title AS to_label,
|
||||
ST_Distance(
|
||||
from_point.geom,
|
||||
to_point.geom,
|
||||
TRUE
|
||||
) AS distance
|
||||
FROM spatial_data AS from_point, spatial_data AS to_point
|
||||
WHERE from_point.id != to_point.id;
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"database_url": "postgres://my_username:my_password@localhost:5432/my_geographic_database"
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
GET http://localhost:8080/
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
body contains "Points of interest"
|
||||
body contains "Add a point"
|
||||
body not contains "An error occurred"
|
||||
|
||||
POST http://localhost:8080/add_point.sql
|
||||
[FormParams]
|
||||
Title: Hurl Paris
|
||||
Latitude: 48.8566
|
||||
Longitude: 2.3522
|
||||
Text: First Hurl point
|
||||
HTTP 302
|
||||
[Asserts]
|
||||
header "Location" == "index.sql"
|
||||
|
||||
POST http://localhost:8080/add_point.sql
|
||||
[FormParams]
|
||||
Title: Hurl Lyon
|
||||
Latitude: 45.764
|
||||
Longitude: 4.8357
|
||||
Text: Second Hurl point
|
||||
HTTP 302
|
||||
|
||||
GET http://localhost:8080/
|
||||
HTTP 200
|
||||
[Captures]
|
||||
paris_id: xpath "substring-after(string(//a[normalize-space(.)='Hurl Paris']/@href), 'id=')"
|
||||
[Asserts]
|
||||
body contains "Hurl Paris"
|
||||
body contains "Hurl Lyon"
|
||||
body htmlUnescape contains "point.sql?id={{paris_id}}"
|
||||
body not contains "An error occurred"
|
||||
|
||||
GET http://localhost:8080/point.sql?id={{paris_id}}
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
body contains "48.8566"
|
||||
body contains "2.3522"
|
||||
body contains "First Hurl point"
|
||||
body contains "Closest points"
|
||||
body contains "Hurl Lyon"
|
||||
body htmlUnescape contains "edition_form.sql?id={{paris_id}}"
|
||||
body not contains "An error occurred"
|
||||
|
||||
POST http://localhost:8080/edition_form.sql?id={{paris_id}}
|
||||
[FormParams]
|
||||
Text: Updated Hurl point
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
body contains "Updated Hurl point"
|
||||
body not contains "An error occurred"
|
||||
Reference in New Issue
Block a user