Tuesday, October 29, 2013

Phát triển ứng dụng GIS với Python

Quách Đồng Thắng 
Trung tâm Ứng dụng GIS Tp.HCM

Abstract: This paper introduces the Python language, the role of Python in existing GIS software, the Python GIS libraries support developing GIS applications. The paper also presents a case study of building Python WebGIS application based on django framework using eclipse IDE with pydev extension. 
Keywords: Python, GeoDjango, eclipse, Pydev, PostGIS.

1.   GIỚI THIỆU
     Python là một ngôn ngữ lập trình kịch bản (scripting), thông dịch (interpreter) thích hợp cho nhiều loại ứng dụng trên nhiều platform khác nhau. Trong lĩnh vực GIS, phần lớn các phần mềm GIS hiện nay sử dụng Python làm ngôn ngữ scripting và để xây dựng các extension; các thư viện lập trình GIS thường có Python binding để có thể dễ dàng sử dụng trên môi trường Python.

Cách tiếp cận lập trình GIS với Python:

  • Sử dụng scripting language được nhúng trực tiếp trong phần mềm: Ví dụ trong ArcGIS có tích hợp ArcPy (thay thế cho VBA từ phiên bản ArcGIS 10), QGIS cũng có tích hợp Python console. Ví dụ sau trả về số lượng của layer đang được chọn (active) trong QGIS:
   layer = qgis.utils.iface.activeLayer()
  layer.featureCount()


  • Phát triển plugins gắn thêm vào các phần mềm GIS: Ví dụ, QGIS được phát triển bằng C++, tuy nhiên người dùng có thể xây dựng các plugin cho QGIS bằng Python thay vì C++, và hiện nay Python plugins chiếm phần lớn số lượng plugin và không ngừng phát triển trong cộng đồng người dùng QGIS.
  • Phát triển ứng dụng GIS độc lập bằng cách cài đặt thêm các thư viện cần thiết để làm việc với dữ liệu không gian trong môi trường Python.
Hiện nay có rất nhiều thư viện hỗ trợ lập trình GIS bằng Python để xây dựng một ứng dụng GIS độc lập. Bài báo đề xuất một số thư viện cơ bản sau:

  • Fiona - Python binding của OGR/GDAL: đọc, ghi dữ liệu vector/ raster ở nhiều định dạng khác nhau.
  • Shapely - Python binding của Geos: thực hiện các phép toán trên dữ liệu không gian.
  • PyProj - Python binding của PROJ.4: định nghĩa, quản lý và chuyển đổi giữa các datum và projection khác nhau cho dữ liệu không gian.
  • NumPy - Numerical Python: thực hiện các tính toán khoa học.
  • owslib - OGC Web Service utility library: thư viện tương tác với các dịch vụ dữ liệu không gian theo chuẩn OGC.
  • Geodjango: Tạo ứng dụng Python WebGIS trên nền django framework.
  • MapFish: Tạo ứng dụng Python WebGIS trên nền Pylons framework.
  • GeoAlchamy : mở rộng SQLAlchemy (một Object Relational Mapper cho Python) làm việc với dữ liệu không gian, hỗ trợ PostGIS, Spatialite, MySQL, Oracle và MS SQL Server 2008.
Nhà phát triển Python có thể sử dụng các công cụ hỗ trợ sau:
  • Sử dụng giao diện command line.
  • Sử dụng IDE: một số IDE tiêu biểu như Komodo, PyScripter, Spyder, Crimson Editor, PyDev (trên nền eclipse), IDLE (IDLE được tích hợp sẵn khi cài đặt Python).
  • Để thiết kế giao diện đồ họa cho Python có thể dùng PyQt .
Ngoài ra, có thể sử dụng một số nguồn dữ liệu miễn phí phục vụ cho mục đích học tập, nghiên cứu: Gdam, OpenStreetMap, Natural Earth, diva-gis, thematicmapping. (Lưu ý đây là chỉ là nguồn dữ liệu miễn phí và mang tính tham khảo, bài báo không bàn đến khía cạnh pháp lý của dữ liệu.)
Các tham khảo hữu ích cho các nhà phát triển ứng dụng GIS với Python:

  • Python tutorial trên trang web của Python.
  • Bài giảng Geoprocessing with Python using Open Source GIS.
  • Sách Python Geospatial Development .

2.   XÂY DỰNG ỨNG DỤNG PYTHON WEBGIS VỚI GEODJANGO
          Khi xây dựng ứng dụng, việc sử dụng các framework được xây dựng sẵn rất có ích để có thể tạo các ứng dụng một cách nhanh chóng, thuận tiện, chuẩn hóa và dễ bảo trì. Để lập trình web với Python, hiện nay có nhiều framework hỗ trợ như Django, Pylons, TurboGears, web2py, Zope2. Bài báo giới thiệu cách xây dựng một ứng dụng Python WebGIS đơn giản trên nền Django framework (theo mô hình Model - Template - View) với phần mở rộng Geodjango hỗ trợ dữ liệu không gian.

    2.1.   Cài đặt các công cụ cần thiết

    • Cài đặt Python (bài báo sử dụng Python 2.7). Sau khi cài đặt thành công, có thể khởi động Python ở chế độ cmd hoặc sử dụng IDLE để kiểm tra kết quả cài đặt.


    • Cài đặt pip để thuận tiện khi cài đặt các package gắn thêm vào python được quản lý trên pypi (Python package Index). Cài đặt pip trong giao diện cmd:
               Đường dẫn đến pip> python setup.py install
    • Sau khi cài đặt Python, có thể download Django và cài đặt tương tự như pip, hoặc có thể sử dụng câu lệnh đơn giản hơn để cài đặt django từ pyp
             >pip install django
    • Sau khi cài đặt django, có thể kiểm tra lại bằng cách:
    >>> import django
    >>> print(django.get_version())
    1.5.2

    2.2.   Tạo project Geodjango đầu tiên

    • Tạo project với tên mydjango:
    C:\Python27\Lib\site-packages\django\bin>django-admin.py startproject mydjango

    • Cấu trúc của project mydjango:
    mydjango/
    manage.py
    mysite/
    __init__.py
    settings.py
    urls.py
    wsgi.py

    • Khởi động server:
    C:\Python27\Lib\site-packages\django\bin\mydjango>manage.py runserver


    • Kết quả trên trình duyệt:

    2.3.   Xây dựng Geodjango WebGIS với PyDev
             Trên thực tế, các công cụ giao diện đồ hoạ thường được sử dụng để đơn giản hoá các bước xây dựng ứng dụng. Bài báo trình bày các bước xây dựng một Geodjango WebGIS trên nền eclipse/PyDev, cụ thể là xây dựng một ứng dụng CRUD (Create- Read-Update-Delete) WebGIS cho đối tượng không gian là lớp dữ liệu world_borders shapefile. Qua đó phần nào thấy được hiện thực của mô hình Model – Template – View cũng như chức năng ORM (Object-Relational Mapping) của django framework.

    • Cài đặt PostgreSQL/PostGIS, tạo GIS database với tên là geodjango (sử dụng template_postgis).
    • Tải shapefile world_borders trên thematicmapping.
    • Cài đặt psycopg2 để Python giao tiếp với CSDL PostgreSQL/PostGIS.
    • Cài đặt eclipse và extension pydev. Vào Window/ Preferences, thiết lập Python interpreter cho eclipse (C:\Python27\python.exe).
    • Tạo pyDev Django Project với tên là geodjango. Cấu hình Database là CSDL geodjango vừa tạo ở bước trên.

    • Chỉnh sửa DATABASE ENGINE thành postgis trong geodjango/setting.py:
    DATABASES = {
    'default': {
    'ENGINE''django.contrib.gis.db.backends.postgis',
    'NAME''geodjango',
    'USER''postgres',
    'PASSWORD''postgres',
    'HOST''localhost',
    'PORT''5432',
    }
    }

    • Tạo application với tên world:


    • Trong geodjango/setting.py, thêm 'django.contrib.gis' và application 'world' vào INSTALL_APPS:
    INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'django.contrib.gis',
    'world'
    )


    • Chỉnh sửa file world/models.py thành (Lưu ý model này được xây dựng dựa trên cấu trúc thuộc tính của world_borders shapefile):
    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('SubRegion Code')
    lon = models.FloatField()
    lat = models.FloatField()
    # GeoDjango‐specific: a geometry field (MultiPolygonField), and
    # overriding the default manager with a GeoManager instance.
    mpoly = models.MultiPolygonField()
    objects = models.GeoManager()
    # Returns the string representation of the model.
    # On Python 3: def __str__(self):
    def __unicode__(self):
    return self.name


    • Sau đó sử dụng chức năng django/syncDB để đồng bộ model và CSDL. Trong khi syncDB, điền các thông tin tạo superuser để login vào giao diện quản trị geodjango:

    • Kết quả sau khi đồng bộ database trong PostGIS:


    • Tiếp theo đổi tên table world_worldborder (table được tạo sau bước syncdb ở trên) thành world_worldborder_old, import world_borders shapefile vào database với tên là world_ worldborder, đặt tên cột geometry là mpoly. Sau khi import, rename cột gid thành id để đồng bộ với class WorldBorder được định nghĩa trong models.py ở bước trên.
    • Tạo admin.py trong world với nội dung:
    from django.contrib.gis import admin
    from models import WorldBorder
    admin.site.register(WorldBorder, admin.GeoModelAdmin)


    • Chỉnh sửa file urls.py trong geodjango:
    from django.conf.urls import patterns, url, include
    from django.contrib.gis import admin
    admin.autodiscover()
    urlpatterns = patterns('',
    url(r'^admin/', include(admin.site.urls)),)

    • Run as/ pydev Django để khởi chạy ứng dụng, truy cập vào localhost:8000/admin để đăng nhập vào giao diện quản trị geodjango.
    • Thử nghiệm: chọn add để tạo một đối tượng mới cho đối tượng world borders:


    • Giao diện tạo mới một đối tượng world border hỗ trợ dữ liệu không gian thông qua Openlayers:
     
    3.   KẾT LUẬN
          Bài báo đã trình bày cách tiếp cận lập trình GIS với Python, cũng như chi tiết cách xây dựng một ứng dụng CRUD WebGIS cơ bản trên nền Django framework với phần mở rộng cho dữ liệu không gian. Xây dựng ứng dụng GIS với Python là một trong những hướng lập trình rất thú vị và hữu ích vì Python hiện đang là một ngôn ngữ được lựa chọn trong rất nhiều ứng dụng nhờ tính tiện dụng, đơn giản và hiệu quả. Với geodjango, các nhà phát triển hoàn toàn có thể xây dựng ứng dụng WebGIS một cách nhanh chóng, đơn giản, tiện lợi và dễ bảo trì.


    Tài liệu tham khảo

    Alessandro Pasotti, P. C. (2010). Developing Geospatial software with Python.GFOSS Day. Foligno.
    Creating custom spatial functions within the QGIS application framework using Python. Z-Pulley Inc.
    django. (n.d.). Retrieved from https://www.djangoproject.com/
    Dr. Marco Hugentobler, D. H. (2008). Extending the Functionality of QGIS with Python Plugins. Workshop FOSS4G.
    Etherington, T. R. Python and geographic information system - current applications and future potential inlandscape ecology. The university of AucKland.
    Ganeson, C. (2009). Spatializing your data with PostGIS, GeoDjango, and openlayers. Orelly's OSCON.
    geodjango. (n.d.). Retrieved from http://geodjango.org/
    Mishkovskyi, A. V. (2010). Python and GIS - Nobody expects Python in maps!
    pydev. (n.d.). Retrieved from http://pydev.org/index.html
    Westra, E. (2010). Python Geospatial development. Birmingham, B27 6PA, UK.: PACKT.

    Friday, October 11, 2013