testing loading with fiona instead of geopandas (eliminates dependencies not available for raspberry pi) and tested loading place names
This commit is contained in:
parent
9c284a8460
commit
ab1dce1d15
43
Map.cpp
43
Map.cpp
|
@ -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
14
Map.h
|
@ -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;
|
||||||
|
|
19
View.cpp
19
View.cpp
|
@ -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
1
View.h
|
@ -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);
|
||||||
|
|
35
mapconverter-fiona-name.py
Normal file
35
mapconverter-fiona-name.py
Normal 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
65
mapconverter-fiona.py
Normal 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))
|
Loading…
Reference in a new issue