void OsmAnd::ObfMapSectionReader_P::readTreeNodeChildren( const std::unique_ptr<ObfReader_P>& reader, const std::shared_ptr<const ObfMapSectionInfo>& section, const std::shared_ptr<ObfMapSectionLevelTreeNode>& treeNode, MapFoundationType& foundation, QList< std::shared_ptr<ObfMapSectionLevelTreeNode> >* nodesWithData, const AreaI* bbox31, IQueryController* controller) { auto cis = reader->_codedInputStream.get(); for(;;) { auto tag = cis->ReadTag(); switch(gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: return; case OBF::OsmAndMapIndex_MapDataBox::kBoxesFieldNumber: { auto length = ObfReaderUtilities::readBigEndianInt(cis); auto offset = cis->CurrentPosition(); auto oldLimit = cis->PushLimit(length); std::shared_ptr<ObfMapSectionLevelTreeNode> childNode(new ObfMapSectionLevelTreeNode()); childNode->_foundation = treeNode->_foundation; childNode->_offset = offset; childNode->_length = length; readTreeNode(reader, section, treeNode->_area31, childNode); if(bbox31 && !bbox31->intersects(childNode->_area31)) { cis->Skip(cis->BytesUntilLimit()); cis->PopLimit(oldLimit); break; } cis->PopLimit(oldLimit); if(childNode->_foundation != MapFoundationType::Undefined) { if(foundation == MapFoundationType::Undefined) foundation = childNode->_foundation; else if(foundation != childNode->_foundation) foundation = MapFoundationType::Mixed; } if(nodesWithData && childNode->_dataOffset > 0) nodesWithData->push_back(childNode); cis->Seek(offset); oldLimit = cis->PushLimit(length); cis->Skip(childNode->_childrenInnerOffset); readTreeNodeChildren(reader, section, childNode, foundation, nodesWithData, bbox31, controller); assert(cis->BytesUntilLimit() == 0); cis->PopLimit(oldLimit); } break; default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } } }
treeObj *msReadTree(const TCHAR *filename, int debug) { treeObj *tree=NULL; SHPTreeHandle disktree; disktree = msSHPDiskTreeOpen( filename, debug ); if(!disktree) { #if MAPSHAPEERROR msSetError(MS_IOERR, NULL, "msReadTree()"); #endif return(NULL); } tree = (treeObj *) malloc(sizeof(treeObj)); if(!tree) { #if MAPSHAPEERROR msSetError(MS_MEMERR, NULL, "msReadTree()"); #endif return(NULL); } tree->numshapes = disktree->nShapes; tree->maxdepth = disktree->nDepth; tree->root = readTreeNode( disktree ); return(tree); }
void OsmAnd::ObfMapSectionReader_P::readMapLevelTreeNodes( const ObfReader_P& reader, const std::shared_ptr<const ObfMapSectionInfo>& section, const std::shared_ptr<const ObfMapSectionLevel>& level, QList< std::shared_ptr<const ObfMapSectionLevelTreeNode> >& trees) { const auto cis = reader.getCodedInputStream().get(); bool atLeastOneMapRootLevelRead = false; for (;;) { gpb::uint32 tag = cis->ReadTag(); switch (gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: if (!ObfReaderUtilities::reachedDataEnd(cis)) return; return; case OBF::OsmAndMapIndex_MapRootLevel::kBoxesFieldNumber: { const auto length = ObfReaderUtilities::readBigEndianInt(cis); const auto offset = cis->CurrentPosition(); const auto oldLimit = cis->PushLimit(length); const std::shared_ptr<ObfMapSectionLevelTreeNode> levelTree(new ObfMapSectionLevelTreeNode(level)); levelTree->offset = offset; levelTree->length = length; readTreeNode(reader, section, level->area31, levelTree); ObfReaderUtilities::ensureAllDataWasRead(cis); cis->PopLimit(oldLimit); trees.push_back(qMove(levelTree)); atLeastOneMapRootLevelRead = true; break; } default: if (atLeastOneMapRootLevelRead) return; ObfReaderUtilities::skipUnknownField(cis, tag); break; } } }
treeObj *msReadTree(char *filename, int debug) { treeObj *tree=NULL; SHPTreeHandle disktree; disktree = msSHPDiskTreeOpen( filename, debug ); if(!disktree) { msSetError(MS_IOERR, NULL, "msReadTree()"); return(NULL); } tree = (treeObj *) malloc(sizeof(treeObj)); MS_CHECK_ALLOC(tree, sizeof(treeObj), NULL); tree->numshapes = disktree->nShapes; tree->maxdepth = disktree->nDepth; tree->root = readTreeNode( disktree ); return(tree); }
void OsmAnd::ObfMapSectionReader_P::readMapLevelTreeNodes( const std::unique_ptr<ObfReader_P>& reader, const std::shared_ptr<const ObfMapSectionInfo>& section, const std::shared_ptr<const ObfMapSectionLevel>& level, QList< std::shared_ptr<ObfMapSectionLevelTreeNode> >& trees ) { auto cis = reader->_codedInputStream.get(); for(;;) { gpb::uint32 tag = cis->ReadTag(); switch(gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: return; case OBF::OsmAndMapIndex_MapRootLevel::kBoxesFieldNumber: { const auto length = ObfReaderUtilities::readBigEndianInt(cis); const auto offset = cis->CurrentPosition(); const auto oldLimit = cis->PushLimit(length); std::shared_ptr<ObfMapSectionLevelTreeNode> levelTree(new ObfMapSectionLevelTreeNode(level)); levelTree->_offset = offset; levelTree->_length = length; readTreeNode(reader, section, level->area31, levelTree); cis->PopLimit(oldLimit); trees.push_back(qMove(levelTree)); } break; case OBF::OsmAndMapIndex_MapRootLevel::kBlocksFieldNumber: cis->Skip(cis->BytesUntilLimit()); return; default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } } }
void OsmAnd::ObfMapSectionReader_P::readTreeNodeChildren( const ObfReader_P& reader, const std::shared_ptr<const ObfMapSectionInfo>& section, const std::shared_ptr<const ObfMapSectionLevelTreeNode>& treeNode, MapSurfaceType& outChildrenSurfaceType, QList< std::shared_ptr<const ObfMapSectionLevelTreeNode> >* nodesWithData, const AreaI* bbox31, const std::shared_ptr<const IQueryController>& queryController, ObfMapSectionReader_Metrics::Metric_loadMapObjects* const metric) { const auto cis = reader.getCodedInputStream().get(); outChildrenSurfaceType = MapSurfaceType::Undefined; for (;;) { const auto tag = cis->ReadTag(); switch (gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: if (!ObfReaderUtilities::reachedDataEnd(cis)) return; return; case OBF::OsmAndMapIndex_MapDataBox::kBoxesFieldNumber: { const auto length = ObfReaderUtilities::readBigEndianInt(cis); const auto offset = cis->CurrentPosition(); const auto oldLimit = cis->PushLimit(length); const std::shared_ptr<ObfMapSectionLevelTreeNode> childNode(new ObfMapSectionLevelTreeNode(treeNode->level)); childNode->surfaceType = treeNode->surfaceType; childNode->offset = offset; childNode->length = length; readTreeNode(reader, section, treeNode->area31, childNode); ObfReaderUtilities::ensureAllDataWasRead(cis); cis->PopLimit(oldLimit); // Update metric if (metric) metric->visitedNodes++; if (bbox31) { const auto shouldSkip = !bbox31->contains(childNode->area31) && !childNode->area31.contains(*bbox31) && !bbox31->intersects(childNode->area31); if (shouldSkip) break; } // Update metric if (metric) metric->acceptedNodes++; if (nodesWithData && childNode->dataOffset > 0) nodesWithData->push_back(childNode); auto subchildrenSurfaceType = MapSurfaceType::Undefined; if (childNode->hasChildrenDataBoxes) { cis->Seek(childNode->offset); const auto oldLimit = cis->PushLimit(childNode->length); cis->Skip(childNode->firstDataBoxInnerOffset); readTreeNodeChildren(reader, section, childNode, subchildrenSurfaceType, nodesWithData, bbox31, queryController, metric); ObfReaderUtilities::ensureAllDataWasRead(cis); cis->PopLimit(oldLimit); } const auto surfaceTypeToMerge = (subchildrenSurfaceType != MapSurfaceType::Undefined) ? subchildrenSurfaceType : childNode->surfaceType; if (surfaceTypeToMerge != MapSurfaceType::Undefined) { if (outChildrenSurfaceType == MapSurfaceType::Undefined) outChildrenSurfaceType = surfaceTypeToMerge; else if (outChildrenSurfaceType != surfaceTypeToMerge) outChildrenSurfaceType = MapSurfaceType::Mixed; } break; } default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } } }
void OsmAnd::ObfMapSectionReader_P::readTreeNodeChildren( const std::unique_ptr<ObfReader_P>& reader, const std::shared_ptr<const ObfMapSectionInfo>& section, const std::shared_ptr<ObfMapSectionLevelTreeNode>& treeNode, MapFoundationType& foundation, QList< std::shared_ptr<ObfMapSectionLevelTreeNode> >* nodesWithData, const AreaI* bbox31, const IQueryController* const controller, ObfMapSectionReader_Metrics::Metric_loadMapObjects* const metric) { auto cis = reader->_codedInputStream.get(); foundation = MapFoundationType::Undefined; for(;;) { auto tag = cis->ReadTag(); switch(gpb::internal::WireFormatLite::GetTagFieldNumber(tag)) { case 0: return; case OBF::OsmAndMapIndex_MapDataBox::kBoxesFieldNumber: { auto length = ObfReaderUtilities::readBigEndianInt(cis); auto offset = cis->CurrentPosition(); auto oldLimit = cis->PushLimit(length); std::shared_ptr<ObfMapSectionLevelTreeNode> childNode(new ObfMapSectionLevelTreeNode(treeNode->level)); childNode->_foundation = treeNode->_foundation; childNode->_offset = offset; childNode->_length = length; readTreeNode(reader, section, treeNode->_area31, childNode); // Update metric if(metric) metric->visitedNodes++; if(bbox31) { const auto shouldSkip = !bbox31->contains(childNode->_area31) && !childNode->_area31.contains(*bbox31) && !bbox31->intersects(childNode->_area31); if(shouldSkip) { cis->Skip(cis->BytesUntilLimit()); cis->PopLimit(oldLimit); break; } } cis->PopLimit(oldLimit); // Update metric if(metric) metric->acceptedNodes++; if(nodesWithData && childNode->_dataOffset > 0) nodesWithData->push_back(childNode); auto childrenFoundation = MapFoundationType::Undefined; if(childNode->_childrenInnerOffset > 0) { cis->Seek(offset); oldLimit = cis->PushLimit(length); cis->Skip(childNode->_childrenInnerOffset); readTreeNodeChildren(reader, section, childNode, childrenFoundation, nodesWithData, bbox31, controller, metric); assert(cis->BytesUntilLimit() == 0); cis->PopLimit(oldLimit); } const auto foundationToMerge = (childrenFoundation != MapFoundationType::Undefined) ? childrenFoundation : childNode->_foundation; if(foundationToMerge != MapFoundationType::Undefined) { if(foundation == MapFoundationType::Undefined) foundation = foundationToMerge; else if(foundation != foundationToMerge) foundation = MapFoundationType::Mixed; } } break; default: ObfReaderUtilities::skipUnknownField(cis, tag); break; } } }
int main( int argc, char ** argv ) { SHPTreeHandle qix; int i, j; rectObj rect; int pos; ms_bitarray bitmap = NULL; char mBigEndian; treeNodeObj *node = NULL; /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc <= 1 ) { printf( "shptreetst shapefile {minx miny maxx maxy}\n" ); exit( 1 ); } i = 1; if( *((unsigned char *) &i) == 1 ) mBigEndian = 0; else mBigEndian = 1; qix = msSHPDiskTreeOpen (AddFileSuffix(argv[1],".qix"), 0 /* no debug*/); if( qix == NULL ) { printf("unable to open index file %s \n", argv[1]); exit(-1); } printf ("This %s %s index supports a shapefile with %d shapes, %d depth \n", (qix->version ? "new": "old"), (qix->LSB_order? "LSB": "MSB"), (int) qix->nShapes, (int) qix->nDepth); /* -------------------------------------------------------------------- */ /* Skim over the list of shapes, printing all the vertices. */ /* -------------------------------------------------------------------- */ pos = ftell (qix->fp); j = 0; while( pos && j < 20) { j ++; /* fprintf (stderr,"box %d, at %d pos \n", j, (int) ftell(qix)); */ node = readTreeNode (qix); if (node ) { fprintf (stdout,"shapes %d, node %d, %f,%f,%f,%f \n",(int) node->numshapes,node->numsubnodes,node->rect.minx, node->rect.miny, node->rect.maxx, node->rect.maxy); } else { pos = 0; } } printf ("read entire file now at quad box rec %d file pos %ld\n", j, ftell (qix->fp)); j = qix->nShapes; msSHPDiskTreeClose (qix); if( argc >= 5 ) { rect.minx = atof (argv[2]); rect.miny = atof (argv[3]); rect.maxx = atof (argv[4]); rect.maxy = atof (argv[5]); } else { printf ("using last read box as a search \n"); rect.minx = node->rect.minx; rect.miny = node->rect.miny; rect.maxx = node->rect.maxx; rect.maxy = node->rect.maxy; } bitmap = msSearchDiskTree( argv[1], rect, 0 /* no debug*/ ); if ( bitmap ) { printf ("result of rectangle search was \n"); for ( i=0; i<j; i++) { if ( msGetBit(bitmap,i) ) { printf(" %d,",i); } } } printf("\n"); return(0); }
int main( int argc, char ** argv ) { SHPHandle hSHP; DBFHandle hDBF; SHPTreeHandle qix; int i; char *myfile = NULL; treeNodeObj *node; #ifdef MAPSERVER shapeObj shape; lineObj line[3]; pointObj pts[6]; #else SHPObject *shape; double X[6], Y[6]; #endif int result; char mBigEndian; int this_rec, factor; /* -------------------------------------------------------------------- */ /* Display a usage message. */ /* -------------------------------------------------------------------- */ if( argc <= 2 ) { printf( "shptreevis shapefile new_shapefile \n" ); exit( 1 ); } i = 1; if( *((unsigned char *) &i) == 1 ) mBigEndian = 0; else mBigEndian = 1; qix = msSHPDiskTreeOpen (AddFileSuffix(argv[1],".qix"), 0 /* no debug*/); if( qix == NULL ) { printf("unable to open index file %s \n", argv[1]); exit(-1); } /* -------------------------------------------------------------------- */ /* Open the passed shapefile. */ /* -------------------------------------------------------------------- */ myfile = AddFileSuffix(argv[2],".shp"); #ifdef MAPSERVER hSHP = msSHPCreate ( myfile, SHPT_POLYGON ); hDBF = msDBFCreate ( AddFileSuffix(argv[2],".dbf") ); #else hSHP = SHPCreate ( myfile, SHPT_POLYGON ); hDBF = DBFCreate ( AddFileSuffix(argv[2],".dbf") ); #endif if ( (!hSHP) || (!hDBF) ) { printf ("create error for %s ... exiting \n", myfile); exit (-1); } /* add fields to dbf */ #ifdef MAPSERVER msDBFAddField ( hDBF, "ITEMS", FTInteger, 15,0 ); msDBFAddField ( hDBF, "SUBNODES", FTInteger, 15,0 ); msDBFAddField ( hDBF, "FACTOR", FTInteger, 15,0 ); #else DBFAddField ( hDBF, "ITEMS", FTInteger, 15,0 ); DBFAddField ( hDBF, "SUBNODES", FTInteger, 15,0 ); DBFAddField ( hDBF, "FACTOR", FTInteger, 15,0 ); #endif #ifndef MAPSERVER SHPClose ( hSHP ); hSHP = SHPOpen ( myfile, "r+b" ); DBFClose (hDBF); hDBF = DBFOpen ( myfile, "r+b"); #endif printf ("This %s %s index supports a shapefile with %d shapes, %d depth \n", (qix->version ? "new": "old"), (qix->LSB_order? "LSB": "MSB"), (int) qix->nShapes, (int) qix->nDepth); /* -------------------------------------------------------------------- */ /* Skim over the list of shapes, printing all the vertices. */ /* -------------------------------------------------------------------- */ while( 1 ) { node = readTreeNode (qix); if (node ) { this_rec = hDBF->nRecords; #ifdef MAPSERVER msDBFWriteIntegerAttribute( hDBF, this_rec, 0, node->numshapes); msDBFWriteIntegerAttribute( hDBF, this_rec, 1, node->numsubnodes); #else DBFWriteIntegerAttribute( hDBF, this_rec, 0, node->numshapes); DBFWriteIntegerAttribute( hDBF, this_rec, 1, node->numsubnodes); #endif factor = node->numshapes + node->numsubnodes; #ifdef MAPSERVER shape.numlines = 1; shape.type = SHPT_POLYGON; pts[0].x = node->rect.minx; pts[0].y = node->rect.miny; pts[1].x = node->rect.maxx; pts[1].y = node->rect.miny; pts[2].x = node->rect.maxx; pts[2].y = node->rect.maxy; pts[3].x = node->rect.minx; pts[3].y = node->rect.maxy; pts[4].x = node->rect.minx; pts[4].y = node->rect.miny; line[0].numpoints = 5; line[0].point = &pts[0]; shape.line = &line[0]; shape.bounds = node->rect; result = msSHPWriteShape ( hSHP, &shape ); if ( result < 0 ) { printf ("unable to write shape \n"); exit (0); } #else X[0] = node->rect.minx; X[1] = node->rect.maxx; X[2] = node->rect.maxx; X[3] = node->rect.minx; X[4] = node->rect.minx; Y[0] = node->rect.miny; Y[1] = node->rect.miny; Y[2] = node->rect.maxy; Y[3] = node->rect.maxy; Y[4] = node->rect.miny; shape = SHPCreateSimpleObject( SHPT_POLYGON, 5, X, Y, NULL); SHPWriteObject(hSHP, -1, shape); SHPDestroyObject ( shape ); #endif } else break; } #ifdef MAPSERVER msSHPClose( hSHP ); msDBFClose( hDBF ); #else SHPClose( hSHP ); DBFClose( hDBF ); #endif msSHPDiskTreeClose (qix); return(0); }