Skip to content

Commit

Permalink
Added a simplifed go based render
Browse files Browse the repository at this point in the history
Initial simplifed go based render. Does not do
everything that original render does, but is able
to generate a png, based on OSMesa.
  • Loading branch information
gdey committed Oct 5, 2018
1 parent c98c7ac commit 20744d0
Show file tree
Hide file tree
Showing 12 changed files with 637 additions and 20 deletions.
189 changes: 189 additions & 0 deletions cmd/snapshot_simple/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
package main

import (
"flag"
"fmt"
"image"
"image/png"
"log"
"os"
"strconv"
"strings"

"github.com/go-spatial/geom"
"github.com/go-spatial/geom/slippy"
mbgl "github.com/go-spatial/go-mbgl/mbgl/simplified"
)

/*
snapshotter bounds "lat long lat long" -width=100, -height=100 style filename.png
snapshotter tile "z/x/y" style filename.png
*/

type cmdType uint8

const (
CmdUnknown = cmdType(iota)
CmdBounds
CmdTile
)

func (c cmdType) String() string {
switch c {
case CmdBounds:
return "Bounds"
case CmdTile:
return "Tile"
default:
return "Unknown"
}
}

var FWidth uint
var FHeight uint
var FStyle string
var FPixelRatio float64

var FBounds geom.Extent
var FTile slippy.Tile
var FOutputFilename string

func usage() {
fmt.Fprintf(os.Stderr, "%v [options...] \"lat long lat long\" output_filename.png\n", os.Args[0])
fmt.Fprintf(os.Stderr, "%v [options...] bounds \"lat long lat long\" output_filename.png\n", os.Args[0])
fmt.Fprintf(os.Stderr, "%v [options...] tile \"z/x/y\" output_filename.png\n", os.Args[0])
flag.PrintDefaults()
}

func parseBounds(boundString string) {
var err error
bounds := strings.Split(boundString, " ")
if len(bounds) != 4 {
fmt.Fprintf(os.Stderr, "Error: invalid bounds provided — %v\n", boundString)
usage()
os.Exit(2)
}
for i, bound := range bounds {
FBounds[i], err = strconv.ParseFloat(strings.TrimSpace(bound), 64)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: invalid bounds provided — %v\n", boundString)
fmt.Fprintf(os.Stderr, "Error: unabled to parse %v(%v) as a float.\n", bound, i)
usage()
os.Exit(2)
}
}
}

func parseTile(tileString string) {
var err error
var v uint64
parts := strings.Split(tileString, "/")
if len(parts) != 3 {
fmt.Fprintf(os.Stderr, "Error: invalid z/x/y coordinates — %v\n", tileString)
usage()
os.Exit(2)
}
var label = [...]string{"Z", "X", "Y"}

for i, part := range parts {
v, err = strconv.ParseUint(strings.TrimSpace(part), 10, 64)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: invalid tile coordinates provided — %v\n", tileString)
fmt.Fprintf(os.Stderr, "Error: unabled to parse %v %v as a uint.\n", label[i], part)
usage()
os.Exit(2)
}
switch i {
case 0:
FTile.Z = uint(v)
case 1:
FTile.X = uint(v)
case 2:
FTile.Y = uint(v)
}
}
}

func ParseFlags() cmdType {

flag.UintVar(&FWidth, "width", 512, "Width of the image to generate.")
flag.UintVar(&FWidth, "w", 512, "Width of the image to generate.")

flag.UintVar(&FHeight, "height", 512, "Height of the image to generate.")
flag.UintVar(&FHeight, "h", 512, "Height of the image to generate.")

flag.StringVar(&FStyle, "style", "file://style.json", "Style file")
flag.Float64Var(&FPixelRatio, "pixel", 1.0, "The pixel ratio")

flag.Parse()

if flag.NArg() < 3 {
usage()
os.Exit(2)
}

var cmd cmdType
var fileIdx = 2

switch strings.TrimSpace(strings.ToLower(flag.Arg(0))) {
case "bounds":
// The next variable should be the bounds seperated by spaces.
parseBounds(flag.Arg(1))
cmd = CmdBounds
case "tile":
// The next variable should be the coordinates sepearted by forward slash.
parseTile(flag.Arg(1))

cmd = CmdTile
default: // assume bounds as the default subcommand
parseBounds(flag.Arg(0))
fileIdx = 1
cmd = CmdBounds
}

// Next should be the output filename.
FOutputFilename = strings.TrimSpace(flag.Arg(fileIdx))
return cmd

}

func main() {
var file *os.File
var err error
var img image.Image
_ = ParseFlags()
snpsht := mbgl.Snapshotter{
Style: FStyle,
Width: uint32(FWidth),
Height: uint32(FHeight),
PPIRatio: int(FPixelRatio),
}
img, err = mbgl.Snapshot(snpsht)
if err != nil {
fmt.Fprintf(os.Stderr, "got an error creating the snapshot: %v\n", err)
os.Exit(3)
}
/*
switch cmd {
case CmdBounds:
img = ss.Snapshot(&FBounds, size)
case CmdTile:
img = mbgl.SnapshotTile(ss, FTile, size)
}
*/
file, err = os.Create(FOutputFilename)
if err != nil {
fmt.Fprintf(os.Stderr, "error creating output file: %v -- %v\n", FOutputFilename, err)
os.Exit(3)
}
defer file.Close()
if err := png.Encode(file, img); err != nil {
log.Printf("Failed to write %v", FOutputFilename)
log.Println(err)
return
}

fmt.Printf("successfully wrote outfile: %v\n", FOutputFilename)
}
1 change: 1 addition & 0 deletions cmd/snapshot_simple/style.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"version":8,"name":"osm","center":[-76.275329586789,39.153492567373],"zoom":8,"sources":{"osm":{"type":"vector","url":"https://osm.tegola.io/capabilities/osm.json"}},"layers":[{"id":"populated_places","source":"osm","source-layer":"populated_places","type":"circle","layout":{"visibility":"visible"},"paint":{"circle-radius":3,"circle-color":"#71ab62"}},{"id":"country_lines","source":"osm","source-layer":"country_lines","type":"line","layout":{"visibility":"visible"},"paint":{"line-color":"#168120"}},{"id":"country_lines_disputed","source":"osm","source-layer":"country_lines_disputed","type":"line","layout":{"visibility":"visible"},"paint":{"line-color":"#29e597"}},{"id":"country_label_points","source":"osm","source-layer":"country_label_points","type":"circle","layout":{"visibility":"visible"},"paint":{"circle-radius":3,"circle-color":"#9776f3"}},{"id":"country_polygons","source":"osm","source-layer":"country_polygons","type":"fill","layout":{"visibility":"visible"},"paint":{"fill-color":"rgba(2,85,36,0.1)","fill-outline-color":"#025524"}},{"id":"state_lines","source":"osm","source-layer":"state_lines","type":"line","layout":{"visibility":"visible"},"paint":{"line-color":"#d1050f"}},{"id":"land","source":"osm","source-layer":"land","type":"fill","layout":{"visibility":"visible"},"paint":{"fill-color":"rgba(235,145,50,0.1)","fill-outline-color":"#eb9132"}},{"id":"admin_lines","source":"osm","source-layer":"admin_lines","type":"fill","layout":{"visibility":"visible"},"paint":{"fill-color":"rgba(15,190,3,0.1)","fill-outline-color":"#0fbe03"}},{"id":"state_label_points","source":"osm","source-layer":"state_label_points","type":"circle","layout":{"visibility":"visible"},"paint":{"circle-radius":3,"circle-color":"#7c39e4"}},{"id":"landuse_areas","source":"osm","source-layer":"landuse_areas","type":"fill","layout":{"visibility":"visible"},"paint":{"fill-color":"rgba(67,79,119,0.1)","fill-outline-color":"#434f77"}},{"id":"water_areas","source":"osm","source-layer":"water_areas","type":"fill","layout":{"visibility":"visible"},"paint":{"fill-color":"rgba(94,252,42,0.1)","fill-outline-color":"#5efc2a"}},{"id":"water_lines","source":"osm","source-layer":"water_lines","type":"line","layout":{"visibility":"visible"},"paint":{"line-color":"#d709c2"}},{"id":"transport_lines","source":"osm","source-layer":"transport_lines","type":"line","layout":{"visibility":"visible"},"paint":{"line-color":"#69e68c"}},{"id":"transport_areas","source":"osm","source-layer":"transport_areas","type":"fill","layout":{"visibility":"visible"},"paint":{"fill-color":"rgba(240,216,245,0.1)","fill-outline-color":"#f0d8f5"}},{"id":"transport_points","source":"osm","source-layer":"transport_points","type":"circle","layout":{"visibility":"visible"},"paint":{"circle-radius":3,"circle-color":"#b9b235"}},{"id":"amenity_areas","source":"osm","source-layer":"amenity_areas","type":"fill","layout":{"visibility":"visible"},"paint":{"fill-color":"rgba(128,132,166,0.1)","fill-outline-color":"#8084a6"}},{"id":"amenity_points","source":"osm","source-layer":"amenity_points","type":"circle","layout":{"visibility":"visible"},"paint":{"circle-radius":3,"circle-color":"#29799a"}},{"id":"other_points","source":"osm","source-layer":"other_points","type":"circle","layout":{"visibility":"visible"},"paint":{"circle-radius":3,"circle-color":"#f2c89f"}},{"id":"other_lines","source":"osm","source-layer":"other_lines","type":"line","layout":{"visibility":"visible"},"paint":{"line-color":"#10a5da"}},{"id":"other_areas","source":"osm","source-layer":"other_areas","type":"fill","layout":{"visibility":"visible"},"paint":{"fill-color":"rgba(151,151,67,0.1)","fill-outline-color":"#979743"}},{"id":"buildings","source":"osm","source-layer":"buildings","type":"fill","layout":{"visibility":"visible"},"paint":{"fill-color":"rgba(63,68,136,0.1)","fill-outline-color":"#3f4488"}}]}
90 changes: 72 additions & 18 deletions mbgl/c/bin/render_stripped.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,35 +13,89 @@
#include <iostream>
#include <fstream>


struct snapshot_params {
std::string style;
std::string cache_file;
std::string asset_root;
uint32_t width;
uint32_t height;
int ppi_ratio;
double lat;
double lng;
double zoom;
double pitch;
double bearing;
};

struct snapshot_result {
mbgl::PremultipliedImage image;
bool did_error;
std::string err;
};


struct snapshot_result snapshot( struct snapshot_params params ) {

struct snapshot_result result;
result.did_error = false;

mbgl::ThreadPool threadPool(4);

mbgl::DefaultFileSource fileSource(params.cache_file, params.asset_root);
mbgl::HeadlessFrontend frontend({ params.height, params.width }, params.ppi_ratio, fileSource, threadPool);

mbgl::Map map(frontend, mbgl::MapObserver::nullObserver(), frontend.getSize(), params.ppi_ratio, fileSource, threadPool, mbgl::MapMode::Static);

//map.getStyle().loadURL("file://style.json");
map.getStyle().loadURL(params.style);
map.setLatLngZoom({ params.lat, params.lng }, params.zoom);
map.setBearing(params.bearing);
map.setPitch(params.pitch);

try {
result.image = frontend.render(map);
} catch(std::exception& e) {
result.did_error = true;
result.err = e.what();
}
return result;
}


int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)) ) {
const std::string output = "out.png";
const std::string cache_file = "cache.sqlite";
const std::string asset_root = ".";

using namespace mbgl;

util::RunLoop loop;

DefaultFileSource fileSource(cache_file, asset_root);
ThreadPool threadPool(4);
HeadlessFrontend frontend({ 512, 512 }, 1, fileSource, threadPool);
Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), 1, fileSource, threadPool, MapMode::Static);


map.getStyle().loadURL("file://style.json");
map.setLatLngZoom({ 0, 0 }, 0);
map.setBearing(0);
map.setPitch(0);

struct snapshot_params snpParams;
snpParams.cache_file = "cache.sqlite";
snpParams.asset_root = ".";
snpParams.style = "file://style.json";
snpParams.width = 512;
snpParams.height = 512;
snpParams.ppi_ratio = 1;
snpParams.lat = 0;
snpParams.lng = 0;
snpParams.zoom = 0;
snpParams.pitch = 0;
snpParams.bearing = 0;

struct snapshot_result ret;
ret = snapshot(snpParams);
if(ret.did_error){
std::cout << "Error :" << ret.err << std::endl;
exit(1);
}
try {
std::ofstream out(output, std::ios::binary);
out << encodePNG(frontend.render(map));
out << encodePNG(ret.image);
out.close();
} catch(std::exception& e) {
std::cout << "Error: " << e.what() << std::endl;
exit(1);
}catch(std::exception& e) {
std::cout << "Error :" << e.what() << std::endl;
exit(1);
}

return 0;
}
61 changes: 61 additions & 0 deletions mbgl/c/build_render_with_local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/bash -e

echo "Building the object file."

g++ \
-DRAPIDJSON_HAS_STDSTRING=1 \
-D_GLIBCXX_USE_CXX11_ABI=1 \
-Iinclude \
-ftemplate-depth=1024 \
-Wall \
-Wextra \
-Wshadow \
-Wnon-virtual-dtor \
-Wno-variadic-macros \
-Wno-unknown-pragmas \
-Werror \
-fext-numeric-literals \
-g \
-fPIE \
-fvisibility=hidden \
-fvisibility-inlines-hidden \
-std=c++14 \
-o bin/render_stripped.cpp.o \
-c bin/render_stripped.cpp


echo "Building executable."

# libmbgl-core.a libmbgl-filesource.a libmbgl-loop-uv.a libsqlite.a -Wl,--no-as-needed -lcurl -Wl,--as-needed libmbgl-core.a -lOSMesa ../../../mason_packages/linux-x86_64/libpng/1.6.25/lib/libpng.a -lz -lm ../../../mason_packages/linux-x86_64/libjpeg-turbo/1.5.0/lib/libjpeg.a libnunicode.a libicu.a -lz -static-libstdc++ -Wl,-Bsymbolic-functions ../../../mason_packages/linux-x86_64/libuv/1.9.1/lib/libuv.a -lrt -lpthread -lnsl -ldl

g++ \
-ftemplate-depth=1024 \
-Wall \
-Wextra \
-Wshadow \
-Wnon-virtual-dtor \
-Wno-variadic-macros \
-Wno-unknown-pragmas \
-Werror -fext-numeric-literals \
-static-libstdc++ \
-g bin/render_stripped.cpp.o \
lib/linux/libmbgl-core.a \
lib/linux/libmbgl-filesource.a \
lib/linux/libmbgl-loop-uv.a \
lib/linux/libsqlite.a \
-Wl,--no-as-needed -lcurl \
-Wl,--as-needed lib/linux/libmbgl-core.a \
-lOSMesa \
lib/linux/libpng.a \
-lz \
-lm \
lib/linux/libjpeg.a \
lib/linux/libnunicode.a \
lib/linux/libicu.a \
-Wl,-Bsymbolic-functions lib/linux/libuv.a \
-lrt \
-lpthread \
-lnsl \
-ldl \
-o bin/mbgl-render-stripped \

Loading

0 comments on commit 20744d0

Please sign in to comment.