-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Conversation
Going to refactor this using the visitor pattern as this would be more clean as the virtual function approach. |
0bc2db4
to
09fd2a2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR adds a few functions, but they don't seem to be used or tested anywhere?
See also mapbox/mapbox-gl-js#6829 for discussion on unit tests for this in the JS version. |
d009eda
to
35b0557
Compare
35b0557
to
fce4bff
Compare
@kkaefer @mourner Added unit test for GeoJSONSource d4485c9 do you think it is sufficient? Also, noticed that GeoJSONSource::Impl shares its private data as a raw pointer and GeoJSONSource doesn't check whether data is null. Fixed in fce4bff. Do you think it is required? If not, I will drop that commit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for fixing up the code and the tests look great! Since I added a part of the code, I don't feel that I'm the right person to sign off on this. @kkaefer can you take a look?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great to me from the API standpoint. Can't comment on the C++ specifics though (pointer/type changes), maybe needs another pair of eyes.
test/style/source.test.cpp
Outdated
ASSERT_NE(geojson_source, nullptr); | ||
EXPECT_FALSE(geojson_source->getClusterChildren(1).empty()); | ||
EXPECT_FALSE(geojson_source->getClusterLeaves(1).empty()); | ||
EXPECT_NE(geojson_source->getClusterExpansionZoom(1), 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we test that the API returns specific values here instead of just making sure they're not default ones like for non-clustered sources?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mourner Done. I noticed that default GeoJSONSource clustering options differ from supercluster's defaults. Should default options be synced or there was a specific reason for different default options?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Supercluster (the JS version) can be used in different contexts than GL Native (e.g. with Leaflet), so it's not a problem that we don't match default options.
GeoJSONSource::Impl shares its private data as a raw pointer, this may lead to unwanted side-effects. Moreover GeoJSONSource, used to access its Impl data without checking whether data is valid, this PR fixes both issues.
fce4bff
to
34c3373
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a synchronization issue exposed by the new methods on mbgl::style::GeoJSONSource
. These methods return content from the current data available on the main thread. Cluster node information from queryRenderedFeatures
is retrieved from the data available on the render thread.
Using cluster_id
s from results of qRF
data may not match the data on the main thread when already modified with a call to GeoJSONSource::setURL
or GeoJSONSource::setGeoJSON
.
One way to provide the results here is to use a ClusterFeature
class for cluster nodes and implement that in the supercluster module or in mbgl::style::SuperclusterData
. Features from qRF
can then be cast to ClusteredFeature
which would provide the getLeaf
, getChildren
, and getExpansionZoom
methods. That said, each of these instances would need a shared_ptr<>
back to to the root data.
Alternately, the new APIs can be provided in Renderer
with a sourceId
. That would move the implementation of the methods to RenderGeoJSONSource
. Mobile SDKs already forward the qRF
invocations from source peers to the renderer, so their implementation would remain on the source objects.
@@ -63,7 +63,7 @@ void RenderGeoJSONSource::update(Immutable<style::Source::Impl> baseImpl_, | |||
util::tileSize, | |||
impl().getZoomRange(), | |||
optional<LatLngBounds>{}, | |||
[&] (const OverscaledTileID& tileID) { | |||
[&, data = data_] (const OverscaledTileID& tileID) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use data_
or rename so as to not shadow the member variable.
|
||
if (data_ != data) { | ||
if (data.lock() != data_) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it necessary to create the shared_ptr<>
here for the comparison or can you compare the internal pointers directly?
ASSERT_NE(geojson_source, nullptr); | ||
|
||
auto children = geojson_source->getClusterChildren(1); | ||
EXPECT_EQ(children.size(), 4U); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: use lower-case u
to match style convention in this repo.
@asheemmamoowala Thanks for review.
Would that require heap allocated Features, right? At the moment most of the code passes vectors of POD Features. If I would move methods to |
Ahhh, good catch @alexshalamov . Yes, they would not be POD-types anymore, and would have to hold Using the |
@tobrun Do you have any suggestions? If I understand correctly, generic problem is that there should be an interface for querying additional data about the |
This is a good way to think about this problem. How can different classes of features be queried for their particular unique datum. For the supercluster nodes though it does not address the need for identifying nodes using class Renderer {
...
mbgl::Value queryFeatureExtensions(
std::string sourceId,
optional<std::string> sourceLayer,
const mbgl::Feature& feature,
std::string extension,
std::string extensionField );
}
//Usage:
auto zoomValue = queryFeatureExtensions("my_geosjon", {}, featureFromQRF, "supercluster", "expansionZoom" ); The |
@asheemmamoowala could you please take a look at #13382 and tell what do you think? |
This PR is now obsolete with #13631 |
This PR exposes the
getChildren
,getLeaves
andgetClusterExpansionZoom
from v0.3.0 ofsupercluster.hpp
(see mapbox/supercluster.hpp#16 for upstream PR).Wasn't really sure about what the best approach is to expose these methods to the public API of
geojson_source.cpp
. For now, I introduced virtual methods that are no-op forGeoJSONVTData
. Lmk if there is a cleaner way of handling this.