Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
refs #352: current state of feature querying
Browse files Browse the repository at this point in the history
  • Loading branch information
incanus committed Nov 26, 2015
1 parent b1ad1b6 commit 8a4f068
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 10 deletions.
2 changes: 2 additions & 0 deletions include/mbgl/ios/MGLMapView.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,8 @@ IB_DESIGNABLE
/** Whether the map view should display a heading calibration alert when necessary. The default value is `YES`. */
@property (nonatomic, assign) BOOL displayHeadingCalibration;

- (void)featuresAt:(CGPoint)point;

#pragma mark - Debugging

/** @name Debugging */
Expand Down
3 changes: 3 additions & 0 deletions include/mbgl/map/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ class Map : private util::noncopyable {
LatLngBounds getBoundsForAnnotations(const AnnotationIDs&);
double getTopOffsetPixelsForAnnotationSymbol(const std::string&);

// Features
std::vector<std::string> featuresAt(const PrecisionPoint) const;

// Sprites
void setSprite(const std::string&, std::shared_ptr<const SpriteImage>);
void removeSprite(const std::string&);
Expand Down
16 changes: 9 additions & 7 deletions ios/app/MBXViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -296,13 +296,15 @@ - (void)handleLongPress:(UILongPressGestureRecognizer *)longPress
{
if (longPress.state == UIGestureRecognizerStateBegan)
{
MGLPointAnnotation *point = [MGLPointAnnotation new];
point.coordinate = [self.mapView convertPoint:[longPress locationInView:longPress.view]
toCoordinateFromView:self.mapView];
point.title = @"Dropped Marker";
point.subtitle = [NSString stringWithFormat:@"lat: %.3f, lon: %.3f", point.coordinate.latitude, point.coordinate.longitude];
[self.mapView addAnnotation:point];
[self.mapView selectAnnotation:point animated:YES];
// MGLPointAnnotation *point = [MGLPointAnnotation new];
// point.coordinate = [self.mapView convertPoint:[longPress locationInView:longPress.view]
// toCoordinateFromView:self.mapView];
// point.title = @"Dropped Marker";
// point.subtitle = [NSString stringWithFormat:@"lat: %.3f, lon: %.3f", point.coordinate.latitude, point.coordinate.longitude];
// [self.mapView addAnnotation:point];
// [self.mapView selectAnnotation:point animated:YES];

[self.mapView featuresAt:[longPress locationInView:longPress.view]];
}
}

Expand Down
5 changes: 5 additions & 0 deletions platform/ios/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,11 @@ - (void)commonInit
}];
}

- (void)featuresAt:(CGPoint)point
{
_mbglMap->featuresAt(mbgl::PrecisionPoint(point.x, point.y));
}

- (void)createGLView
{
if (_context) return;
Expand Down
7 changes: 7 additions & 0 deletions src/mbgl/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,13 @@ LatLngBounds Map::getBoundsForAnnotations(const AnnotationIDs& annotations) {
}


#pragma mark - Features

std::vector<std::string> Map::featuresAt(const PrecisionPoint point) const {
return context->invokeSync<std::vector<std::string>>(&MapContext::featuresAt, point);
}


#pragma mark - Sprites

void Map::setSprite(const std::string& name, std::shared_ptr<const SpriteImage> sprite) {
Expand Down
78 changes: 78 additions & 0 deletions src/mbgl/map/map_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <mbgl/map/map_data.hpp>
#include <mbgl/map/view.hpp>
#include <mbgl/map/still_image.hpp>
#include <mbgl/map/tile.hpp>

#include <mbgl/platform/log.hpp>

Expand All @@ -22,9 +23,12 @@
#include <mbgl/util/texture_pool.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/tile_coordinate.hpp>

#include <algorithm>

#include <boost/function_output_iterator.hpp>

namespace mbgl {

MapContext::MapContext(View& view_, FileSource& fileSource, MapData& data_)
Expand Down Expand Up @@ -277,6 +281,80 @@ double MapContext::getTopOffsetPixelsForAnnotationSymbol(const std::string& symb
}
}

std::vector<std::string> MapContext::featuresAt(const PrecisionPoint point) const {

LatLng p_ = transformState.pointToLatLng(point);

// figure out tile
//
double sine = std::sin(p_.latitude * M_PI / 180);
double x = p_.longitude / 360 + 0.5;
double y = 0.5 - 0.25 * std::log((1 + sine) / (1 - sine)) / M_PI;

y = y < -1 ? -1 : y > 1 ? 1 : y;

// PrecisionPoint p(x, y);

const auto z = floor(transformState.getZoom());
const auto z2 = powf(2, z);
TileID id(z, floor(x * z2), floor(y * z2), ::fmin(z, 15));

// figure out tile coordinate
//
TileCoordinate coordinate = transformState.pointToCoordinate(point);

// figure out query bounds
//
const auto world_size = util::tileSize * transformState.getScale();
const auto scale = world_size / z2;

coordinate.zoomTo(::fmin(id.z, 18));
// const auto tileCoordinate = vec2<uint16_t>(id.x * 4096, id.y * 4096);


vec3<uint16_t> position((coordinate.column - id.x) * 4096, (coordinate.row - id.y) * 4096, scale);




std::vector<std::string> results;

printf("=====\n");



const auto radius = 5 * 4096 / scale;
FeatureBox queryBox = {
{ position.x - radius, position.y - radius },
{ position.x + radius, position.y + radius }
};




for (const auto& source : style->sources) {
if (source->info.type == SourceType::Vector) {
for (const auto& tile : source->getLoadedTiles()) {
// if (tile->id == coordinate)
// printf("[%s]: %i,%i,%i\n", source->info.source_id.c_str(), tile->id.z, tile->id.x, tile->id.y);

const auto& tile_data = tile->data;
tile_data->featureTree.query(boost::geometry::index::intersects(queryBox),
boost::make_function_output_iterator([&](const auto& val) {
results.push_back(val.second);
}));


}
}
}

// (void)point;

return results;

}

void MapContext::setSourceTileCacheSize(size_t size) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
if (size != sourceCacheSize) {
Expand Down
3 changes: 3 additions & 0 deletions src/mbgl/map/map_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <mbgl/style/style.hpp>
#include <mbgl/util/gl_object_store.hpp>
#include <mbgl/util/ptr.hpp>
#include <mbgl/util/geo.hpp>

#include <vector>

Expand Down Expand Up @@ -51,6 +52,8 @@ class MapContext : public Style::Observer {
double getTopOffsetPixelsForAnnotationSymbol(const std::string& symbol);
void updateAnnotations();

std::vector<std::string> featuresAt(const PrecisionPoint) const;

void setSourceTileCacheSize(size_t size);
void onLowMemory();

Expand Down
29 changes: 29 additions & 0 deletions src/mbgl/map/tile_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,39 @@
#include <memory>
#include <functional>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wshadow"
#ifdef __clang__
#pragma GCC diagnostic ignored "-Wunknown-pragmas"
#endif
#pragma GCC diagnostic ignored "-Wpragmas"
#pragma GCC diagnostic ignored "-Wdeprecated-register"
#pragma GCC diagnostic ignored "-Wshorten-64-to-32"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/index/rtree.hpp>
#pragma GCC diagnostic pop

namespace mbgl {

class StyleLayer;
class Worker;
class DebugBucket;

namespace FeatureBG = boost::geometry;
namespace FeatureBGM = FeatureBG::model;
namespace FeatureBGI = FeatureBG::index;
typedef FeatureBGM::point<int16_t, 2, FeatureBG::cs::cartesian> FeaturePoint;
typedef FeatureBGM::box<FeaturePoint> FeatureBox;
typedef std::pair<FeatureBox, std::string> Feature;
typedef FeatureBGI::rtree<Feature, FeatureBGI::linear<16, 4>> FeatureTree;

class TileData : private util::noncopyable {
public:
// initial:
Expand Down Expand Up @@ -98,6 +125,8 @@ class TileData : private util::noncopyable {
// Contains the tile ID string for painting debug information.
std::unique_ptr<DebugBucket> debugBucket;

FeatureTree featureTree;

protected:
std::atomic<State> state;
std::string error;
Expand Down
6 changes: 3 additions & 3 deletions src/mbgl/map/tile_worker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void TileWorker::parseLayer(const StyleLayer& layer, const GeometryTile& geometr
//
// also, we don't get here for raster buckets, since they don't have layers

if (!partialParse && layer.id.substr(0, 3) == "poi" && bucket->hasData()) {
if (!partialParse && /*layer.id.substr(0, 3) == "poi" &&*/ bucket->hasData()) {
result.featureTree.clear();
for (std::size_t i = 0; i < geometryLayer->featureCount(); i++) {
const auto feature = geometryLayer->getFeature(i);
Expand Down Expand Up @@ -178,12 +178,12 @@ void TileWorker::parseLayer(const StyleLayer& layer, const GeometryTile& geometr
}
name = layer.id + " - " + name;
result.featureTree.insert(std::make_pair(featureBox, layer.id + name));
// printf("added %s\n", name.c_str());
printf("added %s\n", name.c_str());
}
}
}
if (result.featureTree.size()) {
// printf("feature tree for %i,%i,%i [%s] has %lu members\n", id.z, id.x, id.y, layer.id.c_str(), result.featureTree.size());
printf("feature tree for %i,%i,%i [%s] has %lu members\n", id.z, id.x, id.y, layer.id.c_str(), result.featureTree.size());
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/mbgl/map/vector_tile_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ VectorTileData::VectorTileData(const TileID& id_,
// existing buckets in case we got a refresh parse.
buckets = std::move(resultBuckets.buckets);

// featureTree.clear();
featureTree.insert(resultBuckets.featureTree.begin(), resultBuckets.featureTree.end());

// The target configuration could have changed since we started placement. In this case,
// we're starting another placement run.
if (placedConfig != targetConfig) {
Expand Down

0 comments on commit 8a4f068

Please sign in to comment.