搜索引擎是个好东西,GIS也是个好东西。当前还有Django和Ionic。最后效果图
![elasticsearch_ionic_map][1] ![elasticsearch_ionic_info_page][2]
##构架设计
对我们的需求进行简要的思考后,设计出了下面的一些简单的架构。
![Django ElasticSearch Ionic 架构][3]
###GIS架构说明 —— 服务端
简单说明:
- 用户在前台或者后台创建数据。
- 在model保存数据的时候,会调用Google的API解析GPS
- 在haystack的配置中设置实时更新,当数据创建的时候自动更新索引
- 数据被ElasticSearch索引
下面是框架的一些简单的介绍
####Django
> [Django](http://www.phodal.com/blog/tag/django/) 是一个开放源代码的Web应用框架,由Python写成。采用了MVC的软件设计模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的。并于2005年7月在BSD许可证下发布。这套框架是以比利时的吉普赛爵士吉他手Django Reinhardt来命名的。
> [Django](http://www.phodal.com/blog/tag/django/) 的主要目标是使得开发复杂的、数据库驱动的网站变得简单。Django注重组件的重用性和“可插拔性”,敏捷开发和DRY法则(Don't Repeat Yourself)。在Django中Python被普遍使用,甚至包括配置文件和数据模型。
首先考虑Django,而不是其他Node或者Ruby框架的原因是:
- 内置认证系统
- 内置CSRF
当然这是其他框架也所拥有的,主要特性还有:
- 一个表单序列化及验证系统,用于HTML表单和适于数据库存储的数据之间的转换。
- 一套协助创建地理信息系统(GIS)的基础框架
最后一个才是亮点,内置GIS,虽然没怎么用到,但是至少在部署上还是比较方便的。
###Haystack
> Haystack provides modular search for Django. It features a unified, familiar API that allows you to plug in different search backends (such as Solr, Elasticsearch, Whoosh, Xapian, etc.) without having to modify your code.
Haystack是为Django提供一个搜索模块blabla..,他的主要特性是可以
> write your search code once and choose the search engine you want it to run on
也就是说你只需要写你的代码选择你的搜索引擎就可以工作了。
###ElasticSearch
在上面的Haystack提供了这些一堆的搜索引擎,当然支持地点搜索的只有``Solr``和``ElasticSearch``,他们支持的空间搜索有:
- within
- dwithin
- distance
- order_by(‘distance’)
- polygon
在文档上没有写Solr的polygon搜索,但是实际上也是支持的(详细见这篇文章: [google map solr polygon 搜索](http://www.phodal.com/blog/google-map-width-solr-use-polygon-search/,用的地图是谷歌,所以需要先学会访问谷歌)。
至于为什么用的是ElasticSearch,是因为之前用Solr做过。。。
###GIS架构说明 —— 客户端
####简单说明 —— GET
1. 当我们访问Map View的时候,会调用HTML5获取用户的位置
2. 根据用户的位置定位,设置缩放
3. 根据用户的位置发出ElasticSearch请求,返回结果中带上距离
4. 显示
####简单说明 —— POST
1. 用户填写数据会发给Django API,并验证
2. 成功时,存入数据库,更新索引。
###Ionic
> Ionic提供了一个免费且开源的移动优化HTML,CSS和JS组件库,来构建高交互性应用。基于Sass构建和AngularJS 优化。
用到的主要是AngularJS,之前用他写过三个APP。
###Django REST Framework
与Django Tastypie相比,DRF的主要优势在于Web界面的调试。
##其他
因为选的是比较熟悉的技术栈,所以也只花了不到两天的业余时间完成的。或许,这也是全栈程序员的优势所在。
服务端代码: [https://github.com/phodal/django-elasticsearch](https://github.com/phodal/django-elasticsearch)
客户端代码: [https://github.com/phodal/ionic-elasticsearch](https://github.com/phodal/ionic-elasticsearch)
下一章: [GIS 移动应用实战 —— Django Haystack ElasticSearch 环境准备](http://www.phodal.com/blog/django-elasticsearch-haystack-prepare-enviorment/)
[1]: /static/media/uploads/elasticsearch_ionic_map.jpg
[2]: /static/media/uploads/elasticsearch_ionic_info_page.jpg
[3]: /static/media/uploads/struct.png
在一篇中,我们介绍了 [《Django ElasticSearch Ionic 打造 GIS 移动应用 —— 架构设计》](http://www.phodal.com/blog/django-elasticsearch-ionic-build-gis-application/)。接着,我们就开始实战了,内容也很简单。
##Django GIS准备
1.创建虚拟环境
virtualenv -p /usr/bin/python2.67 django-elasticsearch
2.创建项目
为了方便,这里用的是Mezzanine CMS,相比Django的主要优势是,以后扩展方便。但是对于Django也是可以的。
3.安装依赖
这里我的所有依赖有
django-haystack
Mezzanine==3.1.10
djangorestframework
pygeocoder
elasticsearch
安装
pip install requirements.txt
4.安装ElasticSearch
CentOS
wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.4.2.zip
sudo unzip elasticsearch-1.4.2 -d /usr/local/elasticsearch
rm elasticsearch-1.4.2.zip
cd /usr/local/elasticsearch/elasticsearch-1.4.2/
./bin/plugin install elasticsearch/elasticsearch-cloud-aws/2.4.1
curl -XGET http://localhost:9200
Mac OS
brew install elasticsearch
5.Django Geo环境搭建
CentOS等GNU/Linux系统: 可以参照[CentOS Django Geo 环境搭建](http://www.phodal.com/blog/install-geo-django-in-centos/)
MacOS: [Mac OS Django Geo 环境搭建](http://www.phodal.com/blog/django-elasticsearch-geo-solution/)
##配置Django
###配置Haystack
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.elasticsearch_backend.ElasticsearchSearchEngine',
'URL': 'http://127.0.0.1:9200/',
'INDEX_NAME': 'haystack',
},
}
``HAYSTACK_SIGNAL_PROCESSOR``是为了可以实时处理。
``HAYSTACK_CONNECTIONS`` 则是配置搜索引擎用的。
###配置Django
在``settings.py``中的``INSTALLED_APPS``添加
"haystack",
"rest_framework",
接着
python manage.py createdb
python manage.py migreate
运行
python manage.py runserver
##其他:
服务端代码: [https://github.com/phodal/django-elasticsearch](https://github.com/phodal/django-elasticsearch)
客户端代码: [https://github.com/phodal/ionic-elasticsearch](https://github.com/phodal/ionic-elasticsearch)
上一篇中我们说到了[Django Haystack ElasticSearch 环境准备](http://www.phodal.com/blog/django-elasticsearch-haystack-prepare-enviorment/),接着实战啦~~
官方有一个简单的文档说明空间搜索—— [Spatial Search](http://django-haystack.readthedocs.org/en/latest/spatial.html)
里面只有``Solr``和``ElasticSearch``是支持的,当然我们也不需要这么复杂的特性。
创建Django app名为nx,目录结构如下
.
|______init__.py
|____api.py
|____models.py
|____search_indexes.py
|____templates
| |____search
| | |____indexes
| | | |____nx
| | | | |____note_text.txt
api.py是后面要用的。
###Django Haystack Model创建
而一般的model没有什么区别,除了修改了save方法
from django.contrib import admin
from django.contrib.gis.geos import Point
from django.core import validators
from django.utils.translation import ugettext_lazy as _
from django.db import models
from pygeocoder import Geocoder
class Note(models.Model):
title = models.CharField("标题", max_length=30, unique=True)
latitude = models.FloatField(blank=True)
longitude = models.FloatField(blank=True)
def __unicode__(self):
return self.title
def save(self, *args, **kwargs):
results = Geocoder.geocode(self.province + self.city + self.address)
self.latitude = results[0].coordinates[0]
self.longitude = results[0].coordinates[1]
super(Note, self).save(*args, **kwargs)
def get_location(self):
return Point(self.longitude, self.latitude)
def get_location_info(self):
return self.province + self.city + self.address
admin.site.register(Note)
通过``Geocoder.geocode`` 解析用户输入的地址,为了方便直接后台管理了。
###创建search_index
在源码的目录下有一个``search_indexes.py``的文件就是用于索引用的。
from haystack import indexes
from .models import Note
class NoteIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
title = indexes.CharField(model_attr='title')
location = indexes.LocationField(model_attr='get_location')
location_info = indexes.CharField(model_attr='get_location_info')
def get_model(self):
return Note
与些同时我们还需要在``templates/search/indexes/nx/``目录中有``note_text.txt``里面的内容是:
{{ object.title }}
{{ object.get_location }}
{{ object.get_location_info }}
##创建数据
migrate数据库
python manage.py migrate
run
python manage.py runserver
接着我们就可以后台创建数据了。 打开: http://127.0.0.1:8000/admin/nx/note/,把除了``Latitude``和``Longitude``以外的数据都一填——经纬度是自动生成的。就可以创建数据了。
###测试
访问 http://localhost:9200/haystack/_search
或者
curl -XGET http://127.0.0.1:9200/haystack/_search
##其他:
服务端代码: [https://github.com/phodal/django-elasticsearch](https://github.com/phodal/django-elasticsearch)
客户端代码: [https://github.com/phodal/ionic-elasticsearch](https://github.com/phodal/ionic-elasticsearch)
在上一篇[《GIS 移动应用实战 —— Django Haystack ElasticSearch 构建》](http://www.phodal.com/blog/django-elasticsearch-ionic-build-gis-application-create-model/)中,我们构建了我们的服务端,可以通过搜索搜索到结果,这一篇,我们来构建一个简单的搜索。
最后效果如下图所示:
![Ionic ElasticSearch][1]
##开始之前
如果你没有Ionic的经验,可以参考一下之前的一些文章:[《HTML5打造原生应用——Ionic框架简介与Ionic Hello World》](http://www.phodal.com/blog/ionic-development-android-ios-windows-phone-application/)。
我们用到的库有:
- elasticsearch
- ionic
- ngCordova
将他们添加到``bower.json``,然后
bower install
吧
##Ionic ElasticSearch 创建页面
1.引入库
在``index.html``中添加
接着开始写我们的搜索模板``tab-search.html``
```html
简介: {{result.body}}{{result.title}}
" + feature.get('distance') + "公里
" }); $(element).popover('show'); } else { $(element).popover('destroy'); } }); 当用户点击时,调用Bootstrap的Popover来显示信息。 ##其他: 服务端代码: [https://github.com/phodal/django-elasticsearch](https://github.com/phodal/django-elasticsearch) 客户端代码: [https://github.com/phodal/ionic-elasticsearch](https://github.com/phodal/ionic-elasticsearch) [1]: /static/media/uploads/elasticsearch_ionit_map.jpg