testing loading with fiona instead of geopandas (eliminates dependencies not available for raspberry pi) and tested loading place names

This commit is contained in:
nathan 2020-06-19 22:04:57 -07:00
parent 9c284a8460
commit ab1dce1d15
6 changed files with 173 additions and 6 deletions

43
Map.cpp
View file

@ -32,6 +32,10 @@
#include "Map.h" #include "Map.h"
#include <stdio.h> #include <stdio.h>
#include <cstdlib> #include <cstdlib>
#include <sstream>
#include <fstream>
#include <string>
#include <iostream>
bool Map::QTInsert(QuadTree *tree, Line *line, int depth) { bool Map::QTInsert(QuadTree *tree, Line *line, int depth) {
@ -186,8 +190,8 @@ Map::Map() {
FILE *fileptr; FILE *fileptr;
if(!(fileptr = fopen("mapdata.bin", "rb"))) { if(!(fileptr = fopen("mapdata.bin", "rb"))) {
printf("Couldn't read mapdata.bin\nDid you run getmap.sh?\n"); printf("No map file found\n");
exit(0); return;
} }
fseek(fileptr, 0, SEEK_END); fseek(fileptr, 0, SEEK_END);
@ -196,7 +200,7 @@ Map::Map() {
mapPoints = (float *)malloc(mapPoints_count * sizeof(float)); mapPoints = (float *)malloc(mapPoints_count * sizeof(float));
if(!fread(mapPoints, sizeof(float), mapPoints_count, fileptr)){ if(!fread(mapPoints, sizeof(float), mapPoints_count, fileptr)){
printf("Read error\n"); printf("Map read error\n");
exit(0); exit(0);
} }
@ -223,7 +227,7 @@ Map::Map() {
} }
} }
printf("map bounds: %f %f %f %f\n",root.lon_min, root.lon_max, root.lat_min, root.lat_max); //printf("map bounds: %f %f %f %f\n",root.lon_min, root.lon_max, root.lat_min, root.lat_max);
Point currentPoint; Point currentPoint;
Point nextPoint; Point nextPoint;
@ -248,5 +252,36 @@ Map::Map() {
QTInsert(&root, new Line(currentPoint, nextPoint), 0); QTInsert(&root, new Line(currentPoint, nextPoint), 0);
} }
std::string line;
std::ifstream infile("mapnames");
while (std::getline(infile, line))
{
float lon, lat;
std::istringstream iss(line);
iss >> lon;
iss >> lat;
std::string assemble;
iss >> assemble;
for(std::string s; iss >> s; ) {
assemble = assemble + " " + s;
}
// std::cout << "[" << x << "," << y << "] " << assemble << "\n";
Label *label = new Label(lon,lat,assemble);
mapnames.push_back(label);
}
std::cout << "Read " << mapnames.size() << " place names\n";
printf("done\n"); printf("done\n");
} }

14
Map.h
View file

@ -33,12 +33,24 @@
#define MAP_H #define MAP_H
#include <vector> #include <vector>
#include <string>
typedef struct Point{ typedef struct Point{
float lat; float lat;
float lon; float lon;
} Point; } Point;
typedef struct Label{
Point location;
std::string text;
Label(float lon, float lat, std::string text) {
this->location.lon = lon;
this->location.lat = lat;
this->text = text;
}
} Label;
typedef struct Line{ typedef struct Line{
float lat_min; float lat_min;
float lat_max; float lat_max;
@ -112,6 +124,8 @@ public:
std::vector<Line*> getLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max); std::vector<Line*> getLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
std::vector<Line*> getLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max); std::vector<Line*> getLines(float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
std::vector<Label*> mapnames;
Map(); Map();
int mapPoints_count; int mapPoints_count;

View file

@ -727,10 +727,26 @@ void View::drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen
} }
void View::drawPlaceNames() {
for(std::vector<Label*>::iterator label = map.mapnames.begin(); label != map.mapnames.end(); ++label) {
float dx, dy;
int x,y;
pxFromLonLat(&dx, &dy, (*label)->location.lon, (*label)->location.lat);
screenCoords(&x, &y, dx, dy);
if(outOfBounds(x,y)) {
continue;
}
drawString((*label)->text, x, y, mapFont, grey);
}
}
void View::drawGeography() { void View::drawGeography() {
if((mapRedraw && !mapMoved) || (mapAnimating && elapsed(lastRedraw) > 8 * FRAMETIME)) { if((mapRedraw && !mapMoved) || (mapAnimating && elapsed(lastRedraw) > 8 * FRAMETIME) || elapsed(lastRedraw) > 2000) {
SDL_SetRenderTarget(renderer, mapTexture); SDL_SetRenderTarget(renderer, mapTexture);
@ -739,6 +755,7 @@ void View::drawGeography() {
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
drawLines(0, 0, screen_width, screen_height, 0); drawLines(0, 0, screen_width, screen_height, 0);
drawPlaceNames();
SDL_SetRenderTarget(renderer, NULL ); SDL_SetRenderTarget(renderer, NULL );

1
View.h
View file

@ -124,6 +124,7 @@ class View {
void drawScaleBars(); void drawScaleBars();
void drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max); void drawLinesRecursive(QuadTree *tree, float screen_lat_min, float screen_lat_max, float screen_lon_min, float screen_lon_max);
void drawLines(int left, int top, int right, int bottom, int bailTime); void drawLines(int left, int top, int right, int bottom, int bailTime);
void drawPlaceNames();
void drawGeography(); void drawGeography();
void drawSignalMarks(Aircraft *p, int x, int y); void drawSignalMarks(Aircraft *p, int x, int y);
void drawPlaneText(Aircraft *p); void drawPlaneText(Aircraft *p);

View file

@ -0,0 +1,35 @@
import fiona
from tqdm import tqdm
import argparse
import os
bin_file = open("mapnames", "w")
parser = argparse.ArgumentParser(description='viz1090 Natural Earth Data Map Converter')
parser.add_argument("--minpop", default=100000, type=int, help="map simplification tolerance")
parser.add_argument("--scale", default="10m", choices=["10m","50m","110m"], type=str, help="map file scale")
parser.add_argument("mapfile", type=str, help="shapefile to load (e.g., from https://www.naturalearthdata.com/downloads/")
args = parser.parse_args()
shapefile = fiona.open(args.mapfile)
count = 0
for i in tqdm(range(len(shapefile))):
xcoord = shapefile[i]['geometry']['coordinates'][0]
ycoord = shapefile[i]['geometry']['coordinates'][1]
pop = shapefile[i]['properties']['POP_MIN']
name = shapefile[i]['properties']['NAME']
if pop > args.minpop:
outstring = "{0} {1} {2}\n".format(xcoord, ycoord, name)
bin_file.write(outstring)
count = count + 1
bin_file.close()
print("Wrote %d place names" % count)

65
mapconverter-fiona.py Normal file
View file

@ -0,0 +1,65 @@
import fiona
from shapely.geometry import shape
import numpy as np
from tqdm import tqdm
import zipfile
from io import BytesIO
#from urllib.request import urlopen
import requests
import argparse
import os
def convertLinestring(linestring):
outlist = []
pointx = linestring.coords.xy[0]
pointy = linestring.coords.xy[1]
for j in range(len(pointx)):
outlist.extend([float(pointx[j]),float(pointy[j])])
outlist.extend([0,0])
return outlist
def extractLines(shapefile, tolerance):
print("Extracting map lines")
outlist = []
for i in tqdm(range(len(shapefile))):
simplified = shape(shapefile[i]['geometry']).simplify(tolerance, preserve_topology=False)
if(simplified.geom_type == "LineString"):
outlist.extend(convertLinestring(simplified))
elif(simplified.geom_type == "MultiPolygon" or simplified.geom_type == "Polygon"):
if(simplified.boundary.geom_type == "MultiLineString"):
for boundary in simplified.boundary:
outlist.extend(convertLinestring(boundary))
else:
outlist.extend(convertLinestring(simplified.boundary))
else:
print("Unsupported type: " + simplified.geom_type)
return outlist
parser = argparse.ArgumentParser(description='viz1090 Natural Earth Data Map Converter')
parser.add_argument("--tolerance", default=0.001, type=float, help="map simplification tolerance")
parser.add_argument("--scale", default="10m", choices=["10m","50m","110m"], type=str, help="map file scale")
parser.add_argument("mapfile", type=str, help="shapefile to load (e.g., from https://www.naturalearthdata.com/downloads/")
args = parser.parse_args()
shapefile = fiona.open(args.mapfile)
outlist = extractLines(shapefile, args.tolerance)
bin_file = open("mapdata.bin", "wb")
np.asarray(outlist).astype(np.single).tofile(bin_file)
bin_file.close()
print("Wrote %d points" % (len(outlist) / 2))