Build simple pc app

This commit is contained in:
Victor Shcherb 2012-05-01 01:43:09 +02:00
parent 76643bfc26
commit 535c517d56
16 changed files with 747 additions and 651 deletions

1
Osmand-kernel/freetype/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
build/

View file

@ -1,18 +1,12 @@
LOCAL_PATH:= $(call my-dir) LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
include $(LOCAL_PATH)/Common.mk
# compile in ARM mode, since the glyph loader/renderer is a hotspot # compile in ARM mode, since the glyph loader/renderer is a hotspot
# when loading complex pages in the browser # when loading complex pages in the browser
# #
LOCAL_ARM_MODE := arm LOCAL_ARM_MODE := arm
ifeq ($(OSMAND_FREETYPE_LOC),)
OSMAND_FREETYPE_LOC := ./freetype_library
endif
ifeq ($(OSMAND_FREETYPE_ABS),)
OSMAND_FREETYPE_ABS := $(LOCAL_PATH)/freetype_library
endif
ifneq ($(OSMAND_BUILDING_NEON_LIBRARY),true) ifneq ($(OSMAND_BUILDING_NEON_LIBRARY),true)
LOCAL_MODULE := ft2_static LOCAL_MODULE := ft2_static
else else
@ -22,43 +16,6 @@ endif
ifneq ($(OSMAND_USE_PREBUILT),true) ifneq ($(OSMAND_USE_PREBUILT),true)
LOCAL_SRC_FILES:= \
$(OSMAND_FREETYPE_LOC)/src/base/ftbbox.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftbitmap.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftfstype.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftglyph.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftlcdfil.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftstroke.c \
$(OSMAND_FREETYPE_LOC)/src/base/fttype1.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftxf86.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftbase.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftsystem.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftinit.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftgasp.c \
$(OSMAND_FREETYPE_LOC)/src/raster/raster.c \
$(OSMAND_FREETYPE_LOC)/src/sfnt/sfnt.c \
$(OSMAND_FREETYPE_LOC)/src/smooth/smooth.c \
$(OSMAND_FREETYPE_LOC)/src/autofit/autofit.c \
$(OSMAND_FREETYPE_LOC)/src/truetype/truetype.c \
$(OSMAND_FREETYPE_LOC)/src/cff/cff.c \
$(OSMAND_FREETYPE_LOC)/src/psnames/psnames.c \
$(OSMAND_FREETYPE_LOC)/src/pshinter/pshinter.c
LOCAL_C_INCLUDES += \
$(OSMAND_FREETYPE_ABS)/builds \
$(OSMAND_FREETYPE_ABS)/include
LOCAL_CFLAGS += -W -Wall
LOCAL_CFLAGS += -fPIC -DPIC
LOCAL_CFLAGS += "-DDARWIN_NO_CARBON"
LOCAL_CFLAGS += "-DFT2_BUILD_LIBRARY"
# the following is for testing only, and should not be used in final builds
# of the product
#LOCAL_CFLAGS += "-DTT_CONFIG_OPTION_BYTECODE_INTERPRETER"
LOCAL_CFLAGS += -O2
include $(BUILD_STATIC_LIBRARY) include $(BUILD_STATIC_LIBRARY)
else else

View file

@ -0,0 +1,41 @@
OSMAND_FREETYPE_LOC := ./freetype_library
OSMAND_FREETYPE_ABS := $(LOCAL_PATH)/freetype_library
LOCAL_SRC_FILES:= \
$(OSMAND_FREETYPE_LOC)/src/base/ftbbox.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftbitmap.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftfstype.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftglyph.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftlcdfil.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftstroke.c \
$(OSMAND_FREETYPE_LOC)/src/base/fttype1.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftxf86.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftbase.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftsystem.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftinit.c \
$(OSMAND_FREETYPE_LOC)/src/base/ftgasp.c \
$(OSMAND_FREETYPE_LOC)/src/raster/raster.c \
$(OSMAND_FREETYPE_LOC)/src/sfnt/sfnt.c \
$(OSMAND_FREETYPE_LOC)/src/smooth/smooth.c \
$(OSMAND_FREETYPE_LOC)/src/autofit/autofit.c \
$(OSMAND_FREETYPE_LOC)/src/truetype/truetype.c \
$(OSMAND_FREETYPE_LOC)/src/cff/cff.c \
$(OSMAND_FREETYPE_LOC)/src/psnames/psnames.c \
$(OSMAND_FREETYPE_LOC)/src/pshinter/pshinter.c
LOCAL_C_INCLUDES += \
$(OSMAND_FREETYPE_ABS)/builds \
$(OSMAND_FREETYPE_ABS)/include
LOCAL_CFLAGS += -W -Wall
LOCAL_CFLAGS += -fPIC -DPIC
LOCAL_CFLAGS += "-DDARWIN_NO_CARBON"
LOCAL_CFLAGS += "-DFT2_BUILD_LIBRARY"
# the following is for testing only, and should not be used in final builds
# of the product
#LOCAL_CFLAGS += "-DTT_CONFIG_OPTION_BYTECODE_INTERPRETER"
LOCAL_CFLAGS += -O2

View file

@ -0,0 +1,24 @@
LOCAL_PATH = .
include Common.mk
CPP_FILE_EXTENSION = c
LIBNAME := libft2.a
PREBUILT_DIR = ../jni-prebuilt/linux-x86/
OBJECTS = $(LOCAL_SRC_FILES:%.$(CPP_FILE_EXTENSION)=build/obj/%.o)
C_INCLUDES := $(addprefix -I, $(LOCAL_C_INCLUDES))
CPPFLAGS = $(LOCAL_CFLAGS) $(C_INCLUDES)
target : $(PREBUILT_DIR)/$(LIBNAME)
$(PREBUILT_DIR)/$(LIBNAME) : build/$(LIBNAME)
cp build/$(LIBNAME) $(PREBUILT_DIR)/$(LIBNAME)
build/$(LIBNAME): $(OBJECTS)
ar -rf build/$(LIBNAME) $(OBJECTS)
build/obj/%.o : %.$(CPP_FILE_EXTENSION) $(LOCAL_C_INCLUDES)
@mkdir -p `dirname $@`
$(CXX) -o $@ -c $*.$(CPP_FILE_EXTENSION) $(CPPFLAGS)
clean:
$(RM) $(OBJECTS) build/$(LIBNAME)

View file

@ -17,6 +17,7 @@ LOCAL_SRC_FILES := \
src/osmand_log.cpp \ src/osmand_log.cpp \
src/common.cpp \ src/common.cpp \
src/mapObjects.cpp \ src/mapObjects.cpp \
src/multipolygons.cpp \
src/renderRules.cpp \ src/renderRules.cpp \
src/rendering.cpp \ src/rendering.cpp \
src/binaryRead.cpp src/binaryRead.cpp

View file

@ -1,10 +1,15 @@
LOCAL_PATH := . LOCAL_PATH := .
PREBUILT_DIR = ../jni-prebuilt/linux-x86/ PREBUILT_DIR = ../jni-prebuilt/linux-x86/
LIBNAME := osmand.lib LIBNAME := osmand.lib
include Common.mk RUNFILE := osmand_main
include ./Common.mk
LOCAL_SRC_FILES += src/osmand_main.cpp
LDFLAGS = -Wl,--hash-style=both -shared LDFLAGS = -Wl,--hash-style=both -shared
LDLIBS = -L$(PREBUILT_DIR) -lskia -lproto LDRUNFLAGS = -Wl,--hash-style=both
LDLIBS = -L$(PREBUILT_DIR) -lskia -lproto -lpthread -lrt -lft2
CPP_FILE_EXTENSION = cpp CPP_FILE_EXTENSION = cpp
OBJECTS = $(LOCAL_SRC_FILES:src/%.$(CPP_FILE_EXTENSION)=build/obj/%.o) OBJECTS = $(LOCAL_SRC_FILES:src/%.$(CPP_FILE_EXTENSION)=build/obj/%.o)
@ -19,6 +24,14 @@ CPPFLAGS := \
-DHAVING_HASH \ -DHAVING_HASH \
$(C_INCLUDES) $(C_INCLUDES)
target : ../$(RUNFILE)
#target : $(PREBUILT_DIR)/$(LIBNAME) ../$(RUNFILE)
../$(RUNFILE) : $(OBJECTS) $(PREBUILT_DIR)/libskia.a $(PREBUILT_DIR)/libproto.a
$(CXX) $(LDRUNFLAGS) -o ../$(RUNFILE) $(OBJECTS) $(LDLIBS)
@chmod +x ../$(RUNFILE)
$(PREBUILT_DIR)/$(LIBNAME) : build/$(LIBNAME) $(PREBUILT_DIR)/$(LIBNAME) : build/$(LIBNAME)
cp build/$(LIBNAME) $(PREBUILT_DIR)/$(LIBNAME) cp build/$(LIBNAME) $(PREBUILT_DIR)/$(LIBNAME)

View file

@ -1,15 +1,8 @@
#ifndef _OSMAND_BINARY_READ #ifndef _OSMAND_BINARY_READ
#define _OSMAND_BINARY_READ #define _OSMAND_BINARY_READ
#include <math.h> #include "binaryRead.h"
#include "osmand_log.h"
#include <osmand_log.h>
#include <stdio.h>
#include <fstream>
#include <algorithm>
#include <map>
#include <string>
#include "google/protobuf/io/zero_copy_stream_impl.h" #include "google/protobuf/io/zero_copy_stream_impl.h"
#include "google/protobuf/wire_format_lite.h" #include "google/protobuf/wire_format_lite.h"
#include "google/protobuf/wire_format_lite.cc" #include "google/protobuf/wire_format_lite.cc"
@ -18,7 +11,6 @@
#include "common.h" #include "common.h"
#include "mapObjects.h" #include "mapObjects.h"
#include "multipolygons.h" #include "multipolygons.h"
//#include "multipolygons.h"
#include "proto/osmand_odb.pb.h" #include "proto/osmand_odb.pb.h"
using namespace std; using namespace std;
@ -29,8 +21,6 @@ using namespace google::protobuf::internal;
static const int MAP_VERSION = 2; static const int MAP_VERSION = 2;
static const int BASEMAP_ZOOM = 11; static const int BASEMAP_ZOOM = 11;
struct BinaryMapFile; struct BinaryMapFile;
std::map<std::string, BinaryMapFile*> openFiles; std::map<std::string, BinaryMapFile*> openFiles;
@ -101,106 +91,6 @@ struct SearchQuery {
} }
}; };
struct MapTreeBounds {
uint32 length;
uint32 filePointer;
uint32 mapDataBlock;
uint32 left ;
uint32 right ;
uint32 top ;
uint32 bottom;
bool ocean;
MapTreeBounds() {
ocean = -1;
}
};
struct MapRoot: MapTreeBounds {
int minZoom ;
int maxZoom ;
std::vector<MapTreeBounds> bounds;
};
struct MapIndex {
uint32 length;
int filePointer;
std::string name;
std::vector<MapRoot> levels;
HMAP::hash_map<int, tag_value > decodingRules;
// DEFINE hash
//HMAP::hash_map<tag_value, int> encodingRules;
int nameEncodingType;
int refEncodingType;
int coastlineEncodingType;
int coastlineBrokenEncodingType;
int landEncodingType;
int onewayAttribute ;
int onewayReverseAttribute ;
HMAP::hash_set< int > positiveLayers;
HMAP::hash_set< int > negativeLayers;
MapIndex(){
nameEncodingType = refEncodingType = coastlineBrokenEncodingType = coastlineEncodingType = -1;
landEncodingType = onewayAttribute = onewayReverseAttribute = -1;
}
void finishInitializingTags() {
int free = decodingRules.size() * 2 + 1;
coastlineBrokenEncodingType = free++;
initMapEncodingRule(0, coastlineBrokenEncodingType, "natural", "coastline_broken");
if (landEncodingType == -1) {
landEncodingType = free++;
initMapEncodingRule(0, landEncodingType, "natural", "land");
}
}
void initMapEncodingRule(uint32 type, uint32 id, std::string tag, std::string val) {
tag_value pair = tag_value(tag, val);
// DEFINE hash
//encodingRules[pair] = id;
decodingRules[id] = pair;
if ("name" == tag) {
nameEncodingType = id;
} else if ("natural" == tag && "coastline" == val) {
coastlineEncodingType = id;
} else if ("natural" == tag && "land" == val) {
landEncodingType = id;
} else if ("oneway" == tag && "yes" == val) {
onewayAttribute = id;
} else if ("oneway" == tag && "-1" == val) {
onewayReverseAttribute = id;
} else if ("ref" == tag) {
refEncodingType = id;
} else if ("layer" == tag) {
if (val != "" && val != "0") {
if (val[0] == '-') {
negativeLayers.insert(id);
} else {
positiveLayers.insert(id);
}
}
}
}
};
struct BinaryMapFile {
std::string inputName;
std::vector<MapIndex> mapIndexes;
FILE* f;
bool basemap;
bool isBasemap(){
return basemap;
}
~BinaryMapFile() {
fclose(f);
}
};
bool readMapTreeBounds(io::CodedInputStream* input, MapTreeBounds* tree, MapRoot* root) { bool readMapTreeBounds(io::CodedInputStream* input, MapTreeBounds* tree, MapRoot* root) {
int init = 0; int init = 0;

View file

@ -0,0 +1,123 @@
#ifndef _OSMAND_BINARY_READ_H
#define _OSMAND_BINARY_READ_H
#include <stdio.h>
#include <fstream>
#include <algorithm>
#include <map>
#include <string>
#include <stdint.h>
#include "google/protobuf/wire_format_lite.h"
#include "common.h"
#include "mapObjects.h"
struct MapTreeBounds {
uint32 length;
uint32 filePointer;
uint32 mapDataBlock;
uint32 left ;
uint32 right ;
uint32 top ;
uint32 bottom;
bool ocean;
MapTreeBounds() {
ocean = -1;
}
};
struct MapRoot: MapTreeBounds {
int minZoom ;
int maxZoom ;
std::vector<MapTreeBounds> bounds;
};
struct MapIndex {
uint32 length;
int filePointer;
std::string name;
std::vector<MapRoot> levels;
HMAP::hash_map<int, tag_value > decodingRules;
// DEFINE hash
//HMAP::hash_map<tag_value, int> encodingRules;
int nameEncodingType;
int refEncodingType;
int coastlineEncodingType;
int coastlineBrokenEncodingType;
int landEncodingType;
int onewayAttribute ;
int onewayReverseAttribute ;
HMAP::hash_set< int > positiveLayers;
HMAP::hash_set< int > negativeLayers;
MapIndex(){
nameEncodingType = refEncodingType = coastlineBrokenEncodingType = coastlineEncodingType = -1;
landEncodingType = onewayAttribute = onewayReverseAttribute = -1;
}
void finishInitializingTags() {
int free = decodingRules.size() * 2 + 1;
coastlineBrokenEncodingType = free++;
initMapEncodingRule(0, coastlineBrokenEncodingType, "natural", "coastline_broken");
if (landEncodingType == -1) {
landEncodingType = free++;
initMapEncodingRule(0, landEncodingType, "natural", "land");
}
}
void initMapEncodingRule(uint32 type, uint32 id, std::string tag, std::string val) {
tag_value pair = tag_value(tag, val);
// DEFINE hash
//encodingRules[pair] = id;
decodingRules[id] = pair;
if ("name" == tag) {
nameEncodingType = id;
} else if ("natural" == tag && "coastline" == val) {
coastlineEncodingType = id;
} else if ("natural" == tag && "land" == val) {
landEncodingType = id;
} else if ("oneway" == tag && "yes" == val) {
onewayAttribute = id;
} else if ("oneway" == tag && "-1" == val) {
onewayReverseAttribute = id;
} else if ("ref" == tag) {
refEncodingType = id;
} else if ("layer" == tag) {
if (val != "" && val != "0") {
if (val[0] == '-') {
negativeLayers.insert(id);
} else {
positiveLayers.insert(id);
}
}
}
}
};
struct BinaryMapFile {
std::string inputName;
std::vector<MapIndex> mapIndexes;
FILE* f;
bool basemap;
bool isBasemap(){
return basemap;
}
~BinaryMapFile() {
fclose(f);
}
};
extern "C" JNIEXPORT jboolean JNICALL Java_net_osmand_plus_render_NativeOsmandLibrary_initBinaryMapFile(JNIEnv* ienv,
jobject obj, jobject path);
#endif

View file

@ -8,6 +8,28 @@
#include <hash_map> #include <hash_map>
#include <hash_set> #include <hash_set>
#ifdef _MSC_VER
typedef __int8 int8;
typedef __int16 int16;
typedef __int32 int32;
typedef __int64 int64;
typedef unsigned __int8 uint8;
typedef unsigned __int16 uint16;
typedef unsigned __int32 uint32;
typedef unsigned __int64 uint64;
#else
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef int64_t int64;
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef uint64_t uint64;
#endif
#ifdef HAVING_HASH #ifdef HAVING_HASH
#define HMAP __gnu_cxx #define HMAP __gnu_cxx

View file

@ -0,0 +1,497 @@
#ifndef _MULTIPOLYGONS_CPP
#define _MULTIPOLYGONS_CPP
#include "multipolygons.h"
#include "osmand_log.h"
void processCoastlines(std::vector<MapDataObject*>& coastLines, int leftX, int rightX, int bottomY, int topY, int zoom,
bool showIncompleted, std::vector<MapDataObject*>& res) {
std::vector<coordinates> completedRings;
std::vector<coordinates > uncompletedRings;
std::vector<MapDataObject*>::iterator val = coastLines.begin();
res.reserve(coastLines.size());
long long dbId = 0;
for (; val != coastLines.end(); val++) {
MapDataObject* o = *val;
int len = o->points.size();
if (len < 2) {
continue;
}
dbId = o->id >> 1;
coordinates* cs = new coordinates();
int px = o->points.at(0).first;
int py = o->points.at(0).second;
int x = px;
int y = py;
bool pinside = leftX <= x && x <= rightX && y >= topY && y <= bottomY;
if (pinside) {
cs->push_back(int_pair(x, y));
}
for (int i = 1; i < len; i++) {
x = o->points.at(i).first;
y = o->points.at(i).second;
bool inside = leftX <= x && x <= rightX && y >= topY && y <= bottomY;
bool lineEnded = calculateLineCoordinates(inside, x, y, pinside, px, py, leftX, rightX, bottomY, topY, *cs);
if (lineEnded) {
combineMultipolygonLine(completedRings, uncompletedRings, *cs);
// create new line if it goes outside
cs = new coordinates();
}
px = x;
py = y;
pinside = inside;
}
combineMultipolygonLine(completedRings, uncompletedRings, *cs);
}
if (completedRings.size() == 0 && uncompletedRings.size() == 0) {
return;
}
if (uncompletedRings.size() > 0) {
unifyIncompletedRings(uncompletedRings, completedRings, leftX, rightX, bottomY, topY, dbId, zoom);
}
if (!showIncompleted && uncompletedRings.size() > 0) {
res.clear();
return;
}
bool clockwiseFound = false;
for (int i = 0; i < completedRings.size(); i++) {
bool clockwise = isClockwiseWay(completedRings[i]);
clockwiseFound = clockwiseFound || clockwise;
MapDataObject* o = new MapDataObject();
o->points = completedRings[i];
if (clockwise) {
o->types.push_back(tag_value("natural", "coastline"));
} else {
o->types.push_back(tag_value("natural", "land"));
}
o->id = dbId;
o->area = true;
res.push_back(o);
}
// draw uncompleted for debug purpose
for (int i = 0; i < uncompletedRings.size(); i++) {
MapDataObject* o = new MapDataObject();
o->points = uncompletedRings[i];
o->types.push_back(tag_value("natural", "coastline_broken"));
//res.push_back(o);
}
if (!clockwiseFound && uncompletedRings.size() == 0) {
// add complete water tile
MapDataObject* o = new MapDataObject();
o->points.push_back(int_pair(leftX, topY));
o->points.push_back(int_pair(rightX, topY));
o->points.push_back(int_pair(rightX, bottomY));
o->points.push_back(int_pair(leftX, bottomY));
o->points.push_back(int_pair(leftX, topY));
o->id = dbId;
o->types.push_back(tag_value("natural", "coastline"));
osmand_log_print(LOG_ERROR, "!!! Isolated islands !!!");
res.push_back(o);
}
}
// Copied from MapAlgorithms
int ray_intersect_x(int prevX, int prevY, int x, int y, int middleY) {
// prev node above line
// x,y node below line
if (prevY > y) {
int tx = x;
int ty = y;
x = prevX;
y = prevY;
prevX = tx;
prevY = ty;
}
if (y == middleY || prevY == middleY) {
middleY -= 1;
}
if (prevY > middleY || y < middleY) {
return INT_MIN;
} else {
if (y == prevY) {
// the node on the boundary !!!
return x;
}
// that tested on all cases (left/right)
double rx = x + ((double) middleY - y) * ((double) x - prevX) / (((double) y - prevY));
return (int) rx;
}
}
// Copied from MapAlgorithms
bool isClockwiseWay(std::vector<int_pair>& c) {
if (c.size() == 0) {
return true;
}
// calculate middle Y
long long middleY = 0;
for (size_t i = 0; i < c.size(); i++) {
middleY += c.at(i).second;
}
middleY /= (long long) c.size();
double clockwiseSum = 0;
bool firstDirectionUp = false;
int previousX = INT_MIN;
int firstX = INT_MIN;
int prevX = c.at(0).first;
int prevY = c.at(0).second;
for (size_t i = 1; i < c.size(); i++) {
int x = c.at(i).first;
int y = c.at(i).second;
int rX = ray_intersect_x(prevX, prevY, x, y, (int) middleY);
if (rX != INT_MIN) {
bool skipSameSide = (y <= middleY) == (prevY <= middleY);
if (skipSameSide) {
continue;
}
bool directionUp = prevY >= middleY;
if (firstX == INT_MIN) {
firstDirectionUp = directionUp;
firstX = rX;
} else {
bool clockwise = (!directionUp) == (previousX < rX);
if (clockwise) {
clockwiseSum += abs(previousX - rX);
} else {
clockwiseSum -= abs(previousX - rX);
}
}
previousX = rX;
}
prevX = x;
prevY = y;
}
if (firstX != INT_MIN) {
bool clockwise = (!firstDirectionUp) == (previousX < firstX);
if (clockwise) {
clockwiseSum += abs(previousX - firstX);
} else {
clockwiseSum -= abs(previousX - firstX);
}
}
return clockwiseSum >= 0;
}
void combineMultipolygonLine(std::vector<coordinates>& completedRings, std::vector<coordinates>& incompletedRings,
coordinates& coordinates) {
if (coordinates.size() > 0) {
if (coordinates.at(0) == coordinates.at(coordinates.size() - 1)) {
completedRings.push_back(coordinates);
} else {
bool add = true;
for (size_t k = 0; k < incompletedRings.size();) {
bool remove = false;
std::vector<int_pair> i = incompletedRings.at(k);
if (coordinates.at(0) == i.at(i.size() - 1)) {
std::vector<int_pair>::iterator tit = coordinates.begin();
i.insert(i.end(), ++tit, coordinates.end());
remove = true;
coordinates = i;
} else if (coordinates.at(coordinates.size() - 1) == i.at(0)) {
std::vector<int_pair>::iterator tit = i.begin();
coordinates.insert(coordinates.end(), ++tit, i.end());
remove = true;
}
if (remove) {
std::vector<std::vector<int_pair> >::iterator ti = incompletedRings.begin();
ti += k;
incompletedRings.erase(ti);
} else {
k++;
}
if (coordinates.at(0) == coordinates.at(coordinates.size() - 1)) {
completedRings.push_back(coordinates);
add = false;
break;
}
}
if (add) {
incompletedRings.push_back(coordinates);
}
}
}
}
int safelyAddDelta(int number, int delta) {
int res = number + delta;
if (delta > 0 && res < number) {
return INT_MAX;
} else if (delta < 0 && res > number) {
return INT_MIN;
}
return res;
}
void unifyIncompletedRings(std::vector<std::vector<int_pair> >& toProccess, std::vector<std::vector<int_pair> >& completedRings,
int leftX, int rightX, int bottomY, int topY, long dbId, int zoom) {
std::set<int> nonvisitedRings;
std::vector<coordinates > incompletedRings(toProccess);
toProccess.clear();
std::vector<coordinates >::iterator ir = incompletedRings.begin();
int j = 0;
for (j = 0; ir != incompletedRings.end(); ir++,j++) {
int x = ir->at(0).first;
int y = ir->at(0).second;
int sx = ir->at(ir->size() - 1).first;
int sy = ir->at(ir->size() - 1).second;
bool st = y == topY || x == rightX || y == bottomY || x == leftX;
bool end = sy == topY || sx == rightX || sy == bottomY || sx == leftX;
// something goes wrong
// These exceptions are used to check logic about processing multipolygons
// However this situation could happen because of broken multipolygons (so it should data causes app error)
// that's why these exceptions could be replaced with return; statement.
if (!end || !st) {
osmand_log_print(LOG_ERROR, "Error processing multipolygon");
toProccess.push_back(*ir);
} else {
nonvisitedRings.insert(j);
}
}
ir = incompletedRings.begin();
for (j = 0; ir != incompletedRings.end(); ir++, j++) {
if (nonvisitedRings.find(j) == nonvisitedRings.end()) {
continue;
}
int x = ir->at(ir->size() - 1).first;
int y = ir->at(ir->size() - 1).second;
// 31 - (zoom + 8)
const int EVAL_DELTA = 6 << (23 - zoom);
const int UNDEFINED_MIN_DIFF = -1 - EVAL_DELTA;
while (true) {
int st = 0; // st already checked to be one of the four
if (y == topY) {
st = 0;
} else if (x == rightX) {
st = 1;
} else if (y == bottomY) {
st = 2;
} else if (x == leftX) {
st = 3;
}
int nextRingIndex = -1;
// BEGIN go clockwise around rectangle
for (int h = st; h < st + 4; h++) {
// BEGIN find closest nonvisited start (including current)
int mindiff = UNDEFINED_MIN_DIFF;
std::vector<std::vector<int_pair> >::iterator cni = incompletedRings.begin();
int cnik = 0;
for (;cni != incompletedRings.end(); cni++, cnik ++) {
if (nonvisitedRings.find(cnik) == nonvisitedRings.end()) {
continue;
}
int csx = cni->at(0).first;
int csy = cni->at(0).second;
if (h % 4 == 0) {
// top
if (csy == topY && csx >= safelyAddDelta(x, -EVAL_DELTA)) {
if (mindiff == UNDEFINED_MIN_DIFF || (csx - x) <= mindiff) {
mindiff = (csx - x);
nextRingIndex = cnik;
}
}
} else if (h % 4 == 1) {
// right
if (csx == rightX && csy >= safelyAddDelta(y, -EVAL_DELTA)) {
if (mindiff == UNDEFINED_MIN_DIFF || (csy - y) <= mindiff) {
mindiff = (csy - y);
nextRingIndex = cnik;
}
}
} else if (h % 4 == 2) {
// bottom
if (csy == bottomY && csx <= safelyAddDelta(x, EVAL_DELTA)) {
if (mindiff == UNDEFINED_MIN_DIFF || (x - csx) <= mindiff) {
mindiff = (x - csx);
nextRingIndex = cnik;
}
}
} else if (h % 4 == 3) {
// left
if (csx == leftX && csy <= safelyAddDelta(y, EVAL_DELTA)) {
if (mindiff == UNDEFINED_MIN_DIFF || (y - csy) <= mindiff) {
mindiff = (y - csy);
nextRingIndex = cnik;
}
}
}
} // END find closest start (including current)
// we found start point
if (mindiff != UNDEFINED_MIN_DIFF) {
break;
} else {
if (h % 4 == 0) {
// top
y = topY;
x = rightX;
} else if (h % 4 == 1) {
// right
y = bottomY;
x = rightX;
} else if (h % 4 == 2) {
// bottom
y = bottomY;
x = leftX;
} else if (h % 4 == 3) {
y = topY;
x = leftX;
}
ir->push_back(int_pair(x, y));
}
} // END go clockwise around rectangle
if (nextRingIndex == -1) {
// it is impossible (current start should always be found)
} else if (nextRingIndex == j) {
ir->push_back(ir->at(0));
nonvisitedRings.erase(j);
break;
} else {
std::vector<int_pair> p = incompletedRings.at(nextRingIndex);
ir->insert(ir->end(), p.begin(), p.end());
nonvisitedRings.erase(nextRingIndex);
// get last point and start again going clockwise
x = ir->at(ir->size() - 1).first;
y = ir->at(ir->size() - 1).second;
}
}
completedRings.push_back(*ir);
}
}
/**
* @return -1 if there is no instersection or x<<32 | y
*/
bool calculateIntersection(int x, int y, int px, int py, int leftX, int rightX, int bottomY, int topY, int_pair& b) {
// firstly try to search if the line goes in
if (py < topY && y >= topY) {
int tx = (int) (px + ((double) (x - px) * (topY - py)) / (y - py));
if (leftX <= tx && tx <= rightX) {
b.first = tx;
b.second = topY;
return true;
}
}
if (py > bottomY && y <= bottomY) {
int tx = (int) (px + ((double) (x - px) * (py - bottomY)) / (py - y));
if (leftX <= tx && tx <= rightX) {
b.first = tx;
b.second = bottomY;
return true;
}
}
if (px < leftX && x >= leftX) {
int ty = (int) (py + ((double) (y - py) * (leftX - px)) / (x - px));
if (ty >= topY && ty <= bottomY) {
b.first = leftX;
b.second = ty;
return true;
}
}
if (px > rightX && x <= rightX) {
int ty = (int) (py + ((double) (y - py) * (px - rightX)) / (px - x));
if (ty >= topY && ty <= bottomY) {
b.first = rightX;
b.second = ty;
return true;
}
}
// try to search if point goes out
if (py > topY && y <= topY) {
int tx = (int) (px + ((double) (x - px) * (topY - py)) / (y - py));
if (leftX <= tx && tx <= rightX) {
b.first = tx;
b.second = topY;
return true;
}
}
if (py < bottomY && y >= bottomY) {
int tx = (int) (px + ((double) (x - px) * (py - bottomY)) / (py - y));
if (leftX <= tx && tx <= rightX) {
b.first = tx;
b.second = bottomY;
return true;
}
}
if (px > leftX && x <= leftX) {
int ty = (int) (py + ((double) (y - py) * (leftX - px)) / (x - px));
if (ty >= topY && ty <= bottomY) {
b.first = leftX;
b.second = ty;
return true;
}
}
if (px < rightX && x >= rightX) {
int ty = (int) (py + ((double) (y - py) * (px - rightX)) / (px - x));
if (ty >= topY && ty <= bottomY) {
b.first = rightX;
b.second = ty;
return true;
}
}
if (px == rightX || px == leftX || py == topY || py == bottomY) {
b.first = px;
b.second = py;
// return true;
// Is it right? to not return anything?
}
return false;
}
bool calculateLineCoordinates(bool inside, int x, int y, bool pinside, int px, int py, int leftX, int rightX,
int bottomY, int topY, std::vector<int_pair>& coordinates) {
bool lineEnded = false;
int_pair b(x, y);
if (pinside) {
if (!inside) {
bool is = calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY, b);
if (!is) {
b.first = px;
b.second = py;
}
coordinates.push_back(b);
lineEnded = true;
} else {
coordinates.push_back(b);
}
} else {
bool is = calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY, b);
if (inside) {
// assert is != -1;
coordinates.push_back(b);
int_pair n(x, y);
coordinates.push_back(n);
} else if (is) {
coordinates.push_back(b);
calculateIntersection(x, y, b.first, b.second, leftX, rightX, bottomY, topY, b);
coordinates.push_back(b);
lineEnded = true;
}
}
return lineEnded;
}
#endif

View file

@ -1,3 +1,5 @@
#ifndef _MULTIPOLYGONS_H
#define _MULTIPOLYGONS_H
#include <stdio.h> #include <stdio.h>
#include <map> #include <map>
@ -9,6 +11,7 @@
/// !!! Fuly copied from MapRenderRepositories.java, should be carefully synchroinized /// !!! Fuly copied from MapRenderRepositories.java, should be carefully synchroinized
bool isClockwiseWay(std::vector<int_pair>& c) ; bool isClockwiseWay(std::vector<int_pair>& c) ;
bool calculateLineCoordinates(bool inside, int x, int y, bool pinside, int px, int py, int leftX, int rightX, bool calculateLineCoordinates(bool inside, int x, int y, bool pinside, int px, int py, int leftX, int rightX,
int bottomY, int topY, std::vector<int_pair>& coordinates); int bottomY, int topY, std::vector<int_pair>& coordinates);
@ -20,491 +23,6 @@ void unifyIncompletedRings(std::vector<std::vector<int_pair> >& incompletedRings
void processCoastlines(std::vector<MapDataObject*>& coastLines, int leftX, int rightX, int bottomY, int topY, int zoom, void processCoastlines(std::vector<MapDataObject*>& coastLines, int leftX, int rightX, int bottomY, int topY, int zoom,
bool showIncompleted, std::vector<MapDataObject*>& res) { bool showIncompleted, std::vector<MapDataObject*>& res);
std::vector<coordinates> completedRings;
std::vector<coordinates > uncompletedRings;
std::vector<MapDataObject*>::iterator val = coastLines.begin();
res.reserve(coastLines.size());
long long dbId = 0;
for (; val != coastLines.end(); val++) {
MapDataObject* o = *val;
int len = o->points.size();
if (len < 2) {
continue;
}
dbId = o->id >> 1;
coordinates* cs = new coordinates();
int px = o->points.at(0).first;
int py = o->points.at(0).second;
int x = px;
int y = py;
bool pinside = leftX <= x && x <= rightX && y >= topY && y <= bottomY;
if (pinside) {
cs->push_back(int_pair(x, y));
}
for (int i = 1; i < len; i++) {
x = o->points.at(i).first;
y = o->points.at(i).second;
bool inside = leftX <= x && x <= rightX && y >= topY && y <= bottomY;
bool lineEnded = calculateLineCoordinates(inside, x, y, pinside, px, py, leftX, rightX, bottomY, topY, *cs);
if (lineEnded) {
combineMultipolygonLine(completedRings, uncompletedRings, *cs);
// create new line if it goes outside
cs = new coordinates();
}
px = x;
py = y;
pinside = inside;
}
combineMultipolygonLine(completedRings, uncompletedRings, *cs);
}
if (completedRings.size() == 0 && uncompletedRings.size() == 0) {
return;
}
if (uncompletedRings.size() > 0) {
unifyIncompletedRings(uncompletedRings, completedRings, leftX, rightX, bottomY, topY, dbId, zoom);
}
if (!showIncompleted && uncompletedRings.size() > 0) {
res.clear();
return;
}
bool clockwiseFound = false;
for (int i = 0; i < completedRings.size(); i++) {
bool clockwise = isClockwiseWay(completedRings[i]);
clockwiseFound = clockwiseFound || clockwise;
MapDataObject* o = new MapDataObject();
o->points = completedRings[i];
if (clockwise) {
o->types.push_back(tag_value("natural", "coastline"));
} else {
o->types.push_back(tag_value("natural", "land"));
}
o->id = dbId;
o->area = true;
res.push_back(o);
}
// draw uncompleted for debug purpose #endif
for (int i = 0; i < uncompletedRings.size(); i++) {
MapDataObject* o = new MapDataObject();
o->points = uncompletedRings[i];
o->types.push_back(tag_value("natural", "coastline_broken"));
//res.push_back(o);
}
if (!clockwiseFound && uncompletedRings.size() == 0) {
// add complete water tile
MapDataObject* o = new MapDataObject();
o->points.push_back(int_pair(leftX, topY));
o->points.push_back(int_pair(rightX, topY));
o->points.push_back(int_pair(rightX, bottomY));
o->points.push_back(int_pair(leftX, bottomY));
o->points.push_back(int_pair(leftX, topY));
o->id = dbId;
o->types.push_back(tag_value("natural", "coastline"));
osmand_log_print(LOG_ERROR, "!!! Isolated islands !!!");
res.push_back(o);
}
}
// Copied from MapAlgorithms
int ray_intersect_x(int prevX, int prevY, int x, int y, int middleY) {
// prev node above line
// x,y node below line
if (prevY > y) {
int tx = x;
int ty = y;
x = prevX;
y = prevY;
prevX = tx;
prevY = ty;
}
if (y == middleY || prevY == middleY) {
middleY -= 1;
}
if (prevY > middleY || y < middleY) {
return INT_MIN;
} else {
if (y == prevY) {
// the node on the boundary !!!
return x;
}
// that tested on all cases (left/right)
double rx = x + ((double) middleY - y) * ((double) x - prevX) / (((double) y - prevY));
return (int) rx;
}
}
// Copied from MapAlgorithms
bool isClockwiseWay(std::vector<int_pair>& c) {
if (c.size() == 0) {
return true;
}
// calculate middle Y
long long middleY = 0;
for (size_t i = 0; i < c.size(); i++) {
middleY += c.at(i).second;
}
middleY /= (long long) c.size();
double clockwiseSum = 0;
bool firstDirectionUp = false;
int previousX = INT_MIN;
int firstX = INT_MIN;
int prevX = c.at(0).first;
int prevY = c.at(0).second;
for (size_t i = 1; i < c.size(); i++) {
int x = c.at(i).first;
int y = c.at(i).second;
int rX = ray_intersect_x(prevX, prevY, x, y, (int) middleY);
if (rX != INT_MIN) {
bool skipSameSide = (y <= middleY) == (prevY <= middleY);
if (skipSameSide) {
continue;
}
bool directionUp = prevY >= middleY;
if (firstX == INT_MIN) {
firstDirectionUp = directionUp;
firstX = rX;
} else {
bool clockwise = (!directionUp) == (previousX < rX);
if (clockwise) {
clockwiseSum += abs(previousX - rX);
} else {
clockwiseSum -= abs(previousX - rX);
}
}
previousX = rX;
}
prevX = x;
prevY = y;
}
if (firstX != INT_MIN) {
bool clockwise = (!firstDirectionUp) == (previousX < firstX);
if (clockwise) {
clockwiseSum += abs(previousX - firstX);
} else {
clockwiseSum -= abs(previousX - firstX);
}
}
return clockwiseSum >= 0;
}
void combineMultipolygonLine(std::vector<coordinates>& completedRings, std::vector<coordinates>& incompletedRings,
coordinates& coordinates) {
if (coordinates.size() > 0) {
if (coordinates.at(0) == coordinates.at(coordinates.size() - 1)) {
completedRings.push_back(coordinates);
} else {
bool add = true;
for (size_t k = 0; k < incompletedRings.size();) {
bool remove = false;
std::vector<int_pair> i = incompletedRings.at(k);
if (coordinates.at(0) == i.at(i.size() - 1)) {
std::vector<int_pair>::iterator tit = coordinates.begin();
i.insert(i.end(), ++tit, coordinates.end());
remove = true;
coordinates = i;
} else if (coordinates.at(coordinates.size() - 1) == i.at(0)) {
std::vector<int_pair>::iterator tit = i.begin();
coordinates.insert(coordinates.end(), ++tit, i.end());
remove = true;
}
if (remove) {
std::vector<std::vector<int_pair> >::iterator ti = incompletedRings.begin();
ti += k;
incompletedRings.erase(ti);
} else {
k++;
}
if (coordinates.at(0) == coordinates.at(coordinates.size() - 1)) {
completedRings.push_back(coordinates);
add = false;
break;
}
}
if (add) {
incompletedRings.push_back(coordinates);
}
}
}
}
int safelyAddDelta(int number, int delta) {
int res = number + delta;
if (delta > 0 && res < number) {
return INT_MAX;
} else if (delta < 0 && res > number) {
return INT_MIN;
}
return res;
}
void unifyIncompletedRings(std::vector<std::vector<int_pair> >& toProccess, std::vector<std::vector<int_pair> >& completedRings,
int leftX, int rightX, int bottomY, int topY, long dbId, int zoom) {
std::set<int> nonvisitedRings;
std::vector<coordinates > incompletedRings(toProccess);
toProccess.clear();
std::vector<coordinates >::iterator ir = incompletedRings.begin();
int j = 0;
for (j = 0; ir != incompletedRings.end(); ir++,j++) {
int x = ir->at(0).first;
int y = ir->at(0).second;
int sx = ir->at(ir->size() - 1).first;
int sy = ir->at(ir->size() - 1).second;
bool st = y == topY || x == rightX || y == bottomY || x == leftX;
bool end = sy == topY || sx == rightX || sy == bottomY || sx == leftX;
// something goes wrong
// These exceptions are used to check logic about processing multipolygons
// However this situation could happen because of broken multipolygons (so it should data causes app error)
// that's why these exceptions could be replaced with return; statement.
if (!end || !st) {
osmand_log_print(LOG_ERROR, "Error processing multipolygon");
toProccess.push_back(*ir);
} else {
nonvisitedRings.insert(j);
}
}
ir = incompletedRings.begin();
for (j = 0; ir != incompletedRings.end(); ir++, j++) {
if (nonvisitedRings.find(j) == nonvisitedRings.end()) {
continue;
}
int x = ir->at(ir->size() - 1).first;
int y = ir->at(ir->size() - 1).second;
// 31 - (zoom + 8)
const int EVAL_DELTA = 6 << (23 - zoom);
const int UNDEFINED_MIN_DIFF = -1 - EVAL_DELTA;
while (true) {
int st = 0; // st already checked to be one of the four
if (y == topY) {
st = 0;
} else if (x == rightX) {
st = 1;
} else if (y == bottomY) {
st = 2;
} else if (x == leftX) {
st = 3;
}
int nextRingIndex = -1;
// BEGIN go clockwise around rectangle
for (int h = st; h < st + 4; h++) {
// BEGIN find closest nonvisited start (including current)
int mindiff = UNDEFINED_MIN_DIFF;
std::vector<std::vector<int_pair> >::iterator cni = incompletedRings.begin();
int cnik = 0;
for (;cni != incompletedRings.end(); cni++, cnik ++) {
if (nonvisitedRings.find(cnik) == nonvisitedRings.end()) {
continue;
}
int csx = cni->at(0).first;
int csy = cni->at(0).second;
if (h % 4 == 0) {
// top
if (csy == topY && csx >= safelyAddDelta(x, -EVAL_DELTA)) {
if (mindiff == UNDEFINED_MIN_DIFF || (csx - x) <= mindiff) {
mindiff = (csx - x);
nextRingIndex = cnik;
}
}
} else if (h % 4 == 1) {
// right
if (csx == rightX && csy >= safelyAddDelta(y, -EVAL_DELTA)) {
if (mindiff == UNDEFINED_MIN_DIFF || (csy - y) <= mindiff) {
mindiff = (csy - y);
nextRingIndex = cnik;
}
}
} else if (h % 4 == 2) {
// bottom
if (csy == bottomY && csx <= safelyAddDelta(x, EVAL_DELTA)) {
if (mindiff == UNDEFINED_MIN_DIFF || (x - csx) <= mindiff) {
mindiff = (x - csx);
nextRingIndex = cnik;
}
}
} else if (h % 4 == 3) {
// left
if (csx == leftX && csy <= safelyAddDelta(y, EVAL_DELTA)) {
if (mindiff == UNDEFINED_MIN_DIFF || (y - csy) <= mindiff) {
mindiff = (y - csy);
nextRingIndex = cnik;
}
}
}
} // END find closest start (including current)
// we found start point
if (mindiff != UNDEFINED_MIN_DIFF) {
break;
} else {
if (h % 4 == 0) {
// top
y = topY;
x = rightX;
} else if (h % 4 == 1) {
// right
y = bottomY;
x = rightX;
} else if (h % 4 == 2) {
// bottom
y = bottomY;
x = leftX;
} else if (h % 4 == 3) {
y = topY;
x = leftX;
}
ir->push_back(int_pair(x, y));
}
} // END go clockwise around rectangle
if (nextRingIndex == -1) {
// it is impossible (current start should always be found)
} else if (nextRingIndex == j) {
ir->push_back(ir->at(0));
nonvisitedRings.erase(j);
break;
} else {
std::vector<int_pair> p = incompletedRings.at(nextRingIndex);
ir->insert(ir->end(), p.begin(), p.end());
nonvisitedRings.erase(nextRingIndex);
// get last point and start again going clockwise
x = ir->at(ir->size() - 1).first;
y = ir->at(ir->size() - 1).second;
}
}
completedRings.push_back(*ir);
}
}
/**
* @return -1 if there is no instersection or x<<32 | y
*/
bool calculateIntersection(int x, int y, int px, int py, int leftX, int rightX, int bottomY, int topY, int_pair& b) {
// firstly try to search if the line goes in
if (py < topY && y >= topY) {
int tx = (int) (px + ((double) (x - px) * (topY - py)) / (y - py));
if (leftX <= tx && tx <= rightX) {
b.first = tx;
b.second = topY;
return true;
}
}
if (py > bottomY && y <= bottomY) {
int tx = (int) (px + ((double) (x - px) * (py - bottomY)) / (py - y));
if (leftX <= tx && tx <= rightX) {
b.first = tx;
b.second = bottomY;
return true;
}
}
if (px < leftX && x >= leftX) {
int ty = (int) (py + ((double) (y - py) * (leftX - px)) / (x - px));
if (ty >= topY && ty <= bottomY) {
b.first = leftX;
b.second = ty;
return true;
}
}
if (px > rightX && x <= rightX) {
int ty = (int) (py + ((double) (y - py) * (px - rightX)) / (px - x));
if (ty >= topY && ty <= bottomY) {
b.first = rightX;
b.second = ty;
return true;
}
}
// try to search if point goes out
if (py > topY && y <= topY) {
int tx = (int) (px + ((double) (x - px) * (topY - py)) / (y - py));
if (leftX <= tx && tx <= rightX) {
b.first = tx;
b.second = topY;
return true;
}
}
if (py < bottomY && y >= bottomY) {
int tx = (int) (px + ((double) (x - px) * (py - bottomY)) / (py - y));
if (leftX <= tx && tx <= rightX) {
b.first = tx;
b.second = bottomY;
return true;
}
}
if (px > leftX && x <= leftX) {
int ty = (int) (py + ((double) (y - py) * (leftX - px)) / (x - px));
if (ty >= topY && ty <= bottomY) {
b.first = leftX;
b.second = ty;
return true;
}
}
if (px < rightX && x >= rightX) {
int ty = (int) (py + ((double) (y - py) * (px - rightX)) / (px - x));
if (ty >= topY && ty <= bottomY) {
b.first = rightX;
b.second = ty;
return true;
}
}
if (px == rightX || px == leftX || py == topY || py == bottomY) {
b.first = px;
b.second = py;
// return true;
// Is it right? to not return anything?
}
return false;
}
bool calculateLineCoordinates(bool inside, int x, int y, bool pinside, int px, int py, int leftX, int rightX,
int bottomY, int topY, std::vector<int_pair>& coordinates) {
bool lineEnded = false;
int_pair b(x, y);
if (pinside) {
if (!inside) {
bool is = calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY, b);
if (!is) {
b.first = px;
b.second = py;
}
coordinates.push_back(b);
lineEnded = true;
} else {
coordinates.push_back(b);
}
} else {
bool is = calculateIntersection(x, y, px, py, leftX, rightX, bottomY, topY, b);
if (inside) {
// assert is != -1;
coordinates.push_back(b);
int_pair n(x, y);
coordinates.push_back(n);
} else if (is) {
coordinates.push_back(b);
calculateIntersection(x, y, b.first, b.second, leftX, rightX, bottomY, topY, b);
coordinates.push_back(b);
lineEnded = true;
}
}
return lineEnded;
}

View file

@ -25,7 +25,7 @@ void osmand_log_print(int type, const char* msg, ...) {
va_list args; va_list args;
va_start( args, msg); va_start( args, msg);
// TODO by type // TODO by type
printf(msg, msg, args); printf(msg, args);
va_end(args); va_end(args);
} }

View file

@ -0,0 +1,6 @@
#include "binaryRead.h"
int main() {
printf("Hello world \n");
}

BIN
Osmand-kernel/osmand_main Executable file

Binary file not shown.

View file

@ -1,7 +1,9 @@
include Common.mk include Common.mk
CPP_FILE_EXTENSION = cpp
LIBNAME := libproto.a LIBNAME := libproto.a
PREBUILT_DIR = ../jni-prebuilt/linux-x86/ PREBUILT_DIR = ../jni-prebuilt/linux-x86/
OBJECTS = $(LOCAL_SRC_FILES:%.cc=build/obj/%.o) OBJECTS = $(LOCAL_SRC_FILES:%.$(CPP_FILE_EXTENSION)=build/obj/%.o)
CPPFLAGS := -DGOOGLE_PROTOBUF_NO_RTTI -I. CPPFLAGS := -DGOOGLE_PROTOBUF_NO_RTTI -I.
LDLIBS = -lpthread LDLIBS = -lpthread
@ -13,9 +15,9 @@ $(PREBUILT_DIR)/$(LIBNAME) : build/$(LIBNAME)
build/$(LIBNAME): $(OBJECTS) build/$(LIBNAME): $(OBJECTS)
ar -rf build/$(LIBNAME) $(OBJECTS) ar -rf build/$(LIBNAME) $(OBJECTS)
build/obj/%.o : build/obj/%.o : %.$(CPP_FILE_EXTENSION) $(LOCAL_C_INCLUDES)
@mkdir -p `dirname $@` @mkdir -p `dirname $@`
$(CXX) -o $@ -c $*.cc $(CPPFLAGS) $(CXX) -o $@ -c $*.$(CPP_FILE_EXTENSION) $(CPPFLAGS)
clean: clean:
$(RM) $(OBJECTS) build/$(LIBNAME) $(RM) $(OBJECTS) build/$(LIBNAME)

View file

@ -12,6 +12,7 @@ LOCAL_SRC_FILES += \
$(OSMAND_SKIA_LOC)/src/ports/SkThread_pthread.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkThread_pthread.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkDebug_stdio.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkDebug_stdio.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkFontHost_FreeType.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkFontHost_FreeType.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkFontHost_linux.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkOSFile_stdio.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkOSFile_stdio.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkTime_Unix.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkTime_Unix.cpp \
$(OSMAND_SKIA_LOC)/src/ports/SkMemory_malloc.cpp \ $(OSMAND_SKIA_LOC)/src/ports/SkMemory_malloc.cpp \
@ -40,7 +41,7 @@ build/$(LIBNAME): $(OBJECTS)
ar -rf build/$(LIBNAME) $(OBJECTS) ar -rf build/$(LIBNAME) $(OBJECTS)
cp build/$(LIBNAME) ../jni-prebuilt/linux-x86/$(LIBNAME) cp build/$(LIBNAME) ../jni-prebuilt/linux-x86/$(LIBNAME)
build/obj/%.o : build/obj/%.o : %.$(CPP_FILE_EXTENSION) $(LOCAL_C_INCLUDES)
@mkdir -p `dirname $@` @mkdir -p `dirname $@`
$(CXX) -o $@ -c $*.$(CPP_FILE_EXTENSION) $(CPPFLAGS) $(CXX) -o $@ -c $*.$(CPP_FILE_EXTENSION) $(CPPFLAGS)