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;
        }
    }
}
Example #2
0
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;
        }
    }
}
Example #4
0
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;
        }
    }
}
Example #8
0
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);
}
Example #9
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);
}