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

initial featuresAt implementation (merged master into 352-featuresAt) #3854

Closed
wants to merge 65 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
139b9e7
refs #352: catalog (hardcoded: POI) features on tile parse
incanus Nov 25, 2015
b1ad1b6
fix crasher
incanus Nov 26, 2015
8a4f068
refs #352: current state of feature querying
incanus Nov 26, 2015
5de3f99
refs #352: remove unused forward declaration
incanus Nov 26, 2015
3f89f50
refs #352: parse interactive layer property from style
incanus Nov 26, 2015
e4f1339
refs #352: further work on featuresAt
incanus Dec 1, 2015
32cb432
refs #352: debug tap coordinate & fix y flip for core
incanus Dec 1, 2015
e309fe3
refs #352: remove logging
incanus Dec 1, 2015
7515847
refs #352: hook up `name_en` & normal radius (works for <=z15!)
incanus Dec 1, 2015
dc4f5fa
refs #352: naively fetch all feature properties upfront for now
incanus Dec 1, 2015
454c014
refs #352: clean up adds
incanus Dec 1, 2015
8fd4eaf
refs #352: better debug logging
incanus Dec 1, 2015
bda6e0c
refs #352: only query clicked tile
incanus Dec 1, 2015
cd15d85
refs #352: properly query scale
incanus Dec 1, 2015
29dc55e
refs #352: clean out existing tile feature tree on any sort of re-parse
incanus Dec 2, 2015
b1e3da9
refs #352: fix for overzoomed tiles & disable some debug logs
incanus Dec 2, 2015
d0a34c5
refs #352: pipe source through the features query
incanus Dec 2, 2015
f8fb791
refs #352: typedef feature results for brevity
incanus Dec 2, 2015
caa2576
refs #352: naive plumbing of work down into source
incanus Dec 2, 2015
fdfb377
refs #352: commenting cleanup
incanus Dec 2, 2015
41159cb
refs #352: public interface cleanup & get rid of unneeded optional/va…
incanus Dec 2, 2015
fd4b063
refs #352: cleanups
incanus Dec 2, 2015
181a997
refs #352: add comment
incanus Dec 2, 2015
641e7db
refs #352: move result feature tree directly
incanus Dec 2, 2015
ac6ada3
refs #352: clean up extent handling & only add features when valid bbox
incanus Dec 3, 2015
7cdcc49
refs #352: obtain non-string vector tile properties as well
incanus Dec 3, 2015
b5f5a24
refs #352: sort result keys at query time as on JS
incanus Dec 3, 2015
a9b9568
refs #352: clarify comment
incanus Dec 3, 2015
e7b01cd
refs #352: don't clobber debug output properties each loop
incanus Dec 3, 2015
d5c31e2
refs #352: fix partial parse symbol layers
incanus Dec 3, 2015
660ff91
refs #352: remove debug log
incanus Dec 3, 2015
22e5c48
refs #352: remove logging & reorganize
incanus Dec 3, 2015
7f6010a
refs #352: build up Cocoa API and remove last of logging
incanus Dec 3, 2015
9824937
refs #352: add Cocoa docs
incanus Dec 3, 2015
91976cb
refs #352: add gesture for feature querying
incanus Dec 3, 2015
2c266e3
refs #352: added interactive style mode to iOS test app
incanus Dec 3, 2015
00339ac
refs #352: removed more extraneous debug stuff
incanus Dec 3, 2015
2a1f0e6
refs #352: pipe through a radius parameter and use 50 on mobile
incanus Dec 3, 2015
0e05c3e
refs #352: add legit iOS feature querying mode
incanus Dec 3, 2015
72ef933
refs #352: return all properties for annotation tiles
incanus Dec 3, 2015
b9f47f8
refs #352: move away from interrupting alert
incanus Dec 3, 2015
42741cd
refs #352: remove last debug note
incanus Dec 3, 2015
f91df07
refs #352: use actual source max zoom
incanus Dec 3, 2015
0b6953e
refs #352: scroll text area to top when changing contents
incanus Dec 3, 2015
392acd9
refs #352: be more explicit about numeric types and fix tests(?)
incanus Dec 3, 2015
1320df7
refs #352: finally fix tests on Linux by being explicit about numeric…
incanus Dec 3, 2015
0ea4f53
more descriptive & safer public API
incanus Dec 14, 2015
b98b686
use defined type
incanus Dec 14, 2015
4c639e5
abstract tile extent 4096 variable
incanus Dec 14, 2015
6c86e78
interactive -> isInteractive
incanus Dec 14, 2015
262665e
boxed literals for UTF8 strings
incanus Dec 14, 2015
beda70d
fix bug with storing to reference
incanus Dec 14, 2015
505f929
better, stronger types & more clear method names
incanus Dec 14, 2015
b6ad5e2
fix camel case for local variables
incanus Dec 14, 2015
d123545
radius uint8_t -> uint16_t as with height & width
incanus Dec 14, 2015
ac655ce
better comments, abstract extent, and don't iterate over all loaded t…
incanus Dec 14, 2015
394c484
expose feature query radius in MGLMapView API
incanus Dec 14, 2015
10d36f8
refer to screen points in public API
incanus Dec 14, 2015
6b72663
Merge remote-tracking branch 'origin/master' into 352-featuresAt
incanus Dec 14, 2015
d088794
layer is now a pointer
incanus Dec 14, 2015
a04b13e
fix getAllValues() for new GeoJSON feature type
incanus Dec 14, 2015
7f07974
getAllValues() -> getValues()
incanus Dec 14, 2015
30239c2
fix Linux narrow warning by using correct type
incanus Dec 14, 2015
02ea849
more POI layers in demo, but cleaner output visually
incanus Dec 15, 2015
f8b32b6
Merge remote-tracking branch 'origin/master' into 352-featuresAt
jonkan Feb 8, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions include/mbgl/darwin/MGLTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ typedef NS_ENUM(NSUInteger, MGLUserTrackingMode) {
MGLUserTrackingModeFollowWithCourse,
};

/** The style layer name for a queried map feature. */
extern NSString * const MGLFeatureLayerNameKey;

/** The style source name for a queried map feature. */
extern NSString * const MGLFeatureSourceNameKey;

/** The properties from the source data for a queried map feature. */
extern NSString * const MGLFeaturePropertiesKey;

NS_ASSUME_NONNULL_END

#pragma clang diagnostic push
Expand Down
8 changes: 8 additions & 0 deletions include/mbgl/ios/MGLMapView.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,14 @@ IB_DESIGNABLE
*/
@property (nonatomic, readonly) UIButton *attributionButton;

/** Query the visible map for features at a given point.
*
* @param point A point on screen, for example at a user gesture.
* @param radius A distance in screen points around which to query features.
* @return An array of `NSDictionary` objects representing features near the point. Keys and values provided include `MGLFeatureLayerNameKey` for the feature layer name in the active style, `MGLFeatureSourceNameKey` for the feature source name in the active style, and `MGLFeaturePropertiesKey` containing a dictionary of properties of the feature from the source data as `NSString` keys and values. */
- (NS_ARRAY_OF(NSDictionary *) *)featureDescriptionsAtPoint:(CGPoint)point radius:(CGFloat)radius;

#pragma mark - Accessing the Delegate
/**
Currently active style classes, represented as an array of string identifiers.
*/
Expand Down
5 changes: 5 additions & 0 deletions include/mbgl/map/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <mbgl/util/geo.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/vec.hpp>
#include <mbgl/util/interactive_features.hpp>
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/style/types.hpp>

Expand Down Expand Up @@ -166,6 +167,7 @@ class Map : private util::noncopyable {

AnnotationIDs getPointAnnotationsInBounds(const LatLngBounds&);

// Style API
void addCustomLayer(const std::string& id,
CustomLayerInitializeFunction,
CustomLayerRenderFunction,
Expand All @@ -174,6 +176,9 @@ class Map : private util::noncopyable {
const char* before = nullptr);
void removeCustomLayer(const std::string& id);

// Features
std::vector<FeatureDescription> featureDescriptionsAt(const PrecisionPoint, const uint16_t radius = 0) const;

// Memory
void setSourceTileCacheSize(size_t);
void onLowMemory();
Expand Down
20 changes: 20 additions & 0 deletions include/mbgl/util/interactive_features.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef MBGL_UTIL_INTERACTIVE_FEATURES
#define MBGL_UTIL_INTERACTIVE_FEATURES

#include <map>
#include <string>

namespace mbgl {

struct FeatureDescription {
inline explicit FeatureDescription(std::string layer_, std::string source_, std::map<std::string, std::string>properties_)
: layer(layer_), source(source_), properties(properties_) {}

std::string layer;
std::string source;
std::map<std::string, std::string> properties;
};

}

#endif
108 changes: 108 additions & 0 deletions ios/app/MBXViewController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ @interface MBXViewController () <UIActionSheetDelegate, MGLMapViewDelegate>

@property (nonatomic) MGLMapView *mapView;
@property (nonatomic) NSUInteger styleIndex;
@property (nonatomic) UIView *interactiveShield;
@property (nonatomic) UITextView *featuresView;

@end

Expand Down Expand Up @@ -175,6 +177,7 @@ - (void)showSettings
: @"Show Custom Style Layer"),
@"Print Telemetry Logfile",
@"Delete Telemetry Logfile",
@"Enable Interactivity",
nil];

[sheet showFromBarButtonItem:self.navigationItem.leftBarButtonItem animated:YES];
Expand Down Expand Up @@ -326,6 +329,35 @@ - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSIn
}
}
}
else if (buttonIndex == actionSheet.firstOtherButtonIndex + 16)
{
if ([self.mapView.styleURL.scheme isEqualToString:@"mapbox"])
{
self.mapView.userInteractionEnabled = NO;

self.interactiveShield = [[UIView alloc] initWithFrame:self.mapView.frame];
self.interactiveShield.backgroundColor = [UIColor clearColor];
self.interactiveShield.userInteractionEnabled = YES;
[self.view insertSubview:self.interactiveShield aboveSubview:self.mapView];

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleInteractivityPan:)];
[self.interactiveShield addGestureRecognizer:pan];

self.featuresView = [[UITextView alloc] initWithFrame:CGRectMake(20, self.topLayoutGuide.length + 20,
self.view.bounds.size.width / 2 - 40, self.view.bounds.size.height / 4)];
self.featuresView.selectable = NO;
self.featuresView.font = [UIFont systemFontOfSize:16];
self.featuresView.backgroundColor = [UIColor whiteColor];
self.featuresView.alpha = 0.75;
self.featuresView.text = @"Moving the map is now disabled until you change the style. Pan with your finger to query for features.";

[self.view addSubview:self.featuresView];

self.mapView.styleURL = [NSURL URLWithString:@"asset://streets-interactive-poi-v8.json"];

[(UIButton *)self.navigationItem.titleView setTitle:@"Interactive Streets" forState:UIControlStateNormal];
}
}
}

- (void)parseFeaturesAddingCount:(NSUInteger)featuresCount
Expand Down Expand Up @@ -455,8 +487,84 @@ - (void)handleLongPress:(UILongPressGestureRecognizer *)longPress
}
}

- (void)handleInteractivityPan:(UIPanGestureRecognizer *)pan
{
if (pan.state == UIGestureRecognizerStateBegan || pan.state == UIGestureRecognizerStateChanged)
{
self.featuresView.userInteractionEnabled = NO;

CGPoint point = [pan locationInView:pan.view];

NSArray *features = [self.mapView featureDescriptionsAtPoint:point radius:50];

if ([features count])
{
NSMutableArray *outputNames = [NSMutableArray array];
NSMutableArray *seenIDs = [NSMutableArray array];

for (NSDictionary *feature in features)
{
NSDictionary *properties = feature[MGLFeaturePropertiesKey];

NSString *featureID = properties[@"osm_id"];

if ( ! [seenIDs containsObject:featureID])
{
[seenIDs addObject:featureID];

NSString *featureName = properties[@"name_en"];

// Mapbox-returned OSM IDs have 1 + zero padding in front of
// the actual OSM ID, so let's remove that.
//
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^10+(.*)"
options:0
error:nil];

featureID = [regex stringByReplacingMatchesInString:featureID
options:0
range:NSMakeRange(0, featureID.length)
withTemplate:@"$1"];

[outputNames addObject:[NSString stringWithFormat:@"- %@ (OSM #%@)", featureName, featureID]];
}
}

NSMutableString *output = [NSMutableString stringWithString:@"Features:\n\n"];

for (NSString *outputName in outputNames)
{
[output appendString:outputName];
[output appendString:@"\n"];
}

self.featuresView.text = output;
self.featuresView.contentOffset = CGPointZero;
}
else
{
self.featuresView.text = nil;
}
}
else
{
self.featuresView.userInteractionEnabled = YES;
}
}

- (void)cycleStyles
{
if (self.interactiveShield)
{
[self.interactiveShield removeFromSuperview];
self.interactiveShield = nil;

[self.featuresView removeFromSuperview];
self.featuresView = nil;

self.mapView.userInteractionEnabled = YES;
}

UIButton *titleButton = (UIButton *)self.navigationItem.titleView;

self.styleIndex = (self.styleIndex + 1) % mbgl::util::default_styles::numOrderedStyles;
Expand Down
3 changes: 2 additions & 1 deletion ios/app/mapboxgl-app.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
'./threestates.geojson',
'./Settings.bundle/',
'./app-info.plist',
'./streets-interactive-poi-v8.json',
],

'dependencies': [
Expand Down Expand Up @@ -63,7 +64,7 @@
},
},
},

'copies': [
{
'destination': '<(PRODUCT_DIR)/$(FRAMEWORKS_FOLDER_PATH)',
Expand Down
Loading