如何创建一个Geoserver和一个地理数据库

358 阅读5分钟

创建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的坐标。坐标变量添加了我们模型中定义的aoicoordinate

最后,我们将坐标添加到我们的数据库中,并使用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服务,并呈现给物流公司,因为他们可以快速协调一个特定的位置。