创建Geoserver和Geodatabase
在本教程中,我们将学习如何创建一个地理空间服务器和数据库。服务器将为数据库提供动力,并作为用户和空间数据库之间的网关。
空间数据是包含任何地点的经度和纬度的任何数据。因此,它们提供了关于一个物理位置的信息。空间数据也被称为地理信息系统(GIS)。
Geoserver是一个处理空间数据的服务器,也为地理数据库提供动力。它作为地理数据库和用户之间的纽带,让他们能够访问空间数据。
地理数据库是一个存储空间数据的数据库。它允许用户创建、更新、检索和删除空间数据。这些数据可以存储为点、线或多边形。我们将使用PostgreSQL的一个扩展调用Postgis ,这样数据库就可以处理空间数据。
前提条件
- 对Python、HTML和Jinja模板的基本理解
- PostgreSQL
- PostGIS
在我们开始编码之前,我们需要进行基本的设置。然后,我们将创建并激活一个名为env的新环境。
建立数据库
我们通过安装Postgis ,开始数据库的安装。
我们将从我们的终端创建数据库,并通过运行下面的命令以Postgres user 。确保你在命令执行后输入你的用户密码。
psql -U Postgres
下一步是创建数据库。
CREATE DATABASE geodata
我们需要将数据库连接到项目中,并使用下面的代码在上面启用Postgis扩展。
\c geodata;
CREATE EXTENSION postgis;
\q
我们使用\c geodata; 连接到数据库,同时CREATE EXTENSION postgis; 启用PostGIS扩展,我们使用\q 退出psql 。
下一步是将我们的数据库连接到项目,所以让我们安装Flask、geoalchemy2、flask_sqlalchemy和psycopg2。
pip install flask geoalchemy2 flask_sqlalchemy psycopg2
创建一个新的文件app.py ,并输入以下代码片段。
from flask import Flask
app = Flask(__name__)
app.config['SECRET_KEY'] = 'Thisissecret!'
app.config['SQLALCHEMY_DATABASE_URI']='postgresql://postgres:password@localhost/geodata'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
if __name__ == "__main__":
app.run(host="127.0.0.1", port="5000", debug=True)
我们在app变量中创建了一个新的Flask实例,我们可以在我们的项目中使用。我们还创建了一个秘密密钥,应该改成安全密钥。你可以使用UUID生成一个随机数。最后一节告诉应用程序在条件name== "main"为真时运行。
app.config['SQLALCHEMY_DATABASE_URI']='postgresql://postgres:password@localhost/geodata'
PostgreSQL告诉sqlalchemy,我们使用的是PostgreSQL数据库管理系统。
- Postgres:是我们的数据库用户
- password: 是数据库用户的密码
- geodata:是我们将使用的数据库
我们将使用flask_sqlalchemy将我们的数据库连接到项目中。
from flask_sqlalchemy import SQLAlchemy
导入后,我们将使用 "Sqlalchemy "将实例合并到我们的应用程序。
db = SQLAlchemy(app)
我们将使用db 对象来创建我们的模型并将数据保存到我们的数据库。
现在是时候创建我们的表了。让我们称它为AoiCordinate ,它将有一个名为coordinate 的几何列来存储我们所有的坐标。
class AoiCoordinate(db.Model):
id = db.Column(db.Integer, primary_key=True)
aoi = db.Column(db.String(50), nullable=False)
coordinate = db.Column(Geometry('POLYGON'))
我们将使用Python shell通过导入db对象来创建我们的数据库。
from app import db
db.create_all()
exit()
保存坐标
用户可以通过填写表格和上传geojson 文件或shapefile 来提交他们的坐标,所以让我们创建一个提交端点。
让我们将下面的片段添加到我们的app.py 文件中。
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
aoi = request.form.get('aoi')
file = request.files['file']
read_file = file.read()
file_json = json.loads(read_file)
aoi_coordinate = file_json["features"][0]['geometry']
coordinate = AoiCoordinate(aoi=aoi, coordinate=json.dumps(aoi_coordinate))
db.session.add(coordinate)
db.session.commit()
return aoi
return render_template('index.html')
@app.route('/', methods=['GET', 'POST']) 创建接受GET和POST请求的端点。我们创建一个名为index 的函数,它渲染了index.html 页面。
在这个函数中,我们检查请求是否是POST请求来处理表单。变量aoi 存储用户感兴趣的区域,而file 存储上传的坐标。
使用read() 方法读取文件内容,并使用json. loads() 转换为JSON对象。
aoi_coordinate 变量从file_json 选择Polygon的坐标。坐标变量添加了我们模型中定义的aoi 和coordinate 。
最后,我们将坐标添加到我们的数据库中,并使用db对象提交更改。
Flask使用Jinja模板方法来渲染HTML页面,这就是我们在本教程中要使用的方法。
HTML页面存储在templates文件夹中,所以让我们在根目录下创建一个新的文件夹,名为templates 。在templates文件夹中,我们还将创建一个新的文件,名为``index.html。最后,我们将使用bootstrap 5.1来设计我们的表单。
<form action="{{url_for('index')}}", method="post">
<div class="mb-3">
<label for="exampleInputText" class="form-label">Location</label>
<input type="text" class="form-control" id="exampleInputText" >
</div>
<div class="mb-3">
<label for="formFile" class="form-label">Upload Coordinate</label>
<input class="form-control" name="coordinate" type="file" id="formFile">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
显示坐标
创建另一个路由,它将显示所有保存的坐标。坐标被保存为二进制,所以我们将使用geoalchemy2 to_shape ,将其转换为可读坐标。
我们将导入to_shape ,并使用这些片段来检索我们所有的坐标。
from geoalchemy2.shape import to_shape
@app.route('/all')
def all_coordinate():
coordinates = AoiCoordinate.query.all()
all_cord = []
for location in coordinates:
location_coordinate = to_shape(location.coordinate)
location_aoi = location.aoi
location = {
'location_coordinate': location_coordinate,
'location_aoi': location_aoi
}
all_cord.append(location)
return render_template('all.html', all_coordinates=all_cord)
我们查询了数据库并检索了坐标变量中的所有坐标。由于它们是以二进制存储的,我们需要将它们转换为坐标,方法是在它们之间循环,并将它们追加到空列表all_cord 。
在循环过程中,每个坐标都被保存在location_coordinate 变量中。
位置字典存储了每个位置Aoi和坐标,并被追加到all_coord 列表中。我们将该列表存储在all_coordinates ,并将其传递给all.html 页面。
让我们使用下面的代码,创建扩展了`.的all.html 页面。
{% extends 'base.html' %}
{% block main %}
<div class="container">
<table class="table">
<thead>
<tr>
<th scope="col">AOI</th>
<th scope="col">Coordinate</th>
</tr>
</thead>
<tbody>
{% for coordinate in all_coordinates %}
<tr>
<td>{{coordinate.location_aoi}}</td>
<td>{{coordinate.location_coordinate}}</td>
</tr>
{% endfor %}
</tbody>
</table>
结语
这个教程教我们如何创建一个地理空间服务器和数据库,保存和返回位置坐标。该应用程序可以进一步构建为API服务,并呈现给物流公司,因为他们可以快速协调一个特定的位置。