教你用Django实现一个简单的GIS功能

地理信息系统(Geographic Information System或 Geo-Information system,GIS)有时又称为“地学信息系统”。它是一种特定的十分重要的空间信息系统。它是在计算机硬、软件系统支持下,对整个或部分地球表层(包括大气层)空间中的有关地理分布数据进行采集、储存、管理、运算、分析、显示和描述的技术系统。

看上去挺简单,但是实现起来是挺复杂的,这里面涉及到专用的地理数据库,图层,空间查询等等。

这里,我使用的是Django GEO框架实现一个简单的通过GPS(WGS-84坐标系)坐标查询具体城市功能。

Django是一个python敏捷开发框架,十分方便,这里就不诸多介绍了,就算没有学过,上手也是非常简单的。

django-admin.py startproject gisApp

创建一个叫gisApp的应用

然后 python manage.py startapp ChinaCity

创建了一个叫ChinaCity的可插拔模块

在gisApp目录里面的settings.py中修改INSTALLED_APPS 元组,加入’gisApp’

INSTALLED_APPS = (
    ‘django.contrib.admin‘,
    ‘django.contrib.auth‘,
    ‘django.contrib.contenttypes‘,
    ‘django.contrib.sessions‘,
    ‘django.contrib.messages‘,
    ‘django.contrib.staticfiles‘,
    ‘ChinaCity‘,

然后参考https://docs.djangoproject.com/en/1.7/ref/contrib/gis/这里把类库配置好,把数据库安装上,推荐用postgresql,因为postgresql支持的地理查询功能最强大。

INSTALLED_APPS = (
    ‘django.contrib.admin‘,
    ‘django.contrib.auth‘,
    ‘django.contrib.contenttypes‘,
    ‘django.contrib.sessions‘,
    ‘django.contrib.messages‘,
    ‘django.contrib.staticfiles‘,
    ‘django.contrib.gis‘,
    ‘ChinaCity‘,

我们打算通过使用API调用这个查询功能,用ReSTful风格,所以用到了Django restful framework,十分易用的restful框架

pip install djangorestframework

然后再加一个配置模块

INSTALLED_APPS = (
    ‘django.contrib.admin‘,
    ‘django.contrib.auth‘,
    ‘django.contrib.contenttypes‘,
    ‘django.contrib.sessions‘,
    ‘django.contrib.messages‘,
    ‘django.contrib.staticfiles‘,
    ‘django.contrib.gis‘,
    ‘rest_framework‘,
    ‘ChinaCity‘,

到这里,环境已经配好了,可以开始写功能了

我们要用到中国的城市空间数据,在网上到处都是

下载了一份保存到ChinaCity/data/china/CHN_adm2.shp

使用django自动的扫描功能

python manage.py ogrinspect SMGIS/data/china/CHN_adm2.shp ChinaCity –mapping –multi

得到的数据如下

class ChinaCity(models.Model):
    id_0 = models.IntegerField()
    iso = models.CharField(max_length=3)
    name_0 = models.CharField(max_length=75)
    id_1 = models.IntegerField()
    name_1 = models.CharField(max_length=75)
    id_2 = models.IntegerField()
    name_2 = models.CharField(max_length=75)
    nl_name_2 = models.CharField(max_length=75)
    varname_2 = models.CharField(max_length=150)
    type_2 = models.CharField(max_length=50)
    engtype_2 = models.CharField(max_length=50)
    geom = models.MultiPolygonField(srid=-1)
    objects = models.GeoManager()

# Auto-generated `LayerMapping` dictionary for ChinaCity model
chinacity_mapping = {
    ‘id_0‘ : ‘ID_0‘,
    ‘iso‘ : ‘ISO‘,
    ‘name_0‘ : ‘NAME_0‘,
    ‘id_1‘ : ‘ID_1‘,
    ‘name_1‘ : ‘NAME_1‘,
    ‘id_2‘ : ‘ID_2‘,
    ‘name_2‘ : ‘NAME_2‘,
    ‘nl_name_2‘ : ‘NL_NAME_2‘,
    ‘varname_2‘ : ‘VARNAME_2‘,
    ‘type_2‘ : ‘TYPE_2‘,
    ‘engtype_2‘ : ‘ENGTYPE_2‘,
    ‘geom‘ : ‘MULTIPOLYGON‘,
}

稍作修改,我们在ChinaCity.models新建一个类

class ChinaCity(models.Model):
    id_0 = models.IntegerField()
    iso = models.CharField(max_length=3)
    name_0 = models.CharField(max_length=75)
    id_1 = models.IntegerField()
    name_1 = models.CharField(max_length=75)
    id_2 = models.IntegerField()
    name_2 = models.CharField(max_length=75)
    nl_name_2 = models.CharField(max_length=75)
    varname_2 = models.CharField(max_length=150)
    type_2 = models.CharField(max_length=50)
    engtype_2 = models.CharField(max_length=50)
    geom = models.MultiPolygonField(srid=4326)
    objects = models.GeoManager()

然后新建一个Load.py

chinacity_mapping = {
    ‘id_0‘ : ‘ID_0‘,
    ‘iso‘ : ‘ISO‘,
    ‘name_0‘ : ‘NAME_0‘,
    ‘id_1‘ : ‘ID_1‘,
    ‘name_1‘ : ‘NAME_1‘,
    ‘id_2‘ : ‘ID_2‘,
    ‘name_2‘ : ‘NAME_2‘,
    ‘nl_name_2‘ : ‘NL_NAME_2‘,
    ‘varname_2‘ : ‘VARNAME_2‘,
    ‘type_2‘ : ‘TYPE_2‘,
    ‘engtype_2‘ : ‘ENGTYPE_2‘,
    ‘geom‘ : ‘MULTIPOLYGON‘,
}

world_shp = os.path.abspath(os.path.join(os.path.dirname(__file__), ‘data/china/CHN_adm2.shp‘))

def run(verbose=True):
    lm = LayerMapping(ChinaCity, world_shp, chinacity_mapping,
                      transform=False, encoding=‘UTF-8‘)

    lm.save(strict=False, verbose=verbose)

打开shell

python manage.py shell

from gisApp.ChinaCity import Load
load.run()

这样我们就已经导入数据到空间数据库了

接下来我们要写api了

新建一个serializers.py

from rest_framework import serializers
from .models import ChinaCity

class ChinaCitySerializer(serializers.ModelSerializer):
    class Meta:
        model = ChinaCity
        fields = (‘name_2‘,)

这是一个序列化类

然后我们在views中

from rest_framework.views import APIView
from .models import ChinaCity
from .serializers import ChinaCitySerializer
from rest_framework.response import Response
from rest_framework import permissions

class ChinaCityQuery(APIView):
    permission_classes = (permissions.AllowAny, )
    def getCityObj(self, position):
        print position
        #try:
        return ChinaCity.objects.filter(geom__contains=position)[0]
        #except:
            #raise Http404
    def get(self, request, position, format=None):
        position = ‘POINT(‘ + position + ‘)‘
        city = self.getCityObj(position)
        return Response( ChinaCitySerializer(city).data )

接下来在gisApp中的urls.py中

from ChinaCity.views import *
#gis
urlpatterns += [
    url(r‘^api/gis/city/(?P<position>[\d\s\.]+)$‘, ChinaCityQuery.as_view()),
]

已经写好了,打开django自带的服务器

python manage.py runserver

在浏览器中打开

http://localhost:8000/api/gis/city/116.395645%2039.929986

其中最后116.395645%2039.929986是坐标

大功告成

时间: 2024-11-08 21:00:28

教你用Django实现一个简单的GIS功能的相关文章

PHP实现一个简单url路由功能

如果一个页面的内容呈现,需要根据url上传递的参数来进行渲染.很多时候可能是这样子写:xxx.com/xx?c=x&m=x& t=..,而我们看到的url往往是这样子的(以新浪微游戏的咖啡恋人为例) game.weibo.com/ilovecoffee….这种URL设计看上去比前一种更好一点:) 如果我们访问一下不存在的游戏应用,例如game.weibo.com/ilovecoffee222,则会输出如下的错误提示: game.weibo.com后面匹配到的项,指向了某个php页面,然后根

jQuery实现一个简单的购物车功能

最近由于工作需要的原因,开始系统学习jQuery的知识,然后跟着一个视频教程做了一个购物车的功能,现总结如下. 第一步:准备HTML页面,代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.

使用JS完成一个简单的计算器功能

使用JS完成一个简单的计算器功能.实现2个输入框中输入整数后,点击第三个输入框能给出2个整数的加减乘除. 提示:获取元素的值设置和获取方法为:例:赋值:document.getElementById("id").value = 1: 取值:var = document.getElementById("id").value: 任务 第一步: 创建构建运算函数count(). 第二步: 获取两个输入框中的值和获取选择框的值. 提示:document.getElement

django创建一个简单的web站点

一.新建project 使用Pycharm,File->New Project-,选择Django,给project命名 (project不能用test命名) 新建的project目录如下: settings.py:工程相关的配置 urls.py:网站访问入口,对应到views wigs.py:部署相关 manage.py:执行命令 templates:html等静态文件 备注:新建工程后需要安装django的lib包,然后验证django是否安装成功 >>> import dja

一步一步教你使用CGI实现一个简单的后门

程序实例1:使用CGI实现文件定向操作 #include <stdio.h> #include <stdlib.h> #include <string.h> void main() { //设置HTML语言 printf("Content-type:text/html\n\n"); //文件定向操作 char* str = "ipconfig > 1.txt"; system(str); } 将上面的代码编译成的exe文件拷

Django创建一个简单的blog

1. 使用django-admin.py 创建mysite项目 [email protected]:~/PycharmProjects$ django-admin.py startproject mysite 2. 进入项目目录中,启动服务器,测试连通性 [email protected]:~/PycharmProjects$ cd mysite/ [email protected]-ThinkPad-T450:~/PycharmProjects/mysite$ ./manage.py runs

手对手的教你用canvas画一个简单的海报

啦啦啦,首先说下需求,产品想让用户在我们app内,分享一张图片到微信.qq等平台.图片中包含用户的姓名.头像.和带着自己信息的二维码.然后,如何生成这张海报呢~~~首先我们老大告诉我有一个插件叫html2canvas.其作用就是可以将dom节点转化成图片,是个不错的东西.我试验了下.确实可以,但~这个插件有点大啊,为了满足海报的这个需求引入这么大的东西感觉很亏!!!所以,还是自己画一个~首先先上效果图 当当当当~~~最后生成的海报中包括头像和姓名与二维码,当然图上的二维码是百度的二维码~最后生成

django的一个简单应用

django-admin startproject mysite 创建一个django项目 python manage.py startapp blog 创建应用命令 model 创建数据库 admin 管理数据库 pycharm创建的根目录在环境变量中 python manage.py runserver 8080 启动项目 return HttpResponse("hello") render(request,"index_html",{“time”:t}) 

Django 部署一个简单的用户后台

第一步编写models.py,下面是通过在myauth.py 文件models.py 的用户内容,再在models.py中引入这个文件 models.py内容如下: from __future__ import unicode_literals from django.db import models import myauth # Create your models here. myauth.py内容 #!/usr/bin/python # -*- coding: utf-8 -*- __a