×
Community Blog How to Connect Geodjango App with ApsaraDB RDS for PostgreSQL

How to Connect Geodjango App with ApsaraDB RDS for PostgreSQL

In this tutorial, we will build a minimal geodjango app that will connect with our ApsaraDB RDS for PostgreSQL instance on Alibaba Cloud.

By Grace Amondi, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud's incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.

Learn how to connect a geodjango application with ApsaraDB RDS for PostgreSQL on Alibaba Cloud the easy way. In this tutorial, we are going to build a minimal geodjango application that will connect with our ApsaraDB RDS for PostgreSQL instance on Alibaba Cloud.

GeoDjango is an included contrib module for Django that turns it into a world-class geographic Web framework. GeoDjango strives to make it as simple as possible to create geographic Web applications, like location-based services. Its features include:

  1. Django model fields for OGC geometries and raster data.
  2. Extensions to Django's ORM for querying and manipulating spatial data.
  3. Loosely-coupled, high-level Python interfaces for GIS geometry and raster operations and data manipulation in different formats.
  4. Editing geometry fields from the admin.

Prerequisites

For you to successfully complete this tutorial. you will need to have:

  1. A valid Alibaba Cloud account. If you don't have one already, sign up to the Free Trial to enjoy up to $300 worth in Alibaba Cloud products.
  2. An ECS instance running Ubuntu 16.04. You can select your preferred region and configurations; this will not affect the outcome of the server setup.
  3. A root password for your server.
  4. Geodjango Setup on your ECS instance.
  5. An ApsaraDB RDS for PostgreSQL instance.

Step 1: Create a Virtual Environment

The main purpose of Python virtual environments is to create an isolated environment for Python projects. This means that each project can have its own dependencies, regardless of what dependencies every other project has.

First upgrade pip then install virtualenv package using:

$ sudo -H pip3 install --upgrade pip
$ sudo -H pip3 install virtualenv

Create a directory where the project will be housed:

$ mkdir geodjango
$ cd geodjango

Next create a virtual environment by running the following command:

$ virtualenv geodjangoenv

This will create a virtual environmnet named geoapi where we will be able to install dependancies for this project.

Finally activate the virtualenv using:

$ source geodjangoenv/bin/activate

Your prompt should change to indicate that you are now operating within a Python virtual environment. It will look something like this: (geodjangoenv)user@host:~/geoadjango$

Step 2: Install Python Packages

Next we will install python packages that will be need for the application we will create.

$ pip3 install django psycopg2

Run the following command to add your installed requirements to a requirements.txt file.

$ pip freeze > requirements.txt

Step 3:Create the Geodjango Application

Start by creating a directory geoadjango where your project will be housed.Then move into the directory and create the project.

$ mkdir geodjango && cd geodjango
$ django-admin startproject myapp

This will create a folder named myapp containing the following files:

myapp/
    manage.py
    myapp/
        __init__.py
        settings.py
        urls.py
        wsgi.py

To create your app, make sure you're in the same directory as manage.py and type this command:

$ myapp/manage.py startapp worldapp

That'll create a directory worldapp, which is laid out like this:

worldapp/
    __init__.py
    admin.py
    apps.py
    migrations/
        __init__.py
    models.py
    tests.py
    views.py

Step 4: Configure Settings.py

Open settings.py file and modify the INSTALLED_APPS setting to include django.contrib.admin, django.contrib.gis, and worldapp (your newly created application):

$ nano myapp/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.gis',
    'worldapp',
]

Step 5: Connecting to ApsaraDB RDS for PostgreSQL

When you connect to an RDS instance through a client, choose to use an intranet or Internet address as follows:

  • Use the intranet IP address when your client is installed on the ECS that is located in the same region and the same network type as the RDS instance to be connected.
  • Use the Internet IP address for the other situations.

Also include the new ApsaraDB credentials to database configurations:

DATABASES = {
    'default': {
         'ENGINE': 'django.contrib.gis.db.backends.postgis',
         'NAME': '<database name>',
         'USER': '<user>',
         'PASSWORD':'<password>'
         'HOST':'<database host>'
         'PORT':'<database port>'
    },
}

Host name/address: refers to the connection address of the RDS instance. If your application accesses the RDS instance through the intranet, enter the intranet IP address of the RDS instance. If your application accesses the RDS instance through the Internet, enter the Internet IP address of the RDS instance.

Port: refers to the port number of the RDS instance. If your application accesses the RDS instance through the intranet, enter the intranet port number of the RDS instance. If your application accesses the RDS instance through the Internet, enter the Internet port number of the RDS instance.

User: refers to the initial account name of the RDS instance.

Password: refers to the password of the initial account name of the RDS instance.

All these configurations can be found at your RDS Console. You will need to select the region where the target instance is located.

Click the ID of the instance to visit the Basic Information page. In the Basic Information area, you can find the connection addresses and port numbers of the RDS instance.

Step 6: Download Geospatial Datasets

We will be using world borders for this tutorial. Create a directory called data in your worldapp directory, download the borders and unzip the file:

$ mkdir worldapp/data
$ cd worldapp/data
$ wget https://thematicmapping.org/downloads/TM_WORLD_BORDERS-0.3.zip
$ unzip TM_WORLD_BORDERS-0.3.zip
$ cd ../..

The world borders ZIP file contains a set of data files collectively known as an ESRI Shapefile, one of the most popular geospatial data formats. When unzipped, the world borders dataset includes files with the following extensions:

  • .shp: Holds the vector data for the world borders geometries.
  • .shx: Spatial index file for geometries stored in the .shp.
  • .dbf: Database file for holding non-geometric attribute data (e.g., integer and character fields).
  • .prj: Contains the spatial reference information for the geographic data stored in the shapefile.

Next we will need to find out the available fields for the data. We will use ogrinfo to examine spatial data.The GDAL ogrinfo utility allows examining the metadata of shapefiles or other vector data sources:

$ ogrinfo -so world/data/TM_WORLD_BORDERS-0.3.shp TM_WORLD_BORDERS-0.3

It should display something similar to the code below:

INFO: Open of `world/data/TM_WORLD_BORDERS-0.3.shp'
      using driver `ESRI Shapefile' successful.

Layer name: TM_WORLD_BORDERS-0.3
Geometry: Polygon
Feature Count: 246
Extent: (-180.000000, -90.000000) - (180.000000, 83.623596)
Layer SRS WKT:
GEOGCS["GCS_WGS_1984",
    DATUM["WGS_1984",
        SPHEROID["WGS_1984",6378137.0,298.257223563]],
    PRIMEM["Greenwich",0.0],
    UNIT["Degree",0.0174532925199433]]
FIPS: String (2.0)
ISO2: String (2.0)
ISO3: String (3.0)
UN: Integer (3.0)
NAME: String (50.0)
AREA: Integer (7.0)
POP2005: Integer (10.0)
REGION: Integer (3.0)
SUBREGION: Integer (3.0)
LON: Real (8.3)
LAT: Real (7.3)

These fields will be helpful when creating our models to represent this data.

Step 7: Define Geographic Models

Open worldapp/models.py and add the following:

$ nano worldapp/models.py
from django.contrib.gis.db import models

class WorldBorder(models.Model):
    # Regular Django fields corresponding to the attributes in the
    # world borders shapefile.
    name = models.CharField(max_length=50)
    area = models.IntegerField()
    pop2005 = models.IntegerField('Population 2005')
    fips = models.CharField('FIPS Code', max_length=2)
    iso2 = models.CharField('2 Digit ISO', max_length=2)
    iso3 = models.CharField('3 Digit ISO', max_length=3)
    un = models.IntegerField('United Nations Code')
    region = models.IntegerField('Region Code')
    subregion = models.IntegerField('Sub-Region Code')
    lon = models.FloatField()
    lat = models.FloatField()

    # GeoDjango-specific: a geometry field (MultiPolygonField)
    mpoly = models.MultiPolygonField()

    # Returns the string representation of the model.
    def __str__(self):
        return self.name

Step 8: Sync Models with Database

After defining the models, you will need to sync them with the database by typing:

$ myapp/manage.py makemigrations

Run migrate to create the world_worldborder table in the database:

$ myapp/manage.py migrate

Step 9: Layer Mapping the Spatial Data

We will import the world borders shapefile into the database via GeoDjango models using the LayerMapping data import utility.

Create a file called load.py inside the worldapp application, with the following code:

import os
from django.contrib.gis.utils import LayerMapping
from .models import WorldBorder

world_mapping = {
    'fips' : 'FIPS',
    'iso2' : 'ISO2',
    'iso3' : 'ISO3',
    'un' : 'UN',
    'name' : 'NAME',
    'area' : 'AREA',
    'pop2005' : 'POP2005',
    'region' : 'REGION',
    'subregion' : 'SUBREGION',
    'lon' : 'LON',
    'lat' : 'LAT',
    'mpoly' : 'MULTIPOLYGON',
}

world_shp = os.path.abspath(
    os.path.join(os.path.dirname(__file__), 'data', 'TM_WORLD_BORDERS-0.3.shp'),
)

def run(verbose=True):
    lm = LayerMapping(WorldBorder, world_shp, world_mapping, transform=False)
    lm.save(strict=True, verbose=verbose)

Next invoke the django shell:

$ myapp/manage.py shell

Next, import the load module, call the run routine, and watch LayerMapping do the work:

>>> from worldapp import load
>>> load.run()

You should see something like this:

...
Saved: Antigua and Barbuda
Saved: Algeria
Saved: Azerbaijan
Saved: Albania
Saved: Armenia
...

Step 10: Interact with the Geographic Admin

Let's add the following to admin.py file inside the worldapp directory:

from django.contrib.gis import admin
from .models import WorldBorder

admin.site.register(WorldBorder, admin.GeoModelAdmin)

Next, edit your urls.py in the geodjango application folder as follows:

from django.contrib.gis import admin
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
]

Finally we are going to create an admin superuser and start the development server:

$ myapp/manage.py createsuperuser
$ myapp/manage.py runserver 0.0.0.0:8000

In your web browser, visit your server's domain name or IP address followed by :8000:

http://server_domain_or_IP:8000

You should have something like this displayed once logged in:

1

Head on over to World Borders then select one country. You are now able to edit the polygon shape of the country as well as change other attributes related to the country or delete.You should see something like this:

2

Conclusion

With everything in place you should now be able to connect your ApsaraDB RDS for PostgreSQL with your Geodjango Application. I hope this tutorial came in handy.

0 0 0
Share on

Alibaba Clouder

2,599 posts | 762 followers

You may also like

Comments