Improve native rendering. Sort rendering area based on area
This commit is contained in:
parent
4c6c68e8b1
commit
b2668c3429
5 changed files with 139 additions and 107 deletions
|
@ -122,11 +122,13 @@ public class PoiFiltersHelper {
|
|||
} else if(UDF_SIGHTSEEING.equals(key)){
|
||||
putAll(types, AmenityType.HISTORIC);
|
||||
putAll(types, AmenityType.TOURISM);
|
||||
putAll(types, AmenityType.OSMWIKI);
|
||||
putValues(types, AmenityType.OTHER, "place_of_worship");
|
||||
} else if(UDF_FOR_TOURISTS.equals(key)){
|
||||
putAll(types, AmenityType.HISTORIC);
|
||||
putAll(types, AmenityType.TOURISM);
|
||||
putAll(types, AmenityType.FINANCE);
|
||||
putAll(types, AmenityType.OSMWIKI);
|
||||
putValues(types, AmenityType.OTHER, "place_of_worship", "internet_access", "embassy","emergency_phone","marketplace",
|
||||
"post_office","telephone", "toilets");
|
||||
} else if(UDF_FUEL.equals(key)){
|
||||
|
|
|
@ -172,7 +172,7 @@ std::string RenderingContext::getReshapedString(const std::string& src) {
|
|||
}
|
||||
|
||||
|
||||
inline double getPowZoom(float zoom){
|
||||
double getPowZoom(float zoom){
|
||||
if(zoom >= 0 && zoom - floor(zoom) < 0.05f){
|
||||
return 1 << ((int)zoom);
|
||||
} else {
|
||||
|
|
|
@ -162,8 +162,8 @@ public:
|
|||
int visible;
|
||||
int allObjects;
|
||||
int lastRenderedKey;
|
||||
class ElapsedTimer textRendering;
|
||||
class ElapsedTimer nativeOperations;
|
||||
ElapsedTimer textRendering;
|
||||
ElapsedTimer nativeOperations;
|
||||
|
||||
// because they used in 3rd party functions
|
||||
public :
|
||||
|
@ -294,6 +294,8 @@ void purgeCachedBitmaps();
|
|||
int get31TileNumberX(double longitude);
|
||||
int get31TileNumberY( double latitude);
|
||||
|
||||
double getPowZoom(float zoom);
|
||||
|
||||
double getLongitudeFromTile(float zoom, double x) ;
|
||||
double getLatitudeFromTile(float zoom, double y);
|
||||
|
||||
|
|
|
@ -25,8 +25,18 @@
|
|||
#include "binaryRead.h"
|
||||
#include "textdraw.cpp"
|
||||
#include "mapObjects.h"
|
||||
#include "rendering.h"
|
||||
|
||||
|
||||
|
||||
struct MapDataObjectPrimitive {
|
||||
MapDataObject* obj;
|
||||
int typeInd;
|
||||
float order;
|
||||
int objectType;
|
||||
};
|
||||
|
||||
const int MAX_V = 32;
|
||||
void calcPoint(std::pair<int, int> c, RenderingContext* rc)
|
||||
{
|
||||
rc->pointCount++;
|
||||
|
@ -360,6 +370,14 @@ void drawPolyline(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas
|
|||
if (!rendered || !updatePaint(req, paint, 0, 0, rc)) {
|
||||
return;
|
||||
}
|
||||
int shadowColor = req->getIntPropertyValue(req->props()->R_SHADOW_COLOR);
|
||||
int shadowRadius = req->getIntPropertyValue(req->props()->R_SHADOW_RADIUS);
|
||||
if(drawOnlyShadow && shadowRadius == 0) {
|
||||
return;
|
||||
}
|
||||
if(shadowColor == 0) {
|
||||
shadowColor = rc->getShadowRenderingColor();
|
||||
}
|
||||
int oneway = 0;
|
||||
if (rc->getZoom() >= 16 && pair.first == "highway") {
|
||||
if (mObj->containsAdditional("oneway", "yes")) {
|
||||
|
@ -377,6 +395,7 @@ void drawPolyline(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas
|
|||
float prevx;
|
||||
float prevy;
|
||||
bool intersect = false;
|
||||
int prevCross = 0;
|
||||
for (; i < length; i++) {
|
||||
calcPoint(mObj->points.at(i), rc);
|
||||
if (i == 0) {
|
||||
|
@ -388,22 +407,22 @@ void drawPolyline(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas
|
|||
path.lineTo(rc->calcX, rc->calcY);
|
||||
}
|
||||
if (!intersect) {
|
||||
if (rc->calcX >= 0 && rc->calcY >= 0 && rc->calcX < rc->getWidth()&& rc->calcY < rc->getHeight()) {
|
||||
if (rc->calcX >= 0 && rc->calcY >= 0 && rc->calcX < rc->getWidth() && rc->calcY < rc->getHeight()) {
|
||||
intersect = true;
|
||||
}
|
||||
if (!intersect && i > 0) {
|
||||
if ((rc->calcX < 0 && prevx < 0) || (rc->calcY < 0 && prevy < 0) ||
|
||||
(rc->calcX> rc->getWidth() && prevx > rc->getWidth())
|
||||
|| (rc->calcY > rc->getHeight() && prevy > rc->getHeight())) {
|
||||
intersect = false;
|
||||
} else {
|
||||
intersect = true;
|
||||
} else {
|
||||
int cross = 0;
|
||||
cross |= (rc->calcX < 0 ? 1 : 0);
|
||||
cross |= (rc->calcX > rc->getWidth() ? 2 : 0);
|
||||
cross |= (rc->calcY < 0 ? 4 : 0);
|
||||
cross |= (rc->calcY > rc->getHeight() ? 8 : 0);
|
||||
if(i > 0) {
|
||||
if((prevCross & cross) == 0) {
|
||||
intersect = true;
|
||||
}
|
||||
}
|
||||
|
||||
prevCross = cross;
|
||||
}
|
||||
}
|
||||
prevx = rc->calcX;
|
||||
prevy = rc->calcY;
|
||||
}
|
||||
|
||||
if (!intersect) {
|
||||
|
@ -412,11 +431,6 @@ void drawPolyline(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas
|
|||
|
||||
if (i > 0) {
|
||||
if (drawOnlyShadow) {
|
||||
int shadowColor = req->getIntPropertyValue(req->props()->R_SHADOW_COLOR);
|
||||
int shadowRadius = req->getIntPropertyValue(req->props()->R_SHADOW_RADIUS);
|
||||
if(shadowColor == 0) {
|
||||
shadowColor = rc->getShadowRenderingColor();
|
||||
}
|
||||
drawPolylineShadow(cv, paint, rc, &path, shadowColor, shadowRadius);
|
||||
} else {
|
||||
if (updatePaint(req, paint, -2, 0, rc)) {
|
||||
|
@ -467,9 +481,7 @@ void drawPolygon(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas*
|
|||
rc->visible++;
|
||||
SkPath path;
|
||||
int i = 0;
|
||||
float prevx;
|
||||
float prevy;
|
||||
bool intersect = false;
|
||||
bool containsPoint = false;
|
||||
int bounds = 0;
|
||||
for (; i < length; i++) {
|
||||
calcPoint(mObj->points.at(i), rc);
|
||||
|
@ -478,35 +490,36 @@ void drawPolygon(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas*
|
|||
} else {
|
||||
path.lineTo(rc->calcX, rc->calcY);
|
||||
}
|
||||
xText += rc->calcX;
|
||||
yText += rc->calcY;
|
||||
if (!intersect) {
|
||||
float tx = rc->calcX;
|
||||
if (tx < 0) {
|
||||
tx = 0;
|
||||
}
|
||||
if (tx > rc->getWidth()) {
|
||||
tx = rc->getWidth();
|
||||
}
|
||||
float ty = rc->calcX;
|
||||
if (ty < 0) {
|
||||
ty = 0;
|
||||
}
|
||||
if (ty > rc->getHeight()) {
|
||||
ty = rc->getHeight();
|
||||
}
|
||||
xText += tx;
|
||||
yText += ty;
|
||||
if (!containsPoint) {
|
||||
if (rc->calcX >= 0 && rc->calcY >= 0 && rc->calcX < rc->getWidth() && rc->calcY < rc->getHeight()) {
|
||||
intersect = true;
|
||||
containsPoint = true;
|
||||
}
|
||||
bounds |= (rc->calcX < 0 ? 1 : 0);
|
||||
bounds |= (rc->calcX >= rc->getWidth() ? 2 : 0);
|
||||
bounds |= (rc->calcY < 0 ? 4 : 0);
|
||||
bounds |= (rc->calcY >= rc->getHeight() ? 8 : 0);
|
||||
if (!intersect && i > 0) {
|
||||
if ((rc->calcX < 0 && prevx < 0) || (rc->calcY < 0 && prevy < 0)
|
||||
|| (rc->calcX > rc->getWidth() && prevx > rc->getWidth())
|
||||
|| (rc->calcY > rc->getHeight() && prevy > rc->getHeight())) {
|
||||
intersect = false;
|
||||
} else {
|
||||
intersect = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!intersect){
|
||||
xText /= length;
|
||||
yText /= length;
|
||||
if(!containsPoint){
|
||||
if(bounds == 15) {
|
||||
path.reset();
|
||||
path.moveTo(0, 0);
|
||||
path.lineTo(0, rc->getWidth());
|
||||
path.lineTo(rc->getHeight(), rc->getWidth());
|
||||
path.lineTo(rc->getHeight(), 0);
|
||||
path.close();
|
||||
xText = rc->getWidth() / 2;
|
||||
yText = rc->getHeight() / 2;
|
||||
} else {
|
||||
|
@ -534,7 +547,7 @@ void drawPolygon(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas*
|
|||
PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
|
||||
}
|
||||
|
||||
renderText(mObj, req, rc, pair.first, pair.second, xText / length, yText / length, NULL);
|
||||
renderText(mObj, req, rc, pair.first, pair.second, xText, yText, NULL);
|
||||
}
|
||||
|
||||
void drawPoint(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas* cv, SkPaint* paint,
|
||||
|
@ -579,18 +592,30 @@ void drawPoint(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas* c
|
|||
|
||||
}
|
||||
|
||||
void drawObject(RenderingContext* rc, MapDataObject* mObj, SkCanvas* cv, RenderingRuleSearchRequest* req,
|
||||
SkPaint* paint, int l, int renderText, int drawOnlyShadow, int t) {
|
||||
rc->allObjects++;
|
||||
tag_value pair = mObj->types.at(l);
|
||||
if (t == 1 && !drawOnlyShadow) {
|
||||
// point
|
||||
drawPoint(mObj, req, cv, paint, rc, pair, renderText);
|
||||
} else if (t == 2) {
|
||||
drawPolyline(mObj, req, cv, paint, rc, pair, mObj->getSimpleLayer(), drawOnlyShadow);
|
||||
} else if (t == 3 && !drawOnlyShadow) {
|
||||
// polygon
|
||||
drawPolygon(mObj, req, cv, paint, rc, pair);
|
||||
void drawObject(RenderingContext* rc, SkCanvas* cv, RenderingRuleSearchRequest* req,
|
||||
SkPaint* paint, vector<MapDataObjectPrimitive>& array, int objOrder) {
|
||||
|
||||
double limit = 100;
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
rc->allObjects++;
|
||||
MapDataObject* mObj = array[i].obj;
|
||||
tag_value pair = mObj->types.at(array[i].typeInd);
|
||||
if (objOrder == 0) {
|
||||
if (array[i].order < limit) {
|
||||
return;
|
||||
}
|
||||
// polygon
|
||||
drawPolygon(mObj, req, cv, paint, rc, pair);
|
||||
} else if (objOrder == 1) {
|
||||
drawPolyline(mObj, req, cv, paint, rc, pair, mObj->getSimpleLayer(), true);
|
||||
} else if (objOrder == 2) {
|
||||
drawPolyline(mObj, req, cv, paint, rc, pair, mObj->getSimpleLayer(), false);
|
||||
} else if (objOrder == 3) {
|
||||
drawPoint(mObj, req, cv, paint, rc, pair, array[i].typeInd == 0);
|
||||
}
|
||||
if (i % 25 == 0 && rc->interrupted()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -635,12 +660,30 @@ void drawIconsOverCanvas(RenderingContext* rc, SkCanvas* canvas)
|
|||
}
|
||||
}
|
||||
|
||||
UNORDERED(map)<int, std::vector<int> > sortObjectsByProperOrder(std::vector <MapDataObject* > mapDataObjects,
|
||||
RenderingRuleSearchRequest* req, RenderingContext* rc) {
|
||||
UNORDERED(map)<int, std::vector<int> > orderMap;
|
||||
double polygonArea(MapDataObject* obj, float mult) {
|
||||
double area = 0.;
|
||||
int j = obj->points.size() - 1;
|
||||
for (int i = 0; i < obj->points.size(); i++) {
|
||||
int_pair x = obj->points[i] ;
|
||||
int_pair y = obj->points[j];
|
||||
area += (y.first + ((float) x.first) )* (y.second- ((float)x.second));
|
||||
j = i;
|
||||
}
|
||||
return std::abs(area) * mult * mult * .5;
|
||||
}
|
||||
|
||||
|
||||
bool sortByOrder(const MapDataObjectPrimitive& i,const MapDataObjectPrimitive& j) { return (i.order<j.order); }
|
||||
bool sortByRevOrder(const MapDataObjectPrimitive& i,const MapDataObjectPrimitive& j) { return (i.order>j.order); }
|
||||
|
||||
void sortObjectsByProperOrder(std::vector <MapDataObject* > mapDataObjects,
|
||||
RenderingRuleSearchRequest* req, RenderingContext* rc,
|
||||
std::vector<MapDataObjectPrimitive>& polygonsArray, std::vector<MapDataObjectPrimitive>& pointsArray,
|
||||
std::vector<MapDataObjectPrimitive>& linesArray) {
|
||||
if (req != NULL) {
|
||||
req->clearState();
|
||||
const int size = mapDataObjects.size();
|
||||
float mult = 1. / getPowZoom(max(31 - (rc->getZoom() + 8), 0));
|
||||
int i = 0;
|
||||
for (; i < size; i++) {
|
||||
uint32_t sh = i << 8;
|
||||
|
@ -657,11 +700,22 @@ UNORDERED(map)<int, std::vector<int> > sortObjectsByProperOrder(std::vector <Map
|
|||
if (req->searchRule(RenderingRulesStorage::ORDER_RULES)) {
|
||||
int objectType = req->getIntPropertyValue(req->props()->R_OBJECT_TYPE);
|
||||
int order = req->getIntPropertyValue(req->props()->R_ORDER);
|
||||
orderMap[(order << 2)|objectType].push_back(sh + j);
|
||||
MapDataObjectPrimitive mapObj;
|
||||
mapObj.objectType = objectType;
|
||||
mapObj.order = order;
|
||||
mapObj.typeInd = j;
|
||||
mapObj.obj = mobj;
|
||||
// polygon
|
||||
if(objectType == 3) {
|
||||
// add icon point all the time
|
||||
orderMap[(128 << 2)|1].push_back(sh + j);
|
||||
MapDataObjectPrimitive pointObj = mapObj;
|
||||
pointObj.objectType = 1;
|
||||
mapObj.order = polygonArea(mobj, mult);
|
||||
polygonsArray.push_back(mapObj);
|
||||
pointsArray.push_back(pointObj);
|
||||
} else if(objectType == 1) {
|
||||
pointsArray.push_back(mapObj);
|
||||
} else {
|
||||
linesArray.push_back(mapObj);
|
||||
}
|
||||
if (req->getIntPropertyValue(req->props()->R_SHADOW_LEVEL) > 0) {
|
||||
rc->shadowLevelMin = std::min(rc->shadowLevelMin, order);
|
||||
|
@ -672,8 +726,10 @@ UNORDERED(map)<int, std::vector<int> > sortObjectsByProperOrder(std::vector <Map
|
|||
|
||||
}
|
||||
}
|
||||
sort(polygonsArray.begin(), polygonsArray.end(), sortByRevOrder);
|
||||
sort(pointsArray.begin(), pointsArray.end(), sortByOrder);
|
||||
sort(linesArray.begin(), linesArray.end(), sortByOrder);
|
||||
}
|
||||
return orderMap;
|
||||
}
|
||||
|
||||
void doRendering(std::vector <MapDataObject* > mapDataObjects, SkCanvas* canvas,
|
||||
|
@ -683,53 +739,23 @@ void doRendering(std::vector <MapDataObject* > mapDataObjects, SkCanvas* canvas,
|
|||
SkPaint* paint = new SkPaint;
|
||||
paint->setAntiAlias(true);
|
||||
|
||||
// put in order map
|
||||
UNORDERED(map)<int, std::vector<int> > orderMap = sortObjectsByProperOrder(mapDataObjects, req, rc);
|
||||
std::set<int> keys;
|
||||
UNORDERED(map)<int, std::vector<int> >::iterator it = orderMap.begin();
|
||||
std::vector<MapDataObjectPrimitive> polygonsArray;
|
||||
std::vector<MapDataObjectPrimitive> pointsArray;
|
||||
std::vector<MapDataObjectPrimitive> linesArray;
|
||||
sortObjectsByProperOrder(mapDataObjects, req, rc, polygonsArray, pointsArray, linesArray);
|
||||
rc->lastRenderedKey = 0;
|
||||
|
||||
while (it != orderMap.end()) {
|
||||
keys.insert(it->first);
|
||||
it++;
|
||||
drawObject(rc, canvas, req, paint, polygonsArray, 0);
|
||||
rc->lastRenderedKey = 5;
|
||||
if (rc->getShadowRenderingMode() > 1) {
|
||||
drawObject(rc, canvas, req, paint, linesArray, 1);
|
||||
}
|
||||
bool shadowDrawn = false;
|
||||
for (std::set<int>::iterator ks = keys.begin(); ks != keys.end(); ks++) {
|
||||
if (!shadowDrawn && ((*ks)>>2) >= rc->shadowLevelMin && ((*ks)>>2) <= rc->shadowLevelMax && rc->getShadowRenderingMode() > 1) {
|
||||
for (std::set<int>::iterator ki = ks; ki != keys.end(); ki++) {
|
||||
if (((*ki)>>2) > rc->shadowLevelMax || rc->interrupted()) {
|
||||
break;
|
||||
}
|
||||
std::vector<int> list = orderMap[*ki];
|
||||
for (std::vector<int>::iterator ls = list.begin(); ls != list.end(); ls++) {
|
||||
int i = *ls;
|
||||
int ind = i >> 8;
|
||||
int l = i & 0xff;
|
||||
MapDataObject* mapObject = mapDataObjects.at(ind);
|
||||
rc->lastRenderedKey = 40;
|
||||
drawObject(rc, canvas, req, paint, linesArray, 2);
|
||||
rc->lastRenderedKey = 60;
|
||||
|
||||
// show text only for main type
|
||||
|
||||
drawObject(rc, mapObject, canvas, req, paint, l, l == 0, true, (*ki)&3);
|
||||
}
|
||||
}
|
||||
shadowDrawn = true;
|
||||
}
|
||||
|
||||
std::vector<int> list = orderMap[*ks];
|
||||
for (std::vector<int>::iterator ls = list.begin(); ls != list.end(); ls++) {
|
||||
int i = *ls;
|
||||
int ind = i >> 8;
|
||||
int l = i & 0xff;
|
||||
|
||||
MapDataObject* mapObject = mapDataObjects.at(ind);
|
||||
// show text only for main type
|
||||
drawObject(rc, mapObject, canvas, req, paint, l, l == 0, false, (*ks)&3);
|
||||
}
|
||||
rc->lastRenderedKey = (*ks) >>2;
|
||||
if (rc->interrupted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
drawObject(rc, canvas, req, paint, pointsArray, 3);
|
||||
rc->lastRenderedKey = 125;
|
||||
|
||||
drawIconsOverCanvas(rc, canvas);
|
||||
|
||||
|
|
|
@ -9,4 +9,6 @@
|
|||
|
||||
void doRendering(std::vector <MapDataObject* > mapDataObjects, SkCanvas* canvas,
|
||||
RenderingRuleSearchRequest* req, RenderingContext* rc);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue