Compare commits
No commits in common. "67f1bb2c80a28a4cb384c4875bde1b7b05eab630" and "11c8c73319740520eb142359e310874a1cbf2c86" have entirely different histories.
67f1bb2c80
...
11c8c73319
|
@ -1,12 +1,10 @@
|
||||||
from flask import Flask, jsonify, request, json, Response, send_from_directory, abort
|
from flask import Flask, request, json, Response
|
||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
import orjson, os
|
import orjson
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
CORS(app)
|
CORS(app)
|
||||||
|
|
||||||
FILES_DIRECTORY = '../data/'
|
|
||||||
|
|
||||||
@app.route('/bitcoin_business_growth_by_country', methods=['GET'])
|
@app.route('/bitcoin_business_growth_by_country', methods=['GET'])
|
||||||
def business_growth():
|
def business_growth():
|
||||||
# Parse args from request
|
# Parse args from request
|
||||||
|
@ -38,26 +36,45 @@ def business_growth():
|
||||||
# Return json
|
# Return json
|
||||||
return Response(json.dumps(sorted_data), mimetype='application/json')
|
return Response(json.dumps(sorted_data), mimetype='application/json')
|
||||||
|
|
||||||
@app.route('/get_json/<filename>', methods=['GET'])
|
@app.route('/price', methods=['GET'])
|
||||||
def get_json(filename):
|
def price():
|
||||||
file_path = os.path.join(FILES_DIRECTORY, filename)
|
|
||||||
if not os.path.isfile(file_path):
|
|
||||||
abort(404)
|
|
||||||
|
|
||||||
with open(file_path, 'r') as file:
|
# Open json locally
|
||||||
data = json.load(file)
|
with open('../data/final__price.json', 'rb') as f:
|
||||||
|
data = orjson.loads(f.read())
|
||||||
|
|
||||||
return jsonify(data)
|
# Return json
|
||||||
|
return Response(json.dumps(data), mimetype='application/json')
|
||||||
|
|
||||||
@app.route('/download/<filename>', methods=['GET'])
|
@app.route('/miner_rewards', methods=['GET'])
|
||||||
def download_file(filename):
|
def miner_rewards():
|
||||||
try:
|
|
||||||
return send_from_directory(FILES_DIRECTORY, filename, as_attachment=True)
|
|
||||||
except FileNotFoundError:
|
|
||||||
abort(404)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
# Open json locally
|
||||||
app.run(debug=True)
|
with open('../data/final__miner_rewards.json', 'rb') as f:
|
||||||
|
data = orjson.loads(f.read())
|
||||||
|
|
||||||
|
# Return json
|
||||||
|
return Response(json.dumps(data), mimetype='application/json')
|
||||||
|
|
||||||
|
@app.route('/hashrate', methods=['GET'])
|
||||||
|
def hashrate():
|
||||||
|
|
||||||
|
# Open json locally
|
||||||
|
with open('../data/dev/final__hashrate.json', 'rb') as f:
|
||||||
|
data = orjson.loads(f.read())
|
||||||
|
|
||||||
|
# Return json
|
||||||
|
return Response(json.dumps(data), mimetype='application/json')
|
||||||
|
|
||||||
|
@app.route('/feerates', methods=['GET'])
|
||||||
|
def feerates():
|
||||||
|
|
||||||
|
# Open json locally
|
||||||
|
with open('../data/final__feerate_percentiles.json', 'rb') as f:
|
||||||
|
data = orjson.loads(f.read())
|
||||||
|
|
||||||
|
# Return json
|
||||||
|
return Response(json.dumps(data), mimetype='application/json')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run()
|
app.run()
|
||||||
|
|
|
@ -4,11 +4,7 @@ toc: False
|
||||||
|
|
||||||
# Grounded Insights from Open Data
|
# Grounded Insights from Open Data
|
||||||
|
|
||||||
This site is currently under construction. The direction I intend for this site to take is as a place to publish analytical insights derived from open data. I have a page called [Data Lab](/data-lab) where I publish interactive analytical dashboards, a blog to publish tutorials and thoughts on various related topics, and a [data downloads](/data-download) page for data access.
|
Data is often chaotic and dispersed. This requires us to build solid data pipelines to efficiently transform data into a unified and useful format.
|
||||||
|
|
||||||
I'm interested in a broad set of topics such as Linux, analytics and data engineering, GIS and bitcoin. So expect to see content related to these topics published on this site.
|
|
||||||
|
|
||||||
I strongly believe in the philosophy of [Free Software](https://www.gnu.org/philosophy/free-sw.html) and [Open Data](https://en.wikipedia.org/wiki/Open_data). Therefore, all material on this site is released into the public domain unless otherwise specified. For more information, see [here](/license).
|
|
||||||
|
|
||||||
### Explore Based Data
|
### Explore Based Data
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ The final image looks like this:
|
||||||
It's possible to download the entire SRTM (Shuttle Radar Topography Mission) satellite imagery dataset and insert it into a Postgres database for personal use. This can be helpful for if you need global elevation data for your analysis and don't want to be limited by third-parties APIs.
|
It's possible to download the entire SRTM (Shuttle Radar Topography Mission) satellite imagery dataset and insert it into a Postgres database for personal use. This can be helpful for if you need global elevation data for your analysis and don't want to be limited by third-parties APIs.
|
||||||
|
|
||||||
The SRTM is a near-global dataset of elevation data with a resolution of 1-arc-second (30m). More information is available from [USGS](https://www.usgs.gov/centers/eros/science/usgs-eros-archive-digital-elevation-shuttle-radar-topography-mission-srtm?qt-science_center_objects=0#qt-science_center_objects).
|
The SRTM is a near-global dataset of elevation data with a resolution of 1-arc-second (30m). More information is available from [USGS](https://www.usgs.gov/centers/eros/science/usgs-eros-archive-digital-elevation-shuttle-radar-topography-mission-srtm?qt-science_center_objects=0#qt-science_center_objects).
|
||||||
In this guide we will go through the process of downloading the data, inserting it into a Postgres database with PostGIS, then querying the final result to create a DEM for any country or region.
|
In this guide we will go through downloading the data, inserting it into a Postgres database with PostGIS, then querying the final result to create a DEM for any country or region.
|
||||||
|
|
||||||
This guide assumes you are using Linux (this may also apply to other Unix like systems such as MacOS) and have a Postgres database with the PostGIS extension installed. More information on how to do this can be found on the [PostGIS](https://postgis.net/documentation/getting_started/) website.
|
This guide assumes you are using Linux (this may also apply to other Unix like systems such as MacOS) and have a Postgres database with the PostGIS extension installed. More information on how to do this can be found on the [PostGIS](https://postgis.net/documentation/getting_started/) website.
|
||||||
|
|
||||||
|
@ -51,8 +51,6 @@ Next we can run the following command to download the rasters. This will take so
|
||||||
aws s3 cp s3://raster/SRTM_GL1/ . --recursive --endpoint-url https://opentopography.s3.sdsc.edu --no-sign-request
|
aws s3 cp s3://raster/SRTM_GL1/ . --recursive --endpoint-url https://opentopography.s3.sdsc.edu --no-sign-request
|
||||||
{{</ highlight >}}
|
{{</ highlight >}}
|
||||||
|
|
||||||
If you'd prefer to download specific rasters or rasters for a region instead, you can checkout this [website](https://dwtkns.com/srtm30m/).
|
|
||||||
|
|
||||||
## Using raster2pgsql to import raster tiles into PostGIS
|
## Using raster2pgsql to import raster tiles into PostGIS
|
||||||
Now we have the data downloaded on our system, we can import it into our database.
|
Now we have the data downloaded on our system, we can import it into our database.
|
||||||
If we look inside the SRTM_GL1_srtm directory, we can see all of the 14280 raster files:
|
If we look inside the SRTM_GL1_srtm directory, we can see all of the 14280 raster files:
|
||||||
|
@ -220,7 +218,5 @@ vacuum analyze "dem"."singapore_srtm";
|
||||||
|
|
||||||
Looks much better!
|
Looks much better!
|
||||||
|
|
||||||
This DEM raster of Singapore is available for download from the downloads page [here](/data-downloads/singapore-srtm)
|
|
||||||
|
|
||||||
#### Citations
|
#### Citations
|
||||||
NASA Shuttle Radar Topography Mission (SRTM)(2013). Shuttle Radar Topography Mission (SRTM) Global. Distributed by OpenTopography. https://doi.org/10.5069/G9445JDF. Accessed: 2024-08-06
|
NASA Shuttle Radar Topography Mission (SRTM)(2013). Shuttle Radar Topography Mission (SRTM) Global. Distributed by OpenTopography. https://doi.org/10.5069/G9445JDF. Accessed: 2024-08-06
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
---
|
|
||||||
title: "Data Downloads"
|
|
||||||
---
|
|
||||||
|
|
||||||
Data available for download
|
|
|
@ -1,17 +0,0 @@
|
||||||
---
|
|
||||||
title: 'Singapore SRTM DEM (Data Download)'
|
|
||||||
date: 2024-08-06T12:15:44+01:00
|
|
||||||
author:
|
|
||||||
name: "Sam Chance"
|
|
||||||
header_image: '/pics/blog/batch-import-postgis-rasters/singapore-final.webp'
|
|
||||||
summary: "Download the Shuttle Radar Topography Mission (SRTM) Digital Elevation Model (DEM) of Singapore"
|
|
||||||
toc: false
|
|
||||||
tags: ["QGIS", "SRTM", "DEM", "Raster", "download"]
|
|
||||||
---
|
|
||||||
{{< figure src="/pics/blog/batch-import-postgis-rasters/singapore-final.webp" width="300">}}
|
|
||||||
Download the Digital Elevation Model featured in [this](/blog/batch-import-postgis-rasters/) blog.
|
|
||||||
|
|
||||||
{{< download-data src="http://localhost:5000/download/singapore-srtm-dem.tif" name="singapore-srtm-dem.tif" >}}
|
|
||||||
|
|
||||||
#### Citations
|
|
||||||
NASA Shuttle Radar Topography Mission (SRTM)(2013). Shuttle Radar Topography Mission (SRTM) Global. Distributed by OpenTopography. https://doi.org/10.5069/G9445JDF. Accessed: 2024-08-06
|
|
|
@ -5,7 +5,6 @@
|
||||||
<a href="#" class="dropbtn">Projects</a>
|
<a href="#" class="dropbtn">Projects</a>
|
||||||
<div class="navbar-link-dropdown-content">
|
<div class="navbar-link-dropdown-content">
|
||||||
<a href="/data-lab">Data Lab</a>
|
<a href="/data-lab">Data Lab</a>
|
||||||
<a href="/data-downloads">Data Downloads</a>
|
|
||||||
<a href="https://semitamaps.com">Map Printing</a>
|
<a href="https://semitamaps.com">Map Printing</a>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
<button class="download-button" onclick="downloadFile('{{ .Get "src" }}', '{{ .Get "name" }}')">
|
|
||||||
Download
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
async function downloadFile(url, name) {
|
|
||||||
try {
|
|
||||||
const response = await fetch(url);
|
|
||||||
const blob = await response.blob();
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = URL.createObjectURL(blob);
|
|
||||||
link.download = name;
|
|
||||||
document.body.appendChild(link);
|
|
||||||
link.click();
|
|
||||||
document.body.removeChild(link);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error downloading the file:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -303,7 +303,3 @@ ol {
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.download-button {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ const myChart = echarts.init(document.getElementById("chart"));
|
||||||
|
|
||||||
async function fetchDataForChart() {
|
async function fetchDataForChart() {
|
||||||
try {
|
try {
|
||||||
const apiEndpoint = "https://api.bitlab21.com/get_json/final__price.json";
|
const apiEndpoint = "https://api.bitlab21.com/price";
|
||||||
const response = await fetch(apiEndpoint);
|
const response = await fetch(apiEndpoint);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
|
|
@ -3,8 +3,7 @@ const myChart = echarts.init(document.getElementById("chart"));
|
||||||
|
|
||||||
async function fetchDataForChart() {
|
async function fetchDataForChart() {
|
||||||
try {
|
try {
|
||||||
const apiEndpoint =
|
const apiEndpoint = "https://api.bitlab21.com/feerates";
|
||||||
"https://api.bitlab21.com/get_json/final__feerate_percentiles.json";
|
|
||||||
const response = await fetch(apiEndpoint);
|
const response = await fetch(apiEndpoint);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
|
|
@ -3,8 +3,7 @@ const myChart = echarts.init(document.getElementById("chart"));
|
||||||
|
|
||||||
async function fetchDataForChart() {
|
async function fetchDataForChart() {
|
||||||
try {
|
try {
|
||||||
const apiEndpoint =
|
const apiEndpoint = "https://api.bitlab21.com/hashrate";
|
||||||
"https://api.bitlab21.com/get_json/final__hashrate.json";
|
|
||||||
const response = await fetch(apiEndpoint);
|
const response = await fetch(apiEndpoint);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
|
|
@ -3,8 +3,7 @@ const myChart = echarts.init(document.getElementById("chart"));
|
||||||
|
|
||||||
async function fetchDataForChart() {
|
async function fetchDataForChart() {
|
||||||
try {
|
try {
|
||||||
const apiEndpoint =
|
const apiEndpoint = "https://api.bitlab21.com/miner_rewards";
|
||||||
"https://api.bitlab21.com/get_json/final__miner_rewards.json";
|
|
||||||
const response = await fetch(apiEndpoint);
|
const response = await fetch(apiEndpoint);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
|
Loading…
Reference in New Issue