Fix C compilation problems
This commit is contained in:
parent
b02400b186
commit
ad350f003f
12 changed files with 3474 additions and 2494 deletions
|
@ -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>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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 ?
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ¤t->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, ¤t->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());
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
@ -258,6 +213,11 @@ void drawPointText(RenderingRuleSearchRequest* req, RenderingContext* rc, std::s
|
|||
}
|
||||
}
|
||||
|
||||
it++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void drawPolylineShadow(SkCanvas* cv, SkPaint* paint, RenderingContext* rc, SkPath* path, int shadowColor, int shadowRadius)
|
||||
{
|
||||
// blurred shadows
|
||||
|
@ -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,7 +312,7 @@ 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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue