El análisis geoespacial no se limita a un solo software de escritorio o un kernel de Python; si usa un análisis espacial masivo o si trabaja en un equipo que quiere un resultado espacial específico, el uso de un Rest Api puede ser conveniente. Hemos desarrollado un tutorial básico, introductorio pero claro de una Rest Api geoespacial que implementa el método Post y el método Get y devuelve el centroide de un polígono y la lista de elementos con sus coordenadas respectivamente. El tutorial se realiza en Windows, sin embargo, se espera que un servidor Rest real que ejecuta varias consultas espaciales de alta energía se ejecute en Linux.
Tutorial
Código
Este es el código del servidor Flask:
# app.py
from flask import Flask, request, jsonify
from shapely.geometry import shape
import json
app = Flask(__name__)
polygons = [
]
def _find_next_id():
print(polygons)
if len(polygons) > 0:
return max(polygon["id"] for polygon in polygons) + 1
else:
return 1
@app.get("/centroids")
def get_countries():
return jsonify(polygons)
@app.post("/centroids")
def add_polygon():
if request.is_json:
polygon = json.loads(request.get_json())
polyCoords = polygon["features"][0]["geometry"]["coordinates"]
polyShape = shape({
"type": "MultiPolygon",
"coordinates":polyCoords
})
polygon["centroidx"] = polyShape.centroid.x
polygon["centroidy"] = polyShape.centroid.y
polygon["id"] = _find_next_id()
polygon["name"] = polygon["features"][0]["properties"]["name"]
#remove unwanted keys
polygon.pop("features")
polygon.pop("type")
polygons.append(polygon)
return polygon, 201
return {"error": "Request must be JSON"}, 415
Este es código que llama al servidor:
import requests, json
import folium
import geopandas as gpd
#open geospatial data
facDf = gpd.read_file('../In/schoolsHospitalsPoliceFire.gpkg')
#plot polygon
facDf.plot()
<AxesSubplot:>
#show dataframehead
facDf.head()
| amenity | name | geometry | |
|---|---|---|---|
| 0 | school | Pioneer Elementary School | MULTIPOLYGON (((-116.34768 43.64752, -116.3475... |
| 1 | school | Centennial High School | MULTIPOLYGON (((-116.33940 43.65290, -116.3389... |
| 2 | school | Joplin Elementary School | MULTIPOLYGON (((-116.33274 43.65530, -116.3300... |
| 3 | school | Lowell Scott Middle School | MULTIPOLYGON (((-116.35409 43.65206, -116.3539... |
| 4 | school | Cecil D. Andrus Elementary School | MULTIPOLYGON (((-116.34585 43.66075, -116.3447... |
#get the first row
firstRow = facDf.loc[[0]]
type(firstRow)
geopandas.geodataframe.GeoDataFrame#first row as json
rowJson = firstRow.to_json()
rowJson
'{"type": "FeatureCollection", "features": [{"id": "0", "type": "Feature", "properties": {"amenity": "school", "name": "Pioneer Elementary School"}, "geometry": {"type": "MultiPolygon", "coordinates": [[[[-116.347681, 43.6475172], [-116.3475058, 43.6475166], [-116.346734, 43.6475155], [-116.3466762, 43.6475261], [-116.3466453, 43.6475518], [-116.3466085, 43.6475852], [-116.3465764, 43.6475987], [-116.3465489, 43.6476038], [-116.3465174, 43.6476076], [-116.3464713, 43.6476106], [-116.346431, 43.6476106], [-116.3463823, 43.6476086], [-116.3463207, 43.6476059], [-116.346322, 43.6474886], [-116.3444521, 43.6474892], [-116.3444149, 43.6474889], [-116.3444291, 43.6458487], [-116.3445183, 43.6458486], [-116.3477109, 43.6458464], [-116.347681, 43.6475172]]]]}}]}'#url of the rest api
apiUrl = "http://127.0.0.1:5000/centroids"
#get all polygons, none to the moment
response = requests.get(apiUrl)
response.json()
[{'centroidx': -116.34606811481463,
'centroidy': 43.64667797982817,
'id': 1,
'name': 'Pioneer Elementary School'},
{'centroidx': -116.33714292646543,
'centroidy': 43.65049255824704,
'id': 2,
'name': 'Centennial High School'}]#add one poly
response = requests.post(apiUrl,json=rowJson)
responseDict = response.json()
responseDict
{'centroidx': -116.34606811481463,
'centroidy': 43.64667797982817,
'id': 3,
'name': 'Pioneer Elementary School'}import folium
m = folium.Map(
location=[responseDict['centroidy'],responseDict['centroidx']],
tiles="cartodbpositron",
zoom_start=16,
)
centroidMarker = folium.Marker(location=[responseDict['centroidy'],responseDict['centroidx']])
centroidMarker.add_to(m)
polyJson = folium.GeoJson(data=rowJson,
style_function=lambda x: {'fillColor': 'orange'})
polyJson.add_to(m)
m
#get all polygons, one to the moment
response = requests.get(apiUrl)
response.json()
[{'centroidx': -116.34606811481463,
'centroidy': 43.64667797982817,
'id': 1,
'name': 'Pioneer Elementary School'},
{'centroidx': -116.33714292646543,
'centroidy': 43.65049255824704,
'id': 2,
'name': 'Centennial High School'},
{'centroidx': -116.34606811481463,
'centroidy': 43.64667797982817,
'id': 3,
'name': 'Pioneer Elementary School'}]### All step involved for second polygon
#get the second row
secondRow = facDf.loc[[1]].to_json()
#url of the rest api
apiUrl = "http://127.0.0.1:5000/centroids"
#add one poly
response = requests.post(apiUrl,json=secondRow)
#get respones
responseDict = response.json()
print(responseDict['centroidx'],responseDict['centroidy'])
-116.33714292646543 43.65049255824704#get all polygons, two to the moment
response = requests.get(apiUrl)
response.json()
[{'centroidx': -116.34606811481463,
'centroidy': 43.64667797982817,
'id': 1,
'name': 'Pioneer Elementary School'},
{'centroidx': -116.33714292646543,
'centroidy': 43.65049255824704,
'id': 2,
'name': 'Centennial High School'},
{'centroidx': -116.34606811481463,
'centroidy': 43.64667797982817,
'id': 3,
'name': 'Pioneer Elementary School'},
{'centroidx': -116.33714292646543,
'centroidy': 43.65049255824704,
'id': 4,
'name': 'Centennial High School'}]

FloPy es la librerìa de Python que construye y ejecuta modelos MODFLOW; esta librería se ha mejorado para proporcionar un soporte completo de MODFLOW 6 y la mayor parte de su desarrollo está relacionado con la funcionalidad de MODFLOW 6, herramientas para usar datos espaciales vectoriales, rasters y funcionalidades comunes de ploteo y exportación.
Python es un lenguaje de programación sencillo y potente; su simplicidad es notable en comparación con otros lenguajes de programación y su potencia se basa en la cantidad de herramientas disponibles para las diferentes áreas de estudio.
Hemos desarrollado un programa completo en modelamiento de aguas subterráneas con MODFLOW y FloPy que abarca desde los temas esenciales en Python hasta casos aplicados de modelamiento regional e intrusión marina. El programa está diseñado para brindarle al estudiante un enfoque metodológico para aprender FloPy basado en una serie de ejemplos aplicados junto con las opiniones/experiencias del profesor y la revisión del software.