Example #1
0
bool
TopographyFile::Update(const WindowProjection &map_projection)
{
  if (IsEmpty())
    return false;

  if (map_projection.GetMapScale() > scale_threshold)
    /* not visible, don't update cache now */
    return false;

  const GeoBounds screenRect =
    map_projection.GetScreenBounds();
  if (cache_bounds.IsValid() && cache_bounds.IsInside(screenRect))
    /* the cache is still fresh */
    return false;

  cache_bounds = map_projection.GetScreenBounds().Scale(fixed(2));

  rectObj deg_bounds = ConvertRect(cache_bounds);

  // Test which shapes are inside the given bounds and save the
  // status to file.status
  msShapefileWhichShapes(&file, dir, deg_bounds, 0);

  // If not a single shape is inside the bounds
  if (!file.status) {
    // ... clear the whole buffer
    ClearCache();
    return false;
  }

  // Iterate through the shapefile entries
  const ShapeList **current = &first;
  auto it = shapes.begin();
  for (int i = 0; i < file.numshapes; ++i, ++it) {
    if (!msGetBit(file.status, i)) {
      // If the shape is outside the bounds
      // delete the shape from the cache
      delete it->shape;
      it->shape = NULL;
    } else {
      // is inside the bounds
      if (it->shape == NULL)
        // shape isn't cached yet -> cache the shape
        it->shape = new XShape(&file, i, label_field);
      // update list pointer
      *current = it;
      current = &it->next;
    }
  }
  // end of list marker
  *current = NULL;

  ++serial;
  return true;
}
Example #2
0
// Function to filter search results further against feature bboxes
void msFilterTreeSearch(shapefileObj *shp, char *status, rectObj search_rect)
{
    int i;
    rectObj shape_rect;

    for(i=0; i<shp->numshapes; i++) { /* for each shape */
        if(msGetBit(status, i)) {
            if(!msSHPReadBounds(shp->hSHP, i, &shape_rect))
                if(msRectOverlap(&shape_rect, &search_rect) != MS_TRUE)
                    msSetBit(status, i, 0);
        }
    }
}
Example #3
0
void Topology::updateCache(MapWindowProjection &map_projection,
			   rectObj thebounds, bool purgeonly) {

  if (!triggerUpdateCache) return;

  if (!shapefileopen) return;

  in_scale = CheckScale(map_projection.GetMapScaleUser());

  if (!in_scale) {
    // not visible, so flush the cache
    // otherwise we waste time on looking up which shapes are in bounds
    flushCache();
    triggerUpdateCache = false;
    return;
  }

  if (purgeonly) return;

  triggerUpdateCache = false;

  msSHPWhichShapes(&shpfile, thebounds, 0);
  if (!shpfile.status) {
    // this happens if entire shape is out of range
    // so clear buffer.
    flushCache();
    return;
  }

  shapes_visible_count = 0;

  for (int i=0; i<shpfile.numshapes; i++) {
    if (msGetBit(shpfile.status, i)) {
      if (shpCache[i]==NULL) {
        // shape is now in range, and wasn't before
        shpCache[i] = addShape(i);
      }
      shapes_visible_count++;
    } else {
      removeShape(i);
    }
  }
}
Example #4
0
void Topology::updateCache(rectObj thebounds, bool purgeonly) {
  if (!triggerUpdateCache) return;

  if (!shapefileopen) return;

  in_scale = CheckScale();

  if (!in_scale) {
    // not visible, so flush the cache
    // otherwise we waste time on looking up which shapes are in bounds
    flushCache();
    triggerUpdateCache = false;
    in_scale_last = false;
    return;
  }

  if (purgeonly) {
    in_scale_last = in_scale;
    return;
  }

  triggerUpdateCache = false;

#ifdef DEBUG_TFC
#ifdef TOPOFASTCACHE
  StartupStore(TEXT("---UpdateCache() starts, mode%d%s"),cache_mode,NEWLINE);
#else
  StartupStore(TEXT("---UpdateCache() starts, original code%s"),NEWLINE);
#endif
  int starttick = GetTickCount();
#endif

#ifdef TOPOFASTCACHE
  if(msRectOverlap(&shpfile.bounds, &thebounds) != MS_TRUE) {
    // this happens if entire shape is out of range
    // so clear buffer.
    flushCache();
    in_scale_last = in_scale;
    return;
  }

  bool smaller = false;
  bool bigger = false;
  bool in_scale_again = in_scale && !in_scale_last;
  int shapes_loaded = 0;
  shapes_visible_count = 0;
  in_scale_last = in_scale;
  
  switch (cache_mode) {
    case 0: // Original code plus one special case
      smaller = (msRectContained(&thebounds, &lastBounds) == MS_TRUE);
      if (smaller) { //Special case, search inside, we don't need to load additional shapes, just remove
        shapes_visible_count = 0;
        for (int i=0; i<shpfile.numshapes; i++) {
          if (shpCache[i]) {
            if(msRectOverlap(&(shpCache[i]->shape.bounds), &thebounds) != MS_TRUE) {
              removeShape(i);
            } else shapes_visible_count++;
          }
        }//for
      } else { 
        //In this case we have to run the original algoritm
        msSHPWhichShapes(&shpfile, thebounds, 0);
        shapes_visible_count = 0;
        for (int i=0; i<shpfile.numshapes; i++) {
          if (msGetBit(shpfile.status, i)) {
            if (shpCache[i]==NULL) {
              // shape is now in range, and wasn't before
              shpCache[i] = addShape(i);
              shapes_loaded++;
            }
            shapes_visible_count++;
          } else {
            removeShape(i);
          }
        }//for
      }
      break;

    case 1:  // Bounds array in memory
      bigger = (msRectContained(&lastBounds, &thebounds) == MS_TRUE);
      smaller = (msRectContained(&thebounds, &lastBounds) == MS_TRUE);
      if (bigger || in_scale_again) { //We don't need to remove shapes, just load, so skip loaded ones
        for (int i=0; i<shpfile.numshapes; i++) {
          if (shpCache[i]) continue;
          if(msRectOverlap(&shpBounds[i], &thebounds) == MS_TRUE) {
            // shape is now in range, and wasn't before
            shpCache[i] = addShape(i);
            shapes_loaded++;
          }
        }//for
        shapes_visible_count+=shapes_loaded;
      } else
      if (smaller) { //Search inside, we don't need to load additional shapes, just remove
        for (int i=0; i<shpfile.numshapes; i++) {
          if (shpCache[i]==NULL) continue;
          if(msRectOverlap(&shpBounds[i], &thebounds) != MS_TRUE) {
            removeShape(i);
          } else shapes_visible_count++;
        }//for
      } else { 
        //Otherwise we have to search the all array
        for (int i=0; i<shpfile.numshapes; i++) {
          if(msRectOverlap(&shpBounds[i], &thebounds) == MS_TRUE) {
            if (shpCache[i]==NULL) {
              // shape is now in range, and wasn't before
              shpCache[i] = addShape(i);
              shapes_loaded++;
            }
            shapes_visible_count++;
          } else {
            removeShape(i);
          }
        }//for
      }
      break;

    case 2: // All shapes in memory	
      XShape *pshp;
      shapes_visible_count = 0;
      for (int i=0; i<shpfile.numshapes; i++) {
        pshp = shps[i];
        if(msRectOverlap(&(pshp->shape.bounds), &thebounds) == MS_TRUE) {
          shpCache[i] = pshp;
          shapes_visible_count++;
        } else {
          shpCache[i] = NULL;
        }
      }//for
      break;
    }//sw

    lastBounds = thebounds;
#else

  msSHPWhichShapes(&shpfile, thebounds, 0);
  if (!shpfile.status) {
    // this happens if entire shape is out of range
    // so clear buffer.
    flushCache();
    return;
  }

  shapes_visible_count = 0;

  for (int i=0; i<shpfile.numshapes; i++) {

    if (msGetBit(shpfile.status, i)) {
      
      if (shpCache[i]==NULL) {
	// shape is now in range, and wasn't before
	shpCache[i] = addShape(i);
      }
      shapes_visible_count++;
    } else {
      removeShape(i);
    }
  }
#endif

#ifdef DEBUG_TFC
  long free_size = CheckFreeRam();
  StartupStore(TEXT("   UpdateCache() ends, shps_visible=%d ram=%li (%dms)%s"),shapes_visible_count, free_size, GetTickCount()-starttick,NEWLINE);
#endif
}
Example #5
0
bool
TopographyFile::Update(const WindowProjection &map_projection)
{
    if (IsEmpty())
        return false;

    if (map_projection.GetMapScale() > scale_threshold)
        /* not visible, don't update cache now */
        return false;

    const GeoBounds screenRect =
        map_projection.GetScreenBounds();
    if (cache_bounds.IsValid() && cache_bounds.IsInside(screenRect))
        /* the cache is still fresh */
        return false;

    cache_bounds = screenRect.Scale(2);

    rectObj deg_bounds = ConvertRect(cache_bounds);

    // Test which shapes are inside the given bounds and save the
    // status to file.status
    switch (msShapefileWhichShapes(&file, dir, deg_bounds, 0)) {
    case MS_FAILURE:
        ClearCache();
        return false;

    case MS_DONE:
        /* screen is outside of map bounds */
        return false;

    case MS_SUCCESS:
        break;
    }

    assert(file.status != nullptr);

    // Iterate through the shapefile entries
    const ShapeList **current = &first;
    auto it = shapes.begin();
    for (int i = 0; i < file.numshapes; ++i, ++it) {
        if (!msGetBit(file.status, i)) {
            // If the shape is outside the bounds
            // delete the shape from the cache
            if (it->shape != nullptr) {
                assert(*current == it);

                /* remove from linked list (protected) */
                {
                    const ScopeLock lock(mutex);
                    *current = it->next;
                    ++serial;
                }

                /* now it's unreachable, and we can delete the XShape without
                   holding a lock */
                delete it->shape;
                it->shape = nullptr;
            }
        } else {
            // is inside the bounds
            if (it->shape == nullptr) {
                assert(*current != it);

                // shape isn't cached yet -> cache the shape
                it->shape = LoadShape(&file, center, i, label_field);
                it->next = *current;

                /* insert into linked list (protected) */
                {
                    const ScopeLock lock(mutex);
                    *current = it;
                    ++serial;
                }
            }

            current = &it->next;
        }
    }
    // end of list marker
    assert(*current == nullptr);

    return true;
}
Example #6
0
bool
TopographyFile::Update(const WindowProjection &map_projection)
{
  if (IsEmpty())
    return false;

  if (map_projection.GetMapScale() > scale_threshold)
    /* not visible, don't update cache now */
    return false;

  const GeoBounds screenRect =
    map_projection.GetScreenBounds();
  if (cache_bounds.inside(screenRect))
    /* the cache is still fresh */
    return false;

  cache_bounds = map_projection.GetScreenBounds().scale(fixed_two);

  rectObj deg_bounds = ConvertRect(cache_bounds);

  // Test which shapes are inside the given bounds and save the
  // status to file.status
  msShapefileWhichShapes(&file, dir, deg_bounds, 0);

  // If not a single shape is inside the bounds
  if (!file.status) {
    // ... clear the whole buffer
    ClearCache();
    return false;
  }

  // Iterate through the shapefile entries
  for (int i = 0; i < file.numshapes; i++) {
    if (!msGetBit(file.status, i)) {
      // If the shape is outside the bounds
      // delete the shape from the cache
      delete shapes[i].shape;
      shapes[i].shape = NULL;
    } else if (shapes[i].shape == NULL) {
      // If the shape is inside the bounds and if the
      // shape isn't cached yet -> cache the shape
      shapes[i].shape = new XShape(&file, i, label_field);
    }
  }

  ShapeList::NotNull not_null;
  XShapePointerArray::iterator end = shapes.end(), it = shapes.begin();
  it = std::find_if(it, end, not_null);
  if (it != shapes.end()) {
    ShapeList *current = &*it;
    first = current;

    while (true) {
      ++it;
      it = std::find_if(it, end, not_null);
      if (it == end) {
        current->next = NULL;
        break;
      }

      ShapeList *next = &*it;
      current->next = next;
      current = next;
    }
  } else
    first = NULL;

  return true;
}
Example #7
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);
}