Test native routing implementation

This commit is contained in:
Victor Shcherb 2012-11-01 00:46:09 +01:00
parent 95c90a0784
commit efaf4e25c4
9 changed files with 726 additions and 251 deletions

View file

@ -7,6 +7,7 @@ import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
import net.osmand.binary.RouteDataObject;
import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage;
import net.osmand.router.RouteSegmentResult;
public class NativeLibrary {
@ -81,7 +82,6 @@ public class NativeLibrary {
if(rs.nativeHandler == 0) {
// do not throw exception because it is expected situation
return new RouteDataObject[0];
// throw new IllegalStateException("Native route handler is 0");
}
return getRouteDataObjects(rs.region.routeReg, rs.nativeHandler, x31, y31);
}
@ -99,6 +99,10 @@ public class NativeLibrary {
return closeBinaryMapFile(filePath);
}
public RouteSegmentResult[] testRoutingInternal(int sx31, int sy31, int ex31, int ey31) {
return testRouting(sx31, sy31, ex31, ey31);
}
public NativeRouteSearchResult loadRouteRegion(RouteSubregion sub, boolean loadObjects) {
@ -118,6 +122,8 @@ public class NativeLibrary {
protected static native RouteDataObject[] getRouteDataObjects(RouteRegion reg, long rs, int x31, int y31);
protected static native RouteSegmentResult[] testRouting(int sx31, int sy31, int ex31, int ey31);
protected static native void deleteSearchResult(long searchResultHandle);
protected static native boolean initBinaryMapFile(String filePath);

View file

@ -517,13 +517,20 @@ public class RoutingContext {
}
public void loadTileData(int x31, int y31, int zoomAround, final List<RouteDataObject> toFillIn) {
int coordinatesShift = (1 << (31 - zoomAround));
int t = zoomAround - config.ZOOM_TO_LOAD_TILES;
if(t <= 0) {
t = 1;
} else {
t = 1 << t;
}
int coordinatesShift = (1 << (31 - config.ZOOM_TO_LOAD_TILES));
TLongHashSet ts = new TLongHashSet();
long now = System.nanoTime();
ts.add(getRoutingTile(x31 - coordinatesShift, y31 - coordinatesShift, 0, OPTION_IN_MEMORY_LOAD));
ts.add(getRoutingTile(x31 + coordinatesShift, y31 - coordinatesShift, 0, OPTION_IN_MEMORY_LOAD));
ts.add(getRoutingTile(x31 - coordinatesShift, y31 + coordinatesShift, 0, OPTION_IN_MEMORY_LOAD));
ts.add(getRoutingTile(x31 + coordinatesShift, y31 + coordinatesShift, 0, OPTION_IN_MEMORY_LOAD));
for(int i = -t; i <= t; i++) {
for(int j = -t; j <= t; j++) {
ts.add(getRoutingTile(x31 +i*coordinatesShift, y31 + j*coordinatesShift, 0, OPTION_IN_MEMORY_LOAD));
}
}
TLongIterator it = ts.iterator();
while(it.hasNext()){
getAllObjects(it.next(), toFillIn);

View file

@ -631,6 +631,8 @@ public class MapRouterLayer implements MapPanelLayer {
if (e == null) {
throw new RuntimeException("End point to calculate route was not found");
}
log.info("End road " + e.getRoad().getHighway() + " " + e.getRoad().id);
List<RouteSegment> inters = new ArrayList<BinaryRoutePlanner.RouteSegment>();
@ -714,8 +716,14 @@ public class MapRouterLayer implements MapPanelLayer {
});
List<RouteSegmentResult> searchRoute = router.searchRoute(ctx, st, e, inters, false);
this.previousRoute = searchRoute;
int ex31 = e.getRoad().getPoint31XTile(e.getSegmentStart());
int ey31 = e.getRoad().getPoint31YTile(e.getSegmentStart());
int sx31 = st.getRoad().getPoint31XTile(st.getSegmentStart());
int sy31 = st.getRoad().getPoint31YTile(st.getSegmentStart());
// FIXME
RouteSegmentResult[] searchRoute = ctx.nativeLib.testRoutingInternal(sx31, sy31, ex31, ey31);
/*List<RouteSegmentResult> searchRoute = */router.searchRoute(ctx, st, e, inters, false);
// this.previousRoute = searchRoute;
if (animateRoutingCalculation) {
playPauseButton.setVisible(false);
nextTurn.setText("FINISH");
@ -734,13 +742,14 @@ public class MapRouterLayer implements MapPanelLayer {
// String name = String.format("beg %.2f end %.2f ", s.getBearingBegin(), s.getBearingEnd());
way.putTag(OSMTagKey.NAME.getValue(),name);
boolean plus = s.getStartPointIndex() < s.getEndPointIndex();
System.out.println("Segment " + s.getObject().id + " "+s.getStartPointIndex() + " -> " + s.getEndPointIndex());
int i = s.getStartPointIndex();
while (true) {
LatLon l = s.getPoint(i);
net.osmand.osm.Node n = new net.osmand.osm.Node(l.getLatitude(), l.getLongitude(), -1);
if (prevWayNode != null) {
if (MapUtils.getDistance(prevWayNode, n) > 0) {
System.out.println("Warning not connected road " + " " + s.getObject().getHighway() + " dist "
System.out.println("Warning not connected road " + " " + s.getObject().id + " dist "
+ MapUtils.getDistance(prevWayNode, n));
}
prevWayNode = null;
@ -760,9 +769,7 @@ public class MapRouterLayer implements MapPanelLayer {
}
res.add(way);
}
} catch (IOException e) {
ExceptionHandler.handle(e);
} catch (InterruptedException e) {
} catch (Exception e) {
ExceptionHandler.handle(e);
} finally {
playPauseButton.setVisible(false);

View file

@ -1,3 +1,4 @@
#include "binaryRead.h"
#include <fcntl.h>
@ -22,6 +23,7 @@ using google::protobuf::internal::WireFormatLite;
static int zoomForBaseRouteRendering = 14;
std::map< std::string, BinaryMapFile* > openFiles;
OsmAndStoredIndex* cache = NULL;
typedef UNORDERED(set)<long long> IDS_SET;
void searchRouteSubRegion(int fileInd, std::vector<RouteDataObject*>& list, RoutingIndex* routingIndex, RouteSubregion* sub);
void searchRouteRegion(CodedInputStream* input, SearchQuery* q, RoutingIndex* ind, std::vector<RouteSubregion>& subregions,
@ -249,7 +251,8 @@ bool readMapEncodingRule(CodedInputStream* input, MapIndex* index, uint32_t id)
}
bool readRouteTree(CodedInputStream* input, RouteSubregion* thisTree, RouteSubregion* parentTree, int depth, bool readCoordinates) {
bool readRouteTree(CodedInputStream* input, RouteSubregion* thisTree, RouteSubregion* parentTree, RoutingIndex* ind,
int depth, bool readCoordinates) {
bool readChildren = depth != 0;
uint32_t tag;
int i;
@ -290,11 +293,11 @@ bool readRouteTree(CodedInputStream* input, RouteSubregion* thisTree, RouteSubre
}
case OsmAndRoutingIndex_RouteDataBox::kBoxesFieldNumber: {
if (readChildren) {
RouteSubregion subregion;
RouteSubregion subregion(ind);
readInt(input, &subregion.length);
subregion.filePointer = input->getTotalBytesRead();
int oldLimit = input->PushLimit(subregion.length);
readRouteTree(input, &subregion, thisTree, depth - 1, true);
readRouteTree(input, &subregion, thisTree, ind, depth - 1, true);
input->PopLimit(oldLimit);
input->Seek(subregion.filePointer + subregion.length);
thisTree->subregions.push_back(subregion);
@ -340,18 +343,16 @@ bool readRoutingIndex(CodedInputStream* input, RoutingIndex* routingIndex) {
case OsmAndRoutingIndex::kRootBoxesFieldNumber:
case OsmAndRoutingIndex::kBasemapBoxesFieldNumber:{
bool basemap = WireFormatLite::GetTagFieldNumber(tag) == OsmAndRoutingIndex::kBasemapBoxesFieldNumber;
RouteSubregion subregion;
RouteSubregion subregion(routingIndex);
readInt(input, &subregion.length);
subregion.filePointer = input->getTotalBytesRead();
int oldLimit = input->PushLimit(subregion.length);
readRouteTree(input, &subregion, NULL, 0, true);
readRouteTree(input, &subregion, NULL, routingIndex, 0, true);
input->PopLimit(oldLimit);
input->Seek(subregion.filePointer + subregion.length);
if(basemap) {
osmand_log_print(LOG_INFO, "route basemap %d %s",subregion.filePointer, routingIndex->name.c_str() );
routingIndex->basesubregions.push_back(subregion);
} else {
osmand_log_print(LOG_INFO, "route map %d %s",subregion.filePointer, routingIndex->name.c_str() );
routingIndex->subregions.push_back(subregion);
}
break;
@ -902,7 +903,7 @@ void searchMapData(CodedInputStream* input, MapRoot* root, MapIndex* ind, Search
void convertRouteDataObjecToMapObjects(SearchQuery* q, std::vector<RouteDataObject*>& list, std::vector<MapDataObject*>& tempResult,
bool skipDuplicates, UNORDERED(set)<long long>& ids) {
bool skipDuplicates, IDS_SET& ids) {
std::vector<RouteDataObject*>::iterator rIterator = list.begin();
tempResult.reserve((size_t) (list.size() + tempResult.size()));
for (; rIterator != list.end(); rIterator++) {
@ -972,62 +973,97 @@ void checkAndInitRouteRegionRules(int fileInd, RoutingIndex* routingIndex){
}
}
void readRouteDataAsMapObjects(SearchQuery* q, BinaryMapFile* file, std::vector<MapDataObject*>& tempResult,
bool skipDuplicates, UNORDERED(set)<long long>& ids) {
for (std::vector<RoutingIndex*>::iterator routeIndex = file->routingIndexes.begin();
routeIndex != file->routingIndexes.end(); routeIndex++) {
if (q->publisher->isCancelled()) {
break;
}
bool contains = false;
std::vector<RouteSubregion> subs =
q->zoom <= zoomForBaseRouteRendering ? (*routeIndex)->basesubregions : (*routeIndex)->subregions;
for (std::vector<RouteSubregion>::iterator subreg = subs.begin(); subreg != subs.end(); subreg++) {
if (subreg->right >= q->left && q->right >= subreg->left && subreg->bottom >= q->top
&& q->bottom >= subreg->top) {
osmand_log_print(LOG_INFO, "Search route map %s", (*routeIndex)->name.c_str());
contains = true;
}
}
osmand_log_print(LOG_INFO, "Search map %s %d", (*routeIndex)->name.c_str(), subs.size());
if (contains) {
vector<RouteSubregion> found;
lseek(file->fd, 0, SEEK_SET);
FileInputStream input(file->fd);
input.SetCloseOnDelete(false);
CodedInputStream cis(&input);
cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 1);
cis.Seek((*routeIndex)->filePointer);
uint32_t old = cis.PushLimit((*routeIndex)->length);
searchRouteRegion(&cis, q, *routeIndex, subs, found);
cis.PopLimit(old);
checkAndInitRouteRegionRules(file->fd, (*routeIndex));
osmand_log_print(LOG_INFO, "Search map %s %d", (*routeIndex)->name.c_str(), found.size());
sort(found.begin(), found.end(), sortRouteRegions);
{
lseek(file->fd, 0, SEEK_SET);
FileInputStream input(file->fd);
input.SetCloseOnDelete(false);
CodedInputStream cis(&input);
cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 2);
for (std::vector<RouteSubregion>::iterator sub = found.begin(); sub != found.end();sub++) {
std::vector<RouteDataObject*> list;
cis.Seek(sub->filePointer + sub->mapDataBlock);
uint32_t length;
cis.ReadVarint32(&length);
uint32_t old = cis.PushLimit(length);
readRouteTreeData(&cis, &(*sub), list, *routeIndex);
cis.PopLimit(old);
convertRouteDataObjecToMapObjects(q, list, tempResult, skipDuplicates, ids);
}
}
void searchRouteSubregions(SearchQuery* q, std::vector<RouteSubregion>& tempResult) {
map<std::string, BinaryMapFile*>::iterator i = openFiles.begin();
for (; i != openFiles.end() && !q->publisher->isCancelled(); i++) {
BinaryMapFile* file = i->second;
std::vector<RoutingIndex*>::iterator routeIndex = file->routingIndexes.begin();
for (; routeIndex != file->routingIndexes.end(); routeIndex++) {
bool contains = false;
std::vector<RouteSubregion>& subs = (*routeIndex)->subregions;
for (std::vector<RouteSubregion>::iterator subreg = subs.begin(); subreg != subs.end(); subreg++) {
if (subreg->right >= q->left && q->right >= subreg->left && subreg->bottom >= q->top
&& q->bottom >= subreg->top) {
contains = true;
}
}
if (contains) {
lseek(file->fd, 0, SEEK_SET);
FileInputStream input(file->fd);
input.SetCloseOnDelete(false);
CodedInputStream cis(&input);
cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 1);
cis.Seek((*routeIndex)->filePointer);
uint32_t old = cis.PushLimit((*routeIndex)->length);
searchRouteRegion(&cis, q, *routeIndex, subs, tempResult);
cis.PopLimit(old);
checkAndInitRouteRegionRules(file->fd, (*routeIndex));
}
}
}
}
void readRouteMapObjects(SearchQuery* q, BinaryMapFile* file, vector<RouteSubregion>& found,
RoutingIndex* routeIndex, std::vector<MapDataObject*>& tempResult, bool skipDuplicates,
IDS_SET& ids) {
osmand_log_print(LOG_INFO, "Search map %s %d", routeIndex->name.c_str(), found.size());
sort(found.begin(), found.end(), sortRouteRegions);
lseek(file->fd, 0, SEEK_SET);
FileInputStream input(file->fd);
input.SetCloseOnDelete(false);
CodedInputStream cis(&input);
cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 2);
for (std::vector<RouteSubregion>::iterator sub = found.begin(); sub != found.end(); sub++) {
std::vector<RouteDataObject*> list;
cis.Seek(sub->filePointer + sub->mapDataBlock);
uint32_t length;
cis.ReadVarint32(&length);
uint32_t old = cis.PushLimit(length);
readRouteTreeData(&cis, &(*sub), list, routeIndex);
cis.PopLimit(old);
convertRouteDataObjecToMapObjects(q, list, tempResult, skipDuplicates, ids);
}
}
void readRouteDataAsMapObjects(SearchQuery* q, BinaryMapFile* file, std::vector<MapDataObject*>& tempResult,
bool skipDuplicates, IDS_SET& ids) {
std::vector<RoutingIndex*>::iterator routeIndex = file->routingIndexes.begin();
for (; routeIndex != file->routingIndexes.end(); routeIndex++) {
if (q->publisher->isCancelled()) {
break;
}
bool contains = false;
std::vector<RouteSubregion> subs = (*routeIndex)->subregions;
if (q->zoom <= zoomForBaseRouteRendering) {
subs = (*routeIndex)->basesubregions;
}
for (std::vector<RouteSubregion>::iterator subreg = subs.begin(); subreg != subs.end(); subreg++) {
if (subreg->right >= q->left && q->right >= subreg->left && subreg->bottom >= q->top
&& q->bottom >= subreg->top) {
osmand_log_print(LOG_INFO, "Search route map %s", (*routeIndex)->name.c_str());
contains = true;
}
}
osmand_log_print(LOG_INFO, "Search map %s %d", (*routeIndex)->name.c_str(), subs.size());
if (contains) {
vector<RouteSubregion> found;
lseek(file->fd, 0, SEEK_SET);
FileInputStream input(file->fd);
input.SetCloseOnDelete(false);
CodedInputStream cis(&input);
cis.SetTotalBytesLimit(INT_MAX, INT_MAX >> 1);
cis.Seek((*routeIndex)->filePointer);
uint32_t old = cis.PushLimit((*routeIndex)->length);
searchRouteRegion(&cis, q, *routeIndex, subs, found);
cis.PopLimit(old);
checkAndInitRouteRegionRules(file->fd, (*routeIndex));
readRouteMapObjects(q, file, found, (*routeIndex), tempResult, skipDuplicates, ids);
}
}
}
void readMapObjects(SearchQuery* q, BinaryMapFile* file) {
for (std::vector<MapIndex>::iterator mapIndex = file->mapIndexes.begin(); mapIndex != file->mapIndexes.end();
mapIndex++) {
@ -1080,7 +1116,7 @@ void readMapObjects(SearchQuery* q, BinaryMapFile* file) {
ResultPublisher* searchObjectsForRendering(SearchQuery* q, bool skipDuplicates, int renderRouteDataFile, std::string msgNothingFound) {
map<std::string, BinaryMapFile*>::iterator i = openFiles.begin();
UNORDERED(set)<long long> ids;
IDS_SET ids;
if(skipDuplicates){
// override it for now
// TODO skip duplicates doesn't work correctly with basemap ?
@ -1230,7 +1266,7 @@ void searchRouteRegion(CodedInputStream* input, SearchQuery* q, RoutingIndex* in
&& subreg->bottom >= q->bottom;
input->Seek(subreg->filePointer);
uint32_t old = input->PushLimit(subreg->length);
readRouteTree(input, &(*subreg), NULL, -1/*contains? -1 : 1*/, false);
readRouteTree(input, &(*subreg), NULL, ind, -1/*contains? -1 : 1*/, false);
input->PopLimit(old);
}
searchRouteRegion(input, q, ind, subreg->subregions, toLoad);
@ -1507,9 +1543,10 @@ void searchRouteSubRegion(int fileInd, std::vector<RouteDataObject*>& list, Rou
cis.PopLimit(old);
}
void searchRouteDataForSubRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs, RouteSubregion* sub){
void searchRouteDataForSubRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RouteSubregion* sub){
map<std::string, BinaryMapFile*>::iterator i = openFiles.begin();
UNORDERED(set)<long long> ids;
RoutingIndex* rs = sub->routingIndex;
IDS_SET ids;
bool basemapExists = false;
for (; i != openFiles.end() && !q->publisher->isCancelled(); i++) {
BinaryMapFile* file = i->second;
@ -1645,7 +1682,7 @@ BinaryMapFile* initBinaryMapFile(std::string inputName) {
mi.name = mp.name();
for (int j = 0; j < mp.subregions_size(); j++) {
RoutingSubregion ml = mp.subregions(j);
RouteSubregion mr;
RouteSubregion mr(&mi);
mr.bottom = ml.bottom();
mr.left = ml.left();
mr.right = ml.right();

View file

@ -38,7 +38,7 @@ struct MapTreeBounds {
ocean = -1;
}
};
struct RoutingIndex;
struct RouteSubregion {
uint32_t length;
uint32_t filePointer;
@ -48,8 +48,9 @@ struct RouteSubregion {
uint32_t top;
uint32_t bottom;
std::vector<RouteSubregion> subregions;
RoutingIndex* routingIndex;
RouteSubregion() : length(0), filePointer(0), mapDataBlock(0){
RouteSubregion(RoutingIndex* ind) : length(0), filePointer(0), mapDataBlock(0), routingIndex(ind){
}
};
@ -252,7 +253,9 @@ struct SearchQuery {
}
};
void searchRouteDataForSubRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs, RouteSubregion* sub);
void searchRouteSubregions(SearchQuery* q, std::vector<RouteSubregion>& tempResult);
void searchRouteDataForSubRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RouteSubregion* sub);
ResultPublisher* searchObjectsForRendering(SearchQuery* q, bool skipDuplicates, int renderRouteDataFile, std::string msgNothingFound);

View file

@ -1,6 +1,8 @@
#include "common.h"
#include <queue>
#include <algorithm>
#include "binaryRead.h"
#include "binaryRoutePlanner.h"
#include <functional>
static bool PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
@ -27,131 +29,6 @@ inline int roadPriorityComparator(float o1DistanceFromStart, float o1DistanceToE
}
return f1 < f2 ? -1 : 1;
}
struct RouteSegment {
public :
int segmentStart;
SHARED_PTR<RouteDataObject> road;
// needed to store intersection of routes
SHARED_PTR<RouteSegment> next;
// search context (needed for searching route)
// Initially it should be null (!) because it checks was it segment visited before
SHARED_PTR<RouteSegment> parentRoute;
int parentSegmentEnd;
// distance measured in time (seconds)
float distanceFromStart;
float distanceToEnd;
RouteSegment(SHARED_PTR<RouteDataObject> road, int segmentStart) : road(road), segmentStart(segmentStart),
parentSegmentEnd(0), distanceFromStart(0), distanceToEnd(0){
}
};
// FIXME
const static int ZOOM_TO_LOAD_TILES = 16;
struct RoutingSubregionTile {
RouteSubregion subregion;
// make it without get/set for fast access
int access;
int loaded;
UNORDERED(map)<long long, SHARED_PTR<RouteSegment> > routes;
RoutingSubregionTile():access(0), loaded(0) {
}
bool isLoaded(){
return loaded > 0;
}
};
static long calcRouteId(SHARED_PTR<RouteDataObject> o, int ind) {
return (o->id << 10) + ind;
}
struct RoutingContext {
int visitedSegments;
ElapsedTimer timeToLoad;
ElapsedTimer timeToCalculate;
int firstRoadDirection;
int64_t firstRoadId;
vector<SHARED_PTR<RouteSegment> > segmentsToVisitNotForbidden;
vector<SHARED_PTR<RouteSegment> > segmentsToVisitPrescripted;
int finalReverseEndSegment;
SHARED_PTR<RouteSegment> finalReverseRoute;
int finalDirectEndSegment;
SHARED_PTR<RouteSegment> finalDirectRoute;
UNORDERED(map)<long long, vector<SHARED_PTR<RoutingSubregionTile> > > indexedSubregions;
// void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs, RouteSubregion* sub)
SHARED_PTR<RouteSegment> loadRouteSegment(int x31, int y31) {
timeToLoad.start();
int64_t xloc = x31 >> (31 - ZOOM_TO_LOAD_TILES);
int64_t yloc = y31 >> (31 - ZOOM_TO_LOAD_TILES);
int64_t tileId = (xloc << ZOOM_TO_LOAD_TILES) + yloc;
// if (indexedSubregions[tileId] == indexedSubregions.end()) {
// SearchQuery q((int) (xloc << zoomToLoad),
// (int) ((xloc + 1) << zoomToLoad), (int) (yloc << zoomToLoad), (int) ((yloc + 1) << zoomToLoad));
// vector<SHARED_PTR<RoutingSubregionTile> > collection = loadTileHeaders(x31, y31);
// indexedSubregions.put(tileId, collection);
// }
// vector<SHARED_PTR<RoutingSubregionTile> > subregions = indexedSubregions.get(tileId);
// if (subregions != null) {
// for (RoutingSubregionTile ts : subregions) {
// if (!ts.isLoaded()) {
// loadSubregionTile(ts, loadOptions == OPTION_IN_MEMORY_LOAD);
// }
// }
// }
timeToLoad.pause();
return SHARED_PTR<RouteSegment>();
}
bool isInterrupted(){
return false;
}
float getHeuristicCoefficient(){
return 1;
}
bool planRouteIn2Directions() {
return true;
}
int getPlanRoadDirection() {
return 0;
}
float defineSpeedPriority(SHARED_PTR<RouteDataObject> r) {
return 1;
}
float defineSpeed(SHARED_PTR<RouteDataObject> r) {
return 1;
}
float getMinDefaultSpeed(){
return 40;
}
float getMaxDefaultSpeed(){
return 130;
}
bool isOneWay(SHARED_PTR<RouteDataObject> r) {
return true;
}
float calculateTurnTime(SHARED_PTR<RouteSegment> segment, int index, SHARED_PTR<RouteSegment> next, int nextIndex){
return 0;
}
float defineRoutingObstacle(SHARED_PTR<RouteDataObject> road, int segmentEnd) {
return 0;
}
bool restrictionsAware(){
return true;
}
};
static double convert31YToMeters(int y1, int y2) {
@ -172,10 +49,6 @@ static double squareRootDist(int x1, int y1, int x2, int y2) {
// return measuredDist(x1, y1, x2, y2);
}
static double measuredDist(int x1, int y1, int x2, int y2) {
return getDistance(get31LatitudeY(y1), get31LongitudeX(x1), get31LatitudeY(y2),
get31LongitudeX(x2));
}
static double squareDist(int x1, int y1, int x2, int y2) {
// translate into meters
@ -203,18 +76,19 @@ struct SegmentsComparator : public std::binary_function<SHARED_PTR<RouteSegment>
}
bool operator()(const SHARED_PTR<RouteSegment> lhs, const SHARED_PTR<RouteSegment> rhs) const
{
return roadPriorityComparator(lhs.get()->distanceFromStart, lhs.get()->distanceToEnd, rhs.get()->distanceFromStart, rhs.get()->distanceToEnd, ctx->getHeuristicCoefficient()) < 0;
return roadPriorityComparator(lhs.get()->distanceFromStart, lhs.get()->distanceToEnd, rhs.get()->distanceFromStart,
rhs.get()->distanceToEnd, ctx->getHeuristicCoefficient()) > 0;
}
};
struct NonHeuristicSegmentsComparator : public std::binary_function<SHARED_PTR<RouteSegment>, SHARED_PTR<RouteSegment>, bool>
{
bool operator()(const SHARED_PTR<RouteSegment> lhs, const SHARED_PTR<RouteSegment> rhs) const
{
return roadPriorityComparator(lhs.get()->distanceFromStart, lhs.get()->distanceToEnd, rhs.get()->distanceFromStart, rhs.get()->distanceToEnd, 0.5) < 0;
return roadPriorityComparator(lhs.get()->distanceFromStart, lhs.get()->distanceToEnd, rhs.get()->distanceFromStart, rhs.get()->distanceToEnd, 0.5) > 0;
}
};
typedef UNORDERED(map)<long long, SHARED_PTR<RouteSegment> > VISITED_MAP;
typedef UNORDERED(map)<int64_t, SHARED_PTR<RouteSegment> > VISITED_MAP;
typedef priority_queue<SHARED_PTR<RouteSegment>, vector<SHARED_PTR<RouteSegment> >, SegmentsComparator > SEGMENTS_QUEUE;
bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
SEGMENTS_QUEUE& graphSegments, VISITED_MAP& visitedSegments, int targetEndX, int targetEndY,
@ -225,7 +99,6 @@ bool processIntersections(RoutingContext* ctx, SEGMENTS_QUEUE& graphSegments,
SHARED_PTR<RouteSegment> segment, int segmentEnd, SHARED_PTR<RouteSegment> inputNext,
bool reverseWay);
/**
* Calculate route between start.segmentEnd and end.segmentStart (using A* algorithm)
* return list of segments
@ -283,7 +156,6 @@ void searchRouteInternal(RoutingContext* ctx, SHARED_PTR<RouteSegment> start, SH
while (graphSegments->size() > 0) {
SHARED_PTR<RouteSegment> segment = graphSegments->top();
graphSegments->pop();
ctx->visitedSegments++;
bool routeFound = false;
if (!inverse) {
routeFound = processRouteSegment(ctx, false, graphDirectSegments, visitedDirectSegments, targetEndX, targetEndY,
@ -324,6 +196,9 @@ void searchRouteInternal(RoutingContext* ctx, SHARED_PTR<RouteSegment> start, SH
}
}
ctx->timeToCalculate.pause();
osmand_log_print(LOG_WARN, "[Native] Result visited (visited roads %d, visited segments %d / %d , queue sizes %d / %d ) ",
ctx-> visitedSegments, visitedDirectSegments.size(), visitedOppositeSegments.size(),
graphDirectSegments.size(),graphReverseSegments.size());
}
bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
SEGMENTS_QUEUE& graphSegments, VISITED_MAP& visitedSegments, int targetEndX, int targetEndY,
@ -337,9 +212,13 @@ bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
double obstacleMinusTime = 0;
// 0. mark route segment as visited
long nt = (road->id << ROUTE_POINTS) + middle;
int64_t nt = (road->id << ROUTE_POINTS) + middle;
if(visitedSegments.find(nt) != visitedSegments.end()) {
return false;
}
ctx->visitedSegments++;
// avoid empty segments to connect but mark the point as visited
visitedSegments[nt] =SHARED_PTR<RouteSegment>();
visitedSegments[nt] = SHARED_PTR<RouteSegment>();
int oneway = ctx->isOneWay(road);
bool minusAllowed;
@ -396,7 +275,7 @@ bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
continue;
}
// if we found end point break cycle
long nts = (road->id << ROUTE_POINTS) + segmentEnd;
int64_t nts = (road->id << ROUTE_POINTS) + segmentEnd;
visitedSegments[nts]=segment;
// 2. calculate point and try to load neighbor ways if they are not loaded
@ -434,13 +313,14 @@ bool processRouteSegment(RoutingContext* ctx, bool reverseWaySearch,
// throw new OutOfMemoryError("There is no enough memory " + ctx.config.memoryLimitation/(1<<20) + " Mb");
// }
SHARED_PTR<RouteSegment> next = ctx->loadRouteSegment(x, y);
// 3. get intersected ways
if (next.get() != NULL) {
// TO-DO U-Turn
if((next.get() == segment.get() || next->road->id == road->id) && next->next.get() == NULL) {
// simplification if there is no real intersection
continue;
}
// Using A* routing algorithm
// g(x) - calculate distance to that point and calculate time
@ -488,7 +368,7 @@ bool proccessRestrictions(RoutingContext* ctx, SHARED_PTR<RouteDataObject> road,
} else {
for (int i = 0; i < next->road->restrictions.size(); i++) {
int rt = next->road->restrictions[i] & 7;
long restrictedTo = next->road->restrictions[i] >> 3;
int64_t restrictedTo = next->road->restrictions[i] >> 3;
if (restrictedTo == road->id) {
type = rt;
break;
@ -557,26 +437,23 @@ bool processIntersections(RoutingContext* ctx, SEGMENTS_QUEUE& graphSegments,
if (thereAreRestrictions) {
next = *nextIterator;
}
long nts = (next->road->id << ROUTE_POINTS) + next->segmentStart;
int64_t nts = (next->road->id << ROUTE_POINTS) + next->segmentStart;
// 1. Check if opposite segment found so we can stop calculations
if (oppositeSegments[nts].get() != NULL) {
if (oppositeSegments.find(nts) != oppositeSegments.end()) {
// restrictions checked
SHARED_PTR<RouteSegment> opposite = oppositeSegments[nts];
// additional check if opposite way not the same as current one
if (next->segmentStart != segmentEnd ||
opposite->road->id != segment->road->id) {
if (reverseWay) {
ctx->finalReverseEndSegment = segmentEnd;
ctx->finalReverseRoute = segment;
ctx->finalDirectEndSegment = next->segmentStart;
ctx->finalDirectRoute = opposite;
} else {
ctx->finalDirectEndSegment = segmentEnd;
ctx->finalDirectRoute = segment;
ctx->finalReverseEndSegment = next->segmentStart;
ctx->finalReverseRoute = opposite;
}
if (opposite.get() != NULL && (next->segmentStart != segmentEnd ||
opposite->road->id != segment->road->id)) {
SHARED_PTR<FinalRouteSegment> frs = SHARED_PTR<FinalRouteSegment>(new FinalRouteSegment);
frs->direct = segment;
frs->reverseWaySearch = reverseWay;
SHARED_PTR<RouteSegment> op = SHARED_PTR<RouteSegment>(new RouteSegment(segment->road, segmentEnd));
op->parentRoute = opposite;
op->parentSegmentEnd = next->getSegmentStart();
frs->opposite = op;
frs->distanceFromStart = opposite->distanceFromStart + segment->distanceFromStart;
ctx->finalRouteSegment = frs;
return true;
}
}
@ -588,14 +465,8 @@ bool processIntersections(RoutingContext* ctx, SEGMENTS_QUEUE& graphSegments,
|| roadPriorityComparator(next->distanceFromStart, next->distanceToEnd, distFromStart, distanceToEnd,
ctx->getHeuristicCoefficient()) > 0) {
if (next->parentRoute.get() != NULL) {
// already in queue remove it
// FIXME remove
// if (!graphSegments.remove(next))
{
// exist in different queue!
RouteSegment* cpy = new RouteSegment(next->road, next->segmentStart);
next = SHARED_PTR<RouteSegment>(cpy);
}
// already in queue remove it (we can not remove it)
next = SHARED_PTR<RouteSegment>(new RouteSegment(next->road, next->segmentStart));
}
next->distanceFromStart = distFromStart;
next->distanceToEnd = distanceToEnd;
@ -625,3 +496,99 @@ bool processIntersections(RoutingContext* ctx, SEGMENTS_QUEUE& graphSegments,
}
return false;
}
// FIXME
SHARED_PTR<RouteSegment> findRouteSegment(int px, int py, RoutingContext* ctx) {
return ctx->loadSegmentAround(px, py);
}
bool combineTwoSegmentResult(RouteSegmentResult& toAdd, RouteSegmentResult& previous,
bool reverse) {
bool ld = previous.endPointIndex > previous.startPointIndex;
bool rd = toAdd.endPointIndex > toAdd.startPointIndex;
if (rd == ld) {
if (toAdd.startPointIndex == previous.endPointIndex && !reverse) {
previous.endPointIndex = toAdd.endPointIndex;
return true;
} else if (toAdd.endPointIndex == previous.startPointIndex && reverse) {
previous.startPointIndex = toAdd.startPointIndex;
return true;
}
}
return false;
}
void addRouteSegmentToResult(vector<RouteSegmentResult>& result, RouteSegmentResult& res, bool reverse) {
if (res.endPointIndex != res.startPointIndex) {
if (result.size() > 0) {
RouteSegmentResult last = result[result.size() - 1];
if (last.object->id == res.object->id) {
if (combineTwoSegmentResult(res, last, reverse)) {
return;
}
}
}
result.push_back(res);
}
}
vector<RouteSegmentResult> convertFinalSegmentToResults(RoutingContext* ctx) {
vector<RouteSegmentResult> result;
if (ctx->finalRouteSegment.get() != NULL) {
osmand_log_print(LOG_INFO, "Routing calculated time distance %f", ctx->finalRouteSegment->distanceFromStart);
SHARED_PTR<FinalRouteSegment> finalSegment = ctx->finalRouteSegment;
// Get results from opposite direction roads
SHARED_PTR<RouteSegment> segment = finalSegment->reverseWaySearch ? finalSegment->direct : finalSegment->opposite->parentRoute;
int parentSegmentStart =
finalSegment->reverseWaySearch ?
finalSegment->opposite->getSegmentStart() : finalSegment->opposite->parentSegmentEnd;
while (segment.get() != NULL) {
RouteSegmentResult res(segment->road, parentSegmentStart, segment->getSegmentStart());
parentSegmentStart = segment->parentSegmentEnd;
segment = segment->parentRoute;
addRouteSegmentToResult(result, res, false);
}
// reverse it just to attach good direction roads
std::reverse(result.begin(), result.end());
segment = finalSegment->reverseWaySearch ? finalSegment->opposite->parentRoute : finalSegment->direct;
int parentSegmentEnd =
finalSegment->reverseWaySearch ?
finalSegment->opposite->parentSegmentEnd : finalSegment->opposite->getSegmentStart();
while (segment.get() != NULL) {
RouteSegmentResult res(segment->road, segment->getSegmentStart(), parentSegmentEnd);
parentSegmentEnd = segment->parentSegmentEnd;
segment = segment->parentRoute;
// happens in smart recalculation
addRouteSegmentToResult(result, res, true);
}
std::reverse(result.begin(), result.end());
}
return result;
}
vector<RouteSegmentResult> searchRouteInternal(RoutingContext* ctx, bool leftSideNavigation) {
SHARED_PTR<RouteSegment> start = findRouteSegment(ctx->startX, ctx->startY, ctx);
if(start.get() == NULL) {
osmand_log_print(LOG_WARN, "Start point was not found [Native]");
return vector<RouteSegmentResult>();
} else {
osmand_log_print(LOG_WARN, "Start point was found %lld [Native]", start->road->id);
}
SHARED_PTR<RouteSegment> end = findRouteSegment(ctx->endX, ctx->endY, ctx);
if(end.get() == NULL) {
osmand_log_print(LOG_WARN, "End point was not found [Native]");
return vector<RouteSegmentResult>();
} else {
osmand_log_print(LOG_WARN, "End point was found %lld [Native]", end->road->id);
}
searchRouteInternal(ctx, start, end, leftSideNavigation);
osmand_log_print(LOG_WARN, "[Native] Result timing (time to load %d, time to calc %d, loaded tiles %d) ", ctx->timeToLoad.getElapsedTime()
, ctx->timeToCalculate.getElapsedTime(), ctx->loadedTiles);
return convertFinalSegmentToResults(ctx);
}

View file

@ -3,4 +3,418 @@
#include "common.h"
#include "binaryRead.h"
static double measuredDist(int x1, int y1, int x2, int y2) {
return getDistance(get31LatitudeY(y1), get31LongitudeX(x1), get31LatitudeY(y2),
get31LongitudeX(x2));
}
struct RouteSegment {
public :
int segmentStart;
SHARED_PTR<RouteDataObject> road;
// needed to store intersection of routes
SHARED_PTR<RouteSegment> next;
// search context (needed for searching route)
// Initially it should be null (!) because it checks was it segment visited before
SHARED_PTR<RouteSegment> parentRoute;
int parentSegmentEnd;
// distance measured in time (seconds)
float distanceFromStart;
float distanceToEnd;
inline int getSegmentStart() {
return segmentStart;
}
RouteSegment(SHARED_PTR<RouteDataObject> road, int segmentStart) : road(road), segmentStart(segmentStart),
parentSegmentEnd(0), distanceFromStart(0), distanceToEnd(0),next(), parentRoute(){
}
~RouteSegment(){
}
};
struct RouteSegmentResult {
SHARED_PTR<RouteDataObject> object;
int startPointIndex;
int endPointIndex;
RouteSegmentResult(SHARED_PTR<RouteDataObject> object, int startPointIndex, int endPointIndex) :
object(object), startPointIndex(startPointIndex), endPointIndex (endPointIndex) {
}
};
struct FinalRouteSegment {
SHARED_PTR<RouteSegment> direct;
bool reverseWaySearch;
SHARED_PTR<RouteSegment> opposite;
float distanceFromStart;
};
const static int ZOOM_TO_LOAD_TILES = 16;
struct RoutingSubregionTile {
RouteSubregion subregion;
// make it without get/set for fast access
int access;
int loaded;
UNORDERED(map)<int64_t, SHARED_PTR<RouteSegment> > routes;
RoutingSubregionTile(RouteSubregion& sub) : access(0), loaded(0), subregion(sub) {
}
~RoutingSubregionTile(){
}
bool isLoaded(){
return loaded > 0;
}
void setLoaded(){
loaded++;
}
void add(SHARED_PTR<RouteDataObject> o) {
for (int i = 0; i < o->pointsX.size(); i++) {
uint64_t x31 = o->pointsX[i];
uint64_t y31 = o->pointsY[i];
uint64_t l = (((uint64_t) x31) << 31) + (uint64_t) y31;
SHARED_PTR<RouteSegment> segment = SHARED_PTR<RouteSegment>(new RouteSegment(o, i));
if (routes[l].get() == NULL) {
routes[l] = segment;
} else {
SHARED_PTR<RouteSegment> orig = routes[l];
int cnt = 0;
while (orig->next.get() != NULL) {
orig = orig->next;
cnt++;
}
orig->next = segment;
}
}
}
};
static int64_t calcRouteId(SHARED_PTR<RouteDataObject> o, int ind) {
return (o->id << 10) + ind;
}
// FIXME configuration methods
struct RoutingContext {
int visitedSegments;
int loadedTiles;
ElapsedTimer timeToLoad;
ElapsedTimer timeToCalculate;
int firstRoadDirection;
int64_t firstRoadId;
int startX;
int startY;
int endX;
int endY;
vector<SHARED_PTR<RouteSegment> > segmentsToVisitNotForbidden;
vector<SHARED_PTR<RouteSegment> > segmentsToVisitPrescripted;
SHARED_PTR<FinalRouteSegment> finalRouteSegment;
UNORDERED(map)<int64_t, SHARED_PTR<RoutingSubregionTile> > subregionTiles;
UNORDERED(map)<int64_t, std::vector<SHARED_PTR<RoutingSubregionTile> > > indexedSubregions;
RoutingContext() : finalRouteSegment(), firstRoadDirection(0), loadedTiles(0), visitedSegments(0){
}
bool acceptLine(SHARED_PTR<RouteDataObject> r) {
string v = getHighway(r);
if(v != "" && v != "cycleway" && v != "footway" && v != "steps"){
return true;
}
return false;
}
string getHighway(SHARED_PTR<RouteDataObject> r) {
std::vector<uint32_t>::iterator t = r->types.begin();
for(; t != r->types.end(); t++) {
tag_value type = r->region->decodingRules[*t];
if(type.first=="highway") {
return type.second;
}
}
return "";
}
void loadHeaderObjects(int64_t tileId) {
vector<SHARED_PTR<RoutingSubregionTile> > subregions = indexedSubregions[tileId];
for(int j = 0; j<subregions.size(); j++) {
if(!subregions[j]->isLoaded()) {
loadedTiles++;
subregions[j]->setLoaded();
SearchQuery q;
vector<RouteDataObject*> res;
searchRouteDataForSubRegion(&q, res, &subregions[j]->subregion);
vector<RouteDataObject*>::iterator i = res.begin();
for(;i!=res.end(); i++) {
if(*i != NULL) {
SHARED_PTR<RouteDataObject> o(*i);
if(acceptLine(o)) {
subregions[j]->add(o);
}
}
}
}
}
}
void loadHeaders(uint32_t xloc, uint32_t yloc) {
timeToLoad.start();
int z = ZOOM_TO_LOAD_TILES;
int tz = 31 - z;
int64_t tileId = (xloc << z) + yloc;
if (indexedSubregions.find(tileId) == indexedSubregions.end()) {
SearchQuery q((uint32_t) (xloc << tz),
(uint32_t) ((xloc + 1) << tz), (uint32_t) (yloc << tz), (uint32_t) ((yloc + 1) << tz));
std::vector<RouteSubregion> tempResult;
searchRouteSubregions(&q, tempResult);
std::vector<SHARED_PTR<RoutingSubregionTile> > collection;
for(int i=0; i<tempResult.size(); i++) {
RouteSubregion& rs = tempResult[i];
int64_t key = ((int64_t)rs.left << 31)+ rs.length;
if(subregionTiles.find(key) == subregionTiles.end()) {
subregionTiles[key] = SHARED_PTR<RoutingSubregionTile>(new RoutingSubregionTile(rs));
}
collection.push_back(subregionTiles[key]);
}
//osmand_log_print(LOG_INFO, "Native load %d %d (%d)", xloc, yloc, tempResult.size());
indexedSubregions[tileId] = collection;
}
loadHeaderObjects(tileId);
timeToLoad.pause();
}
// FIXME
SHARED_PTR<RouteSegment> loadSegmentAround(int x31, int y31) {
timeToLoad.start();
SHARED_PTR<RouteSegment> r;
float dist = -1;
int z = ZOOM_TO_LOAD_TILES;
uint32_t xloc = x31 >> (31 - z);
uint32_t yloc = y31 >> (31 - z);
uint64_t l = (((uint64_t) x31) << 31) + (uint64_t) y31;
int64_t tileId = (xloc << z) + yloc;
loadHeaders(xloc, yloc);
vector<SHARED_PTR<RoutingSubregionTile> > subregions = indexedSubregions[tileId];
for(int j = 0; j<subregions.size(); j++) {
if(subregions[j]->isLoaded()) {
UNORDERED(map)<int64_t, SHARED_PTR<RouteSegment> >::iterator s = subregions[j]->routes.begin();
while(s != subregions[j]->routes.end()) {
SHARED_PTR<RouteSegment> seg = s->second;
if(seg.get() != NULL) {
double d = measuredDist(x31, y31, seg->road->pointsX[seg->getSegmentStart()],
seg->road->pointsY[seg->getSegmentStart()]);
if(dist == -1 || d < dist) {
r = seg;
dist = d;
}
}
s++;
}
}
}
timeToLoad.pause();
return r;
}
// void searchRouteRegion(SearchQuery* q, std::vector<RouteDataObject*>& list, RoutingIndex* rs, RouteSubregion* sub)
SHARED_PTR<RouteSegment> loadRouteSegment(int x31, int y31) {
int z = ZOOM_TO_LOAD_TILES;
int64_t xloc = x31 >> (31 - z);
int64_t yloc = y31 >> (31 - z);
uint64_t l = (((uint64_t) x31) << 31) + (uint64_t) y31;
int64_t tileId = (xloc << z) + yloc;
loadHeaders(xloc, yloc);
vector<SHARED_PTR<RoutingSubregionTile> > subregions = indexedSubregions[tileId];
UNORDERED(map)<int64_t, SHARED_PTR<RouteDataObject> > excludeDuplications;
SHARED_PTR<RouteSegment> original;
for(int j = 0; j<subregions.size(); j++) {
if(subregions[j]->isLoaded()) {
SHARED_PTR<RouteSegment> segment = subregions[j]->routes[l];
subregions[j]->access++;
while (segment.get() != NULL) {
SHARED_PTR<RouteDataObject> ro = segment->road;
SHARED_PTR<RouteDataObject> toCmp = excludeDuplications[calcRouteId(ro, segment->getSegmentStart())];
if (toCmp.get() == NULL || toCmp->pointsX.size() < ro->pointsX.size()) {
excludeDuplications[calcRouteId(ro, segment->getSegmentStart())] = ro;
SHARED_PTR<RouteSegment> s = SHARED_PTR<RouteSegment>(new RouteSegment(ro, segment->getSegmentStart()));
s->next = original;
original = s;
}
segment = segment->next;
}
}
}
return original;
}
bool isInterrupted(){
return false;
}
float getHeuristicCoefficient(){
return 1;
}
bool planRouteIn2Directions() {
return getPlanRoadDirection() == 0;
}
int getPlanRoadDirection() {
return 1;
}
float defineSpeedPriority(SHARED_PTR<RouteDataObject> r) {
string v = getHighway(r);
if(v == "") {
return 1;
} else if(v == "motorway") {
return 1.2;
} else if(v == "motorway_link") {
return 1.2;
} else if(v == "trunk") {
return 1.2;
} else if(v == "trunk_link") {
return 1.2;
} else if(v == "primary") {
return 1.1;
} else if(v == "primary_link") {
return 1.1;
} else if(v == "secondary") {
return 1.05;
} else if(v == "secondary_link") {
return 1.05;
} else if(v == "tertiary") {
return 1;
} else if(v == "tertiary_link") {
return 1;
} else if(v == "unclassified") {
return 0.7;
} else if(v == "road") {
return 0.7;
} else if(v == "service") {
return 0.5;
} else if(v == "track") {
return 0.3;
} else if(v == "residential") {
return 0.5;
} else if(v == "living_street") {
return 0.5;
}
return 1;
}
float maxSpeed(SHARED_PTR<RouteDataObject> r) {
std::vector<uint32_t>::iterator t = r->types.begin();
for(; t != r->types.end(); t++) {
tag_value type = r->region->decodingRules[*t];
if(type.first=="maxspeed") {
std::string v = type.second;
int i = 0;
while(i < v.length() && v[i] >= '0' && v[i] <= '9') {
i++;
}
if(i > 0) {
float f = atoi(v.substr(0, i).c_str());
f /= 3.6; // km/h -> m/s
if(v.find("mph") != std::string::npos ) {
f *= 1.6;
}
return f;
}
return 0;
}
}
return 0;
}
float defineSpeed(SHARED_PTR<RouteDataObject> r) {
float speed = maxSpeed(r);
if(speed > 0) {
return speed;
}
string v = getHighway(r);
if(v == "") {
} else if(v == "motorway") {
speed = 110;
} else if(v == "motorway_link") {
speed = 80;
} else if(v == "trunk") {
speed = 100;
} else if(v == "trunk_link") {
speed = 75;
} else if(v == "primary") {
speed = 65;
} else if(v == "primary_link") {
speed = 50;
} else if(v == "secondary") {
speed = 60;
} else if(v == "secondary_link") {
speed = 50;
} else if(v == "tertiary") {
speed = 45;
} else if(v == "tertiary_link") {
speed = 40;
} else if(v == "unclassified") {
speed = 35;
} else if(v == "road") {
speed = 35;
} else if(v == "service") {
speed = 30;
} else if(v == "track") {
speed = 15;
} else if(v == "residential") {
speed = 35;
} else if(v == "living_street") {
speed = 25;
}
return speed / 3.;
}
float getMinDefaultSpeed(){
return 40 / 3.6;
}
float getMaxDefaultSpeed(){
return 130 / 3.6;
}
int isOneWay(SHARED_PTR<RouteDataObject> r) {
std::vector<uint32_t>::iterator t = r->types.begin();
for(; t != r->types.end(); t++){
tag_value type = r->region->decodingRules[*t];
if(type.first == "oneway") {
string v = type.second;
if("-1" ==v || "reverse" == v) {
return -1;
} else if("1" == v || "yes" == v) {
return 1;
}
}
}
return 0;
}
float calculateTurnTime(SHARED_PTR<RouteSegment> segment, int index, SHARED_PTR<RouteSegment> next, int nextIndex){
return 0;
}
float defineRoutingObstacle(SHARED_PTR<RouteDataObject> road, int segmentEnd) {
return 0;
}
bool restrictionsAware(){
return true;
}
};
vector<RouteSegmentResult> searchRouteInternal(RoutingContext* ctx, bool leftSideNavigation);
#endif /*_OSMAND_BINARY_ROUTE_PLANNER_H*/

View file

@ -79,7 +79,7 @@ void ElapsedTimer::start()
#elif defined(__APPLE__)
startInit = mach_absolute_time();
#else
clock_gettime(CLOCK_MONOTONIC, &startInit);
clock_gettime(CLOCK_REALTIME, &startInit);
#endif
}
run = true;
@ -91,7 +91,7 @@ void ElapsedTimer::pause()
return;
#if defined(_WIN32)
endInit = timeGetTime();
elapsedTime += (endInit - startInit) * 1e6;
elapsedTime += (endInit - startInit) * 1000;
#elif defined(__APPLE__)
endInit = mach_absolute_time();
uint64_t duration = endInit - startInit;
@ -99,11 +99,11 @@ void ElapsedTimer::pause()
duration /= machTimeInfo.denom;
elapsedTime += duration;
#else
clock_gettime(CLOCK_MONOTONIC, &endInit);
clock_gettime(CLOCK_REALTIME, &endInit);
int sec = endInit.tv_sec - startInit.tv_sec;
if (sec > 0)
elapsedTime += 1e9 * sec;
elapsedTime += endInit.tv_nsec - startInit.tv_nsec;
elapsedTime += 1000000 * sec;
elapsedTime += (endInit.tv_nsec - startInit.tv_nsec) / 1000;
#endif
run = false;
}
@ -111,7 +111,7 @@ void ElapsedTimer::pause()
int ElapsedTimer::getElapsedTime()
{
pause();
return elapsedTime / 1e6;
return elapsedTime / 1000;
}
SkBitmap* RenderingContext::getCachedBitmap(const std::string& bitmapResource) {

View file

@ -11,6 +11,7 @@
#include "java_wrap.h"
#include "binaryRead.h"
#include "rendering.h"
#include "binaryRoutePlanner.h"
JavaVM* globalJVM = NULL;
@ -410,8 +411,17 @@ jfieldID jfield_RouteSubregion_bottom = NULL;
jfieldID jfield_RouteSubregion_shiftToData = NULL;
jclass jclass_RouteSegmentResult = NULL;
jmethodID jmethod_RouteSegmentResult_ctor = NULL;
void loadJniRenderingContext(JNIEnv* env)
{
jclass_RouteSegmentResult = findClass(env, "net/osmand/router/RouteSegmentResult");
jmethod_RouteSegmentResult_ctor = env->GetMethodID(jclass_RouteSegmentResult,
"<init>", "(Lnet/osmand/binary/RouteDataObject;II)V");
jclass_RenderingContext = findClass(env, "net/osmand/RenderingContext");
jfield_RenderingContext_interrupted = getFid(env, jclass_RenderingContext, "interrupted", "Z");
jfield_RenderingContext_leftX = getFid(env, jclass_RenderingContext, "leftX", "F" );
@ -570,7 +580,31 @@ extern "C" JNIEXPORT void JNICALL Java_net_osmand_NativeLibrary_deleteRouteSearc
}
delete t;
}
extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_testRouting(JNIEnv* ienv,
jobject obj, jint sx31,
jint sy31, jint ex31, jint ey31) {
RoutingContext c;
c.startX = sx31;
c.startY = sy31;
c.endX = ex31;
c.endY = ey31;
vector<RouteSegmentResult> r = searchRouteInternal(&c, false);
jobjectArray res = ienv->NewObjectArray(r.size(), jclass_RouteSegmentResult, NULL);
for (int i = 0; i < r.size(); i++) {
jobject robj = convertRouteDataObjectToJava(ienv, r[i].object.get(), NULL);
jobject resobj = ienv->NewObject(jclass_RouteSegmentResult, jmethod_RouteSegmentResult_ctor, robj,
r[i].startPointIndex, r[i].endPointIndex);
ienv->SetObjectArrayElement(res, i, resobj);
ienv->DeleteLocalRef(robj);
ienv->DeleteLocalRef(resobj);
}
if (r.size() == 0) {
osmand_log_print(LOG_INFO, "No route found");
}
fflush(stdout);
return res;
}
// protected static native RouteDataObject[] getRouteDataObjects(NativeRouteSearchResult rs, int x31, int y31!);
extern "C" JNIEXPORT jobjectArray JNICALL Java_net_osmand_NativeLibrary_getRouteDataObjects(JNIEnv* ienv,
@ -596,7 +630,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_NativeLibrary_loadRoutingDa
RoutingIndex ind;
ind.filePointer = regFilePointer;
ind.name = getString(ienv, regName);
RouteSubregion sub;
RouteSubregion sub(&ind);
sub.filePointer = ienv->GetIntField(subreg, jfield_RouteSubregion_filePointer);
sub.length = ienv->GetIntField(subreg, jfield_RouteSubregion_length);
sub.left = ienv->GetIntField(subreg, jfield_RouteSubregion_left);
@ -606,7 +640,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_net_osmand_NativeLibrary_loadRoutingDa
sub.mapDataBlock= ienv->GetIntField(subreg, jfield_RouteSubregion_shiftToData);
std::vector<RouteDataObject*> result;
SearchQuery q;
searchRouteDataForSubRegion(&q, result, &ind, &sub);
searchRouteDataForSubRegion(&q, result, &sub);
if (loadObjects) {