PageRenderTime 28ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/DataExtractionOSM/src/net/osmand/binary/BinaryMapTransportReaderAdapter.java

https://code.google.com/
Java | 481 lines | 434 code | 41 blank | 6 comment | 63 complexity | 57066eaf510326f046dd1d16e297a13c MD5 | raw file
Possible License(s): MIT
  1. package net.osmand.binary;
  2. import static net.osmand.binary.BinaryMapIndexReader.TRANSPORT_STOP_ZOOM;
  3. import gnu.trove.list.array.TIntArrayList;
  4. import gnu.trove.map.hash.TIntObjectHashMap;
  5. import java.io.IOException;
  6. import java.util.Arrays;
  7. import java.util.List;
  8. import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
  9. import net.osmand.data.TransportStop;
  10. import net.osmand.osm.MapUtils;
  11. import net.sf.junidecode.Junidecode;
  12. import com.google.protobuf.CodedInputStreamRAF;
  13. import com.google.protobuf.WireFormat;
  14. public class BinaryMapTransportReaderAdapter {
  15. private CodedInputStreamRAF codedIS;
  16. private final BinaryMapIndexReader map;
  17. protected BinaryMapTransportReaderAdapter(BinaryMapIndexReader map){
  18. this.codedIS = map.codedIS;
  19. this.map = map;
  20. }
  21. private void skipUnknownField(int t) throws IOException {
  22. map.skipUnknownField(t);
  23. }
  24. private int readInt() throws IOException {
  25. return map.readInt();
  26. }
  27. public static class TransportIndex extends BinaryIndexPart {
  28. int left = 0;
  29. int right = 0;
  30. int top = 0;
  31. int bottom = 0;
  32. int stopsFileOffset = 0;
  33. int stopsFileLength = 0;
  34. public int getLeft() {
  35. return left;
  36. }
  37. public int getRight() {
  38. return right;
  39. }
  40. public int getTop() {
  41. return top;
  42. }
  43. public int getBottom() {
  44. return bottom;
  45. }
  46. IndexStringTable stringTable = null;
  47. }
  48. protected static class IndexStringTable {
  49. int fileOffset = 0;
  50. int length = 0;
  51. // offset from start for each SIZE_OFFSET_ARRAY elements
  52. // (SIZE_OFFSET_ARRAY + 1) offset = offsets[0] + skipOneString()
  53. TIntArrayList offsets = new TIntArrayList();
  54. }
  55. protected void readTransportIndex(TransportIndex ind) throws IOException {
  56. while(true){
  57. int t = codedIS.readTag();
  58. int tag = WireFormat.getTagFieldNumber(t);
  59. switch (tag) {
  60. case 0:
  61. return;
  62. case OsmandOdb.OsmAndTransportIndex.ROUTES_FIELD_NUMBER :
  63. skipUnknownField(t);
  64. break;
  65. case OsmandOdb.OsmAndTransportIndex.NAME_FIELD_NUMBER :
  66. ind.setName(codedIS.readString());
  67. break;
  68. case OsmandOdb.OsmAndTransportIndex.STOPS_FIELD_NUMBER :
  69. ind.stopsFileLength = readInt();
  70. ind.stopsFileOffset = codedIS.getTotalBytesRead();
  71. int old = codedIS.pushLimit(ind.stopsFileLength);
  72. readTransportBounds(ind);
  73. codedIS.popLimit(old);
  74. break;
  75. case OsmandOdb.OsmAndTransportIndex.STRINGTABLE_FIELD_NUMBER :
  76. IndexStringTable st = new IndexStringTable();
  77. st.length = codedIS.readRawVarint32();
  78. st.fileOffset = codedIS.getTotalBytesRead();
  79. // Do not cache for now save memory
  80. // readStringTable(st, 0, 20, true);
  81. ind.stringTable = st;
  82. codedIS.seek(st.length + st.fileOffset);
  83. break;
  84. default:
  85. skipUnknownField(t);
  86. break;
  87. }
  88. }
  89. }
  90. private void readTransportBounds(TransportIndex ind) throws IOException {
  91. while(true){
  92. int t = codedIS.readTag();
  93. int tag = WireFormat.getTagFieldNumber(t);
  94. switch (tag) {
  95. case 0:
  96. return;
  97. case OsmandOdb.TransportStopsTree.LEFT_FIELD_NUMBER :
  98. ind.left = codedIS.readSInt32();
  99. break;
  100. case OsmandOdb.TransportStopsTree.RIGHT_FIELD_NUMBER :
  101. ind.right = codedIS.readSInt32();
  102. break;
  103. case OsmandOdb.TransportStopsTree.TOP_FIELD_NUMBER :
  104. ind.top = codedIS.readSInt32();
  105. break;
  106. case OsmandOdb.TransportStopsTree.BOTTOM_FIELD_NUMBER :
  107. ind.bottom = codedIS.readSInt32();
  108. break;
  109. default:
  110. skipUnknownField(t);
  111. break;
  112. }
  113. }
  114. }
  115. protected void searchTransportTreeBounds(int pleft, int pright, int ptop, int pbottom,
  116. SearchRequest<TransportStop> req) throws IOException {
  117. int init = 0;
  118. int lastIndexResult = -1;
  119. int cright = 0;
  120. int cleft = 0;
  121. int ctop = 0;
  122. int cbottom = 0;
  123. req.numberOfReadSubtrees++;
  124. while(true){
  125. if(req.isCancelled()){
  126. return;
  127. }
  128. int t = codedIS.readTag();
  129. int tag = WireFormat.getTagFieldNumber(t);
  130. if(init == 0xf){
  131. // coordinates are init
  132. init = 0;
  133. if(cright < req.left || cleft > req.right || ctop > req.bottom || cbottom < req.top){
  134. return;
  135. } else {
  136. req.numberOfAcceptedSubtrees++;
  137. }
  138. }
  139. switch (tag) {
  140. case 0:
  141. return;
  142. case OsmandOdb.TransportStopsTree.BOTTOM_FIELD_NUMBER :
  143. cbottom = codedIS.readSInt32() + pbottom;
  144. init |= 1;
  145. break;
  146. case OsmandOdb.TransportStopsTree.LEFT_FIELD_NUMBER :
  147. cleft = codedIS.readSInt32() + pleft;
  148. init |= 2;
  149. break;
  150. case OsmandOdb.TransportStopsTree.RIGHT_FIELD_NUMBER :
  151. cright = codedIS.readSInt32() + pright;
  152. init |= 4;
  153. break;
  154. case OsmandOdb.TransportStopsTree.TOP_FIELD_NUMBER :
  155. ctop = codedIS.readSInt32() + ptop;
  156. init |= 8;
  157. break;
  158. case OsmandOdb.TransportStopsTree.LEAFS_FIELD_NUMBER :
  159. int stopOffset = codedIS.getTotalBytesRead();
  160. int length = codedIS.readRawVarint32();
  161. int oldLimit = codedIS.pushLimit(length);
  162. if(lastIndexResult == -1){
  163. lastIndexResult = req.getSearchResults().size();
  164. }
  165. req.numberOfVisitedObjects++;
  166. TransportStop transportStop = readTransportStop(stopOffset, cleft, cright, ctop, cbottom, req);
  167. if(transportStop != null){
  168. req.publish(transportStop);
  169. }
  170. codedIS.popLimit(oldLimit);
  171. break;
  172. case OsmandOdb.TransportStopsTree.SUBTREES_FIELD_NUMBER :
  173. // left, ... already initialized
  174. length = readInt();
  175. int filePointer = codedIS.getTotalBytesRead();
  176. if (req.limit == -1 || req.limit >= req.getSearchResults().size()) {
  177. oldLimit = codedIS.pushLimit(length);
  178. searchTransportTreeBounds(cleft, cright, ctop, cbottom, req);
  179. codedIS.popLimit(oldLimit);
  180. }
  181. codedIS.seek(filePointer + length);
  182. if(lastIndexResult >= 0){
  183. throw new IllegalStateException();
  184. }
  185. break;
  186. case OsmandOdb.TransportStopsTree.BASEID_FIELD_NUMBER :
  187. long baseId = codedIS.readUInt64();
  188. if (lastIndexResult != -1) {
  189. for (int i = lastIndexResult; i < req.getSearchResults().size(); i++) {
  190. TransportStop rs = req.getSearchResults().get(i);
  191. rs.setId(rs.getId() + baseId);
  192. }
  193. }
  194. break;
  195. default:
  196. skipUnknownField(t);
  197. break;
  198. }
  199. }
  200. }
  201. private String regStr(TIntObjectHashMap<String> stringTable) throws IOException{
  202. int i = codedIS.readUInt32();
  203. stringTable.putIfAbsent(i, "");
  204. return ((char) i)+"";
  205. }
  206. public net.osmand.data.TransportRoute getTransportRoute(int filePointer, TIntObjectHashMap<String> stringTable,
  207. boolean onlyDescription) throws IOException {
  208. codedIS.seek(filePointer);
  209. int routeLength = codedIS.readRawVarint32();
  210. int old = codedIS.pushLimit(routeLength);
  211. net.osmand.data.TransportRoute dataObject = new net.osmand.data.TransportRoute();
  212. boolean end = false;
  213. long rid = 0;
  214. int rx = 0;
  215. int ry = 0;
  216. long did = 0;
  217. int dx = 0;
  218. int dy = 0;
  219. while(!end){
  220. int t = codedIS.readTag();
  221. int tag = WireFormat.getTagFieldNumber(t);
  222. switch (tag) {
  223. case 0:
  224. end = true;
  225. break;
  226. case OsmandOdb.TransportRoute.DISTANCE_FIELD_NUMBER :
  227. dataObject.setDistance(codedIS.readUInt32());
  228. break;
  229. case OsmandOdb.TransportRoute.ID_FIELD_NUMBER :
  230. dataObject.setId(codedIS.readUInt64());
  231. break;
  232. case OsmandOdb.TransportRoute.REF_FIELD_NUMBER :
  233. dataObject.setRef(codedIS.readString());
  234. break;
  235. case OsmandOdb.TransportRoute.TYPE_FIELD_NUMBER :
  236. dataObject.setType(regStr(stringTable)); //$NON-NLS-1$
  237. break;
  238. case OsmandOdb.TransportRoute.NAME_EN_FIELD_NUMBER :
  239. dataObject.setEnName(regStr(stringTable)); //$NON-NLS-1$
  240. break;
  241. case OsmandOdb.TransportRoute.NAME_FIELD_NUMBER :
  242. dataObject.setName(regStr(stringTable)); //$NON-NLS-1$
  243. break;
  244. case OsmandOdb.TransportRoute.OPERATOR_FIELD_NUMBER:
  245. dataObject.setOperator(regStr(stringTable)); //$NON-NLS-1$
  246. break;
  247. case OsmandOdb.TransportRoute.REVERSESTOPS_FIELD_NUMBER:
  248. if(onlyDescription){
  249. end = true;
  250. codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
  251. break;
  252. }
  253. int length = codedIS.readRawVarint32();
  254. int olds = codedIS.pushLimit(length);
  255. TransportStop stop = readTransportRouteStop(dx, dy, did, stringTable);
  256. dataObject.getBackwardStops().add(stop);
  257. did = stop.getId();
  258. dx = (int) MapUtils.getTileNumberX(TRANSPORT_STOP_ZOOM, stop.getLocation().getLongitude());
  259. dy = (int) MapUtils.getTileNumberY(TRANSPORT_STOP_ZOOM, stop.getLocation().getLatitude());
  260. codedIS.popLimit(olds);
  261. break;
  262. case OsmandOdb.TransportRoute.DIRECTSTOPS_FIELD_NUMBER:
  263. if(onlyDescription){
  264. end = true;
  265. codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
  266. break;
  267. }
  268. length = codedIS.readRawVarint32();
  269. olds = codedIS.pushLimit(length);
  270. stop = readTransportRouteStop(rx, ry, rid, stringTable);
  271. dataObject.getForwardStops().add(stop);
  272. rid = stop.getId();
  273. rx = (int) MapUtils.getTileNumberX(TRANSPORT_STOP_ZOOM, stop.getLocation().getLongitude());
  274. ry = (int) MapUtils.getTileNumberY(TRANSPORT_STOP_ZOOM, stop.getLocation().getLatitude());
  275. codedIS.popLimit(olds);
  276. break;
  277. default:
  278. skipUnknownField(t);
  279. break;
  280. }
  281. }
  282. codedIS.popLimit(old);
  283. return dataObject;
  284. }
  285. protected void initializeStringTable(TransportIndex ind, TIntObjectHashMap<String> stringTable) throws IOException {
  286. int[] values = stringTable.keys();
  287. Arrays.sort(values);
  288. codedIS.seek(ind.stringTable.fileOffset);
  289. int oldLimit = codedIS.pushLimit(ind.stringTable.length);
  290. int current = 0;
  291. int i = 0;
  292. while (i < values.length) {
  293. int t = codedIS.readTag();
  294. int tag = WireFormat.getTagFieldNumber(t);
  295. switch (tag) {
  296. case 0:
  297. break;
  298. case OsmandOdb.StringTable.S_FIELD_NUMBER:
  299. if (current == values[i]) {
  300. String value = codedIS.readString();
  301. stringTable.put(values[i], value);
  302. i++;
  303. } else {
  304. skipUnknownField(t);
  305. }
  306. current ++;
  307. break;
  308. default:
  309. skipUnknownField(t);
  310. break;
  311. }
  312. }
  313. codedIS.popLimit(oldLimit);
  314. }
  315. protected void initializeNames(boolean onlyDescription, net.osmand.data.TransportRoute dataObject,
  316. TIntObjectHashMap<String> stringTable) throws IOException {
  317. if(dataObject.getName().length() > 0){
  318. dataObject.setName(stringTable.get(dataObject.getName().charAt(0)));
  319. }
  320. if(dataObject.getEnName().length() > 0){
  321. dataObject.setEnName(stringTable.get(dataObject.getEnName().charAt(0)));
  322. }
  323. if(dataObject.getName().length() > 0 && dataObject.getEnName().length() == 0){
  324. dataObject.setEnName(Junidecode.unidecode(dataObject.getName()));
  325. }
  326. if(dataObject.getOperator().length() > 0){
  327. dataObject.setOperator(stringTable.get(dataObject.getOperator().charAt(0)));
  328. }
  329. if(dataObject.getType().length() > 0){
  330. dataObject.setType(stringTable.get(dataObject.getType().charAt(0)));
  331. }
  332. for (int i = 0; i < 2 && !onlyDescription; i++) {
  333. List<TransportStop> stops = i == 0 ? dataObject.getForwardStops() : dataObject.getBackwardStops();
  334. for (TransportStop s : stops) {
  335. initializeNames(stringTable, s);
  336. }
  337. }
  338. }
  339. protected void initializeNames(TIntObjectHashMap<String> stringTable, TransportStop s) {
  340. if (s.getName().length() > 0) {
  341. s.setName(stringTable.get(s.getName().charAt(0)));
  342. }
  343. if (s.getEnName().length() > 0) {
  344. s.setEnName(stringTable.get(s.getEnName().charAt(0)));
  345. }
  346. if (s.getEnName().length() == 0) {
  347. s.setEnName(Junidecode.unidecode(s.getName()));
  348. }
  349. }
  350. private TransportStop readTransportRouteStop(int dx, int dy, long did, TIntObjectHashMap<String> stringTable) throws IOException {
  351. TransportStop dataObject = new TransportStop();
  352. boolean end = false;
  353. while(!end){
  354. int t = codedIS.readTag();
  355. int tag = WireFormat.getTagFieldNumber(t);
  356. switch (tag) {
  357. case 0:
  358. end = true;
  359. break;
  360. case OsmandOdb.TransportRouteStop.NAME_EN_FIELD_NUMBER :
  361. dataObject.setEnName(regStr(stringTable)); //$NON-NLS-1$
  362. break;
  363. case OsmandOdb.TransportRouteStop.NAME_FIELD_NUMBER :
  364. dataObject.setName(regStr(stringTable)); //$NON-NLS-1$
  365. break;
  366. case OsmandOdb.TransportRouteStop.ID_FIELD_NUMBER :
  367. did += codedIS.readSInt64();
  368. break;
  369. case OsmandOdb.TransportRouteStop.DX_FIELD_NUMBER :
  370. dx += codedIS.readSInt32();
  371. break;
  372. case OsmandOdb.TransportRouteStop.DY_FIELD_NUMBER :
  373. dy += codedIS.readSInt32();
  374. break;
  375. default:
  376. skipUnknownField(t);
  377. break;
  378. }
  379. }
  380. dataObject.setId(did);
  381. dataObject.setLocation(MapUtils.getLatitudeFromTile(TRANSPORT_STOP_ZOOM, dy), MapUtils.getLongitudeFromTile(TRANSPORT_STOP_ZOOM, dx));
  382. return dataObject;
  383. }
  384. private TransportStop readTransportStop(int shift, int cleft, int cright, int ctop, int cbottom, SearchRequest<TransportStop> req) throws IOException {
  385. int tag = WireFormat.getTagFieldNumber(codedIS.readTag());
  386. if(OsmandOdb.TransportStop.DX_FIELD_NUMBER != tag) {
  387. throw new IllegalArgumentException();
  388. }
  389. int x = codedIS.readSInt32() + cleft;
  390. tag = WireFormat.getTagFieldNumber(codedIS.readTag());
  391. if(OsmandOdb.TransportStop.DY_FIELD_NUMBER != tag) {
  392. throw new IllegalArgumentException();
  393. }
  394. int y = codedIS.readSInt32() + ctop;
  395. if(req.right < x || req.left > x || req.top > y || req.bottom < y){
  396. codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
  397. return null;
  398. }
  399. req.numberOfAcceptedObjects++;
  400. req.cacheTypes.clear();
  401. TransportStop dataObject = new TransportStop();
  402. dataObject.setLocation(MapUtils.getLatitudeFromTile(TRANSPORT_STOP_ZOOM, y), MapUtils.getLongitudeFromTile(TRANSPORT_STOP_ZOOM, x));
  403. dataObject.setFileOffset(shift);
  404. while(true){
  405. int t = codedIS.readTag();
  406. tag = WireFormat.getTagFieldNumber(t);
  407. switch (tag) {
  408. case 0:
  409. dataObject.setReferencesToRoutes(req.cacheTypes.toArray());
  410. if(dataObject.getEnName().length() == 0){
  411. dataObject.setEnName(Junidecode.unidecode(dataObject.getName()));
  412. }
  413. return dataObject;
  414. case OsmandOdb.TransportStop.ROUTES_FIELD_NUMBER :
  415. req.cacheTypes.add(shift - codedIS.readUInt32());
  416. break;
  417. case OsmandOdb.TransportStop.NAME_EN_FIELD_NUMBER :
  418. if (req.stringTable != null) {
  419. dataObject.setEnName(regStr(req.stringTable)); //$NON-NLS-1$
  420. } else {
  421. skipUnknownField(t);
  422. }
  423. break;
  424. case OsmandOdb.TransportStop.NAME_FIELD_NUMBER :
  425. if (req.stringTable != null) {
  426. dataObject.setName(regStr(req.stringTable)); //$NON-NLS-1$
  427. } else {
  428. skipUnknownField(t);
  429. }
  430. break;
  431. case OsmandOdb.TransportStop.ID_FIELD_NUMBER :
  432. dataObject.setId(codedIS.readSInt64());
  433. break;
  434. default:
  435. skipUnknownField(t);
  436. break;
  437. }
  438. }
  439. }
  440. }