Open 1ec5 opened 8 years ago
Just came across this issue because I was in need for this feature.
While looking for a workaround, I faced other problems:
I tried to exchange the whole GeoJSON source. First I removed the old GeoJSON source with mapView.style().remove(geoJSONSource)
followed by creating a new instance of MGLGeoJSONSource with the updated .geojson file. Then I added it with mapView.style().add(geoJSONSource)
. I'm pretty sure that this will be a performance issue with a huge .geojson file, when only a few points have been updated.
Another problem: The MapView doesn't re-render itself after updating the source, only when I drag the map around the updated GeoJSON source is visible. I fixed this with a little workaround because I couldn't find any update()
or reload()
method.
let currentCenter = mapView.centerCoordinate
let newCenter = CLLocationCoordinate2D(latitude: currentCenter.latitude + 0.000001, longitude: currentCenter.longitude)
mapView.centerCoordinate = newCenter
mapView.centerCoordinate = currentCenter
I'm pretty sure that this will be a performance issue with a huge .geojson file, when only a few points have been updated.
Yes, that’s the point I was trying to make in https://github.com/mapbox/mapbox-gl-native/issues/5626#issuecomment-231545691. Since support for incremental GeoJSON source updates isn’t planned in core, we’d have to implement this important functionality at the SDK level. So whatever performance issues you see with your implementation (serializing and deserializing the entire GeoJSON structure, for instance) will unfortunately remain.
The MapView doesn't re-render itself after updating the source, only when I drag the map around the updated GeoJSON source is visible.
We just released v3.4.0-alpha.5, which contains #6201. Does that address the problem?
MGLPointAnnotation and MGLMultiPoint (MGLPolyline, MGLPolygon) can both be mutable. When the developer adds an MGLPointFeature, MGLPolylineFeature, or MGLPolygonFeature to a MGLGeoJSONSource, they may expect the source to update automatically as the geometry changes, not just when individual features are added and removed. That would require something similar to the key-value observation in MGLMapView that we added in #3835 and #6565. MGLGeoJSONSource would have to keep all the MGLFeature objects around, just as MGLMapView does for annotations, and regenerate the entire mbgl GeoJSON structure any time anything changes. To reduce overhead, we could rely on feature identifiers, when present, to modify only the affected part of the GeoJSON structure.
Just read your comment @1ec5. Based on your previous comment this can (must?) be done at the SDK level so it's something I'm confident to resolve and find a solution. Are there any more ideas in your head which may help me?
I'm hearing that a solution down in mbgl is no longer off the table, but that it's a difficult proposition. An SDK-level solution is needed anyways if we're to track changes within an MGLFeature object.
We just released beta 1, which has #6524, which should make the task here quite a bit easier.
@rmnblm @1ec5 just noting that I've opened https://github.com/mapbox/mapbox-gl-native/pull/6777 to address #6159. #6777 allows you to mutate the features
property of MGLGeoJSONSource
and that mutation will trigger map updates. However, #6777 will not attempt to monitor for and react to changes to the features themselves as discussed above.
In case you know OTOH @1ec5, is this still relevant? The way I'm seeing the current API, you can modify MGLShapeSource.shape
; however it is a copy
property, so likely not as efficient as desired. I dig into the current state of things if it's helpful.
Yes, this is still relevant. #7458 would streamline shape source updating somewhat from the perspective of application code, but the fact remains that something (whether application code or SDK code) still has to blow away the entire source and recreate it every time you want to modify any detail about an individual shape or its vertices. By contrast, you can update annotations very performantly because existing annotations are never removed in the process. This is currently a fundamental deficiency of the runtime styling API versus the annotation API.
This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.
I want to fill Mapbox map with data again ,when refresh button click.i remove source and layer from map .but 'MGLRedundantSourceIdentifierException', reason: 'Source mapSource already exists' error is appeared
This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.
This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.
In order for the runtime styling API to have parity with the annotation API, it needs to be possible to modify a GeoJSON source more granularly. #6159 tracks making MGLGeoJSONSource’s data mutable, but the developer would still need to set the source’s entire data in one shot. That’s a dealbreaker for the most common use cases of point annotations. For example:
With the annotation API, each of these cases (except for #6160) is straightforward – just a line of code. By contrast, with the runtime styling API, the developer needs to obtain the entire source data, mutate it, then feed the result back into the source every time a modification is needed. This can be terribly inconvenient, not to mention less performant than dealing with annotations.
Per https://github.com/mapbox/mapbox-gl-native/issues/5626#issuecomment-232391207, no core support is planned for granular GeoJSON modification, so it’d be up to MGLGeoJSONSource itself to handle the source data mutation and feed the result back into the underlying source object. Hopefully performance won’t be an issue with that approach.
/cc @incanus @jfirebaugh @frederoni