Currently I am removing SKPolylines by tracking their setIdentifier(int) numbers when I create them, and then when I delete them I apply a new polyline to the map with the same identifier that is transparent. I have two issues with this:
I assume there should be a way to do mapView.removePolyline(int identifier); or mapView.removeAllPolylines();
I also assume there should be a way to do mapView.getAllPolylines() that returns a List<SKPolyine> because that is possible with POI's and annotations. At the very least mapView.getNumPolylines(); that returns the number of polylines so that I can delete them all with my original method, without having to track how many I have put down.
My question is: Am I missing either functionality described in 1/2? If those functionalities do not exist then is there a better way than my current method?
Related
I'm creating an Android app using MapBox. I've already set up a simple map functionality with markers sourced from .json file. Next step is filtering the markers on the map, just like in this gl-js example here:
https://docs.mapbox.com/mapbox-gl-js/example/filter-markers/
I can't find any sdk examples anywhere, and since this is my first app I really can't figure it out on my own. Any help will be appreciated.
You can check out this example https://docs.mapbox.com/android/maps/examples/multiple-expressions-temperature-change/ that features two layers that fetch a min or max temperature from the data source and display it.
The filtering part is done here:
// Only display Maximum Temperature in this layer
maxTempLayer.setFilter(eq(get("element"), literal("All-Time Maximum Temperature")));
loadedMapStyle.addLayer(maxTempLayer);
Filters accept expressions as arguments, and here Expression.eq is used to compare "element" from the GeoJSON data source (referenced with the Expression.get) with the "All-Time Maximum Temperature" value. If it resolves to true, the feature is going to be displayed, otherwise, it's going to be hidden.
I use here-map sdk. I have db file with 16500 ! paths (coordinates of a point). I need to draw all paths on the map, when user activate function "show additional paths". But i think, if i try to fetch big number of path and add all poplilynes object on here map, it will take a huge amount of time.
Help to find the optimal solution.
I would filter your data based on the visible viewport and disable this functionality where it doesn't make much sense (continental or globe level).
So, let's assume you app shows the map on zoomlevel 16 or 17 (district level), you can retrieve the viewport as GeoBoundingBox from the Map instance (e.g. via mapView.getMap()) with getBoundingBox().
The GeoBoundingBox makes it easy for you now to check for collisions with your own objects, since it has several "contains()" methods.
So everything that collides with your viewport should be shown, everything else is ignored.
You can update whenever the map viewport changes with either listening for OnTransformListener in the Map class or register for the MapGesture events (get MapGesture via getMapGesture() and listen for zooming events via addOnGestureListener())
If the amount of data for filtering is still too big, you can also think about preparing your data for more efficient filtering, like partitioning (region based would be my first idea) so only a subset of your data needs to be filtered.
It seems that Custom Location Extension (https://developer.here.com/platform-extensions/documentation/custom-location/topics/what-is.html) can help with this case.
In short, it allows you to upload a custom data to the HERE backend and query it later.
Why is setValueAt(...) in the public interface of the SparseArray class? I was using it instead of put(...) obviously not getting the result I had in mind.
I came here trying to figure out the same thing. As Prekak Sola mentioned in the comments, setValueAt maps a value on a specific index, while put maps a value on a specific key.
Obviously, that can become confusing, but I think it is a very useful feature, because if you look at the official SparseArray documentation, it is mentioned that the SparseArray is generally slower than a HashMap, because lookups require a binary search and adds and removes require inserting and deleting entries in the array.
So, I guess that in certain cases, it would perform much faster if you iterate over the items in this container using keyAt(int), size(), and obviously all index-related functions, such as setValueAt, instead of using the keys.
My application has separate algorithms to fetch data for scroll change and on user location change . For location change am using com.google.android.gms.location.LocationListener Which is working fine.
But for on user scroll, I am getting mMap.setOnCameraChangeListener(new OnCameraChangeListener(). But the issue is com.google.android.gms.location.LocationListene also triggers mMap.setOnCameraChangeListener(new OnCameraChangeListener().
So how to distinguish. Presently I am using Boolean values to differentiate, but it's not reliable and dirty.
I had the same issue, was trying all sorts of stuff like wrapping the view to intercept touches, or wrapping any calls to change the viewport and listening to when it started and stopped changing so I could tell if something else changed it, or matching the current viewport to what I last set it to... it's all rather fiddly. Then someone pointed me at this, and it looks promising update: has now worked flawlessly for us for months without a single issue:
map.setOnCameraMoveStartedListener { reasonCode ->
if (reasonCode == GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE) {
// I will no longer keep updating the camera location because
// the user interacted with it. This is my field I check before
// snapping the camera location to the latest value.
tracking = false
}
}
I doubt that there's an easy, reliable, and real-time way to do this. IOW, I suspect that it is going to be "dirty".
If I had to try, I would supply my own LocationSource, so that I knew when the map would be changing based upon position. I would then try to ignore the next call (calls?) to my OnCameraChangeListener, as being ones tied to the location change.
(BTW, note that LocationListener was deprecated)
Or, I would try to change my data-fetching algorithm to treat all camera changes equally. After all, if my objective is to make sure that I have data on all sides of the map from the current center, it doesn't matter how I got to that center, just so long as I am there.
I had read the .dex format document on Google, but I still got some confuses with some layer.
link_size & link_off : Google said it left unspecified and then said it's hook for runtime, so what it is? The static hook for global or local? or the hook to native library?
map_off : Why it need this redundancy IDs list? is it some kinda like the file address table?
proto_size & proto_off : Not quite sure what it actually is. I had de-assembled an randomly picked dex and look on this section, this section contained some short sign like DD/LL/JLJJ/...brabrabra, that made me more confused about this section. What exactly this section doing for?
Can anyone enlighten me?
The link section has never been specified or used. You might run across some dex files that have a garbage value for these fields, as an attempt to prevent baksmali from being able to be run on them (due to an old bug, that has been fixed for a while).
For the map item, Yes, there is redundancy for the locations of the indexed item sections - the location for these are specified in both the header item and the map item. But the map item is the only place the locations of the offset item sections are specified (the variable size items in the data section)
The prototype section defines the prototype for a method, i.e. the parameters and return type. If you look in the method_id_item, you'll see that it has a reference to a prototype item.