Skip to content

Commit

Permalink
move prime_server functions to worker
Browse files Browse the repository at this point in the history
  • Loading branch information
hjanetzek committed May 29, 2017
1 parent fc5fbba commit 6f9359a
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 264 deletions.
7 changes: 0 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,6 @@ matrix:
jdk: oraclejdk8

before_install:
- sudo add-apt-repository -y ppa:kevinkreiser/libsodium
- sudo add-apt-repository -y ppa:kevinkreiser/libpgm
- sudo add-apt-repository -y ppa:kevinkreiser/zeromq3
- sudo add-apt-repository -y ppa:kevinkreiser/czmq
- sudo apt-get update
- sudo apt-get install libzmq3-dev libczmq-dev

- git submodule update --init
- source ./scripts/travis/before_install.sh

Expand Down
254 changes: 19 additions & 235 deletions paparazzi/src/paparazzi.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
#include "paparazzi.h"

#include <prime_server/logging.hpp>

using namespace Tangram;

#define AA_SCALE 1.0
#define MAX_WAITING_TIME 100.0
#define IMAGE_DEPTH 4

#if PLATFORM_LINUX
#include "platform_linux.h"
std::shared_ptr<LinuxPlatform> platform;
#elif PLATFORM_OSX
#include "platform_osx.h"
std::shared_ptr<OSXPlatform> platform;
#endif

#include "log.h"
#include "gl/texture.h"

Expand All @@ -23,19 +17,15 @@ std::shared_ptr<OSXPlatform> platform;
#include <functional>
#include <csignal>
#include <fstream>
#include <regex>
#include <sstream>
#include <sys/time.h>
#include <unistd.h>
#include "glm/trigonometric.hpp"

#include "stb_image_write.h"

const headers_t::value_type CORS{"Access-Control-Allow-Origin", "*"};
const headers_t::value_type PNG_MIME{"Content-type", "image/png"};
const headers_t::value_type TXT_MIME{"Content-type", "text/plain;charset=utf-8"};

const std::regex TILE_REGEX("\\/(\\d*)\\/(\\d*)\\/(\\d*)\\.png");
using namespace Tangram;

unsigned long long timeStart;

Expand Down Expand Up @@ -68,9 +58,9 @@ Paparazzi::Paparazzi()
#if PLATFORM_LINUX
UrlClient::Options urlClientOptions;
urlClientOptions.numberOfThreads = 10;
platform = std::make_shared<LinuxPlatform>(urlClientOptions);
auto platform = std::make_shared<LinuxPlatform>(urlClientOptions);
#elif PLATFORM_OSX
platform = std::make_shared<OSXPlatform>();
auto platform = std::make_shared<OSXPlatform>();
#endif

timeStart = getTime();
Expand Down Expand Up @@ -162,12 +152,11 @@ void Paparazzi::setSceneContent(const std::string &_yaml_content) {
m_map->loadScene(name.c_str(), false, {SceneUpdate("global.sdk_mapzen_api_key", "mapzen-y6KCsnw")});
}

bool Paparazzi::update() {
bool Paparazzi::update(int32_t _maxWaitTime) {
double startTime = getTime();
float delta = 0.0;

while (delta < MAX_WAITING_TIME) {
logMsg("Update: waiting %f\n", delta);
while (_maxWaitTime < 0 || delta < _maxWaitTime) {

bool bFinish = m_map->update(10.);
delta = float(getTime() - startTime);
Expand All @@ -182,225 +171,20 @@ bool Paparazzi::update() {
return false;
}

struct coord_s {
/** @brief coordinate x or column value */
uint32_t x;
/** @brief coordinate y or row value */
uint32_t y;
/** @brief coordinate z or zoom value */
uint32_t z;
};

static double radians_to_degrees(double radians) {
return radians * 180 / M_PI;
}

static double degrees_to_radians(double degrees) {
return degrees * M_PI / 180;
}

// http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
// TODO make output into point
void coord_to_lnglat(coord_s *coord, double *out_lng_deg, double *out_lat_deg) {
double n = pow(2, coord->z);
double lng_deg = coord->x / n * 360.0 - 180.0;
double lat_rad = atan(sinh(M_PI * (1 - 2 * coord->y / n)));
double lat_deg = radians_to_degrees(lat_rad);
*out_lng_deg = lng_deg;
*out_lat_deg = lat_deg;
}

// http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
// make input point
void lnglat_to_coord(double lng_deg, double lat_deg, int zoom, coord_s *out) {
double lat_rad = degrees_to_radians(lat_deg);
double n = pow(2.0, zoom);
out->x = (lng_deg + 180.0) / 360.0 * n;
out->y = (1.0 - log(tan(lat_rad) + (1 / cos(lat_rad))) / M_PI) / 2.0 * n;
out->z = zoom;
}

worker_t::result_t Paparazzi::work(const std::list<zmq::message_t>& job, void* request_info){
// false means this is going back to the client, there is no next stage of the pipeline
worker_t::result_t result{false, {}, ""};

// This type differs per protocol hence the void* fun
auto& info = *static_cast<http_request_info_t*>(request_info);

// Try to generate a response
http_response_t response;
try {
// double start_call = getTime();

logging::INFO(std::string("Handle request: ") + static_cast<const char*>(job.front().data()));
//TODO:
// - actually use/validate the request parameters
auto request = http_request_t::from_string(static_cast<const char*>(job.front().data()),
job.front().size());

if (request.path == "/check") {
// ELB check
response = http_response_t(200, "OK", "OK", headers_t{CORS, TXT_MIME}, "HTTP/1.1");
response.from_info(info);
result.messages.emplace_back(response.to_string());
return result;
}

// SCENE
// ---------------------
auto scene_itr = request.query.find("scene");
if (scene_itr == request.query.cend() || scene_itr->second.size() == 0) {
// If there is NO SCENE QUERY value
if (request.body.empty())
// if there is not POST body content return error...
throw std::runtime_error("Missing scene parameter");

// ... other whise load content
setSceneContent(request.body);

// The size of the custom scene is unique enough
result.heart_beat = std::to_string(request.body.size());
} else {
// If there IS a SCENE QUERRY value load it
setScene(scene_itr->second.front());

result.heart_beat = scene_itr->second.front();
}

bool size_and_pos = true;
float pixel_density = 1.0f;

// SIZE
auto width_itr = request.query.find("width");
if (width_itr == request.query.cend() || width_itr->second.size() == 0)
size_and_pos = false;
auto height_itr = request.query.find("height");
if (height_itr == request.query.cend() || height_itr->second.size() == 0)
size_and_pos = false;
auto density_itr = request.query.find("density");
if (density_itr != request.query.cend() && density_itr->second.size() > 0)
pixel_density = fmax(1.,std::stof(density_itr->second.front()));

// POSITION
auto lat_itr = request.query.find("lat");
if (lat_itr == request.query.cend() || lat_itr->second.size() == 0)
size_and_pos = false;
auto lon_itr = request.query.find("lon");
if (lon_itr == request.query.cend() || lon_itr->second.size() == 0)
size_and_pos = false;
auto zoom_itr = request.query.find("zoom");
if (zoom_itr == request.query.cend() || zoom_itr->second.size() == 0)
size_and_pos = false;

std::smatch match;

if (size_and_pos) {
// Set Map and OpenGL context size
setSize(std::stoi(width_itr->second.front()),
std::stoi(height_itr->second.front()),
pixel_density);
setPosition(std::stod(lon_itr->second.front()),
std::stod(lat_itr->second.front()));
setZoom(std::stof(zoom_itr->second.front()));

} else if (std::regex_search(request.path, match, TILE_REGEX) && match.size() == 4) {
setSize(256, 256, pixel_density);

int tile_coord[3] = {0,0,0};
for (int i = 0; i < 3; i++) {
std::istringstream cur(match.str(i+1));
cur >> tile_coord[i];
}
coord_s tile;
tile.z = tile_coord[0];
setZoom(tile.z);

tile.x = tile_coord[1];
tile.y = tile_coord[2];

double n = pow(2, tile.z);
double lng_deg = (tile.x + 0.5) / n * 360.0 - 180.0;
double lat_rad = atan(sinh(M_PI * (1 - 2 * (tile.y + 0.5) / n)));
double lat_deg = radians_to_degrees(lat_rad);

setPosition(lng_deg, lat_deg);
} else {
throw std::runtime_error("Missing parameters to construct image");
}

// OPTIONAL tilt and rotation
// ---------------------
auto tilt_itr = request.query.find("tilt");
if (tilt_itr != request.query.cend() && tilt_itr->second.size() != 0) {
// If TILT QUERRY is provided assigned ...
setTilt(std::stof(tilt_itr->second.front()));
}
else {
// othewise use default (0.)
setTilt(0.0f);
}
void Paparazzi::render(std::string& _image) {
m_glContext->makeCurrent();

auto rotation_itr = request.query.find("rotation");
if (rotation_itr != request.query.cend() && rotation_itr->second.size() != 0) {
// If ROTATION QUERRY is provided assigned ...
setRotation(std::stof(rotation_itr->second.front()));
}
else {
// othewise use default (0.)
setRotation(0.0f);
}

// Time to render
// ---------------------

if (!update()) {
throw std::runtime_error("Image creation timeout");
}

m_glContext->makeCurrent();

// Render Tangram Scene
//m_glContext->bind();
m_map->render();

GL::finish();

//m_glContext->unbind();

// Once the main FBO is draw take a picture
//m_glContext->getPixelsAsString(image);
// double total_time = getTime()-start_call;
// LOG("TOTAL CALL: %f", total_time);
// LOG("TOTAL speed: %f millisec per pixel", (total_time/((m_width * m_height)/1000.0)));

std::string image;

// m_glContext->writeImage("test.ppm");

//Texture::flipImageData(m_glContext->buffer(), m_glContext->width(), m_glContext->height(), IMAGE_DEPTH);

stbi_write_png_to_func([](void *context, void *data, int size) {
static_cast<std::string*>(context)->append(static_cast<const char*>(data), size);
},
&image,
m_glContext->width(),
m_glContext->height(),
IMAGE_DEPTH,
m_glContext->buffer(),
m_glContext->width() * IMAGE_DEPTH);

response = http_response_t(200, "OK", image, headers_t{CORS, PNG_MIME}, "HTTP/1.1");
}
catch(const std::exception& e) {
response = http_response_t(400, "Bad Request", e.what(), headers_t{CORS}, "HTTP/1.1");
}

response.from_info(info);
result.messages.emplace_back(response.to_string());

return result;
}
m_map->render();

void Paparazzi::cleanup () {
GL::finish();

stbi_write_png_to_func([](void *context, void *data, int size) {
static_cast<std::string*>(context)->append(static_cast<const char*>(data), size);
},
&_image,
m_glContext->width(),
m_glContext->height(),
IMAGE_DEPTH,
m_glContext->buffer(),
m_glContext->width() * IMAGE_DEPTH);
}
27 changes: 12 additions & 15 deletions paparazzi/src/paparazzi.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#include <string>

//prime_server guts
#include <prime_server/prime_server.hpp>
#include <prime_server/http_protocol.hpp>
using namespace prime_server;
// #include <prime_server/prime_server.hpp>
// #include <prime_server/http_protocol.hpp>
// using namespace prime_server;

#include "tangram.h" // Tangram-ES
#include "headlessContext.h"
Expand All @@ -16,20 +16,17 @@ class Paparazzi {
Paparazzi();
~Paparazzi();

void setSize(const int &_width, const int &_height, const float &_density);
void setZoom(const float &_zoom);
void setTilt(const float &_deg);
void setRotation(const float &_deg);
void setScene(const std::string &_url);
void setSceneContent(const std::string &_yaml_content);
void setPosition(const double &_lon, const double &_lat);

// prime_server stuff
worker_t::result_t work (const std::list<zmq::message_t>& job, void* request_info);
void cleanup();
void setSize(const int &_width, const int &_height, const float &_density);
void setZoom(const float &_zoom);
void setTilt(const float &_deg);
void setRotation(const float &_deg);
void setScene(const std::string &_url);
void setSceneContent(const std::string &_yaml_content);
void setPosition(const double &_lon, const double &_lat);
void render(std::string& _image);
bool update(int32_t _maxWaitTime = -1);

protected:
bool update();

std::string m_scene;
double m_lat;
Expand Down
Loading

0 comments on commit 6f9359a

Please sign in to comment.