private void setTileClipping( QueryParameters queryParameters, long mCurrentRow, long mCurrentCol) { long numRows = queryParameters.toBlockY - queryParameters.fromBlockY; long numCols = queryParameters.toBlockX - queryParameters.fromBlockX; // log.debug(numCols + "/" + numRows + " " + mCurrentCol + " " + mCurrentRow); xmin = -16; ymin = -16; xmax = Tile.SIZE + 16; ymax = Tile.SIZE + 16; if (numRows > 0) { int w = (int) (Tile.SIZE / (numCols + 1)); int h = (int) (Tile.SIZE / (numRows + 1)); if (mCurrentCol > 0) xmin = (int) (mCurrentCol * w); if (mCurrentCol < numCols) xmax = (int) (mCurrentCol * w + w); if (mCurrentRow > 0) ymin = (int) (mCurrentRow * h); if (mCurrentRow < numRows) ymax = (int) (mCurrentRow * h + h); } mTileClipper.setRect(xmin, ymin, xmax, ymax); }
/** * Processes the given number of ways. * * @param queryParameters the parameters of the current query. * @param mapDataSink the callback which handles the extracted ways. * @param numberOfWays how many ways should be processed. * @return true if the ways could be processed successfully, false otherwise. */ private boolean processWays( QueryParameters queryParameters, ITileDataSink mapDataSink, int numberOfWays) { Tag[] wayTags = mTileSource.fileInfo.wayTags; MapElement e = mElem; int numTags = 0; int wayDataBlocks; // skip string block int stringsSize = 0; stringOffset = 0; if (mTileSource.experimental) { stringsSize = mReadBuffer.readUnsignedInt(); stringOffset = mReadBuffer.getBufferPosition(); mReadBuffer.skipBytes(stringsSize); } // setTileClipping(queryParameters); for (int elementCounter = numberOfWays; elementCounter != 0; --elementCounter) { if (mDebugFile) { // get and check the way signature mSignatureWay = mReadBuffer.readUTF8EncodedString(SIGNATURE_LENGTH_WAY); if (!mSignatureWay.startsWith("---WayStart")) { log.warn("invalid way signature: " + mSignatureWay); log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock); return false; } } if (queryParameters.useTileBitmask) { elementCounter = mReadBuffer.skipWays(queryParameters.queryTileBitmask, elementCounter); if (elementCounter == 0) return true; if (elementCounter < 0) return false; if (mTileSource.experimental && mReadBuffer.lastTagPosition > 0) { int pos = mReadBuffer.getBufferPosition(); mReadBuffer.setBufferPosition(mReadBuffer.lastTagPosition); byte numberOfTags = (byte) (mReadBuffer.readByte() & WAY_NUMBER_OF_TAGS_BITMASK); if (!mReadBuffer.readTags(e.tags, wayTags, numberOfTags)) return false; numTags = numberOfTags; mReadBuffer.setBufferPosition(pos); } } else { int wayDataSize = mReadBuffer.readUnsignedInt(); if (wayDataSize < 0) { log.warn("invalid way data size: " + wayDataSize); if (mDebugFile) { log.warn(DEBUG_SIGNATURE_BLOCK + mSignatureBlock); } log.error("BUG way 2"); return false; } /* ignore the way tile bitmask (2 bytes) */ mReadBuffer.skipBytes(2); } /* get the special byte which encodes multiple flags */ byte specialByte = mReadBuffer.readByte(); /* bit 1-4 represent the layer */ byte layer = (byte) ((specialByte & WAY_LAYER_BITMASK) >>> WAY_LAYER_SHIFT); /* bit 5-8 represent the number of tag IDs */ byte numberOfTags = (byte) (specialByte & WAY_NUMBER_OF_TAGS_BITMASK); if (numberOfTags != 0) { if (!mReadBuffer.readTags(e.tags, wayTags, numberOfTags)) return false; numTags = numberOfTags; } /* get the feature bitmask (1 byte) */ byte featureByte = mReadBuffer.readByte(); /* bit 1-6 enable optional features */ boolean featureWayDoubleDeltaEncoding = (featureByte & WAY_FEATURE_DOUBLE_DELTA_ENCODING) != 0; boolean hasName = (featureByte & WAY_FEATURE_NAME) != 0; boolean hasHouseNr = (featureByte & WAY_FEATURE_HOUSE_NUMBER) != 0; boolean hasRef = (featureByte & WAY_FEATURE_REF) != 0; e.tags.numTags = numTags; if (mTileSource.experimental) { if (hasName) { int textPos = mReadBuffer.readUnsignedInt(); String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos); e.tags.add(new Tag(Tag.KEY_NAME, str, false)); } if (hasHouseNr) { int textPos = mReadBuffer.readUnsignedInt(); String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos); e.tags.add(new Tag(Tag.KEY_HOUSE_NUMBER, str, false)); } if (hasRef) { int textPos = mReadBuffer.readUnsignedInt(); String str = mReadBuffer.readUTF8EncodedStringAt(stringOffset + textPos); e.tags.add(new Tag(Tag.KEY_REF, str, false)); } } else { if (hasName) { String str = mReadBuffer.readUTF8EncodedString(); e.tags.add(new Tag(Tag.KEY_NAME, str, false)); } if (hasHouseNr) { String str = mReadBuffer.readUTF8EncodedString(); e.tags.add(new Tag(Tag.KEY_HOUSE_NUMBER, str, false)); } if (hasRef) { String str = mReadBuffer.readUTF8EncodedString(); e.tags.add(new Tag(Tag.KEY_REF, str, false)); } } if ((featureByte & WAY_FEATURE_LABEL_POSITION) != 0) // labelPosition = readOptionalLabelPosition(); if ((featureByte & WAY_FEATURE_DATA_BLOCKS_BYTE) != 0) { wayDataBlocks = mReadBuffer.readUnsignedInt(); if (wayDataBlocks < 1) { log.warn("invalid number of way data blocks: " + wayDataBlocks); logDebugSignatures(); return false; } } else { wayDataBlocks = 1; } /* some guessing if feature is a line or a polygon */ boolean linearFeature = e.tags.containsKey("highway") || e.tags.containsKey("boundary") || e.tags.containsKey("railway"); if (linearFeature) { Tag areaTag = e.tags.get("area"); if (areaTag != null && areaTag.value == Tag.VALUE_YES) linearFeature = false; } for (int wayDataBlock = 0; wayDataBlock < wayDataBlocks; wayDataBlock++) { e.clear(); if (!processWayDataBlock(e, featureWayDoubleDeltaEncoding, linearFeature)) return false; /* drop invalid outer ring */ if (e.isPoly() && e.index[0] < 6) { continue; } mTileProjection.project(e); if (!e.tags.containsKey("building")) if (!mTileClipper.clip(e)) { continue; } e.simplify(1, true); e.setLayer(layer); mapDataSink.process(e); } } return true; }