iPhone 3.0 MapKit - Multiple Annotations in the Same Location - iphone

Background: I have created an application that allows users to submit an entry to an online database, and view other entries from that database. These entries contain geocodes for latitude and longitude which are used for positioning the annotations on the MapKit. Users can submit the location using either their current location or an address, which is then geocoded.
Question: What is the proper or suggested method of handling annotations that fall on the exact same coordinates?
I was thinking of checking if there are any duplicate geocodes in the XML file pulled from the database and creating a single annotation with a custom annotationView that displays all of the separate ones. In addition, I was thinking of checking for duplicates and displaying "Multiple Entries..." and having the detail view display a table view with all of the entries.
Am I on the right track?

I think you are on the right track, you should check for duplicate geocodes and merge them into one. Displaying many annotations with the same location could be confusing because the pins will stack on top of each other and will be hard to diffrentiate and to click one by one.

Are you talking exact same geocode or kinda sorta close? Because if it's exact, then you're on the right track, but if it's +/- delta-T then you may have to come up with a different way of handling them since when zoomed-in all the way each location could be distinct. An easy way to hanle it is to drop or round-off decimal points in the lat/long value based on the zoom factor before checking for coordinate equality.
Other than that it sounds like you're on the right track. You will probably want to do both the custom annotation view (but that could work for only a few items) with the option to move on to a separate table view if there are more items to show.
One other thing I'd add is you could make it so your placemarker shows the number of items that co-reside in that location. You can do this by sticking a text label on top of your custom placemarker view and putting the number in it or by having pre-rendered icons with say, 1-9 and "..." (for more than that) in the heads of the markers. That way the user can quickly see there's more items to look for.

Related

Two cursors on maps at same time in Mapbox GL-JS

I am developing a weather radar viewer using Mapbox. In a certain mode, there are 2 Mapbox maps on the screen at the same time showing different modes of the radar. The maps are locked to each other. When one map moves, rotates, or pans - the other one does as well. I did this by simply passing the properties of one map to the other. In the below screenshot, you will see how they are showing identical locations.
What I want to do is - when the user is hovering the mouse over "map1", I would like an identical (ghost or false) cursor on "map2". Here is what I am looking to do:
(edit: What you are looking at is an actual screenshot. Each map is enclosed in a DIV with 50% width of the screen, if this helps to explain)
I don't know if this is even possible in Mapbox. Hopefully someone can give some guidance as I can't find any other questions related to this and I really have no code to show without knowing where to start.
If you attempt to do this inside Mapbox-GL-JS (for instance, by constantly updating the location of a GeoJSON feature layer), I think the performance will be pretty poor.
But since the two views are exactly locked (and presumably the exact same dimensions), you can just do this at an HTML/CSS level. Detect mouse movement on the first map, and update the location of an absolutely-positioned element hovering over the second map to match.
Another approach would be using a canvas element overlaid over the second map, similarly updated.

Mapbox: show only one country on base map?

I'm using Mapbox GL JS. Is there any way I can style my base layer to look like the Mapbox Light example, but showing only the UK?
I assume I would use Mapbox Studio to build my own base layer, but I can't see any way in Studio to filter by country.
If that's not possible, is there any way I could show labels on the UK only, and show other countries as filled polygons? (As per this unanswered question.)
Unfortunately it is not possible to filter by a certain geography when selecting the data source for a layer. If you're working with Mapbox's tiles, they'll always cover the entire planet.
There is the possibility to restrict the map to a certain (rectangular) bounds, with the map.setMaxBounds method (https://www.mapbox.com/mapbox-gl-js/api/#Map#setMaxBounds). This might work reasonably well since you want to restrict the view to the UK, but might not be suitable depending on the geometry you want to restrict the view to.
As a workaround you could create a dataset and add a polygon that covers the entire planet except for the extent you want to show in your map. Then add this dataset in your style as the top most layer and style it with whatever you'd like the empty space in your map to look like.
The workaround has been also suggested in this SO answer, if you can get maptiles for the UK only (the SO answer gives a link, but for Germany) you can
upload them to Mapbox as a dataset, export it to tilesets, and then
to a map as a layer. Delete all other layers
You have also the possibility to Style a single country in Mapbox
studio ref this tutorial. The other countries are still shown, but you can style your map in a way to highlight UK
There is a option that allows you to show only one country highlighted. But drawback is, you lose all the layers and tile-level details. Here is the link https://www.mapbox.com/videos/how-to/map-a-single-country-in-mapbox-studio/.
But if you want to include the tile details as well as whole world map but in that map only one or two or custom amount of countries highlighted, then, from above link of Natural Earth download the zipped file of ne_10m_admin_0_countries and upload.
Go back to your map style, and instead of making a blank one. Add another layer of ne_10m_admin_0_countries in your current map. Select the country in the filter option (in same way as shown in video). And change its opacity. That's it.
Hope it helps. Have a great day.

iPhone iOS how to deal with time gaps in Core Data when presenting a graph?

I'm running into a problem of how to display sequences of core data entities on a single graph, if there are time gaps between sequences.
I got a fixed-length bar graph (backed by UITableView) with each bar represented by a core data entity, all entities are timestamped and follow each other, so sorting such data results in a graph like below. The good thing about such graph is that NSFetchedResultsController can be used to dynamically update the table view in response to new events being added. The result is that it appears to the user that new bars are added on the left as time goes by.
My problem is that I want to expand this graph and make it 24 hour long and scrollable side to side. In this case, there will be episodes where no data will be present in the app. The end result is that if I rely on NSFetchedResultsController when there are gaps in data, and I want to display blank cells for missing data.
I'm interested in how you would approach the problem.
I see two potential solutions:
1) Drop the approach of using NSFetchedResultsController, and instead manually calculate the number of bars in a UITableView. Each bar is defined by a start date and an end date. Then I can use NSFetchRequest with predicate to query each bar's data. If there's an event with a timestamp that falls within the bar's date range, then a bar is shown, otherwise a blank is shown.
The problem with approach #1 is that it is slow, and while it does allow scrolling through the entire data set, it is slow and laggy, as each fetch request is executed for each new bar. Additionally, I need to manually refresh the table in response to new data being added, which is difficult to implement properly.
2) Maybe I can pre-populate the data set with blank events, and then "fill them in" as data becomes available. This would allow me to keep the table view with fetched results controller, resulting in smoother scrolling, but at the price of significantly increasing the persistent storage used by the app (as blank entities will be created between app use).
I'm wandering if there's an additional approach that I'm not thinking of. How would you create a side scrollable bar graph that would allow for "gaps" in the app's persistent data storage?
Thank you for your input!
Your question really doesn't have (or shouldn't have) anything to do with Core Data or NSFetchedResultsController. How your graph view draws the data it's given is entirely up to the graph view. There's no reason that you couldn't write a graph view that uses NSFetchedResultsController and deals appropriately with gaps in the data, but UITableView was never intended to deal with missing/empty cells.
The problem is not that you're using either Core Data or NSFetchedResultsController. The problem is that you're abusing UITableView.
Drawing a bar graph is pretty easy -- it's just a series of rectangles drawn at appropriate locations. You can give your view a fetched results controller and have it look at the fetchedObjects property to get the current list of objects. It can then render as many of those objects as it likes, and it can use the start and end date of each object to locate the drawing on the graph. Put your graph in a UIScrollView so that you don't have to worry about scrolling. If the graph can get large, add tiling so that you're only drawing the parts that the user is looking at, just like UITableView does.
It looks like you're currently drawing some content above your table view, too. If you create your own graph view, you might consider drawing that additional content (the red line, the red and green bubbles, the high REM probability thing) at the same time. Doing that will make it easy to ensure that all that content is located correctly on the graph (which is probably a bit of a pain with your current scheme).

How to deal with lag resulting from hundreds of map annotations on an MKMapView?

I'm in a situation where there will be 500+ annotations to load onto a map. What some ways that you have dealt with the resulting lag with so many annotations on the map?
One thing I've considered: only loading a portion of the annotations based on the current map region in view. But what happens when they zoom out or move around? Reload based on the region displayed?
MKMapView has a dequeueReusableAnnotationViewWithIdentifier: method (documentation) that I believe you're supposed to use. It looks like it works similarly to UITableView's dequeueReusableCellWithIdentifier: method.
Another thing might be to group clustered pins together into one pin. As you zoom in, you can expand these groups.
update: Found a cool open-source library that might be useful for dealing with tons of annotation points: ADClusterMapView

Show annotation on MKMapView based on user location

I've problem with Objective C at the moment with developing something special.
So - after the MKMapView is initialized and the users position is shown, I would like to implement a method to show annotations which are next to users position. I've stored all necessary points in an SQLite database in a special table. I've two fields - namely lonand lat- I think it's clear what is meant by that.
Has anybody an idea how to show JUST those annotations which are visible at the screen to be as performant as possible. After the user scrolls the map - it should call the method again to look up in database wether there are also other points which need to be shown...
Thank you very much in advance for your help,
kind regards,
Dominik
You will need to do a few things.
1) Get the center of your map - use the centerCoordinate property of your MKMapView
2) Ask your database for all items within a certain distance from the center of the map.
3) Display them
It's (2) that's the tricky one - you need a method that will return all items near to the lat lng you have.
This link has a handy implementation of how to do that :)
Hope that helps.
A couple of points:
If you're using iOS4, the mapview behaviour has changed so that it automatically saves memory by only creating the annotations which are in the visible view.
Secondly, in the same way that you can create a tableview with thousands of cells and still have it scroll smoothly, the annotations offscreen don't affect the performance that much. You should be keeping your annotations very small so they don't consume much memory. The annotation views are the ones that take up the memory.
Your problem is going to come when the user zooms out and there are too many annotation views visible at the same time. When you're zoomed in, you don't need to worry too much about off-screen annotations.