Build your first GIS App in two steps
Tags: tutorial, react, express, node
Published: 2021-10-23 19:21:50

We’re going to build an app that allows us to display a geometry stored in a database on a map !

In this tutorial our GIS application will be based on a PERN app and uses React Leaflet. In case you don’t know what a PERN app is, P stands for Postgres, E for Express, R for React and N for Nodejs.

You’ll need to have Nodejs and Postgres installed, and that’s it ! We can start building our GIS app.

#####A GIS apps allows you to create interactive queries and store, edit spatial and non-spatial data, analyze it and visualize the results on maps.


Step 1 : Setting our PERN app

Let’s start with building our server. Open an empty folder on your visual studio code and create a server folder in it.

Inside of the server folder, run using the terminal npm init, after that install your dependencies by running npm i express pg cors

Then create a server.js file inside of the server folder, so your folder structure will be like this :
DEMO
 |
 +-- server
 |  |  
 |  +-- server.js

Then write the following code in it :
{%  gist https://gist.github.com/SoukainaTartour/854443895b5fdf7c619dfdc7424ec7f8 %}

Run npm start and your server should be running on port 5000.
Now we're going to create our spatial database !

#####A spatial database is a database that allows you to store and query spatial data.

In order to do that, you should have the stack builder to install extensions for your postgres, use it to insall PostGIS.

To create your spatial database make sure to use postgis_31_sample as a template for the database, it will allow you to create spatial fields and execute spatial queries.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bkd6hq09rzp1bx2zpcbr.png)

To add a geometry in your db you have to create your table first, to create a table with a geometry field run this sql query :
{% gist https://gist.github.com/SoukainaTartour/662a18da5774f48a8ca15f07eafc0354 %}

This will create a table with two fields, gid which is our primary key, and a geometry field called geom. The default coordinate system used by Postgres is WGS84.
Now let's add a record to the table by running this query that uses GeoJSON format

{% gist https://gist.github.com/SoukainaTartour/12cb47fc8c66f8e11bbee5bc66641499 %}

###GeoJSON is an encoding format of geographic data structures based on JSON.

We use the ST_GeomFromGeoJSON function to build a spatial geometry from a GeoJSON object.
For the GeoJSON object we have the first key that is the type of our geometry. In general, there are three types of geometries which we can use in the GeoJSON format : Point, Polygon and Polyline.

For the second key we specify the polygon's coordinates in our wgs84 coordinate system and in the order of latitude and longitude.

In my case I gave it the coordinates of a polygon that exists in a region called Aklim in Morocco. You can use Google maps to find coordinates of your region of interest.
To visualize our polygon we use PostGIS visualizer which is represented on the table by a little eye next to the geom field in our geomtable.


<img width="100%" style="width:100%" src="https://media.giphy.com/media/GDiDMMPBaeplzhqCrk/giphy.gif">

Now we're going to connect our database to the server. In order to do that, go to the server folder and create a db.js file and create a pool with all the information related to your database and then export the module.

{% gist https://gist.github.com/SoukainaTartour/4095aff40cfa10af72661f81d1c327e4 %}

Go back to your server.js and require the pool, and then get the geometry in the GeoJSON format using the PostGIS function ST_AsGeoJSON. So your server.js file will look like that :

{% gist https://gist.github.com/SoukainaTartour/c654a7b6716df1196e10ba6ee2733e4b %}

Let's test this using Postman so that we can have a clear vision of the JSON object that we get after sending the HTTP request.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2mf5buez8ts9tmt2s0l0.PNG)

---

Now let's move to the Front-End part of our application
Go to the main folder and create a React app inside of a client folder, you do that by running the following command in your terminal :
npx create-react-app client

Create a components folder inside the src folder of the client folder, then add a LeafletMap.js file to it.

---

Step 2 : Adding a Leaflet map to our PERN app !

Before installing react-leaflet, we have to install leaflet by running the command in our client folder :
npm install leaflet --save

And then we'll install the version 2.7.0 of react leaflet.
npm install react-leaflet@2.7.0 --save
Go to your LeafletMap.js file and write this code :

{% gist https://gist.github.com/SoukainaTartour/31a6712fa335d2c26c001fc169ab8ad8 %}

Then go to your App.js file and import your map :

{% gist https://gist.github.com/SoukainaTartour/6eb24e5c9cd9f4cc360c909ff83e7667 %}

A very important thing, is to define height and width of your leaflet map container, you do it by adding this block to your App.css file :

{% gist https://gist.github.com/SoukainaTartour/23a55cd7a6f8059f30ab5e0a6f6e257a %}

In the terminal start your app by running the command npm start
You'll get this result :

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2j5qtt2emz4khk7isfc3.png)

Now we're going to display our geometry on the map. In order to do that we we'll use the GeoJSON tag which allow us to display GeoJSON data on the map.
In LeafletMap.js file we're going to add the following code :

{% gist https://gist.github.com/SoukainaTartour/24b3d7d0e4b005a9888b326cb199aa78 %}

Run your app again, and you'll get this final result :

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sd4g1l6tshwu7474cv55.PNG)

This tutorial shows you the basics for displaying a leaflet map on your app and also geometry layers using the GeoJSON format. You can then customize it and add your own features !

You'll find the GitHub repository of this project Here :
{% github SoukainaTartour/TwoStepsGISApp %}