Fix C compilation problems

This commit is contained in:
Victor Shcherb 2012-04-17 23:56:41 +02:00
parent b02400b186
commit ad350f003f
12 changed files with 3474 additions and 2494 deletions

View file

@ -6,5 +6,14 @@
<arg value="--java_out=./src/" />
</exec>
</target>
<target name="cpp">
<exec dir="." executable="/usr/bin/protoc">
<arg value="src/osmand_odb.proto" />
<arg value="--cpp_out=../OsmAnd/jni/osmand/proto/" />
</exec>
</target>
</project>

View file

@ -9,20 +9,16 @@ public class ToDoConstants {
// Index
// Map QuadTree (skip small areas!!!)
// Routing index !!
// TODO native support!
// TODO Delete/Extract the code with multipolygons ! (coastline))
// Render : support additional tags in render.xml
// ------ TO try & to test ----
// Test rendering of 2 dimensional values
// Polish UI with new building address search ...(Better completely new address search)
// Search for city in all indexes
// Test GeoIndexActivity
// TODO images in the map index ?

View file

@ -780,14 +780,6 @@ public class BinaryMapIndexReader {
case MapDataBlock.BASEID_FIELD_NUMBER:
baseId = codedIS.readUInt64();
break;
// case MapDataBlock.RASTERTYPE_FIELD_NUMBER:
// // not used now
// codedIS.readUInt32();
// break;
// case MapDataBlock.RASTERIMAGE_FIELD_NUMBER:
// // not used now
// codedIS.readBytes();
// break;
case MapDataBlock.DATAOBJECTS_FIELD_NUMBER:
int length = codedIS.readRawVarint32();
int oldLimit = codedIS.pushLimit(length);

View file

@ -5,8 +5,10 @@
#include <android/log.h>
#include <stdio.h>
#include <fstream>
#include <algorithm>
#include <map>
#include <hash_map>
#include <hash_set>
#include "google/protobuf/io/zero_copy_stream_impl.h"
#include "google/protobuf/wire_format_lite.h"
#include "google/protobuf/wire_format_lite.cc"
@ -14,13 +16,15 @@
#include "renderRules.h"
#include "common.h"
#include "mapObjects.h"
#include "multipolygons.h"
//#include "multipolygons.h"
#include "proto/osmand_odb.pb.h"
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
using namespace google::protobuf;
using namespace google::protobuf::internal;
struct BinaryMapFile;
std::map<std::string, BinaryMapFile*> openFiles;
@ -65,9 +69,9 @@ struct SearchQuery {
jobject o;
jfieldID interruptedField;
std::vector<std::pair<int, int> > cacheCoordinates;
std::vector<int> cacheTypes;
std::vector<std::pair< std::string, std::string> > cacheTagValues;
coordinates cacheCoordinates;
bool ocean;
bool land;
int numberOfVisitedObjects;
int numberOfAcceptedObjects;
@ -78,6 +82,7 @@ struct SearchQuery {
req(req), left(l), right(r), top(t), bottom(b), o(o), interruptedField(interruptedField) {
numberOfAcceptedObjects = numberOfVisitedObjects = 0;
numberOfAcceptedSubtrees = numberOfReadSubtrees = 0;
ocean = land = false;
}
bool isCancelled(){
@ -87,22 +92,22 @@ struct SearchQuery {
struct MapTreeBounds {
uint32 length;
int filePointer;
int left ;
int right ;
int top ;
int bottom;
uint32 filePointer;
uint32 mapDataBlock;
uint32 left ;
uint32 right ;
uint32 top ;
uint32 bottom;
bool ocean;
MapTreeBounds() {
ocean = -1;
}
};
struct MapRoot {
uint32 length;
int filePointer;
struct MapRoot: MapTreeBounds {
int minZoom ;
int maxZoom ;
int left ;
int right ;
int top ;
int bottom;
vector<MapTreeBounds> bounds;
};
@ -110,8 +115,65 @@ struct MapIndex {
uint32 length;
int filePointer;
std::string name;
std::hash_map<int, tag_value > decodingRules;
vector<MapRoot> levels;
std::hash_map<int, tag_value > decodingRules;
// DEFINE hash
//std::hash_map<tag_value, int> encodingRules;
int nameEncodingType;
int refEncodingType;
int coastlineEncodingType;
int coastlineBrokenEncodingType;
int landEncodingType;
int onewayAttribute ;
int onewayReverseAttribute ;
std::hash_set< int > positiveLayers;
std::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 {
@ -127,26 +189,31 @@ struct BinaryMapFile {
bool readMapTreeBounds(io::CodedInputStream* input, MapTreeBounds* tree, MapRoot* root) {
int init = 0;
int tag;
int32 si;
while ((tag = input->ReadTag()) != 0) {
switch (WireFormatLite::GetTagFieldNumber(tag)) {
case MapTree::kLeftFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &tree->left)));
tree->left += root->left;
case OsmAndMapIndex_MapDataBox::kLeftFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &si)));
tree->left = si + root->left;
break;
}
case MapTree::kRightFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &tree->right)));
tree->right += root->right;
case OsmAndMapIndex_MapDataBox::kRightFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &si)));
tree->right = si + root->right;
break;
}
case MapTree::kTopFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &tree->top)));
tree->top += root->top;
case OsmAndMapIndex_MapDataBox::kTopFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &si)));
tree->top = si + root->top;
break;
}
case MapTree::kBottomFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &tree->bottom)));
tree->bottom += root->bottom;
case OsmAndMapIndex_MapDataBox::kBottomFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &si)));
tree->bottom = si + root->bottom;
break;
}
case OsmAndMapIndex_MapDataBox::kOceanFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(input, &tree->ocean)));
break;
}
default: {
@ -168,41 +235,52 @@ bool readMapTreeBounds(io::CodedInputStream* input, MapTreeBounds* tree, MapRoot
bool readMapLevel(io::CodedInputStream* input, MapRoot* root) {
int tag;
int si;
while ((tag = input->ReadTag()) != 0) {
switch (WireFormatLite::GetTagFieldNumber(tag)) {
case MapRootLevel::kMaxZoomFieldNumber: {
case OsmAndMapIndex_MapRootLevel::kMaxZoomFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &root->maxZoom)));
break;
}
case MapRootLevel::kMinZoomFieldNumber: {
case OsmAndMapIndex_MapRootLevel::kMinZoomFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &root->minZoom)));
break;
}
case MapRootLevel::kBottomFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &root->bottom)));
case OsmAndMapIndex_MapRootLevel::kBottomFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &si)));
root->bottom = si;
break;
}
case MapRootLevel::kTopFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &root->top)));
case OsmAndMapIndex_MapRootLevel::kTopFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &si)));
root->top = si;
break;
}
case MapRootLevel::kLeftFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &root->left)));
case OsmAndMapIndex_MapRootLevel::kLeftFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &si)));
root->left = si;
break;
}
case MapRootLevel::kRightFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &root->right)));
case OsmAndMapIndex_MapRootLevel::kRightFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &si)));
root->right = si;
break;
}
case MapRootLevel::kRootFieldNumber: {
MapTreeBounds mapBounds;
readInt(input, &mapBounds.length);
mapBounds.filePointer = input->getTotalBytesRead();
int oldLimit = input->PushLimit(mapBounds.length);
readMapTreeBounds(input, &mapBounds, root);
case OsmAndMapIndex_MapRootLevel::kBoxesFieldNumber: {
uint32 length;
readInt(input, &length);
int filePointer = input->getTotalBytesRead();
int oldLimit = input->PushLimit(length);
MapTreeBounds bounds;
readMapTreeBounds(input, &bounds, root);
root->bounds.push_back(bounds);
input->Skip(input->BytesUntilLimit());
input->PopLimit(oldLimit);
root->bounds.push_back(mapBounds);
break;
}
case OsmAndMapIndex_MapRootLevel::kBlocksFieldNumber: {
input->Skip(input->BytesUntilLimit());
break;
}
@ -220,28 +298,27 @@ bool readMapLevel(io::CodedInputStream* input, MapRoot* root) {
return true;
}
bool readMapEncodingRule(io::CodedInputStream* input, MapIndex* index) {
bool readMapEncodingRule(io::CodedInputStream* input, MapIndex* index, uint32 id) {
int tag;
std::string tagS;
std::string value;
uint32 type = 0;
uint32 subtype = 0;
while ((tag = input->ReadTag()) != 0) {
switch (WireFormatLite::GetTagFieldNumber(tag)) {
case MapEncodingRule::kValueFieldNumber: {
case OsmAndMapIndex_MapEncodingRule::kValueFieldNumber: {
DO_((WireFormatLite::ReadString(input, &value)));
break;
}
case MapEncodingRule::kTagFieldNumber: {
case OsmAndMapIndex_MapEncodingRule::kTagFieldNumber: {
DO_((WireFormatLite::ReadString(input, &tagS)));
break;
}
case MapEncodingRule::kTypeFieldNumber: {
case OsmAndMapIndex_MapEncodingRule::kTypeFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(input, &type)));
break;
}
case MapEncodingRule::kSubtypeFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(input, &subtype)));
case OsmAndMapIndex_MapEncodingRule::kIdFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(input, &id)));
break;
}
default: {
@ -255,16 +332,14 @@ bool readMapEncodingRule(io::CodedInputStream* input, MapIndex* index) {
}
}
}
int ind = ((subtype << 5) | type);
// Special case for check to not replace primary with primary_link
if(index->decodingRules.find(ind) == index->decodingRules.end()) {
index->decodingRules[ind] = std::pair < std::string, std::string > (tagS, value);
}
index->initMapEncodingRule(type, id, tagS, value);
return true;
}
bool readMapIndex(io::CodedInputStream* input, MapIndex* mapIndex) {
uint32 tag;
uint32 defaultId = 1;
while ((tag = input->ReadTag()) != 0) {
switch (WireFormatLite::GetTagFieldNumber(tag)) {
case OsmAndMapIndex::kNameFieldNumber: {
@ -275,7 +350,7 @@ bool readMapIndex(io::CodedInputStream* input, MapIndex* mapIndex) {
int len;
WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &len);
int oldLimit = input->PushLimit(len);
readMapEncodingRule(input, mapIndex);
readMapEncodingRule(input, mapIndex, defaultId++);
input->PopLimit(oldLimit);
break;
}
@ -301,6 +376,7 @@ bool readMapIndex(io::CodedInputStream* input, MapIndex* mapIndex) {
}
}
}
mapIndex->finishInitializingTags();
return true;
}
@ -348,6 +424,10 @@ bool initMapStructure(io::CodedInputStream* input, BinaryMapFile* file) {
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Corrupted file. It should be ended as it starts with version");
return false;
}
if (version != 2) {
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Version of the file is not supported.");
return false;
}
return true;
}
@ -392,21 +472,43 @@ bool readStringTable(io::CodedInputStream* input, std::vector<std::string>& list
static const int SHIFT_COORDINATES = 5;
static const int MASK_TO_READ = ~((1 << SHIFT_COORDINATES) - 1);
static const int MASK_10 = (1 << 10) - 1;
MapDataObject* readMapDataObject(io::CodedInputStream* input, int left, int right, int top, int bottom, SearchQuery* req,
bool acceptTypes(SearchQuery* req, std::vector<tag_value>& types, MapIndex* root) {
RenderingRuleSearchRequest* r = req->req;
bool accept = true;
for (std::vector<tag_value>::iterator type = types.begin(); type != types.end(); type++) {
for (int i = 1; i <= 3; i++) {
r->setIntFilter(r->props()->R_MINZOOM, req->zoom);
r->setStringFilter(r->props()->R_TAG, type->first);
r->setStringFilter(r->props()->R_VALUE, type->second);
if (r->search(i, false)) {
return true;
}
}
r->setStringFilter(r->props()->R_TAG, type->first);
r->setStringFilter(r->props()->R_VALUE, type->second);
if (r->search(RenderingRulesStorage::TEXT_RULES, false)) {
return true;
}
}
return false;
}
MapDataObject* readMapDataObject(io::CodedInputStream* input, MapTreeBounds* tree, SearchQuery* req,
MapIndex* root) {
uint32 tag = input->ReadTag();
if (MapData::kCoordinatesFieldNumber != WireFormatLite::GetTagFieldNumber(tag)) {
bool area = MapData::kAreaCoordinatesFieldNumber == tag;
if(!area && MapData::kCoordinatesFieldNumber != tag) {
return NULL;
}
req->cacheCoordinates.clear();
uint32 size;
input->ReadVarint32(&size);
int old = input->PushLimit(size);
int px = left & MASK_TO_READ;
int py = top & MASK_TO_READ;
int px = tree->left & MASK_TO_READ;
int py = tree->top & MASK_TO_READ;
bool contains = false;
long long id = 0;
int minX = INT_MAX;
int maxX = 0;
int minY = INT_MAX;
@ -447,104 +549,118 @@ MapDataObject* readMapDataObject(io::CodedInputStream* input, int left, int righ
}
// READ types
tag = input->ReadTag();
if (MapData::kTypesFieldNumber != WireFormatLite::GetTagFieldNumber(tag)) {
std::vector< coordinates > innercoordinates;
std::vector< tag_value > additionalTypes;
std::vector< tag_value > types;
std::hash_map< std::string, unsigned int> stringIds;
bool loop = true;
while (loop) {
uint32 t = input->ReadTag();
switch (WireFormatLite::GetTagFieldNumber(t)) {
case 0:
loop = false;
break;
case MapData::kPolygonInnerCoordinatesFieldNumber: {
coordinates polygon;
px = tree->left & MASK_TO_READ;
py = tree->top & MASK_TO_READ;
input->ReadVarint32(&size);
old = input->PushLimit(size);
while (input->BytesUntilLimit() > 0) {
WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &x);
WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &y);
x = (x << SHIFT_COORDINATES) + px;
y = (y << SHIFT_COORDINATES) + py;
polygon.push_back(std::pair<int, int>(x, y));
px = x;
py = y;
}
input->PopLimit(old);
innercoordinates.push_back(polygon);
break;
}
case MapData::kAdditionalTypesFieldNumber: {
input->ReadVarint32(&size);
old = input->PushLimit(size);
while (input->BytesUntilLimit() > 0) {
WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &x);
if (root->decodingRules.find(x) != root->decodingRules.end()) {
tag_value t = root->decodingRules[x];
additionalTypes.push_back(t);
}
}
input->PopLimit(old);
break;
}
case MapData::kTypesFieldNumber: {
input->ReadVarint32(&size);
old = input->PushLimit(size);
while (input->BytesUntilLimit() > 0) {
WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &x);
if (root->decodingRules.find(x) != root->decodingRules.end()) {
tag_value t = root->decodingRules[x];
types.push_back(t);
}
}
input->PopLimit(old);
bool acceptTps = acceptTypes(req, types, root);
if (!acceptTps) {
return NULL;
}
req->cacheTypes.clear();
req->cacheTagValues.clear();
uint32 sizeL;
input->ReadVarint32(&sizeL);
unsigned char* buff = new unsigned char[sizeL];
if (!input->ReadRaw(buff, sizeL)) {
return NULL;
break;
}
case MapData::kIdFieldNumber:
WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(input, &id);
break;
case MapData::kStringNamesFieldNumber:
input->ReadVarint32(&size);
old = input->PushLimit(size);
while (input->BytesUntilLimit() > 0) {
WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &x);
WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &y);
if (root->decodingRules.find(x) != root->decodingRules.end()) {
tag_value t = root->decodingRules[x];
stringIds[t.first] = y;
}
}
input->PopLimit(old);
break;
default: {
if (WireFormatLite::GetTagWireType(t) == WireFormatLite::WIRETYPE_END_GROUP) {
return false;
}
if (!skipUnknownFields(input, t)) {
return false;
}
break;
}
}
}
bool accept = false;
RenderingRuleSearchRequest* r = req->req;
for (uint32 i = 0; i < sizeL / 2; i++) {
int s = (((int) buff[i * 2 + 1]) << 8) | buff[i * 2];
int mask = s & 3;
int type = s >> 2;
if (mask != RenderingRulesStorage::POINT_RULES) {
type = type & MASK_10;
}
tag_value pair = root->decodingRules[type];
if (r != NULL && !accept) {
if(mask == RenderingRulesStorage::MULTI_POLYGON_TYPE){
mask = RenderingRulesStorage::POLYGON_RULES;
}
r->setIntFilter(r->props()->R_MINZOOM, req->zoom);
r->setStringFilter(r->props()->R_TAG, pair.first);
r->setStringFilter(r->props()->R_VALUE, pair.second);
accept |= r->search(mask, false);
if (mask == RenderingRulesStorage::POINT_RULES && !accept) {
r->setStringFilter(r->props()->R_TAG, pair.first);
r->setStringFilter(r->props()->R_VALUE, pair.second);
accept |= r->search(RenderingRulesStorage::TEXT_RULES, false);
}
} else {
accept = true;
}
req->cacheTagValues.push_back(pair);
req->cacheTypes.push_back(s);
}
delete buff;
if (!accept) {
return NULL;
}
req->numberOfAcceptedObjects++;
MapDataObject* dataObject = new MapDataObject();
dataObject->points = req->cacheCoordinates;
dataObject->types = req->cacheTypes;
dataObject->tagValues = req->cacheTagValues;
dataObject->additionalTypes = additionalTypes;
dataObject->types = types;
dataObject->id = id;
dataObject->stringIds = stringIds;
dataObject->polygonInnerCoordinates = innercoordinates;
while ((tag = input->ReadTag()) != 0) {
switch (WireFormatLite::GetTagFieldNumber(tag)) {
//case MapData::kRestrictionsFieldNumber : {
//sizeL = codedIS.readRawVarint32();
//TLongArrayList list = new TLongArrayList();
//old = codedIS.pushLimit(sizeL);
//while(codedIS.getBytesUntilLimit() > 0){
//list.add(codedIS.readSInt64());
//}
//codedIS.popLimit(old);
//dataObject.restrictions = list.toArray();
//break; }
case MapData::kHighwayMetaFieldNumber:
WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_INT32>(input, &dataObject->highwayAttributes);
break;
case MapData::kIdFieldNumber:
WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(input, &dataObject->id);
break;
case MapData::kStringIdFieldNumber:
WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(input, &dataObject->stringId);
break;
default: {
if (WireFormatLite::GetTagWireType(tag) == WireFormatLite::WIRETYPE_END_GROUP) {
return false;
}
if (!skipUnknownFields(input, tag)) {
return false;
}
break;
}
}
}
return dataObject;
}
bool searchMapTreeBounds(io::CodedInputStream* input, int pleft, int pright, int ptop, int pbottom, SearchQuery* req, MapIndex* root) {
bool searchMapTreeBounds(io::CodedInputStream* input, MapTreeBounds* current, MapTreeBounds* parent,
SearchQuery* req, std::vector<MapTreeBounds>* foundSubtrees) {
int init = 0;
int lastIndexResult = -1;
int cright = 0;
int cleft = 0;
int ctop = 0;
int cbottom = 0;
int tag;
int si;
req->numberOfReadSubtrees++;
while ((tag = input->ReadTag()) != 0) {
if (req->isCancelled()) {
@ -553,7 +669,7 @@ bool searchMapTreeBounds(io::CodedInputStream* input, int pleft, int pright, int
if (init == 0xf) {
init = 0;
// coordinates are init
if (cright < req->left || cleft > req->right || ctop > req->bottom || cbottom < req->top) {
if (current->right < req->left || current->left > req->right || current->top > req->bottom || current->bottom < req->top) {
return false;
} else {
req->numberOfAcceptedSubtrees++;
@ -561,96 +677,59 @@ bool searchMapTreeBounds(io::CodedInputStream* input, int pleft, int pright, int
}
switch (WireFormatLite::GetTagFieldNumber(tag)) {
// required uint32 version = 1;
case MapTree::kLeftFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &cleft)));
cleft += pleft;
case OsmAndMapIndex_MapDataBox::kLeftFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &si)));
current->left = si + parent->left;
init |= 1;
break;
}
case MapTree::kRightFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &cright)));
cright += pright;
case OsmAndMapIndex_MapDataBox::kRightFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &si)));
current->right = si + parent->right;
init |= 2;
break;
}
case MapTree::kTopFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &ctop)));
ctop += ptop;
case OsmAndMapIndex_MapDataBox::kTopFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &si)));
current->top = si + parent->top;
init |= 4;
break;
}
case MapTree::kBottomFieldNumber: {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &cbottom)));
cbottom += pbottom;
case OsmAndMapIndex_MapDataBox::kBottomFieldNumber : {
DO_((WireFormatLite::ReadPrimitive<int32, WireFormatLite::TYPE_SINT32>(input, &si)));
current->bottom = si + parent->bottom;
init |= 8;
break;
}
case MapTree::kLeafsFieldNumber: {
uint32 length;
input->ReadVarint32(&length);
int oldLimit = input->PushLimit(length);
if (lastIndexResult == -1) {
lastIndexResult = req->result.size();
case OsmAndMapIndex_MapDataBox::kShiftToMapDataFieldNumber : {
readInt(input, &current->mapDataBlock);
current->mapDataBlock += current->filePointer;
foundSubtrees->push_back(*current);
break;
}
MapDataObject* mapObject = readMapDataObject(input, cleft, cright, ctop, cbottom, req, root);
if (mapObject != NULL) {
req->result.push_back(mapObject);
case OsmAndMapIndex_MapDataBox::kOceanFieldNumber : {
DO_((WireFormatLite::ReadPrimitive<bool, WireFormatLite::TYPE_BOOL>(input, &current->ocean)));
if(current->ocean){
req->ocean = true;
} else {
req->land = true;
}
input->Skip(input->BytesUntilLimit());
break;
}
case OsmAndMapIndex_MapDataBox::kBoxesFieldNumber: {
MapTreeBounds* child = new MapTreeBounds();
readInt(input, &child->length);
child->filePointer = input->getTotalBytesRead();
int oldLimit = input->PushLimit(child->length);
if (current->ocean != -1) {
child->ocean = current->ocean;
}
searchMapTreeBounds(input, child, current, req, foundSubtrees);
delete child;
input->PopLimit(oldLimit);
input->Seek(child->filePointer + child->length);
break;
}
case MapTree::kSubtreesFieldNumber: {
uint32 length;
readInt(input, &length);
// int filePointer = input->getTotalBytesRead();
int oldLimit = input->PushLimit(length);
searchMapTreeBounds(input, cleft, cright, ctop, cbottom, req, root);
input->Skip(input->BytesUntilLimit());
input->PopLimit(oldLimit);
// input->Seek(filePointer + length);
if (lastIndexResult >= 0) {
return false;
}
break;
}
case MapTree::kOldbaseIdFieldNumber:
case MapTree::kBaseIdFieldNumber: {
uint64 baseId;
input->ReadVarint64(&baseId);
if (lastIndexResult != -1) {
for (uint32 i = lastIndexResult; i < req->result.size(); i++) {
BaseMapDataObject* rs = req->result.at(i);
rs->id += baseId;
// restrictions are not supported
// if (rs.restrictions != null) {
// for (int j = 0; j < rs.restrictions.length; j++) {
// rs.restrictions[j] += baseId;
// }
// }
}
}
break;
}
case MapTree::kStringTableFieldNumber:
case MapTree::kOldstringTableFieldNumber: {
uint32 length;
input->ReadVarint32(&length);
int oldLimit = input->PushLimit(length);
std::vector<std::string> stringTable;
readStringTable(input, stringTable);
input->PopLimit(oldLimit);
if (lastIndexResult != -1) {
for (uint32 i = lastIndexResult; i < req->result.size(); i++) {
BaseMapDataObject* rs = req->result.at(i);
if (rs->stringId != BaseMapDataObject::UNDEFINED_STRING) {
rs->name = stringTable.at(rs->stringId);
}
}
}
break;
}
default: {
if (WireFormatLite::GetTagWireType(tag) == WireFormatLite::WIRETYPE_END_GROUP) {
return true;
@ -665,6 +744,72 @@ bool searchMapTreeBounds(io::CodedInputStream* input, int pleft, int pright, int
return true;
}
bool readMapDataBlocks(io::CodedInputStream* input, SearchQuery* req, MapTreeBounds* tree, MapIndex* root) {
long long baseId = 0;
int tag;
std::vector< MapDataObject* > results;
while ((tag = input->ReadTag()) != 0) {
if (req->isCancelled()) {
return false;
}
switch (WireFormatLite::GetTagFieldNumber(tag)) {
// required uint32 version = 1;
case MapDataBlock::kBaseIdFieldNumber : {
WireFormatLite::ReadPrimitive<int64, WireFormatLite::TYPE_SINT64>(input, &baseId);
break;
}
case MapDataBlock::kStringTableFieldNumber: {
uint32 length;
DO_((WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(input, &length)));
int oldLimit = input->PushLimit(length);
if(results.size() > 0) {
std::vector<std::string> stringTable;
readStringTable(input, stringTable);
MapDataObject* o;
for (std::vector<MapDataObject*>::iterator obj = results.begin(); obj != results.end(); obj++) {
if ((*obj)->stringIds.size() > 0) {
std::hash_map<std::string, unsigned int >::iterator val=(*obj)->stringIds.begin();
while(val != (*obj)->stringIds.end()){
(*obj)->objectNames[val->first]=stringTable.at(val->second);
val++;
}
}
}
}
input->Skip(input->BytesUntilLimit());
input->PopLimit(oldLimit);
break;
}
case MapDataBlock::kDataObjectsFieldNumber: {
uint32 length;
DO_((WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(input, &length)));
int oldLimit = input->PushLimit(length);
MapDataObject* mapObject = readMapDataObject(input, tree, req, root);
if (mapObject != NULL) {
mapObject->id += baseId;
results.push_back(mapObject);
req->result.push_back(mapObject);
}
input->Skip(input->BytesUntilLimit());
input->PopLimit(oldLimit);
break;
}
default: {
if (WireFormatLite::GetTagWireType(tag) == WireFormatLite::WIRETYPE_END_GROUP) {
return true;
}
if (!skipUnknownFields(input, tag)) {
return false;
}
break;
}
}
}
return true;
}
bool sortTreeBounds (const MapTreeBounds& i,const MapTreeBounds& j) { return (i.mapDataBlock<j.mapDataBlock); }
void searchMapData(io::CodedInputStream* input, MapRoot* root, MapIndex* ind, SearchQuery* req) {
// search
@ -676,10 +821,25 @@ void searchMapData(io::CodedInputStream* input, MapRoot* root, MapIndex* ind, Se
if (i->right < req->left || i->left > req->right || i->top > req->bottom || i->bottom < req->top) {
continue;
}
vector<MapTreeBounds> foundSubtrees;
input->Seek(i->filePointer);
int oldLimit = input->PushLimit(i->length);
searchMapTreeBounds(input, root->left, root->right, root->top, root->bottom, req, ind);
searchMapTreeBounds(input, i, root, req, &foundSubtrees);
input->PopLimit(oldLimit);
sort(foundSubtrees.begin(), foundSubtrees.end(), sortTreeBounds);
uint32 length;
for (std::vector<MapTreeBounds>::iterator tree = foundSubtrees.begin();
tree != foundSubtrees.end(); tree++) {
if (req->isCancelled()) {
return;
}
input->Seek(tree->mapDataBlock);
WireFormatLite::ReadPrimitive<uint32, WireFormatLite::TYPE_UINT32>(input, &tree->mapDataBlock);
int oldLimit = input->PushLimit(length);
readMapDataBlocks(input, req, tree, ind);
input->PopLimit(oldLimit);
}
}
}
@ -704,6 +864,7 @@ extern "C" JNIEXPORT jint JNICALL Java_net_osmand_plus_render_NativeOsmandLibrar
jfieldID interruptedField = getFid(clObjInterrupted, "interrupted", "Z");
getGlobalJniEnv()->DeleteLocalRef(clObjInterrupted);
SearchQuery q(sleft,sright, stop, sbottom, req, objInterrupted, interruptedField);
q.zoom = zoom;
fseek(file->f, 0, 0);
io::FileInputStream input(fileno(file->f));
@ -713,7 +874,7 @@ extern "C" JNIEXPORT jint JNICALL Java_net_osmand_plus_render_NativeOsmandLibrar
if(req != NULL){
req->clearState();
}
q.zoom = zoom;
for(vector<MapIndex>::iterator mapIndex = file->mapIndexes.begin();
mapIndex != file->mapIndexes.end(); mapIndex++) {
for (vector<MapRoot>::iterator mapLevel = mapIndex->levels.begin(); mapLevel != mapIndex->levels.end();
@ -730,19 +891,20 @@ extern "C" JNIEXPORT jint JNICALL Java_net_osmand_plus_render_NativeOsmandLibrar
}
}
result->result.insert(result->result.end(), q.result.begin(), q.result.end());
std::map<tagValueType, std::vector<MapDataObject*> > multyPolygons;
std::vector<MapDataObject*>::iterator mdo = q.result.begin();
for(;mdo!= q.result.end(); mdo++) {
for(size_t j = 0; j<(*mdo)->types.size(); j++) {
int type = (*mdo)->types.at(j);
if((type & 0x3) == RenderingRulesStorage::MULTI_POLYGON_TYPE) {
tagValueType tagValue((*mdo)->tagValues.at(j), type);
multyPolygons[tagValue].push_back(*mdo);
}
}
}
proccessMultiPolygons(multyPolygons, q.left, q.right, q.bottom, q.top, q.zoom, result->result);
// FIXME process multi polygons
// std::map<tagValueType, std::vector<MapDataObject*> > multyPolygons;
// std::vector<MapDataObject*>::iterator mdo = q.result.begin();
// for(;mdo!= q.result.end(); mdo++) {
// for(size_t j = 0; j<(*mdo)->types.size(); j++) {
// int type = (*mdo)->types.at(j);
// if((type & 0x3) == RenderingRulesStorage::MULTI_POLYGON_TYPE) {
// tagValueType tagValue((*mdo)->tagValues.at(j), type);
// multyPolygons[tagValue].push_back(*mdo);
// }
// }
// }
//
// proccessMultiPolygons(multyPolygons, q.left, q.right, q.bottom, q.top, q.zoom, result->result);
if(q.result.size() > 0) {
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Search : tree - read( %d), accept( %d), objs - visit( %d), accept(%d), in result(%d) ", q.numberOfReadSubtrees,
q.numberOfAcceptedSubtrees, q.numberOfVisitedObjects, q.numberOfAcceptedObjects, result->result.size());

View file

@ -1,4 +1,4 @@
#ifndef _OSMAND_MAP_OBJECTS
#ifndef _OSMAND_MAP_OBJECTSTagValuePairClass
#define _OSMAND_MAP_OBJECTS
#include <jni.h>
@ -9,11 +9,7 @@
jclass TagValuePairClass;
jfieldID TagValuePair_tag;
jfieldID TagValuePair_value;
void deleteObjects(std::vector <BaseMapDataObject* > & v)
void deleteObjects(std::vector <MapDataObject* > & v)
{
for(size_t i = 0; i< v.size(); i++)
{
@ -26,26 +22,11 @@ void deleteObjects(std::vector <BaseMapDataObject* > & v)
void loadJniMapObjects()
{
TagValuePairClass = findClass("net/osmand/binary/BinaryMapIndexReader$TagValuePair");
TagValuePair_tag = getGlobalJniEnv()->GetFieldID(TagValuePairClass, "tag", "Ljava/lang/String;");
TagValuePair_value = getGlobalJniEnv()->GetFieldID(TagValuePairClass, "value", "Ljava/lang/String;");
}
void unloadJniMapObjects()
{
getGlobalJniEnv()->DeleteGlobalRef( TagValuePairClass );
}
int getNegativeWayLayer(int type) {
int i = (3 & (type >> 12));
if (i == 1) {
return -1;
} else if (i == 2) {
return 1;
}
return 0;
}
#endif /*_OSMAND_MAP_OBJECTS*/

View file

@ -3,66 +3,81 @@
#include <jni.h>
#include <vector>
#include <hash_map>
#include <string>
#include "common.h"
typedef std::pair<std::string, std::string> tag_value;
typedef std::pair<int, int> int_pair;
typedef std::vector< std::pair<int, int> > coordinates;
class BaseMapDataObject
class MapDataObject
{
public :
static const unsigned int UNDEFINED_STRING = INT_MAX;
const int type;
static const int MAP_DATA_OBJECT = 1;
static const int MULTI_POLYGON = 2;
long long id;
unsigned int stringId;
std::string name;
protected :
BaseMapDataObject(int t) : type(t), id(0), stringId(UNDEFINED_STRING){ }
public:
std::vector<tag_value> types;
std::vector<tag_value> additionalTypes;
int objectType;
coordinates points;
std::vector < coordinates > polygonInnerCoordinates;
std::hash_map< std::string, unsigned int> stringIds;
std::hash_map< std::string, std::string > objectNames;
bool area;
long long id;
//
bool cycle(){
return points[0] == points[points.size() -1];
}
bool containsAdditional(std::string key, std::string val) {
std::vector<tag_value>::iterator it = additionalTypes.begin();
while (it != additionalTypes.end()) {
if (it->first == key) {
return it->second == val;
}
it++;
}
return false;
}
int getSimpleLayer() {
std::vector<tag_value>::iterator it = additionalTypes.begin();
while (it != additionalTypes.end()) {
if (it->first == "layer") {
if(it->second.length() > 0) {
if(it->second[0] == '-'){
return -1;
} else {
return 0;
}
} else {
return 0;
}
}
it++;
}
return 0;
}
};
struct SearchResult {
std::vector< BaseMapDataObject*> result;
};
class MultiPolygonObject : public BaseMapDataObject
{
public:
MultiPolygonObject() : BaseMapDataObject(MULTI_POLYGON) { }
std::string tag;
std::string value;
std::vector< std::string > names;
int layer;
std::vector< std::vector< int_pair> > points;
};
class MapDataObject : public BaseMapDataObject
{
public:
MapDataObject() : BaseMapDataObject(MAP_DATA_OBJECT) { }
std::vector< int> types;
std::vector< int_pair > points;
std::vector< tag_value > tagValues;
int highwayAttributes;
std::vector< MapDataObject* > result;
};
//std::vector <BaseMapDataObject* > marshalObjects(jobjectArray binaryMapDataObjects);
void deleteObjects(std::vector <BaseMapDataObject* > & v);
void deleteObjects(std::vector <MapDataObject* > & v);
void loadJniMapObjects();
void unloadJniMapObjects();
// 0 - normal, -1 - under, 1 - bridge,over
int getNegativeWayLayer(int type);
#endif /*_OSMAND_MAP_OBJECTS_H*/

View file

@ -38,7 +38,7 @@ void processMultipolygonLine(std::vector<std::vector<int_pair> >& completedRings
void unifyIncompletedRings(std::vector<std::vector<int_pair> >& incompletedRings, std::vector<std::vector<int_pair> >& completedRings, std::vector<std::string> &completedRingNames,
std::vector<std::string> &incompletedRingNames, int leftX, int rightX, int bottomY, int topY, long dbId, int zoom);
MultiPolygonObject* processMultiPolygon(int leftX, int rightX, int bottomY, int topY,
MapDataObject* processMultiPolygon(int leftX, int rightX, int bottomY, int topY,
std::vector<std::vector<int_pair > >& completedRings, std::vector<std::vector<int_pair> >& incompletedRings,
std::vector<std::string>& completedRingNames, std::vector<std::string>& incompletedRingNames,
const tagValueType& type, std::vector<MapDataObject* > & directList, std::vector<MapDataObject*>& inverselist,
@ -127,7 +127,7 @@ MultiPolygonObject* processMultiPolygon(int leftX, int rightX, int bottomY, int
static std::vector<MapDataObject*> EMPTY_LIST;
void proccessMultiPolygons(std::map<tagValueType, std::vector<MapDataObject*> >& multyPolygons, int leftX,
int rightX, int bottomY, int topY, int zoom, std::vector<BaseMapDataObject*>& listPolygons) {
int rightX, int bottomY, int topY, int zoom, std::vector<MapDataObject*>& listPolygons) {
std::vector<std::vector<int_pair> > completedRings;
std::vector<std::vector<int_pair> > incompletedRings;
std::vector<std::string> completedRingNames;
@ -158,13 +158,14 @@ void proccessMultiPolygons(std::map<tagValueType, std::vector<MapDataObject*> >&
incompletedRingNames.clear();
__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Process multipolygon %s %s direct list %d rev %d", val->first.tag.c_str(), val->first.value.c_str(), directList->size(), inverselist->size());
MultiPolygonObject* pl = processMultiPolygon(leftX, rightX, bottomY, topY, completedRings, incompletedRings,
completedRingNames, incompletedRingNames, val->first, *directList, *inverselist, zoom);
if (pl != NULL) {
listPolygons.push_back(pl);
} else {
__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Multipolygon skipped");
}
// FIXME
// MultiPolygonObject* pl = processMultiPolygon(leftX, rightX, bottomY, topY, completedRings, incompletedRings,
// completedRingNames, incompletedRingNames, val->first, *directList, *inverselist, zoom);
// if (pl != NULL) {
// listPolygons.push_back(pl);
// } else {
// __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "Multipolygon skipped");
// }
}
}

File diff suppressed because it is too large Load diff

View file

@ -424,6 +424,16 @@ bool RenderingRuleSearchRequest::visitRule(RenderingRule* rule, bool loadOutput)
match = rule->intProperties[i] <= values[rp->id];
} else if (rp == PROPS->R_MAXZOOM) {
match = rule->intProperties[i] >= values[rp->id];
} else if (rp == PROPS->R_ADDITIONAL) {
if(obj == NULL){
return true;
}
std::string val = storage->getDictionaryValue(rule->intProperties[i]);
int i = val.find('=');
if(i >= 0) {
return obj->containsAdditional(val.substr(0, i), val.substr(i+1));
}
return false;
} else {
match = rule->intProperties[i] == values[rp->id];
}
@ -462,19 +472,22 @@ bool RenderingRuleSearchRequest::visitRule(RenderingRule* rule, bool loadOutput)
}
void RenderingRuleSearchRequest::clearState() {
obj = NULL;
memcpy(values, savedValues, storage->getPropertiesSize() * sizeof(int));
memcpy(fvalues, savedFvalues, storage->getPropertiesSize() * sizeof(float));
}
void RenderingRuleSearchRequest::setInitialTagValueZoom(std::string tag, std::string value, int zoom) {
void RenderingRuleSearchRequest::setInitialTagValueZoom(std::string tag, std::string value, int zoom, MapDataObject* obj) {
clearState();
this->obj = obj;
setIntFilter(PROPS->R_MINZOOM, zoom);
setIntFilter(PROPS->R_MAXZOOM, zoom);
setStringFilter(PROPS->R_TAG, tag);
setStringFilter(PROPS->R_VALUE, value);
}
void RenderingRuleSearchRequest::setTagValueZoomLayer(std::string tag, std::string val, int zoom, int layer) {
void RenderingRuleSearchRequest::setTagValueZoomLayer(std::string tag, std::string val, int zoom, int layer, MapDataObject* obj) {
this->obj = obj;
setIntFilter(PROPS->R_MINZOOM, zoom);
setIntFilter(PROPS->R_MAXZOOM, zoom);
setIntFilter(PROPS->R_LAYER, layer);

View file

@ -3,6 +3,7 @@
#include <jni.h>
#include <string>
#include <mapObjects.h>
class RenderingRuleProperty
{
@ -128,7 +129,6 @@ public:
RenderingRuleProperty* R_ICON;
RenderingRuleProperty* R_LAYER;
RenderingRuleProperty* R_ORDER;
RenderingRuleProperty* R_ORDER_TYPE;
RenderingRuleProperty* R_TAG;
RenderingRuleProperty* R_VALUE;
RenderingRuleProperty* R_MINZOOM;
@ -140,6 +140,12 @@ public:
RenderingRuleProperty* R_TEXT_COLOR;
RenderingRuleProperty* R_TEXT_HALO_RADIUS;
RenderingRuleProperty* R_TEXT_WRAP_WIDTH;
RenderingRuleProperty* R_ADDITIONAL;
RenderingRuleProperty* R_OBJECT_TYPE;
RenderingRuleProperty* R_POINT;
RenderingRuleProperty* R_AREA;
RenderingRuleProperty* R_CYCLE;
RenderingRuleProperty* R_NAME_TAG;
RenderingRulesStorageProperties(RenderingRulesStorage* storage)
{
@ -168,7 +174,6 @@ public:
R_ICON = storage->getProperty("icon");
R_LAYER = storage->getProperty("layer");
R_ORDER = storage->getProperty("order");
R_ORDER_TYPE = storage->getProperty("orderType");
R_TAG = storage->getProperty("tag");
R_VALUE = storage->getProperty("value");
R_MINZOOM = storage->getProperty("minzoom");
@ -180,6 +185,12 @@ public:
R_TEXT_HALO_RADIUS = storage->getProperty("textHaloRadius");
R_TEXT_WRAP_WIDTH = storage->getProperty("textWrapWidth");
R_SHADOW_LEVEL = storage->getProperty("shadowLevel");
R_ADDITIONAL = storage->getProperty("additional");
R_OBJECT_TYPE = storage->getProperty("objectType");
R_POINT = storage->getProperty("point");
R_AREA = storage->getProperty("area");
R_CYCLE = storage->getProperty("cycle");
R_CYCLE = storage->getProperty("nameTag");
}
@ -197,6 +208,7 @@ private :
int* savedValues;
float* savedFvalues;
bool searchResult;
MapDataObject* obj;
bool searchInternal(int state, int tagKey, int valueKey, bool loadOutput);
void initObject(jobject rrs);
@ -230,9 +242,9 @@ public:
void clearState();
void setInitialTagValueZoom(std::string tag, std::string value, int zoom);
void setInitialTagValueZoom(std::string tag, std::string value, int zoom, MapDataObject* obj);
void setTagValueZoomLayer(std::string tag, std::string val, int zoom, int layer);
void setTagValueZoomLayer(std::string tag, std::string val, int zoom, int layer, MapDataObject* obj);
};

View file

@ -6,6 +6,7 @@
#include <math.h>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <set>
#include <hash_map>
#include <time.h>
@ -30,12 +31,12 @@
jclass jclass_JUnidecode;
jmethodID jmethod_JUnidecode_unidecode;
void calcPoint(MapDataObject* mObj, jint ind, RenderingContext* rc)
void calcPoint(std::pair<int, int> c, RenderingContext* rc)
{
rc->pointCount++;
float tx = mObj->points.at(ind).first/ (rc->tileDivisor);
float ty = mObj->points.at(ind).second / (rc->tileDivisor);
float tx = c.first/ (rc->tileDivisor);
float ty = c.second / (rc->tileDivisor);
float dTileX = tx - rc->leftX;
float dTileY = ty - rc->topY;
@ -46,20 +47,6 @@ void calcPoint(MapDataObject* mObj, jint ind, RenderingContext* rc)
rc->pointInsideCount++;
}
void calcMultipolygonPoint(int xt, int yt, jint ind, jint b, RenderingContext* rc)
{
rc->pointCount++;
float tx = xt/ (rc->tileDivisor);
float ty = yt / (rc->tileDivisor);
float dTileX = tx - rc->leftX;
float dTileY = ty - rc->topY;
rc->calcX = rc->cosRotateTileSize * dTileX - rc->sinRotateTileSize * dTileY;
rc->calcY = rc->sinRotateTileSize * dTileX + rc->cosRotateTileSize * dTileY;
if (rc->calcX >= 0 && rc->calcX < rc->width && rc->calcY >= 0 && rc->calcY < rc->height)
rc->pointInsideCount++;
}
std::hash_map<std::string, SkPathEffect*> pathEffects;
SkPathEffect* getDashEffect(std::string input)
@ -197,57 +184,25 @@ int updatePaint(RenderingRuleSearchRequest* req, SkPaint* paint, int ind, int ar
return 1;
}
void drawPointText(RenderingRuleSearchRequest* req, RenderingContext* rc, std::string tag, std::string value, float xText, float yText, std::string name, SkPath* path)
{
if(rc->useEnglishNames)
{
void renderText(MapDataObject* obj, RenderingRuleSearchRequest* req, RenderingContext* rc, std::string tag,
std::string value, float xText, float yText, SkPath* path) {
std::hash_map<std::string, std::string>::iterator it = obj->objectNames.begin();
while (it != obj->objectNames.end()) {
if (it->second.length() > 0) {
std::string name = it->second;
if (rc->useEnglishNames) {
jstring n = getGlobalJniEnv()->NewStringUTF(name.c_str());
name = getString((jstring) getGlobalJniEnv()->CallStaticObjectMethod(jclass_JUnidecode, jmethod_JUnidecode_unidecode, n));
name = getString(
(jstring) getGlobalJniEnv()->CallStaticObjectMethod(jclass_JUnidecode,
jmethod_JUnidecode_unidecode, n));
getGlobalJniEnv()->DeleteLocalRef(n);
}
if (name.at(0) == REF_CHAR)
{
std::string ref = name.substr(1);
name = "";
for (uint k = 0; k < ref.length(); k++)
{
if (ref.at(k) == REF_CHAR)
{
if (k < ref.length() - 1)
{
name = ref.substr(k + 1);
}
ref = ref.substr(0, k);
break;
}
}
if (ref.length() > 0)
{
req->setInitialTagValueZoom(tag, value, rc->zoom);
req->setIntFilter(req->props()->R_TEXT_LENGTH, ref.length());
req->setBooleanFilter(req->props()->R_REF, true);
if (req->searchRule(RenderingRulesStorage::TEXT_RULES))
{
if (req->getIntPropertyValue(req->props()->R_TEXT_SIZE) > 0)
{
TextDrawInfo* text = new TextDrawInfo(ref);
fillTextProperties(text, req, xText, yText);
if (path != NULL)
text->path = new SkPath(*path);
rc->textToDraw.push_back(text);
}
}
}
}
req->setInitialTagValueZoom(tag, value, rc->zoom);
req->setInitialTagValueZoom(tag, value, rc->zoom, obj);
req->setIntFilter(req->props()->R_TEXT_LENGTH, name.length());
req->setBooleanFilter(req->props()->R_REF, false);
if (req->searchRule(RenderingRulesStorage::TEXT_RULES) &&
req->getIntPropertyValue(req->props()->R_TEXT_SIZE) > 0)
{
std::string tagName = it->first == "name" ? "" : it->first;
req->setStringFilter(req->props()->R_NAME_TAG, tagName);
if (req->searchRule(RenderingRulesStorage::TEXT_RULES)
&& req->getIntPropertyValue(req->props()->R_TEXT_SIZE) > 0) {
TextDrawInfo* info = new TextDrawInfo(name);
info->drawOnPath = (path != NULL) && (req->getIntPropertyValue(req->props()->R_TEXT_ON_PATH, 0) > 0);
if (path != NULL)
@ -256,6 +211,11 @@ void drawPointText(RenderingRuleSearchRequest* req, RenderingContext* rc, std::s
fillTextProperties(info, req, xText, yText);
rc->textToDraw.push_back(info);
}
}
it++;
}
}
void drawPolylineShadow(SkCanvas* cv, SkPaint* paint, RenderingContext* rc, SkPath* path, int shadowColor, int shadowRadius)
@ -320,16 +280,10 @@ void drawOneWayPaints(RenderingContext* rc, SkCanvas* cv, SkPath* p) {
}
}
bool isOneWayWay(int highwayAttributes) {
return (highwayAttributes & 1) > 0;
}
bool isRoundabout(int highwayAttributes) {
return ((highwayAttributes >> 2) & 1) > 0;
}
void drawPolyline(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas* cv, SkPaint* paint,
RenderingContext* rc, std::pair<std::string, std::string> pair, int layer, int drawOnlyShadow) {
RenderingContext* rc, tag_value pair, int layer, int drawOnlyShadow) {
jint length = mObj->points.size();
if (length < 2) {
return;
@ -337,17 +291,20 @@ void drawPolyline(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas
std::string tag = pair.first;
std::string value = pair.second;
req->setInitialTagValueZoom(tag, value, rc->zoom);
req->setInitialTagValueZoom(tag, value, rc->zoom, mObj);
req->setIntFilter(req->props()->R_LAYER, layer);
bool oneway = false;
if (rc->zoom >= 16 && "highway" == pair.first && isOneWayWay(mObj->highwayAttributes)) {
oneway = true;
}
bool rendered = req->searchRule(2);
if (!rendered || !updatePaint(req, paint, 0, 0, rc)) {
return;
}
int oneway = 0;
if (rc->zoom >= 16 && pair.first == "highway") {
if (mObj->containsAdditional("oneway", "yes")) {
oneway = 1;
} else if (mObj->containsAdditional("oneway", "-1")) {
oneway = -1;
}
}
rc->visible++;
SkPath path;
@ -355,11 +312,11 @@ void drawPolyline(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas
SkPoint middlePoint;
int middle = length / 2;
for (; i < length; i++) {
calcPoint(mObj, i, rc);
calcPoint(mObj->points.at(i), rc);
if (i == 0) {
path.moveTo(rc->calcX, rc->calcY);
} else {
if(i == middle){
if (i == middle) {
middlePoint.set(rc->calcX, rc->calcY);
}
path.lineTo(rc->calcX, rc->calcY);
@ -381,68 +338,16 @@ void drawPolyline(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas
if (oneway && !drawOnlyShadow) {
drawOneWayPaints(rc, cv, &path);
}
if (!drawOnlyShadow && mObj->name.length() > 0) {
drawPointText(req, rc,pair.first, pair.second, middlePoint.fX, middlePoint.fY, mObj->name,
&path);
if (!drawOnlyShadow) {
renderText(mObj, req, rc, pair.first, pair.second, middlePoint.fX, middlePoint.fY, &path);
}
}
}
}
void drawMultiPolygon(MultiPolygonObject* mapObject,RenderingRuleSearchRequest* req, SkCanvas* cv, SkPaint* paint,
RenderingContext* rc) {
if (req == NULL) {
return;
}
req->setInitialTagValueZoom(mapObject->tag, mapObject->value, rc->zoom);
bool rendered = req->searchRule(3);
if (!rendered || !updatePaint(req, paint, 0, 1, rc)) {
return;
}
int boundsCount = mapObject->points.size();
rc->visible++;
SkPath path;
for (int i = 0; i < boundsCount; i++) {
int cnt = mapObject->points.at(i).size();
float xText = 0;
float yText = 0;
for (int j = 0; j < cnt; j++) {
std::pair<int,int> pair = mapObject->points.at(i).at(j);
calcMultipolygonPoint(pair.first, pair.second, j, i, rc);
xText += rc->calcX;
yText += rc->calcY;
if (j == 0) {
path.moveTo(rc->calcX, rc->calcY);
} else {
path.lineTo(rc->calcX, rc->calcY);
}
}
if (cnt > 0) {
std::string name = mapObject->names.at(i);
if (name.length() > 0) {
drawPointText(req, rc, mapObject->tag, mapObject->value, xText / cnt, yText / cnt, name, NULL);
}
}
}
PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
// for test purpose
// paint->setStyle(SkPaint::kStroke_Style);
// paint->setStrokeWidth(2);
// paint->setPathEffect(NULL);
// paint->setColor(BLACK_COLOR);
// PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
if (updatePaint(req, paint, 1, 0, rc)) {
PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
}
}
void drawPolygon(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas* cv, SkPaint* paint,
RenderingContext* rc, std::pair<std::string, std::string> pair) {
RenderingContext* rc, tag_value pair) {
jint length = mObj->points.size();
if (length <= 2) {
return;
@ -450,7 +355,7 @@ void drawPolygon(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas*
std::string tag = pair.first;
std::string value = pair.second;
req->setInitialTagValueZoom(tag, value, rc->zoom);
req->setInitialTagValueZoom(tag, value, rc->zoom, mObj);
bool rendered = req->searchRule(3);
float xText = 0;
@ -463,7 +368,7 @@ void drawPolygon(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas*
SkPath path;
int i = 0;
for (; i < length; i++) {
calcPoint(mObj, i, rc);
calcPoint(mObj->points.at(i), rc);
if (i == 0) {
path.moveTo(rc->calcX, rc->calcY);
} else {
@ -472,32 +377,42 @@ void drawPolygon(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas*
xText += rc->calcX;
yText += rc->calcY;
}
std::vector<coordinates> polygonInnerCoordinates = mObj->polygonInnerCoordinates;
if (polygonInnerCoordinates.size() > 0) {
path.setFillType(SkPath::kEvenOdd_FillType);
for (int j = 0; j < polygonInnerCoordinates.size(); j++) {
coordinates cs = polygonInnerCoordinates.at(j);
for (int i = 0; i < cs.size(); i++) {
calcPoint(cs[i], rc);
if (i == 0) {
path.moveTo(rc->calcX, rc->calcY);
} else {
path.lineTo(rc->calcX, rc->calcY);
}
}
}
}
PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
if (updatePaint(req, paint, 1, 0, rc)) {
PROFILE_NATIVE_OPERATION(rc, cv->drawPath(path, *paint));
}
std::string name = mObj->name;
if (name.length() > 0) {
drawPointText(req, rc, tag, value, xText / length, yText / length, name, NULL);
}
renderText(mObj, req, rc, pair.first, pair.second, xText / length, yText / length, NULL);
}
void drawPoint(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas* cv, SkPaint* paint,
RenderingContext* rc, std::pair<std::string, std::string> pair, int renderText)
RenderingContext* rc, std::pair<std::string, std::string> pair, int renderTxt)
{
std::string tag = pair.first;
std::string value = pair.second;
req->setInitialTagValueZoom(tag, value, rc->zoom);
req->setInitialTagValueZoom(tag, value, rc->zoom, mObj);
req->searchRule(1);
std::string resId = req->getStringPropertyValue(req-> props()-> R_ICON);
SkBitmap* bmp = getCachedBitmap(rc, resId);
std::string name;
if (renderText)
name = mObj->name;
if (!bmp && name.length() == 0)
if (!bmp && !renderText)
return;
jint length = mObj->points.size();
@ -506,7 +421,7 @@ void drawPoint(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas* c
float py = 0;
int i = 0;
for (; i < length; i++) {
calcPoint(mObj, i, rc);
calcPoint(mObj->points.at(i), rc);
px += rc->calcX;
py += rc->calcY;
}
@ -522,35 +437,22 @@ void drawPoint(MapDataObject* mObj, RenderingRuleSearchRequest* req, SkCanvas* c
ico.bmp = bmp;
rc->iconsToDraw.push_back(ico);
}
if (name.length() > 0) {
drawPointText(req, rc, tag, value, px, py, name, NULL);
if (renderTxt) {
renderText(mObj, req, rc, pair.first, pair.second, px, py, NULL);
}
}
void drawObject(RenderingContext* rc, BaseMapDataObject* mapObject, SkCanvas* cv, RenderingRuleSearchRequest* req,
void drawObject(RenderingContext* rc, MapDataObject* mObj, SkCanvas* cv, RenderingRuleSearchRequest* req,
SkPaint* paint, int l, int renderText, int drawOnlyShadow) {
rc->allObjects++;
if (mapObject-> type == BaseMapDataObject::MULTI_POLYGON) {
if (!drawOnlyShadow) {
drawMultiPolygon((MultiPolygonObject*) mapObject, req, cv, paint, rc);
}
return;
}
MapDataObject* mObj = (MapDataObject*) mapObject;
jint mainType = mObj->types.at(l);
int t = mainType & 3;
std::pair<std::string, std::string> pair = mObj->tagValues.at(l);
int t = mObj->objectType;
tag_value pair = mObj->types.at(l);
if (t == 1 && !drawOnlyShadow) {
// point
drawPoint(mObj, req, cv, paint, rc, pair, renderText);
} else if (t == 2) {
// polyline
int layer = getNegativeWayLayer(mainType);
// __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "Draw polyline");
drawPolyline(mObj, req, cv, paint, rc, pair, layer, drawOnlyShadow);
drawPolyline(mObj, req, cv, paint, rc, pair, mObj->getSimpleLayer(), drawOnlyShadow);
} else if (t == 3 && !drawOnlyShadow) {
// polygon
drawPolygon(mObj, req, cv, paint, rc, pair);
@ -601,45 +503,27 @@ void drawIconsOverCanvas(RenderingContext* rc, SkCanvas* canvas)
}
}
std::hash_map<int, std::vector<int> > sortObjectsByProperOrder(std::vector <BaseMapDataObject* > mapDataObjects,
std::hash_map<int, std::vector<int> > sortObjectsByProperOrder(std::vector <MapDataObject* > mapDataObjects,
RenderingRuleSearchRequest* req, RenderingContext* rc) {
std::hash_map<int, std::vector<int> > orderMap;
if (req != NULL) {
req->clearState();
const size_t size = mapDataObjects.size();
size_t i = 0;
const int size = mapDataObjects.size();
int i = 0;
for (; i < size; i++) {
uint sh = i << 8;
BaseMapDataObject* obj = mapDataObjects.at(i);
if (obj->type == BaseMapDataObject::MULTI_POLYGON) {
MultiPolygonObject* mobj = (MultiPolygonObject*) obj;
req->setTagValueZoomLayer(mobj->tag, mobj->value, rc->zoom, mobj->layer);
req->setIntFilter(req->props()->R_ORDER_TYPE, RenderingRulesStorage::POLYGON_RULES);
if (req->searchRule(RenderingRulesStorage::ORDER_RULES)) {
int order = req->getIntPropertyValue(req->props()->R_ORDER);
orderMap[order].push_back(sh);
if (req->getIntPropertyValue(req->props()->R_SHADOW_LEVEL) > 0) {
rc->shadowLevelMin = std::min(rc->shadowLevelMin, order);
rc->shadowLevelMax = std::max(rc->shadowLevelMax, order);
req->clearIntvalue(req->props()->R_SHADOW_LEVEL);
}
}
} else {
MapDataObject* mobj = (MapDataObject*) obj;
MapDataObject* mobj = mapDataObjects[i];
size_t sizeTypes = mobj->types.size();
size_t j = 0;
for (; j < sizeTypes; j++) {
int wholeType = mobj->types.at(j);
int mask = wholeType & 3;
int layer = 0;
if (mask != 1) {
layer = getNegativeWayLayer(wholeType);
}
std::pair<std::string, std::string> pair = mobj->tagValues.at(j);
req->setTagValueZoomLayer(pair.first, pair.second, rc->zoom, layer);
req->setIntFilter(req->props()->R_ORDER_TYPE, mask);
int layer = mobj->getSimpleLayer();
tag_value pair = mobj->types[j];
req->setTagValueZoomLayer(pair.first, pair.second, rc->zoom, layer, mobj);
req->setIntFilter(req->props()->R_AREA, mobj->area);
req->setIntFilter(req->props()->R_POINT, mobj->points.size() == 1);
req->setIntFilter(req->props()->R_CYCLE, mobj->cycle());
if (req->searchRule(RenderingRulesStorage::ORDER_RULES)) {
mobj->objectType = req->getIntPropertyValue(req->props()->R_OBJECT_TYPE);
int order = req->getIntPropertyValue(req->props()->R_ORDER);
orderMap[order].push_back(sh + j);
if (req->getIntPropertyValue(req->props()->R_SHADOW_LEVEL) > 0) {
@ -648,7 +532,6 @@ std::hash_map<int, std::vector<int> > sortObjectsByProperOrder(std::vector <Base
req->clearIntvalue(req->props()->R_SHADOW_LEVEL);
}
}
}
}
}
@ -656,7 +539,7 @@ std::hash_map<int, std::vector<int> > sortObjectsByProperOrder(std::vector <Base
return orderMap;
}
void doRendering(std::vector <BaseMapDataObject* > mapDataObjects, SkCanvas* canvas, SkPaint* paint,
void doRendering(std::vector <MapDataObject* > mapDataObjects, SkCanvas* canvas, SkPaint* paint,
RenderingRuleSearchRequest* req, RenderingContext* rc) {
// put in order map
std::hash_map<int, std::vector<int> > orderMap = sortObjectsByProperOrder(mapDataObjects, req, rc);
@ -681,7 +564,7 @@ void doRendering(std::vector <BaseMapDataObject* > mapDataObjects, SkCanvas* can
int i = *ls;
int ind = i >> 8;
int l = i & 0xff;
BaseMapDataObject* mapObject = mapDataObjects.at(ind);
MapDataObject* mapObject = mapDataObjects.at(ind);
// show text only for main type
drawObject(rc, mapObject, canvas, req, paint, l, l == 0, true);
@ -696,7 +579,7 @@ void doRendering(std::vector <BaseMapDataObject* > mapDataObjects, SkCanvas* can
int ind = i >> 8;
int l = i & 0xff;
BaseMapDataObject* mapObject = mapDataObjects.at(ind);
MapDataObject* mapObject = mapDataObjects.at(ind);
// show text only for main type
drawObject(rc, mapObject, canvas, req, paint, l, l == 0, false);
}

View file

@ -13,8 +13,6 @@
#include "common.h"
#include "renderRules.h"
const char REF_CHAR = ((char)0x0019);
const char DELIM_CHAR = ((char)0x0018);
template <typename T> class quad_tree {
private :
@ -490,13 +488,6 @@ void drawTextOverCanvas(RenderingContext* rc, SkCanvas* cv) {
for (uint i = 0; i < size; i++) {
TextDrawInfo* text = rc->textToDraw.at(i);
if (text->text.length() > 0) {
size_t d = text->text.find(DELIM_CHAR);
// not used now functionality
// possibly it will be used specifying english names after that character
if (d > 0) {
text->text = text->text.substr(0, d);
}
// sest text size before finding intersection (it is used there)
float textSize = getDensityValue(rc, text->textSize);
paintText.setTextSize(textSize);